From de0e330ad2ae19580ea509a02ba3745e79e11211 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Kr=C3=BChlmann?= Date: Mon, 1 Aug 2022 10:52:49 +0200 Subject: [PATCH] Add unused import filter --- .eslintrc.js | 43 +- package-lock.json | 653 +++++++++- package.json | 19 +- ui/balance_druid/inputs.ts | 20 +- ui/balance_druid/presets.ts | 9 +- ui/balance_druid/sim.ts | 2 +- ui/balance_druid/tsconfig.json | 13 - ui/core/components/character_stats.ts | 14 +- ui/core/individual_sim_ui.ts | 1644 ++++++++++++------------- ui/core/tsconfig.json | 12 - ui/deathknight/index.ts | 2 +- ui/deathknight/inputs.ts | 2 +- ui/deathknight/presets.ts | 1 - ui/deathknight/tsconfig.json | 13 - ui/detailed_results/tsconfig.json | 13 - ui/elemental_shaman/index.ts | 2 +- ui/elemental_shaman/presets.ts | 11 +- ui/elemental_shaman/tsconfig.json | 13 - ui/enhancement_shaman/index.ts | 2 +- ui/enhancement_shaman/inputs.ts | 18 +- ui/enhancement_shaman/presets.ts | 11 +- ui/enhancement_shaman/tsconfig.json | 13 - ui/feral_druid/index.ts | 2 +- ui/feral_druid/presets.ts | 8 +- ui/feral_druid/tsconfig.json | 13 - ui/feral_tank_druid/index.ts | 2 +- ui/feral_tank_druid/presets.ts | 9 - ui/feral_tank_druid/tsconfig.json | 13 - ui/hunter/index.ts | 2 +- ui/hunter/presets.ts | 2 - ui/hunter/tsconfig.json | 13 - ui/mage/index.ts | 2 +- ui/mage/tsconfig.json | 13 - ui/protection_paladin/tsconfig.json | 13 - ui/protection_warrior/index.ts | 2 +- ui/protection_warrior/presets.ts | 9 - ui/protection_warrior/tsconfig.json | 13 - ui/raid/tsconfig.json | 28 - ui/retribution_paladin/tsconfig.json | 13 - ui/rogue/index.ts | 2 +- ui/rogue/inputs.ts | 14 - ui/rogue/presets.ts | 8 - ui/rogue/tsconfig.json | 13 - ui/shadow_priest/index.ts | 2 +- ui/shadow_priest/inputs.ts | 12 +- ui/shadow_priest/presets.ts | 7 - ui/shadow_priest/tsconfig.json | 13 - ui/smite_priest/index.ts | 2 +- ui/smite_priest/presets.ts | 8 +- ui/smite_priest/tsconfig.json | 13 - ui/tank_deathknight/index.ts | 2 +- ui/tank_deathknight/inputs.ts | 19 +- ui/tank_deathknight/presets.ts | 11 +- ui/tank_deathknight/tsconfig.json | 13 - ui/warlock/index.ts | 2 +- ui/warlock/presets.ts | 12 - ui/warlock/tsconfig.json | 13 - ui/warrior/index.ts | 2 +- ui/warrior/tsconfig.json | 13 - 59 files changed, 1514 insertions(+), 1354 deletions(-) delete mode 100644 ui/balance_druid/tsconfig.json delete mode 100644 ui/core/tsconfig.json delete mode 100644 ui/deathknight/tsconfig.json delete mode 100644 ui/detailed_results/tsconfig.json delete mode 100644 ui/elemental_shaman/tsconfig.json delete mode 100644 ui/enhancement_shaman/tsconfig.json delete mode 100644 ui/feral_druid/tsconfig.json delete mode 100644 ui/feral_tank_druid/tsconfig.json delete mode 100644 ui/hunter/tsconfig.json delete mode 100644 ui/mage/tsconfig.json delete mode 100644 ui/protection_paladin/tsconfig.json delete mode 100644 ui/protection_warrior/tsconfig.json delete mode 100644 ui/raid/tsconfig.json delete mode 100644 ui/retribution_paladin/tsconfig.json delete mode 100644 ui/rogue/tsconfig.json delete mode 100644 ui/shadow_priest/tsconfig.json delete mode 100644 ui/smite_priest/tsconfig.json delete mode 100644 ui/tank_deathknight/tsconfig.json delete mode 100644 ui/warlock/tsconfig.json delete mode 100644 ui/warrior/tsconfig.json diff --git a/.eslintrc.js b/.eslintrc.js index 90bc2080d5..42ec48d2a1 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,18 +1,27 @@ module.exports = { - "env": { - "browser": true, - "es6": true, - "node": true - }, - "extends": "eslint:recommended", - "globals": { - "Atomics": "readonly", - "SharedArrayBuffer": "readonly" - }, - "parserOptions": { - "ecmaVersion": 2018, - "sourceType": "module" - }, - "rules": { - } -}; \ No newline at end of file + "plugins": [ + "@typescript-eslint", + "unused-imports" + ], + "env": { + "browser": true, + "es6": true, + "node": true + }, + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parserOptions": { + "ecmaVersion": 2018, + "sourceType": "module" + }, + "rules": { + "@typescript-eslint/no-unused-vars": "off", + "unused-imports/no-unused-imports": "error", + "unused-imports/no-unused-vars": [ + "error", + { "vars": "all", "varsIgnorePattern": "^_", "args": "after-used", "argsIgnorePattern": "^_" } + ], + } +}; diff --git a/package-lock.json b/package-lock.json index 3599298192..1ef76e1fa2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -58,9 +58,9 @@ } }, "@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz", + "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", @@ -104,6 +104,12 @@ } } }, + "@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==", + "dev": true + }, "@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", @@ -159,10 +165,37 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, "@protobuf-ts/plugin": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@protobuf-ts/plugin/-/plugin-2.0.4.tgz", "integrity": "sha512-01LGLAy7HjJBXRO8MOWVfYSG4BQb7AJUZrhKB/rUKebR6w8ZcdOm/MSXi9WB9UK6mRzTx6sHhG87dgzzoKOAgg==", + "dev": true, "requires": { "@protobuf-ts/plugin-framework": "^2.0.4", "@protobuf-ts/protoc": "^2.0.4", @@ -174,7 +207,8 @@ "typescript": { "version": "3.9.10", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", - "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==" + "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", + "dev": true } } }, @@ -182,6 +216,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/@protobuf-ts/plugin-framework/-/plugin-framework-2.0.4.tgz", "integrity": "sha512-MGv1oGe9Fy0UbTrYczr+vB2Lzb4UZsrZ2LFV63G24l1fIb6MCuMphA0/ZE0FCtJJYmg/JyZyVuR1TsYw7O8KIA==", + "dev": true, "requires": { "@protobuf-ts/runtime": "^2.0.4", "typescript": "^3.9" @@ -190,34 +225,264 @@ "typescript": { "version": "3.9.10", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", - "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==" + "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", + "dev": true } } }, "@protobuf-ts/protoc": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@protobuf-ts/protoc/-/protoc-2.0.4.tgz", - "integrity": "sha512-fg85kg7kyEUzrdxDy2nqp9KMvleHjT19l/DxD6XmJq2jwf6Cfh+nyPZ1NL1t3onPuhBeCPVPp27Bcv/xxQRMdg==" + "integrity": "sha512-fg85kg7kyEUzrdxDy2nqp9KMvleHjT19l/DxD6XmJq2jwf6Cfh+nyPZ1NL1t3onPuhBeCPVPp27Bcv/xxQRMdg==", + "dev": true }, "@protobuf-ts/runtime": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@protobuf-ts/runtime/-/runtime-2.0.4.tgz", - "integrity": "sha512-2N7LJJisWImt+J6EW4ih75TumYhztDtPKE8gqvjwFluD/Oz4NmY6g6GaD5HA4WxXUBGY4rXsLycTjYFVzHlnuQ==" + "integrity": "sha512-2N7LJJisWImt+J6EW4ih75TumYhztDtPKE8gqvjwFluD/Oz4NmY6g6GaD5HA4WxXUBGY4rXsLycTjYFVzHlnuQ==", + "dev": true }, "@protobuf-ts/runtime-rpc": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@protobuf-ts/runtime-rpc/-/runtime-rpc-2.0.4.tgz", "integrity": "sha512-LP45kvtWFaNJwHVl481j5dC/dTNcPDTJYdaZJUgs7DlxnoZ9PKMN81dLFyU6bVRCt3IIfyiep0sInwdEeUO2ZA==", + "dev": true, "requires": { "@protobuf-ts/runtime": "^2.0.4" } }, + "@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, "@types/node": { "version": "18.6.1", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.6.1.tgz", "integrity": "sha512-z+2vB6yDt1fNwKOeGbckpmirO+VBDuQqecXkgeIqDlaOtmKn6hPR/viQ8cxCfqLU4fTlvM3+YjM367TukWdxpg==", "dev": true }, + "@typescript-eslint/eslint-plugin": { + "version": "5.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.31.0.tgz", + "integrity": "sha512-VKW4JPHzG5yhYQrQ1AzXgVgX8ZAJEvCz0QI6mLRX4tf7rnFfh5D8SKm0Pq6w5PyNfAWJk6sv313+nEt3ohWMBQ==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.31.0", + "@typescript-eslint/type-utils": "5.31.0", + "@typescript-eslint/utils": "5.31.0", + "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==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "@typescript-eslint/parser": { + "version": "5.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.31.0.tgz", + "integrity": "sha512-UStjQiZ9OFTFReTrN+iGrC6O/ko9LVDhreEK5S3edmXgR396JGq7CoX2TWIptqt/ESzU2iRKXAHfSF2WJFcWHw==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.31.0", + "@typescript-eslint/types": "5.31.0", + "@typescript-eslint/typescript-estree": "5.31.0", + "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==", + "dev": true, + "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==", + "dev": true + } + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.31.0.tgz", + "integrity": "sha512-8jfEzBYDBG88rcXFxajdVavGxb5/XKXyvWgvD8Qix3EEJLCFIdVloJw+r9ww0wbyNLOTYyBsR+4ALNGdlalLLg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.31.0", + "@typescript-eslint/visitor-keys": "5.31.0" + } + }, + "@typescript-eslint/type-utils": { + "version": "5.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.31.0.tgz", + "integrity": "sha512-7ZYqFbvEvYXFn9ax02GsPcEOmuWNg+14HIf4q+oUuLnMbpJ6eHAivCg7tZMVwzrIuzX3QCeAOqKoyMZCv5xe+w==", + "dev": true, + "requires": { + "@typescript-eslint/utils": "5.31.0", + "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==", + "dev": true, + "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==", + "dev": true + } + } + }, + "@typescript-eslint/types": { + "version": "5.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.31.0.tgz", + "integrity": "sha512-/f/rMaEseux+I4wmR6mfpM2wvtNZb1p9hAV77hWfuKc3pmaANp5dLAZSiE3/8oXTYTt3uV9KW5yZKJsMievp6g==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.31.0.tgz", + "integrity": "sha512-3S625TMcARX71wBc2qubHaoUwMEn+l9TCsaIzYI/ET31Xm2c9YQ+zhGgpydjorwQO9pLfR/6peTzS/0G3J/hDw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.31.0", + "@typescript-eslint/visitor-keys": "5.31.0", + "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==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "@typescript-eslint/utils": { + "version": "5.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.31.0.tgz", + "integrity": "sha512-kcVPdQS6VIpVTQ7QnGNKMFtdJdvnStkqS5LeALr4rcwx11G6OWb2HB17NMPnlRHvaZP38hL9iK8DdE9Fne7NYg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.31.0", + "@typescript-eslint/types": "5.31.0", + "@typescript-eslint/typescript-estree": "5.31.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.31.0.tgz", + "integrity": "sha512-ZK0jVxSjS4gnPirpVjXHz7mgdOsZUHzNYSfTw2yPa3agfbt9YfqaBiBZFSSxeBWnpWkzCxTfUpnzA3Vily/CSg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.31.0", + "eslint-visitor-keys": "^3.3.0" + } + }, "acorn": { "version": "8.8.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", @@ -261,6 +526,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -272,10 +538,17 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, "async": { "version": "2.6.4", "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, "requires": { "lodash": "^4.17.14" } @@ -289,12 +562,14 @@ "basic-auth": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-1.1.0.tgz", - "integrity": "sha1-RSIe5Cn37h5QNb4/UVM/HN/SmIQ=" + "integrity": "sha1-RSIe5Cn37h5QNb4/UVM/HN/SmIQ=", + "dev": true }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true }, "brace-expansion": { "version": "2.0.1", @@ -309,6 +584,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, "requires": { "fill-range": "^7.0.1" } @@ -323,6 +599,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, "requires": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" @@ -348,6 +625,7 @@ "version": "3.5.2", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", + "dev": true, "requires": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -377,17 +655,20 @@ "colors": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true }, "commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true }, "commandpost": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/commandpost/-/commandpost-1.4.0.tgz", - "integrity": "sha512-aE2Y4MTFJ870NuB/+2z1cXBhSBBzRydVVjzhFC4gtenEhpnj15yu0qptWGJsO9YGrcPZ3ezX8AWb1VA391MKpQ==" + "integrity": "sha512-aE2Y4MTFJ870NuB/+2z1cXBhSBBzRydVVjzhFC4gtenEhpnj15yu0qptWGJsO9YGrcPZ3ezX8AWb1VA391MKpQ==", + "dev": true }, "concat-map": { "version": "0.0.1", @@ -398,7 +679,8 @@ "corser": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", - "integrity": "sha1-jtolLsqrWEDc2XXOuQ2TcMgZ/4c=" + "integrity": "sha1-jtolLsqrWEDc2XXOuQ2TcMgZ/4c=", + "dev": true }, "cross-spawn": { "version": "7.0.3", @@ -415,6 +697,7 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, "requires": { "ms": "^2.1.1" } @@ -425,6 +708,15 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -438,6 +730,7 @@ "version": "0.15.3", "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "dev": true, "requires": { "commander": "^2.19.0", "lru-cache": "^4.1.5", @@ -620,13 +913,14 @@ "dev": true }, "eslint": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.20.0.tgz", - "integrity": "sha512-d4ixhz5SKCa1D6SCPrivP7yYVi7nyD6A4vs6HIAul9ujBzcEmZVM3/0NN/yu5nKhmO1wjp5xQ46iRfmDGlOviA==", + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.21.0.tgz", + "integrity": "sha512-/XJ1+Qurf1T9G2M5IHrsjp+xrGT73RZf23xA1z5wB1ZzzEAWSZKvRwhWxTFp1rvkvCfwcvAUNAP31bhKTTGfDA==", "dev": true, "requires": { "@eslint/eslintrc": "^1.3.0", - "@humanwhocodes/config-array": "^0.9.2", + "@humanwhocodes/config-array": "^0.10.4", + "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -636,14 +930,17 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.2", + "espree": "^9.3.3", "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", @@ -681,6 +978,22 @@ "ms": "2.1.2" } }, + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, "glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -718,14 +1031,29 @@ } } }, + "eslint-plugin-unused-imports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-2.0.0.tgz", + "integrity": "sha512-3APeS/tQlTrFa167ThtP0Zm0vctjr4M44HMpeg1P4bK6wItarumq0Ma82xorMKdFsWpphQBlRPzw/pxiVELX1A==", + "dev": true, + "requires": { + "eslint-rule-composer": "^0.3.0" + } + }, + "eslint-rule-composer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz", + "integrity": "sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==", + "dev": true + }, "eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "requires": { "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" + "estraverse": "^4.1.1" } }, "eslint-utils": { @@ -752,12 +1080,12 @@ "dev": true }, "espree": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", - "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", + "version": "9.3.3", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.3.tgz", + "integrity": "sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng==", "dev": true, "requires": { - "acorn": "^8.7.1", + "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.3.0" } @@ -769,6 +1097,14 @@ "dev": true, "requires": { "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } } }, "esrecurse": { @@ -778,12 +1114,20 @@ "dev": true, "requires": { "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } } }, "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true }, "esutils": { @@ -795,7 +1139,8 @@ "eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true }, "fast-deep-equal": { "version": "3.1.3", @@ -803,6 +1148,19 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "fast-glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -815,6 +1173,15 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -828,10 +1195,21 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, "requires": { "to-regex-range": "^5.0.1" } }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, "flat-cache": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", @@ -851,7 +1229,8 @@ "follow-redirects": { "version": "1.14.9", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", - "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==" + "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", + "dev": true }, "fs.realpath": { "version": "1.0.0", @@ -863,12 +1242,14 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, "optional": true }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "functional-red-black-tree": { "version": "1.0.1", @@ -880,6 +1261,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -903,6 +1285,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, "requires": { "is-glob": "^4.0.1" } @@ -916,10 +1299,31 @@ "type-fest": "^0.20.2" } }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -933,17 +1337,20 @@ "has-symbols": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true }, "http-proxy": { "version": "1.18.1", "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, "requires": { "eventemitter3": "^4.0.0", "follow-redirects": "^1.0.0", @@ -954,6 +1361,7 @@ "version": "13.0.1", "resolved": "https://registry.npmjs.org/http-server/-/http-server-13.0.1.tgz", "integrity": "sha512-ke9rphoNuqsOCHy4tA3b3W4Yuxy7VUIXcTHSLz6bkMDAJPQD4twjEatquelJBIPwNhZuC3+FYj/+dSaGHdKTCw==", + "dev": true, "requires": { "basic-auth": "^1.0.3", "colors": "^1.4.0", @@ -1011,6 +1419,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, "requires": { "binary-extensions": "^2.0.0" } @@ -1027,12 +1436,14 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true }, "is-glob": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, "requires": { "is-extglob": "^2.1.1" } @@ -1040,7 +1451,8 @@ "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true }, "isexe": { "version": "2.0.0", @@ -1079,10 +1491,20 @@ "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==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true }, "lodash.merge": { "version": "4.6.2", @@ -1094,15 +1516,41 @@ "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, "requires": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" } }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "dependencies": { + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + } + } + }, "mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true }, "minimatch": { "version": "5.1.0", @@ -1116,12 +1564,14 @@ "minimist": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true }, "mkdirp": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, "requires": { "minimist": "^1.2.5" } @@ -1129,7 +1579,8 @@ "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true }, "nanoid": { "version": "3.3.4", @@ -1146,12 +1597,14 @@ "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true }, "object-inspect": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==" + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "dev": true }, "once": { "version": "1.4.0", @@ -1165,7 +1618,8 @@ "opener": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==" + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true }, "optionator": { "version": "0.9.1", @@ -1181,6 +1635,24 @@ "word-wrap": "^1.2.3" } }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -1190,6 +1662,12 @@ "callsites": "^3.0.0" } }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -1208,6 +1686,12 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -1217,12 +1701,14 @@ "picomatch": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==" + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true }, "portfinder": { "version": "1.0.28", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", + "dev": true, "requires": { "async": "^2.6.2", "debug": "^3.1.1", @@ -1249,7 +1735,8 @@ "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true }, "punycode": { "version": "2.1.1", @@ -1261,14 +1748,22 @@ "version": "6.10.1", "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", + "dev": true, "requires": { "side-channel": "^1.0.4" } }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, "requires": { "picomatch": "^2.2.1" } @@ -1282,7 +1777,8 @@ "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true }, "resolve": { "version": "1.22.1", @@ -1301,6 +1797,12 @@ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -1354,10 +1856,20 @@ "fsevents": "~2.3.2" } }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, "sass": { "version": "1.39.0", "resolved": "https://registry.npmjs.org/sass/-/sass-1.39.0.tgz", "integrity": "sha512-F4o+RhJkNOIG0b6QudYU8c78ZADKZjKDk5cyrf8XTKWfrgbtyVVXImFstJrc+1pkQDCggyidIOytq6gS4gCCZg==", + "dev": true, "requires": { "chokidar": ">=3.0.0 <4.0.0" } @@ -1365,12 +1877,14 @@ "secure-compare": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", - "integrity": "sha1-8aAymzCLIh+uN7mXTz1XjQypmeM=" + "integrity": "sha1-8aAymzCLIh+uN7mXTz1XjQypmeM=", + "dev": true }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true }, "shebang-command": { "version": "2.0.0", @@ -1391,6 +1905,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, "requires": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", @@ -1400,7 +1915,14 @@ "sigmund": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true }, "source-map": { "version": "0.6.1", @@ -1476,10 +1998,26 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, "requires": { "is-number": "^7.0.0" } }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -1498,12 +2036,14 @@ "typescript": { "version": "4.3.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", - "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==" + "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", + "dev": true }, "typescript-formatter": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/typescript-formatter/-/typescript-formatter-7.2.2.tgz", "integrity": "sha512-V7vfI9XArVhriOTYHPzMU2WUnm5IMdu9X/CPxs8mIMGxmTBFpDABlbkBka64PZJ9/xgQeRpK8KzzAG4MPzxBDQ==", + "dev": true, "requires": { "commandpost": "^1.0.0", "editorconfig": "^0.15.0" @@ -1513,6 +2053,7 @@ "version": "0.5.0", "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", + "dev": true, "requires": { "qs": "^6.4.0" } @@ -1529,7 +2070,8 @@ "url-join": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.5.tgz", - "integrity": "sha1-WvIvGMBSoACkjXuCxenC4v7tpyg=" + "integrity": "sha1-WvIvGMBSoACkjXuCxenC4v7tpyg=", + "dev": true }, "v8-compile-cache": { "version": "2.3.0", @@ -1574,7 +2116,14 @@ "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true } } } diff --git a/package.json b/package.json index 539fddb1d9..e733b0f026 100644 --- a/package.json +++ b/package.json @@ -3,22 +3,23 @@ "version": "0.1.0", "private": true, "devDependencies": { + "@protobuf-ts/plugin": "^2.0.4", + "@protobuf-ts/runtime": "^2.0.4", "@types/node": "^18.6.1", - "eslint": "^8.20.0", + "@typescript-eslint/eslint-plugin": "^5.31.0", + "@typescript-eslint/parser": "^5.31.0", + "eslint": "^8.21.0", + "eslint-plugin-unused-imports": "^2.0.0", "glob": "^8.0.3", + "http-server": "13.0.1", + "sass": "^1.39.0", "terser": "^5.14.2", + "typescript": "4.3.5", + "typescript-formatter": "^7.2.2", "vite": "^3.0.3" }, "scripts": { "build": "bazel build //...", "test": "bazel test //..." - }, - "dependencies": { - "@protobuf-ts/plugin": "^2.0.4", - "@protobuf-ts/runtime": "^2.0.4", - "http-server": "13.0.1", - "sass": "^1.39.0", - "typescript": "4.3.5", - "typescript-formatter": "^7.2.2" } } diff --git a/ui/balance_druid/inputs.ts b/ui/balance_druid/inputs.ts index 2c8766eefd..fe459f71a9 100644 --- a/ui/balance_druid/inputs.ts +++ b/ui/balance_druid/inputs.ts @@ -1,13 +1,13 @@ -import { BalanceDruid_Options as DruidOptions, BalanceDruid_Rotation_RotationType as RotationType } from '/wotlk/core/proto/druid.js'; -import { RaidTarget } from '/wotlk/core/proto/common.js'; -import { Spec } from '/wotlk/core/proto/common.js'; -import { NO_TARGET } from '/wotlk/core/proto_utils/utils.js'; -import { ActionId } from '/wotlk/core/proto_utils/action_id.js'; -import { Player } from '/wotlk/core/player.js'; -import { Sim } from '/wotlk/core/sim.js'; -import { EventID, TypedEvent } from '/wotlk/core/typed_event.js'; -import { IndividualSimUI } from '/wotlk/core/individual_sim_ui.js'; -import { Target } from '/wotlk/core/target.js'; +import { BalanceDruid_Options as DruidOptions, BalanceDruid_Rotation_RotationType as RotationType } from '../core/proto/druid.js'; +import { RaidTarget } from '../core/proto/common.js'; +import { Spec } from '../core/proto/common.js'; +import { NO_TARGET } from '../core/proto_utils/utils.js'; +import { ActionId } from '../core/proto_utils/action_id.js'; +import { Player } from '../core/player.js'; +import { Sim } from '../core/sim.js'; +import { EventID, TypedEvent } from '../core/typed_event.js'; +import { IndividualSimUI } from '../core/individual_sim_ui.js'; +import { Target } from '../core/target.js'; import * as InputHelpers from '../core/components/input_helpers.js'; diff --git a/ui/balance_druid/presets.ts b/ui/balance_druid/presets.ts index 16bd7af0a7..daff08c20e 100644 --- a/ui/balance_druid/presets.ts +++ b/ui/balance_druid/presets.ts @@ -1,19 +1,12 @@ import { Consumes } from '../core/proto/common.js'; import { Flask } from '../core/proto/common.js'; import { Food } from '../core/proto/common.js'; -import { Glyphs } from '../core/proto/common.js'; import { EquipmentSpec } from '../core/proto/common.js'; -import { ItemSpec } from '../core/proto/common.js'; import { Potions } from '../core/proto/common.js'; -import { WeaponImbue } from '../core/proto/common.js'; -import { Faction } from '../core/proto/common.js'; import { SavedTalents } from '../core/proto/ui.js'; -import { Player } from '../core/player.js'; -import { BalanceDruid, BalanceDruid_Rotation as BalanceDruidRotation, DruidTalents as DruidTalents, BalanceDruid_Options as BalanceDruidOptions, BalanceDruid_Rotation_RotationType as RotationType } from '/wotlk/core/proto/druid.js'; +import { BalanceDruid_Rotation as BalanceDruidRotation, BalanceDruid_Options as BalanceDruidOptions, BalanceDruid_Rotation_RotationType as RotationType } from '../core/proto/druid.js'; -import * as Enchants from '../core/constants/enchants.js'; -import * as Gems from '../core/proto_utils/gems.js'; import * as Tooltips from '../core/constants/tooltips.js'; // Preset options for this spec. diff --git a/ui/balance_druid/sim.ts b/ui/balance_druid/sim.ts index f748ae66ef..cebf6af301 100644 --- a/ui/balance_druid/sim.ts +++ b/ui/balance_druid/sim.ts @@ -16,7 +16,7 @@ import { Player } from '../core/player.js'; import { Sim } from '../core/sim.js'; import { IndividualSimUI } from '../core/individual_sim_ui.js'; -import { BalanceDruid, BalanceDruid_Rotation as BalanceDruidRotation, DruidTalents as DruidTalents, BalanceDruid_Options as BalanceDruidOptions } from '/wotlk/core/proto/druid.js'; +import { BalanceDruid, BalanceDruid_Rotation as BalanceDruidRotation, DruidTalents as DruidTalents, BalanceDruid_Options as BalanceDruidOptions } from '../core/proto/druid.js'; import * as IconInputs from '../core/components/icon_inputs.js'; import * as OtherInputs from '../core/components/other_inputs.js'; diff --git a/ui/balance_druid/tsconfig.json b/ui/balance_druid/tsconfig.json deleted file mode 100644 index db6df68671..0000000000 --- a/ui/balance_druid/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../tsconfig-base", - "compilerOptions": { - "composite": true, - "outDir": "../../dist/wotlk/balance_druid", - }, - "include": [ - "**/*.ts", - ], - "references": [ - { "path": "../core" }, - ], -} diff --git a/ui/core/components/character_stats.ts b/ui/core/components/character_stats.ts index a369c40a12..ee30fc51dc 100644 --- a/ui/core/components/character_stats.ts +++ b/ui/core/components/character_stats.ts @@ -1,10 +1,10 @@ -import { PlayerStats } from '/wotlk/core/proto/api.js'; -import { Stat, Class } from '/wotlk/core/proto/common.js'; -import { TristateEffect } from '/wotlk/core/proto/common.js' -import { statNames, statOrder } from '/wotlk/core/proto_utils/names.js'; -import { Stats } from '/wotlk/core/proto_utils/stats.js'; -import { Player } from '/wotlk/core/player.js'; -import { EventID, TypedEvent } from '/wotlk/core/typed_event.js'; +import { PlayerStats } from '..//proto/api.js'; +import { Stat, Class } from '..//proto/common.js'; +import { TristateEffect } from '..//proto/common.js' +import { statNames, statOrder } from '..//proto_utils/names.js'; +import { Stats } from '..//proto_utils/stats.js'; +import { Player } from '..//player.js'; +import { EventID, TypedEvent } from '..//typed_event.js'; import * as Mechanics from '../constants/mechanics.js'; diff --git a/ui/core/individual_sim_ui.ts b/ui/core/individual_sim_ui.ts index 64b357aae7..9957889ce5 100644 --- a/ui/core/individual_sim_ui.ts +++ b/ui/core/individual_sim_ui.ts @@ -97,252 +97,252 @@ const SAVED_SETTINGS_STORAGE_KEY = '__savedSettings__'; const SAVED_TALENTS_STORAGE_KEY = '__savedTalents__'; export type InputConfig = ( - InputHelpers.TypedBooleanPickerConfig | - InputHelpers.TypedNumberPickerConfig | - InputHelpers.TypedEnumPickerConfig); + InputHelpers.TypedBooleanPickerConfig | + InputHelpers.TypedNumberPickerConfig | + InputHelpers.TypedEnumPickerConfig); export type IconInputConfig = ( - InputHelpers.TypedIconPickerConfig | - InputHelpers.TypedIconEnumPickerConfig); + InputHelpers.TypedIconPickerConfig | + InputHelpers.TypedIconEnumPickerConfig); export interface InputSection { - tooltip?: string, - inputs: Array>>, + tooltip?: string, + inputs: Array>>, } export interface IndividualSimUIConfig { - // Additional css class to add to the root element. - cssClass: string, - - knownIssues?: Array; - warnings?: Array<(simUI: IndividualSimUI) => SimWarning>, - - epStats: Array; - epReferenceStat: Stat; - displayStats: Array; - modifyDisplayStats?: (player: Player) => StatMods, - - defaults: { - gear: EquipmentSpec, - epWeights: Stats, - consumes: Consumes, - rotation: SpecRotation, - talents: SavedTalents, - specOptions: SpecOptions, - - raidBuffs: RaidBuffs, - partyBuffs: PartyBuffs, - individualBuffs: IndividualBuffs, - - debuffs: Debuffs, - }, - - playerIconInputs: Array, any>>, - petConsumeInputs?: Array, any>>, - rotationInputs: InputSection; - rotationIconInputs?: Array, any>>; - includeBuffDebuffInputs: Array, - excludeBuffDebuffInputs: Array, - otherInputs: InputSection; - - // Extra UI sections with the same input config as other sections. - additionalSections?: Record; - additionalIconSections?: Record, any>>>; - - // For when extra sections are needed, with even more flexibility than additionalSections. - // Return value is the label for the section. - customSections?: Array<(simUI: IndividualSimUI, parentElem: HTMLElement) => string>; - - encounterPicker: EncounterPickerConfig, - - presets: { - gear: Array, - talents: Array, SavedTalents>>, - rotation?: Array, string>>, - }, + // Additional css class to add to the root element. + cssClass: string, + + knownIssues?: Array; + warnings?: Array<(simUI: IndividualSimUI) => SimWarning>, + + epStats: Array; + epReferenceStat: Stat; + displayStats: Array; + modifyDisplayStats?: (player: Player) => StatMods, + + defaults: { + gear: EquipmentSpec, + epWeights: Stats, + consumes: Consumes, + rotation: SpecRotation, + talents: SavedTalents, + specOptions: SpecOptions, + + raidBuffs: RaidBuffs, + partyBuffs: PartyBuffs, + individualBuffs: IndividualBuffs, + + debuffs: Debuffs, + }, + + playerIconInputs: Array, any>>, + petConsumeInputs?: Array, any>>, + rotationInputs: InputSection; + rotationIconInputs?: Array, any>>; + includeBuffDebuffInputs: Array, + excludeBuffDebuffInputs: Array, + otherInputs: InputSection; + + // Extra UI sections with the same input config as other sections. + additionalSections?: Record; + additionalIconSections?: Record, any>>>; + + // For when extra sections are needed, with even more flexibility than additionalSections. + // Return value is the label for the section. + customSections?: Array<(simUI: IndividualSimUI, parentElem: HTMLElement) => string>; + + encounterPicker: EncounterPickerConfig, + + presets: { + gear: Array, + talents: Array, SavedTalents>>, + rotation?: Array, string>>, + }, } export interface GearAndStats { - gear: Gear, - bonusStats?: Stats, + gear: Gear, + bonusStats?: Stats, } export interface PresetGear { - name: string; - gear: EquipmentSpec; - tooltip?: string; - enableWhen?: (obj: Player) => boolean; + name: string; + gear: EquipmentSpec; + tooltip?: string; + enableWhen?: (obj: Player) => boolean; } export interface Settings { - raidBuffs: RaidBuffs, - partyBuffs: PartyBuffs, - individualBuffs: IndividualBuffs, - consumes: Consumes, - race: Race, - professions?: Array; + raidBuffs: RaidBuffs, + partyBuffs: PartyBuffs, + individualBuffs: IndividualBuffs, + consumes: Consumes, + race: Race, + professions?: Array; } // Extended shared UI for all individual player sims. export abstract class IndividualSimUI extends SimUI { - readonly player: Player; - readonly individualConfig: IndividualSimUIConfig; - - private raidSimResultsManager: RaidSimResultsManager | null; - - private settingsMuuri: any; - - prevEpIterations: number; - prevEpSimResult: StatWeightsResult | null; - - constructor(parentElem: HTMLElement, player: Player, config: IndividualSimUIConfig) { - super(parentElem, player.sim, { - spec: player.spec, - knownIssues: config.knownIssues, - launchStatus: simLaunchStatuses[player.spec], - }); - this.rootElem.classList.add('individual-sim-ui', config.cssClass); - this.player = player; - this.individualConfig = config; - this.raidSimResultsManager = null; - this.settingsMuuri = null; - this.prevEpIterations = 0; - this.prevEpSimResult = null; - - this.addWarning({ - updateOn: this.player.gearChangeEmitter, - getContent: () => { - if (!this.player.getGear().hasInactiveMetaGem()) { - return ''; - } - - const metaGem = this.player.getGear().getMetaGem()!; - return `Meta gem disabled (${metaGem.name}): ${getMetaGemConditionDescription(metaGem)}`; - }, - }); - this.addWarning({ - updateOn: TypedEvent.onAny([this.player.gearChangeEmitter, this.player.professionChangeEmitter]), - getContent: () => { - const failedProfReqs = this.player.getGear().getFailedProfessionRequirements(this.player.getProfessions()); - if (failedProfReqs.length == 0) { - return ''; - } - - return failedProfReqs.map(fpr => `${fpr.name} requires ${professionNames[fpr.requiredProfession]}, but it is not selected.`); - }, - }); - this.addWarning({ - updateOn: this.player.gearChangeEmitter, - getContent: () => { - const jcGems = this.player.getGear().getJCGems(); - if (jcGems.length <= 3) { - return ''; - } - - return `Only 3 Jewelcrafting Gems are allowed, but ${jcGems.length} are equipped.`; - }, - }); - (config.warnings || []).forEach(warning => this.addWarning(warning(this))); - - if (!this.isWithinRaidSim) { - // This needs to go before all the UI components so that gear loading is the - // first callback invoked from waitForInit(). - this.sim.waitForInit().then(() => this.loadSettings()); - } - - this.addSidebarComponents(); - this.addTopbarComponents(); - this.addGearTab(); - this.addSettingsTab(); - this.addTalentsTab(); - - if (!this.isWithinRaidSim) { - this.addDetailedResultsTab(); - this.addLogTab(); - } - - this.player.changeEmitter.on(() => this.recomputeSettingsLayout()); - } - - private loadSettings() { - const initEventID = TypedEvent.nextEventID(); - TypedEvent.freezeAllAndDo(() => { - let loadedSettings = false; - - let hash = window.location.hash; - if (hash.length > 1) { - // Remove leading '#' - hash = hash.substring(1); - try { - const binary = atob(hash); - const bytes = new Uint8Array(binary.length); - for (let i = 0; i < bytes.length; i++) { - bytes[i] = binary.charCodeAt(i); - } - - const settingsBytes = pako.inflate(bytes); - const settings = IndividualSimSettings.fromBinary(settingsBytes); - this.fromProto(initEventID, settings); - loadedSettings = true; - } catch (e) { - console.warn('Failed to parse settings from window hash: ' + e); - } - } - window.location.hash = ''; - - const savedSettings = window.localStorage.getItem(this.getSettingsStorageKey()); - if (!loadedSettings && savedSettings != null) { - try { - const settings = IndividualSimSettings.fromJsonString(savedSettings); - this.fromProto(initEventID, settings); - loadedSettings = true; - } catch (e) { - console.warn('Failed to parse saved settings: ' + e); - } - } - - if (!loadedSettings) { - this.applyDefaults(initEventID); - } - this.player.setName(initEventID, 'Player'); - - // This needs to go last so it doesn't re-store things as they are initialized. - this.changeEmitter.on(eventID => { - const jsonStr = IndividualSimSettings.toJsonString(this.toProto()); - window.localStorage.setItem(this.getSettingsStorageKey(), jsonStr); - }); - }); - } - - private addSidebarComponents() { - this.raidSimResultsManager = addRaidSimAction(this); - addStatWeightsAction(this, this.individualConfig.epStats, this.individualConfig.epReferenceStat); - - const characterStats = new CharacterStats( - this.rootElem.getElementsByClassName('sim-sidebar-footer')[0] as HTMLElement, - this.player, - this.individualConfig.displayStats, - this.individualConfig.modifyDisplayStats); - } - - private addTopbarComponents() { - this.addToolbarItem(newIndividualImporters(this)); - this.addToolbarItem(newIndividualExporters(this)); - - const optionsMenu = document.createElement('span'); - optionsMenu.classList.add('fas', 'fa-cog'); - tippy(optionsMenu, { - 'content': 'Options', - 'allowHTML': true, - }); - optionsMenu.addEventListener('click', event => { - new SettingsMenu(this.rootElem, this); - }); - this.addToolbarItem(optionsMenu); - } - - private addGearTab() { - this.addTab('GEAR', 'gear-tab', ` + readonly player: Player; + readonly individualConfig: IndividualSimUIConfig; + + private raidSimResultsManager: RaidSimResultsManager | null; + + private settingsMuuri: any; + + prevEpIterations: number; + prevEpSimResult: StatWeightsResult | null; + + constructor(parentElem: HTMLElement, player: Player, config: IndividualSimUIConfig) { + super(parentElem, player.sim, { + spec: player.spec, + knownIssues: config.knownIssues, + launchStatus: simLaunchStatuses[player.spec], + }); + this.rootElem.classList.add('individual-sim-ui', config.cssClass); + this.player = player; + this.individualConfig = config; + this.raidSimResultsManager = null; + this.settingsMuuri = null; + this.prevEpIterations = 0; + this.prevEpSimResult = null; + + this.addWarning({ + updateOn: this.player.gearChangeEmitter, + getContent: () => { + if (!this.player.getGear().hasInactiveMetaGem()) { + return ''; + } + + const metaGem = this.player.getGear().getMetaGem()!; + return `Meta gem disabled (${metaGem.name}): ${getMetaGemConditionDescription(metaGem)}`; + }, + }); + this.addWarning({ + updateOn: TypedEvent.onAny([this.player.gearChangeEmitter, this.player.professionChangeEmitter]), + getContent: () => { + const failedProfReqs = this.player.getGear().getFailedProfessionRequirements(this.player.getProfessions()); + if (failedProfReqs.length == 0) { + return ''; + } + + return failedProfReqs.map(fpr => `${fpr.name} requires ${professionNames[fpr.requiredProfession]}, but it is not selected.`); + }, + }); + this.addWarning({ + updateOn: this.player.gearChangeEmitter, + getContent: () => { + const jcGems = this.player.getGear().getJCGems(); + if (jcGems.length <= 3) { + return ''; + } + + return `Only 3 Jewelcrafting Gems are allowed, but ${jcGems.length} are equipped.`; + }, + }); + (config.warnings || []).forEach(warning => this.addWarning(warning(this))); + + if (!this.isWithinRaidSim) { + // This needs to go before all the UI components so that gear loading is the + // first callback invoked from waitForInit(). + this.sim.waitForInit().then(() => this.loadSettings()); + } + + this.addSidebarComponents(); + this.addTopbarComponents(); + this.addGearTab(); + this.addSettingsTab(); + this.addTalentsTab(); + + if (!this.isWithinRaidSim) { + this.addDetailedResultsTab(); + this.addLogTab(); + } + + this.player.changeEmitter.on(() => this.recomputeSettingsLayout()); + } + + private loadSettings() { + const initEventID = TypedEvent.nextEventID(); + TypedEvent.freezeAllAndDo(() => { + let loadedSettings = false; + + let hash = window.location.hash; + if (hash.length > 1) { + // Remove leading '#' + hash = hash.substring(1); + try { + const binary = atob(hash); + const bytes = new Uint8Array(binary.length); + for (let i = 0; i < bytes.length; i++) { + bytes[i] = binary.charCodeAt(i); + } + + const settingsBytes = pako.inflate(bytes); + const settings = IndividualSimSettings.fromBinary(settingsBytes); + this.fromProto(initEventID, settings); + loadedSettings = true; + } catch (e) { + console.warn('Failed to parse settings from window hash: ' + e); + } + } + window.location.hash = ''; + + const savedSettings = window.localStorage.getItem(this.getSettingsStorageKey()); + if (!loadedSettings && savedSettings != null) { + try { + const settings = IndividualSimSettings.fromJsonString(savedSettings); + this.fromProto(initEventID, settings); + loadedSettings = true; + } catch (e) { + console.warn('Failed to parse saved settings: ' + e); + } + } + + if (!loadedSettings) { + this.applyDefaults(initEventID); + } + this.player.setName(initEventID, 'Player'); + + // This needs to go last so it doesn't re-store things as they are initialized. + this.changeEmitter.on(eventID => { + const jsonStr = IndividualSimSettings.toJsonString(this.toProto()); + window.localStorage.setItem(this.getSettingsStorageKey(), jsonStr); + }); + }); + } + + private addSidebarComponents() { + this.raidSimResultsManager = addRaidSimAction(this); + addStatWeightsAction(this, this.individualConfig.epStats, this.individualConfig.epReferenceStat); + + const characterStats = new CharacterStats( + this.rootElem.getElementsByClassName('sim-sidebar-footer')[0] as HTMLElement, + this.player, + this.individualConfig.displayStats, + this.individualConfig.modifyDisplayStats); + } + + private addTopbarComponents() { + this.addToolbarItem(newIndividualImporters(this)); + this.addToolbarItem(newIndividualExporters(this)); + + const optionsMenu = document.createElement('span'); + optionsMenu.classList.add('fas', 'fa-cog'); + tippy(optionsMenu, { + 'content': 'Options', + 'allowHTML': true, + }); + optionsMenu.addEventListener('click', event => { + new SettingsMenu(this.rootElem, this); + }); + this.addToolbarItem(optionsMenu); + } + + private addGearTab() { + this.addTab('GEAR', 'gear-tab', `
@@ -357,51 +357,51 @@ export abstract class IndividualSimUI extends SimUI {
`); - const gearPicker = new GearPicker(this.rootElem.getElementsByClassName('gear-picker')[0] as HTMLElement, this.player); - const bonusStatsPicker = new BonusStatsPicker(this.rootElem.getElementsByClassName('bonus-stats-picker')[0] as HTMLElement, this.player, this.individualConfig.epStats); - - const savedGearManager = new SavedDataManager, SavedGearSet>(this.rootElem.getElementsByClassName('saved-gear-manager')[0] as HTMLElement, this.player, { - label: 'Gear', - storageKey: this.getSavedGearStorageKey(), - getData: (player: Player) => { - return SavedGearSet.create({ - gear: player.getGear().asSpec(), - bonusStats: player.getBonusStats().asArray(), - }); - }, - setData: (eventID: EventID, player: Player, newSavedGear: SavedGearSet) => { - TypedEvent.freezeAllAndDo(() => { - player.setGear(eventID, this.sim.lookupEquipmentSpec(newSavedGear.gear || EquipmentSpec.create())); - player.setBonusStats(eventID, new Stats(newSavedGear.bonusStats || [])); - }); - }, - changeEmitters: [this.player.changeEmitter], - equals: (a: SavedGearSet, b: SavedGearSet) => SavedGearSet.equals(a, b), - toJson: (a: SavedGearSet) => SavedGearSet.toJson(a), - fromJson: (obj: any) => SavedGearSet.fromJson(obj), - }); - - this.sim.waitForInit().then(() => { - savedGearManager.loadUserData(); - this.individualConfig.presets.gear.forEach(presetGear => { - savedGearManager.addSavedData({ - name: presetGear.name, - tooltip: presetGear.tooltip, - isPreset: true, - data: SavedGearSet.create({ - // Convert to gear and back so order is always the same. - gear: this.sim.lookupEquipmentSpec(presetGear.gear).asSpec(), - bonusStats: new Stats().asArray(), - }), - enableWhen: presetGear.enableWhen, - }); - }); - }); - } - - - private addSettingsTab() { - this.addTab('SETTINGS', 'settings-tab', ` + const gearPicker = new GearPicker(this.rootElem.getElementsByClassName('gear-picker')[0] as HTMLElement, this.player); + const bonusStatsPicker = new BonusStatsPicker(this.rootElem.getElementsByClassName('bonus-stats-picker')[0] as HTMLElement, this.player, this.individualConfig.epStats); + + const savedGearManager = new SavedDataManager, SavedGearSet>(this.rootElem.getElementsByClassName('saved-gear-manager')[0] as HTMLElement, this.player, { + label: 'Gear', + storageKey: this.getSavedGearStorageKey(), + getData: (player: Player) => { + return SavedGearSet.create({ + gear: player.getGear().asSpec(), + bonusStats: player.getBonusStats().asArray(), + }); + }, + setData: (eventID: EventID, player: Player, newSavedGear: SavedGearSet) => { + TypedEvent.freezeAllAndDo(() => { + player.setGear(eventID, this.sim.lookupEquipmentSpec(newSavedGear.gear || EquipmentSpec.create())); + player.setBonusStats(eventID, new Stats(newSavedGear.bonusStats || [])); + }); + }, + changeEmitters: [this.player.changeEmitter], + equals: (a: SavedGearSet, b: SavedGearSet) => SavedGearSet.equals(a, b), + toJson: (a: SavedGearSet) => SavedGearSet.toJson(a), + fromJson: (obj: any) => SavedGearSet.fromJson(obj), + }); + + this.sim.waitForInit().then(() => { + savedGearManager.loadUserData(); + this.individualConfig.presets.gear.forEach(presetGear => { + savedGearManager.addSavedData({ + name: presetGear.name, + tooltip: presetGear.tooltip, + isPreset: true, + data: SavedGearSet.create({ + // Convert to gear and back so order is always the same. + gear: this.sim.lookupEquipmentSpec(presetGear.gear).asSpec(), + bonusStats: new Stats().asArray(), + }), + enableWhen: presetGear.enableWhen, + }); + }); + }); + } + + + private addSettingsTab() { + this.addTab('SETTINGS', 'settings-tab', `
@@ -486,40 +486,40 @@ export abstract class IndividualSimUI extends SimUI {
`); - const settingsTab = this.rootElem.getElementsByClassName('settings-inputs')[0] as HTMLElement; - - const configureIconSection = (sectionElem: HTMLElement, iconPickers: Array, tooltip?: string, adjustColumns?: boolean) => { - if (tooltip) { - tippy(sectionElem, { - 'content': tooltip, - 'allowHTML': true, - }); - } - - if (iconPickers.length == 0) { - sectionElem.style.display = 'none'; - } else if (adjustColumns) { - if (iconPickers.length < 4) { - sectionElem.style.gridTemplateColumns = `repeat(${iconPickers.length}, 1fr)`; - } else if (iconPickers.length > 4 && iconPickers.length < 8) { - sectionElem.style.gridTemplateColumns = `repeat(${Math.ceil(iconPickers.length / 2)}, 1fr)`; - } - } - }; - - const makeIconInput = (parent: HTMLElement, inputConfig: IconInputConfig, any>) => { - if (inputConfig.type == 'icon') { - return new IconPicker, any>(parent, this.player, inputConfig); - } else if (inputConfig.type == 'iconEnum') { - return new IconEnumPicker, any>(parent, this.player, inputConfig); - } - }; - - const playerIconsSection = this.rootElem.getElementsByClassName('player-iconrow')[0] as HTMLElement; - configureIconSection( - playerIconsSection, - this.individualConfig.playerIconInputs.map(iconInput => makeIconInput(playerIconsSection, iconInput)), - '', true); + const settingsTab = this.rootElem.getElementsByClassName('settings-inputs')[0] as HTMLElement; + + const configureIconSection = (sectionElem: HTMLElement, iconPickers: Array, tooltip?: string, adjustColumns?: boolean) => { + if (tooltip) { + tippy(sectionElem, { + 'content': tooltip, + 'allowHTML': true, + }); + } + + if (iconPickers.length == 0) { + sectionElem.style.display = 'none'; + } else if (adjustColumns) { + if (iconPickers.length < 4) { + sectionElem.style.gridTemplateColumns = `repeat(${iconPickers.length}, 1fr)`; + } else if (iconPickers.length > 4 && iconPickers.length < 8) { + sectionElem.style.gridTemplateColumns = `repeat(${Math.ceil(iconPickers.length / 2)}, 1fr)`; + } + } + }; + + const makeIconInput = (parent: HTMLElement, inputConfig: IconInputConfig, any>) => { + if (inputConfig.type == 'icon') { + return new IconPicker, any>(parent, this.player, inputConfig); + } else if (inputConfig.type == 'iconEnum') { + return new IconEnumPicker, any>(parent, this.player, inputConfig); + } + }; + + const playerIconsSection = this.rootElem.getElementsByClassName('player-iconrow')[0] as HTMLElement; + configureIconSection( + playerIconsSection, + this.individualConfig.playerIconInputs.map(iconInput => makeIconInput(playerIconsSection, iconInput)), + '', true); const buffOptions = this.splitRelevantOptions([ { item: IconInputs.AllStatsBuff, stats: [] }, @@ -576,109 +576,109 @@ export abstract class IndividualSimUI extends SimUI { }, this); } - const debuffOptions = this.splitRelevantOptions([ - { item: IconInputs.MajorArmorDebuff, stats: [Stat.StatArmorPenetration] }, - { item: IconInputs.MinorArmorDebuff, stats: [Stat.StatArmorPenetration] }, - { item: IconInputs.PhysicalDamageDebuff, stats: [Stat.StatAttackPower] }, - { item: IconInputs.BleedDebuff, stats: [Stat.StatAttackPower] }, - { item: IconInputs.SpellDamageDebuff, stats: [Stat.StatSpellPower] }, - { item: IconInputs.SpellHitDebuff, stats: [Stat.StatSpellHit] }, - { item: IconInputs.SpellCritDebuff, stats: [Stat.StatSpellCrit] }, - { item: IconInputs.CritDebuff, stats: [Stat.StatMeleeCrit, Stat.StatSpellCrit] }, - { item: IconInputs.AttackPowerDebuff, stats: [Stat.StatArmor] }, - { item: IconInputs.MeleeAttackSpeedDebuff, stats: [Stat.StatArmor] }, - { item: IconInputs.MeleeHitDebuff, stats: [Stat.StatDodge] }, - ]); - const debuffsSection = this.rootElem.getElementsByClassName('debuffs-section')[0] as HTMLElement; - configureIconSection( - debuffsSection, - debuffOptions.map(multiIconInput => new MultiIconPicker(debuffsSection, this.player, multiIconInput, this)), - Tooltips.DEBUFFS_SECTION); - - const otherDebuffOptions = this.splitRelevantOptions([ - { item: IconInputs.JudgementOfWisdom, stats: [Stat.StatMP5, Stat.StatIntellect] }, - { item: IconInputs.HuntersMark, stats: [Stat.StatRangedAttackPower] }, - ] as Array, any>>>); - otherDebuffOptions.forEach(iconInput => makeIconInput(debuffsSection, iconInput)); - - const miscDebuffOptions = this.splitRelevantOptions([ - { item: IconInputs.JudgementOfLight, stats: [Stat.StatStamina] }, - { item: IconInputs.GiftOfArthas, stats: [Stat.StatAttackPower] }, - ] as Array, any>>>); - if (miscDebuffOptions.length > 0) { - new MultiIconPicker(debuffsSection, this.player, { - inputs: miscDebuffOptions, - numColumns: 3, - emptyColor: 'grey', - label: 'Misc', - }, this); - } - - const potionOptions = this.splitRelevantOptions([ - { item: Potions.RunicHealingPotion, stats: [Stat.StatStamina] }, - { item: Potions.RunicManaPotion, stats: [Stat.StatIntellect] }, - { item: Potions.IndestructiblePotion, stats: [Stat.StatArmor] }, - { item: Potions.PotionOfSpeed, stats: [Stat.StatMeleeHaste, Stat.StatSpellHaste] }, - { item: Potions.PotionOfWildMagic, stats: [Stat.StatMeleeCrit, Stat.StatSpellCrit, Stat.StatSpellPower] }, - ]); - if (potionOptions.length) { - const elem = this.rootElem.getElementsByClassName('consumes-potions')[0] as HTMLElement; - new IconEnumPicker(elem, this.player, IconInputs.makePotionsInput(potionOptions)); - } - - const conjuredOptions = this.splitRelevantOptions([ - { item: Conjured.ConjuredHealthstone, stats: [Stat.StatStamina] }, - { item: Conjured.ConjuredDarkRune, stats: [Stat.StatIntellect] }, - { item: Conjured.ConjuredFlameCap, stats: [Stat.StatStrength, Stat.StatAgility, Stat.StatFireSpellPower] }, - ]); - if (conjuredOptions.length) { - const elem = this.rootElem.getElementsByClassName('consumes-conjured')[0] as HTMLElement; - new IconEnumPicker(elem, this.player, IconInputs.makeConjuredInput(conjuredOptions)); - } - - const flaskOptions = this.splitRelevantOptions([ - { item: Flask.FlaskOfTheFrostWyrm, stats: [Stat.StatSpellPower] }, - { item: Flask.FlaskOfEndlessRage, stats: [Stat.StatAttackPower, Stat.StatRangedAttackPower] }, - { item: Flask.FlaskOfPureMojo, stats: [Stat.StatMP5] }, - { item: Flask.FlaskOfStoneblood, stats: [Stat.StatStamina] }, - { item: Flask.LesserFlaskOfToughness, stats: [Stat.StatResilience] }, - { item: Flask.LesserFlaskOfResistance, stats: [Stat.StatArcaneResistance, Stat.StatFireResistance, Stat.StatFrostResistance, Stat.StatNatureResistance, Stat.StatShadowResistance] }, - ]); - if (flaskOptions.length) { - const elem = this.rootElem.getElementsByClassName('consumes-flasks')[0] as HTMLElement; - new IconEnumPicker(elem, this.player, IconInputs.makeFlasksInput(flaskOptions)); - } - - const battleElixirOptions = this.splitRelevantOptions([ - { item: BattleElixir.ElixirOfAccuracy, stats: [Stat.StatMeleeHit, Stat.StatSpellHit] }, - { item: BattleElixir.ElixirOfArmorPiercing, stats: [Stat.StatArmorPenetration] }, - { item: BattleElixir.ElixirOfDeadlyStrikes, stats: [Stat.StatMeleeCrit, Stat.StatSpellCrit] }, - { item: BattleElixir.ElixirOfExpertise, stats: [Stat.StatExpertise] }, - { item: BattleElixir.ElixirOfLightningSpeed, stats: [Stat.StatMeleeHaste, Stat.StatSpellHaste] }, - { item: BattleElixir.ElixirOfMightyAgility, stats: [Stat.StatAgility] }, - { item: BattleElixir.ElixirOfMightyStrength, stats: [Stat.StatStrength] }, - { item: BattleElixir.GurusElixir, stats: [Stat.StatStamina, Stat.StatAgility, Stat.StatStrength, Stat.StatSpirit, Stat.StatIntellect] }, - { item: BattleElixir.SpellpowerElixir, stats: [Stat.StatSpellPower] }, - { item: BattleElixir.WrathElixir, stats: [Stat.StatAttackPower, Stat.StatRangedAttackPower] }, - ]); - if (battleElixirOptions.length) { - const elem = this.rootElem.getElementsByClassName('consumes-battle-elixirs')[0] as HTMLElement; - new IconEnumPicker(elem, this.player, IconInputs.makeBattleElixirsInput(battleElixirOptions)); - } - - const guardianElixirOptions = this.splitRelevantOptions([ - { item: GuardianElixir.ElixirOfMightyDefense, stats: [Stat.StatDefense] }, - { item: GuardianElixir.ElixirOfMightyFortitude, stats: [Stat.StatStamina] }, - { item: GuardianElixir.ElixirOfMightyMageblood, stats: [Stat.StatMP5] }, - { item: GuardianElixir.ElixirOfMightyThoughts, stats: [Stat.StatIntellect] }, - { item: GuardianElixir.ElixirOfProtection, stats: [Stat.StatArmor] }, - { item: GuardianElixir.ElixirOfSpirit, stats: [Stat.StatSpirit] }, - { item: GuardianElixir.GiftOfArthas, stats: [Stat.StatStamina] }, - ]); - if (guardianElixirOptions.length) { - const elem = this.rootElem.getElementsByClassName('consumes-guardian-elixirs')[0] as HTMLElement; - new IconEnumPicker(elem, this.player, IconInputs.makeGuardianElixirsInput(guardianElixirOptions)); - } + const debuffOptions = this.splitRelevantOptions([ + { item: IconInputs.MajorArmorDebuff, stats: [Stat.StatArmorPenetration] }, + { item: IconInputs.MinorArmorDebuff, stats: [Stat.StatArmorPenetration] }, + { item: IconInputs.PhysicalDamageDebuff, stats: [Stat.StatAttackPower] }, + { item: IconInputs.BleedDebuff, stats: [Stat.StatAttackPower] }, + { item: IconInputs.SpellDamageDebuff, stats: [Stat.StatSpellPower] }, + { item: IconInputs.SpellHitDebuff, stats: [Stat.StatSpellHit] }, + { item: IconInputs.SpellCritDebuff, stats: [Stat.StatSpellCrit] }, + { item: IconInputs.CritDebuff, stats: [Stat.StatMeleeCrit, Stat.StatSpellCrit] }, + { item: IconInputs.AttackPowerDebuff, stats: [Stat.StatArmor] }, + { item: IconInputs.MeleeAttackSpeedDebuff, stats: [Stat.StatArmor] }, + { item: IconInputs.MeleeHitDebuff, stats: [Stat.StatDodge] }, + ]); + const debuffsSection = this.rootElem.getElementsByClassName('debuffs-section')[0] as HTMLElement; + configureIconSection( + debuffsSection, + debuffOptions.map(multiIconInput => new MultiIconPicker(debuffsSection, this.player, multiIconInput, this)), + Tooltips.DEBUFFS_SECTION); + + const otherDebuffOptions = this.splitRelevantOptions([ + { item: IconInputs.JudgementOfWisdom, stats: [Stat.StatMP5, Stat.StatIntellect] }, + { item: IconInputs.HuntersMark, stats: [Stat.StatRangedAttackPower] }, + ] as Array, any>>>); + otherDebuffOptions.forEach(iconInput => makeIconInput(debuffsSection, iconInput)); + + const miscDebuffOptions = this.splitRelevantOptions([ + { item: IconInputs.JudgementOfLight, stats: [Stat.StatStamina] }, + { item: IconInputs.GiftOfArthas, stats: [Stat.StatAttackPower] }, + ] as Array, any>>>); + if (miscDebuffOptions.length > 0) { + new MultiIconPicker(debuffsSection, this.player, { + inputs: miscDebuffOptions, + numColumns: 3, + emptyColor: 'grey', + label: 'Misc', + }, this); + } + + const potionOptions = this.splitRelevantOptions([ + { item: Potions.RunicHealingPotion, stats: [Stat.StatStamina] }, + { item: Potions.RunicManaPotion, stats: [Stat.StatIntellect] }, + { item: Potions.IndestructiblePotion, stats: [Stat.StatArmor] }, + { item: Potions.PotionOfSpeed, stats: [Stat.StatMeleeHaste, Stat.StatSpellHaste] }, + { item: Potions.PotionOfWildMagic, stats: [Stat.StatMeleeCrit, Stat.StatSpellCrit, Stat.StatSpellPower] }, + ]); + if (potionOptions.length) { + const elem = this.rootElem.getElementsByClassName('consumes-potions')[0] as HTMLElement; + new IconEnumPicker(elem, this.player, IconInputs.makePotionsInput(potionOptions)); + } + + const conjuredOptions = this.splitRelevantOptions([ + { item: Conjured.ConjuredHealthstone, stats: [Stat.StatStamina] }, + { item: Conjured.ConjuredDarkRune, stats: [Stat.StatIntellect] }, + { item: Conjured.ConjuredFlameCap, stats: [Stat.StatStrength, Stat.StatAgility, Stat.StatFireSpellPower] }, + ]); + if (conjuredOptions.length) { + const elem = this.rootElem.getElementsByClassName('consumes-conjured')[0] as HTMLElement; + new IconEnumPicker(elem, this.player, IconInputs.makeConjuredInput(conjuredOptions)); + } + + const flaskOptions = this.splitRelevantOptions([ + { item: Flask.FlaskOfTheFrostWyrm, stats: [Stat.StatSpellPower] }, + { item: Flask.FlaskOfEndlessRage, stats: [Stat.StatAttackPower, Stat.StatRangedAttackPower] }, + { item: Flask.FlaskOfPureMojo, stats: [Stat.StatMP5] }, + { item: Flask.FlaskOfStoneblood, stats: [Stat.StatStamina] }, + { item: Flask.LesserFlaskOfToughness, stats: [Stat.StatResilience] }, + { item: Flask.LesserFlaskOfResistance, stats: [Stat.StatArcaneResistance, Stat.StatFireResistance, Stat.StatFrostResistance, Stat.StatNatureResistance, Stat.StatShadowResistance] }, + ]); + if (flaskOptions.length) { + const elem = this.rootElem.getElementsByClassName('consumes-flasks')[0] as HTMLElement; + new IconEnumPicker(elem, this.player, IconInputs.makeFlasksInput(flaskOptions)); + } + + const battleElixirOptions = this.splitRelevantOptions([ + { item: BattleElixir.ElixirOfAccuracy, stats: [Stat.StatMeleeHit, Stat.StatSpellHit] }, + { item: BattleElixir.ElixirOfArmorPiercing, stats: [Stat.StatArmorPenetration] }, + { item: BattleElixir.ElixirOfDeadlyStrikes, stats: [Stat.StatMeleeCrit, Stat.StatSpellCrit] }, + { item: BattleElixir.ElixirOfExpertise, stats: [Stat.StatExpertise] }, + { item: BattleElixir.ElixirOfLightningSpeed, stats: [Stat.StatMeleeHaste, Stat.StatSpellHaste] }, + { item: BattleElixir.ElixirOfMightyAgility, stats: [Stat.StatAgility] }, + { item: BattleElixir.ElixirOfMightyStrength, stats: [Stat.StatStrength] }, + { item: BattleElixir.GurusElixir, stats: [Stat.StatStamina, Stat.StatAgility, Stat.StatStrength, Stat.StatSpirit, Stat.StatIntellect] }, + { item: BattleElixir.SpellpowerElixir, stats: [Stat.StatSpellPower] }, + { item: BattleElixir.WrathElixir, stats: [Stat.StatAttackPower, Stat.StatRangedAttackPower] }, + ]); + if (battleElixirOptions.length) { + const elem = this.rootElem.getElementsByClassName('consumes-battle-elixirs')[0] as HTMLElement; + new IconEnumPicker(elem, this.player, IconInputs.makeBattleElixirsInput(battleElixirOptions)); + } + + const guardianElixirOptions = this.splitRelevantOptions([ + { item: GuardianElixir.ElixirOfMightyDefense, stats: [Stat.StatDefense] }, + { item: GuardianElixir.ElixirOfMightyFortitude, stats: [Stat.StatStamina] }, + { item: GuardianElixir.ElixirOfMightyMageblood, stats: [Stat.StatMP5] }, + { item: GuardianElixir.ElixirOfMightyThoughts, stats: [Stat.StatIntellect] }, + { item: GuardianElixir.ElixirOfProtection, stats: [Stat.StatArmor] }, + { item: GuardianElixir.ElixirOfSpirit, stats: [Stat.StatSpirit] }, + { item: GuardianElixir.GiftOfArthas, stats: [Stat.StatStamina] }, + ]); + if (guardianElixirOptions.length) { + const elem = this.rootElem.getElementsByClassName('consumes-guardian-elixirs')[0] as HTMLElement; + new IconEnumPicker(elem, this.player, IconInputs.makeGuardianElixirsInput(guardianElixirOptions)); + } const tradeConsumesElem = this.rootElem.getElementsByClassName('consumes-trade')[0] as HTMLElement; //tradeConsumesElem.parentElement!.style.display = 'none'; @@ -712,220 +712,212 @@ export abstract class IndividualSimUI extends SimUI { }); } - const configureInputSection = (sectionElem: HTMLElement, sectionConfig: InputSection) => { - if (sectionConfig.tooltip) { - tippy(sectionElem, { - 'content': sectionConfig.tooltip, - 'allowHTML': true, - }); - } - - sectionConfig.inputs.forEach(inputConfig => { - if (inputConfig.type == 'number') { - new NumberPicker(sectionElem, this.player, inputConfig); - } else if (inputConfig.type == 'boolean') { - new BooleanPicker(sectionElem, this.player, inputConfig); - } else if (inputConfig.type == 'enum') { - new EnumPicker(sectionElem, this.player, inputConfig); - } - }); - }; - - if (this.individualConfig.rotationIconInputs?.length) { - const rotationIconSection = this.rootElem.getElementsByClassName('rotation-iconrow')[0] as HTMLElement; - configureIconSection( - rotationIconSection, - this.individualConfig.rotationIconInputs.map(iconInput => makeIconInput(rotationIconSection, iconInput)), - '', true); - } - - - configureInputSection(this.rootElem.getElementsByClassName('rotation-section')[0] as HTMLElement, this.individualConfig.rotationInputs); - - if (this.individualConfig.otherInputs?.inputs.length) { - configureInputSection(this.rootElem.getElementsByClassName('other-settings-section')[0] as HTMLElement, this.individualConfig.otherInputs); - } - - const races = specToEligibleRaces[this.player.spec]; - const racePicker = new EnumPicker(this.rootElem.getElementsByClassName('race-section')[0] as HTMLElement, this.player, { - label: 'Race', - values: races.map(race => { - return { - name: raceNames[race], - value: race, - }; - }), - changedEvent: sim => sim.raceChangeEmitter, - getValue: sim => sim.getRace(), - setValue: (eventID, sim, newValue) => sim.setRace(eventID, newValue), - }); - const professions = getEnumValues(Profession) as Array; - const profession1Picker = new EnumPicker(this.rootElem.getElementsByClassName('race-section')[0] as HTMLElement, this.player, { - label: 'Profession 1', - values: professions.map(p => { - return { - name: professionNames[p], - value: p, - }; - }), - changedEvent: sim => sim.professionChangeEmitter, - getValue: sim => sim.getProfession1(), - setValue: (eventID, sim, newValue) => sim.setProfession1(eventID, newValue), - }); - const profession2Picker = new EnumPicker(this.rootElem.getElementsByClassName('race-section')[0] as HTMLElement, this.player, { - label: 'Profession 2', - values: professions.map(p => { - return { - name: professionNames[p], - value: p, - }; - }), - changedEvent: sim => sim.professionChangeEmitter, - getValue: sim => sim.getProfession2(), - setValue: (eventID, sim, newValue) => sim.setProfession2(eventID, newValue), - }); - const shattFactionPicker = new EnumPicker(this.rootElem.getElementsByClassName('race-section')[0] as HTMLElement, this.player, { - label: 'Shatt Faction', - values: [ShattrathFaction.ShattrathFactionAldor, ShattrathFaction.ShattrathFactionScryer].map(faction => { - return { - name: shattFactionNames[faction], - value: faction, - }; - }), - changedEvent: sim => sim.gearChangeEmitter, - getValue: sim => sim.getShattFaction(), - setValue: (eventID, sim, newValue) => sim.setShattFaction(eventID, newValue), - showWhen: (player: Player) => this.player.getEquippedItem(ItemSlot.ItemSlotNeck)?.item.id == 34678 || this.player.getEquippedItem(ItemSlot.ItemSlotNeck)?.item.id == 34679, - }); - - const encounterSectionElem = settingsTab.getElementsByClassName('encounter-section')[0] as HTMLElement; - new EncounterPicker(encounterSectionElem, this.sim.encounter, this.individualConfig.encounterPicker, this); - const savedEncounterManager = new SavedDataManager(this.rootElem.getElementsByClassName('saved-encounter-manager')[0] as HTMLElement, this.sim.encounter, { - label: 'Encounter', - storageKey: this.getSavedEncounterStorageKey(), - getData: (encounter: Encounter) => SavedEncounter.create({ encounter: encounter.toProto() }), - setData: (eventID: EventID, encounter: Encounter, newEncounter: SavedEncounter) => encounter.fromProto(eventID, newEncounter.encounter!), - changeEmitters: [this.sim.encounter.changeEmitter], - equals: (a: SavedEncounter, b: SavedEncounter) => SavedEncounter.equals(a, b), - toJson: (a: SavedEncounter) => SavedEncounter.toJson(a), - fromJson: (obj: any) => SavedEncounter.fromJson(obj), - }); - - const cooldownSectionElem = settingsTab.getElementsByClassName('cooldowns-section')[0] as HTMLElement; - const cooldownContentElem = settingsTab.getElementsByClassName('cooldowns-section-content')[0] as HTMLElement; - new CooldownsPicker(cooldownContentElem, this.player); - tippy(cooldownSectionElem, { - content: Tooltips.COOLDOWNS_SECTION, - allowHTML: true, - placement: 'left', - }); - - // Init Muuri layout only when settings tab is clicked, because it needs the elements - // to be shown so it can calculate sizes. - (this.rootElem.getElementsByClassName('settings-tab-tab')[0] as HTMLElement)!.addEventListener('click', event => { - if (this.settingsMuuri == null) { - setTimeout(() => { - this.settingsMuuri = new Muuri('.settings-inputs'); - }, 200); // Magic amount of time before Muuri init seems to work - } - - setTimeout(() => { - this.recomputeSettingsLayout(); - }, 200); - }); - - const savedSettingsManager = new SavedDataManager, SavedSettings>(this.rootElem.getElementsByClassName('saved-settings-manager')[0] as HTMLElement, this, { - label: 'Settings', - storageKey: this.getSavedSettingsStorageKey(), - getData: (simUI: IndividualSimUI) => { - return SavedSettings.create({ - raidBuffs: simUI.sim.raid.getBuffs(), - partyBuffs: simUI.player.getParty()?.getBuffs() || PartyBuffs.create(), - playerBuffs: simUI.player.getBuffs(), - debuffs: simUI.sim.raid.getDebuffs(), - consumes: simUI.player.getConsumes(), - race: simUI.player.getRace(), - cooldowns: simUI.player.getCooldowns(), - }); - }, - setData: (eventID: EventID, simUI: IndividualSimUI, newSettings: SavedSettings) => { - TypedEvent.freezeAllAndDo(() => { - simUI.sim.raid.setBuffs(eventID, newSettings.raidBuffs || RaidBuffs.create()); - simUI.sim.raid.setDebuffs(eventID, newSettings.debuffs || Debuffs.create()); - const party = simUI.player.getParty(); - if (party) { - party.setBuffs(eventID, newSettings.partyBuffs || PartyBuffs.create()); - } - simUI.player.setBuffs(eventID, newSettings.playerBuffs || IndividualBuffs.create()); - simUI.player.setConsumes(eventID, newSettings.consumes || Consumes.create()); - simUI.player.setRace(eventID, newSettings.race); - simUI.player.setCooldowns(eventID, newSettings.cooldowns || Cooldowns.create()); - }); - }, - changeEmitters: [ - this.sim.raid.buffsChangeEmitter, - this.sim.raid.debuffsChangeEmitter, - this.player.getParty()!.buffsChangeEmitter, - this.player.buffsChangeEmitter, - this.player.consumesChangeEmitter, - this.player.raceChangeEmitter, - this.player.cooldownsChangeEmitter, - ], - equals: (a: SavedSettings, b: SavedSettings) => SavedSettings.equals(a, b), - toJson: (a: SavedSettings) => SavedSettings.toJson(a), - fromJson: (obj: any) => SavedSettings.fromJson(obj), - }); - - const customSectionsContainer = this.rootElem.getElementsByClassName('custom-sections-container')[0] as HTMLElement; - let anyCustomSections = false; - for (const [sectionName, sectionConfig] of Object.entries(this.individualConfig.additionalSections || {})) { - const sectionCssPrefix = sectionName.replace(/\s+/g, ''); - const sectionElem = document.createElement('fieldset'); - sectionElem.classList.add('settings-section', sectionCssPrefix + '-section'); - sectionElem.innerHTML = `${sectionName}`; - customSectionsContainer.appendChild(sectionElem); - configureInputSection(sectionElem, sectionConfig); - anyCustomSections = true; - }; - - for (const [sectionName, sectionConfig] of Object.entries(this.individualConfig.additionalIconSections || {})) { - const sectionCssPrefix = sectionName.replace(/\s+/g, ''); - const sectionElem = document.createElement('fieldset'); - sectionElem.classList.add('settings-section', sectionCssPrefix + '-section'); - sectionElem.innerHTML = `${sectionName}`; - customSectionsContainer.appendChild(sectionElem); - configureIconSection(sectionElem, sectionConfig.map(iconInput => makeIconInput(sectionElem, iconInput))); - anyCustomSections = true; - }; - - (this.individualConfig.customSections || []).forEach(customSection => { - const sectionElem = document.createElement('fieldset'); - customSectionsContainer.appendChild(sectionElem); - const sectionName = customSection(this, sectionElem); - const sectionCssPrefix = sectionName.replace(/\s+/g, ''); - sectionElem.classList.add('settings-section', sectionCssPrefix + '-section'); - const labelElem = document.createElement('legend'); - labelElem.textContent = sectionName; - sectionElem.prepend(labelElem); - anyCustomSections = true; - }); - - if (!anyCustomSections) { - customSectionsContainer.remove(); - } - - this.sim.waitForInit().then(() => { - savedEncounterManager.loadUserData(); - savedSettingsManager.loadUserData(); - }); - - Array.from(this.rootElem.getElementsByClassName('settings-section-container')).forEach((container, i) => { - (container as HTMLElement).style.zIndex = String(1000 - i); - }); - } - - private addTalentsTab() { - this.addTab('TALENTS', 'talents-tab', ` + sectionConfig.inputs.forEach(inputConfig => { + if (inputConfig.type == 'number') { + new NumberPicker(sectionElem, this.player, inputConfig); + } else if (inputConfig.type == 'boolean') { + new BooleanPicker(sectionElem, this.player, inputConfig); + } else if (inputConfig.type == 'enum') { + new EnumPicker(sectionElem, this.player, inputConfig); + } + }); + }; + + if (this.individualConfig.rotationIconInputs?.length) { + const rotationIconSection = this.rootElem.getElementsByClassName('rotation-iconrow')[0] as HTMLElement; + configureIconSection( + rotationIconSection, + this.individualConfig.rotationIconInputs.map(iconInput => makeIconInput(rotationIconSection, iconInput)), + '', true); + } + + + configureInputSection(this.rootElem.getElementsByClassName('rotation-section')[0] as HTMLElement, this.individualConfig.rotationInputs); + + if (this.individualConfig.otherInputs?.inputs.length) { + configureInputSection(this.rootElem.getElementsByClassName('other-settings-section')[0] as HTMLElement, this.individualConfig.otherInputs); + } + + const races = specToEligibleRaces[this.player.spec]; + const racePicker = new EnumPicker(this.rootElem.getElementsByClassName('race-section')[0] as HTMLElement, this.player, { + label: 'Race', + values: races.map(race => { + return { + name: raceNames[race], + value: race, + }; + }), + changedEvent: sim => sim.raceChangeEmitter, + getValue: sim => sim.getRace(), + setValue: (eventID, sim, newValue) => sim.setRace(eventID, newValue), + }); + const professions = getEnumValues(Profession) as Array; + const profession1Picker = new EnumPicker(this.rootElem.getElementsByClassName('race-section')[0] as HTMLElement, this.player, { + label: 'Profession 1', + values: professions.map(p => { + return { + name: professionNames[p], + value: p, + }; + }), + changedEvent: sim => sim.professionChangeEmitter, + getValue: sim => sim.getProfession1(), + setValue: (eventID, sim, newValue) => sim.setProfession1(eventID, newValue), + }); + const profession2Picker = new EnumPicker(this.rootElem.getElementsByClassName('race-section')[0] as HTMLElement, this.player, { + label: 'Profession 2', + values: professions.map(p => { + return { + name: professionNames[p], + value: p, + }; + }), + changedEvent: sim => sim.professionChangeEmitter, + getValue: sim => sim.getProfession2(), + setValue: (eventID, sim, newValue) => sim.setProfession2(eventID, newValue), + }); + const shattFactionPicker = new EnumPicker(this.rootElem.getElementsByClassName('race-section')[0] as HTMLElement, this.player, { + label: 'Shatt Faction', + values: [ShattrathFaction.ShattrathFactionAldor, ShattrathFaction.ShattrathFactionScryer].map(faction => { + return { + name: shattFactionNames[faction], + value: faction, + }; + }), + changedEvent: sim => sim.gearChangeEmitter, + getValue: sim => sim.getShattFaction(), + setValue: (eventID, sim, newValue) => sim.setShattFaction(eventID, newValue), + showWhen: (player: Player) => this.player.getEquippedItem(ItemSlot.ItemSlotNeck)?.item.id == 34678 || this.player.getEquippedItem(ItemSlot.ItemSlotNeck)?.item.id == 34679, + }); + + const encounterSectionElem = settingsTab.getElementsByClassName('encounter-section')[0] as HTMLElement; + new EncounterPicker(encounterSectionElem, this.sim.encounter, this.individualConfig.encounterPicker, this); + const savedEncounterManager = new SavedDataManager(this.rootElem.getElementsByClassName('saved-encounter-manager')[0] as HTMLElement, this.sim.encounter, { + label: 'Encounter', + storageKey: this.getSavedEncounterStorageKey(), + getData: (encounter: Encounter) => SavedEncounter.create({ encounter: encounter.toProto() }), + setData: (eventID: EventID, encounter: Encounter, newEncounter: SavedEncounter) => encounter.fromProto(eventID, newEncounter.encounter!), + changeEmitters: [this.sim.encounter.changeEmitter], + equals: (a: SavedEncounter, b: SavedEncounter) => SavedEncounter.equals(a, b), + toJson: (a: SavedEncounter) => SavedEncounter.toJson(a), + fromJson: (obj: any) => SavedEncounter.fromJson(obj), + }); + + const cooldownSectionElem = settingsTab.getElementsByClassName('cooldowns-section')[0] as HTMLElement; + const cooldownContentElem = settingsTab.getElementsByClassName('cooldowns-section-content')[0] as HTMLElement; + new CooldownsPicker(cooldownContentElem, this.player); + tippy(cooldownSectionElem, { + content: Tooltips.COOLDOWNS_SECTION, + allowHTML: true, + placement: 'left', + }); + + // Init Muuri layout only when settings tab is clicked, because it needs the elements + // to be shown so it can calculate sizes. + (this.rootElem.getElementsByClassName('settings-tab-tab')[0] as HTMLElement)!.addEventListener('click', event => { + if (this.settingsMuuri == null) { + setTimeout(() => { + this.settingsMuuri = new Muuri('.settings-inputs'); + }, 200); // Magic amount of time before Muuri init seems to work + } + + setTimeout(() => { + this.recomputeSettingsLayout(); + }, 200); + }); + + const savedSettingsManager = new SavedDataManager, SavedSettings>(this.rootElem.getElementsByClassName('saved-settings-manager')[0] as HTMLElement, this, { + label: 'Settings', + storageKey: this.getSavedSettingsStorageKey(), + getData: (simUI: IndividualSimUI) => { + return SavedSettings.create({ + raidBuffs: simUI.sim.raid.getBuffs(), + partyBuffs: simUI.player.getParty()?.getBuffs() || PartyBuffs.create(), + playerBuffs: simUI.player.getBuffs(), + debuffs: simUI.sim.raid.getDebuffs(), + consumes: simUI.player.getConsumes(), + race: simUI.player.getRace(), + cooldowns: simUI.player.getCooldowns(), + }); + }, + setData: (eventID: EventID, simUI: IndividualSimUI, newSettings: SavedSettings) => { + TypedEvent.freezeAllAndDo(() => { + simUI.sim.raid.setBuffs(eventID, newSettings.raidBuffs || RaidBuffs.create()); + simUI.sim.raid.setDebuffs(eventID, newSettings.debuffs || Debuffs.create()); + const party = simUI.player.getParty(); + if (party) { + party.setBuffs(eventID, newSettings.partyBuffs || PartyBuffs.create()); + } + simUI.player.setBuffs(eventID, newSettings.playerBuffs || IndividualBuffs.create()); + simUI.player.setConsumes(eventID, newSettings.consumes || Consumes.create()); + simUI.player.setRace(eventID, newSettings.race); + simUI.player.setCooldowns(eventID, newSettings.cooldowns || Cooldowns.create()); + }); + }, + changeEmitters: [ + this.sim.raid.buffsChangeEmitter, + this.sim.raid.debuffsChangeEmitter, + this.player.getParty()!.buffsChangeEmitter, + this.player.buffsChangeEmitter, + this.player.consumesChangeEmitter, + this.player.raceChangeEmitter, + this.player.cooldownsChangeEmitter, + ], + equals: (a: SavedSettings, b: SavedSettings) => SavedSettings.equals(a, b), + toJson: (a: SavedSettings) => SavedSettings.toJson(a), + fromJson: (obj: any) => SavedSettings.fromJson(obj), + }); + + const customSectionsContainer = this.rootElem.getElementsByClassName('custom-sections-container')[0] as HTMLElement; + let anyCustomSections = false; + for (const [sectionName, sectionConfig] of Object.entries(this.individualConfig.additionalSections || {})) { + const sectionCssPrefix = sectionName.replace(/\s+/g, ''); + const sectionElem = document.createElement('fieldset'); + sectionElem.classList.add('settings-section', sectionCssPrefix + '-section'); + sectionElem.innerHTML = `${sectionName}`; + customSectionsContainer.appendChild(sectionElem); + configureInputSection(sectionElem, sectionConfig); + anyCustomSections = true; + }; + + for (const [sectionName, sectionConfig] of Object.entries(this.individualConfig.additionalIconSections || {})) { + const sectionCssPrefix = sectionName.replace(/\s+/g, ''); + const sectionElem = document.createElement('fieldset'); + sectionElem.classList.add('settings-section', sectionCssPrefix + '-section'); + sectionElem.innerHTML = `${sectionName}`; + customSectionsContainer.appendChild(sectionElem); + configureIconSection(sectionElem, sectionConfig.map(iconInput => makeIconInput(sectionElem, iconInput))); + anyCustomSections = true; + }; + + (this.individualConfig.customSections || []).forEach(customSection => { + const sectionElem = document.createElement('fieldset'); + customSectionsContainer.appendChild(sectionElem); + const sectionName = customSection(this, sectionElem); + const sectionCssPrefix = sectionName.replace(/\s+/g, ''); + sectionElem.classList.add('settings-section', sectionCssPrefix + '-section'); + const labelElem = document.createElement('legend'); + labelElem.textContent = sectionName; + sectionElem.prepend(labelElem); + anyCustomSections = true; + }); + + if (!anyCustomSections) { + customSectionsContainer.remove(); + } + + this.sim.waitForInit().then(() => { + savedEncounterManager.loadUserData(); + savedSettingsManager.loadUserData(); + }); + + Array.from(this.rootElem.getElementsByClassName('settings-section-container')).forEach((container, i) => { + (container as HTMLElement).style.zIndex = String(1000 - i); + }); + } + + private addTalentsTab() { + this.addTab('TALENTS', 'talents-tab', `
@@ -947,220 +939,220 @@ export abstract class IndividualSimUI extends SimUI {
`); - const talentsPicker = newTalentsPicker(this.rootElem.getElementsByClassName('talents-picker')[0] as HTMLElement, this.player); - const glyphsPicker = newGlyphsPicker(this.rootElem.getElementsByClassName('glyphs-picker')[0] as HTMLElement, this.player); - - const savedTalentsManager = new SavedDataManager, SavedTalents>(this.rootElem.getElementsByClassName('saved-talents-manager')[0] as HTMLElement, this.player, { - label: 'Talents', - storageKey: this.getSavedTalentsStorageKey(), - getData: (player: Player) => SavedTalents.create({ - talentsString: player.getTalentsString(), - glyphs: player.getGlyphs(), - }), - setData: (eventID: EventID, player: Player, newTalents: SavedTalents) => { - TypedEvent.freezeAllAndDo(() => { - player.setTalentsString(eventID, newTalents.talentsString); - player.setGlyphs(eventID, newTalents.glyphs || Glyphs.create()); - }); - }, - changeEmitters: [this.player.talentsChangeEmitter, this.player.glyphsChangeEmitter], - equals: (a: SavedTalents, b: SavedTalents) => SavedTalents.equals(a, b), - toJson: (a: SavedTalents) => SavedTalents.toJson(a), - fromJson: (obj: any) => SavedTalents.fromJson(obj), - }); - - this.sim.waitForInit().then(() => { - savedTalentsManager.loadUserData(); - this.individualConfig.presets.talents.forEach(config => { - config.isPreset = true; - savedTalentsManager.addSavedData({ - name: config.name, - isPreset: true, - data: config.data, - }); - }); - - if (this.player.getClass() == Class.ClassHunter) { - const petTalentsPicker = new HunterPetTalentsPicker(this.rootElem.getElementsByClassName('pet-talents-picker')[0] as HTMLElement, this.player as Player); - - let curShown = 0; - const toggledElems = Array.from(this.rootElem.getElementsByClassName('talents-content')) as Array; - const updateToggle = () => { - toggledElems[1 - curShown].style.display = 'none'; - toggledElems[curShown].style.removeProperty('display'); - - if (curShown == 0) { - petTypeToggle.rootElem.style.display = 'none'; - } else { - petTypeToggle.rootElem.style.removeProperty('display'); - } - } - - const toggleContainer = this.rootElem.getElementsByClassName('player-pet-toggle')[0] as HTMLElement; - const playerPetToggle = new EnumPicker(toggleContainer, this, { - values: [ - { name: 'Player', value: 0 }, - { name: 'Pet', value: 1 }, - ], - changedEvent: sim => new TypedEvent(), - getValue: sim => curShown, - setValue: (eventID, sim, newValue) => { - curShown = newValue; - updateToggle(); - }, - }); - const petTypeToggle = new IconEnumPicker(toggleContainer, this.player as Player, makePetTypeInputConfig(false)); - updateToggle(); - } - }); - } - - private addDetailedResultsTab() { - this.addTab('DETAILED RESULTS', 'detailed-results-tab', ` + const talentsPicker = newTalentsPicker(this.rootElem.getElementsByClassName('talents-picker')[0] as HTMLElement, this.player); + const glyphsPicker = newGlyphsPicker(this.rootElem.getElementsByClassName('glyphs-picker')[0] as HTMLElement, this.player); + + const savedTalentsManager = new SavedDataManager, SavedTalents>(this.rootElem.getElementsByClassName('saved-talents-manager')[0] as HTMLElement, this.player, { + label: 'Talents', + storageKey: this.getSavedTalentsStorageKey(), + getData: (player: Player) => SavedTalents.create({ + talentsString: player.getTalentsString(), + glyphs: player.getGlyphs(), + }), + setData: (eventID: EventID, player: Player, newTalents: SavedTalents) => { + TypedEvent.freezeAllAndDo(() => { + player.setTalentsString(eventID, newTalents.talentsString); + player.setGlyphs(eventID, newTalents.glyphs || Glyphs.create()); + }); + }, + changeEmitters: [this.player.talentsChangeEmitter, this.player.glyphsChangeEmitter], + equals: (a: SavedTalents, b: SavedTalents) => SavedTalents.equals(a, b), + toJson: (a: SavedTalents) => SavedTalents.toJson(a), + fromJson: (obj: any) => SavedTalents.fromJson(obj), + }); + + this.sim.waitForInit().then(() => { + savedTalentsManager.loadUserData(); + this.individualConfig.presets.talents.forEach(config => { + config.isPreset = true; + savedTalentsManager.addSavedData({ + name: config.name, + isPreset: true, + data: config.data, + }); + }); + + if (this.player.getClass() == Class.ClassHunter) { + const petTalentsPicker = new HunterPetTalentsPicker(this.rootElem.getElementsByClassName('pet-talents-picker')[0] as HTMLElement, this.player as Player); + + let curShown = 0; + const toggledElems = Array.from(this.rootElem.getElementsByClassName('talents-content')) as Array; + const updateToggle = () => { + toggledElems[1 - curShown].style.display = 'none'; + toggledElems[curShown].style.removeProperty('display'); + + if (curShown == 0) { + petTypeToggle.rootElem.style.display = 'none'; + } else { + petTypeToggle.rootElem.style.removeProperty('display'); + } + } + + const toggleContainer = this.rootElem.getElementsByClassName('player-pet-toggle')[0] as HTMLElement; + const playerPetToggle = new EnumPicker(toggleContainer, this, { + values: [ + { name: 'Player', value: 0 }, + { name: 'Pet', value: 1 }, + ], + changedEvent: sim => new TypedEvent(), + getValue: sim => curShown, + setValue: (eventID, sim, newValue) => { + curShown = newValue; + updateToggle(); + }, + }); + const petTypeToggle = new IconEnumPicker(toggleContainer, this.player as Player, makePetTypeInputConfig(false)); + updateToggle(); + } + }); + } + + private addDetailedResultsTab() { + this.addTab('DETAILED RESULTS', 'detailed-results-tab', `
`); - const detailedResults = new DetailedResults(this.rootElem.getElementsByClassName('detailed-results')[0] as HTMLElement, this, this.raidSimResultsManager!); - } + const detailedResults = new DetailedResults(this.rootElem.getElementsByClassName('detailed-results')[0] as HTMLElement, this, this.raidSimResultsManager!); + } - private addLogTab() { - this.addTab('LOG', 'log-tab', ` + private addLogTab() { + this.addTab('LOG', 'log-tab', `
`); - const logRunner = new LogRunner(this.rootElem.getElementsByClassName('log-runner')[0] as HTMLElement, this); - } - - applyDefaults(eventID: EventID) { - TypedEvent.freezeAllAndDo(() => { - const tankSpec = isTankSpec(this.player.spec); - - this.player.setRace(eventID, specToEligibleRaces[this.player.spec][0]); - this.player.setGear(eventID, this.sim.lookupEquipmentSpec(this.individualConfig.defaults.gear)); - this.player.setConsumes(eventID, this.individualConfig.defaults.consumes); - this.player.setRotation(eventID, this.individualConfig.defaults.rotation); - this.player.setTalentsString(eventID, this.individualConfig.defaults.talents.talentsString); - this.player.setGlyphs(eventID, this.individualConfig.defaults.talents.glyphs || Glyphs.create()); - this.player.setSpecOptions(eventID, this.individualConfig.defaults.specOptions); - this.player.setBuffs(eventID, this.individualConfig.defaults.individualBuffs); - this.player.getParty()!.setBuffs(eventID, this.individualConfig.defaults.partyBuffs); - this.player.getRaid()!.setBuffs(eventID, this.individualConfig.defaults.raidBuffs); - this.player.setEpWeights(eventID, this.individualConfig.defaults.epWeights); - this.player.applySharedDefaults(eventID); - - if (!this.isWithinRaidSim) { - this.sim.encounter.applyDefaults(eventID); - this.sim.raid.setDebuffs(eventID, this.individualConfig.defaults.debuffs); - this.sim.applyDefaults(eventID, tankSpec); - - if (tankSpec) { - this.sim.raid.setTanks(eventID, [this.player.makeRaidTarget()]); - } else { - this.sim.raid.setTanks(eventID, []); - } - } - }); - } - - getSavedGearStorageKey(): string { - return this.getStorageKey(SAVED_GEAR_STORAGE_KEY); - } - - getSavedRotationStorageKey(): string { - return this.getStorageKey(SAVED_ROTATION_STORAGE_KEY); - } - - getSavedSettingsStorageKey(): string { - return this.getStorageKey(SAVED_SETTINGS_STORAGE_KEY); - } - - getSavedTalentsStorageKey(): string { - return this.getStorageKey(SAVED_TALENTS_STORAGE_KEY); - } - - private recomputeSettingsLayout() { - if (this.settingsMuuri) { - //this.settingsMuuri.refreshItems(); - } - window.dispatchEvent(new Event('resize')); - } - - // Returns the actual key to use for local storage, based on the given key part and the site context. - getStorageKey(keyPart: string): string { - // Local storage is shared by all sites under the same domain, so we need to use - // different keys for each spec site. - return specToLocalStorageKey[this.player.spec] + keyPart; - } - - toProto(): IndividualSimSettings { - return IndividualSimSettings.create({ - settings: this.sim.toProto(), - player: this.player.toProto(true), - raidBuffs: this.sim.raid.getBuffs(), - debuffs: this.sim.raid.getDebuffs(), - tanks: this.sim.raid.getTanks(), - partyBuffs: this.player.getParty()?.getBuffs() || PartyBuffs.create(), - encounter: this.sim.encounter.toProto(), - epWeights: this.player.getEpWeights().asArray(), - }); - } - - toLink(): string { - const proto = this.toProto(); - // When sharing links, people generally don't intend to share settings/ep weights. - proto.settings = undefined; - proto.epWeights = []; - - const protoBytes = IndividualSimSettings.toBinary(proto); - const deflated = pako.deflate(protoBytes, { to: 'string' }); - const encoded = btoa(String.fromCharCode(...deflated)); - - const linkUrl = new URL(window.location.href); - linkUrl.hash = encoded; - return linkUrl.toString(); - } - - fromProto(eventID: EventID, settings: IndividualSimSettings) { - TypedEvent.freezeAllAndDo(() => { - if (!settings.player) { - return; - } - if (settings.settings) { - this.sim.fromProto(eventID, settings.settings); - } - this.player.fromProto(eventID, settings.player); - if (settings.epWeights?.length > 0) { - this.player.setEpWeights(eventID, new Stats(settings.epWeights)); - } else { - this.player.setEpWeights(eventID, this.individualConfig.defaults.epWeights); - } - this.sim.raid.setBuffs(eventID, settings.raidBuffs || RaidBuffs.create()); - this.sim.raid.setDebuffs(eventID, settings.debuffs || Debuffs.create()); - this.sim.raid.setTanks(eventID, settings.tanks || []); - const party = this.player.getParty(); - if (party) { - party.setBuffs(eventID, settings.partyBuffs || PartyBuffs.create()); - } - - this.sim.encounter.fromProto(eventID, settings.encounter || EncounterProto.create()); - }); - } - - splitRelevantOptions(options: Array>): Array { - return options - .filter(option => - this.individualConfig.includeBuffDebuffInputs.includes(option.item) || - option.stats.length == 0 || - option.stats.some(stat => this.individualConfig.epStats.includes(stat))) - .filter(option => - !this.individualConfig.excludeBuffDebuffInputs.includes(option.item)) - .map(option => option.item); - } + const logRunner = new LogRunner(this.rootElem.getElementsByClassName('log-runner')[0] as HTMLElement, this); + } + + applyDefaults(eventID: EventID) { + TypedEvent.freezeAllAndDo(() => { + const tankSpec = isTankSpec(this.player.spec); + + this.player.setRace(eventID, specToEligibleRaces[this.player.spec][0]); + this.player.setGear(eventID, this.sim.lookupEquipmentSpec(this.individualConfig.defaults.gear)); + this.player.setConsumes(eventID, this.individualConfig.defaults.consumes); + this.player.setRotation(eventID, this.individualConfig.defaults.rotation); + this.player.setTalentsString(eventID, this.individualConfig.defaults.talents.talentsString); + this.player.setGlyphs(eventID, this.individualConfig.defaults.talents.glyphs || Glyphs.create()); + this.player.setSpecOptions(eventID, this.individualConfig.defaults.specOptions); + this.player.setBuffs(eventID, this.individualConfig.defaults.individualBuffs); + this.player.getParty()!.setBuffs(eventID, this.individualConfig.defaults.partyBuffs); + this.player.getRaid()!.setBuffs(eventID, this.individualConfig.defaults.raidBuffs); + this.player.setEpWeights(eventID, this.individualConfig.defaults.epWeights); + this.player.applySharedDefaults(eventID); + + if (!this.isWithinRaidSim) { + this.sim.encounter.applyDefaults(eventID); + this.sim.raid.setDebuffs(eventID, this.individualConfig.defaults.debuffs); + this.sim.applyDefaults(eventID, tankSpec); + + if (tankSpec) { + this.sim.raid.setTanks(eventID, [this.player.makeRaidTarget()]); + } else { + this.sim.raid.setTanks(eventID, []); + } + } + }); + } + + getSavedGearStorageKey(): string { + return this.getStorageKey(SAVED_GEAR_STORAGE_KEY); + } + + getSavedRotationStorageKey(): string { + return this.getStorageKey(SAVED_ROTATION_STORAGE_KEY); + } + + getSavedSettingsStorageKey(): string { + return this.getStorageKey(SAVED_SETTINGS_STORAGE_KEY); + } + + getSavedTalentsStorageKey(): string { + return this.getStorageKey(SAVED_TALENTS_STORAGE_KEY); + } + + private recomputeSettingsLayout() { + if (this.settingsMuuri) { + //this.settingsMuuri.refreshItems(); + } + window.dispatchEvent(new Event('resize')); + } + + // Returns the actual key to use for local storage, based on the given key part and the site context. + getStorageKey(keyPart: string): string { + // Local storage is shared by all sites under the same domain, so we need to use + // different keys for each spec site. + return specToLocalStorageKey[this.player.spec] + keyPart; + } + + toProto(): IndividualSimSettings { + return IndividualSimSettings.create({ + settings: this.sim.toProto(), + player: this.player.toProto(true), + raidBuffs: this.sim.raid.getBuffs(), + debuffs: this.sim.raid.getDebuffs(), + tanks: this.sim.raid.getTanks(), + partyBuffs: this.player.getParty()?.getBuffs() || PartyBuffs.create(), + encounter: this.sim.encounter.toProto(), + epWeights: this.player.getEpWeights().asArray(), + }); + } + + toLink(): string { + const proto = this.toProto(); + // When sharing links, people generally don't intend to share settings/ep weights. + proto.settings = undefined; + proto.epWeights = []; + + const protoBytes = IndividualSimSettings.toBinary(proto); + const deflated = pako.deflate(protoBytes, { to: 'string' }); + const encoded = btoa(String.fromCharCode(...deflated)); + + const linkUrl = new URL(window.location.href); + linkUrl.hash = encoded; + return linkUrl.toString(); + } + + fromProto(eventID: EventID, settings: IndividualSimSettings) { + TypedEvent.freezeAllAndDo(() => { + if (!settings.player) { + return; + } + if (settings.settings) { + this.sim.fromProto(eventID, settings.settings); + } + this.player.fromProto(eventID, settings.player); + if (settings.epWeights?.length > 0) { + this.player.setEpWeights(eventID, new Stats(settings.epWeights)); + } else { + this.player.setEpWeights(eventID, this.individualConfig.defaults.epWeights); + } + this.sim.raid.setBuffs(eventID, settings.raidBuffs || RaidBuffs.create()); + this.sim.raid.setDebuffs(eventID, settings.debuffs || Debuffs.create()); + this.sim.raid.setTanks(eventID, settings.tanks || []); + const party = this.player.getParty(); + if (party) { + party.setBuffs(eventID, settings.partyBuffs || PartyBuffs.create()); + } + + this.sim.encounter.fromProto(eventID, settings.encounter || EncounterProto.create()); + }); + } + + splitRelevantOptions(options: Array>): Array { + return options + .filter(option => + this.individualConfig.includeBuffDebuffInputs.includes(option.item) || + option.stats.length == 0 || + option.stats.some(stat => this.individualConfig.epStats.includes(stat))) + .filter(option => + !this.individualConfig.excludeBuffDebuffInputs.includes(option.item)) + .map(option => option.item); + } } export interface StatOption { - stats: Array, - item: T, + stats: Array, + item: T, } diff --git a/ui/core/tsconfig.json b/ui/core/tsconfig.json deleted file mode 100644 index b76d1f04fe..0000000000 --- a/ui/core/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../tsconfig-base", - "compilerOptions": { - "composite": true, - "rootDir": "..", - "outDir": "../../dist/wotlk", - }, - "include": [ - "**/*.js", - "**/*.ts", - ] -} diff --git a/ui/deathknight/index.ts b/ui/deathknight/index.ts index a70c83b2fc..0145fe692b 100644 --- a/ui/deathknight/index.ts +++ b/ui/deathknight/index.ts @@ -1,7 +1,7 @@ import { Spec } from '../core/proto/common.js'; import { Sim } from '../core/sim.js'; import { Player } from '../core/player.js'; -import { EventID, TypedEvent } from '../core/typed_event.js'; +import { TypedEvent } from '../core/typed_event.js'; import { DeathknightSimUI } from './sim.js'; diff --git a/ui/deathknight/inputs.ts b/ui/deathknight/inputs.ts index c0bd5dc503..d9797bd7da 100644 --- a/ui/deathknight/inputs.ts +++ b/ui/deathknight/inputs.ts @@ -9,7 +9,7 @@ import { Deathknight_Options as DeathKnightOptions, } from '../core/proto/deathknight.js'; -import * as InputHelpers from '/wotlk/core/components/input_helpers.js'; +import * as InputHelpers from '../core/components/input_helpers.js'; import { Player } from '../core/player'; import { TypedEvent } from '../core/typed_event'; diff --git a/ui/deathknight/presets.ts b/ui/deathknight/presets.ts index 300dbad833..204d33788d 100644 --- a/ui/deathknight/presets.ts +++ b/ui/deathknight/presets.ts @@ -7,7 +7,6 @@ import { Potions } from '../core/proto/common.js'; import { SavedTalents } from '../core/proto/ui.js'; import { - DeathknightTalents, Deathknight_Rotation as DeathKnightRotation, Deathknight_Options as DeathKnightOptions, DeathknightMajorGlyph, diff --git a/ui/deathknight/tsconfig.json b/ui/deathknight/tsconfig.json deleted file mode 100644 index 21cd0281e4..0000000000 --- a/ui/deathknight/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../tsconfig-base", - "compilerOptions": { - "composite": true, - "outDir": "../../dist/wotlk/deathknight", - }, - "include": [ - "**/*.ts", - ], - "references": [ - { "path": "../core" }, - ], -} diff --git a/ui/detailed_results/tsconfig.json b/ui/detailed_results/tsconfig.json deleted file mode 100644 index b77a71124e..0000000000 --- a/ui/detailed_results/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../tsconfig-base", - "compilerOptions": { - "declaration": false, - "outDir": "../../dist/wotlk/detailed_results", - }, - "include": [ - "**/*.ts", - ], - "references": [ - { "path": "../core" }, - ], -} diff --git a/ui/elemental_shaman/index.ts b/ui/elemental_shaman/index.ts index 7c73ef5593..4af2959e9a 100644 --- a/ui/elemental_shaman/index.ts +++ b/ui/elemental_shaman/index.ts @@ -1,7 +1,7 @@ import { Spec } from '../core/proto/common.js'; import { Sim } from '../core/sim.js'; import { Player } from '../core/player.js'; -import { EventID, TypedEvent } from '../core/typed_event.js'; +import { TypedEvent } from '../core/typed_event.js'; import { ElementalShamanSimUI } from './sim.js'; diff --git a/ui/elemental_shaman/presets.ts b/ui/elemental_shaman/presets.ts index f2c58bce60..98e5449334 100644 --- a/ui/elemental_shaman/presets.ts +++ b/ui/elemental_shaman/presets.ts @@ -4,15 +4,12 @@ import { EquipmentSpec } from '../core/proto/common.js'; import { Flask } from '../core/proto/common.js'; import { Food } from '../core/proto/common.js'; import { Glyphs } from '../core/proto/common.js'; -import { ItemSpec } from '../core/proto/common.js'; import { Potions } from '../core/proto/common.js'; -import { Faction } from '../core/proto/common.js'; import { SavedTalents } from '../core/proto/ui.js'; import { WeaponImbue } from '../core/proto/common.js'; -import { Player } from '../core/player.js'; -import { ElementalShaman, ElementalShaman_Rotation as ElementalShamanRotation, ElementalShaman_Options as ElementalShamanOptions, ShamanShield, ShamanMajorGlyph, ShamanMinorGlyph } from '/wotlk/core/proto/shaman.js'; -import { ElementalShaman_Rotation_RotationType as RotationType } from '/wotlk/core/proto/shaman.js'; +import { ElementalShaman_Rotation as ElementalShamanRotation, ElementalShaman_Options as ElementalShamanOptions, ShamanShield, ShamanMajorGlyph, ShamanMinorGlyph } from '../core/proto/shaman.js'; +import { ElementalShaman_Rotation_RotationType as RotationType } from '../core/proto/shaman.js'; import { AirTotem, @@ -23,8 +20,6 @@ import { } from '../core/proto/shaman.js'; -import * as Enchants from '../core/constants/enchants.js'; -import * as Gems from '../core/proto_utils/gems.js'; import * as Tooltips from '../core/constants/tooltips.js'; // Preset options for this spec. @@ -37,7 +32,7 @@ export const StandardTalents = { name: 'Standard', data: SavedTalents.create({ talentsString: '0532001523212351322301351-005052031', - glyphs: Glyphs.create({ + glyphs: Glyphs.create({ major1: ShamanMajorGlyph.GlyphOfLava, major2: ShamanMajorGlyph.GlyphOfTotemOfWrath, major3: ShamanMajorGlyph.GlyphOfLightningBolt, diff --git a/ui/elemental_shaman/tsconfig.json b/ui/elemental_shaman/tsconfig.json deleted file mode 100644 index fe51b7ebac..0000000000 --- a/ui/elemental_shaman/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../tsconfig-base", - "compilerOptions": { - "composite": true, - "outDir": "../../dist/wotlk/elemental_shaman", - }, - "include": [ - "**/*.ts", - ], - "references": [ - { "path": "../core" }, - ], -} diff --git a/ui/enhancement_shaman/index.ts b/ui/enhancement_shaman/index.ts index e86b9395b7..abf16d9d72 100644 --- a/ui/enhancement_shaman/index.ts +++ b/ui/enhancement_shaman/index.ts @@ -1,7 +1,7 @@ import { Spec } from '../core/proto/common.js'; import { Sim } from '../core/sim.js'; import { Player } from '../core/player.js'; -import { EventID, TypedEvent } from '../core/typed_event.js'; +import { TypedEvent } from '../core/typed_event.js'; import { EnhancementShamanSimUI } from './sim.js'; diff --git a/ui/enhancement_shaman/inputs.ts b/ui/enhancement_shaman/inputs.ts index 44b1f77f7e..3c39ff6b72 100644 --- a/ui/enhancement_shaman/inputs.ts +++ b/ui/enhancement_shaman/inputs.ts @@ -13,15 +13,15 @@ import { ShamanShield, ShamanImbue, ShamanSyncType -} from '/wotlk/core/proto/shaman.js'; -import { Spec } from '/wotlk/core/proto/common.js'; -import { WeaponImbue } from '/wotlk/core/proto/common.js'; -import { ActionId } from '/wotlk/core/proto_utils/action_id.js'; -import { Player } from '/wotlk/core/player.js'; -import { Sim } from '/wotlk/core/sim.js'; -import { IndividualSimUI } from '/wotlk/core/individual_sim_ui.js'; -import { Target } from '/wotlk/core/target.js'; -import { EventID, TypedEvent } from '/wotlk/core/typed_event.js'; +} from '../core/proto/shaman.js'; +import { Spec } from '../core/proto/common.js'; +import { WeaponImbue } from '../core/proto/common.js'; +import { ActionId } from '../core/proto_utils/action_id.js'; +import { Player } from '../core/player.js'; +import { Sim } from '../core/sim.js'; +import { IndividualSimUI } from '../core/individual_sim_ui.js'; +import { Target } from '../core/target.js'; +import { EventID, TypedEvent } from '../core/typed_event.js'; import * as InputHelpers from '../core/components/input_helpers.js'; diff --git a/ui/enhancement_shaman/presets.ts b/ui/enhancement_shaman/presets.ts index f2dd33cb07..1dc5b8a4c5 100644 --- a/ui/enhancement_shaman/presets.ts +++ b/ui/enhancement_shaman/presets.ts @@ -3,15 +3,10 @@ import { Consumes } from '../core/proto/common.js'; import { EquipmentSpec } from '../core/proto/common.js'; import { Flask } from '../core/proto/common.js'; import { Food } from '../core/proto/common.js'; -import { Glyphs } from '../core/proto/common.js'; -import { ItemSpec } from '../core/proto/common.js'; import { Potions } from '../core/proto/common.js'; -import { WeaponImbue } from '../core/proto/common.js'; -import { Faction } from '../core/proto/common.js'; import { SavedTalents } from '../core/proto/ui.js'; -import { Player } from '../core/player.js'; -import { EnhancementShaman, EnhancementShaman_Rotation as EnhancementShamanRotation, EnhancementShaman_Options as EnhancementShamanOptions, ShamanShield } from '../core/proto/shaman.js'; +import { EnhancementShaman_Rotation as EnhancementShamanRotation, EnhancementShaman_Options as EnhancementShamanOptions, ShamanShield } from '../core/proto/shaman.js'; import { AirTotem, EarthTotem, @@ -20,10 +15,8 @@ import { ShamanTotems, ShamanImbue, ShamanSyncType -} from '/wotlk/core/proto/shaman.js'; +} from '../core/proto/shaman.js'; -import * as Enchants from '../core/constants/enchants.js'; -import * as Gems from '../core/proto_utils/gems.js'; import * as Tooltips from '../core/constants/tooltips.js'; // Preset options for this spec. diff --git a/ui/enhancement_shaman/tsconfig.json b/ui/enhancement_shaman/tsconfig.json deleted file mode 100644 index 8410a330a1..0000000000 --- a/ui/enhancement_shaman/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../tsconfig-base", - "compilerOptions": { - "composite": true, - "outDir": "../../dist/wotlk/enhancement_shaman", - }, - "include": [ - "**/*.ts", - ], - "references": [ - { "path": "../core" }, - ], -} diff --git a/ui/feral_druid/index.ts b/ui/feral_druid/index.ts index 63b71b7a04..afd0aef953 100644 --- a/ui/feral_druid/index.ts +++ b/ui/feral_druid/index.ts @@ -1,7 +1,7 @@ import { Spec } from '../core/proto/common.js'; import { Sim } from '../core/sim.js'; import { Player } from '../core/player.js'; -import { EventID, TypedEvent } from '../core/typed_event.js'; +import { TypedEvent } from '../core/typed_event.js'; import { FeralDruidSimUI } from './sim.js'; diff --git a/ui/feral_druid/presets.ts b/ui/feral_druid/presets.ts index b887cb93c3..49246300be 100644 --- a/ui/feral_druid/presets.ts +++ b/ui/feral_druid/presets.ts @@ -1,21 +1,15 @@ import { Consumes } from '../core/proto/common.js'; import { BattleElixir } from '../core/proto/common.js'; import { Food } from '../core/proto/common.js'; -import { Glyphs } from '../core/proto/common.js'; import { EquipmentSpec } from '../core/proto/common.js'; -import { ItemSpec } from '../core/proto/common.js'; import { Potions } from '../core/proto/common.js'; import { Conjured } from '../core/proto/common.js'; import { WeaponImbue } from '../core/proto/common.js'; -import { Faction } from '../core/proto/common.js'; import { SavedTalents } from '../core/proto/ui.js'; -import { Player } from '../core/player.js'; -import { FeralDruid, FeralDruid_Rotation as FeralDruidRotation, DruidTalents as DruidTalents, FeralDruid_Options as FeralDruidOptions } from '../core/proto/druid.js'; +import { FeralDruid_Rotation as FeralDruidRotation, FeralDruid_Options as FeralDruidOptions } from '../core/proto/druid.js'; import { FeralDruid_Rotation_FinishingMove as FinishingMove } from '../core/proto/druid.js'; -import * as Enchants from '../core/constants/enchants.js'; -import * as Gems from '../core/proto_utils/gems.js'; import * as Tooltips from '../core/constants/tooltips.js'; // Preset options for this spec. diff --git a/ui/feral_druid/tsconfig.json b/ui/feral_druid/tsconfig.json deleted file mode 100644 index a85f73bd9b..0000000000 --- a/ui/feral_druid/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../tsconfig-base", - "compilerOptions": { - "composite": true, - "outDir": "../../dist/wotlk/feral_druid", - }, - "include": [ - "**/*.ts", - ], - "references": [ - { "path": "../core" }, - ], -} diff --git a/ui/feral_tank_druid/index.ts b/ui/feral_tank_druid/index.ts index a75a15442c..065f1007a3 100644 --- a/ui/feral_tank_druid/index.ts +++ b/ui/feral_tank_druid/index.ts @@ -1,7 +1,7 @@ import { Spec } from '../core/proto/common.js'; import { Sim } from '../core/sim.js'; import { Player } from '../core/player.js'; -import { EventID, TypedEvent } from '../core/typed_event.js'; +import { TypedEvent } from '../core/typed_event.js'; import { FeralTankDruidSimUI } from './sim.js'; diff --git a/ui/feral_tank_druid/presets.ts b/ui/feral_tank_druid/presets.ts index 36ecb6384f..035823455f 100644 --- a/ui/feral_tank_druid/presets.ts +++ b/ui/feral_tank_druid/presets.ts @@ -2,28 +2,19 @@ import { Consumes } from '../core/proto/common.js'; import { BattleElixir } from '../core/proto/common.js'; import { GuardianElixir } from '../core/proto/common.js'; import { Food } from '../core/proto/common.js'; -import { Glyphs } from '../core/proto/common.js'; import { EquipmentSpec } from '../core/proto/common.js'; -import { ItemSpec } from '../core/proto/common.js'; import { Potions } from '../core/proto/common.js'; import { Conjured } from '../core/proto/common.js'; import { RaidTarget } from '../core/proto/common.js'; -import { WeaponImbue } from '../core/proto/common.js'; -import { Faction } from '../core/proto/common.js'; import { SavedTalents } from '../core/proto/ui.js'; import { NO_TARGET } from '../core/proto_utils/utils.js'; -import { Player } from '../core/player.js'; import { - DruidTalents as DruidTalents, - FeralTankDruid, FeralTankDruid_Rotation as DruidRotation, FeralTankDruid_Rotation_Swipe as Swipe, FeralTankDruid_Options as DruidOptions } from '../core/proto/druid.js'; -import * as Enchants from '../core/constants/enchants.js'; -import * as Gems from '../core/proto_utils/gems.js'; import * as Tooltips from '../core/constants/tooltips.js'; // Preset options for this spec. diff --git a/ui/feral_tank_druid/tsconfig.json b/ui/feral_tank_druid/tsconfig.json deleted file mode 100644 index 2ab9d5808e..0000000000 --- a/ui/feral_tank_druid/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../tsconfig-base", - "compilerOptions": { - "composite": true, - "outDir": "../../dist/wotlk/feral_tank_druid", - }, - "include": [ - "**/*.ts", - ], - "references": [ - { "path": "../core" }, - ], -} diff --git a/ui/hunter/index.ts b/ui/hunter/index.ts index 016b01fe0e..a06a053938 100644 --- a/ui/hunter/index.ts +++ b/ui/hunter/index.ts @@ -1,7 +1,7 @@ import { Spec } from '../core/proto/common.js'; import { Sim } from '../core/sim.js'; import { Player } from '../core/player.js'; -import { EventID, TypedEvent } from '../core/typed_event.js'; +import { TypedEvent } from '../core/typed_event.js'; import { HunterSimUI } from './sim.js'; diff --git a/ui/hunter/presets.ts b/ui/hunter/presets.ts index f610796dac..77916afaa3 100644 --- a/ui/hunter/presets.ts +++ b/ui/hunter/presets.ts @@ -4,8 +4,6 @@ import { Flask } from '../core/proto/common.js'; import { Food } from '../core/proto/common.js'; import { Glyphs } from '../core/proto/common.js'; import { Potions } from '../core/proto/common.js'; -import { WeaponImbue } from '../core/proto/common.js'; -import { Player } from '../core/player.js'; import { SavedTalents } from '../core/proto/ui.js'; import { ferocityDefault } from '../core/talents/hunter_pet.js'; diff --git a/ui/hunter/tsconfig.json b/ui/hunter/tsconfig.json deleted file mode 100644 index c56416b5c5..0000000000 --- a/ui/hunter/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../tsconfig-base", - "compilerOptions": { - "composite": true, - "outDir": "../../dist/wotlk/hunter", - }, - "include": [ - "**/*.ts", - ], - "references": [ - { "path": "../core" }, - ], -} diff --git a/ui/mage/index.ts b/ui/mage/index.ts index b240e579fa..4573f149a0 100644 --- a/ui/mage/index.ts +++ b/ui/mage/index.ts @@ -1,7 +1,7 @@ import { Spec } from '../core/proto/common.js'; import { Sim } from '../core/sim.js'; import { Player } from '../core/player.js'; -import { EventID, TypedEvent } from '../core/typed_event.js'; +import { TypedEvent } from '../core/typed_event.js'; import { MageSimUI } from './sim.js'; diff --git a/ui/mage/tsconfig.json b/ui/mage/tsconfig.json deleted file mode 100644 index 23a6901ce7..0000000000 --- a/ui/mage/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../tsconfig-base", - "compilerOptions": { - "composite": true, - "outDir": "../../dist/wotlk/mage", - }, - "include": [ - "**/*.ts", - ], - "references": [ - { "path": "../core" }, - ], -} diff --git a/ui/protection_paladin/tsconfig.json b/ui/protection_paladin/tsconfig.json deleted file mode 100644 index b0cd04f2cf..0000000000 --- a/ui/protection_paladin/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../tsconfig-base", - "compilerOptions": { - "composite": true, - "outDir": "../../dist/wotlk/protection_paladin", - }, - "include": [ - "**/*.ts", - ], - "references": [ - { "path": "../core" }, - ], -} diff --git a/ui/protection_warrior/index.ts b/ui/protection_warrior/index.ts index 84d6358bbc..b88c88ff3d 100644 --- a/ui/protection_warrior/index.ts +++ b/ui/protection_warrior/index.ts @@ -1,7 +1,7 @@ import { Spec } from '../core/proto/common.js'; import { Sim } from '../core/sim.js'; import { Player } from '../core/player.js'; -import { EventID, TypedEvent } from '../core/typed_event.js'; +import { TypedEvent } from '../core/typed_event.js'; import { ProtectionWarriorSimUI } from './sim.js'; diff --git a/ui/protection_warrior/presets.ts b/ui/protection_warrior/presets.ts index eca456f625..3400ab714d 100644 --- a/ui/protection_warrior/presets.ts +++ b/ui/protection_warrior/presets.ts @@ -2,27 +2,18 @@ import { Consumes } from '../core/proto/common.js'; import { EquipmentSpec } from '../core/proto/common.js'; import { Flask } from '../core/proto/common.js'; import { Food } from '../core/proto/common.js'; -import { Glyphs } from '../core/proto/common.js'; -import { ItemSpec } from '../core/proto/common.js'; import { Potions } from '../core/proto/common.js'; -import { Spec } from '../core/proto/common.js'; import { WeaponImbue } from '../core/proto/common.js'; -import { Faction } from '../core/proto/common.js'; import { SavedTalents } from '../core/proto/ui.js'; -import { Player } from '../core/player.js'; import { WarriorShout, - WarriorTalents as WarriorTalents, - ProtectionWarrior, ProtectionWarrior_Rotation as ProtectionWarriorRotation, ProtectionWarrior_Rotation_DemoShout as DemoShout, ProtectionWarrior_Rotation_ThunderClap as ThunderClap, ProtectionWarrior_Options as ProtectionWarriorOptions } from '../core/proto/warrior.js'; -import * as Enchants from '../core/constants/enchants.js'; -import * as Gems from '../core/proto_utils/gems.js'; import * as Tooltips from '../core/constants/tooltips.js'; // Preset options for this spec. diff --git a/ui/protection_warrior/tsconfig.json b/ui/protection_warrior/tsconfig.json deleted file mode 100644 index 4169126c18..0000000000 --- a/ui/protection_warrior/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../tsconfig-base", - "compilerOptions": { - "composite": true, - "outDir": "../../dist/wotlk/protection_warrior", - }, - "include": [ - "**/*.ts", - ], - "references": [ - { "path": "../core" }, - ], -} diff --git a/ui/raid/tsconfig.json b/ui/raid/tsconfig.json deleted file mode 100644 index ae303a1fba..0000000000 --- a/ui/raid/tsconfig.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "extends": "../tsconfig-base", - "compilerOptions": { - "declaration": false, - "outDir": "../../dist/wotlk/raid", - }, - "include": [ - "**/*.ts", - ], - "references": [ - { "path": "../core" }, - { "path": "../balance_druid" }, - { "path": "../feral_druid" }, - { "path": "../feral_tank_druid" }, - { "path": "../elemental_shaman" }, - { "path": "../enhancement_shaman" }, - { "path": "../hunter" }, - { "path": "../mage" }, - { "path": "../rogue" }, - { "path": "../retribution_paladin" }, - { "path": "../protection_paladin" }, - { "path": "../shadow_priest" }, - { "path": "../smite_priest" }, - { "path": "../warrior" }, - { "path": "../protection_warrior" }, - { "path": "../warlock" } - ], -} diff --git a/ui/retribution_paladin/tsconfig.json b/ui/retribution_paladin/tsconfig.json deleted file mode 100644 index 09ad08116d..0000000000 --- a/ui/retribution_paladin/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../tsconfig-base", - "compilerOptions": { - "composite": true, - "outDir": "../../dist/wotlk/retribution_paladin", - }, - "include": [ - "**/*.ts", - ], - "references": [ - { "path": "../core" }, - ], -} \ No newline at end of file diff --git a/ui/rogue/index.ts b/ui/rogue/index.ts index b6df36401c..8e784fad22 100644 --- a/ui/rogue/index.ts +++ b/ui/rogue/index.ts @@ -1,7 +1,7 @@ import { Spec } from '../core/proto/common.js'; import { Sim } from '../core/sim.js'; import { Player } from '../core/player.js'; -import { EventID, TypedEvent } from '../core/typed_event.js'; +import { TypedEvent } from '../core/typed_event.js'; import { RogueSimUI } from './sim.js'; diff --git a/ui/rogue/inputs.ts b/ui/rogue/inputs.ts index c3bd251778..ba3c21f61b 100644 --- a/ui/rogue/inputs.ts +++ b/ui/rogue/inputs.ts @@ -1,23 +1,9 @@ -import { BooleanPicker } from '../core/components/boolean_picker.js'; -import { EnumPicker } from '../core/components/enum_picker.js'; -import { IconEnumPicker, IconEnumPickerConfig } from '../core/components/icon_enum_picker.js'; -import { IconPickerConfig } from '../core/components/icon_picker.js'; import { Spec } from '../core/proto/common.js'; -import { WeaponImbue } from '../core/proto/common.js'; -import { ActionId } from '../core/proto_utils/action_id.js'; -import { Player } from '../core/player.js'; -import { Sim } from '../core/sim.js'; -import { IndividualSimUI } from '../core/individual_sim_ui.js'; -import { Target } from '../core/target.js'; -import { EventID, TypedEvent } from '../core/typed_event.js'; import * as InputHelpers from '../core/components/input_helpers.js'; import { - Rogue, - Rogue_Rotation as RogueRotation, Rogue_Rotation_Builder as Builder, - Rogue_Options as RogueOptions, } from '../core/proto/rogue.js'; // Configuration for spec-specific UI elements on the settings tab. diff --git a/ui/rogue/presets.ts b/ui/rogue/presets.ts index e00ad93030..1513b3d4ee 100644 --- a/ui/rogue/presets.ts +++ b/ui/rogue/presets.ts @@ -3,25 +3,17 @@ import { Conjured } from '../core/proto/common.js'; import { Consumes } from '../core/proto/common.js'; import { EquipmentSpec } from '../core/proto/common.js'; -import { Flask } from '../core/proto/common.js'; import { Food } from '../core/proto/common.js'; -import { Glyphs } from '../core/proto/common.js'; -import { ItemSpec } from '../core/proto/common.js'; import { Potions } from '../core/proto/common.js'; import { WeaponImbue } from '../core/proto/common.js'; -import { Faction } from '../core/proto/common.js'; import { SavedTalents } from '../core/proto/ui.js'; -import { Player } from '../core/player.js'; import { - Rogue, Rogue_Rotation as RogueRotation, Rogue_Rotation_Builder as Builder, Rogue_Options as RogueOptions, } from '../core/proto/rogue.js'; -import * as Enchants from '../core/constants/enchants.js'; -import * as Gems from '../core/proto_utils/gems.js'; import * as Tooltips from '../core/constants/tooltips.js'; // Preset options for this spec. diff --git a/ui/rogue/tsconfig.json b/ui/rogue/tsconfig.json deleted file mode 100644 index 925f696e22..0000000000 --- a/ui/rogue/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../tsconfig-base", - "compilerOptions": { - "composite": true, - "outDir": "../../dist/wotlk/rogue", - }, - "include": [ - "**/*.ts", - ], - "references": [ - { "path": "../core" }, - ], -} diff --git a/ui/shadow_priest/index.ts b/ui/shadow_priest/index.ts index 1ad8996883..70ae4b8d9a 100644 --- a/ui/shadow_priest/index.ts +++ b/ui/shadow_priest/index.ts @@ -1,7 +1,7 @@ import { Spec } from '../core/proto/common.js'; import { Sim } from '../core/sim.js'; import { Player } from '../core/player.js'; -import { EventID, TypedEvent } from '../core/typed_event.js'; +import { TypedEvent } from '../core/typed_event.js'; import { ShadowPriestSimUI } from './sim.js'; diff --git a/ui/shadow_priest/inputs.ts b/ui/shadow_priest/inputs.ts index 1e4d5d9223..49fdcc5a0b 100644 --- a/ui/shadow_priest/inputs.ts +++ b/ui/shadow_priest/inputs.ts @@ -1,12 +1,12 @@ -import { IndividualSimUI } from '/wotlk/core/individual_sim_ui.js'; -import { Player } from '/wotlk/core/player.js'; -import { Spec } from '/wotlk/core/proto/common.js'; +import { IndividualSimUI } from '../core/individual_sim_ui.js'; +import { Player } from '../core/player.js'; +import { Spec } from '../core/proto/common.js'; import { ShadowPriest_Options_Armor as Armor, ShadowPriest_Rotation_RotationType as RotationType -} from '/wotlk/core/proto/priest.js'; -import { EventID } from '/wotlk/core/typed_event.js'; -import { ActionId } from '/wotlk/core/proto_utils/action_id.js'; +} from '../core/proto/priest.js'; +import { EventID } from '../core/typed_event.js'; +import { ActionId } from '../core/proto_utils/action_id.js'; import * as InputHelpers from '../core/components/input_helpers.js'; diff --git a/ui/shadow_priest/presets.ts b/ui/shadow_priest/presets.ts index e5507df224..a763dea2f3 100644 --- a/ui/shadow_priest/presets.ts +++ b/ui/shadow_priest/presets.ts @@ -3,15 +3,10 @@ import { EquipmentSpec } from '../core/proto/common.js'; import { Flask } from '../core/proto/common.js'; import { Food } from '../core/proto/common.js'; import { Glyphs } from '../core/proto/common.js'; -import { ItemSpec } from '../core/proto/common.js'; import { Potions } from '../core/proto/common.js'; -import { WeaponImbue } from '../core/proto/common.js'; -import { Faction } from '../core/proto/common.js'; import { SavedTalents } from '../core/proto/ui.js'; -import { Player } from '../core/player.js'; import { - ShadowPriest, ShadowPriest_Rotation as Rotation, ShadowPriest_Options as Options, ShadowPriest_Rotation_RotationType, @@ -20,8 +15,6 @@ import { } from '../core/proto/priest.js'; -import * as Enchants from '../core/constants/enchants.js'; -import * as Gems from '../core/proto_utils/gems.js'; import * as Tooltips from '../core/constants/tooltips.js'; // Preset options for this spec. diff --git a/ui/shadow_priest/tsconfig.json b/ui/shadow_priest/tsconfig.json deleted file mode 100644 index d837fb7dea..0000000000 --- a/ui/shadow_priest/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../tsconfig-base", - "compilerOptions": { - "composite": true, - "outDir": "../../dist/wotlk/shadow_priest", - }, - "include": [ - "**/*.ts", - ], - "references": [ - { "path": "../core" }, - ], -} diff --git a/ui/smite_priest/index.ts b/ui/smite_priest/index.ts index f678710d27..c48850aa23 100644 --- a/ui/smite_priest/index.ts +++ b/ui/smite_priest/index.ts @@ -1,7 +1,7 @@ import { Spec } from '../core/proto/common.js'; import { Sim } from '../core/sim.js'; import { Player } from '../core/player.js'; -import { EventID, TypedEvent } from '../core/typed_event.js'; +import { TypedEvent } from '../core/typed_event.js'; import { SmitePriestSimUI } from './sim.js'; diff --git a/ui/smite_priest/presets.ts b/ui/smite_priest/presets.ts index d13bc92ab4..2bc57cb8d2 100644 --- a/ui/smite_priest/presets.ts +++ b/ui/smite_priest/presets.ts @@ -2,18 +2,12 @@ import { Consumes } from '../core/proto/common.js'; import { EquipmentSpec } from '../core/proto/common.js'; import { Flask } from '../core/proto/common.js'; import { Food } from '../core/proto/common.js'; -import { Glyphs } from '../core/proto/common.js'; -import { ItemSpec } from '../core/proto/common.js'; import { Potions } from '../core/proto/common.js'; import { WeaponImbue } from '../core/proto/common.js'; -import { Faction } from '../core/proto/common.js'; import { SavedTalents } from '../core/proto/ui.js'; -import { Player } from '../core/player.js'; -import { SmitePriest, SmitePriest_Rotation as Rotation, SmitePriest_Options as Options, SmitePriest_Rotation_RotationType } from '../core/proto/priest.js'; +import { SmitePriest_Rotation as Rotation, SmitePriest_Options as Options, SmitePriest_Rotation_RotationType } from '../core/proto/priest.js'; -import * as Enchants from '../core/constants/enchants.js'; -import * as Gems from '../core/proto_utils/gems.js'; import * as Tooltips from '../core/constants/tooltips.js'; // Preset options for this spec. diff --git a/ui/smite_priest/tsconfig.json b/ui/smite_priest/tsconfig.json deleted file mode 100644 index 08cd58da1f..0000000000 --- a/ui/smite_priest/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../tsconfig-base", - "compilerOptions": { - "composite": true, - "outDir": "../../dist/wotlk/smite_priest", - }, - "include": [ - "**/*.ts", - ], - "references": [ - { "path": "../core" }, - ], -} diff --git a/ui/tank_deathknight/index.ts b/ui/tank_deathknight/index.ts index e9ca667b41..ca8f630d7b 100644 --- a/ui/tank_deathknight/index.ts +++ b/ui/tank_deathknight/index.ts @@ -1,7 +1,7 @@ import { Spec } from '../core/proto/common.js'; import { Sim } from '../core/sim.js'; import { Player } from '../core/player.js'; -import { EventID, TypedEvent } from '../core/typed_event.js'; +import { TypedEvent } from '../core/typed_event.js'; import { TankDeathknightSimUI } from './sim.js'; diff --git a/ui/tank_deathknight/inputs.ts b/ui/tank_deathknight/inputs.ts index 0d5de838bd..3da224aeae 100644 --- a/ui/tank_deathknight/inputs.ts +++ b/ui/tank_deathknight/inputs.ts @@ -1,24 +1,9 @@ -import { IconPickerConfig } from '../core/components/icon_picker.js'; -import { RaidTarget } from '../core/proto/common.js'; import { Spec } from '../core/proto/common.js'; -import { NO_TARGET } from '../core/proto_utils/utils.js'; -import { ActionId } from '../core/proto_utils/action_id.js'; -import { Player } from '../core/player.js'; -import { Sim } from '../core/sim.js'; -import { EventID, TypedEvent } from '../core/typed_event.js'; -import { IndividualSimUI } from '../core/individual_sim_ui.js'; -import { Target } from '../core/target.js'; -import { - DeathknightTalents as DeathKnightTalents, - TankDeathknight, - TankDeathknight_Rotation as DeathKnightRotation, - TankDeathknight_Options as DeathKnightOptions, -} from '../core/proto/deathknight.js'; + + import * as InputHelpers from '../core/components/input_helpers.js'; -import * as Presets from './presets.js'; -import { SimUI } from '../core/sim_ui.js'; // Configuration for spec-specific UI elements on the settings tab. // These don't need to be in a separate file but it keeps things cleaner. diff --git a/ui/tank_deathknight/presets.ts b/ui/tank_deathknight/presets.ts index 4fe984d56b..8e275ccb0c 100644 --- a/ui/tank_deathknight/presets.ts +++ b/ui/tank_deathknight/presets.ts @@ -1,27 +1,18 @@ -import { Consumes, PetFood } from '../core/proto/common.js'; +import { Consumes } from '../core/proto/common.js'; import { EquipmentSpec } from '../core/proto/common.js'; import { Flask } from '../core/proto/common.js'; import { Food } from '../core/proto/common.js'; import { Glyphs } from '../core/proto/common.js'; -import { ItemSpec } from '../core/proto/common.js'; import { Potions } from '../core/proto/common.js'; -import { Spec } from '../core/proto/common.js'; -import { WeaponImbue } from '../core/proto/common.js'; -import { Faction } from '../core/proto/common.js'; import { SavedTalents } from '../core/proto/ui.js'; -import { Player } from '../core/player.js'; import { - DeathknightTalents as DeathKnightTalents, - TankDeathknight, TankDeathknight_Rotation as TankDeathKnightRotation, TankDeathknight_Options as TankDeathKnightOptions, DeathknightMajorGlyph, DeathknightMinorGlyph, } from '../core/proto/deathknight.js'; -import * as Enchants from '../core/constants/enchants.js'; -import * as Gems from '../core/proto_utils/gems.js'; import * as Tooltips from '../core/constants/tooltips.js'; // Preset options for this spec. diff --git a/ui/tank_deathknight/tsconfig.json b/ui/tank_deathknight/tsconfig.json deleted file mode 100644 index 40515ead24..0000000000 --- a/ui/tank_deathknight/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../tsconfig-base", - "compilerOptions": { - "composite": true, - "outDir": "../../dist/wotlk/tank_deathknight", - }, - "include": [ - "**/*.ts", - ], - "references": [ - { "path": "../core" }, - ], -} diff --git a/ui/warlock/index.ts b/ui/warlock/index.ts index 398032fe76..24ad956938 100644 --- a/ui/warlock/index.ts +++ b/ui/warlock/index.ts @@ -1,7 +1,7 @@ import { Spec } from '../core/proto/common.js'; import { Sim } from '../core/sim.js'; import { Player } from '../core/player.js'; -import { EventID, TypedEvent } from '../core/typed_event.js'; +import { TypedEvent } from '../core/typed_event.js'; import { WarlockSimUI } from './sim.js'; diff --git a/ui/warlock/presets.ts b/ui/warlock/presets.ts index 0dac6f7a30..917012de49 100644 --- a/ui/warlock/presets.ts +++ b/ui/warlock/presets.ts @@ -3,25 +3,16 @@ import { Consumes, Food, Glyphs, EquipmentSpec, - ItemSpec, Potions, - Faction, RaidBuffs, - PartyBuffs, IndividualBuffs, Debuffs, - Spec, - Stat, TristateEffect, - Race, } from '../core/proto/common.js'; import { SavedTalents } from '../core/proto/ui.js'; -import { Player } from '../core/player.js'; import { - Warlock, Warlock_Rotation as WarlockRotation, - WarlockTalents as WarlockTalents, Warlock_Options as WarlockOptions, Warlock_Rotation_PrimarySpell as PrimarySpell, Warlock_Rotation_SecondaryDot as SecondaryDot, @@ -34,9 +25,6 @@ import { WarlockMinorGlyph as MinorGlyph, } from '../core/proto/warlock.js'; -import * as Enchants from '/wotlk/core/constants/enchants.js'; -import * as Gems from '/wotlk/core/proto_utils/gems.js'; -import * as Tooltips from '/wotlk/core/constants/tooltips.js'; import * as WarlockTooltips from './tooltips.js'; // Default talents. Uses the wowhead calculator format, make the talents on diff --git a/ui/warlock/tsconfig.json b/ui/warlock/tsconfig.json deleted file mode 100644 index 0ede6c3ceb..0000000000 --- a/ui/warlock/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../tsconfig-base", - "compilerOptions": { - "composite": true, - "outDir": "../../dist/wotlk/warlock", - }, - "include": [ - "**/*.ts", - ], - "references": [ - { "path": "../core" }, - ], -} diff --git a/ui/warrior/index.ts b/ui/warrior/index.ts index d9d4f77c2d..3a4665064d 100644 --- a/ui/warrior/index.ts +++ b/ui/warrior/index.ts @@ -1,7 +1,7 @@ import { Spec } from '../core/proto/common.js'; import { Sim } from '../core/sim.js'; import { Player } from '../core/player.js'; -import { EventID, TypedEvent } from '../core/typed_event.js'; +import { TypedEvent } from '../core/typed_event.js'; import { WarriorSimUI } from './sim.js'; diff --git a/ui/warrior/tsconfig.json b/ui/warrior/tsconfig.json deleted file mode 100644 index 8c14a86ace..0000000000 --- a/ui/warrior/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../tsconfig-base", - "compilerOptions": { - "composite": true, - "outDir": "../../dist/wotlk/warrior", - }, - "include": [ - "**/*.ts", - ], - "references": [ - { "path": "../core" }, - ], -}