diff --git a/.eslintrc.yml b/.eslintrc.yml new file mode 100644 index 0000000..09a55b7 --- /dev/null +++ b/.eslintrc.yml @@ -0,0 +1,82 @@ +env: + es2021: true + node: true + browser: true +extends: + - eslint:recommended + - plugin:@typescript-eslint/recommended +overrides: [] +parser: "@typescript-eslint/parser" +parserOptions: + ecmaVersion: latest + sourceType: module +plugins: + - "@typescript-eslint" +globals: + Vue: readonly + THREE: readonly + SvelteComponents: readonly + $: readonly + Clusterize: readonly + SockJS: readonly +rules: + indent: + - off + "@typescript-eslint/indent": + - error + - 4 + linebreak-style: + - error + - unix + quotes: + - error + - double + - allowTemplateLiterals: true + avoidEscape: true + semi: + - error + - always + "@typescript-eslint/no-explicit-any": + - off + "@typescript-eslint/no-unused-vars": + - error + - argsIgnorePattern: _.* + no-unused-vars: + - error + no-trailing-spaces: + - error + key-spacing: + - error + space-before-blocks: + - error + block-spacing: + - error + brace-style: + - error + curly: + - error + keyword-spacing: + - error + "@typescript-eslint/no-var-requires": + - off + no-multiple-empty-lines: + - error + - max: 1 + func-call-spacing: + - error + - never + padding-line-between-statements: + - error + - blankLine: always + prev: function + next: function + no-var: + - error + no-unused-expressions: + - error + prefer-const: + - error + prefer-template: + - error + template-curly-spacing: + - error diff --git a/package-lock.json b/package-lock.json index 2206680..770abee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,14 @@ "hasInstallScript": true, "license": "GPL-3.0+", "dependencies": { + "@typescript-eslint/eslint-plugin": "^5.36.1", + "@typescript-eslint/parser": "^5.36.1", "browserify": "^17.0.0", + "eslint": "^8.23.0", + "eslint-config-standard-with-typescript": "^22.0.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-n": "^15.2.5", + "eslint-plugin-promise": "^6.0.1", "jshint": "^2.13.4", "jstransformer-escape-html": "^1.1.0", "jstransformer-scss": "^2.0.0", @@ -19,6 +26,152 @@ "pug-cli": "^1.0.0-alpha6" } }, + "node_modules/@eslint/eslintrc": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.1.tgz", + "integrity": "sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/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/@eslint/eslintrc/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/@eslint/eslintrc/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/@humanwhocodes/config-array": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz", + "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==", + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/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/@humanwhocodes/config-array/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/@humanwhocodes/gitignore-to-minimatch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", + "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "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/babel-types": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/babel-types/-/babel-types-7.0.11.tgz", @@ -32,6 +185,325 @@ "@types/babel-types": "*" } }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==" + }, + "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==" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.36.1.tgz", + "integrity": "sha512-iC40UK8q1tMepSDwiLbTbMXKDxzNy+4TfPWgIL661Ym0sD42vRcQU93IsZIrmi+x292DBr60UI/gSwfdVYexCA==", + "dependencies": { + "@typescript-eslint/scope-manager": "5.36.1", + "@typescript-eslint/type-utils": "5.36.1", + "@typescript-eslint/utils": "5.36.1", + "debug": "^4.3.4", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.2.0", + "regexpp": "^3.2.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/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/@typescript-eslint/eslint-plugin/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/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.36.1.tgz", + "integrity": "sha512-/IsgNGOkBi7CuDfUbwt1eOqUXF9WGVBW9dwEe1pi+L32XrTsZIgmDFIi2RxjzsvB/8i+MIf5JIoTEH8LOZ368A==", + "dependencies": { + "@typescript-eslint/scope-manager": "5.36.1", + "@typescript-eslint/types": "5.36.1", + "@typescript-eslint/typescript-estree": "5.36.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/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/@typescript-eslint/parser/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/@typescript-eslint/scope-manager": { + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.36.1.tgz", + "integrity": "sha512-pGC2SH3/tXdu9IH3ItoqciD3f3RRGCh7hb9zPdN2Drsr341zgd6VbhP5OHQO/reUqihNltfPpMpTNihFMarP2w==", + "dependencies": { + "@typescript-eslint/types": "5.36.1", + "@typescript-eslint/visitor-keys": "5.36.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.36.1.tgz", + "integrity": "sha512-xfZhfmoQT6m3lmlqDvDzv9TiCYdw22cdj06xY0obSznBsT///GK5IEZQdGliXpAOaRL34o8phEvXzEo/VJx13Q==", + "dependencies": { + "@typescript-eslint/typescript-estree": "5.36.1", + "@typescript-eslint/utils": "5.36.1", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/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/@typescript-eslint/type-utils/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/@typescript-eslint/types": { + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.36.1.tgz", + "integrity": "sha512-jd93ShpsIk1KgBTx9E+hCSEuLCUFwi9V/urhjOWnOaksGZFbTOxAT47OH2d4NLJnLhkVD+wDbB48BuaycZPLBg==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.36.1.tgz", + "integrity": "sha512-ih7V52zvHdiX6WcPjsOdmADhYMDN15SylWRZrT2OMy80wzKbc79n8wFW0xpWpU0x3VpBz/oDgTm2xwDAnFTl+g==", + "dependencies": { + "@typescript-eslint/types": "5.36.1", + "@typescript-eslint/visitor-keys": "5.36.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/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/@typescript-eslint/typescript-estree/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/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.36.1.tgz", + "integrity": "sha512-lNj4FtTiXm5c+u0pUehozaUWhh7UYKnwryku0nxJlYUEWetyG92uw2pr+2Iy4M/u0ONMKzfrx7AsGBTCzORmIg==", + "dependencies": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.36.1", + "@typescript-eslint/types": "5.36.1", + "@typescript-eslint/typescript-estree": "5.36.1", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.36.1.tgz", + "integrity": "sha512-ojB9aRyRFzVMN3b5joSYni6FAS10BBSCAfKJhjJAV08t/a95aM6tAhz+O1jF+EtgxktuSO3wJysp2R+Def/IWQ==", + "dependencies": { + "@typescript-eslint/types": "5.36.1", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/acorn": { "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", @@ -62,6 +534,14 @@ "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/acorn-node": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", @@ -80,6 +560,21 @@ "node": ">=0.4.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/align-text": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", @@ -121,6 +616,54 @@ "node": ">= 8" } }, + "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.5", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", + "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", + "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", @@ -473,6 +1016,28 @@ "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==" }, + "node_modules/builtins": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", + "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", + "dependencies": { + "semver": "^7.0.0" + } + }, + "node_modules/builtins/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/cached-path-relative": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.1.0.tgz", @@ -490,6 +1055,14 @@ "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/camelcase": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", @@ -617,6 +1190,22 @@ "node": ">=0.8" } }, + "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/combine-source-map": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", @@ -729,6 +1318,19 @@ "sha.js": "^2.4.8" } }, + "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/crypto-browserify": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", @@ -811,6 +1413,11 @@ "node": ">=0.10" } }, + "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", @@ -885,6 +1492,28 @@ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/doctypes": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", @@ -1017,6 +1646,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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==", + "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", @@ -1046,6 +1683,503 @@ "node": ">=0.8.0" } }, + "node_modules/eslint": { + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.0.tgz", + "integrity": "sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==", + "dependencies": { + "@eslint/eslintrc": "^1.3.1", + "@humanwhocodes/config-array": "^0.10.4", + "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@humanwhocodes/module-importer": "^1.0.1", + "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", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.15.0", + "globby": "^11.1.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "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-config-standard-with-typescript": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard-with-typescript/-/eslint-config-standard-with-typescript-22.0.0.tgz", + "integrity": "sha512-VA36U7UlFpwULvkdnh6MQj5GAV2Q+tT68ALLAwJP0ZuNXU2m0wX07uxX4qyLRdHgSzH4QJ73CveKBuSOYvh7vQ==", + "dependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint-config-standard": "17.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^5.0.0", + "eslint": "^8.0.1", + "eslint-plugin-import": "^2.25.2", + "eslint-plugin-n": "^15.0.0", + "eslint-plugin-promise": "^6.0.0", + "typescript": "*" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "dependencies": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/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==", + "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==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/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==", + "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==", + "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==", + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "dependencies": { + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.7.3", + "has": "^1.0.3", + "is-core-module": "^2.8.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.values": "^1.1.5", + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-n": { + "version": "15.2.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.2.5.tgz", + "integrity": "sha512-8+BYsqiyZfpu6NXmdLOXVUfk8IocpCjpd8nMRRH0A9ulrcemhb2VI9RSJMEy5udx++A/YcVPD11zT8hpFq368g==", + "dependencies": { + "builtins": "^5.0.1", + "eslint-plugin-es": "^4.1.0", + "eslint-utils": "^3.0.0", + "ignore": "^5.1.1", + "is-core-module": "^2.10.0", + "minimatch": "^3.1.2", + "resolve": "^1.22.1", + "semver": "^7.3.7" + }, + "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.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-promise": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.0.1.tgz", + "integrity": "sha512-uM4Tgo5u3UWQiroOyDEsYcVMOo7re3zmno0IZmB5auxoaQNIceAbXEkSt8RNrKtaYehARHG06pYK6K1JhtP0Zw==", + "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/eslint/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/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/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/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/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/eslint/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/eslint/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/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/espree": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", + "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/espree/node_modules/acorn": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "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", @@ -1091,11 +2225,60 @@ "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-glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "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/fast-safe-stringify": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "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/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -1107,6 +2290,38 @@ "node": ">=8" } }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "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", @@ -1155,6 +2370,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==" + }, "node_modules/functions-have-names": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", @@ -1226,6 +2446,44 @@ "node": ">= 6" } }, + "node_modules/globals": { + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/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", @@ -1256,6 +2514,14 @@ "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", @@ -1402,11 +2668,42 @@ } ] }, + "node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "engines": { + "node": ">= 4" + } + }, "node_modules/immutable": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==" }, + "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", @@ -1531,9 +2828,9 @@ } }, "node_modules/is-core-module": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", - "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", "dependencies": { "has": "^1.0.3" }, @@ -1756,6 +3053,11 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, "node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", @@ -1769,6 +3071,17 @@ "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==" }, + "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/jshint": { "version": "2.13.4", "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.13.4.tgz", @@ -1805,6 +3118,27 @@ "node": "*" } }, + "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.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, "node_modules/jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", @@ -1900,6 +3234,32 @@ "node": ">=0.10.0" } }, + "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": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -1923,6 +3283,17 @@ "node": ">=0.10.0" } }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -1933,6 +3304,26 @@ "safe-buffer": "^5.1.2" } }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/miller-rabin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", @@ -2025,6 +3416,11 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "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/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -2074,6 +3470,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object.values": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -2082,16 +3494,71 @@ "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/os-browserify": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==" }, + "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/pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" }, + "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/parents": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", @@ -2117,6 +3584,14 @@ "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==" }, + "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", @@ -2125,6 +3600,14 @@ "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", @@ -2138,6 +3621,14 @@ "node": ">= 0.8.0" } }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "engines": { + "node": ">=8" + } + }, "node_modules/pbkdf2": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", @@ -2164,6 +3655,14 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -2353,6 +3852,25 @@ "node": ">=0.4.x" } }, + "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/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -2437,6 +3955,17 @@ "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/repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", @@ -2461,12 +3990,29 @@ "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/resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", "deprecated": "https://github.com/lydell/resolve-url#deprecated" }, + "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/right-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", @@ -2478,6 +4024,20 @@ "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/ripemd160": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", @@ -2487,6 +4047,28 @@ "inherits": "^2.0.1" } }, + "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-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -2560,6 +4142,25 @@ "fast-safe-stringify": "^2.0.7" } }, + "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/shell-quote": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz", @@ -2597,6 +4198,14 @@ } ] }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -2741,6 +4350,14 @@ "node": ">=0.10.0" } }, + "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==", + "engines": { + "node": ">=4" + } + }, "node_modules/strip-json-comments": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", @@ -2827,6 +4444,11 @@ "acorn-node": "^1.2.0" } }, + "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/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -2876,16 +4498,81 @@ "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-0.0.1.tgz", "integrity": "sha512-nfjOAu/zAWmX9tgwi5NRp7O7zTDUD1miHiB40klUnAh9qnL1iXdgzcz/i5dMaL5jahcBAaSfmNOBBJBLJW8TEg==" }, + "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==", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, "node_modules/tty-browserify": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==" }, + "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/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" }, + "node_modules/typescript": { + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.2.tgz", + "integrity": "sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "node_modules/uglify-js": { "version": "2.8.29", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", @@ -2947,6 +4634,22 @@ "undeclared-identifiers": "bin.js" } }, + "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/uri-js/node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "engines": { + "node": ">=6" + } + }, "node_modules/urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", @@ -2998,6 +4701,20 @@ "node": ">=0.10.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", @@ -3060,6 +4777,14 @@ "node": ">=0.4.0" } }, + "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/wordwrap": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", @@ -3081,6 +4806,11 @@ "node": ">=0.4" } }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, "node_modules/yargs": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", @@ -3091,9 +4821,119 @@ "decamelize": "^1.0.0", "window-size": "0.1.0" } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } }, "dependencies": { + "@eslint/eslintrc": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.1.tgz", + "integrity": "sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==", + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "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==" + } + } + }, + "@humanwhocodes/config-array": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz", + "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==", + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "@humanwhocodes/gitignore-to-minimatch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", + "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==" + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==" + }, + "@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==" + }, + "@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==", + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" + }, + "@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==", + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, "@types/babel-types": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/babel-types/-/babel-types-7.0.11.tgz", @@ -3107,6 +4947,196 @@ "@types/babel-types": "*" } }, + "@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==" + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" + }, + "@typescript-eslint/eslint-plugin": { + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.36.1.tgz", + "integrity": "sha512-iC40UK8q1tMepSDwiLbTbMXKDxzNy+4TfPWgIL661Ym0sD42vRcQU93IsZIrmi+x292DBr60UI/gSwfdVYexCA==", + "requires": { + "@typescript-eslint/scope-manager": "5.36.1", + "@typescript-eslint/type-utils": "5.36.1", + "@typescript-eslint/utils": "5.36.1", + "debug": "^4.3.4", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.2.0", + "regexpp": "^3.2.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/parser": { + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.36.1.tgz", + "integrity": "sha512-/IsgNGOkBi7CuDfUbwt1eOqUXF9WGVBW9dwEe1pi+L32XrTsZIgmDFIi2RxjzsvB/8i+MIf5JIoTEH8LOZ368A==", + "requires": { + "@typescript-eslint/scope-manager": "5.36.1", + "@typescript-eslint/types": "5.36.1", + "@typescript-eslint/typescript-estree": "5.36.1", + "debug": "^4.3.4" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.36.1.tgz", + "integrity": "sha512-pGC2SH3/tXdu9IH3ItoqciD3f3RRGCh7hb9zPdN2Drsr341zgd6VbhP5OHQO/reUqihNltfPpMpTNihFMarP2w==", + "requires": { + "@typescript-eslint/types": "5.36.1", + "@typescript-eslint/visitor-keys": "5.36.1" + } + }, + "@typescript-eslint/type-utils": { + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.36.1.tgz", + "integrity": "sha512-xfZhfmoQT6m3lmlqDvDzv9TiCYdw22cdj06xY0obSznBsT///GK5IEZQdGliXpAOaRL34o8phEvXzEo/VJx13Q==", + "requires": { + "@typescript-eslint/typescript-estree": "5.36.1", + "@typescript-eslint/utils": "5.36.1", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "@typescript-eslint/types": { + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.36.1.tgz", + "integrity": "sha512-jd93ShpsIk1KgBTx9E+hCSEuLCUFwi9V/urhjOWnOaksGZFbTOxAT47OH2d4NLJnLhkVD+wDbB48BuaycZPLBg==" + }, + "@typescript-eslint/typescript-estree": { + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.36.1.tgz", + "integrity": "sha512-ih7V52zvHdiX6WcPjsOdmADhYMDN15SylWRZrT2OMy80wzKbc79n8wFW0xpWpU0x3VpBz/oDgTm2xwDAnFTl+g==", + "requires": { + "@typescript-eslint/types": "5.36.1", + "@typescript-eslint/visitor-keys": "5.36.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/utils": { + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.36.1.tgz", + "integrity": "sha512-lNj4FtTiXm5c+u0pUehozaUWhh7UYKnwryku0nxJlYUEWetyG92uw2pr+2Iy4M/u0ONMKzfrx7AsGBTCzORmIg==", + "requires": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.36.1", + "@typescript-eslint/types": "5.36.1", + "@typescript-eslint/typescript-estree": "5.36.1", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "dependencies": { + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.36.1.tgz", + "integrity": "sha512-ojB9aRyRFzVMN3b5joSYni6FAS10BBSCAfKJhjJAV08t/a95aM6tAhz+O1jF+EtgxktuSO3wJysp2R+Def/IWQ==", + "requires": { + "@typescript-eslint/types": "5.36.1", + "eslint-visitor-keys": "^3.3.0" + } + }, "acorn": { "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", @@ -3127,6 +5157,12 @@ } } }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "requires": {} + }, "acorn-node": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", @@ -3142,6 +5178,17 @@ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==" }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "align-text": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", @@ -3171,6 +5218,39 @@ "picomatch": "^2.0.4" } }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "array-includes": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", + "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.7" + } + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" + }, + "array.prototype.flat": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", + "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" + } + }, "asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", @@ -3479,6 +5559,24 @@ "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==" }, + "builtins": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", + "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", + "requires": { + "semver": "^7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, "cached-path-relative": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.1.0.tgz", @@ -3493,6 +5591,11 @@ "get-intrinsic": "^1.0.2" } }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + }, "camelcase": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", @@ -3590,6 +5693,19 @@ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==" }, + "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==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, "combine-source-map": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", @@ -3699,6 +5815,16 @@ "sha.js": "^2.4.8" } }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, "crypto-browserify": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", @@ -3771,6 +5897,11 @@ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", "integrity": "sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==" }, + "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==" + }, "define-properties": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", @@ -3832,6 +5963,22 @@ } } }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "requires": { + "path-type": "^4.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "requires": { + "esutils": "^2.0.2" + } + }, "doctypes": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", @@ -3949,6 +6096,14 @@ "unbox-primitive": "^1.0.2" } }, + "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==", + "requires": { + "has": "^1.0.3" + } + }, "es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", @@ -3969,6 +6124,345 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" }, + "eslint": { + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.0.tgz", + "integrity": "sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==", + "requires": { + "@eslint/eslintrc": "^1.3.1", + "@humanwhocodes/config-array": "^0.10.4", + "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@humanwhocodes/module-importer": "^1.0.1", + "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", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.15.0", + "globby": "^11.1.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "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==" + }, + "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==", + "requires": { + "is-glob": "^4.0.3" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "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==" + }, + "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==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "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==", + "requires": {} + }, + "eslint-config-standard-with-typescript": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard-with-typescript/-/eslint-config-standard-with-typescript-22.0.0.tgz", + "integrity": "sha512-VA36U7UlFpwULvkdnh6MQj5GAV2Q+tT68ALLAwJP0ZuNXU2m0wX07uxX4qyLRdHgSzH4QJ73CveKBuSOYvh7vQ==", + "requires": { + "@typescript-eslint/parser": "^5.0.0", + "eslint-config-standard": "17.0.0" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "requires": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, + "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==", + "requires": { + "debug": "^3.2.7" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, + "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==", + "requires": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "dependencies": { + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" + } + } + }, + "eslint-plugin-import": { + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "requires": { + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.7.3", + "has": "^1.0.3", + "is-core-module": "^2.8.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.values": "^1.1.5", + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "requires": { + "esutils": "^2.0.2" + } + } + } + }, + "eslint-plugin-n": { + "version": "15.2.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.2.5.tgz", + "integrity": "sha512-8+BYsqiyZfpu6NXmdLOXVUfk8IocpCjpd8nMRRH0A9ulrcemhb2VI9RSJMEy5udx++A/YcVPD11zT8hpFq368g==", + "requires": { + "builtins": "^5.0.1", + "eslint-plugin-es": "^4.1.0", + "eslint-utils": "^3.0.0", + "ignore": "^5.1.1", + "is-core-module": "^2.10.0", + "minimatch": "^3.1.2", + "resolve": "^1.22.1", + "semver": "^7.3.7" + }, + "dependencies": { + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "eslint-plugin-promise": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.0.1.tgz", + "integrity": "sha512-uM4Tgo5u3UWQiroOyDEsYcVMOo7re3zmno0IZmB5auxoaQNIceAbXEkSt8RNrKtaYehARHG06pYK6K1JhtP0Zw==", + "requires": {} + }, + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "requires": { + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==" + } + } + }, + "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==" + }, + "espree": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", + "requires": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + }, + "dependencies": { + "acorn": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==" + } + } + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "requires": { + "estraverse": "^5.1.0" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "requires": { + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" + }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -4002,11 +6496,54 @@ "is-extendable": "^1.0.1" } }, + "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==" + }, + "fast-glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + }, "fast-safe-stringify": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" }, + "fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "requires": { + "reusify": "^1.0.4" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "requires": { + "flat-cache": "^3.0.4" + } + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -4015,6 +6552,29 @@ "to-regex-range": "^5.0.1" } }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" + }, "for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -4050,6 +6610,11 @@ "functions-have-names": "^1.2.2" } }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==" + }, "functions-have-names": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", @@ -4100,6 +6665,32 @@ "is-glob": "^4.0.1" } }, + "globals": { + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "requires": { + "type-fest": "^0.20.2" + } + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "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==" + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -4121,6 +6712,11 @@ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==" }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, "has-property-descriptors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", @@ -4233,11 +6829,30 @@ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==" + }, "immutable": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==" }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==" + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -4332,9 +6947,9 @@ "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==" }, "is-core-module": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", - "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", "requires": { "has": "^1.0.3" } @@ -4481,6 +7096,11 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", @@ -4491,6 +7111,14 @@ "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==" }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "requires": { + "argparse": "^2.0.1" + } + }, "jshint": { "version": "2.13.4", "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.13.4.tgz", @@ -4523,6 +7151,24 @@ } } }, + "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==" + }, + "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==" + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "requires": { + "minimist": "^1.2.0" + } + }, "jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", @@ -4594,6 +7240,23 @@ "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", "integrity": "sha512-RE2g0b5VGZsOCFOCgP7omTRYFqydmZkBwl5oNnQ1lDYC57uyO9KqNnNVxT7COSHTxrRCWVcAVOcbjk+tvh/rgQ==" }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "requires": { + "p-locate": "^5.0.0" + } + }, "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -4614,6 +7277,14 @@ "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", "integrity": "sha512-k+yt5n3l48JU4k8ftnKG6V7u32wyH2NfKzeMto9F/QRE0amxy/LayxwlvjjkZEIzqR+19IrtFO8p5kB9QaYUFg==" }, + "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==", + "requires": { + "yallist": "^4.0.0" + } + }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -4624,6 +7295,20 @@ "safe-buffer": "^5.1.2" } }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, "miller-rabin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", @@ -4703,6 +7388,11 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" + }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -4734,6 +7424,16 @@ "object-keys": "^1.1.1" } }, + "object.values": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -4742,16 +7442,53 @@ "wrappy": "1" } }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, "os-browserify": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==" }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "requires": { + "p-limit": "^3.0.2" + } + }, "pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" }, + "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==", + "requires": { + "callsites": "^3.0.0" + } + }, "parents": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", @@ -4777,11 +7514,21 @@ "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==" }, + "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==" + }, "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==" }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, "path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", @@ -4792,6 +7539,11 @@ "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", "integrity": "sha512-Y30dB6rab1A/nfEKsZxmr01nUotHX0c/ZiIAsCTatEe1CmS5Pm5He7fZ195bPT7RdquoaL8lLxFCMQi/bS7IJg==" }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" + }, "pbkdf2": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", @@ -4809,6 +7561,11 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" + }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -4987,6 +7744,11 @@ "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==" }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -5064,6 +7826,11 @@ "functions-have-names": "^1.2.2" } }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==" + }, "repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", @@ -5079,11 +7846,21 @@ "supports-preserve-symlinks-flag": "^1.0.0" } }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==" }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + }, "right-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", @@ -5092,6 +7869,14 @@ "align-text": "^0.1.1" } }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + }, "ripemd160": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", @@ -5101,6 +7886,14 @@ "inherits": "^2.0.1" } }, + "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==", + "requires": { + "queue-microtask": "^1.2.2" + } + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -5148,6 +7941,19 @@ "fast-safe-stringify": "^2.0.7" } }, + "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==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, "shell-quote": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz", @@ -5168,6 +7974,11 @@ "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -5293,6 +8104,11 @@ "ansi-regex": "^2.0.0" } }, + "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==" + }, "strip-json-comments": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", @@ -5351,6 +8167,11 @@ "acorn-node": "^1.2.0" } }, + "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==" + }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -5391,16 +8212,59 @@ "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-0.0.1.tgz", "integrity": "sha512-nfjOAu/zAWmX9tgwi5NRp7O7zTDUD1miHiB40klUnAh9qnL1iXdgzcz/i5dMaL5jahcBAaSfmNOBBJBLJW8TEg==" }, + "tsconfig-paths": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "requires": { + "tslib": "^1.8.1" + } + }, "tty-browserify": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==" }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" + }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" }, + "typescript": { + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.2.tgz", + "integrity": "sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==", + "peer": true + }, "uglify-js": { "version": "2.8.29", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", @@ -5445,6 +8309,21 @@ "xtend": "^4.0.1" } }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + } + } + }, "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", @@ -5494,6 +8373,14 @@ "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==" }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + }, "which-boxed-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", @@ -5540,6 +8427,11 @@ } } }, + "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==" + }, "wordwrap": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", @@ -5555,6 +8447,11 @@ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, "yargs": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", @@ -5565,6 +8462,11 @@ "decamelize": "^1.0.0", "window-size": "0.1.0" } + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" } } } diff --git a/package.json b/package.json index da6d0cf..42ecdce 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,14 @@ "postinstall": "cd src/svelte-components && npm i" }, "dependencies": { + "@typescript-eslint/eslint-plugin": "^5.36.1", + "@typescript-eslint/parser": "^5.36.1", "browserify": "^17.0.0", + "eslint": "^8.23.0", + "eslint-config-standard-with-typescript": "^22.0.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-n": "^15.2.5", + "eslint-plugin-promise": "^6.0.1", "jshint": "^2.13.4", "jstransformer-escape-html": "^1.1.0", "jstransformer-scss": "^2.0.0", @@ -16,4 +23,4 @@ "lodash.merge": "4.6.2", "pug-cli": "^1.0.0-alpha6" } -} \ No newline at end of file +} diff --git a/src/js/admin-general-view.js b/src/js/admin-general-view.js index 02aac51..e707721 100644 --- a/src/js/admin-general-view.js +++ b/src/js/admin-general-view.js @@ -1,143 +1,123 @@ -/******************************************************************************\ - - This file is part of the Buildbotics firmware. - - Copyright (c) 2015 - 2018, Buildbotics LLC - All rights reserved. - - This file ("the software") is free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License, - version 2 as published by the Free Software Foundation. You should - have received a copy of the GNU General Public License, version 2 - along with the software. If not, see . - - The software is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the software. If not, see - . - - For information regarding this software email: - "Joseph Coffland" - -\******************************************************************************/ - -'use strict' +"use strict"; +const api = require("./api"); const merge = require("lodash.merge"); const config_defaults = require("../resources/onefinity_defaults.json"); const variant_defaults = { - machinist_x35: require("../resources/onefinity_machinist_x35_defaults.json"), - woodworker_x35: require("../resources/onefinity_woodworker_x35_defaults.json"), - woodworker_x50: require("../resources/onefinity_woodworker_x50_defaults.json"), - journeyman_x50: require("../resources/onefinity_journeyman_x50_defaults.json") + machinist_x35: require("../resources/onefinity_machinist_x35_defaults.json"), + woodworker_x35: require("../resources/onefinity_woodworker_x35_defaults.json"), + woodworker_x50: require("../resources/onefinity_woodworker_x50_defaults.json"), + journeyman_x50: require("../resources/onefinity_journeyman_x50_defaults.json") }; -const api = require('./api'); - module.exports = { - template: '#admin-general-view-template', - props: ['config', 'state'], + template: "#admin-general-view-template", + props: ["config", "state"], - data: function () { - return { - confirmReset: false, - autoCheckUpgrade: true, - reset_variant: '' - } - }, - - ready: function () { - this.autoCheckUpgrade = this.config.admin['auto-check-upgrade'] - }, - - methods: { - backup: function () { - document.getElementById('download-target').src = '/api/config/download'; + data: function () { + return { + confirmReset: false, + autoCheckUpgrade: true, + reset_variant: "" + }; }, - restore_config: function () { - // If we don't reset the form the browser may cache file if name is same - // even if contents have changed - $('.restore-config')[0].reset(); - $('.restore-config input').click(); + ready: function () { + this.autoCheckUpgrade = this.config.admin["auto-check-upgrade"]; }, - restore: function (e) { - const files = e.target.files || e.dataTransfer.files; - if (!files.length) { - return; - } + methods: { + backup: function () { + document.getElementById("download-target").src = "/api/config/download"; + }, - const fileReader = new FileReader(); - fileReader.onload = async ({ target }) => { - let config; - try { - config = JSON.parse(target.result); - } catch (ex) { - api.alert("Invalid config file"); - return; + restore_config: function () { + // If we don't reset the form the browser may cache file if name is same + // even if contents have changed + $(".restore-config")[0].reset(); + $(".restore-config input").click(); + }, + + restore: function (e) { + const files = e.target.files || e.dataTransfer.files; + if (!files.length) { + return; + } + + const fileReader = new FileReader(); + fileReader.onload = async ({ target }) => { + let config; + try { + config = JSON.parse(target.result); + } catch (ex) { + api.alert("Invalid config file"); + return; + } + + try { + await api.put("config/save", config); + this.$dispatch("update"); + SvelteComponents.showDialog("Message", { + title: "Success", + message: "Configuration restored" + }); + } catch (error) { + api.alert("Restore failed", error); + } + }; + + fileReader.readAsText(files[0]); + }, + + reset: async function () { + const config = merge( + {}, + config_defaults, + variant_defaults[this.reset_variant] + ); + + try { + await api.put("config/save", config); + this.confirmReset = false; + this.$dispatch("update"); + SvelteComponents.showDialog("Message", { + title: "Success", + message: "Configuration restored" + }); + } catch (err) { + api.alert("Restore failed"); + console.error("Restore failed", err); + } + }, + + check: function () { + this.$dispatch("check"); + }, + + upgrade: function () { + this.$dispatch("upgrade"); + }, + + upload_firmware: function () { + // If we don't reset the form the browser may cache file if name is same + // even if contents have changed + $(".upload-firmware")[0].reset(); + $(".upload-firmware input").click(); + }, + + upload: function (e) { + const files = e.target.files || e.dataTransfer.files; + if (!files.length) { + return; + } + this.$dispatch("upload", files[0]); + }, + + change_auto_check_upgrade: function () { + this.config.admin["auto-check-upgrade"] = this.autoCheckUpgrade; + this.$dispatch("config-changed"); } - - try { - await api.put('config/save', config); - this.$dispatch('update'); - SvelteComponents.showDialog("Message", { title: "Success", message: "Configuration restored" }) - } catch (error) { - api.alert('Restore failed', error); - } - } - - fileReader.readAsText(files[0]); - }, - - reset: async function () { - const config = merge( - {}, - config_defaults, - variant_defaults[this.reset_variant] - ); - - try { - await api.put('config/save', config) - this.confirmReset = false; - this.$dispatch('update'); - SvelteComponents.showDialog("Message", { title: "Success", message: "Configuration restored" }) - } catch (err) { - api.alert('Restore failed'); - console.error('Restore failed', err); - } - }, - - check: function () { - this.$dispatch('check') - }, - - upgrade: function () { - this.$dispatch('upgrade') - }, - - upload_firmware: function () { - // If we don't reset the form the browser may cache file if name is same - // even if contents have changed - $('.upload-firmware')[0].reset(); - $('.upload-firmware input').click(); - }, - - upload: function (e) { - var files = e.target.files || e.dataTransfer.files; - if (!files.length) return; - this.$dispatch('upload', files[0]); - }, - - change_auto_check_upgrade: function () { - this.config.admin['auto-check-upgrade'] = this.autoCheckUpgrade; - this.$dispatch('config-changed'); } - } -} +}; diff --git a/src/js/admin-network-view.js b/src/js/admin-network-view.js index 12d20c5..cdb4935 100644 --- a/src/js/admin-network-view.js +++ b/src/js/admin-network-view.js @@ -1,14 +1,14 @@ module.exports = { - template: "#admin-network-view-template", + template: "#admin-network-view-template", - attached: function () { - this.svelteComponent = SvelteComponents.createComponent( - "AdminNetworkView", - document.getElementById("admin-network") - ); - }, + attached: function () { + this.svelteComponent = SvelteComponents.createComponent( + "AdminNetworkView", + document.getElementById("admin-network") + ); + }, - detached: function() { - this.svelteComponent.$destroy(); - } + detached: function() { + this.svelteComponent.$destroy(); + } }; diff --git a/src/js/api.js b/src/js/api.js index c97e86f..507f9de 100644 --- a/src/js/api.js +++ b/src/js/api.js @@ -1,77 +1,37 @@ -'use strict' +"use strict"; +async function callApi(method, url, body) { + try { + const response = await fetch(`/api/${url}`, { + method, + headers: { + "Content-Type": "application/json" + }, + body + }); -function api_cb(method, url, data, config) { - config = $.extend({ - type: method, - url: '/api/' + url, - dataType: 'json', - cache: false - }, config); + if (response.ok) { + return response.json(); + } - if (typeof data == 'object') { - config.data = JSON.stringify(data); - config.contentType = 'application/json; charset=utf-8'; - } + throw new Error(await response.text()); + } catch (error) { + console.debug(`API Error: ${url}: ${error}`); - var d = $.Deferred(); - - $.ajax(config).success(function (data, status, xhr) { - d.resolve(data, status, xhr); - - }).error(function (xhr, status, error) { - var text = xhr.responseText; - try {text = $.parseJSON(xhr.responseText)} catch(e) {} - if (!text) text = error; - - d.reject(text, xhr, status, error); - console.debug('API Error: ' + url + ': ' + text); - }); - - return d.promise(); + throw error; + } } - module.exports = { - get: function (url, config) { - return api_cb('GET', url, undefined, config); - }, + get: function (url) { + return callApi("GET", url); + }, + put: function(url, body = undefined) { + return callApi("PUT", url, body); + }, - put: function(url, data, config) { - return api_cb('PUT', url, data, config); - }, - - - post: function(url, data, config) { - return api_cb('POST', url, data, config); - }, - - - upload: function(url, data, config) { - config = $.extend({ - processData: false, - contentType: false, - cache: false, - data: data - }, config); - - return api_cb('PUT', url, undefined, config); - }, - - - 'delete': function (url, config) { - return api_cb('DELETE', url, undefined, config); - }, - - - alert: function (msg, error) { - if (typeof error != 'undefined') { - if (typeof error.message != 'undefined') - msg += '\n' + error.message; - else msg += '\n' + JSON.stringify(error); + delete: function (url) { + return callApi("DELETE", url); } - - alert(msg); - } -} +}; diff --git a/src/js/app.js b/src/js/app.js index 7210983..2913150 100644 --- a/src/js/app.js +++ b/src/js/app.js @@ -5,411 +5,437 @@ const cookie = require("./cookie")("bbctrl-"); const Sock = require("./sock"); SvelteComponents.createComponent("DialogHost", - document.getElementById("svelte-dialog-host") + document.getElementById("svelte-dialog-host") ); function is_newer_version(current, latest) { - const pattern = /(\d+)\.(\d+)\.(\d+)(.*)/; - const currentParts = current.match(pattern); - const latestParts = latest.match(pattern); + const pattern = /(\d+)\.(\d+)\.(\d+)(.*)/; + const currentParts = current.match(pattern); + const latestParts = latest.match(pattern); - if (!currentParts || !latestParts) { - return false; - } + if (!currentParts || !latestParts) { + return false; + } - // Normal version comparisons - const major = latestParts[1] - currentParts[1]; - const minor = latestParts[2] - currentParts[2]; - const patch = latestParts[3] - currentParts[3]; + // Normal version comparisons + const major = latestParts[1] - currentParts[1]; + const minor = latestParts[2] - currentParts[2]; + const patch = latestParts[3] - currentParts[3]; - // If current is a pre-release, and latest is a release - const betaToRelease = - latestParts[4].length === 0 && currentParts[4].length > 0; + // If current is a pre-release, and latest is a release + const betaToRelease = latestParts[4].length === 0 && currentParts[4].length > 0; - switch (true) { - case major > 0: - case major === 0 && minor > 0: - case major === 0 && minor === 0 && patch > 0: - case major === 0 && minor === 0 && patch === 0 && betaToRelease: - return true; + switch (true) { + case major > 0: + case major === 0 && minor > 0: + case major === 0 && minor === 0 && patch > 0: + case major === 0 && minor === 0 && patch === 0 && betaToRelease: + return true; - default: - return false; - } + default: + return false; + } } function is_object(o) { - return o !== null && typeof o == "object"; + return o !== null && typeof o == "object"; } + function is_array(o) { - return Array.isArray(o); + return Array.isArray(o); } function update_array(dst, src) { - while (dst.length) dst.pop(); - for (var i = 0; i < src.length; i++) Vue.set(dst, i, src[i]); + while (dst.length) { + dst.pop(); + } + + for (let i = 0; i < src.length; i++) { + Vue.set(dst, i, src[i]); + } +} + +function hasOwnProperty(obj, key) { + return Object.prototype.hasOwnProperty.call(obj, key); } function update_object(dst, src, remove) { - var props, index, key, value; + let props, index, key, value; - if (remove) { - props = Object.getOwnPropertyNames(dst); + if (remove) { + props = Object.getOwnPropertyNames(dst); - for (index in props) { - key = props[index]; - if (!src.hasOwnProperty(key)) Vue.delete(dst, key); + for (index in props) { + key = props[index]; + if (!hasOwnProperty(src, key)) { + Vue.delete(dst, key); + } + } } - } - props = Object.getOwnPropertyNames(src); - for (index in props) { - key = props[index]; - value = src[key]; + props = Object.getOwnPropertyNames(src); + for (index in props) { + key = props[index]; + value = src[key]; - if (is_array(value) && dst.hasOwnProperty(key) && is_array(dst[key])) - update_array(dst[key], value); - else if (is_object(value) && dst.hasOwnProperty(key) && is_object(dst[key])) - update_object(dst[key], value, remove); - else Vue.set(dst, key, value); - } + if (is_array(value) && hasOwnProperty(dst, key) && is_array(dst[key])) { + update_array(dst[key], value); + } else if (is_object(value) && hasOwnProperty(dst, key) && is_object(dst[key])) { + update_object(dst[key], value, remove); + } else { + Vue.set(dst, key, value); + } + } } module.exports = new Vue({ - el: "body", + el: "body", - data: function () { - return { - status: "connecting", - currentView: "loading", - display_units: localStorage.getItem("display_units") || "METRIC", - index: -1, - modified: false, - template: require("../resources/config-template.json"), - config: { - settings: { units: "METRIC" }, - motors: [{}, {}, {}, {}], - version: "", - full_version: "", - }, - state: { - messages: [], - }, - video_size: cookie.get("video-size", "small"), - crosshair: cookie.get("crosshair", "false") != "false", - errorTimeout: 30, - errorTimeoutStart: 0, - errorShow: false, - errorMessage: "", - confirmUpgrade: false, - confirmUpload: false, - firmwareUpgrading: false, - checkedUpgrade: false, - firmwareName: "", - latestVersion: "" - }; - }, - - components: { - estop: { template: "#estop-template" }, - "loading-view": { template: "

Loading...

" }, - "control-view": require("./control-view"), - "settings-view": require("./settings-view"), - "motor-view": require("./motor-view"), - "tool-view": require("./tool-view"), - "io-view": require("./io-view"), - "admin-general-view": require("./admin-general-view"), - "admin-network-view": require("./admin-network-view"), - "help-view": { template: "#help-view-template" }, - "cheat-sheet-view": { - template: "#cheat-sheet-view-template", - data: function () { + data: function () { return { - showUnimplemented: false + status: "connecting", + currentView: "loading", + display_units: localStorage.getItem("display_units") || "METRIC", + index: -1, + modified: false, + template: require("../resources/config-template.json"), + config: { + settings: { units: "METRIC" }, + motors: [{}, {}, {}, {}], + version: "", + full_version: "", + }, + state: { + messages: [], + }, + video_size: cookie.get("video-size", "small"), + crosshair: cookie.get("crosshair", "false") != "false", + errorTimeout: 30, + errorTimeoutStart: 0, + errorShow: false, + errorMessage: "", + confirmUpgrade: false, + confirmUpload: false, + firmwareUpgrading: false, + checkedUpgrade: false, + firmwareName: "", + latestVersion: "" }; - }, - }, - }, - - watch: { - display_units: function (value) { - localStorage.setItem("display_units", value); - SvelteComponents.setDisplayUnits(value); - }, - }, - - events: { - "config-changed": function () { - this.modified = true; }, - send: function (msg) { - if (this.status == "connected") { - this.sock.send(msg); - } + components: { + estop: { template: "#estop-template" }, + "loading-view": { template: "

Loading...

" }, + "control-view": require("./control-view"), + "settings-view": require("./settings-view"), + "motor-view": require("./motor-view"), + "tool-view": require("./tool-view"), + "io-view": require("./io-view"), + "admin-general-view": require("./admin-general-view"), + "admin-network-view": require("./admin-network-view"), + "help-view": { template: "#help-view-template" }, + "cheat-sheet-view": { + template: "#cheat-sheet-view-template", + data: function () { + return { + showUnimplemented: false + }; + }, + }, }, - connected: function () { - this.update(); + watch: { + display_units: function (value) { + localStorage.setItem("display_units", value); + SvelteComponents.setDisplayUnits(value); + }, }, - update: function () { - this.update(); - }, + events: { + "config-changed": function () { + this.modified = true; + }, - check: async function () { - try { - const response = await fetch("https://raw.githubusercontent.com/OneFinityCNC/onefinity-release/master/latest.txt", { - cache: "no-cache" - }); + send: function (msg) { + if (this.status == "connected") { + this.sock.send(msg); + } + }, - this.latestVersion = (await response.text()).trim(); - } catch (err) { - this.latestVersion = ""; - } - }, + connected: function () { + this.update(); + }, - upgrade: function () { - this.confirmUpgrade = true; - }, + update: function () { + this.update(); + }, - upload: function (firmware) { - this.firmware = firmware; - this.firmwareName = firmware.name; - this.confirmUpload = true; - }, + check: async function () { + try { + const response = await fetch("https://raw.githubusercontent.com/OneFinityCNC/onefinity-release/master/latest.txt", { + cache: "no-cache" + }); - error: function (msg) { - // Honor user error blocking - if (Date.now() - this.errorTimeoutStart < this.errorTimeout * 1000) - return; + this.latestVersion = (await response.text()).trim(); + } catch (err) { + this.latestVersion = ""; + } + }, - // Wait at least 1 sec to pop up repeated errors - if (1 < msg.repeat && Date.now() - msg.ts < 1000) { - return; - } + upgrade: function () { + this.confirmUpgrade = true; + }, - // Popup error dialog - this.errorShow = true; - this.errorMessage = msg.msg; - }, - }, + upload: function (firmware) { + this.firmware = firmware; + this.firmwareName = firmware.name; + this.confirmUpload = true; + }, - computed: { - popupMessages: function () { - const msgs = []; - - for (let i = 0; i < this.state.messages.length; i++) { - const text = this.state.messages[i].text; - if (!/^#/.test(text)) { - msgs.push(text); - } - } - - return msgs; - }, - }, - - ready: function () { - $(window).on("hashchange", this.parse_hash); - this.connect(); - - SvelteComponents.registerControllerMethods({ - dispatch: (...args) => this.$dispatch(...args) - }); - }, - - methods: { - block_error_dialog: function () { - this.errorTimeoutStart = Date.now(); - this.errorShow = false; - }, - - toggle_video: function (e) { - if (this.video_size == "small") this.video_size = "large"; - else if (this.video_size == "large") this.video_size = "small"; - cookie.set("video-size", this.video_size); - }, - - toggle_crosshair: function (e) { - e.preventDefault(); - this.crosshair = !this.crosshair; - cookie.set("crosshair", this.crosshair); - }, - - estop: function () { - if (this.state.xx == "ESTOPPED") api.put("clear"); - else api.put("estop"); - }, - - upgrade_confirmed: async function () { - this.confirmUpgrade = false; - - try { - await api.put("upgrade"); - this.firmwareUpgrading = true; - } catch (err) { - api.alert("Error during upgrade."); - console.error("Error during upgrade", err); - } - }, - - upload_confirmed: function () { - this.confirmUpload = false; - - const form = new FormData(); - form.append("firmware", this.firmware); - - $.ajax({ - url: "/api/firmware/update", - type: "PUT", - data: form, - cache: false, - contentType: false, - processData: false, - }) - .success( - function () { - this.firmwareUpgrading = true; - }.bind(this) - ) - .error( - function (err) { - api.alert("Firmware update failed"); - console.error("Firmware update failed", err); - }.bind(this) - ); - }, - - show_upgrade: function () { - if (!this.latestVersion) { - return false; - } - - return is_newer_version(this.config.version, this.latestVersion); - }, - - showShutdownDialog: function () { - SvelteComponents.showDialog("Shutdown"); - }, - - update: async function () { - const config = await api.get("config/load"); - - update_object(this.config, config, true); - this.parse_hash(); - - if (!this.checkedUpgrade) { - this.checkedUpgrade = true; - - var check = this.config.admin["auto-check-upgrade"]; - if (typeof check == "undefined" || check) this.$emit("check"); - } - - SvelteComponents.handleConfigUpdate(this.config); - }, - - connect: function () { - this.sock = new Sock(`//${location.host}/sockjs`); - - this.sock.onmessage = (e) => { - if (typeof e.data != "object") { - return; - } - - if ("log" in e.data) { - if (e.data.log.msg !== "Switch not found") { - this.$broadcast("log", e.data.log); - } - } - - // Check for session ID change on controller - if ("sid" in e.data) { - if (typeof this.sid == "undefined") { - this.sid = e.data.sid; - } else if (this.sid != e.data.sid) { - if ( - typeof this.hostname !== "undefined" && - location.hostname !== "localhost" - ) { - location.hostname = this.hostname; + error: function (msg) { + // Honor user error blocking + if (Date.now() - this.errorTimeoutStart < this.errorTimeout * 1000) { + return; } - location.reload(); - } - } + // Wait at least 1 sec to pop up repeated errors + if (1 < msg.repeat && Date.now() - msg.ts < 1000) { + return; + } - update_object(this.state, e.data, false); - - SvelteComponents.handleControllerStateUpdate(this.state); - - delete this.state.log; - - this.$broadcast("update"); - }; - - this.sock.onopen = () => { - this.status = "connected"; - this.$emit(this.status); - this.$broadcast(this.status); - }; - - this.sock.onclose = () => { - this.status = "disconnected"; - this.$emit(this.status); - this.$broadcast(this.status); - }; + // Popup error dialog + this.errorShow = true; + this.errorMessage = msg.msg; + }, }, - parse_hash: function () { - var hash = location.hash.substr(1); + computed: { + popupMessages: function () { + const msgs = []; - if (!hash.trim().length) { - location.hash = "control"; - return; - } + for (let i = 0; i < this.state.messages.length; i++) { + const text = this.state.messages[i].text; + if (!/^#/.test(text)) { + msgs.push(text); + } + } - var parts = hash.split(":"); - - if (parts.length == 2) this.index = parts[1]; - - this.currentView = parts[0]; + return msgs; + }, }, - save: async function () { - const selected_tool = this.config.tool["selected-tool"]; - const saveModbus = - selected_tool !== "pwm" && - selected_tool !== "laser" && - selected_tool !== "router"; - const settings = { - ["tool"]: { ...this.config.tool }, - ["pwm-spindle"]: { ...this.config["pwm-spindle"] }, - ["modbus-spindle"]: saveModbus - ? { ...this.config["modbus-spindle"] } - : undefined, - }; - delete settings.tool["tool-type"]; + ready: function () { + $(window).on("hashchange", this.parse_hash); + this.connect(); - this.config["selected-tool-settings"][selected_tool] = settings; - - try { - await api.put("config/save", this.config); - this.modified = false; - } catch (error) { - api.alert("Save failed", error); - } + SvelteComponents.registerControllerMethods({ + dispatch: (...args) => this.$dispatch(...args) + }); }, - close_messages: function (action) { - if (action == "stop") api.put("stop"); - if (action == "continue") api.put("unpause"); + methods: { + block_error_dialog: function () { + this.errorTimeoutStart = Date.now(); + this.errorShow = false; + }, - // Acknowledge messages - if (this.state.messages.length) { - var id = this.state.messages.slice(-1)[0].id; - api.put("message/" + id + "/ack"); - } + toggle_video: function () { + if (this.video_size == "small") { + this.video_size = "large"; + } else if (this.video_size == "large") { + this.video_size = "small"; + } + cookie.set("video-size", this.video_size); + }, + + toggle_crosshair: function (e) { + e.preventDefault(); + this.crosshair = !this.crosshair; + cookie.set("crosshair", this.crosshair); + }, + + estop: function () { + if (this.state.xx == "ESTOPPED") { + api.put("clear"); + } else { + api.put("estop"); + } + }, + + upgrade_confirmed: async function () { + this.confirmUpgrade = false; + + try { + await api.put("upgrade"); + this.firmwareUpgrading = true; + } catch (err) { + api.alert("Error during upgrade."); + console.error("Error during upgrade", err); + } + }, + + upload_confirmed: function () { + this.confirmUpload = false; + + const form = new FormData(); + form.append("firmware", this.firmware); + + $.ajax({ + url: "/api/firmware/update", + type: "PUT", + data: form, + cache: false, + contentType: false, + processData: false, + }) + .success( + function () { + this.firmwareUpgrading = true; + }.bind(this) + ) + .error( + function (err) { + api.alert("Firmware update failed"); + console.error("Firmware update failed", err); + }.bind(this) + ); + }, + + show_upgrade: function () { + if (!this.latestVersion) { + return false; + } + + return is_newer_version(this.config.version, this.latestVersion); + }, + + showShutdownDialog: function () { + SvelteComponents.showDialog("Shutdown"); + }, + + update: async function () { + const config = await api.get("config/load"); + + update_object(this.config, config, true); + this.parse_hash(); + + if (!this.checkedUpgrade) { + this.checkedUpgrade = true; + + const check = this.config.admin["auto-check-upgrade"]; + if (typeof check == "undefined" || check) { + this.$emit("check"); + } + } + + SvelteComponents.handleConfigUpdate(this.config); + }, + + connect: function () { + this.sock = new Sock(`//${location.host}/sockjs`); + + this.sock.onmessage = (e) => { + if (typeof e.data != "object") { + return; + } + + if ("log" in e.data) { + if (e.data.log.msg !== "Switch not found") { + this.$broadcast("log", e.data.log); + } + } + + // Check for session ID change on controller + if ("sid" in e.data) { + if (typeof this.sid == "undefined") { + this.sid = e.data.sid; + } else if (this.sid != e.data.sid) { + if (this.hostname && location.hostname !== "localhost") { + location.hostname = this.hostname; + } + + location.reload(); + } + } + + update_object(this.state, e.data, false); + + SvelteComponents.handleControllerStateUpdate(this.state); + + delete this.state.log; + + this.$broadcast("update"); + }; + + this.sock.onopen = () => { + this.status = "connected"; + this.$emit(this.status); + this.$broadcast(this.status); + }; + + this.sock.onclose = () => { + this.status = "disconnected"; + this.$emit(this.status); + this.$broadcast(this.status); + }; + }, + + parse_hash: function () { + const hash = location.hash.substr(1); + + if (!hash.trim().length) { + location.hash = "control"; + return; + } + + const parts = hash.split(":"); + + if (parts.length == 2) { + this.index = parts[1]; + } + + this.currentView = parts[0]; + }, + + save: async function () { + const selected_tool = this.config.tool["selected-tool"]; + const saveModbus = + selected_tool !== "pwm" && + selected_tool !== "laser" && + selected_tool !== "router"; + const settings = { + ["tool"]: { ...this.config.tool }, + ["pwm-spindle"]: { ...this.config["pwm-spindle"] }, + ["modbus-spindle"]: saveModbus + ? { ...this.config["modbus-spindle"] } + : undefined, + }; + delete settings.tool["tool-type"]; + + this.config["selected-tool-settings"][selected_tool] = settings; + + try { + await api.put("config/save", this.config); + this.modified = false; + } catch (error) { + api.alert("Save failed", error); + } + }, + + close_messages: function (action) { + if (action == "stop") { + api.put("stop"); + } + + if (action == "continue") { + api.put("unpause"); + } + + // Acknowledge messages + if (this.state.messages.length) { + const id = this.state.messages.slice(-1)[0].id; + api.put("message/" + id + "/ack"); + } + }, }, - }, }); diff --git a/src/js/axis-control.js b/src/js/axis-control.js index c6fa5c3..34a60b0 100644 --- a/src/js/axis-control.js +++ b/src/js/axis-control.js @@ -1,65 +1,37 @@ -/******************************************************************************\ - - This file is part of the Buildbotics firmware. - - Copyright (c) 2015 - 2018, Buildbotics LLC - All rights reserved. - - This file ("the software") is free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License, - version 2 as published by the Free Software Foundation. You should - have received a copy of the GNU General Public License, version 2 - along with the software. If not, see . - - The software is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the software. If not, see - . - - For information regarding this software email: - "Joseph Coffland" - -\******************************************************************************/ - -'use strict' - +"use strict"; module.exports = { - template: '#axis-control-template', - props: ['axes', 'colors', 'enabled', 'adjust', 'step'], + template: "#axis-control-template", + props: ["axes", "colors", "enabled", "adjust", "step"], + methods: { + jog: function (axis, ring, direction) { + const value = direction * this.value(ring); + this.$dispatch(this.step ? "step" : "jog", this.axes[axis], value); + }, - methods: { - jog: function (axis, ring, direction) { - var value = direction * this.value(ring); - this.$dispatch(this.step ? 'step' : 'jog', this.axes[axis], value); - }, + back2zero: function(axis0,axis1) { + this.$dispatch("back2zero",this.axes[axis0],this.axes[axis1]); + }, - back2zero: function(axis0,axis1) { - this.$dispatch('back2zero',this.axes[axis0],this.axes[axis1]) - }, + release: function (axis) { + if (!this.step) { + this.$dispatch("jog", this.axes[axis], 0); + } + }, + value: function (ring) { + const adjust = [0.01, 0.1, 1][this.adjust]; + if (this.step) { + return adjust * [0.1, 1, 10, 100][ring]; + } + return adjust * [0.1, 0.25, 0.5, 1][ring]; + }, - release: function (axis) { - if (!this.step) this.$dispatch('jog', this.axes[axis], 0) - }, - - - value: function (ring) { - var adjust = [0.01, 0.1, 1][this.adjust]; - if (this.step) return adjust * [0.1, 1, 10, 100][ring]; - return adjust * [0.1, 0.25, 0.5, 1][ring]; - }, - - - text: function (ring) { - var value = this.value(ring) * (this.step ? 1 : 100); - value = parseFloat(value.toFixed(3)); - return value + (this.step ? '' : '%'); + text: function (ring) { + let value = this.value(ring) * (this.step ? 1 : 100); + value = parseFloat(value.toFixed(3)); + return value + (this.step ? "" : "%"); + } } - } -} +}; diff --git a/src/js/axis-vars.js b/src/js/axis-vars.js index 0f10539..2846782 100644 --- a/src/js/axis-vars.js +++ b/src/js/axis-vars.js @@ -1,194 +1,254 @@ -'use strict' +"use strict"; module.exports = { - props: ['state', 'config'], + props: ["state", "config"], - computed: { - metric: function () { this.$root.display_units === "METRIC" }, - x: function () { return this._compute_axis('x') }, - y: function () { return this._compute_axis('y') }, - z: function () { return this._compute_axis('z') }, - a: function () { return this._compute_axis('a') }, - b: function () { return this._compute_axis('b') }, - c: function () { return this._compute_axis('c') }, - axes: function () { return this._compute_axes() } - }, + computed: { + metric: function () { + return this.$root.display_units === "METRIC"; + }, - methods: { - _convert_length: function (value) { - return this.metric - ? value - : value / 25.4; - }, + x: function () { + return this._compute_axis("x"); + }, - _length_str: function (value) { - return this._convert_length(value).toLocaleString() + - (this.metric ? ' mm' : ' in'); - }, + y: function () { + return this._compute_axis("y"); + }, - _compute_axis: function (axis) { - var abs = this.state[axis + 'p'] || 0; - var off = this.state['offset_' + axis]; - var motor_id = this._get_motor_id(axis); - var motor = motor_id == -1 ? {} : this.config.motors[motor_id]; - var enabled = typeof motor.enabled != 'undefined' && motor.enabled; - var homingMode = motor['homing-mode'] - var homed = this.state[motor_id + 'homed']; - var min = this.state[motor_id + 'tn']; - var max = this.state[motor_id + 'tm']; - var dim = max - min; - var pathMin = this.state['path_min_' + axis]; - var pathMax = this.state['path_max_' + axis]; - var pathDim = pathMax - pathMin; - var under = pathMin + off < min; - var over = max < pathMax + off; - var klass = (homed ? 'homed' : 'unhomed') + ' axis-' + axis; - var state = 'UNHOMED'; - var icon = 'question-circle'; - var fault = this.state[motor_id + 'df'] & 0x1f; - var shutdown = this.state.power_shutdown; - var title; - var ticon = 'question-circle'; - var tstate = 'NO FILE'; - var toolmsg; - var tklass = (homed ? 'homed' : 'unhomed') + ' axis-' + axis; + z: function () { + return this._compute_axis("z"); + }, - if (fault || shutdown) { - state = shutdown ? 'SHUTDOWN' : 'FAULT'; - klass += ' error'; - icon = 'exclamation-circle'; - } else if (homed) { - state = 'HOMED'; - icon = 'check-circle'; - } + a: function () { + return this._compute_axis("a"); + }, - if (0 < dim && dim < pathDim) { - tstate = 'NO FIT'; - tklass += ' error'; - ticon = 'ban'; - } else { - if (over || under) { - tstate = over ? 'OVER' : 'UNDER'; - tklass += ' warn'; - ticon = 'exclamation-circle'; - } else { - tstate = 'OK'; - ticon = 'check-circle'; + b: function () { + return this._compute_axis("b"); + }, + + c: function () { + return this._compute_axis("c"); + }, + + axes: function () { + return this._compute_axes(); } - } - - switch (state) { - case 'UNHOMED': title = 'Click the home button to home axis.'; break; - case 'HOMED': title = 'Axis successfuly homed.'; break; - case 'FAULT': - title = 'Motor driver fault. A potentially damaging electrical ' + - 'condition was detected and the motor driver was shutdown. ' + - 'Please power down the controller and check your motor cabling. ' + - 'See the "Motor Faults" table on the "Indicators" tab for more ' + - 'information.'; - break; - - case 'SHUTDOWN': - title = 'Motor power fault. All motors in shutdown. ' + - 'See the "Power Faults" table on the "Indicators" tab for more ' + - 'information. Reboot controller to reset.'; - } - - switch (tstate) { - case 'OVER': - toolmsg = 'Caution: The current tool path file would move ' + - this._length_str(pathMax + off - max) + ' above axis limit with the current offset.'; - break; - - case 'UNDER': - toolmsg = 'Caution: The current tool path file would move ' + - this._length_str(min - pathMin - off) + ' below limit with the current offset.'; - break; - - case 'NO FIT': - toolmsg = 'Warning: The current tool path dimensions (' + - this._length_str(pathDim) + ') exceed axis dimensions (' + - this._length_str(dim) + ') by ' + - this._length_str(pathDim - dim) + '.'; - break; - - default: - toolmsg = 'Tool path ' + axis + ' dimensions OK.'; - break; - } - - return { - pos: abs - off, - abs: abs, - off: off, - min: min, - max: max, - dim: dim, - pathMin: pathMin, - pathMax: pathMax, - pathDim: pathDim, - motor: motor_id, - enabled: enabled, - homingMode: homingMode, - homed: homed, - klass: klass, - state: state, - icon: icon, - title: title, - ticon: ticon, - tstate: tstate, - toolmsg: toolmsg, - tklass: tklass - } }, - _get_motor_id: function (axis) { - for (var i = 0; i < this.config.motors.length; i++) { - var motor = this.config.motors[i]; - if (motor.axis.toLowerCase() == axis) return i; - } + methods: { + _convert_length: function (value) { + return this.metric + ? value + : value / 25.4; + }, - return -1; - }, + _length_str: function (value) { + return this._convert_length(value).toLocaleString() + (this.metric ? " mm" : " in"); + }, - _compute_axes: function () { - var homed = false; + _compute_axis: function (axis) { + const abs = this.state[`${axis}p`] || 0; + const off = this.state[`offset_${axis}`]; + const motor_id = this._get_motor_id(axis); + const motor = motor_id == -1 ? {} : this.config.motors[motor_id]; + const enabled = typeof motor.enabled != "undefined" && motor.enabled; + const homingMode = motor["homing-mode"]; + const homed = this.state[`${motor_id}homed`]; + const min = this.state[`${motor_id}tn`]; + const max = this.state[`${motor_id}tm`]; + const dim = max - min; + const pathMin = this.state[`path_min_${axis}`]; + const pathMax = this.state[`path_max_${axis}`]; + const pathDim = pathMax - pathMin; + const under = pathMin + off < min; + const over = max < pathMax + off; + let klass = `${homed ? "homed" : "unhomed"} axis-${axis}`; + let state = "UNHOMED"; + let icon = "question-circle"; + const fault = this.state[`${motor_id}df`] & 0x1f; + const shutdown = this.state.power_shutdown; + let title; + let ticon = "question-circle"; + let tstate = "NO FILE"; + let toolmsg; + let tklass = `${homed ? "homed" : "unhomed"} axis-${axis}`; - for (var name of 'xyzabc') { - var axis = this[name]; + if (fault || shutdown) { + state = shutdown ? "SHUTDOWN" : "FAULT"; + klass += " error"; + icon = "exclamation-circle"; + } else if (homed) { + state = "HOMED"; + icon = "check-circle"; + } - if (!axis.enabled) continue - if (!axis.homed) { homed = false; break } - homed = true; - } + if (0 < dim && dim < pathDim) { + tstate = "NO FIT"; + tklass += " error"; + ticon = "ban"; + } else { + if (over || under) { + tstate = over ? "OVER" : "UNDER"; + tklass += " warn"; + ticon = "exclamation-circle"; + } else { + tstate = "OK"; + ticon = "check-circle"; + } + } - var error = false; - var warn = false; + switch (state) { + case "UNHOMED": + title = "Click the home button to home axis."; + break; - if (homed) - for (name of 'xyzabc') { - axis = this[name]; + case "HOMED": + title = "Axis successfuly homed."; + break; - if (!axis.enabled) continue; - if (axis.klass.indexOf('error') != -1) error = true; - if (axis.klass.indexOf('warn') != -1) warn = true; + case "FAULT": + title = [ + `Motor driver fault. A potentially damaging electrical`, + `condition was detected and the motor driver was shutdown.`, + `Please power down the controller and check your motor cabling.`, + `See the "Motor Faults" table on the "Indicators" tab for more`, + `information.`, + ].join(" "); + break; + + case "SHUTDOWN": + title = [ + `Motor power fault. All motors in shutdown.`, + `See the "Power Faults" table on the "Indicators" tab for more`, + `information. Reboot controller to reset.` + ].join(" "); + break; + } + + switch (tstate) { + case "OVER": + toolmsg = [ + `Caution: The current tool path file would move`, + `${this._length_str(pathMax + off - max)}`, + `above axis limit with the current offset.` + ].join(" "); + break; + + case "UNDER": + toolmsg = [ + `Caution: The current tool path file would move`, + `${this._length_str(min - pathMin - off)}`, + `below limit with the current offset.` + ].join(" "); + break; + + case "NO FIT": + toolmsg = [ + `Warning: The current tool path dimensions`, + `(${this._length_str(pathDim)}) exceed axis dimensions`, + `(${this._length_str(dim)}) by ${this._length_str(pathDim - dim)}.` + ].join(" "); + break; + + default: + toolmsg = `Tool path ${axis} dimensions OK.`; + break; + } + + return { + pos: abs - off, + abs: abs, + off: off, + min: min, + max: max, + dim: dim, + pathMin: pathMin, + pathMax: pathMax, + pathDim: pathDim, + motor: motor_id, + enabled: enabled, + homingMode: homingMode, + homed: homed, + klass: klass, + state: state, + icon: icon, + title: title, + ticon: ticon, + tstate: tstate, + toolmsg: toolmsg, + tklass: tklass + }; + }, + + _get_motor_id: function (axis) { + for (let i = 0; i < this.config.motors.length; i++) { + const motor = this.config.motors[i]; + if (motor.axis.toLowerCase() == axis) { + return i; + } + } + + return -1; + }, + + _compute_axes: function () { + let homed = false; + + for (const name of "xyzabc") { + const axis = this[name]; + + if (!axis.enabled) { + continue; + } + + if (!axis.homed) { + homed = false; break; + } + + homed = true; + } + + let error = false; + let warn = false; + + if (homed) { + for (const name of "xyzabc") { + const axis = this[name]; + + if (!axis.enabled) { + continue; + } + + if (axis.klass.indexOf("error") != -1) { + error = true; + } + + if (axis.klass.indexOf("warn") != -1) { + warn = true; + } + } + } + + let klass = homed ? "homed" : "unhomed"; + if (error) { + klass += " error"; + } else if (warn) { + klass += " warn"; + } + + if (!homed && this.ask_home) { + this.ask_home = false; + SvelteComponents.showDialog("HomeMachine", { + home: () => this.home() + }); + } + + return { + homed: homed, + klass: klass + }; } - - var klass = homed ? 'homed' : 'unhomed'; - if (error) klass += ' error'; - else if (warn) klass += ' warn'; - - if (!homed && this.ask_home) { - this.ask_home = false; - SvelteComponents.showDialog("HomeMachine", { - home: () => this.home() - }); - } - - return { - homed: homed, - klass: klass - } } - } -} +}; diff --git a/src/js/console.js b/src/js/console.js index 5607bba..63772f9 100644 --- a/src/js/console.js +++ b/src/js/console.js @@ -1,87 +1,72 @@ -/******************************************************************************\ - - This file is part of the Buildbotics firmware. - - Copyright (c) 2015 - 2018, Buildbotics LLC - All rights reserved. - - This file ("the software") is free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License, - version 2 as published by the Free Software Foundation. You should - have received a copy of the GNU General Public License, version 2 - along with the software. If not, see . - - The software is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the software. If not, see - . - - For information regarding this software email: - "Joseph Coffland" - -\******************************************************************************/ - -'use strict' - +"use strict"; function _msg_equal(a, b) { - return a.level == b.level && a.source == b.source && a.where == b.where && - a.msg == b.msg; + return a.level == b.level + && a.source == b.source + && a.where == b.where + &&a.msg == b.msg; } - // Shared among all instances -var messages = []; - +const messages = []; module.exports = { - template: '#console-template', + template: "#console-template", + data: function () { + return { + messages + }; + }, - data: function () { - return {messages: messages} - }, + events: { + log: function (msg) { + // There may be multiple instances of this module so ignore messages + // that have already been processed. + if (msg.logged) { + return; + } + msg.logged = true; - events: { - log: function (msg) { - // There may be multiple instances of this module so ignore messages - // that have already been processed. - if (msg.logged) return; - msg.logged = true; + // Make sure we have a message level + msg.level = msg.level || "info"; - // Make sure we have a message level - msg.level = msg.level || 'info'; + // Add to message log and count and collapse repeats + const repeat = messages.length && _msg_equal(msg, messages[0]); + if (repeat) { + messages[0].repeat++; + } else { + msg.repeat = msg.repeat || 1; + messages.unshift(msg); + while (256 < messages.length) { + messages.pop(); + } + } + msg.ts = Date.now(); - // Add to message log and count and collapse repeats - var repeat = messages.length && _msg_equal(msg, messages[0]); - if (repeat) messages[0].repeat++; - else { - msg.repeat = msg.repeat || 1; - messages.unshift(msg); - while (256 < messages.length) messages.pop(); - } - msg.ts = Date.now(); + // Write message to browser console for debugging + const text = JSON.stringify(msg); + if (msg.level == "error" || msg.level == "critical") { + console.error(text); + } else if (msg.level == "warning") { + console.warn(text); + } else if (msg.level == "debug" && console.debug) { + console.debug(text); + } else { + console.log(text); + } - // Write message to browser console for debugging - var text = JSON.stringify(msg); - if (msg.level == 'error' || msg.level == 'critical') console.error(text); - else if (msg.level == 'warning') console.warn(text); - else if (msg.level == 'debug' && console.debug) console.debug(text); - else console.log(text); + // Event on errors + if (msg.level == "error" || msg.level == "critical") { + this.$dispatch("error", msg); + } + } + }, - // Event on errors - if (msg.level == 'error' || msg.level == 'critical') - this.$dispatch('error', msg); + methods: { + clear: function () { + messages.splice(0, messages.length); + }, } - }, - - - methods: { - clear: function () {messages.splice(0, messages.length);}, - } -} +}; diff --git a/src/js/control-view.js b/src/js/control-view.js index 57f60ac..ebd76eb 100644 --- a/src/js/control-view.js +++ b/src/js/control-view.js @@ -1,503 +1,501 @@ -'use strict' +"use strict"; -var api = require('./api'); -var cookie = require('./cookie')('bbctrl-'); +const api = require("./api"); +const cookie = require("./cookie")("bbctrl-"); module.exports = { - template: '#control-view-template', - props: ['config', 'template', 'state'], + template: "#control-view-template", + props: ["config", "template", "state"], - data: function () { - return { - current_time: "", - mach_units: this.$root.state.metric ? "METRIC" : "IMPERIAL", - mdi: '', - last_file: undefined, - last_file_time: undefined, - toolpath: {}, - toolpath_progress: 0, - axes: 'xyzabc', - history: [], - speed_override: 1, - feed_override: 1, - jog_incr_amounts: { - "METRIC": { - fine: 0.1, - small: 1.0, - medium: 10, - large: 100, + data: function () { + return { + current_time: "", + mach_units: this.$root.state.metric ? "METRIC" : "IMPERIAL", + mdi: "", + last_file: undefined, + last_file_time: undefined, + toolpath: {}, + toolpath_progress: 0, + axes: "xyzabc", + history: [], + speed_override: 1, + feed_override: 1, + jog_incr_amounts: { + "METRIC": { + fine: 0.1, + small: 1.0, + medium: 10, + large: 100, + }, + "IMPERIAL": { + fine: 0.005, + small: 0.05, + medium: 0.5, + large: 5, + } + }, + jog_incr: localStorage.getItem("jog_incr") || "small", + jog_step: cookie.get_bool("jog-step"), + jog_adjust: parseInt(cookie.get("jog-adjust", 2)), + deleteGCode: false, + tab: "auto", + ask_home: true, + showGcodeMessage: false + }; + }, + + components: { + "axis-control": require("./axis-control"), + "path-viewer": require("./path-viewer"), + "gcode-viewer": require("./gcode-viewer") + }, + + watch: { + jog_incr: function (value) { + localStorage.setItem("jog_incr", value); }, - "IMPERIAL": { - fine: 0.005, - small: 0.05, - medium: 0.5, - large: 5, - } - }, - jog_incr: localStorage.getItem("jog_incr") || 'small', - jog_step: cookie.get_bool('jog-step'), - jog_adjust: parseInt(cookie.get('jog-adjust', 2)), - deleteGCode: false, - tab: 'auto', - ask_home: true, - showGcodeMessage: false - } - }, - components: { - 'axis-control': require('./axis-control'), - 'path-viewer': require('./path-viewer'), - 'gcode-viewer': require('./gcode-viewer') - }, + "state.metric": { + handler: function (metric) { + this.mach_units = metric + ? "METRIC" + : "IMPERIAL"; + }, + immediate: true + }, - watch: { - jog_incr: function (value) { - localStorage.setItem("jog_incr", value); - }, - - 'state.metric': { - handler: function (metric) { - this.mach_units = metric - ? 'METRIC' - : 'IMPERIAL'; - }, - immediate: true - }, - - 'state.line': function () { - if (this.mach_state != 'HOMING') { - this.$broadcast('gcode-line', this.state.line); - } - }, - - 'state.selected_time': function () { - this.load(); - }, - - jog_step: function () { - cookie.set_bool('jog-step', this.jog_step); - }, - - jog_adjust: function () { - cookie.set('jog-adjust', this.jog_adjust); - } - }, - - computed: { - display_units: { - cache: false, - get: function () { - return this.$root.display_units; - }, - set: function (value) { - this.$root.display_units = value; - } - }, - - metric: function () { - return this.display_units === "METRIC"; - }, - - mach_state: function () { - var cycle = this.state.cycle; - var state = this.state.xx; - - if (typeof cycle != 'undefined' && state != 'ESTOPPED' && - (cycle == 'jogging' || cycle == 'homing')) { - return cycle.toUpperCase(); - } - - return state || '' - }, - - pause_reason: function () { - return this.state.pr - }, - - is_running: function () { - return this.mach_state == 'RUNNING' || this.mach_state == 'HOMING'; - }, - - is_stopping: function () { - return this.mach_state == 'STOPPING' - }, - - is_holding: function () { - return this.mach_state == 'HOLDING' - }, - - is_ready: function () { - return this.mach_state == 'READY' - }, - - is_idle: function () { - return this.state.cycle == 'idle' - }, - - is_paused: function () { - return this.is_holding && - (this.pause_reason == 'User pause' || - this.pause_reason == 'Program pause') - }, - - can_mdi: function () { - return this.is_idle || this.state.cycle == 'mdi' - }, - - can_set_axis: function () { - return this.is_idle - // TODO allow setting axis position during pause - return this.is_idle || this.is_paused - }, - - message: function () { - if (this.mach_state == 'ESTOPPED') { - return this.state.er; - } - - if (this.mach_state == 'HOLDING') { - return this.state.pr; - } - - if (this.state.messages.length) { - return this.state.messages.slice(-1)[0].text; - } - - return ''; - }, - - highlight_state: function () { - return this.mach_state == 'ESTOPPED' || this.mach_state == 'HOLDING'; - }, - - plan_time: function () { - return this.state.plan_time - }, - - plan_time_remaining: function () { - if (!(this.is_stopping || this.is_running || this.is_holding)) { - return 0; - } - - return this.toolpath.time - this.plan_time - }, - - eta: function () { - if (this.mach_state != 'RUNNING') { - return ''; - } - - var remaining = this.plan_time_remaining; - var d = new Date(); - d.setSeconds(d.getSeconds() + remaining); - return d.toLocaleString(); - }, - - progress: function () { - if (!this.toolpath.time || this.is_ready) { - return 0; - } - - var p = this.plan_time / this.toolpath.time; - return p < 1 ? p : 1; - } - }, - - events: { - jog: function (axis, power) { - var data = { ts: new Date().getTime() }; - data[axis] = power; - api.put('jog', data); - }, - - back2zero: function (axis0, axis1) { - this.send(`G0 ${axis0}0 ${axis1}0`); - }, - - step: function (axis, value) { - this.send(` - M70 - G91 - G0 ${axis}${value} - M72 - `); - }, - }, - - ready: function () { - this.load(); - - setInterval(() => { - this.current_time = new Date().toLocaleTimeString(); - }, 1000); - - SvelteComponents.registerControllerMethods({ - stop: (...args) => this.stop(...args), - send: (...args) => this.send(...args), - isAxisHomed: (axis) => this[axis].homed, - unhome: (...args) => this.unhome(...args), - set_position: (...args) => this.set_position(...args), - set_home: (...args) => this.set_home(...args) - }); - }, - - methods: { - getJogIncrStyle(value) { - const weight = `font-weight:${this.jog_incr === value ? 'bold' : 'normal'}`; - const color = this.jog_incr === value ? "color:#0078e7" : ""; - - return [weight, color].join(';'); - }, - - jog_fn: function (x_jog, y_jog, z_jog, a_jog) { - const amount = this.jog_incr_amounts[this.display_units][this.jog_incr]; - - var xcmd = "X" + x_jog * amount; - var ycmd = "Y" + y_jog * amount; - var zcmd = "Z" + z_jog * amount; - var acmd = "A" + a_jog * amount; - - this.send(` - G91 - ${this.metric ? "G21" : "G20"} - G0 ${xcmd}${ycmd}${zcmd}${acmd} - `); - }, - - send: function (msg) { - this.$dispatch('send', msg) - }, - - load: function () { - var file_time = this.state.selected_time; - var file = this.state.selected; - if (this.last_file == file && this.last_file_time == file_time) { - return; - } - - this.last_file = file; - this.last_file_time = file_time; - - this.$broadcast('gcode-load', file); - this.$broadcast('gcode-line', this.state.line); - this.toolpath_progress = 0; - this.load_toolpath(file, file_time); - }, - - load_toolpath: async function (file, file_time) { - this.toolpath = {}; - - if (!file || this.last_file_time != file_time) { - return; - } - - this.showGcodeMessage = true; - - while (this.showGcodeMessage) { - const toolpath = await api.get(`path/${file}`); - this.toolpath_progress = toolpath.progress; - - if (toolpath.progress === 1 || typeof toolpath.progress == 'undefined') { - this.showGcodeMessage = false - - if (toolpath.bounds) { - toolpath.filename = file; - this.toolpath_progress = 1; - this.toolpath = toolpath; - - const state = this.$root.state; - for (let axis of 'xyzabc') { - Vue.set(state, 'path_min_' + axis, toolpath.bounds.min[axis]); - Vue.set(state, 'path_max_' + axis, toolpath.bounds.max[axis]); + "state.line": function () { + if (this.mach_state != "HOMING") { + this.$broadcast("gcode-line", this.state.line); } - } + }, + + "state.selected_time": function () { + this.load(); + }, + + jog_step: function () { + cookie.set_bool("jog-step", this.jog_step); + }, + + jog_adjust: function () { + cookie.set("jog-adjust", this.jog_adjust); } - } }, - submit_mdi: function () { - this.send(this.mdi); + computed: { + display_units: { + cache: false, + get: function () { + return this.$root.display_units; + }, + set: function (value) { + this.$root.display_units = value; + } + }, - if (!this.history.length || this.history[0] != this.mdi) { - this.history.unshift(this.mdi); - } + metric: function () { + return this.display_units === "METRIC"; + }, - this.mdi = ''; - }, + mach_state: function () { + const cycle = this.state.cycle; + const state = this.state.xx; - mdi_start_pause: function () { - if (this.state.xx == 'RUNNING') { - this.pause(); - } else if (this.state.xx == 'STOPPING' || this.state.xx == 'HOLDING') { - this.unpause(); - } else { - this.submit_mdi(); - } - }, + if (state != "ESTOPPED" && (cycle == "jogging" || cycle == "homing")) { + return cycle.toUpperCase(); + } - load_history: function (index) { - this.mdi = this.history[index]; - }, + return state || ""; + }, - open: function (e) { - // If we don't reset the form the browser may cache file if name is same - // even if contents have changed - $('.gcode-file-input')[0].reset(); - $('.gcode-file-input input').click(); - }, + pause_reason: function () { + return this.state.pr; + }, - upload: async function (e) { - const files = e.target.files || e.dataTransfer.files; - if (!files.length) { - return; - } + is_running: function () { + return this.mach_state == "RUNNING" || this.mach_state == "HOMING"; + }, - const file = files[0]; + is_stopping: function () { + return this.mach_state == "STOPPING"; + }, - const extension = file.name.split(".").pop(); - switch (extension.toLowerCase()) { - case "nc": - case "ngc": - case "gcode": - case "gc": - break; + is_holding: function () { + return this.mach_state == "HOLDING"; + }, - default: - alert(`Unsupported file type: ${extension}`); - return; - } + is_ready: function () { + return this.mach_state == "READY"; + }, - SvelteComponents.showDialog("Upload", { - file, - onComplete: () => { - this.last_file_time = undefined; // Force reload - this.$broadcast('gcode-reload', file.name); + is_idle: function () { + return this.state.cycle == "idle"; + }, + + is_paused: function () { + return this.is_holding && (this.pause_reason == "User pause" || this.pause_reason == "Program pause"); + }, + + can_mdi: function () { + return this.is_idle || this.state.cycle == "mdi"; + }, + + can_set_axis: function () { + return this.is_idle; + + // TODO allow setting axis position during pause + // return this.is_idle || this.is_paused; + }, + + message: function () { + if (this.mach_state == "ESTOPPED") { + return this.state.er; + } + + if (this.mach_state == "HOLDING") { + return this.state.pr; + } + + if (this.state.messages.length) { + return this.state.messages.slice(-1)[0].text; + } + + return ""; + }, + + highlight_state: function () { + return this.mach_state == "ESTOPPED" || this.mach_state == "HOLDING"; + }, + + plan_time: function () { + return this.state.plan_time; + }, + + plan_time_remaining: function () { + if (!(this.is_stopping || this.is_running || this.is_holding)) { + return 0; + } + + return this.toolpath.time - this.plan_time; + }, + + eta: function () { + if (this.mach_state != "RUNNING") { + return ""; + } + + const remaining = this.plan_time_remaining; + const d = new Date(); + d.setSeconds(d.getSeconds() + remaining); + return d.toLocaleString(); + }, + + progress: function () { + if (!this.toolpath.time || this.is_ready) { + return 0; + } + + const p = this.plan_time / this.toolpath.time; + return Math.max(1, p); } - }); }, - delete_current: function () { - if (this.state.selected) { - api.delete('file/' + this.state.selected); - } + events: { + jog: function (axis, power) { + const data = { ts: new Date().getTime() }; + data[axis] = power; + api.put("jog", data); + }, - this.deleteGCode = false; + back2zero: function (axis0, axis1) { + this.send(`G0 ${axis0}0 ${axis1}0`); + }, + + step: function (axis, value) { + this.send(` + M70 + G91 + G0 ${axis}${value} + M72 + `); + }, }, - delete_all: function () { - api.delete('file'); - this.deleteGCode = false; + ready: function () { + this.load(); + + setInterval(() => { + this.current_time = new Date().toLocaleTimeString(); + }, 1000); + + SvelteComponents.registerControllerMethods({ + stop: (...args) => this.stop(...args), + send: (...args) => this.send(...args), + isAxisHomed: (axis) => this[axis].homed, + unhome: (...args) => this.unhome(...args), + set_position: (...args) => this.set_position(...args), + set_home: (...args) => this.set_home(...args) + }); }, - home: function (axis) { - this.ask_home = false; + methods: { + getJogIncrStyle(value) { + const weight = `font-weight:${this.jog_incr === value ? "bold" : "normal"}`; + const color = this.jog_incr === value ? "color:#0078e7" : ""; - if (typeof axis == 'undefined') { - api.put('home'); - } else if (this[axis].homingMode != 'manual') { - api.put('home/' + axis); - } else { - SvelteComponents.showDialog("ManualHomeAxis", { axis }); - } - }, + return [weight, color].join(";"); + }, - set_home: function (axis, position) { - api.put('home/' + axis + '/set', { position: parseFloat(position) }); - }, + jog_fn: function (x_jog, y_jog, z_jog, a_jog) { + const amount = this.jog_incr_amounts[this.display_units][this.jog_incr]; - unhome: function (axis) { - api.put('home/' + axis + '/clear'); - }, + const xcmd = `X${x_jog * amount}`; + const ycmd = `Y${y_jog * amount}`; + const zcmd = `Z${z_jog * amount}`; + const acmd = `A${a_jog * amount}`; - show_set_position: function (axis) { - SvelteComponents.showDialog("SetAxisPosition", { axis }); - }, + this.send(` + G91 + ${this.metric ? "G21" : "G20"} + G0 ${xcmd}${ycmd}${zcmd}${acmd} + `); + }, - showMoveToZeroDialog: function (axes) { - SvelteComponents.showDialog("MoveToZero", { axes }); - }, + send: function (msg) { + this.$dispatch("send", msg); + }, - showToolpathMessageDialog: function (axis) { - SvelteComponents.showDialog("Message", { title: this[axis].toolmsg }); - }, + load: function () { + const file_time = this.state.selected_time; + const file = this.state.selected; + if (this.last_file == file && this.last_file_time == file_time) { + return; + } - set_position: function (axis, position) { - api.put('position/' + axis, { 'position': parseFloat(position) }); - }, + this.last_file = file; + this.last_file_time = file_time; - zero_all: function () { - for (var axis of 'xyzabc') { - if (this[axis].enabled) { - this.zero(axis); + this.$broadcast("gcode-load", file); + this.$broadcast("gcode-line", this.state.line); + this.toolpath_progress = 0; + this.load_toolpath(file, file_time); + }, + + load_toolpath: async function (file, file_time) { + this.toolpath = {}; + + if (!file || this.last_file_time != file_time) { + return; + } + + this.showGcodeMessage = true; + + while (this.showGcodeMessage) { + const toolpath = await api.get(`path/${file}`); + this.toolpath_progress = toolpath.progress; + + if (toolpath.progress === 1 || typeof toolpath.progress == "undefined") { + this.showGcodeMessage = false; + + if (toolpath.bounds) { + toolpath.filename = file; + this.toolpath_progress = 1; + this.toolpath = toolpath; + + const state = this.$root.state; + for (const axis of "xyzabc") { + Vue.set(state, `path_min_${axis}`, toolpath.bounds.min[axis]); + Vue.set(state, `path_max_${axis}`, toolpath.bounds.max[axis]); + } + } + } + } + }, + + submit_mdi: function () { + this.send(this.mdi); + + if (!this.history.length || this.history[0] != this.mdi) { + this.history.unshift(this.mdi); + } + + this.mdi = ""; + }, + + mdi_start_pause: function () { + if (this.state.xx == "RUNNING") { + this.pause(); + } else if (this.state.xx == "STOPPING" || this.state.xx == "HOLDING") { + this.unpause(); + } else { + this.submit_mdi(); + } + }, + + load_history: function (index) { + this.mdi = this.history[index]; + }, + + open: function () { + // If we don't reset the form the browser may cache file if name is same + // even if contents have changed + $(".gcode-file-input")[0].reset(); + $(".gcode-file-input input").click(); + }, + + upload: async function (e) { + const files = e.target.files || e.dataTransfer.files; + if (!files.length) { + return; + } + + const file = files[0]; + + const extension = file.name.split(".").pop(); + switch (extension.toLowerCase()) { + case "nc": + case "ngc": + case "gcode": + case "gc": + break; + + default: + alert(`Unsupported file type: ${extension}`); + return; + } + + SvelteComponents.showDialog("Upload", { + file, + onComplete: () => { + this.last_file_time = undefined; // Force reload + this.$broadcast("gcode-reload", file.name); + } + }); + }, + + delete_current: function () { + if (this.state.selected) { + api.delete(`file/${this.state.selected}`); + } + + this.deleteGCode = false; + }, + + delete_all: function () { + api.delete("file"); + this.deleteGCode = false; + }, + + home: function (axis) { + this.ask_home = false; + + if (typeof axis == "undefined") { + api.put("home"); + } else if (this[axis].homingMode != "manual") { + api.put(`home/${axis}`); + } else { + SvelteComponents.showDialog("ManualHomeAxis", { axis }); + } + }, + + set_home: function (axis, position) { + api.put(`home/${axis}/set`, { position: parseFloat(position) }); + }, + + unhome: function (axis) { + api.put(`home/${axis}/clear`); + }, + + show_set_position: function (axis) { + SvelteComponents.showDialog("SetAxisPosition", { axis }); + }, + + showMoveToZeroDialog: function (axes) { + SvelteComponents.showDialog("MoveToZero", { axes }); + }, + + showToolpathMessageDialog: function (axis) { + SvelteComponents.showDialog("Message", { title: this[axis].toolmsg }); + }, + + set_position: function (axis, position) { + api.put(`position/${axis}`, { "position": parseFloat(position) }); + }, + + zero_all: function () { + for (const axis of "xyzabc") { + if (this[axis].enabled) { + this.zero(axis); + } + } + }, + + zero: function (axis) { + if (typeof axis == "undefined") { + this.zero_all(); + } else { + this.set_position(axis, 0); + } + }, + + start_pause: function () { + if (this.state.xx == "RUNNING") { + this.pause(); + } else if (this.state.xx == "STOPPING" || this.state.xx == "HOLDING") { + this.unpause(); + } else { + this.start(); + } + }, + + start: function () { + api.put("start"); + }, + + pause: function () { + api.put("pause"); + }, + + unpause: function () { + api.put("unpause"); + }, + + optional_pause: function () { + api.put("pause/optional"); + }, + + stop: function () { + api.put("stop"); + }, + + step: function () { + api.put("step"); + }, + + override_feed: function () { + api.put(`override/feed/${this.feed_override}`); + }, + + override_speed: function () { + api.put(`override/speed/${this.speed_override}`); + }, + + current: function (axis, value) { + const x = value / 32.0; + if (this.state[`${axis}pl`] == x) { + return; + } + + const data = {}; + data[`${axis}pl`] = x; + this.send(JSON.stringify(data)); + }, + + showProbeDialog: function (probeType) { + SvelteComponents.showDialog("Probe", { probeType }); } - } }, - zero: function (axis) { - if (typeof axis == 'undefined') { - this.zero_all(); - } else { - this.set_position(axis, 0); - } - }, - - start_pause: function () { - if (this.state.xx == 'RUNNING') { - this.pause(); - } else if (this.state.xx == 'STOPPING' || this.state.xx == 'HOLDING') { - this.unpause(); - } else { - this.start(); - } - }, - - start: function () { - api.put('start') - }, - - pause: function () { - api.put('pause') - }, - - unpause: function () { - api.put('unpause') - }, - - optional_pause: function () { - api.put('pause/optional') - }, - - stop: function () { - api.put('stop') - }, - - step: function () { - api.put('step') - }, - - override_feed: function () { - api.put('override/feed/' + this.feed_override) - }, - - override_speed: function () { - api.put('override/speed/' + this.speed_override) - }, - - current: function (axis, value) { - var x = value / 32.0; - if (this.state[axis + 'pl'] == x) { - return; - } - - var data = {}; - data[axis + 'pl'] = x; - this.send(JSON.stringify(data)); - }, - - showProbeDialog: function (probeType) { - SvelteComponents.showDialog("Probe", { probeType }); - } - }, - - mixins: [require('./axis-vars')] -} + mixins: [require("./axis-vars")] +}; diff --git a/src/js/cookie.js b/src/js/cookie.js index 6244436..2342852 100644 --- a/src/js/cookie.js +++ b/src/js/cookie.js @@ -1,69 +1,49 @@ -/******************************************************************************\ - - Copyright 2018. Buildbotics LLC - All Rights Reserved. - - For information regarding this software email: - Joseph Coffland - joseph@buildbotics.com - - This software is free software: you clan redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation, either version 2.1 of - the License, or (at your option) any later version. - - This software is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the C! library. If not, see - . - -\******************************************************************************/ - -'use strict' - +"use strict"; module.exports = function (prefix) { - if (typeof prefix == 'undefined') prefix = ''; - - var cookie = { - get: function (name, defaultValue) { - var decodedCookie = decodeURIComponent(document.cookie); - var ca = decodedCookie.split(';'); - name = prefix + name + '='; - - for (var i = 0; i < ca.length; i++) { - var c = ca[i]; - while (c.charAt(0) == ' ') c = c.substring(1); - if (!c.indexOf(name)) return c.substring(name.length, c.length); - } - - return defaultValue; - }, - - - set: function (name, value, days) { - var offset = 2147483647; // Max value - if (typeof days != 'undefined') offset = days * 24 * 60 * 60 * 1000; - var d = new Date(); - d.setTime(d.getTime() + offset); - var expires = 'expires=' + d.toUTCString(); - document.cookie = prefix + name + '=' + value + ';' + expires + ';path=/'; - }, - - - set_bool: function (name, value) { - cookie.set(name, value ? 'true' : 'false'); - }, - - - get_bool: function (name, defaultValue) { - return cookie.get(name, defaultValue ? 'true' : 'false') == 'true'; + if (typeof prefix == "undefined") { + prefix = ""; } - } - return cookie; -} + const cookie = { + get: function (name, defaultValue) { + const decodedCookie = decodeURIComponent(document.cookie); + const ca = decodedCookie.split(";"); + name = `${prefix + name}=`; + + for (let i = 0; i < ca.length; i++) { + let c = ca[i]; + while (c.charAt(0) == " ") { + c = c.substring(1); + } + if (!c.indexOf(name)) { + return c.substring(name.length, c.length); + } + } + + return defaultValue; + }, + + set: function (name, value, days) { + let offset = 2147483647; // Max value + if (typeof days != "undefined") { + offset = days * 24 * 60 * 60 * 1000; + } + + const d = new Date(); + d.setTime(d.getTime() + offset); + const expires = `expires=${d.toUTCString()}`; + document.cookie = `${prefix}${name}=${value};${expires};path=/`; + }, + + set_bool: function (name, value) { + cookie.set(name, value ? "true" : "false"); + }, + + get_bool: function (name, defaultValue) { + return cookie.get(name, defaultValue ? "true" : "false") == "true"; + } + }; + + return cookie; +}; diff --git a/src/js/gcode-viewer.js b/src/js/gcode-viewer.js index 633a8d5..f26d1d3 100644 --- a/src/js/gcode-viewer.js +++ b/src/js/gcode-viewer.js @@ -1,168 +1,160 @@ -/******************************************************************************\ - - This file is part of the Buildbotics firmware. - - Copyright (c) 2015 - 2018, Buildbotics LLC - All rights reserved. - - This file ("the software") is free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License, - version 2 as published by the Free Software Foundation. You should - have received a copy of the GNU General Public License, version 2 - along with the software. If not, see . - - The software is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the software. If not, see - . - - For information regarding this software email: - "Joseph Coffland" - -\******************************************************************************/ - -'use strict' - -var api = require('./api'); - - -var entityMap = { - '&': '&', '<': '<', '>': '>', '"': '"', "'": ''', - '/': '/', '`': '`', '=': '='} +"use strict"; +const entityMap = { + "&": "&", "<": "<", ">": ">", '"': """, "'": "'", + "/": "/", "`": "`", "=": "="}; function escapeHTML(s) { - return s.replace(/[&<>"'`=\/]/g, function (c) {return entityMap[c]}) + return s.replace(/[&<>"'`=\\/]/g, function (c) { + return entityMap[c]; + }); } - module.exports = { - template: '#gcode-viewer-template', + template: "#gcode-viewer-template", - - data: function () { - return { - empty: true, - file: '', - line: -1, - scrolling: false - } - }, - - - events: { - 'gcode-load': function (file) {this.load(file)}, - 'gcode-clear': function () {this.clear()}, - 'gcode-reload': function (file) {this.reload(file)}, - 'gcode-line': function (line) {this.update_line(line)} - }, - - - ready: function () { - this.clusterize = new Clusterize({ - rows: [], - scrollElem: $(this.$el).find('.clusterize-scroll')[0], - contentElem: $(this.$el).find('.clusterize-content')[0], - no_data_text: 'GCode view...', - callbacks: {clusterChanged: this.highlight} - }); - }, - - - attached: function () { - if (typeof this.clusterize != 'undefined') - this.clusterize.refresh(true); - }, - - - methods: { - load: async function(file) { - if (file == this.file) return; - this.clear(); - this.file = file; - - if (!file) return; - - const response = await fetch(`/api/file/${file}?${Math.random()}`); - const text = await response.text(); - - if (text.length > 20e6) { - this.clusterize.update(['File is large - gcode view disabled']); - } else { - const lines = escapeHTML(text.trimRight()) - .split(/[\r\n]/) - .map((line, i) => `
  • ${i + 1}${line}
  • `); - - this.clusterize.update(lines); - } - - this.empty = false; - - Vue.nextTick(this.update_line); + data: function () { + return { + empty: true, + file: "", + line: -1, + scrolling: false + }; }, - - clear: function () { - this.empty = true; - this.file = ''; - this.line = -1; - this.clusterize.clear(); - }, - - - reload: function (file) { - if (file != this.file) return; - this.clear(); - this.load(file); - }, - - - highlight: function () { - var e = $(this.$el).find('.highlight'); - if (e.length) e.removeClass('highlight'); - - e = $(this.$el).find('.ln' + this.line); - if (e.length) e.addClass('highlight'); - }, - - - update_line: function(line) { - if (typeof line != 'undefined') { - if (this.line == line) return; - this.line = line; - - } else line = this.line; - - var totalLines = this.clusterize.getRowsAmount(); - - if (line <= 0) line = 1; - if (totalLines < line) line = totalLines; - - var e = $(this.$el).find('.clusterize-scroll'); - - var lineHeight = e[0].scrollHeight / totalLines; - var linesPerPage = Math.floor(e[0].clientHeight / lineHeight); - var current = e[0].scrollTop / lineHeight; - var target = line - 1 - Math.floor(linesPerPage / 2); - - // Update scroll position - if (!this.scrolling) { - if (target < current - 20 || current + 20 < target) - e[0].scrollTop = target * lineHeight; - - else { - this.scrolling = true; - e.animate({scrollTop: target * lineHeight}, { - complete: function () {this.scrolling = false}.bind(this) - }) + events: { + "gcode-load": function (file) { + this.load(file); + }, + "gcode-clear": function () { + this.clear(); + }, + "gcode-reload": function (file) { + this.reload(file); + }, + "gcode-line": function (line) { + this.update_line(line); } - } + }, - Vue.nextTick(this.highlight); + ready: function () { + this.clusterize = new Clusterize({ + rows: [], + scrollElem: $(this.$el).find(".clusterize-scroll")[0], + contentElem: $(this.$el).find(".clusterize-content")[0], + no_data_text: "GCode view...", + callbacks: {clusterChanged: this.highlight} + }); + }, + + attached: function () { + if (typeof this.clusterize != "undefined") { + this.clusterize.refresh(true); + } + }, + + methods: { + load: async function(file) { + if (file == this.file) { + return; + } + + this.clear(); + this.file = file; + + if (!file) { + return; + } + + const response = await fetch(`/api/file/${file}?${Math.random()}`); + const text = await response.text(); + + if (text.length > 20e6) { + this.clusterize.update(["File is large - gcode view disabled"]); + } else { + const lines = escapeHTML(text.trimRight()) + .split(/[\r\n]/) + .map((line, i) => `
  • ${i + 1}${line}
  • `); + + this.clusterize.update(lines); + } + + this.empty = false; + + Vue.nextTick(this.update_line); + }, + + clear: function () { + this.empty = true; + this.file = ""; + this.line = -1; + this.clusterize.clear(); + }, + + reload: function (file) { + if (file != this.file) { + return; + } + + this.clear(); + this.load(file); + }, + + highlight: function () { + let e = $(this.$el).find(".highlight"); + if (e.length) { + e.removeClass("highlight"); + } + + e = $(this.$el).find(`.ln${this.line}`); + if (e.length) { + e.addClass("highlight"); + } + }, + + update_line: function(line) { + if (typeof line != "undefined") { + if (this.line == line) { + return; + } + + this.line = line; + } else { + line = this.line; + } + + const totalLines = this.clusterize.getRowsAmount(); + + if (line <= 0) { + line = 1; + } + + if (totalLines < line) { + line = totalLines; + } + + const e = $(this.$el).find(".clusterize-scroll"); + + const lineHeight = e[0].scrollHeight / totalLines; + const linesPerPage = Math.floor(e[0].clientHeight / lineHeight); + const current = e[0].scrollTop / lineHeight; + const target = line - 1 - Math.floor(linesPerPage / 2); + + // Update scroll position + if (!this.scrolling) { + if (target < current - 20 || current + 20 < target) { + e[0].scrollTop = target * lineHeight; + } else { + this.scrolling = true; + e.animate({scrollTop: target * lineHeight}, { + complete: function () { + this.scrolling = false; + }.bind(this) + }); + } + } + + Vue.nextTick(this.highlight); + } } - } -} +}; diff --git a/src/js/indicators.js b/src/js/indicators.js index 0285784..e19a1c6 100644 --- a/src/js/indicators.js +++ b/src/js/indicators.js @@ -1,107 +1,94 @@ -/******************************************************************************\ - - This file is part of the Buildbotics firmware. - - Copyright (c) 2015 - 2018, Buildbotics LLC - All rights reserved. - - This file ("the software") is free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License, - version 2 as published by the Free Software Foundation. You should - have received a copy of the GNU General Public License, version 2 - along with the software. If not, see . - - The software is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the software. If not, see - . - - For information regarding this software email: - "Joseph Coffland" - -\******************************************************************************/ - -'use strict' - -var modbus = require('./modbus.js'); +"use strict"; +const modbus = require("./modbus.js"); module.exports = { - template: '#indicators-template', - props: ['state'], + template: "#indicators-template", + props: ["state"], + computed: { + modbus_status: function () { + return modbus.status_to_string(this.state.mx); + }, - computed: { - modbus_status: function () {return modbus.status_to_string(this.state.mx)}, + sense_error: function () { + let error = ""; + if (this.state.motor_voltage_sense_error) { + error += "Motor voltage\n"; + } + if (this.state.motor_current_sense_error) { + error += "Motor current\n"; + } + if (this.state.load1_sense_error) { + error += "Load 1\n"; + } + if (this.state.load2_sense_error) { + error += "Load 2\n"; + } + if (this.state.vdd_current_sense_error) { + error += "Vdd current\n"; + } - sense_error: function () { - var error = ''; + return error; + } + }, - if (this.state.motor_voltage_sense_error) error += 'Motor voltage\n'; - if (this.state.motor_current_sense_error) error += 'Motor current\n'; - if (this.state.load1_sense_error) error += 'Load 1\n'; - if (this.state.load2_sense_error) error += 'Load 2\n'; - if (this.state.vdd_current_sense_error) error += 'Vdd current\n'; + methods: { + is_motor_enabled: function (motor) { + return typeof this.state[`${motor}me`] != "undefined" && this.state[`${motor}me`]; + }, - return error; + get_min_pin: function (motor) { + switch (motor) { + case 0: return 3; + case 1: return 5; + case 2: return 9; + case 3: return 11; + } + }, + + get_max_pin: function (motor) { + switch (motor) { + case 0: return 4; + case 1: return 8; + case 2: return 10; + case 3: return 12; + } + }, + + motor_fault_class: function (motor, bit) { + if (typeof motor == "undefined") { + const status = this.state["fa"]; + + if (typeof status == "undefined") { + return "fa-question"; + } + + return `fa-thumbs-${status ? "down error" : "up success"}`; + } + + const flags = this.state[`${motor}df`]; + + if (typeof flags == "undefined") { + return "fa-question"; + } + + return (flags & (1 << bit)) ? "fa-thumbs-down error" : + "fa-thumbs-up success"; + }, + + motor_reset: function (motor) { + if (typeof motor == "undefined") { + let cmd = ""; + for (let i = 0; i < 4; i++) { + cmd += `\\$${i}df=0\n`; + } + + this.$dispatch("send", cmd); + } else { + this.$dispatch("send", `\\$${motor}df=0`); + } + } } - }, - - - methods: { - is_motor_enabled: function (motor) { - return typeof this.state[motor + 'me'] != 'undefined' && - this.state[motor + 'me']; - }, - - - get_min_pin: function (motor) { - switch (motor) { - case 0: return 3; - case 1: return 5; - case 2: return 9; - case 3: return 11; - } - }, - - - get_max_pin: function (motor) { - switch (motor) { - case 0: return 4; - case 1: return 8; - case 2: return 10; - case 3: return 12; - } - }, - - - motor_fault_class: function (motor, bit) { - if (typeof motor == 'undefined') { - var status = this.state['fa']; - if (typeof status == 'undefined') return 'fa-question'; - return 'fa-thumbs-' + (status ? 'down error' : 'up success') - } - - var flags = this.state[motor + 'df']; - if (typeof flags == 'undefined') return 'fa-question'; - return (flags & (1 << bit)) ? 'fa-thumbs-down error' : - 'fa-thumbs-up success'; - }, - - - motor_reset: function (motor) { - if (typeof motor == 'undefined') { - var cmd = ''; - for (var i = 0; i < 4; i++) - cmd += '\\$' + i + 'df=0\n'; - this.$dispatch('send', cmd); - - } else this.$dispatch('send', '\\$' + motor + 'df=0'); - } - } -} +}; diff --git a/src/js/io-indicator.js b/src/js/io-indicator.js index 1803661..5385e1d 100644 --- a/src/js/io-indicator.js +++ b/src/js/io-indicator.js @@ -1,177 +1,155 @@ -/******************************************************************************\ - - This file is part of the Buildbotics firmware. - - Copyright (c) 2015 - 2018, Buildbotics LLC - All rights reserved. - - This file ("the software") is free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License, - version 2 as published by the Free Software Foundation. You should - have received a copy of the GNU General Public License, version 2 - along with the software. If not, see . - - The software is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the software. If not, see - . - - For information regarding this software email: - "Joseph Coffland" - -\******************************************************************************/ - -'use strict' - +"use strict"; module.exports = { - template: "#io-indicator-template", - props: ['name', 'state'], + template: "#io-indicator-template", + props: ["name", "state"], + computed: { + klass: function () { + switch (this.name) { + case "min-switch-0": return this.get_motor_min_class(0); + case "min-switch-1": return this.get_motor_min_class(1); + case "min-switch-2": return this.get_motor_min_class(2); + case "min-switch-3": return this.get_motor_min_class(3); + case "max-switch-0": return this.get_motor_max_class(0); + case "max-switch-1": return this.get_motor_max_class(1); + case "max-switch-2": return this.get_motor_max_class(2); + case "max-switch-3": return this.get_motor_max_class(3); + case "estop": return this.get_input_class("ew", "et"); + case "probe": return this.get_input_class("pw", "pt"); + case "load-1": return this.get_output_class("1"); + case "load-2": return this.get_output_class("2"); + case "fault": return this.get_output_class("f"); + case "tool-enable-mode": return this.get_output_class("e"); + case "tool-direction-mode": return this.get_output_class("d"); + } + }, - computed: { - klass: function () { - if (this.name == 'min-switch-0') return this.get_motor_min_class(0); - if (this.name == 'min-switch-1') return this.get_motor_min_class(1); - if (this.name == 'min-switch-2') return this.get_motor_min_class(2); - if (this.name == 'min-switch-3') return this.get_motor_min_class(3); - if (this.name == 'max-switch-0') return this.get_motor_max_class(0); - if (this.name == 'max-switch-1') return this.get_motor_max_class(1); - if (this.name == 'max-switch-2') return this.get_motor_max_class(2); - if (this.name == 'max-switch-3') return this.get_motor_max_class(3); - if (this.name == 'estop') return this.get_input_class('ew', 'et'); - if (this.name == 'probe') return this.get_input_class('pw', 'pt'); - if (this.name == 'load-1') return this.get_output_class('1'); - if (this.name == 'load-2') return this.get_output_class('2'); - if (this.name == 'fault') return this.get_output_class('f'); - if (this.name == 'tool-enable-mode') return this.get_output_class('e'); - if (this.name == 'tool-direction-mode') return this.get_output_class('d'); + tooltip: function () { + switch (this.name) { + case "min-switch-0": return this.get_motor_min_tooltip(0); + case "min-switch-1": return this.get_motor_min_tooltip(1); + case "min-switch-2": return this.get_motor_min_tooltip(2); + case "min-switch-3": return this.get_motor_min_tooltip(3); + case "max-switch-0": return this.get_motor_max_tooltip(0); + case "max-switch-1": return this.get_motor_max_tooltip(1); + case "max-switch-2": return this.get_motor_max_tooltip(2); + case "max-switch-3": return this.get_motor_max_tooltip(3); + case "estop": return this.get_input_tooltip("ew", "et"); + case "probe": return this.get_input_tooltip("pw", "pt"); + case "load-1": return this.get_output_tooltip("1"); + case "load-2": return this.get_output_tooltip("2"); + case "fault": return this.get_output_tooltip("f"); + case "tool-direction-mode": return this.get_output_tooltip("d"); + case "tool-enable-mode": return this.get_output_tooltip("e"); + } + } }, + methods: { + get_io_state_class: function (active, state) { + if (typeof active == "undefined" || typeof state == "undefined") { + return "fa-exclamation-triangle warn"; + } - tooltip: function () { - if (this.name == 'min-switch-0') return this.get_motor_min_tooltip(0); - if (this.name == 'min-switch-1') return this.get_motor_min_tooltip(1); - if (this.name == 'min-switch-2') return this.get_motor_min_tooltip(2); - if (this.name == 'min-switch-3') return this.get_motor_min_tooltip(3); - if (this.name == 'max-switch-0') return this.get_motor_max_tooltip(0); - if (this.name == 'max-switch-1') return this.get_motor_max_tooltip(1); - if (this.name == 'max-switch-2') return this.get_motor_max_tooltip(2); - if (this.name == 'max-switch-3') return this.get_motor_max_tooltip(3); - if (this.name == 'estop') return this.get_input_tooltip('ew', 'et'); - if (this.name == 'probe') return this.get_input_tooltip('pw', 'pt'); - if (this.name == 'load-1') return this.get_output_tooltip('1'); - if (this.name == 'load-2') return this.get_output_tooltip('2'); - if (this.name == 'fault') return this.get_output_tooltip('f'); - if (this.name == 'tool-direction-mode') - return this.get_output_tooltip('d'); - if (this.name == 'tool-enable-mode') - return this.get_output_tooltip('e'); + if (state == 2) { + return "fa-circle-o"; + } + + const icon = state ? "fa-plus-circle" : "fa-minus-circle"; + return `${icon} ${active ? "active" : "inactive"}`; + }, + + get_input_active: function (stateCode, typeCode) { + const type = this.state[typeCode]; + const state = this.state[stateCode]; + + if (type == 1) { + return !state; // Normally open + } else if (type == 2) { + return state; // Normally closed + } + + return false; + }, + + get_input_class: function (stateCode, typeCode) { + return this.get_io_state_class(this.get_input_active(stateCode, typeCode), this.state[stateCode]); + }, + + get_output_class: function (output) { + return this.get_io_state_class(this.state[`${output}oa`], this.state[`${output}os`]); + }, + + get_motor_min_class: function (motor) { + return this.get_input_class(`${motor}lw`, `${motor}ls`); + }, + + get_motor_max_class: function (motor) { + return this.get_input_class(`${motor}xw`, `${motor}xs`); + }, + + get_tooltip: function (mode, active, state) { + if (typeof mode == "undefined" || typeof active == "undefined" || typeof state == "undefined") { + return "Invalid"; + } + + if (state == 0) { + state = "Lo/Gnd"; + } else if (state == 1) { + state = "Hi/+3.3v"; + } else if (state == 2) { + state = "Tristated"; + } else { + return "Invalid"; + } + + return `Mode: ${mode}\nActive: ${active ? "True" : "False"}\nLevel: ${state}`; + }, + + get_input_tooltip: function (stateCode, typeCode) { + let type = this.state[typeCode]; + if (type == 0) { + return "Disabled"; + } else if (type == 1) { + type = "Normally open"; + } else if (type == 2) { + type = "Normally closed"; + } + + const active = this.get_input_active(stateCode, typeCode); + const state = this.state[stateCode]; + + return this.get_tooltip(type, active, state); + }, + + get_output_tooltip: function (output) { + let mode = this.state[`${output}om`]; + + switch (mode) { + case 0: return "Disabled"; + case 1: mode = "Lo/Hi"; break; + case 2: mode = "Hi/Lo"; break; + case 3: mode = "Tri/Lo"; break; + case 4: mode = "Tri/Hi"; break; + case 5: mode = "Lo/Tri"; break; + case 6: mode = "Hi/Tri"; break; + default: + mode = undefined; + } + + const active = this.state[`${output}oa`]; + const state = this.state[`${output}os`]; + + return this.get_tooltip(mode, active, state); + }, + + get_motor_min_tooltip: function (motor) { + return this.get_input_tooltip(`${motor}lw`, `${motor}ls`); + }, + + get_motor_max_tooltip: function (motor) { + return this.get_input_tooltip(`${motor}xw`, `${motor}xs`); + } } - }, - - - methods: { - get_io_state_class: function (active, state) { - if (typeof active == 'undefined' || typeof state == 'undefined') - return 'fa-exclamation-triangle warn'; - - if (state == 2) return 'fa-circle-o'; - - return (state ? 'fa-plus-circle' : 'fa-minus-circle') + ' ' + - (active ? 'active' : 'inactive'); - }, - - - get_input_active: function (stateCode, typeCode) { - var type = this.state[typeCode]; - var state = this.state[stateCode]; - - if (type == 1) return !state; // Normally open - else if (type == 2) return state; // Normally closed - - return false - }, - - - get_input_class: function (stateCode, typeCode) { - return this.get_io_state_class(this.get_input_active(stateCode, typeCode), - this.state[stateCode]); - }, - - - get_output_class: function (output) { - return this.get_io_state_class(this.state[output + 'oa'], - this.state[output + 'os']); - }, - - - get_motor_min_class: function (motor) { - return this.get_input_class(motor + 'lw', motor + 'ls'); - }, - - - get_motor_max_class: function (motor) { - return this.get_input_class(motor + 'xw', motor + 'xs'); - }, - - - get_tooltip: function (mode, active, state) { - if (typeof mode == 'undefined' || typeof active == 'undefined' || - typeof state == 'undefined') return 'Invalid'; - - if (state == 0) state = 'Lo/Gnd'; - else if (state == 1) state = 'Hi/+3.3v'; - else if (state == 2) state = 'Tristated'; - else return 'Invalid'; - - return 'Mode: ' + mode + '\nActive: ' + (active ? 'True' : 'False') + - '\nLevel: ' + state; - }, - - - get_input_tooltip: function (stateCode, typeCode) { - var type = this.state[typeCode]; - if (type == 0) return 'Disabled'; - else if (type == 1) type = 'Normally open'; - else if (type == 2) type = 'Normally closed'; - - var active = this.get_input_active(stateCode, typeCode); - var state = this.state[stateCode]; - - return this.get_tooltip(type, active, state); - }, - - - get_output_tooltip: function (output) { - var mode = this.state[output + 'om']; - if (mode == 0) return 'Disabled'; - else if (mode == 1) mode = 'Lo/Hi'; - else if (mode == 2) mode = 'Hi/Lo'; - else if (mode == 3) mode = 'Tri/Lo'; - else if (mode == 4) mode = 'Tri/Hi'; - else if (mode == 5) mode = 'Lo/Tri'; - else if (mode == 6) mode = 'Hi/Tri'; - else mode = undefined; - - var active = this.state[output + 'oa']; - var state = this.state[output + 'os']; - - return this.get_tooltip(mode, active, state); - }, - - - get_motor_min_tooltip: function (motor) { - return this.get_input_tooltip(motor + 'lw', motor + 'ls'); - }, - - - get_motor_max_tooltip: function (motor) { - return this.get_input_tooltip(motor + 'xw', motor + 'xs'); - } - } -} +}; diff --git a/src/js/io-view.js b/src/js/io-view.js index 1cbdc49..97d8b46 100644 --- a/src/js/io-view.js +++ b/src/js/io-view.js @@ -1,42 +1,13 @@ -/******************************************************************************\ - - This file is part of the Buildbotics firmware. - - Copyright (c) 2015 - 2018, Buildbotics LLC - All rights reserved. - - This file ("the software") is free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License, - version 2 as published by the Free Software Foundation. You should - have received a copy of the GNU General Public License, version 2 - along with the software. If not, see . - - The software is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the software. If not, see - . - - For information regarding this software email: - "Joseph Coffland" - -\******************************************************************************/ - -'use strict' - +"use strict"; module.exports = { - template: '#io-view-template', - props: ['config', 'template', 'state'], + template: "#io-view-template", + props: ["config", "template", "state"], - - events: { - 'input-changed': function() { - this.$dispatch('config-changed'); - return false; + events: { + "input-changed": function() { + this.$dispatch("config-changed"); + return false; + } } - } -} +}; diff --git a/src/js/main.js b/src/js/main.js index 12fd4c1..fa76c38 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -1,148 +1,148 @@ -'use strict'; +"use strict"; function cookie_get(name) { - var decodedCookie = decodeURIComponent(document.cookie); - var ca = decodedCookie.split(';'); - name = name + '='; + const decodedCookie = decodeURIComponent(document.cookie); + const ca = decodedCookie.split(";"); + name = `${name}=`; - for (var i = 0; i < ca.length; i++) { - var c = ca[i]; - while (c.charAt(0) == ' ') { - c = c.substring(1); - } + for (let i = 0; i < ca.length; i++) { + let c = ca[i]; + while (c.charAt(0) == " ") { + c = c.substring(1); + } - if (!c.indexOf(name)) { - return c.substring(name.length, c.length); + if (!c.indexOf(name)) { + return c.substring(name.length, c.length); + } } - } } function cookie_set(name, value, days) { - var d = new Date(); - d.setTime(d.getTime() + days * 24 * 60 * 60 * 1000); - var expires = 'expires=' + d.toUTCString(); - document.cookie = name + '=' + value + ';' + expires + ';path=/'; + const d = new Date(); + d.setTime(d.getTime() + days * 24 * 60 * 60 * 1000); + const expires = `expires=${d.toUTCString()}`; + document.cookie = `${name}=${value};${expires};path=/`; } -var uuid_chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_+'; +const uuid_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_+"; function uuid(length) { - if (typeof length == 'undefined') { - length = 52; - } + if (typeof length == "undefined") { + length = 52; + } - var s = ''; - for (var i = 0; i < length; i++) { - s += uuid_chars[Math.floor(Math.random() * uuid_chars.length)]; - } + let s = ""; + for (let i = 0; i < length; i++) { + s += uuid_chars[Math.floor(Math.random() * uuid_chars.length)]; + } - return s + return s; } $(function () { - if (typeof cookie_get('client-id') == 'undefined') { - cookie_set('client-id', uuid(), 10000); - } - - // Register global components - Vue.component('templated-input', require('./templated-input')); - Vue.component('message', require('./message')); - Vue.component('indicators', require('./indicators')); - Vue.component('io-indicator', require('./io-indicator')); - Vue.component('console', require('./console')); - Vue.component('unit-value', require('./unit-value')); - - Vue.filter('number', function (value) { - if (isNaN(value)) { - return 'NaN'; + if (typeof cookie_get("client-id") == "undefined") { + cookie_set("client-id", uuid(), 10000); } - return value.toLocaleString(); - }); + // Register global components + Vue.component("templated-input", require("./templated-input")); + Vue.component("message", require("./message")); + Vue.component("indicators", require("./indicators")); + Vue.component("io-indicator", require("./io-indicator")); + Vue.component("console", require("./console")); + Vue.component("unit-value", require("./unit-value")); - Vue.filter('percent', function (value, precision) { - if (typeof value == 'undefined') { - return ''; - } + Vue.filter("number", function (value) { + if (isNaN(value)) { + return "NaN"; + } - if (typeof precision == 'undefined') { - precision = 2; - } + return value.toLocaleString(); + }); - return (value * 100.0).toFixed(precision) + '%'; - }); + Vue.filter("percent", function (value, precision) { + if (typeof value == "undefined") { + return ""; + } - Vue.filter('non_zero_percent', function (value, precision) { - if (!value) { - return ''; - } + if (typeof precision == "undefined") { + precision = 2; + } - if (typeof precision == 'undefined') { - precision = 2; - } + return `${(value * 100.0).toFixed(precision)}%`; + }); - return (value * 100.0).toFixed(precision) + '%'; - }); + Vue.filter("non_zero_percent", function (value, precision) { + if (!value) { + return ""; + } - Vue.filter('fixed', function (value, precision) { - if (typeof value == 'undefined') { - return '0'; - } + if (typeof precision == "undefined") { + precision = 2; + } - return parseFloat(value).toFixed(precision) - }); + return `${(value * 100.0).toFixed(precision)}%`; + }); - Vue.filter('upper', function (value) { - if (typeof value == 'undefined') { - return ''; - } + Vue.filter("fixed", function (value, precision) { + if (typeof value == "undefined") { + return "0"; + } - return value.toUpperCase() - }); + return parseFloat(value).toFixed(precision); + }); - Vue.filter('time', function (value, precision) { - if (isNaN(value)) { - return ''; - } + Vue.filter("upper", function (value) { + if (typeof value == "undefined") { + return ""; + } - if (isNaN(precision)) { - precision = 0; - } + return value.toUpperCase(); + }); - var MIN = 60; - var HR = MIN * 60; - var DAY = HR * 24; - var parts = []; + Vue.filter("time", function (value, precision) { + if (isNaN(value)) { + return ""; + } - if (DAY <= value) { - parts.push(Math.floor(value / DAY)); - value %= DAY; - } + if (isNaN(precision)) { + precision = 0; + } - if (HR <= value) { - parts.push(Math.floor(value / HR)); - value %= HR; - } + const MIN = 60; + const HR = MIN * 60; + const DAY = HR * 24; + const parts = []; - if (MIN <= value) { - parts.push(Math.floor(value / MIN)); - value %= MIN; - } else { - parts.push(0); - } + if (DAY <= value) { + parts.push(Math.floor(value / DAY)); + value %= DAY; + } - parts.push(value); + if (HR <= value) { + parts.push(Math.floor(value / HR)); + value %= HR; + } - for (var i = 0; i < parts.length; i++) { - parts[i] = parts[i].toFixed(i == parts.length - 1 ? precision : 0); - if (i && parts[i] < 10) { - parts[i] = '0' + parts[i]; - } - } + if (MIN <= value) { + parts.push(Math.floor(value / MIN)); + value %= MIN; + } else { + parts.push(0); + } - return parts.join(':'); - }); + parts.push(value); - // Vue app - require('./app'); + for (let i = 0; i < parts.length; i++) { + parts[i] = parts[i].toFixed(i == parts.length - 1 ? precision : 0); + if (i && parts[i] < 10) { + parts[i] = `0${parts[i]}`; + } + } + + return parts.join(":"); + }); + + // Vue app + require("./app"); }); diff --git a/src/js/message.js b/src/js/message.js index 57c1fae..3f4c1d4 100644 --- a/src/js/message.js +++ b/src/js/message.js @@ -1,47 +1,19 @@ -/******************************************************************************\ - - This file is part of the Buildbotics firmware. - - Copyright (c) 2015 - 2018, Buildbotics LLC - All rights reserved. - - This file ("the software") is free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License, - version 2 as published by the Free Software Foundation. You should - have received a copy of the GNU General Public License, version 2 - along with the software. If not, see . - - The software is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the software. If not, see - . - - For information regarding this software email: - "Joseph Coffland" - -\******************************************************************************/ - -'use strict' - +"use strict"; module.exports = { - template: '#message-template', + template: "#message-template", - props: { - show: { - type: Boolean, - required: true, - twoWay: true - }, + props: { + show: { + type: Boolean, + required: true, + twoWay: true + }, - class: { - type: String, - required: false, - twoWay: false + class: { + type: String, + required: false, + twoWay: false + } } - } -} +}; diff --git a/src/js/modbus-reg.js b/src/js/modbus-reg.js index 224f22e..288166b 100644 --- a/src/js/modbus-reg.js +++ b/src/js/modbus-reg.js @@ -1,48 +1,20 @@ -/******************************************************************************\ - - This file is part of the Buildbotics firmware. - - Copyright (c) 2015 - 2018, Buildbotics LLC - All rights reserved. - - This file ("the software") is free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License, - version 2 as published by the Free Software Foundation. You should - have received a copy of the GNU General Public License, version 2 - along with the software. If not, see . - - The software is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the software. If not, see - . - - For information regarding this software email: - "Joseph Coffland" - -\******************************************************************************/ - -'use strict' - +"use strict"; module.exports = { - replace: true, - template: '#modbus-reg-view-template', - props: ['index', 'model', 'template', 'enable'], + replace: true, + template: "#modbus-reg-view-template", + props: ["index", "model", "template", "enable"], + computed: { + has_user_value: function () { + const type = this.model["reg-type"]; + return type.indexOf("write") != -1 || type.indexOf("fixed") != -1; + } + }, - computed: { - has_user_value: function () { - var type = this.model['reg-type']; - return type.indexOf('write') != -1 || type.indexOf('fixed') != -1; + methods: { + change: function () { + this.$dispatch("input-changed"); + } } - }, - - - methods: { - change: function () {this.$dispatch('input-changed')} - } -} +}; diff --git a/src/js/modbus.js b/src/js/modbus.js index 83a7504..cc09260 100644 --- a/src/js/modbus.js +++ b/src/js/modbus.js @@ -1,51 +1,23 @@ -/******************************************************************************\ - - This file is part of the Buildbotics firmware. - - Copyright (c) 2015 - 2018, Buildbotics LLC - All rights reserved. - - This file ("the software") is free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License, - version 2 as published by the Free Software Foundation. You should - have received a copy of the GNU General Public License, version 2 - along with the software. If not, see . - - The software is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the software. If not, see - . - - For information regarding this software email: - "Joseph Coffland" - -\******************************************************************************/ - -'use strict' - +"use strict"; // Must match modbus.c -var exports = { - DISCONNECTED: 0, - OK: 1, - CRC: 2, - INVALID: 3, - TIMEDOUT: 4 +const exports = { + DISCONNECTED: 0, + OK: 1, + CRC: 2, + INVALID: 3, + TIMEDOUT: 4 }; - exports.status_to_string = function (status) { - if (status == exports.OK) return 'Ok'; - if (status == exports.CRC) return 'CRC error'; - if (status == exports.INVALID) return 'Invalid response'; - if (status == exports.TIMEDOUT) return 'Timedout'; - return 'Disconnected'; - } - + switch (status) { + case exports.OK: return "Ok"; + case exports.CRC: return "CRC error"; + case exports.INVALID: return "Invalid response"; + case exports.TIMEDOUT: return "Timedout"; + default: return "Disconnected"; + } + }; module.exports = exports; diff --git a/src/js/motor-view.js b/src/js/motor-view.js index 34d5ff8..ab1e2b3 100644 --- a/src/js/motor-view.js +++ b/src/js/motor-view.js @@ -1,120 +1,120 @@ -'use strict' +"use strict"; module.exports = { - template: '#motor-view-template', - props: ['index', 'config', 'template', 'state'], + template: "#motor-view-template", + props: ["index", "config", "template", "state"], - computed: { - metric: function () { - return this.$root.display_units === "METRIC"; - }, + computed: { + metric: function () { + return this.$root.display_units === "METRIC"; + }, - is_slave: function () { - for (var i = 0; i < this.index; i++) { - if (this.motor.axis == this.config.motors[i].axis) { - return true; + is_slave: function () { + for (let i = 0; i < this.index; i++) { + if (this.motor.axis == this.config.motors[i].axis) { + return true; + } + } + + return false; + }, + + motor: function () { + return this.config.motors[this.index]; + }, + + invalidMaxVelocity: function () { + return this.maxMaxVelocity < this.motor["max-velocity"]; + }, + + maxMaxVelocity: function () { + return 1 * (15 * this.umPerStep / this.motor["microsteps"]).toFixed(3); + }, + + ustepPerSec: function () { + return this.rpm * this.stepsPerRev * this.motor["microsteps"] / 60; + }, + + rpm: function () { + return 1000 * this.motor["max-velocity"] / this.motor["travel-per-rev"]; + }, + + gForce: function () { + return this.motor["max-accel"] * 0.0283254504; + }, + + gForcePerMin: function () { + return this.motor["max-jerk"] * 0.0283254504; + }, + + stepsPerRev: function () { + return 360 / this.motor["step-angle"]; + }, + + umPerStep: function () { + return this.motor["travel-per-rev"] * this.motor["step-angle"] / 0.36; + }, + + milPerStep: function () { + return this.umPerStep / 25.4; + }, + + invalidStallVelocity: function () { + if (!this.motor["homing-mode"].startsWith("stall-")) { + return false; + } + + return this.maxStallVelocity < this.motor["search-velocity"]; + }, + + stallRPM: function () { + const v = this.motor["search-velocity"]; + return 1000 * v / this.motor["travel-per-rev"]; + }, + + maxStallVelocity: function () { + const maxRate = 900000 / this.motor["stall-sample-time"]; + const ustep = this.motor["stall-microstep"]; + const angle = this.motor["step-angle"]; + const travel = this.motor["travel-per-rev"]; + const maxStall = maxRate * 60 / 360 / 1000 * angle / ustep * travel; + + return 1 * maxStall.toFixed(3); + }, + + stallUStepPerSec: function () { + const ustep = this.motor["stall-microstep"]; + return this.stallRPM * this.stepsPerRev * ustep / 60; } - } - - return false; }, - motor: function () { - return this.config.motors[this.index] - }, + events: { + "input-changed": function () { + Vue.nextTick(function () { + // Limit max-velocity + if (this.invalidMaxVelocity) { + this.$set('motor["max-velocity"]', this.maxMaxVelocity); + } - invalidMaxVelocity: function () { - return this.maxMaxVelocity < this.motor['max-velocity']; - }, + //Limit stall-velocity + if (this.invalidStallVelocity) { + this.$set('motor["search-velocity"]', this.maxStallVelocity); + } - maxMaxVelocity: function () { - return 1 * (15 * this.umPerStep / this.motor['microsteps']).toFixed(3); - }, + this.$dispatch("config-changed"); + }.bind(this)); - ustepPerSec: function () { - return this.rpm * this.stepsPerRev * this.motor['microsteps'] / 60; - }, - - rpm: function () { - return 1000 * this.motor['max-velocity'] / this.motor['travel-per-rev']; - }, - - gForce: function () { - return this.motor['max-accel'] * 0.0283254504 - }, - - gForcePerMin: function () { - return this.motor['max-jerk'] * 0.0283254504 - }, - - stepsPerRev: function () { - return 360 / this.motor['step-angle'] - }, - - umPerStep: function () { - return this.motor['travel-per-rev'] * this.motor['step-angle'] / 0.36 - }, - - milPerStep: function () { - return this.umPerStep / 25.4 - }, - - invalidStallVelocity: function () { - if (!this.motor['homing-mode'].startsWith('stall-')) { - return false; - } - - return this.maxStallVelocity < this.motor['search-velocity']; - }, - - stallRPM: function () { - var v = this.motor['search-velocity']; - return 1000 * v / this.motor['travel-per-rev']; - }, - - maxStallVelocity: function () { - var maxRate = 900000 / this.motor['stall-sample-time']; - var ustep = this.motor['stall-microstep']; - var angle = this.motor['step-angle']; - var travel = this.motor['travel-per-rev']; - var maxStall = maxRate * 60 / 360 / 1000 * angle / ustep * travel; - - return 1 * maxStall.toFixed(3); - }, - - stallUStepPerSec: function () { - var ustep = this.motor['stall-microstep']; - return this.stallRPM * this.stepsPerRev * ustep / 60; - } - }, - - events: { - 'input-changed': function () { - Vue.nextTick(function () { - // Limit max-velocity - if (this.invalidMaxVelocity) { - this.$set('motor["max-velocity"]', this.maxMaxVelocity); + return false; } + }, - //Limit stall-velocity - if (this.invalidStallVelocity) { - this.$set('motor["search-velocity"]', this.maxStallVelocity); + methods: { + show: function (name, templ) { + if (templ.hmodes == undefined) { + return true; + } + + return templ.hmodes.indexOf(this.motor["homing-mode"]) != -1; } - - this.$dispatch('config-changed'); - }.bind(this)) - - return false; } - }, - - methods: { - show: function (name, templ) { - if (templ.hmodes == undefined) { - return true; - } - - return templ.hmodes.indexOf(this.motor['homing-mode']) != -1; - } - } -} +}; diff --git a/src/js/orbit.js b/src/js/orbit.js index 45c5768..88cbeb9 100644 --- a/src/js/orbit.js +++ b/src/js/orbit.js @@ -7,7 +7,7 @@ * @author jcoffland / https://buildbotics.com/ */ -'use strict' +"use strict"; // This set of controls performs orbiting, dollying (zooming), and panning. // Unlike TrackballControls, it maintains the "up" direction object.up @@ -17,665 +17,682 @@ // Zoom - middle mouse, or mousewheel / touch: two-finger spread or squish // Pan - right mouse, or arrow keys / touch: two-finger move +const OrbitControls = function (object, domElement) { + // internals + // eslint-disable-next-line @typescript-eslint/no-this-alias + const scope = this; -var OrbitControls = function (object, domElement) { - this.object = object; - this.domElement = domElement != undefined ? domElement : document; + const changeEvent = {type: "change"}; + const startEvent = {type: "start"}; + const endEvent = {type: "end"}; - // Set to false to disable this control - this.enabled = true; + const STATE = { + NONE: -1, ROTATE: 0, DOLLY: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_DOLLY_PAN: 4 + }; - // "target" sets the location of focus, where the object orbits around - this.target = new THREE.Vector3(); + let state = STATE.NONE; + const EPS = 0.000001; - // How far you can zoom in and out (OrthographicCamera only) - this.minZoom = 0; - this.maxZoom = Infinity; + // current position in spherical coordinates + const spherical = new THREE.Spherical(); + const sphericalDelta = new THREE.Spherical(); - // How far you can orbit vertically, upper and lower limits. - // Range is 0 to Math.PI radians. - this.minPolarAngle = 0; // radians - this.maxPolarAngle = Math.PI; // radians + let scale = 1; + const panOffset = new THREE.Vector3(); + let zoomChanged = false; - // How far you can orbit horizontally, upper and lower limits. - // If set, must be a sub-interval of the interval [- Math.PI, Math.PI]. - this.minAzimuthAngle = -Infinity; // radians - this.maxAzimuthAngle = Infinity; // radians + const rotateStart = new THREE.Vector2(); + const rotateEnd = new THREE.Vector2(); + const rotateDelta = new THREE.Vector2(); - // Set to true to enable damping (inertia) - // If damping is enabled, call controls.update() in your animation loop - this.enableDamping = false; - this.dampingFactor = 0.25; + const panStart = new THREE.Vector2(); + const panEnd = new THREE.Vector2(); + const panDelta = new THREE.Vector2(); - // This option enables dollying in and out; - // left as "zoom" for backwards compatibility. - // Set to false to disable zooming - this.enableZoom = true; - this.zoomSpeed = 1.0; + const dollyStart = new THREE.Vector2(); + const dollyEnd = new THREE.Vector2(); + const dollyDelta = new THREE.Vector2(); - // Set to false to disable rotating - this.enableRotate = true; - this.rotateSpeed = 1.0; + this.object = object; + this.domElement = domElement != undefined ? domElement : document; - // Set to false to disable panning - this.enablePan = true; - this.panSpeed = 1.0; - this.screenSpacePanning = false; // if true, pan in screen-space - this.keyPanSpeed = 7.0; // pixels moved per arrow key push + // Set to false to disable this control + this.enabled = true; - // Set to true to automatically rotate around the target - // If auto-rotate is enabled, call controls.update() in your animation loop - this.autoRotate = false; - this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60 + // "target" sets the location of focus, where the object orbits around + this.target = new THREE.Vector3(); - // Set to false to disable use of the keys - this.enableKeys = true; + // How far you can zoom in and out (OrthographicCamera only) + this.minZoom = 0; + this.maxZoom = Infinity; - // The four arrow keys - this.keys = {LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40}; + // How far you can orbit vertically, upper and lower limits. + // Range is 0 to Math.PI radians. + this.minPolarAngle = 0; // radians + this.maxPolarAngle = Math.PI; // radians - // Mouse buttons - this.mouseButtons = { - ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT - }; + // How far you can orbit horizontally, upper and lower limits. + // If set, must be a sub-interval of the interval [- Math.PI, Math.PI]. + this.minAzimuthAngle = -Infinity; // radians + this.maxAzimuthAngle = Infinity; // radians - // for reset - this.target0 = this.target.clone(); - this.position0 = this.object.position.clone(); - this.zoom0 = this.object.zoom; + // Set to true to enable damping (inertia) + // If damping is enabled, call controls.update() in your animation loop + this.enableDamping = false; + this.dampingFactor = 0.25; - // public methods - this.getPolarAngle = function () {return spherical.phi} - this.getAzimuthalAngle = function () {return spherical.theta} + // This option enables dollying in and out; + // left as "zoom" for backwards compatibility. + // Set to false to disable zooming + this.enableZoom = true; + this.zoomSpeed = 1.0; + // Set to false to disable rotating + this.enableRotate = true; + this.rotateSpeed = 1.0; - this.saveState = function () { - scope.target0.copy(scope.target); - scope.position0.copy(scope.object.position); - scope.zoom0 = scope.object.zoom; - } + // Set to false to disable panning + this.enablePan = true; + this.panSpeed = 1.0; + this.screenSpacePanning = false; // if true, pan in screen-space + this.keyPanSpeed = 7.0; // pixels moved per arrow key push + // Set to true to automatically rotate around the target + // If auto-rotate is enabled, call controls.update() in your animation loop + this.autoRotate = false; + this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60 - this.reset = function () { - scope.target.copy(scope.target0); - scope.object.position.copy(scope.position0); - scope.object.zoom = scope.zoom0; - scope.object.updateProjectionMatrix(); + // Set to false to disable use of the keys + this.enableKeys = true; - scope.dispatchEvent(changeEvent); - scope.update(); + // The four arrow keys + this.keys = {LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40}; - state = STATE.NONE; - } + // Mouse buttons + this.mouseButtons = { + ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT + }; + // for reset + this.target0 = this.target.clone(); + this.position0 = this.object.position.clone(); + this.zoom0 = this.object.zoom; - this.update = function () { - var offset = new THREE.Vector3(); + // public methods + this.getPolarAngle = function () { + return spherical.phi; + }; - // so camera.up is the orbit axis - var quat = new THREE.Quaternion() - .setFromUnitVectors(object.up, new THREE.Vector3(0, 1, 0)); - var quatInverse = quat.clone().inverse(); + this.getAzimuthalAngle = function () { + return spherical.theta; + }; - var lastPosition = new THREE.Vector3(); - var lastQuaternion = new THREE.Quaternion(); + this.saveState = function () { + scope.target0.copy(scope.target); + scope.position0.copy(scope.object.position); + scope.zoom0 = scope.object.zoom; + }; - return function update() { - var position = scope.object.position; - - offset.copy(position).sub(scope.target); - - // rotate offset to "y-axis-is-up" space - offset.applyQuaternion(quat); - - // angle from z-axis around y-axis - spherical.setFromVector3(offset); - - if (scope.autoRotate && state == STATE.NONE) - rotateLeft(getAutoRotationAngle()); - - spherical.theta += sphericalDelta.theta; - spherical.phi += sphericalDelta.phi; - - // restrict theta to be between desired limits - spherical.theta = - Math.max(scope.minAzimuthAngle, - Math.min(scope.maxAzimuthAngle, spherical.theta)); - - // restrict phi to be between desired limits - spherical.phi = - Math.max(scope.minPolarAngle, - Math.min(scope.maxPolarAngle, spherical.phi)); - - spherical.makeSafe(); - spherical.radius *= scale; - - // restrict radius to be between desired limits - spherical.radius = - Math.max(10, Math.min(scope.object.far * 0.8, spherical.radius)); - - // move target to panned location - scope.target.add(panOffset); - - offset.setFromSpherical(spherical); - - // rotate offset back to "camera-up-vector-is-up" space - offset.applyQuaternion(quatInverse); - - position.copy(scope.target).add(offset); - scope.object.lookAt(scope.target); - - if (scope.enableDamping) { - sphericalDelta.theta *= (1 - scope.dampingFactor); - sphericalDelta.phi *= (1 - scope.dampingFactor); - panOffset.multiplyScalar(1 - scope.dampingFactor); - - } else { - sphericalDelta.set(0, 0, 0); - panOffset.set(0, 0, 0); - } - - // update condition is: - // min(camera displacement, camera rotation in radians)^2 > EPS - // using small-angle approximation cos(x/2) = 1 - x^2 / 8 - if (zoomChanged || scale != 1 || - lastPosition.distanceToSquared(scope.object.position) > EPS || - 8 * (1 - lastQuaternion.dot(scope.object.quaternion)) > EPS) { + this.reset = function () { + scope.target.copy(scope.target0); + scope.object.position.copy(scope.position0); + scope.object.zoom = scope.zoom0; + scope.object.updateProjectionMatrix(); scope.dispatchEvent(changeEvent); + scope.update(); - lastPosition.copy(scope.object.position); - lastQuaternion.copy(scope.object.quaternion); - zoomChanged = false; - scale = 1; + state = STATE.NONE; + }; - return true; - } + this.update = function () { + const offset = new THREE.Vector3(); - return false; + // so camera.up is the orbit axis + const quat = new THREE.Quaternion().setFromUnitVectors(object.up, new THREE.Vector3(0, 1, 0)); + const quatInverse = quat.clone().inverse(); + + const lastPosition = new THREE.Vector3(); + const lastQuaternion = new THREE.Quaternion(); + + return function update() { + const position = scope.object.position; + + offset.copy(position).sub(scope.target); + + // rotate offset to "y-axis-is-up" space + offset.applyQuaternion(quat); + + // angle from z-axis around y-axis + spherical.setFromVector3(offset); + + if (scope.autoRotate && state == STATE.NONE) { + rotateLeft(getAutoRotationAngle()); + } + + spherical.theta += sphericalDelta.theta; + spherical.phi += sphericalDelta.phi; + + // restrict theta to be between desired limits + spherical.theta = Math.max(scope.minAzimuthAngle, Math.min(scope.maxAzimuthAngle, spherical.theta)); + + // restrict phi to be between desired limits + spherical.phi = Math.max(scope.minPolarAngle, Math.min(scope.maxPolarAngle, spherical.phi)); + + spherical.makeSafe(); + spherical.radius *= scale; + + // restrict radius to be between desired limits + spherical.radius = Math.max(10, Math.min(scope.object.far * 0.8, spherical.radius)); + + // move target to panned location + scope.target.add(panOffset); + + offset.setFromSpherical(spherical); + + // rotate offset back to "camera-up-vector-is-up" space + offset.applyQuaternion(quatInverse); + + position.copy(scope.target).add(offset); + scope.object.lookAt(scope.target); + + if (scope.enableDamping) { + sphericalDelta.theta *= (1 - scope.dampingFactor); + sphericalDelta.phi *= (1 - scope.dampingFactor); + panOffset.multiplyScalar(1 - scope.dampingFactor); + + } else { + sphericalDelta.set(0, 0, 0); + panOffset.set(0, 0, 0); + } + + // update condition is: + // min(camera displacement, camera rotation in radians)^2 > EPS + // using small-angle approximation cos(x/2) = 1 - x^2 / 8 + if (zoomChanged + || scale != 1 + || lastPosition.distanceToSquared(scope.object.position) > EPS + || 8 * (1 - lastQuaternion.dot(scope.object.quaternion)) > EPS) { + + scope.dispatchEvent(changeEvent); + + lastPosition.copy(scope.object.position); + lastQuaternion.copy(scope.object.quaternion); + zoomChanged = false; + scale = 1; + + return true; + } + + return false; + }; + }(); + + this.dispose = function () { + scope.domElement.removeEventListener("contextmenu", onContextMenu, false); + scope.domElement.removeEventListener("mousedown", onMouseDown, false); + scope.domElement.removeEventListener("wheel", onMouseWheel, false); + scope.domElement.removeEventListener("touchstart", onTouchStart, false); + scope.domElement.removeEventListener("touchend", onTouchEnd, false); + scope.domElement.removeEventListener("touchmove", onTouchMove, false); + document.removeEventListener("mousemove", onMouseMove, false); + document.removeEventListener("mouseup", onMouseUp, false); + window.removeEventListener("keydown", onKeyDown, false); + }; + + function getAutoRotationAngle() { + return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed; } - }() - - this.dispose = function () { - scope.domElement.removeEventListener('contextmenu', onContextMenu, false); - scope.domElement.removeEventListener('mousedown', onMouseDown, false); - scope.domElement.removeEventListener('wheel', onMouseWheel, false); - scope.domElement.removeEventListener('touchstart', onTouchStart, false); - scope.domElement.removeEventListener('touchend', onTouchEnd, false); - scope.domElement.removeEventListener('touchmove', onTouchMove, false); - document.removeEventListener('mousemove', onMouseMove, false); - document.removeEventListener('mouseup', onMouseUp, false); - window.removeEventListener('keydown', onKeyDown, false); - } - - - // internals - var scope = this; - - var changeEvent = {type: 'change'}; - var startEvent = {type: 'start'}; - var endEvent = {type: 'end'}; - - var STATE = { - NONE: -1, ROTATE: 0, DOLLY: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_DOLLY_PAN: 4 - }; - - var state = STATE.NONE; - var EPS = 0.000001; - - // current position in spherical coordinates - var spherical = new THREE.Spherical(); - var sphericalDelta = new THREE.Spherical(); - - var scale = 1; - var panOffset = new THREE.Vector3(); - var zoomChanged = false; - - var rotateStart = new THREE.Vector2(); - var rotateEnd = new THREE.Vector2(); - var rotateDelta = new THREE.Vector2(); - - var panStart = new THREE.Vector2(); - var panEnd = new THREE.Vector2(); - var panDelta = new THREE.Vector2(); - - var dollyStart = new THREE.Vector2(); - var dollyEnd = new THREE.Vector2(); - var dollyDelta = new THREE.Vector2(); - - - function getAutoRotationAngle() { - return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed; - } - - - function getZoomScale() {return Math.pow(0.95, scope.zoomSpeed)} - function rotateLeft(angle) {sphericalDelta.theta -= angle} - function rotateUp(angle) {sphericalDelta.phi -= angle} - - - var panLeft = function () { - var v = new THREE.Vector3(); - - return function panLeft(distance, objectMatrix) { - v.setFromMatrixColumn(objectMatrix, 0); // get X column of objectMatrix - v.multiplyScalar(-distance); - panOffset.add(v); + function getZoomScale() { + return Math.pow(0.95, scope.zoomSpeed); } - }() - - var panUp = function () { - var v = new THREE.Vector3(); - - return function panUp(distance, objectMatrix) { - if (scope.screenSpacePanning) v.setFromMatrixColumn(objectMatrix, 1); - else { - v.setFromMatrixColumn(objectMatrix, 0); - v.crossVectors(scope.object.up, v); - } - - v.multiplyScalar(distance); - panOffset.add(v); + function rotateLeft(angle) { + sphericalDelta.theta -= angle; } - }() - - function unknownCamera() { - console.warn('WARNING: OrbitControls.js encountered an unknown camera ' + - 'type - pan & zoom disabled.'); - scope.enablePan = false; - scope.enableZoom = false; - } - - - // deltaX and deltaY are in pixels; right and down are positive - var pan = function () { - var offset = new THREE.Vector3(); - - return function pan(deltaX, deltaY) { - var element = scope.domElement === document ? - scope.domElement.body : scope.domElement; - - if (scope.object.isPerspectiveCamera) { - // perspective - offset.copy(scope.object.position).sub(scope.target); - var targetDistance = offset.length(); - - // half of the fov is center to top of screen - targetDistance *= Math.tan((scope.object.fov / 2) * Math.PI / 180.0); - - // we use only clientHeight here so aspect ratio does not distort speed - panLeft(2 * deltaX * targetDistance / element.clientHeight, - scope.object.matrix); - panUp(2 * deltaY * targetDistance / element.clientHeight, - scope.object.matrix); - - } else if (scope.object.isOrthographicCamera) { - // orthographic - panLeft(deltaX * (scope.object.right - scope.object.left) / - scope.object.zoom / element.clientWidth, scope.object.matrix); - panUp(deltaY * (scope.object.top - scope.object.bottom) / - scope.object.zoom / element.clientHeight, scope.object.matrix); - - } else unknownCamera(); + function rotateUp(angle) { + sphericalDelta.phi -= angle; } - }() + const panLeft = function () { + const v = new THREE.Vector3(); - function dollyIn(dollyScale) { - if (scope.object.isPerspectiveCamera) scale /= dollyScale; + return function panLeft(distance, objectMatrix) { + v.setFromMatrixColumn(objectMatrix, 0); // get X column of objectMatrix + v.multiplyScalar(-distance); + panOffset.add(v); + }; + }(); - else if (scope.object.isOrthographicCamera) { - scope.object.zoom = + const panUp = function () { + const v = new THREE.Vector3(); + + return function panUp(distance, objectMatrix) { + if (scope.screenSpacePanning) { + v.setFromMatrixColumn(objectMatrix, 1); + } else { + v.setFromMatrixColumn(objectMatrix, 0); + v.crossVectors(scope.object.up, v); + } + + v.multiplyScalar(distance); + panOffset.add(v); + }; + }(); + + function unknownCamera() { + console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan & zoom disabled."); + scope.enablePan = false; + scope.enableZoom = false; + } + + // deltaX and deltaY are in pixels; right and down are positive + const pan = function () { + const offset = new THREE.Vector3(); + + return function pan(deltaX, deltaY) { + const element = scope.domElement === document + ? scope.domElement.body + : scope.domElement; + + if (scope.object.isPerspectiveCamera) { + // perspective + offset.copy(scope.object.position).sub(scope.target); + let targetDistance = offset.length(); + + // half of the fov is center to top of screen + targetDistance *= Math.tan((scope.object.fov / 2) * Math.PI / 180.0); + + // we use only clientHeight here so aspect ratio does not distort speed + panLeft(2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix); + panUp(2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix); + + } else if (scope.object.isOrthographicCamera) { + // orthographic + panLeft(deltaX * (scope.object.right - scope.object.left) / scope.object.zoom / element.clientWidth, scope.object.matrix); + panUp(deltaY * (scope.object.top - scope.object.bottom) / scope.object.zoom / element.clientHeight, scope.object.matrix); + + } else { + unknownCamera(); + } + }; + }(); + + function dollyIn(dollyScale) { + if (scope.object.isPerspectiveCamera) { + scale /= dollyScale; + } else if (scope.object.isOrthographicCamera) { + scope.object.zoom = Math.max(scope.minZoom, - Math.min(scope.maxZoom, scope.object.zoom * dollyScale)); - scope.object.updateProjectionMatrix(); - zoomChanged = true; + Math.min(scope.maxZoom, scope.object.zoom * dollyScale)); + scope.object.updateProjectionMatrix(); + zoomChanged = true; - } else unknownCamera(); - } + } else { + unknownCamera(); + } + } - - function dollyOut(dollyScale) { - if (scope.object.isPerspectiveCamera) scale *= dollyScale; - - else if (scope.object.isOrthographicCamera) { - scope.object.zoom = + function dollyOut(dollyScale) { + if (scope.object.isPerspectiveCamera) { + scale *= dollyScale; + } else if (scope.object.isOrthographicCamera) { + scope.object.zoom = Math.max(scope.minZoom, - Math.min(scope.maxZoom, scope.object.zoom / dollyScale)); - scope.object.updateProjectionMatrix(); - zoomChanged = true; + Math.min(scope.maxZoom, scope.object.zoom / dollyScale)); + scope.object.updateProjectionMatrix(); + zoomChanged = true; - } else unknownCamera(); - } - - - // event callbacks - update the object state - function handleMouseDownRotate(event) { - rotateStart.set(event.clientX, event.clientY); - } - - - function handleMouseDownDolly(event) { - dollyStart.set(event.clientX, event.clientY); - } - - - function handleMouseDownPan(event) { - panStart.set(event.clientX, event.clientY); - } - - - function handleMouseMoveRotate(event) { - rotateEnd.set(event.clientX, event.clientY); - rotateDelta.subVectors(rotateEnd, rotateStart) - .multiplyScalar(scope.rotateSpeed); - - var element = scope.domElement === document ? - scope.domElement.body : scope.domElement; - - // yes, height - rotateLeft(2 * Math.PI * rotateDelta.x / element.clientHeight); - rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight); - - rotateStart.copy(rotateEnd); - - scope.update(); - } - - - function handleMouseMoveDolly(event) { - dollyEnd.set(event.clientX, event.clientY); - dollyDelta.subVectors(dollyEnd, dollyStart); - - if (dollyDelta.y > 0) dollyIn(getZoomScale()); - else if (dollyDelta.y < 0) dollyOut(getZoomScale()); - - dollyStart.copy(dollyEnd); - scope.update(); - } - - - function handleMouseMovePan(event) { - panEnd.set(event.clientX, event.clientY); - panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed); - pan(panDelta.x, panDelta.y); - panStart.copy(panEnd); - scope.update(); - } - - - function handleMouseUp(event) {} - - - function handleMouseWheel(event) { - if (event.deltaY < 0) dollyOut(getZoomScale()); - else if (event.deltaY > 0) dollyIn(getZoomScale()); - - scope.update(); - } - - - function handleKeyDown(event) { - switch (event.keyCode) { - case scope.keys.UP: - pan(0, scope.keyPanSpeed); - scope.update(); - break; - - case scope.keys.BOTTOM: - pan(0, -scope.keyPanSpeed); - scope.update(); - break; - - case scope.keys.LEFT: - pan(scope.keyPanSpeed, 0); - scope.update(); - break; - - case scope.keys.RIGHT: - pan(-scope.keyPanSpeed, 0); - scope.update(); - break; - } - } - - - function handleTouchStartRotate(event) { - rotateStart.set(event.touches[0].pageX, event.touches[0].pageY); - } - - - function handleTouchStartDollyPan(event) { - if (scope.enableZoom) { - var dx = event.touches[0].pageX - event.touches[1].pageX; - var dy = event.touches[0].pageY - event.touches[1].pageY; - var distance = Math.sqrt(dx * dx + dy * dy); - - dollyStart.set(0, distance); + } else { + unknownCamera(); + } } - if (scope.enablePan) { - var x = 0.5 * (event.touches[0].pageX + event.touches[1].pageX); - var y = 0.5 * (event.touches[0].pageY + event.touches[1].pageY); - panStart.set(x, y); - } - } - - - function handleTouchMoveRotate(event) { - rotateEnd.set(event.touches[0].pageX, event.touches[0].pageY); - rotateDelta.subVectors(rotateEnd, rotateStart) - .multiplyScalar(scope.rotateSpeed); - - var element = scope.domElement === document ? - scope.domElement.body : scope.domElement; - - // yes, height - rotateLeft(2 * Math.PI * rotateDelta.x / element.clientHeight); - rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight); - rotateStart.copy(rotateEnd); - scope.update(); - } - - - function handleTouchMoveDollyPan(event) { - if (scope.enableZoom) { - var dx = event.touches[0].pageX - event.touches[1].pageX; - var dy = event.touches[0].pageY - event.touches[1].pageY; - var distance = Math.sqrt(dx * dx + dy * dy); - - dollyEnd.set(0, distance); - dollyDelta.set(0, Math.pow(dollyEnd.y / dollyStart.y, scope.zoomSpeed)); - dollyIn(dollyDelta.y); - dollyStart.copy(dollyEnd); + // event callbacks - update the object state + function handleMouseDownRotate(event) { + rotateStart.set(event.clientX, event.clientY); } - - if (scope.enablePan) { - var x = 0.5 * (event.touches[0].pageX + event.touches[1].pageX); - var y = 0.5 * (event.touches[0].pageY + event.touches[1].pageY); - - panEnd.set(x, y); - panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed); - pan(panDelta.x, panDelta.y); - panStart.copy(panEnd); + function handleMouseDownDolly(event) { + dollyStart.set(event.clientX, event.clientY); } - scope.update(); - } - - - function handleTouchEnd(event) {} - - - // event handlers - listen for events and reset state - function onMouseDown(event) { - if (!scope.enabled) return; - - event.preventDefault(); - - switch (event.button) { - case scope.mouseButtons.ORBIT: - if (!scope.enableRotate) return; - handleMouseDownRotate(event); - state = STATE.ROTATE; - break; - - case scope.mouseButtons.ZOOM: - if (!scope.enableZoom) return; - handleMouseDownDolly(event); - state = STATE.DOLLY; - break; - - case scope.mouseButtons.PAN: - if (!scope.enablePan) return; - handleMouseDownPan(event); - state = STATE.PAN; - break; + function handleMouseDownPan(event) { + panStart.set(event.clientX, event.clientY); } - if (state != STATE.NONE) { - document.addEventListener('mousemove', onMouseMove, false); - document.addEventListener('mouseup', onMouseUp, false); - scope.dispatchEvent(startEvent); - } - } + function handleMouseMoveRotate(event) { + rotateEnd.set(event.clientX, event.clientY); + rotateDelta.subVectors(rotateEnd, rotateStart) + .multiplyScalar(scope.rotateSpeed); + const element = scope.domElement === document ? + scope.domElement.body : scope.domElement; - function onMouseMove(event) { - if (!scope.enabled) return; + // yes, height + rotateLeft(2 * Math.PI * rotateDelta.x / element.clientHeight); + rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight); - event.preventDefault(); + rotateStart.copy(rotateEnd); - switch (state) { - case STATE.ROTATE: - if (!scope.enableRotate) return; - handleMouseMoveRotate(event); - break; - - case STATE.DOLLY: - if (!scope.enableZoom) return; - handleMouseMoveDolly(event); - break; - - case STATE.PAN: - if (!scope.enablePan) return; - handleMouseMovePan(event); - break; - } - } - - - function onMouseUp(event) { - if (!scope.enabled) return; - - handleMouseUp(event); - document.removeEventListener('mousemove', onMouseMove, false); - document.removeEventListener('mouseup', onMouseUp, false); - scope.dispatchEvent(endEvent); - state = STATE.NONE; - } - - - function onMouseWheel(event) { - if (!scope.enabled || !scope.enableZoom || - (state != STATE.NONE && state != STATE.ROTATE)) return; - - event.preventDefault(); - event.stopPropagation(); - scope.dispatchEvent(startEvent); - handleMouseWheel(event); - scope.dispatchEvent(endEvent); - } - - - function onKeyDown(event) { - if (!scope.enabled || !scope.enableKeys || !scope.enablePan) return; - - handleKeyDown(event); - } - - - function onTouchStart(event) { - if (!scope.enabled) return; - - event.preventDefault(); - - switch (event.touches.length) { - case 1: // one-fingered touch: rotate - if (!scope.enableRotate) return; - handleTouchStartRotate(event); - state = STATE.TOUCH_ROTATE; - break; - - case 2: // two-fingered touch: dolly-pan - if (!scope.enableZoom && !scope.enablePan) return; - handleTouchStartDollyPan(event); - state = STATE.TOUCH_DOLLY_PAN; - break; - - default: state = STATE.NONE; + scope.update(); } - if (state != STATE.NONE) scope.dispatchEvent(startEvent); - } + function handleMouseMoveDolly(event) { + dollyEnd.set(event.clientX, event.clientY); + dollyDelta.subVectors(dollyEnd, dollyStart); + if (dollyDelta.y > 0) { + dollyIn(getZoomScale()); + } else if (dollyDelta.y < 0) { + dollyOut(getZoomScale()); + } - function onTouchMove(event) { - if (!scope.enabled) return; - - event.preventDefault(); - event.stopPropagation(); - - switch (event.touches.length) { - case 1: // one-fingered touch: rotate - if (!scope.enableRotate) return; - if (state != STATE.TOUCH_ROTATE) return; // is this needed? - - handleTouchMoveRotate(event); - break; - - case 2: // two-fingered touch: dolly-pan - if (!scope.enableZoom && !scope.enablePan) return; - if (state != STATE.TOUCH_DOLLY_PAN) return; // is this needed? - - handleTouchMoveDollyPan(event); - break; - - default: state = STATE.NONE; + dollyStart.copy(dollyEnd); + scope.update(); } - } + function handleMouseMovePan(event) { + panEnd.set(event.clientX, event.clientY); + panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed); + pan(panDelta.x, panDelta.y); + panStart.copy(panEnd); + scope.update(); + } - function onTouchEnd(event) { - if (!scope.enabled) return; + function handleMouseWheel(event) { + if (event.deltaY < 0) { + dollyOut(getZoomScale()); + } else if (event.deltaY > 0) { + dollyIn(getZoomScale()); + } - handleTouchEnd(event); - scope.dispatchEvent(endEvent); - state = STATE.NONE; - } + scope.update(); + } + function handleKeyDown(event) { + switch (event.keyCode) { + case scope.keys.UP: + pan(0, scope.keyPanSpeed); + scope.update(); + break; - function onContextMenu(event) { - if (!scope.enabled) return; - event.preventDefault(); - } + case scope.keys.BOTTOM: + pan(0, -scope.keyPanSpeed); + scope.update(); + break; + case scope.keys.LEFT: + pan(scope.keyPanSpeed, 0); + scope.update(); + break; - scope.domElement.addEventListener('contextmenu', onContextMenu, false); - scope.domElement.addEventListener('mousedown', onMouseDown, false); - scope.domElement.addEventListener('wheel', onMouseWheel, false); - scope.domElement.addEventListener('touchstart', onTouchStart, false); - scope.domElement.addEventListener('touchend', onTouchEnd, false); - scope.domElement.addEventListener('touchmove', onTouchMove, false); - window .addEventListener('keydown', onKeyDown, false); + case scope.keys.RIGHT: + pan(-scope.keyPanSpeed, 0); + scope.update(); + break; + } + } - this.update(); // force an update at start -} + function handleTouchStartRotate(event) { + rotateStart.set(event.touches[0].pageX, event.touches[0].pageY); + } + function handleTouchStartDollyPan(event) { + if (scope.enableZoom) { + const dx = event.touches[0].pageX - event.touches[1].pageX; + const dy = event.touches[0].pageY - event.touches[1].pageY; + const distance = Math.sqrt(dx * dx + dy * dy); + + dollyStart.set(0, distance); + } + + if (scope.enablePan) { + const x = 0.5 * (event.touches[0].pageX + event.touches[1].pageX); + const y = 0.5 * (event.touches[0].pageY + event.touches[1].pageY); + panStart.set(x, y); + } + } + + function handleTouchMoveRotate(event) { + rotateEnd.set(event.touches[0].pageX, event.touches[0].pageY); + rotateDelta.subVectors(rotateEnd, rotateStart) + .multiplyScalar(scope.rotateSpeed); + + const element = scope.domElement === document ? + scope.domElement.body : scope.domElement; + + // yes, height + rotateLeft(2 * Math.PI * rotateDelta.x / element.clientHeight); + rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight); + rotateStart.copy(rotateEnd); + scope.update(); + } + + function handleTouchMoveDollyPan(event) { + if (scope.enableZoom) { + const dx = event.touches[0].pageX - event.touches[1].pageX; + const dy = event.touches[0].pageY - event.touches[1].pageY; + const distance = Math.sqrt(dx * dx + dy * dy); + + dollyEnd.set(0, distance); + dollyDelta.set(0, Math.pow(dollyEnd.y / dollyStart.y, scope.zoomSpeed)); + dollyIn(dollyDelta.y); + dollyStart.copy(dollyEnd); + } + + if (scope.enablePan) { + const x = 0.5 * (event.touches[0].pageX + event.touches[1].pageX); + const y = 0.5 * (event.touches[0].pageY + event.touches[1].pageY); + + panEnd.set(x, y); + panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed); + pan(panDelta.x, panDelta.y); + panStart.copy(panEnd); + } + + scope.update(); + } + + // event handlers - listen for events and reset state + function onMouseDown(event) { + if (!scope.enabled) { + return; + } + + event.preventDefault(); + + switch (event.button) { + case scope.mouseButtons.ORBIT: + if (!scope.enableRotate) { + return; + } + handleMouseDownRotate(event); + state = STATE.ROTATE; + break; + + case scope.mouseButtons.ZOOM: + if (!scope.enableZoom) { + return; + } + handleMouseDownDolly(event); + state = STATE.DOLLY; + break; + + case scope.mouseButtons.PAN: + if (!scope.enablePan) { + return; + } + handleMouseDownPan(event); + state = STATE.PAN; + break; + } + + if (state != STATE.NONE) { + document.addEventListener("mousemove", onMouseMove, false); + document.addEventListener("mouseup", onMouseUp, false); + scope.dispatchEvent(startEvent); + } + } + + function onMouseMove(event) { + if (!scope.enabled) { + return; + } + + event.preventDefault(); + + switch (state) { + case STATE.ROTATE: + if (!scope.enableRotate) { + return; + } + handleMouseMoveRotate(event); + break; + + case STATE.DOLLY: + if (!scope.enableZoom) { + return; + } + handleMouseMoveDolly(event); + break; + + case STATE.PAN: + if (!scope.enablePan) { + return; + } + handleMouseMovePan(event); + break; + } + } + + function onMouseUp() { + if (!scope.enabled) { + return; + } + + document.removeEventListener("mousemove", onMouseMove, false); + document.removeEventListener("mouseup", onMouseUp, false); + scope.dispatchEvent(endEvent); + state = STATE.NONE; + } + + function onMouseWheel(event) { + if (!scope.enabled || !scope.enableZoom || + (state != STATE.NONE && state != STATE.ROTATE)) { + return; + } + + event.preventDefault(); + event.stopPropagation(); + scope.dispatchEvent(startEvent); + handleMouseWheel(event); + scope.dispatchEvent(endEvent); + } + + function onKeyDown(event) { + if (!scope.enabled || !scope.enableKeys || !scope.enablePan) { + return; + } + + handleKeyDown(event); + } + + function onTouchStart(event) { + if (!scope.enabled) { + return; + } + + event.preventDefault(); + + switch (event.touches.length) { + case 1: // one-fingered touch: rotate + if (!scope.enableRotate) { + return; + } + handleTouchStartRotate(event); + state = STATE.TOUCH_ROTATE; + break; + + case 2: // two-fingered touch: dolly-pan + if (!scope.enableZoom && !scope.enablePan) { + return; + } + handleTouchStartDollyPan(event); + state = STATE.TOUCH_DOLLY_PAN; + break; + + default: state = STATE.NONE; + } + + if (state != STATE.NONE) { + scope.dispatchEvent(startEvent); + } + } + + function onTouchMove(event) { + if (!scope.enabled) { + return; + } + + event.preventDefault(); + event.stopPropagation(); + + switch (event.touches.length) { + case 1: // one-fingered touch: rotate + if (!scope.enableRotate) { + return; + } + if (state != STATE.TOUCH_ROTATE) { + return; + } // is this needed? + + handleTouchMoveRotate(event); + break; + + case 2: // two-fingered touch: dolly-pan + if (!scope.enableZoom && !scope.enablePan) { + return; + } + if (state != STATE.TOUCH_DOLLY_PAN) { + return; + } // is this needed? + + handleTouchMoveDollyPan(event); + break; + + default: state = STATE.NONE; + } + } + + function onTouchEnd() { + if (!scope.enabled) { + return; + } + + scope.dispatchEvent(endEvent); + state = STATE.NONE; + } + + function onContextMenu(event) { + if (!scope.enabled) { + return; + } + event.preventDefault(); + } + + scope.domElement.addEventListener("contextmenu", onContextMenu, false); + scope.domElement.addEventListener("mousedown", onMouseDown, false); + scope.domElement.addEventListener("wheel", onMouseWheel, false); + scope.domElement.addEventListener("touchstart", onTouchStart, false); + scope.domElement.addEventListener("touchend", onTouchEnd, false); + scope.domElement.addEventListener("touchmove", onTouchMove, false); + window.addEventListener("keydown", onKeyDown, false); + + this.update(); // force an update at start +}; OrbitControls.prototype = Object.create(THREE.EventDispatcher.prototype); OrbitControls.prototype.constructor = OrbitControls; diff --git a/src/js/path-viewer.js b/src/js/path-viewer.js index f790af0..fba2396 100644 --- a/src/js/path-viewer.js +++ b/src/js/path-viewer.js @@ -1,766 +1,771 @@ -/******************************************************************************\ +"use strict"; - Copyright 2018. Buildbotics LLC - All Rights Reserved. - - For information regarding this software email: - Joseph Coffland - joseph@buildbotics.com - - This software is free software: you clan redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation, either version 2.1 of - the License, or (at your option) any later version. - - This software is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the C! library. If not, see - . - -\******************************************************************************/ - -'use strict' - -var orbit = require('./orbit'); -var cookie = require('./cookie')('bbctrl-'); -var font = require('./helvetiker_regular.typeface.json') +const orbit = require("./orbit"); +const cookie = require("./cookie")("bbctrl-"); +const font = require("./helvetiker_regular.typeface.json"); module.exports = { - template: '#path-viewer-template', - props: ['toolpath'], + template: "#path-viewer-template", + props: ["toolpath"], - data: function () { - return { - enabled: false, - loading: false, - dirty: true, - snapView: cookie.get('snap-view', 'isometric'), - small: cookie.get_bool('small-path-view', true), - surfaceMode: 'cut', - showPath: cookie.get_bool('show-path', true), - showTool: cookie.get_bool('show-tool', true), - showBBox: cookie.get_bool('show-bbox', true), - showAxes: cookie.get_bool('show-axes', true), - showIntensity: cookie.get_bool('show-intensity', false) - } - }, - - - computed: { - target: function () { - return $(this.$el).find('.path-viewer-content')[0] + data: function () { + return { + enabled: false, + loading: false, + dirty: true, + snapView: cookie.get("snap-view", "isometric"), + small: cookie.get_bool("small-path-view", true), + surfaceMode: "cut", + showPath: cookie.get_bool("show-path", true), + showTool: cookie.get_bool("show-tool", true), + showBBox: cookie.get_bool("show-bbox", true), + showAxes: cookie.get_bool("show-axes", true), + showIntensity: cookie.get_bool("show-intensity", false) + }; }, - webglAvailable: function() { - // Create canvas element. The canvas is not added to the - // document itself, so it is never displayed in the - // browser window. - const canvas = document.createElement("canvas"); - - // Get WebGLRenderingContext from canvas element. - const gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl"); - - // Report the result. - return gl && gl instanceof WebGLRenderingContext; - } - }, - - - watch: { - toolpath: function () {Vue.nextTick(this.update)}, - surfaceMode: function (mode) {this.update_surface_mode(mode)}, - - - small: function (enable) { - cookie.set_bool('small-path-view', enable); - Vue.nextTick(this.update_view) - }, - - - showPath: function (enable) { - cookie.set_bool('show-path', enable); - this.set_visible(this.pathView, enable) - }, - - - showTool: function (enable) { - cookie.set_bool('show-tool', enable); - this.set_visible(this.toolView, enable) - }, - - - showAxes: function (enable) { - cookie.set_bool('show-axes', enable); - this.set_visible(this.axesView, enable) - }, - - - showIntensity: function (enable) { - cookie.set_bool('show-intensity', enable); - Vue.nextTick(this.update) - }, - - - showBBox: function (enable) { - cookie.set_bool('show-bbox', enable); - this.set_visible(this.bboxView, enable); - this.set_visible(this.envelopeView, enable); - }, - - - x: function () {this.axis_changed()}, - y: function () {this.axis_changed()}, - z: function () {this.axis_changed()} - }, - - - ready: function () { - this.graphics(); - Vue.nextTick(this.update); - }, - - - methods: { - update: async function () { - if (!this.webglAvailable) { - return; - } - - if (!this.state.selected) { - this.dirty = true; - this.scene = new THREE.Scene(); - - } else if (!this.toolpath.filename && !this.loading) { - this.loading = true; - this.dirty = true; - this.draw_loading(); - } - - if (!this.enabled || !this.toolpath.filename) return; - - async function get(url) { - const response = await fetch(`${url}?${Math.random()}`); - const arrayBuffer = await response.arrayBuffer(); - - return new Float32Array(arrayBuffer); - } - - const [positions, speeds] = await Promise.all([ - get('/api/path/' + this.toolpath.filename + '/positions'), - get('/api/path/' + this.toolpath.filename + '/speeds') - ]); - - this.positions = positions - this.speeds = speeds; - this.loading = false; - - // Update scene - this.scene = new THREE.Scene(); - this.draw(this.scene); - this.snap(this.snapView); - - this.update_view(); - }, - - - update_surface_mode: function (mode) { - if (!this.enabled) return; - - if (typeof this.surfaceMaterial != 'undefined') { - this.surfaceMaterial.wireframe = mode == 'wire'; - this.surfaceMaterial.needsUpdate = true; - } - - this.set_visible(this.surfaceMesh, mode == 'cut' || mode == 'wire'); - this.set_visible(this.workpieceMesh, mode == 'solid'); - }, - - - load_surface: function (surface) { - if (typeof surface == 'undefined') { - this.vertices = undefined; - this.normals = undefined; - return; - } - - this.vertices = surface.vertices; - - // Expand normals - this.normals = []; - for (var i = 0; i < surface.normals.length / 3; i++) - for (var j = 0; j < 3; j++) - for (var k = 0; k < 3; k++) - this.normals.push(surface.normals[i * 3 + k]); - }, - - - set_visible: function (target, visible) { - if (typeof target != 'undefined') target.visible = visible; - this.dirty = true; - }, - - - get_dims: function () { - var t = $(this.target); - var width = t.innerWidth(); - var height = t.innerHeight(); - return {width: width, height: height}; - }, - - - update_view: function () { - if (!this.enabled) return; - var dims = this.get_dims(); - - this.camera.aspect = dims.width / dims.height; - this.camera.updateProjectionMatrix(); - this.renderer.setSize(dims.width, dims.height); - - if (this.loading) { - this.controls.reset(); - this.camera.position.copy(new THREE.Vector3(0, 0, 600)); - this.camera.lookAt(new THREE.Vector3(0, 0, 0)); - } - - this.dirty = true; - }, - - - update_tool: function (tool) { - if (!this.enabled) return; - if (typeof tool == 'undefined') tool = this.toolView; - if (typeof tool == 'undefined') return; - tool.position.x = this.x.pos; - tool.position.y = this.y.pos; - tool.position.z = this.z.pos; - }, - - - update_envelope: function (envelope) { - if (!this.enabled || !this.axes.homed) return; - if (typeof envelope == 'undefined') envelope = this.envelopeView; - if (typeof envelope == 'undefined') return; - - var min = new THREE.Vector3(); - var max = new THREE.Vector3(); - - for (var axis of 'xyz') { - min[axis] = this[axis].min - this[axis].off; - max[axis] = this[axis].max - this[axis].off; - } - - var bounds = new THREE.Box3(min, max); - if (bounds.isEmpty()) { - envelope.geometry = this.create_empty_geom(); - } - else { - envelope.geometry = this.create_bbox_geom(bounds); - } - }, - - - axis_changed: function () { - this.update_tool(); - this.update_envelope(); - this.dirty = true; - }, - - - graphics: function () { - if (!this.webglAvailable) { - return; - } - - try { - // Renderer - this.renderer = new THREE.WebGLRenderer({antialias: true, alpha: true}); - this.renderer.setPixelRatio(window.devicePixelRatio); - this.renderer.setClearColor(0, 0); - this.target.appendChild(this.renderer.domElement); - - } catch (e) { - console.log('WebGL not supported: ', e); - return; - } - - this.enabled = true; - - // Camera - this.camera = new THREE.PerspectiveCamera(45, 4 / 3, 1, 10000); - - // Lighting - this.ambient = new THREE.AmbientLight(0xffffff, 0.5); - - var keyLight = new THREE.DirectionalLight - (new THREE.Color('hsl(30, 100%, 75%)'), 0.75); - keyLight.position.set(-100, 0, 100); - - var fillLight = new THREE.DirectionalLight - (new THREE.Color('hsl(240, 100%, 75%)'), 0.25); - fillLight.position.set(100, 0, 100); - - var backLight = new THREE.DirectionalLight(0xffffff, 0.5); - backLight.position.set(100, 0, -100).normalize(); - - this.lights = new THREE.Group(); - this.lights.add(keyLight); - this.lights.add(fillLight); - this.lights.add(backLight); - - // Surface material - this.surfaceMaterial = this.create_surface_material(); - - // Controls - this.controls = new orbit(this.camera, this.renderer.domElement); - this.controls.enableDamping = true; - this.controls.dampingFactor = 0.2; - this.controls.rotateSpeed = 0.25; - this.controls.enableZoom = true; - - // Move lights with scene - this.controls.addEventListener('change', function (scope) { - return function () { - keyLight.position.copy(scope.camera.position); - fillLight.position.copy(scope.camera.position); - backLight.position.copy(scope.camera.position); - keyLight.lookAt(scope.controls.target); - fillLight.lookAt(scope.controls.target); - backLight.lookAt(scope.controls.target); - scope.dirty = true; + computed: { + target: function () { + return $(this.$el).find(".path-viewer-content")[0]; + }, + + webglAvailable: function() { + // Create canvas element. The canvas is not added to the + // document itself, so it is never displayed in the + // browser window. + const canvas = document.createElement("canvas"); + + // Get WebGLRenderingContext from canvas element. + const gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl"); + + // Report the result. + return gl && gl instanceof WebGLRenderingContext; } - }(this)) - - // Events - window.addEventListener('resize', this.update_view, false); - - // Start it - this.render(); }, - - create_surface_material: function () { - return new THREE.MeshPhongMaterial({ - specular: 0x111111, - shininess: 10, - side: THREE.FrontSide, - color: 0x0c2d53 - }); - }, - - - draw_loading: function () { - this.scene = new THREE.Scene(); - - var geometry = new THREE.TextGeometry('Loading 3D View...', { - font: new THREE.Font(font), - size: 40, - height: 5, - curveSegments: 12, - bevelEnabled: true, - bevelThickness: 10, - bevelSize: 8, - bevelSegments: 5 - }); - geometry.computeBoundingBox(); - - var center = geometry.center(); - var mesh = new THREE.Mesh(geometry, this.surfaceMaterial); - - this.scene.add(mesh); - this.scene.add(this.ambient); - this.scene.add(this.lights); - this.update_view(); - }, - - - draw_workpiece: function (scene, material) { - if (typeof this.workpiece == 'undefined') return; - - var min = this.workpiece.min; - var max = this.workpiece.max; - - min = new THREE.Vector3(min[0], min[1], min[2]); - max = new THREE.Vector3(max[0], max[1], max[2]); - var dims = max.clone().sub(min); - - var geometry = new THREE.BoxGeometry(dims.x, dims.y, dims.z) - var mesh = new THREE.Mesh(geometry, material); - - var offset = dims.clone(); - offset.divideScalar(2); - offset.add(min); - - mesh.position.add(offset); - - geometry.computeBoundingBox(); - - scene.add(mesh); - - return mesh; - }, - - - draw_surface: function (scene, material) { - if (typeof this.vertices == 'undefined') return; - - var geometry = new THREE.BufferGeometry(); - - geometry.addAttribute - ('position', new THREE.Float32BufferAttribute(this.vertices, 3)); - geometry.addAttribute - ('normal', new THREE.Float32BufferAttribute(this.normals, 3)); - - geometry.computeBoundingSphere(); - geometry.computeBoundingBox(); - - return new THREE.Mesh(geometry, material); - }, - - - draw_tool: function (scene, bbox) { - // Tool size is relative to bounds - var size = bbox.getSize(new THREE.Vector3()); - var length = (size.x + size.y + size.z) / 24; - - if (length < 1) length = 1; - - var material = new THREE.MeshPhongMaterial({ - transparent: true, - opacity: 0.75, - specular: 0x161616, - shininess: 10, - color: 0xffa500 // Orange - }); - - var geometry = new THREE.CylinderGeometry(length / 2, 0, length, 128); - geometry.translate(0, length / 2, 0); - geometry.rotateX(0.5 * Math.PI); - - var mesh = new THREE.Mesh(geometry, material); - this.update_tool(mesh); - mesh.visible = this.showTool; - scene.add(mesh); - return mesh; - }, - - - draw_axis: function (axis, up, length, radius) { - var color; - - if (axis == 0) color = 0xff0000; // Red - else if (axis == 1) color = 0x00ff00; // Green - else if (axis == 2) color = 0x0000ff; // Blue - - var group = new THREE.Group(); - var material = new THREE.MeshPhongMaterial({ - specular: 0x161616, shininess: 10, color: color - }); - var geometry = new THREE.CylinderGeometry(radius, radius, length, 128); - geometry.translate(0, -length / 2, 0); - group.add(new THREE.Mesh(geometry, material)); - - geometry = new THREE.CylinderGeometry(1.5 * radius, 0, 2 * radius, 128); - geometry.translate(0, -length - radius, 0); - group.add(new THREE.Mesh(geometry, material)); - - if (axis == 0) group.rotateZ((up ? 0.5 : 1.5) * Math.PI); - else if (axis == 1) group.rotateX((up ? 0 : 1 ) * Math.PI); - else if (axis == 2) group.rotateX((up ? 1.5 : 0.5) * Math.PI); - - return group; - }, - - - draw_axes: function (scene, bbox) { - var size = bbox.getSize(new THREE.Vector3()); - var length = (size.x + size.y + size.z) / 3; - length /= 10; - - if (length < 1) length = 1; - - var radius = length / 20; - - var group = new THREE.Group(); - - for (var axis = 0; axis < 3; axis++) - for (var up = 0; up < 2; up++) - group.add(this.draw_axis(axis, up, length, radius)); - - group.visible = this.showAxes; - scene.add(group); - - return group; - }, - - - get_color: function (speed) { - if (isNaN(speed)) return [255, 0, 0]; // Rapid - - var intensity = speed / this.toolpath.maxSpeed; - if (typeof speed == 'undefined' || !this.showIntensity) intensity = 1; - return [0, 255 * intensity, 127 * (1 - intensity)]; - }, - - - draw_path: function (scene) { - var geometry = new THREE.BufferGeometry(); - var material = - new THREE.LineBasicMaterial({ - vertexColors: THREE.VertexColors, - linewidth: 1.5 - }); - - var positions = new THREE.Float32BufferAttribute(this.positions, 3); - geometry.addAttribute('position', positions); - - var colors = []; - for (var i = 0; i < this.speeds.length; i++) { - var color = this.get_color(this.speeds[i]); - Array.prototype.push.apply(colors, color); - } - - colors = new THREE.Uint8BufferAttribute(colors, 3, true); - geometry.addAttribute('color', colors); - - geometry.computeBoundingSphere(); - geometry.computeBoundingBox(); - - var line = new THREE.Line(geometry, material); - - line.visible = this.showPath; - scene.add(line); - - return line; - }, - - - create_empty_geom: function () { - var geometry = new THREE.BufferGeometry(); - geometry.addAttribute('position', - new THREE.Float32BufferAttribute([], 3)); - return geometry; - }, - - - create_bbox_geom: function (bbox) { - var vertices = []; - - if (!bbox.isEmpty()) { - // Top - vertices.push(bbox.min.x, bbox.min.y, bbox.min.z); - vertices.push(bbox.max.x, bbox.min.y, bbox.min.z); - vertices.push(bbox.max.x, bbox.min.y, bbox.min.z); - vertices.push(bbox.max.x, bbox.min.y, bbox.max.z); - vertices.push(bbox.max.x, bbox.min.y, bbox.max.z); - vertices.push(bbox.min.x, bbox.min.y, bbox.max.z); - vertices.push(bbox.min.x, bbox.min.y, bbox.max.z); - vertices.push(bbox.min.x, bbox.min.y, bbox.min.z); - - // Bottom - vertices.push(bbox.min.x, bbox.max.y, bbox.min.z); - vertices.push(bbox.max.x, bbox.max.y, bbox.min.z); - vertices.push(bbox.max.x, bbox.max.y, bbox.min.z); - vertices.push(bbox.max.x, bbox.max.y, bbox.max.z); - vertices.push(bbox.max.x, bbox.max.y, bbox.max.z); - vertices.push(bbox.min.x, bbox.max.y, bbox.max.z); - vertices.push(bbox.min.x, bbox.max.y, bbox.max.z); - vertices.push(bbox.min.x, bbox.max.y, bbox.min.z); - - // Sides - vertices.push(bbox.min.x, bbox.min.y, bbox.min.z); - vertices.push(bbox.min.x, bbox.max.y, bbox.min.z); - vertices.push(bbox.max.x, bbox.min.y, bbox.min.z); - vertices.push(bbox.max.x, bbox.max.y, bbox.min.z); - vertices.push(bbox.max.x, bbox.min.y, bbox.max.z); - vertices.push(bbox.max.x, bbox.max.y, bbox.max.z); - vertices.push(bbox.min.x, bbox.min.y, bbox.max.z); - vertices.push(bbox.min.x, bbox.max.y, bbox.max.z); - } - - var geometry = new THREE.BufferGeometry(); - - geometry.addAttribute('position', - new THREE.Float32BufferAttribute(vertices, 3)); - - return geometry; - }, - - - draw_bbox: function (scene, bbox) { - var geometry = this.create_bbox_geom(bbox); - var material = new THREE.LineBasicMaterial({color: 0xffffff}); - var line = new THREE.LineSegments(geometry, material); - - line.visible = this.showBBox; - - scene.add(line); - - return line; - }, - - - draw_envelope: function (scene) { - var geometry = this.create_empty_geom(); - var material = new THREE.LineBasicMaterial({color: 0x00f7ff}); - var line = new THREE.LineSegments(geometry, material); - - line.visible = this.showBBox; - - scene.add(line); - this.update_envelope(line); - - return line; - }, - - - draw: function (scene) { - // Lights - scene.add(this.ambient); - scene.add(this.lights); - - // Model - this.pathView = this.draw_path(scene); - this.surfaceMesh = this.draw_surface(scene, this.surfaceMaterial); - this.workpieceMesh = this.draw_workpiece(scene, this.surfaceMaterial); - this.update_surface_mode(this.surfaceMode); - - // Compute bounding box - var bbox = this.get_model_bounds(); - - // Tool, axes & bounds - this.toolView = this.draw_tool(scene, bbox); - this.axesView = this.draw_axes(scene, bbox); - this.bboxView = this.draw_bbox(scene, bbox); - this.envelopeView = this.draw_envelope(scene); - }, - - - render: function () { - window.requestAnimationFrame(this.render); - if (typeof this.scene == 'undefined') return; - - if (this.controls.update() || this.dirty) { - this.dirty = false; - this.renderer.render(this.scene, this.camera); - } - }, - - - get_model_bounds: function () { - var bbox = new THREE.Box3(new THREE.Vector3(0, 0, 0), - new THREE.Vector3(0.00001, 0.00001, 0.00001)); - - function add(o) { - if (typeof o != 'undefined') { - var oBBox = new THREE.Box3(); - oBBox.setFromObject(o); - bbox.union(oBBox); + watch: { + toolpath: function () { + Vue.nextTick(this.update); + }, + + surfaceMode: function (mode) { + this.update_surface_mode(mode); + }, + + small: function (enable) { + cookie.set_bool("small-path-view", enable); + Vue.nextTick(this.update_view); + }, + + showPath: function (enable) { + cookie.set_bool("show-path", enable); + this.set_visible(this.pathView, enable); + }, + + showTool: function (enable) { + cookie.set_bool("show-tool", enable); + this.set_visible(this.toolView, enable); + }, + + showAxes: function (enable) { + cookie.set_bool("show-axes", enable); + this.set_visible(this.axesView, enable); + }, + + showIntensity: function (enable) { + cookie.set_bool("show-intensity", enable); + Vue.nextTick(this.update); + }, + + showBBox: function (enable) { + cookie.set_bool("show-bbox", enable); + this.set_visible(this.bboxView, enable); + this.set_visible(this.envelopeView, enable); + }, + + x: function () { + this.axis_changed(); + }, + + y: function () { + this.axis_changed(); + }, + + z: function () { + this.axis_changed(); } - } - - add(this.pathView); - add(this.surfaceMesh); - add(this.workpieceMesh); - - return bbox; }, + ready: function () { + this.graphics(); + Vue.nextTick(this.update); + }, - snap: function (view) { - if (this.loading) return; - if (view != this.snapView) { - this.snapView = view; - cookie.set('snap-view', view); - } + methods: { + update: async function () { + if (!this.webglAvailable) { + return; + } - var bbox = this.get_model_bounds(); - this.controls.reset(); - bbox.getCenter(this.controls.target); - this.update_view(); + if (!this.state.selected) { + this.dirty = true; + this.scene = new THREE.Scene(); - // Compute new camera position - var center = bbox.getCenter(new THREE.Vector3()); - var offset = new THREE.Vector3(); + } else if (!this.toolpath.filename && !this.loading) { + this.loading = true; + this.dirty = true; + this.draw_loading(); + } - if (view == 'isometric') {offset.y -= 1; offset.z += 1;} - if (view == 'front') offset.y -= 1; - if (view == 'back') offset.y += 1; - if (view == 'left') offset.x -= 1; - if (view == 'right') offset.x += 1; - if (view == 'top') offset.z += 1; - if (view == 'bottom') offset.z -= 1; - offset.normalize(); + if (!this.enabled || !this.toolpath.filename) { + return; + } - // Initial camera position - var position = new THREE.Vector3().copy(center).add(offset); - this.camera.position.copy(position); - this.camera.lookAt(center); // Get correct camera orientation + async function get(url) { + const response = await fetch(`${url}?${Math.random()}`); + const arrayBuffer = await response.arrayBuffer(); - var theta = this.camera.fov / 180 * Math.PI; // View angle - var cameraLine = new THREE.Line3(center, position); - var cameraUp = new THREE.Vector3().copy(this.camera.up) - .applyQuaternion(this.camera.quaternion); - var cameraLeft = - new THREE.Vector3().copy(offset).cross(cameraUp).normalize(); + return new Float32Array(arrayBuffer); + } - var corners = [ - new THREE.Vector3(bbox.min.x, bbox.min.y, bbox.min.z), - new THREE.Vector3(bbox.min.x, bbox.min.y, bbox.max.z), - new THREE.Vector3(bbox.min.x, bbox.max.y, bbox.min.z), - new THREE.Vector3(bbox.min.x, bbox.max.y, bbox.max.z), - new THREE.Vector3(bbox.max.x, bbox.min.y, bbox.min.z), - new THREE.Vector3(bbox.max.x, bbox.min.y, bbox.max.z), - new THREE.Vector3(bbox.max.x, bbox.max.y, bbox.min.z), - new THREE.Vector3(bbox.max.x, bbox.max.y, bbox.max.z), - ] + const [positions, speeds] = await Promise.all([ + get(`/api/path/${this.toolpath.filename}/positions`), + get(`/api/path/${this.toolpath.filename}/speeds`) + ]); - var dist = this.camera.near; // Min camera dist + this.positions = positions; + this.speeds = speeds; + this.loading = false; - for (var i = 0; i < corners.length; i++) { - // Project on to camera line - var p1 = cameraLine - .closestPointToPoint(corners[i], false, new THREE.Vector3()); + // Update scene + this.scene = new THREE.Scene(); + this.draw(this.scene); + this.snap(this.snapView); - // Compute distance from projection to center - var d = p1.distanceTo(center); - if (cameraLine.closestPointToPointParameter(p1, false) < 0) d = -d; + this.update_view(); + }, - // Compute up line - var up = - new THREE.Line3(p1, new THREE.Vector3().copy(p1).add(cameraUp)); + update_surface_mode: function (mode) { + if (!this.enabled) { + return; + } - // Project on to up line - var p2 = up.closestPointToPoint(corners[i], false, new THREE.Vector3()); + if (typeof this.surfaceMaterial != "undefined") { + this.surfaceMaterial.wireframe = mode == "wire"; + this.surfaceMaterial.needsUpdate = true; + } - // Compute length - var l = p1.distanceTo(p2); + this.set_visible(this.surfaceMesh, mode == "cut" || mode == "wire"); + this.set_visible(this.workpieceMesh, mode == "solid"); + }, - // Update min camera distance - dist = Math.max(dist, d + l / Math.tan(theta / 2)); + load_surface: function (surface) { + if (typeof surface == "undefined") { + this.vertices = undefined; + this.normals = undefined; + return; + } - // Compute left line - var left = - new THREE.Line3(p1, new THREE.Vector3().copy(p1).add(cameraLeft)); + this.vertices = surface.vertices; - // Project on to left line - var p3 = - left.closestPointToPoint(corners[i], false, new THREE.Vector3()); + // Expand normals + this.normals = []; + for (let i = 0; i < surface.normals.length / 3; i++) { + for (let j = 0; j < 3; j++) { + for (let k = 0; k < 3; k++) { + this.normals.push(surface.normals[i * 3 + k]); + } + } + } + }, - // Compute length - l = p1.distanceTo(p3); + set_visible: function (target, visible) { + if (typeof target != "undefined") { + target.visible = visible; + } + this.dirty = true; + }, - // Update min camera distance - dist = Math.max(dist, d + l / Math.tan(theta / 2) / this.camera.aspect); - } + get_dims: function () { + const t = $(this.target); + const width = t.innerWidth(); + const height = t.innerHeight(); + return {width: width, height: height}; + }, - this.camera.position.copy(offset.multiplyScalar(dist * 1.2).add(center)); - } - }, + update_view: function () { + if (!this.enabled) { + return; + } + const dims = this.get_dims(); - mixins: [require('./axis-vars')] -} + this.camera.aspect = dims.width / dims.height; + this.camera.updateProjectionMatrix(); + this.renderer.setSize(dims.width, dims.height); + + if (this.loading) { + this.controls.reset(); + this.camera.position.copy(new THREE.Vector3(0, 0, 600)); + this.camera.lookAt(new THREE.Vector3(0, 0, 0)); + } + + this.dirty = true; + }, + + update_tool: function (tool) { + if (!this.enabled) { + return; + } + + if (typeof tool == "undefined") { + tool = this.toolView; + } + + if (typeof tool == "undefined") { + return; + } + + tool.position.x = this.x.pos; + tool.position.y = this.y.pos; + tool.position.z = this.z.pos; + }, + + update_envelope: function (envelope) { + if (!this.enabled || !this.axes.homed) { + return; + } + + if (typeof envelope == "undefined") { + envelope = this.envelopeView; + } + + if (typeof envelope == "undefined") { + return; + } + + const min = new THREE.Vector3(); + const max = new THREE.Vector3(); + + for (const axis of "xyz") { + min[axis] = this[axis].min - this[axis].off; + max[axis] = this[axis].max - this[axis].off; + } + + const bounds = new THREE.Box3(min, max); + if (bounds.isEmpty()) { + envelope.geometry = this.create_empty_geom(); + } else { + envelope.geometry = this.create_bbox_geom(bounds); + } + }, + + axis_changed: function () { + this.update_tool(); + this.update_envelope(); + this.dirty = true; + }, + + graphics: function () { + if (!this.webglAvailable) { + return; + } + + try { + // Renderer + this.renderer = new THREE.WebGLRenderer({antialias: true, alpha: true}); + this.renderer.setPixelRatio(window.devicePixelRatio); + this.renderer.setClearColor(0, 0); + this.target.appendChild(this.renderer.domElement); + + } catch (e) { + console.log("WebGL not supported: ", e); + return; + } + + this.enabled = true; + + // Camera + this.camera = new THREE.PerspectiveCamera(45, 4 / 3, 1, 10000); + + // Lighting + this.ambient = new THREE.AmbientLight(0xffffff, 0.5); + + const keyLight = new THREE.DirectionalLight(new THREE.Color("hsl(30, 100%, 75%)"), 0.75); + keyLight.position.set(-100, 0, 100); + + const fillLight = new THREE.DirectionalLight(new THREE.Color("hsl(240, 100%, 75%)"), 0.25); + fillLight.position.set(100, 0, 100); + + const backLight = new THREE.DirectionalLight(0xffffff, 0.5); + backLight.position.set(100, 0, -100).normalize(); + + this.lights = new THREE.Group(); + this.lights.add(keyLight); + this.lights.add(fillLight); + this.lights.add(backLight); + + // Surface material + this.surfaceMaterial = this.create_surface_material(); + + // Controls + this.controls = new orbit(this.camera, this.renderer.domElement); + this.controls.enableDamping = true; + this.controls.dampingFactor = 0.2; + this.controls.rotateSpeed = 0.25; + this.controls.enableZoom = true; + + // Move lights with scene + this.controls.addEventListener("change", function (scope) { + return function () { + keyLight.position.copy(scope.camera.position); + fillLight.position.copy(scope.camera.position); + backLight.position.copy(scope.camera.position); + keyLight.lookAt(scope.controls.target); + fillLight.lookAt(scope.controls.target); + backLight.lookAt(scope.controls.target); + scope.dirty = true; + }; + }(this)); + + // Events + window.addEventListener("resize", this.update_view, false); + + // Start it + this.render(); + }, + + create_surface_material: function () { + return new THREE.MeshPhongMaterial({ + specular: 0x111111, + shininess: 10, + side: THREE.FrontSide, + color: 0x0c2d53 + }); + }, + + draw_loading: function () { + this.scene = new THREE.Scene(); + + const geometry = new THREE.TextGeometry("Loading 3D View...", { + font: new THREE.Font(font), + size: 40, + height: 5, + curveSegments: 12, + bevelEnabled: true, + bevelThickness: 10, + bevelSize: 8, + bevelSegments: 5 + }); + geometry.computeBoundingBox(); + + const mesh = new THREE.Mesh(geometry, this.surfaceMaterial); + + this.scene.add(mesh); + this.scene.add(this.ambient); + this.scene.add(this.lights); + this.update_view(); + }, + + draw_workpiece: function (scene, material) { + if (typeof this.workpiece == "undefined") { + return; + } + + let min = this.workpiece.min; + let max = this.workpiece.max; + + min = new THREE.Vector3(min[0], min[1], min[2]); + max = new THREE.Vector3(max[0], max[1], max[2]); + const dims = max.clone().sub(min); + + const geometry = new THREE.BoxGeometry(dims.x, dims.y, dims.z); + const mesh = new THREE.Mesh(geometry, material); + + const offset = dims.clone(); + offset.divideScalar(2); + offset.add(min); + + mesh.position.add(offset); + + geometry.computeBoundingBox(); + + scene.add(mesh); + + return mesh; + }, + + draw_surface: function (scene, material) { + if (typeof this.vertices == "undefined") { + return; + } + + const geometry = new THREE.BufferGeometry(); + + geometry.addAttribute("position", new THREE.Float32BufferAttribute(this.vertices, 3)); + geometry.addAttribute("normal", new THREE.Float32BufferAttribute(this.normals, 3)); + + geometry.computeBoundingSphere(); + geometry.computeBoundingBox(); + + return new THREE.Mesh(geometry, material); + }, + + draw_tool: function (scene, bbox) { + // Tool size is relative to bounds + const size = bbox.getSize(new THREE.Vector3()); + let length = (size.x + size.y + size.z) / 24; + + if (length < 1) { + length = 1; + } + + const material = new THREE.MeshPhongMaterial({ + transparent: true, + opacity: 0.75, + specular: 0x161616, + shininess: 10, + color: 0xffa500 // Orange + }); + + const geometry = new THREE.CylinderGeometry(length / 2, 0, length, 128); + geometry.translate(0, length / 2, 0); + geometry.rotateX(0.5 * Math.PI); + + const mesh = new THREE.Mesh(geometry, material); + this.update_tool(mesh); + mesh.visible = this.showTool; + scene.add(mesh); + return mesh; + }, + + draw_axis: function (axis, up, length, radius) { + let color; + + if (axis == 0) { + color = 0xff0000; + } else if (axis == 1) { + color = 0x00ff00; + } else if (axis == 2) { + color = 0x0000ff; + } + + const group = new THREE.Group(); + const material = new THREE.MeshPhongMaterial({ + specular: 0x161616, shininess: 10, color: color + }); + let geometry = new THREE.CylinderGeometry(radius, radius, length, 128); + geometry.translate(0, -length / 2, 0); + group.add(new THREE.Mesh(geometry, material)); + + geometry = new THREE.CylinderGeometry(1.5 * radius, 0, 2 * radius, 128); + geometry.translate(0, -length - radius, 0); + group.add(new THREE.Mesh(geometry, material)); + + if (axis == 0) { + group.rotateZ((up ? 0.5 : 1.5) * Math.PI); + } else if (axis == 1) { + group.rotateX((up ? 0 : 1 ) * Math.PI); + } else if (axis == 2) { + group.rotateX((up ? 1.5 : 0.5) * Math.PI); + } + + return group; + }, + + draw_axes: function (scene, bbox) { + const size = bbox.getSize(new THREE.Vector3()); + let length = (size.x + size.y + size.z) / 3; + length /= 10; + + if (length < 1) { + length = 1; + } + + const radius = length / 20; + + const group = new THREE.Group(); + + for (let axis = 0; axis < 3; axis++) { + for (let up = 0; up < 2; up++) { + group.add(this.draw_axis(axis, up, length, radius)); + } + } + + group.visible = this.showAxes; + scene.add(group); + + return group; + }, + + get_color: function (speed) { + if (isNaN(speed)) { + return [255, 0, 0]; + } // Rapid + + let intensity = speed / this.toolpath.maxSpeed; + if (typeof speed == "undefined" || !this.showIntensity) { + intensity = 1; + } + + return [0, 255 * intensity, 127 * (1 - intensity)]; + }, + + draw_path: function (scene) { + const geometry = new THREE.BufferGeometry(); + const material = new THREE.LineBasicMaterial({ + vertexColors: THREE.VertexColors, + linewidth: 1.5 + }); + + const positions = new THREE.Float32BufferAttribute(this.positions, 3); + geometry.addAttribute("position", positions); + + let colors = []; + for (let i = 0; i < this.speeds.length; i++) { + const color = this.get_color(this.speeds[i]); + Array.prototype.push.apply(colors, color); + } + + colors = new THREE.Uint8BufferAttribute(colors, 3, true); + geometry.addAttribute("color", colors); + + geometry.computeBoundingSphere(); + geometry.computeBoundingBox(); + + const line = new THREE.Line(geometry, material); + + line.visible = this.showPath; + scene.add(line); + + return line; + }, + + create_empty_geom: function () { + const geometry = new THREE.BufferGeometry(); + geometry.addAttribute("position", + new THREE.Float32BufferAttribute([], 3)); + return geometry; + }, + + create_bbox_geom: function (bbox) { + const vertices = []; + + if (!bbox.isEmpty()) { + // Top + vertices.push(bbox.min.x, bbox.min.y, bbox.min.z); + vertices.push(bbox.max.x, bbox.min.y, bbox.min.z); + vertices.push(bbox.max.x, bbox.min.y, bbox.min.z); + vertices.push(bbox.max.x, bbox.min.y, bbox.max.z); + vertices.push(bbox.max.x, bbox.min.y, bbox.max.z); + vertices.push(bbox.min.x, bbox.min.y, bbox.max.z); + vertices.push(bbox.min.x, bbox.min.y, bbox.max.z); + vertices.push(bbox.min.x, bbox.min.y, bbox.min.z); + + // Bottom + vertices.push(bbox.min.x, bbox.max.y, bbox.min.z); + vertices.push(bbox.max.x, bbox.max.y, bbox.min.z); + vertices.push(bbox.max.x, bbox.max.y, bbox.min.z); + vertices.push(bbox.max.x, bbox.max.y, bbox.max.z); + vertices.push(bbox.max.x, bbox.max.y, bbox.max.z); + vertices.push(bbox.min.x, bbox.max.y, bbox.max.z); + vertices.push(bbox.min.x, bbox.max.y, bbox.max.z); + vertices.push(bbox.min.x, bbox.max.y, bbox.min.z); + + // Sides + vertices.push(bbox.min.x, bbox.min.y, bbox.min.z); + vertices.push(bbox.min.x, bbox.max.y, bbox.min.z); + vertices.push(bbox.max.x, bbox.min.y, bbox.min.z); + vertices.push(bbox.max.x, bbox.max.y, bbox.min.z); + vertices.push(bbox.max.x, bbox.min.y, bbox.max.z); + vertices.push(bbox.max.x, bbox.max.y, bbox.max.z); + vertices.push(bbox.min.x, bbox.min.y, bbox.max.z); + vertices.push(bbox.min.x, bbox.max.y, bbox.max.z); + } + + const geometry = new THREE.BufferGeometry(); + + geometry.addAttribute("position", + new THREE.Float32BufferAttribute(vertices, 3)); + + return geometry; + }, + + draw_bbox: function (scene, bbox) { + const geometry = this.create_bbox_geom(bbox); + const material = new THREE.LineBasicMaterial({color: 0xffffff}); + const line = new THREE.LineSegments(geometry, material); + + line.visible = this.showBBox; + + scene.add(line); + + return line; + }, + + draw_envelope: function (scene) { + const geometry = this.create_empty_geom(); + const material = new THREE.LineBasicMaterial({color: 0x00f7ff}); + const line = new THREE.LineSegments(geometry, material); + + line.visible = this.showBBox; + + scene.add(line); + this.update_envelope(line); + + return line; + }, + + draw: function (scene) { + // Lights + scene.add(this.ambient); + scene.add(this.lights); + + // Model + this.pathView = this.draw_path(scene); + this.surfaceMesh = this.draw_surface(scene, this.surfaceMaterial); + this.workpieceMesh = this.draw_workpiece(scene, this.surfaceMaterial); + this.update_surface_mode(this.surfaceMode); + + // Compute bounding box + const bbox = this.get_model_bounds(); + + // Tool, axes & bounds + this.toolView = this.draw_tool(scene, bbox); + this.axesView = this.draw_axes(scene, bbox); + this.bboxView = this.draw_bbox(scene, bbox); + this.envelopeView = this.draw_envelope(scene); + }, + + render: function () { + window.requestAnimationFrame(this.render); + + if (typeof this.scene == "undefined") { + return; + } + + if (this.controls.update() || this.dirty) { + this.dirty = false; + this.renderer.render(this.scene, this.camera); + } + }, + + get_model_bounds: function () { + const bbox = new THREE.Box3(new THREE.Vector3(0, 0, 0), + new THREE.Vector3(0.00001, 0.00001, 0.00001)); + + function add(o) { + if (typeof o != "undefined") { + const oBBox = new THREE.Box3(); + oBBox.setFromObject(o); + bbox.union(oBBox); + } + } + + add(this.pathView); + add(this.surfaceMesh); + add(this.workpieceMesh); + + return bbox; + }, + + snap: function (view) { + if (this.loading) { + return; + } + + if (view != this.snapView) { + this.snapView = view; + cookie.set("snap-view", view); + } + + const bbox = this.get_model_bounds(); + this.controls.reset(); + bbox.getCenter(this.controls.target); + this.update_view(); + + // Compute new camera position + const center = bbox.getCenter(new THREE.Vector3()); + const offset = new THREE.Vector3(); + + switch (view) { + case "isometric": offset.y -= 1; offset.z += 1; break; + case "front": offset.y -= 1; break; + case "back": offset.y += 1; break; + case "left": offset.x -= 1; break; + case "right": offset.x += 1; break; + case "top": offset.z += 1; break; + case "bottom": offset.z -= 1; break; + } + + offset.normalize(); + + // Initial camera position + const position = new THREE.Vector3().copy(center).add(offset); + this.camera.position.copy(position); + this.camera.lookAt(center); // Get correct camera orientation + + const theta = this.camera.fov / 180 * Math.PI; // View angle + const cameraLine = new THREE.Line3(center, position); + const cameraUp = new THREE.Vector3() + .copy(this.camera.up) + .applyQuaternion(this.camera.quaternion); + const cameraLeft = new THREE.Vector3() + .copy(offset) + .cross(cameraUp) + .normalize(); + + const corners = [ + new THREE.Vector3(bbox.min.x, bbox.min.y, bbox.min.z), + new THREE.Vector3(bbox.min.x, bbox.min.y, bbox.max.z), + new THREE.Vector3(bbox.min.x, bbox.max.y, bbox.min.z), + new THREE.Vector3(bbox.min.x, bbox.max.y, bbox.max.z), + new THREE.Vector3(bbox.max.x, bbox.min.y, bbox.min.z), + new THREE.Vector3(bbox.max.x, bbox.min.y, bbox.max.z), + new THREE.Vector3(bbox.max.x, bbox.max.y, bbox.min.z), + new THREE.Vector3(bbox.max.x, bbox.max.y, bbox.max.z), + ]; + + let dist = this.camera.near; // Min camera dist + + for (let i = 0; i < corners.length; i++) { + // Project on to camera line + const p1 = cameraLine.closestPointToPoint(corners[i], false, new THREE.Vector3()); + + // Compute distance from projection to center + let d = p1.distanceTo(center); + if (cameraLine.closestPointToPointParameter(p1, false) < 0) { + d = -d; + } + + // Compute up line + const up = new THREE.Line3(p1, new THREE.Vector3().copy(p1).add(cameraUp)); + + // Project on to up line + const p2 = up.closestPointToPoint(corners[i], false, new THREE.Vector3()); + + // Compute length + let l = p1.distanceTo(p2); + + // Update min camera distance + dist = Math.max(dist, d + l / Math.tan(theta / 2)); + + // Compute left line + const left = new THREE.Line3(p1, new THREE.Vector3().copy(p1).add(cameraLeft)); + + // Project on to left line + const p3 = left.closestPointToPoint(corners[i], false, new THREE.Vector3()); + + // Compute length + l = p1.distanceTo(p3); + + // Update min camera distance + dist = Math.max(dist, d + l / Math.tan(theta / 2) / this.camera.aspect); + } + + this.camera.position.copy(offset.multiplyScalar(dist * 1.2).add(center)); + } + }, + + mixins: [require("./axis-vars")] +}; diff --git a/src/js/settings-view.js b/src/js/settings-view.js index ab87296..ac15d35 100644 --- a/src/js/settings-view.js +++ b/src/js/settings-view.js @@ -1,14 +1,14 @@ module.exports = { - template: "#settings-view-template", + template: "#settings-view-template", - attached: function () { - this.svelteComponent = SvelteComponents.createComponent( - "SettingsView", - document.getElementById("settings") - ); - }, + attached: function () { + this.svelteComponent = SvelteComponents.createComponent( + "SettingsView", + document.getElementById("settings") + ); + }, - detached: function() { - this.svelteComponent.$destroy(); - } + detached: function() { + this.svelteComponent.$destroy(); + } }; diff --git a/src/js/sock.js b/src/js/sock.js index 5c274cd..0dcd4d5 100644 --- a/src/js/sock.js +++ b/src/js/sock.js @@ -1,127 +1,106 @@ -/******************************************************************************\ +"use strict"; - This file is part of the Buildbotics firmware. +const Sock = function (url, retry, timeout) { + if (!(this instanceof Sock)) { + return new Sock(url, retry); + } - Copyright (c) 2015 - 2018, Buildbotics LLC - All rights reserved. + if (typeof retry == "undefined") { + retry = 2000; + } + if (typeof timeout == "undefined") { + timeout = 16000; + } - This file ("the software") is free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License, - version 2 as published by the Free Software Foundation. You should - have received a copy of the GNU General Public License, version 2 - along with the software. If not, see . + this.url = url; + this.retry = retry; + this.timeout = timeout; + this.divisions = 4; + this.count = 0; - The software is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + this.connect(); +}; - You should have received a copy of the GNU Lesser General Public - License along with the software. If not, see - . +Sock.prototype.onmessage = function () { + // Ignore +}; - For information regarding this software email: - "Joseph Coffland" - -\******************************************************************************/ - -'use strict' - - -var Sock = function (url, retry, timeout) { - if (!(this instanceof Sock)) return new Sock(url, retry); - - if (typeof retry == 'undefined') retry = 2000; - if (typeof timeout == 'undefined') timeout = 16000; - - this.url = url; - this.retry = retry; - this.timeout = timeout; - this.divisions = 4; - this.count = 0; - - this.connect(); -} - - -Sock.prototype.onmessage = function () {} -Sock.prototype.onopen = function () {} -Sock.prototype.onclose = function () {} +Sock.prototype.onopen = function () { + // Ignore +}; +Sock.prototype.onclose = function () { + // Ignore +}; Sock.prototype.connect = function () { - console.debug('connecting to', this.url); - this.close(); + console.debug("connecting to", this.url); + this.close(); - this._sock = new SockJS(this.url); + this._sock = new SockJS(this.url); - this._sock.onmessage = function (e) { - console.debug('msg:', e.data); - this.heartbeat('msg'); - this.onmessage(e); - }.bind(this); + this._sock.onmessage = function (e) { + console.debug("msg:", e.data); + this.heartbeat("msg"); + this.onmessage(e); + }.bind(this); + this._sock.onopen = function () { + console.debug("connected"); + this.heartbeat("open"); + this.onopen(); + }.bind(this); - this._sock.onopen = function () { - console.debug('connected'); - this.heartbeat('open'); - this.onopen(); - }.bind(this); - - - this._sock.onclose = function () { - console.debug('disconnected'); - this._cancel_timeout(); - - this.onclose(); - if (typeof this._sock != 'undefined') - setTimeout(this.connect.bind(this), this.retry); - }.bind(this); -} + this._sock.onclose = function () { + console.debug("disconnected"); + this._cancel_timeout(); + this.onclose(); + if (typeof this._sock != "undefined") { + setTimeout(this.connect.bind(this), this.retry); + } + }.bind(this); +}; Sock.prototype._timedout = function () { - // Divide timeout so slow browser doesn't trigger timeouts when the - // connection is good. - if (this.divisions <= ++this.count) { - console.debug('connection timedout'); - this._timeout = undefined; - this._sock.close(); - - } else this._set_timeout(); -} + // Divide timeout so slow browser doesn't trigger timeouts when the + // connection is good. + if (this.divisions <= ++this.count) { + console.debug("connection timedout"); + this._timeout = undefined; + this._sock.close(); + } else { + this._set_timeout(); + } +}; Sock.prototype._cancel_timeout = function () { - clearTimeout(this._timeout); - this._timeout = undefined; - this.count = 0; -} - + clearTimeout(this._timeout); + this._timeout = undefined; + this.count = 0; +}; Sock.prototype._set_timeout = function () { - this._timeout = setTimeout(this._timedout.bind(this), - this.timeout / this.divisions); -} - - -Sock.prototype.heartbeat = function (msg) { - //console.debug('heartbeat ' + new Date().toLocaleTimeString() + ' ' + msg); - this._cancel_timeout(); - this._set_timeout(); -} + this._timeout = setTimeout(this._timedout.bind(this), + this.timeout / this.divisions); +}; +Sock.prototype.heartbeat = function () { + this._cancel_timeout(); + this._set_timeout(); +}; Sock.prototype.close = function () { - if (typeof this._sock != 'undefined') { - var sock = this._sock; - this._sock = undefined; - sock.close(); - } -} + if (typeof this._sock != "undefined") { + const sock = this._sock; + this._sock = undefined; + sock.close(); + } +}; +Sock.prototype.send = function (msg) { + this._sock.send(msg); +}; -Sock.prototype.send = function (msg) {this._sock.send(msg)} - - -module.exports = Sock +module.exports = Sock; diff --git a/src/js/templated-input.js b/src/js/templated-input.js index 0d5c2db..801174d 100644 --- a/src/js/templated-input.js +++ b/src/js/templated-input.js @@ -1,69 +1,69 @@ -'use strict' +"use strict"; module.exports = { - replace: true, - template: '#templated-input-template', - props: ['name', 'model', 'template'], + replace: true, + template: "#templated-input-template", + props: ["name", "model", "template"], - data: function () { - return { view: '' } - }, - - computed: { - metric: function () { - return this.$root.display_units === "METRIC"; + data: function () { + return { view: "" }; }, - _view: function () { - if (this.template.scale) { - if (this.metric) { - return 1 * this.model.toFixed(3); + computed: { + metric: function () { + return this.$root.display_units === "METRIC"; + }, + + _view: function () { + if (this.template.scale) { + if (this.metric) { + return 1 * this.model.toFixed(3); + } + + return 1 * (this.model / this.template.scale).toFixed(4); + } + + return this.model; + }, + + units: function () { + return (this.metric || !this.template.iunit) + ? this.template.unit + : this.template.iunit; + }, + + title: function () { + let s = `Default :${this.template.default} ${(this.template.unit || "")}`; + + if (typeof this.template.help != "undefined") { + s = `${this.template.help}\n${s}`; + } + + return s; } - - return 1 * (this.model / this.template.scale).toFixed(4); - } - - return this.model; }, - units: function () { - return (this.metric || !this.template.iunit) - ? this.template.unit - : this.template.iunit; + watch: { + _view: function () { + this.view = this._view; + }, + + view: function () { + if (this.template.scale && !this.metric) { + this.model = this.view * this.template.scale; + } else { + this.model = this.view; + } + } }, - title: function () { - var s = `Default :${this.template.default} ${(this.template.unit || '')}`; - - if (typeof this.template.help != 'undefined') { - s = this.template.help + '\n' + s; - } - - return s; - } - }, - - watch: { - _view: function () { - this.view = this._view + ready: function () { + this.view = this._view; }, - view: function () { - if (this.template.scale && !this.metric) { - this.model = this.view * this.template.scale; - } else { - this.model = this.view; - } + methods: { + change: function () { + this.$dispatch("input-changed"); + } } - }, - - ready: function () { - this.view = this._view - }, - - methods: { - change: function () { - this.$dispatch('input-changed') - } - } -} +}; diff --git a/src/js/tool-view.js b/src/js/tool-view.js index e4bc390..6d7e8df 100644 --- a/src/js/tool-view.js +++ b/src/js/tool-view.js @@ -1,277 +1,252 @@ -/******************************************************************************\ +"use strict"; - This file is part of the Buildbotics firmware. - - Copyright (c) 2015 - 2018, Buildbotics LLC - All rights reserved. - - This file ("the software") is free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License, - version 2 as published by the Free Software Foundation. You should - have received a copy of the GNU General Public License, version 2 - along with the software. If not, see . - - The software is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the software. If not, see - . - - For information regarding this software email: - "Joseph Coffland" - -\******************************************************************************/ - -'use strict'; - -const api = require('./api'); -const modbus = require('./modbus.js'); +const api = require("./api"); +const modbus = require("./modbus.js"); const merge = require("lodash.merge"); module.exports = { - template: '#tool-view-template', - props: ['config', 'template', 'state'], + template: "#tool-view-template", + props: ["config", "template", "state"], - data: function () { - return { - address: 0, - value: 0, - toolList: [ - { - id: "disabled", - name: "Disabled" - }, - { - id: "router", - type: "PWM Spindle", - name: "Router (Makita, etc)" - }, - { - id: "laser", - type: "PWM Spindle", - name: "Laser (J Tech, etc)" - }, - { - id: "pwm", - name: "PWM Spindle" - }, - { - id: "unsupported-separator", - name: "Unsupported Tools", - disabled: true, - unsupported: true - }, - { - id: "huanyang-vfd", - name: "Huanyang VFD", - unsupported: true - }, - { - id: "custom-modbus-vfd", - name: "Custom Modbus VFD", - unsupported: true - }, - { - id: "ac-tech-vfd", - name: "AC-Tech VFD", - unsupported: true - }, - { - id: "nowforever-vfd", - name: "Nowforever VFD", - unsupported: true - }, - { - id: "delta-vfd", - name: "Delta VFD015M21A (Beta)", - unsupported: true - }, - { - id: "yl600-vfd", - name: "YL600, YL620, YL620-A VFD (Beta)", - unsupported: true - }, - { - id: "fr-d700-vfd", - name: "FR-D700 (Beta)", - unsupported: true - }, - { - id: "sunfar-e300-vfd", - name: "Sunfar E300 (Beta)", - unsupported: true - }, - { - id: "omron-mx2-vfd", - name: "OMRON MX2", - unsupported: true + data: function () { + return { + address: 0, + value: 0, + toolList: [ + { + id: "disabled", + name: "Disabled" + }, + { + id: "router", + type: "PWM Spindle", + name: "Router (Makita, etc)" + }, + { + id: "laser", + type: "PWM Spindle", + name: "Laser (J Tech, etc)" + }, + { + id: "pwm", + name: "PWM Spindle" + }, + { + id: "unsupported-separator", + name: "Unsupported Tools", + disabled: true, + unsupported: true + }, + { + id: "huanyang-vfd", + name: "Huanyang VFD", + unsupported: true + }, + { + id: "custom-modbus-vfd", + name: "Custom Modbus VFD", + unsupported: true + }, + { + id: "ac-tech-vfd", + name: "AC-Tech VFD", + unsupported: true + }, + { + id: "nowforever-vfd", + name: "Nowforever VFD", + unsupported: true + }, + { + id: "delta-vfd", + name: "Delta VFD015M21A (Beta)", + unsupported: true + }, + { + id: "yl600-vfd", + name: "YL600, YL620, YL620-A VFD (Beta)", + unsupported: true + }, + { + id: "fr-d700-vfd", + name: "FR-D700 (Beta)", + unsupported: true + }, + { + id: "sunfar-e300-vfd", + name: "Sunfar E300 (Beta)", + unsupported: true + }, + { + id: "omron-mx2-vfd", + name: "OMRON MX2", + unsupported: true + } + ] + }; + }, + + components: { + "modbus-reg": require("./modbus-reg.js") + }, + + watch: { + "state.mr": function () { + this.value = this.state.mr; + } + }, + + events: { + "input-changed": function () { + this.$dispatch("config-changed"); + + return false; + }, + }, + + ready: function () { + this.value = this.state.mr; + }, + + computed: { + regs_tmpl: function () { + return this.template["modbus-spindle"].regs; + }, + + tool_type: function () { + return this.config.tool["tool-type"].toUpperCase(); + }, + + selected_tool: function () { + return this.config.tool["selected-tool"]; + }, + + is_pwm_spindle: function () { + return this.selected_tool == "pwm"; + }, + + is_modbus: function () { + switch (this.selected_tool) { + case "disabled": + case "laser": + case "router": + case "pwm": + return false; + + default: + return true; + } + }, + + modbus_status: function () { + return modbus.status_to_string(this.state.mx); + } + }, + + methods: { + change_selected_tool: function () { + const selectedToolSettings = this.config["selected-tool-settings"] || {}; + const settings = selectedToolSettings[this.selected_tool] || {}; + this.config.tool = merge({}, this.config.tool, settings["tool"]); + this.config["pwm-spindle"] = merge({}, this.config["pwm-spindle"], settings["pwm-spindle"]); + this.config["modbus-spindle"] = merge({}, this.config["modbus-spindle"], settings["modbus-spindle"]); + + const tool = this.toolList.find(tool => tool.id == this.config.tool["selected-tool"]); + this.config.tool["tool-type"] = tool.type || tool.name; + + this.$dispatch("config-changed"); + }, + + show_tool_settings: function (key) { + switch (true) { + case key === "tool-type": + case key === "selected-tool": + return false; + + case this.selected_tool === "disabled": + return false; + + case this.selected_tool === "laser": + case this.selected_tool === "router": + switch (key) { + case "tool-enable-mode": + return true; + + default: + return false; + } + + default: + return true; + } + }, + + get_reg_type: function (reg) { + return this.regs_tmpl.template["reg-type"].values[this.state[`${reg}vt`]]; + }, + + get_reg_addr: function (reg) { + return this.state[`${reg}va`]; + }, + + get_reg_value: function (reg) { + return this.state[`${reg}vv`]; + }, + + get_reg_fails: function (reg) { + const fails = this.state[`${reg}vr`]; + return fails == 255 ? "Max" : fails; + }, + + show_modbus_field: function (key) { + return key != "regs" && (key != "multi-write" || this.tool_type == "CUSTOM MODBUS VFD"); + }, + + read: function (e) { + e.preventDefault(); + api.put("modbus/read", { address: this.address }); + }, + + write: function (e) { + e.preventDefault(); + api.put("modbus/write", { address: this.address, value: this.value }); + }, + + customize: function (e) { + e.preventDefault(); + this.config.tool["tool-type"] = "Custom Modbus VFD"; + + const regs = this.config["modbus-spindle"].regs; + for (let i = 0; i < regs.length; i++) { + const reg = this.regs_tmpl.index[i]; + regs[i]["reg-type"] = this.get_reg_type(reg); + regs[i]["reg-addr"] = this.get_reg_addr(reg); + regs[i]["reg-value"] = this.get_reg_value(reg); + } + + this.$dispatch("config-changed"); + }, + + clear: function (e) { + e.preventDefault(); + this.config.tool["tool-type"] = "Custom Modbus VFD"; + + const regs = this.config["modbus-spindle"].regs; + for (let i = 0; i < regs.length; i++) { + regs[i]["reg-type"] = "disabled"; + regs[i]["reg-addr"] = 0; + regs[i]["reg-value"] = 0; + } + + this.$dispatch("config-changed"); + }, + + reset_failures: function (e) { + e.preventDefault(); + const regs = this.config["modbus-spindle"].regs; + for (let reg = 0; reg < regs.length; reg++) { + this.$dispatch("send", `$${reg}vr=0`); + } } - ] } - }, - - components: { - 'modbus-reg': require('./modbus-reg.js') - }, - - watch: { - 'state.mr': function () { this.value = this.state.mr } - }, - - events: { - 'input-changed': function () { - this.$dispatch('config-changed'); - - return false; - }, - }, - - ready: function () { - this.value = this.state.mr; - }, - - computed: { - regs_tmpl: function () { - return this.template['modbus-spindle'].regs; - }, - - tool_type: function () { - return this.config.tool['tool-type'].toUpperCase(); - }, - - selected_tool: function () { - return this.config.tool['selected-tool']; - }, - - is_pwm_spindle: function () { - return this.selected_tool == 'pwm'; - }, - - is_modbus: function () { - switch (this.selected_tool) { - case "disabled": - case "laser": - case "router": - case "pwm": - return false; - - default: - return true; - } - }, - - modbus_status: function () { - return modbus.status_to_string(this.state.mx); - } - }, - - methods: { - change_selected_tool: function () { - const selectedToolSettings = this.config['selected-tool-settings'] || {}; - const settings = selectedToolSettings[this.selected_tool] || {}; - this.config.tool = merge({}, this.config.tool, settings['tool']); - this.config['pwm-spindle'] = merge({}, this.config['pwm-spindle'], settings['pwm-spindle']); - this.config['modbus-spindle'] = merge({}, this.config['modbus-spindle'], settings['modbus-spindle']); - - const tool = this.toolList.find(tool => tool.id == this.config.tool['selected-tool']); - this.config.tool["tool-type"] = tool.type || tool.name; - - this.$dispatch("config-changed"); - }, - - show_tool_settings: function (key) { - switch (true) { - case key === "tool-type": - case key === "selected-tool": - return false; - - case this.selected_tool === "disabled": - return false; - - case this.selected_tool === "laser": - case this.selected_tool === "router": - switch (key) { - case "tool-enable-mode": - return true; - - default: - return false; - } - - default: - return true; - } - }, - - get_reg_type: function (reg) { - return this.regs_tmpl.template['reg-type'].values[this.state[reg + 'vt']]; - }, - - get_reg_addr: function (reg) { - return this.state[reg + 'va']; - }, - - get_reg_value: function (reg) { - return this.state[reg + 'vv']; - }, - - get_reg_fails: function (reg) { - const fails = this.state[reg + 'vr'] - return fails == 255 ? 'Max' : fails; - }, - - show_modbus_field: function (key) { - return key != 'regs' && - (key != 'multi-write' || this.tool_type == 'CUSTOM MODBUS VFD'); - }, - - read: function (e) { - e.preventDefault(); - api.put('modbus/read', { address: this.address }); - }, - - write: function (e) { - e.preventDefault(); - api.put('modbus/write', { address: this.address, value: this.value }); - }, - - customize: function (e) { - e.preventDefault(); - this.config.tool['tool-type'] = 'Custom Modbus VFD'; - - const regs = this.config['modbus-spindle'].regs; - for (let i = 0; i < regs.length; i++) { - const reg = this.regs_tmpl.index[i]; - regs[i]['reg-type'] = this.get_reg_type(reg); - regs[i]['reg-addr'] = this.get_reg_addr(reg); - regs[i]['reg-value'] = this.get_reg_value(reg); - } - - this.$dispatch('config-changed'); - }, - - clear: function (e) { - e.preventDefault(); - this.config.tool['tool-type'] = 'Custom Modbus VFD'; - - const regs = this.config['modbus-spindle'].regs; - for (let i = 0; i < regs.length; i++) { - regs[i]['reg-type'] = 'disabled'; - regs[i]['reg-addr'] = 0; - regs[i]['reg-value'] = 0; - } - - this.$dispatch('config-changed'); - }, - - reset_failures: function (e) { - e.preventDefault(); - const regs = this.config['modbus-spindle'].regs; - for (let reg = 0; reg < regs.length; reg++) - this.$dispatch('send', '\$' + reg + 'vr=0'); - } - } -} +}; diff --git a/src/js/unit-value.js b/src/js/unit-value.js index de4f4be..72ec6ac 100644 --- a/src/js/unit-value.js +++ b/src/js/unit-value.js @@ -1,47 +1,47 @@ -'use strict' +"use strict"; module.exports = { - replace: true, - template: '{{text}}{{metric ? unit : iunit}}', - props: ['value', 'precision', 'unit', 'iunit', 'scale'], + replace: true, + template: '{{text}}{{metric ? unit : iunit}}', + props: ["value", "precision", "unit", "iunit", "scale"], - computed: { - metric: { - cache: false, - get: function () { - return this.$root.display_units === "METRIC"; - } + computed: { + metric: { + cache: false, + get: function () { + return this.$root.display_units === "METRIC"; + } + }, + + text: function () { + let value = this.value; + if (typeof value == "undefined") { + return ""; + } + + if (!this.metric) { + value /= this.scale; + } + + return (1 * value.toFixed(this.precision)).toLocaleString(); + } }, - text: function () { - var value = this.value; - if (typeof value == 'undefined') { - return ''; - } + ready: function () { + if (typeof this.precision == "undefined") { + this.precision = 0; + } - if (!this.metric) { - value /= this.scale; - } + if (typeof this.unit == "undefined") { + this.unit = "mm"; + } - return (1 * value.toFixed(this.precision)).toLocaleString(); + if (typeof this.iunit == "undefined") { + this.iunit = "in"; + } + + if (typeof this.scale == "undefined") { + this.scale = 25.4; + } } - }, - - ready: function () { - if (typeof this.precision == 'undefined') { - this.precision = 0; - } - - if (typeof this.unit == 'undefined') { - this.unit = 'mm'; - } - - if (typeof this.iunit == 'undefined') { - this.iunit = 'in'; - } - - if (typeof this.scale == 'undefined') { - this.scale = 25.4; - } - } -} +}; diff --git a/src/js/utils.js b/src/js/utils.js new file mode 100644 index 0000000..f21b9e9 --- /dev/null +++ b/src/js/utils.js @@ -0,0 +1,9 @@ +function clickFileInput(formClass) { + const form = document.querySelector(`.${formClass}`); + form.reset(); + form.querySelector("input").click(); +} + +module.exports = { + clickFileInput +}; diff --git a/src/svelte-components/src/components/AdminNetworkView.svelte b/src/svelte-components/src/components/AdminNetworkView.svelte index 72d8844..37accb8 100644 --- a/src/svelte-components/src/components/AdminNetworkView.svelte +++ b/src/svelte-components/src/components/AdminNetworkView.svelte @@ -1,204 +1,210 @@
    -

    Network Info

    +

    Network Info

    -
    -
    - - - - {$networkInfo.hostname} - - - +
    +
    + + + + {$networkInfo.hostname} + + + +
    -
    -
    -
    - - - {#each $networkInfo.ipAddresses as ipAddress} -
    - - {ipAddress} - -
    - {/each} -
    +
    +
    + + + {#each $networkInfo.ipAddresses as ipAddress} +
    + + {ipAddress} + +
    + {/each} +
    +
    -
    -
    -
    - -
    - - - {#if $networkInfo.wifi.networks.length === 0} - - Scanning... - - {:else} - {#each $networkInfo.wifi.networks as network} - onNetworkSelected(network)} - > - - - - - {network.Name} - {#if network.Encryption !== "Open"} - - - - {/if} - - {/each} - {/if} - - - - Click on a Wi-Fi network to connect or disconnect. - -
    +
    +
    + +
    + + + {#if $networkInfo.wifi.networks.length === 0} + + Scanning... + + {:else} + {#each $networkInfo.wifi.networks as network} + + onNetworkSelected(network)} + > + + + + + {network.Name} + {#if network.Encryption !== "Open"} + + + + {/if} + + {/each} + {/if} + + + + Click on a Wi-Fi network to connect or disconnect. + +
    +
    -
    diff --git a/src/svelte-components/src/components/ConfigTemplatedInput.svelte b/src/svelte-components/src/components/ConfigTemplatedInput.svelte index a5f2950..1d5fa4a 100644 --- a/src/svelte-components/src/components/ConfigTemplatedInput.svelte +++ b/src/svelte-components/src/components/ConfigTemplatedInput.svelte @@ -1,131 +1,131 @@ {#if template} -
    - +
    + - {#if template.values} - - {:else if template.type === "bool"} - - {:else if template.type === "float"} - - {:else if template.type === "int"} - - {:else if template.type === "string"} - - {:else if template.type == "text"} -