From 0afcd1cd3d68de87ff33581e999b374e6d732bce Mon Sep 17 00:00:00 2001 From: thepaperpilot Date: Mon, 16 Aug 2021 23:30:54 -0500 Subject: [PATCH] First pass at typescript support Oh man did this end up requiring a *ton* of other work as well. There's still a few typing issues I still can't quite work out, and others I'd like to improve when I have time. In fact, this version doesn't even really work, it has a stack overflow error caused by a tooltip for some reason have a tree inside it, which in turn has another tooltip, etc. There's also 17 errors that I *really* feel like shouldn't be there, but they are, and 113 warnings - mostly using ! to assert that things are non-null. Lots of work left to do, to sum up. The reason I'm committing this now is because I really need to get to work on my game jam, and since it won't use a tree or really many of TMT-X's features, I can get away with using a broken engine :) --- .eslintrc.js | 20 + .prettierrc.json | 4 + babel.config.js | 6 +- jsconfig.json | 5 - package-lock.json | 2726 ++++++++++++++++- package.json | 45 +- src/App.vue | 79 +- src/components/features/Achievement.vue | 104 +- src/components/features/Achievements.vue | 72 +- src/components/features/Bar.vue | 190 +- src/components/features/Buyable.vue | 216 +- src/components/features/Buyables.vue | 138 +- src/components/features/Challenge.vue | 151 +- src/components/features/Challenges.vue | 65 +- src/components/features/Clickable.vue | 154 +- src/components/features/Clickables.vue | 124 +- .../features/DefaultChallengeDisplay.vue | 86 +- .../features/DefaultPrestigeButtonDisplay.vue | 140 +- .../features/DefaultUpgradeDisplay.vue | 97 +- src/components/features/Grid.vue | 52 +- src/components/features/GridCell.vue | 97 + src/components/features/Gridable.vue | 77 - src/components/features/Infobox.vue | 223 +- src/components/features/MainDisplay.vue | 91 +- src/components/features/MarkNode.vue | 82 +- src/components/features/MasterButton.vue | 86 +- src/components/features/Milestone.vue | 97 +- src/components/features/Milestones.vue | 47 +- src/components/features/PrestigeButton.vue | 83 +- src/components/features/ResourceDisplay.vue | 113 +- src/components/features/RespecButton.vue | 184 +- src/components/features/Subtab.vue | 32 + src/components/features/Upgrade.vue | 105 +- src/components/features/Upgrades.vue | 69 +- src/components/fields/DangerButton.vue | 98 +- src/components/fields/FeedbackButton.vue | 113 +- src/components/fields/Select.vue | 74 +- src/components/fields/Slider.vue | 44 +- src/components/fields/Text.vue | 73 +- src/components/fields/Toggle.vue | 105 +- src/components/index.js | 28 - src/components/index.ts | 26 + src/components/system/Column.vue | 20 +- src/components/system/DefaultLayerTab.vue | 73 +- src/components/system/GameOverScreen.vue | 149 +- src/components/system/Info.vue | 211 +- src/components/system/LayerProvider.vue | 39 +- src/components/system/LayerTab.vue | 387 +-- src/components/system/Microtab.vue | 151 +- src/components/system/Modal.vue | 178 +- src/components/system/NaNScreen.vue | 204 +- src/components/system/Nav.vue | 322 +- src/components/system/Options.vue | 139 +- src/components/system/Resource.vue | 27 +- src/components/system/Row.vue | 20 +- src/components/system/Save.vue | 247 +- src/components/system/SavesManager.vue | 462 +-- src/components/system/Spacer.vue | 36 +- src/components/system/Sticky.vue | 113 +- src/components/system/Subtab.vue | 27 - src/components/system/TPS.vue | 40 +- src/components/system/TabButton.vue | 124 +- src/components/system/Tabs.vue | 97 +- src/components/system/Tooltip.vue | 209 +- src/components/system/VerticalRule.vue | 26 +- src/components/tree/BranchLine.vue | 104 +- src/components/tree/BranchNode.vue | 176 +- src/components/tree/Branches.vue | 187 +- src/components/tree/Tree.vue | 155 +- src/components/tree/TreeNode.vue | 236 +- src/data/layers/aca/a.js | 82 - src/data/layers/aca/a.ts | 103 + src/data/layers/aca/c.js | 399 --- src/data/layers/aca/c.ts | 573 ++++ src/data/layers/aca/f.js | 107 - src/data/layers/aca/f.ts | 151 + src/data/layers/demo-infinity.js | 153 - src/data/layers/demo-infinity.ts | 354 +++ src/data/layers/demo.js | 940 ------ src/data/layers/demo.ts | 2301 ++++++++++++++ src/data/mod.js | 120 - src/data/mod.ts | 187 ++ src/data/themes.js | 52 - src/data/themes.ts | 60 + src/game/enums.ts | 30 + src/game/gameLoop.js | 156 - src/game/gameLoop.ts | 171 ++ src/game/layers.js | 452 --- src/game/layers.ts | 604 ++++ src/game/player.js | 52 - src/game/player.ts | 112 + src/lib/break_eternity.js | 2 - src/lib/break_eternity.ts | 2717 ++++++++++++++++ src/main.js | 22 - src/main.ts | 22 + src/shims-vue.d.ts | 6 + src/typings/branches.d.ts | 28 + src/typings/cacheableFunction.d.ts | 3 + src/typings/component.d.ts | 3 + src/typings/computable.d.ts | 5 + src/typings/features/achievement.d.ts | 16 + src/typings/features/bar.d.ts | 15 + src/typings/features/buyable.d.ts | 20 + src/typings/features/challenge.d.ts | 34 + src/typings/features/clickable.d.ts | 15 + src/typings/features/feature.d.ts | 34 + src/typings/features/grid.d.ts | 33 + src/typings/features/hotkey.d.ts | 8 + src/typings/features/infobox.d.ts | 11 + src/typings/features/milestone.d.ts | 12 + src/typings/features/subtab.d.ts | 35 + src/typings/features/upgrade.d.ts | 23 + src/typings/global.d.ts | 27 + src/typings/layer.d.ts | 146 + src/typings/player.d.ts | 66 + src/typings/state.d.ts | 2 + src/typings/theme.d.ts | 7 + src/util/{bignum.js => bignum.ts} | 23 +- src/util/break_eternity.js | 143 - src/util/break_eternity.ts | 186 ++ src/util/common.js | 24 - src/util/common.ts | 30 + src/util/features.js | 77 - src/util/features.ts | 89 + src/util/layers.js | 313 -- src/util/layers.ts | 390 +++ src/util/proxies.js | 149 - src/util/proxies.ts | 187 ++ src/util/save.js | 160 - src/util/save.ts | 191 ++ src/util/vue.js | 57 - src/util/vue.ts | 114 + tsconfig.json | 43 + vue.config.js | 11 +- 134 files changed, 16132 insertions(+), 7106 deletions(-) create mode 100644 .eslintrc.js create mode 100644 .prettierrc.json delete mode 100644 jsconfig.json create mode 100644 src/components/features/GridCell.vue delete mode 100644 src/components/features/Gridable.vue create mode 100644 src/components/features/Subtab.vue delete mode 100644 src/components/index.js create mode 100644 src/components/index.ts delete mode 100644 src/components/system/Subtab.vue delete mode 100644 src/data/layers/aca/a.js create mode 100644 src/data/layers/aca/a.ts delete mode 100644 src/data/layers/aca/c.js create mode 100644 src/data/layers/aca/c.ts delete mode 100644 src/data/layers/aca/f.js create mode 100644 src/data/layers/aca/f.ts delete mode 100644 src/data/layers/demo-infinity.js create mode 100644 src/data/layers/demo-infinity.ts delete mode 100644 src/data/layers/demo.js create mode 100644 src/data/layers/demo.ts delete mode 100644 src/data/mod.js create mode 100644 src/data/mod.ts delete mode 100644 src/data/themes.js create mode 100644 src/data/themes.ts create mode 100644 src/game/enums.ts delete mode 100644 src/game/gameLoop.js create mode 100644 src/game/gameLoop.ts delete mode 100644 src/game/layers.js create mode 100644 src/game/layers.ts delete mode 100644 src/game/player.js create mode 100644 src/game/player.ts delete mode 100644 src/lib/break_eternity.js create mode 100644 src/lib/break_eternity.ts delete mode 100644 src/main.js create mode 100644 src/main.ts create mode 100644 src/shims-vue.d.ts create mode 100644 src/typings/branches.d.ts create mode 100644 src/typings/cacheableFunction.d.ts create mode 100644 src/typings/component.d.ts create mode 100644 src/typings/computable.d.ts create mode 100644 src/typings/features/achievement.d.ts create mode 100644 src/typings/features/bar.d.ts create mode 100644 src/typings/features/buyable.d.ts create mode 100644 src/typings/features/challenge.d.ts create mode 100644 src/typings/features/clickable.d.ts create mode 100644 src/typings/features/feature.d.ts create mode 100644 src/typings/features/grid.d.ts create mode 100644 src/typings/features/hotkey.d.ts create mode 100644 src/typings/features/infobox.d.ts create mode 100644 src/typings/features/milestone.d.ts create mode 100644 src/typings/features/subtab.d.ts create mode 100644 src/typings/features/upgrade.d.ts create mode 100644 src/typings/global.d.ts create mode 100644 src/typings/layer.d.ts create mode 100644 src/typings/player.d.ts create mode 100644 src/typings/state.d.ts create mode 100644 src/typings/theme.d.ts rename src/util/{bignum.js => bignum.ts} (64%) delete mode 100644 src/util/break_eternity.js create mode 100644 src/util/break_eternity.ts delete mode 100644 src/util/common.js create mode 100644 src/util/common.ts delete mode 100644 src/util/features.js create mode 100644 src/util/features.ts delete mode 100644 src/util/layers.js create mode 100644 src/util/layers.ts delete mode 100644 src/util/proxies.js create mode 100644 src/util/proxies.ts delete mode 100644 src/util/save.js create mode 100644 src/util/save.ts delete mode 100644 src/util/vue.js create mode 100644 src/util/vue.ts create mode 100644 tsconfig.json diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..a343a1e --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,20 @@ +module.exports = { + root: true, + env: { + node: true + }, + extends: [ + "plugin:vue/vue3-essential", + "eslint:recommended", + "@vue/typescript/recommended", + "@vue/prettier", + "@vue/prettier/@typescript-eslint" + ], + parserOptions: { + ecmaVersion: 2020 + }, + rules: { + "no-console": process.env.NODE_ENV === "production" ? "warn" : "off", + "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off" + } +}; diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..ec1a921 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,4 @@ +{ + "printWidth": 100, + "tabWidth": 4 +} diff --git a/babel.config.js b/babel.config.js index 414e4ac..4ab6557 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,5 +1,3 @@ module.exports = { - presets: [ - '@vue/cli-plugin-babel/preset' - ] -} + presets: ["@vue/cli-plugin-babel/preset"] +}; diff --git a/jsconfig.json b/jsconfig.json deleted file mode 100644 index adc4c61..0000000 --- a/jsconfig.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "include": [ - "./src/components/**/*" - ] -} diff --git a/package-lock.json b/package-lock.json index a532def..82536ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,26 +8,36 @@ "name": "the-modding-tree-x", "version": "0.1.0", "dependencies": { - "@ivanv/vue-collapse-transition": "^1.0.2", "core-js": "^3.6.5", "lodash.clonedeep": "^4.5.0", - "vue": "^3.1.4", - "vue-next-select": "^2.7.0", + "vue": "^3.2.2", + "vue-class-component": "^8.0.0-rc.1", + "vue-next-select": "^2.9.0", "vue-sortable": "github:Netbel/vue-sortable#master-fix", "vue-textarea-autosize": "^1.1.1", "vue-transition-expand": "^0.1.0" }, "devDependencies": { + "@ivanv/vue-collapse-transition": "^1.0.2", + "@types/lodash.clonedeep": "^4.5.6", + "@typescript-eslint/eslint-plugin": "^4.18.0", + "@typescript-eslint/parser": "^4.18.0", "@vue/cli-plugin-babel": "~4.5.0", "@vue/cli-plugin-eslint": "~4.5.0", + "@vue/cli-plugin-typescript": "~4.5.0", "@vue/cli-service": "~4.5.0", - "@vue/compiler-sfc": "^3.0.0-beta.1", + "@vue/compiler-sfc": "^3.2.2", + "@vue/eslint-config-prettier": "^6.0.0", + "@vue/eslint-config-typescript": "^7.0.0", "babel-eslint": "^10.1.0", "eslint": "^6.7.2", "eslint-plugin-vue": "^7.0.0-alpha.0", + "prettier": "^1.19.1", "raw-loader": "^4.0.2", "sass": "^1.36.0", - "sass-loader": "^10.2.0" + "sass-loader": "^10.2.0", + "tsconfig-paths-webpack-plugin": "^3.5.1", + "typescript": "~4.1.5" } }, "D:/projects/The-Modding-Tree-X/node_modules/@babel/code-frame": { @@ -13057,7 +13067,8 @@ "node_modules/@ivanv/vue-collapse-transition": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@ivanv/vue-collapse-transition/-/vue-collapse-transition-1.0.2.tgz", - "integrity": "sha512-eWEameFXJM/1khcoKbITvKjYYXDP1WKQ/Xf9ItJVPoEjCiOdocR3AgDAERzDrNNg4oWK28gRGi+0ft8Te27zxw==" + "integrity": "sha512-eWEameFXJM/1khcoKbITvKjYYXDP1WKQ/Xf9ItJVPoEjCiOdocR3AgDAERzDrNNg4oWK28gRGi+0ft8Te27zxw==", + "dev": true }, "node_modules/@mrmlnc/readdir-enhanced": { "version": "2.2.1", @@ -13072,6 +13083,28 @@ "node": ">=4" } }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.scandir/node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/@nodelib/fs.stat": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", @@ -13081,6 +13114,19 @@ "node": ">= 6" } }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/@soda/friendly-errors-webpack-plugin": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.8.0.tgz", @@ -13188,6 +13234,21 @@ "integrity": "sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg==", "dev": true }, + "node_modules/@types/lodash": { + "version": "4.14.171", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.171.tgz", + "integrity": "sha512-7eQ2xYLLI/LsicL2nejW9Wyko3lcpN6O/z0ZLHrEQsg280zIdCv1t/0m6UtBjUHokCGBQ3gYTbHzDkZ1xOBwwg==", + "dev": true + }, + "node_modules/@types/lodash.clonedeep": { + "version": "4.5.6", + "resolved": "https://registry.npmjs.org/@types/lodash.clonedeep/-/lodash.clonedeep-4.5.6.tgz", + "integrity": "sha512-cE1jYr2dEg1wBImvXlNtp0xDoS79rfEdGozQVgliDZj1uERH4k+rmEMTudP9b4VQ8O6nRb5gPqft0QzEQGMQgA==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, "node_modules/@types/mime": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", @@ -13218,6 +13279,13 @@ "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", "dev": true }, + "node_modules/@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true, + "optional": true + }, "node_modules/@types/q": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", @@ -13303,6 +13371,12 @@ "http-proxy-middleware": "^1.0.0" } }, + "node_modules/@types/webpack-env": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.16.2.tgz", + "integrity": "sha512-vKx7WNQNZDyJveYcHAm9ZxhqSGLYwoyLhrHjLBOkw3a7cT76sTdjgtwyijhk1MaHyRIuSztcVwrUOO/NEu68Dw==", + "dev": true + }, "node_modules/@types/webpack-sources": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-2.1.1.tgz", @@ -13332,6 +13406,469 @@ "node": ">=0.10.0" } }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "4.28.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.5.tgz", + "integrity": "sha512-m31cPEnbuCqXtEZQJOXAHsHvtoDi9OVaeL5wZnO2KZTnkvELk+u6J6jHg+NzvWQxk+87Zjbc4lJS4NHmgImz6Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "4.28.5", + "@typescript-eslint/scope-manager": "4.28.5", + "debug": "^4.3.1", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^4.0.0", + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "4.28.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.5.tgz", + "integrity": "sha512-bGPLCOJAa+j49hsynTaAtQIWg6uZd8VLiPcyDe4QPULsvQwLHGLSGKKcBN8/lBxIX14F74UEMK2zNDI8r0okwA==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.28.5", + "@typescript-eslint/types": "4.28.5", + "@typescript-eslint/typescript-estree": "4.28.5", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "4.28.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.28.5.tgz", + "integrity": "sha512-NPCOGhTnkXGMqTznqgVbA5LqVsnw+i3+XA1UKLnAb+MG1Y1rP4ZSK9GX0kJBmAZTMIktf+dTwXToT6kFwyimbw==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "4.28.5", + "@typescript-eslint/types": "4.28.5", + "@typescript-eslint/typescript-estree": "4.28.5", + "debug": "^4.3.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "4.28.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.28.5.tgz", + "integrity": "sha512-PHLq6n9nTMrLYcVcIZ7v0VY1X7dK309NM8ya9oL/yG8syFINIMHxyr2GzGoBYUdv3NUfCOqtuqps0ZmcgnZTfQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.28.5", + "@typescript-eslint/visitor-keys": "4.28.5" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "4.28.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.28.5.tgz", + "integrity": "sha512-MruOu4ZaDOLOhw4f/6iudyks/obuvvZUAHBDSW80Trnc5+ovmViLT2ZMDXhUV66ozcl6z0LJfKs1Usldgi/WCA==", + "dev": true, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "4.28.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.5.tgz", + "integrity": "sha512-FzJUKsBX8poCCdve7iV7ShirP8V+ys2t1fvamVeD1rWpiAnIm550a+BX/fmTHrjEpQJ7ZAn+Z7ZZwJjytk9rZw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.28.5", + "@typescript-eslint/visitor-keys": "4.28.5", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/fast-glob": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "4.28.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.5.tgz", + "integrity": "sha512-dva/7Rr+EkxNWdJWau26xU/0slnFlkh88v3TsyTgRS/IIYFi5iIfpCFM4ikw0vQTFUR9FYSSyqgK4w64gsgxhg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.28.5", + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/@vue/babel-helper-vue-jsx-merge-props": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.2.1.tgz", @@ -13603,6 +14140,37 @@ "@vue/cli-service": "^3.0.0 || ^4.0.0-0" } }, + "node_modules/@vue/cli-plugin-typescript": { + "version": "4.5.13", + "resolved": "https://registry.npmjs.org/@vue/cli-plugin-typescript/-/cli-plugin-typescript-4.5.13.tgz", + "integrity": "sha512-CpLlIdFNV1gn9uC4Yh6QgWI42uk2x5Z3cb2ScxNSwWsR1vgSdr0/1DdNzoBm68aP8RUtnHHO/HZfPnvXiq42xA==", + "dev": true, + "dependencies": { + "@types/webpack-env": "^1.15.2", + "@vue/cli-shared-utils": "^4.5.13", + "cache-loader": "^4.1.0", + "fork-ts-checker-webpack-plugin": "^3.1.1", + "globby": "^9.2.0", + "thread-loader": "^2.1.3", + "ts-loader": "^6.2.2", + "tslint": "^5.20.1", + "webpack": "^4.0.0", + "yorkie": "^2.0.0" + }, + "optionalDependencies": { + "fork-ts-checker-webpack-plugin-v5": "npm:fork-ts-checker-webpack-plugin@^5.0.11" + }, + "peerDependencies": { + "@vue/cli-service": "^3.0.0 || ^4.0.0-0", + "@vue/compiler-sfc": "^3.0.0-beta.14", + "typescript": ">=2" + }, + "peerDependenciesMeta": { + "@vue/compiler-sfc": { + "optional": true + } + } + }, "node_modules/@vue/cli-plugin-vuex": { "version": "4.5.13", "resolved": "https://registry.npmjs.org/@vue/cli-plugin-vuex/-/cli-plugin-vuex-4.5.13.tgz", @@ -13753,13 +14321,13 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.1.4.tgz", - "integrity": "sha512-TnUz+1z0y74O/A4YKAbzsdUfamyHV73MihrEfvettWpm9bQKVoZd1nEmR1cGN9LsXWlwAvVQBetBlWdOjmQO5Q==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.2.tgz", + "integrity": "sha512-QhCI0ZU5nAR0LMcLgzW3v75374tIrHGp8XG5CzJS7Nsy+iuignbE4MZ2XJfh5TGIrtpuzfWA4eTIfukZf/cRdg==", "dependencies": { "@babel/parser": "^7.12.0", "@babel/types": "^7.12.0", - "@vue/shared": "3.1.4", + "@vue/shared": "3.2.2", "estree-walker": "^2.0.1", "source-map": "^0.6.1" } @@ -13773,27 +14341,27 @@ } }, "node_modules/@vue/compiler-dom": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.1.4.tgz", - "integrity": "sha512-3tG2ScHkghhUBuFwl9KgyZhrS8CPFZsO7hUDekJgIp5b1OMkROr4AvxHu6rRMl4WkyvYkvidFNBS2VfOnwa6Kw==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.2.tgz", + "integrity": "sha512-ggcc+NV/ENIE0Uc3TxVE/sKrhYVpLepMAAmEiQ047332mbKOvUkowz4TTFZ+YkgOIuBOPP0XpCxmCMg7p874mA==", "dependencies": { - "@vue/compiler-core": "3.1.4", - "@vue/shared": "3.1.4" + "@vue/compiler-core": "3.2.2", + "@vue/shared": "3.2.2" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.1.4.tgz", - "integrity": "sha512-4KDQg60Khy3SgnF+V/TB2NZqzmM4TyGRmzsxqG1SebGdMSecCweFDSlI/F1vDYk6dKiCHgmpoT9A1sLxswkJ0A==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.2.tgz", + "integrity": "sha512-hrtqpQ5L6IPn5v7yVRo7uvLcQxv0z1+KBjZBWMBOcrXz4t+PKUxU/SWd6Tl9T8FDmYlunzKUh6lcx+2CLo6f5A==", "dev": true, "dependencies": { "@babel/parser": "^7.13.9", "@babel/types": "^7.13.0", "@types/estree": "^0.0.48", - "@vue/compiler-core": "3.1.4", - "@vue/compiler-dom": "3.1.4", - "@vue/compiler-ssr": "3.1.4", - "@vue/shared": "3.1.4", + "@vue/compiler-core": "3.2.2", + "@vue/compiler-dom": "3.2.2", + "@vue/compiler-ssr": "3.2.2", + "@vue/shared": "3.2.2", "consolidate": "^0.16.0", "estree-walker": "^2.0.1", "hash-sum": "^2.0.0", @@ -13804,9 +14372,6 @@ "postcss-modules": "^4.0.0", "postcss-selector-parser": "^6.0.4", "source-map": "^0.6.1" - }, - "peerDependencies": { - "vue": "3.1.4" } }, "node_modules/@vue/compiler-sfc/node_modules/icss-utils": { @@ -13927,13 +14492,13 @@ } }, "node_modules/@vue/compiler-ssr": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.1.4.tgz", - "integrity": "sha512-Box8fCuCFPp0FuimIswjDkjwiSDCBkHvt/xVALyFkYCiIMWv2eR53fIjmlsnEHhcBuZ+VgRC+UanCTcKvSA1gA==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.2.tgz", + "integrity": "sha512-rVl1agMFhdEN3Go0bCriXo+3cysxKIuRP0yh1Wd8ysRrKfAmokyDhUA8PrGSq2Ymj/LdZTh+4OKfj3p2+C+hlA==", "dev": true, "dependencies": { - "@vue/compiler-dom": "3.1.4", - "@vue/shared": "3.1.4" + "@vue/compiler-dom": "3.2.2", + "@vue/shared": "3.2.2" } }, "node_modules/@vue/component-compiler-utils": { @@ -13998,6 +14563,38 @@ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true }, + "node_modules/@vue/eslint-config-prettier": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@vue/eslint-config-prettier/-/eslint-config-prettier-6.0.0.tgz", + "integrity": "sha512-wFQmv45c3ige5EA+ngijq40YpVcIkAy0Lihupnsnd1Dao5CBbPyfCzqtejFLZX1EwH/kCJdpz3t6s+5wd3+KxQ==", + "dev": true, + "dependencies": { + "eslint-config-prettier": "^6.0.0" + }, + "peerDependencies": { + "eslint": ">= 5.0.0", + "eslint-plugin-prettier": "^3.1.0", + "prettier": ">= 1.13.0" + } + }, + "node_modules/@vue/eslint-config-typescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@vue/eslint-config-typescript/-/eslint-config-typescript-7.0.0.tgz", + "integrity": "sha512-UxUlvpSrFOoF8aQ+zX1leYiEBEm7CZmXYn/ZEM1zwSadUzpamx56RB4+Htdjisv1mX2tOjBegNUqH3kz2OL+Aw==", + "dev": true, + "dependencies": { + "vue-eslint-parser": "^7.0.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^4.4.0", + "@typescript-eslint/parser": "^4.4.0", + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0", + "eslint-plugin-vue": "^5.2.3 || ^6.0.0 || ^7.0.0" + } + }, "node_modules/@vue/preload-webpack-plugin": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@vue/preload-webpack-plugin/-/preload-webpack-plugin-1.1.2.tgz", @@ -14012,36 +14609,36 @@ } }, "node_modules/@vue/reactivity": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.1.4.tgz", - "integrity": "sha512-YDlgii2Cr9yAoKVZFzgY4j0mYlVT73986X3e5SPp6ifqckSEoFSUWXZK2Tb53TB/9qO29BEEbspnKD3m3wAwkA==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.2.tgz", + "integrity": "sha512-IHjhtmrhK6dzacj/EnLQDWOaA3HuzzVk6w84qgV8EpS4uWGIJXiRalMRg6XvGW2ykJvIl3pLsF0aBFlTMRiLOA==", "dependencies": { - "@vue/shared": "3.1.4" + "@vue/shared": "3.2.2" } }, "node_modules/@vue/runtime-core": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.1.4.tgz", - "integrity": "sha512-qmVJgJuFxfT7M4qHQ4M6KqhKC66fjuswK+aBivE8dWiZ2rtIGl9gtJGpwqwjQEcKEBTOfvvrtrwBncYArJUO8Q==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.2.tgz", + "integrity": "sha512-/aUk1+GO/VPX0oVxhbzSWE1zrf3/wGCsO1ALNisVokYftKqfqLDjbJHE6mrI2hx3MiuwbHrWjJClkGUVTIOPEQ==", "dependencies": { - "@vue/reactivity": "3.1.4", - "@vue/shared": "3.1.4" + "@vue/reactivity": "3.2.2", + "@vue/shared": "3.2.2" } }, "node_modules/@vue/runtime-dom": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.1.4.tgz", - "integrity": "sha512-vbmwgTxku1BU87Kw7r29adv0OIrDXCW0PslOPQT0O/9R5SqcXgS94Yj6zsztDjvghegenwIAPNLlDR1Auh5s+w==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.2.tgz", + "integrity": "sha512-1Le/NpCfawCOfePfJezvWUF+oCVLU8N+IHN4oFDOxRe6/PgHNJ+yT+YdxFifBfI+TIAoXI/9PsnqzmJZV+xsmw==", "dependencies": { - "@vue/runtime-core": "3.1.4", - "@vue/shared": "3.1.4", + "@vue/runtime-core": "3.2.2", + "@vue/shared": "3.2.2", "csstype": "^2.6.8" } }, "node_modules/@vue/shared": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.1.4.tgz", - "integrity": "sha512-6O45kZAmkLvzGLToBxEz4lR2W6kXohCtebV2UxjH9GXjd8X9AhEn68FN9eNanFtWNzvgw1hqd6HkPRVQalqf7Q==" + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.2.tgz", + "integrity": "sha512-dvYb318tk9uOzHtSaT3WII/HscQSIRzoCZ5GyxEb3JlkEXASpAUAQwKnvSe2CudnF8XHFRTB7VITWSnWNLZUtA==" }, "node_modules/@vue/web-component-wrapper": { "version": "1.3.0", @@ -14608,6 +15205,16 @@ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/atob": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", @@ -14657,6 +15264,78 @@ "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", "dev": true }, + "node_modules/babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "node_modules/babel-code-frame/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-code-frame/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-code-frame/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-code-frame/node_modules/js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "node_modules/babel-code-frame/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-code-frame/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/babel-eslint": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", @@ -15165,6 +15844,15 @@ "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", "dev": true }, + "node_modules/builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/builtin-status-codes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", @@ -17025,6 +17713,15 @@ "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", "dev": true }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/diffie-hellman": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", @@ -17496,6 +18193,21 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-config-prettier": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.15.0.tgz", + "integrity": "sha512-a1+kOYLR8wMGustcgAjdydMsQ2A/2ipRPwRKUmfYaSxc9ZPcrku080Ctl6zrZzZNs/U82MjSv+qKREkoq3bJaw==", + "dev": true, + "dependencies": { + "get-stdin": "^6.0.0" + }, + "bin": { + "eslint-config-prettier-check": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=3.14.1" + } + }, "node_modules/eslint-loader": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-2.2.1.tgz", @@ -17514,6 +18226,28 @@ "webpack": ">=2.0.0 <5.0.0" } }, + "node_modules/eslint-plugin-prettier": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz", + "integrity": "sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw==", + "dev": true, + "peer": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "peerDependencies": { + "eslint": ">=5.0.0", + "prettier": ">=1.13.0" + }, + "peerDependenciesMeta": { + "eslint-config-prettier": { + "optional": true + } + } + }, "node_modules/eslint-plugin-vue": { "version": "7.12.1", "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-7.12.1.tgz", @@ -18142,6 +18876,13 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "node_modules/fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true, + "peer": true + }, "node_modules/fast-glob": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", @@ -18171,6 +18912,15 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "node_modules/fastq": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.1.tgz", + "integrity": "sha512-HOnr8Mc60eNYl1gzwp6r5RoUyAn5/glBolUzP/Ez6IFVPMPirxn/9phgL6zhOtaTy7ISwPvQ+wT+hfcRZh/bzw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, "node_modules/faye-websocket": { "version": "0.11.4", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", @@ -18427,6 +19177,313 @@ "node": "*" } }, + "node_modules/fork-ts-checker-webpack-plugin": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-3.1.1.tgz", + "integrity": "sha512-DuVkPNrM12jR41KM2e+N+styka0EgLkTnXmNcXdgOM37vtGeY+oCBK/Jx0hzSeEU6memFCtWb4htrHPMDfwwUQ==", + "dev": true, + "dependencies": { + "babel-code-frame": "^6.22.0", + "chalk": "^2.4.1", + "chokidar": "^3.3.0", + "micromatch": "^3.1.10", + "minimatch": "^3.0.4", + "semver": "^5.6.0", + "tapable": "^1.0.0", + "worker-rpc": "^0.1.0" + }, + "engines": { + "node": ">=6.11.5", + "yarn": ">=1.0.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin-v5": { + "name": "fork-ts-checker-webpack-plugin", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-5.2.1.tgz", + "integrity": "sha512-SVi+ZAQOGbtAsUWrZvGzz38ga2YqjWvca1pXQFUArIVXqli0lLoDQ8uS0wg0kSpcwpZmaW5jVCZXQebkyUQSsw==", + "dev": true, + "optional": true, + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@types/json-schema": "^7.0.5", + "chalk": "^4.1.0", + "cosmiconfig": "^6.0.0", + "deepmerge": "^4.2.2", + "fs-extra": "^9.0.0", + "memfs": "^3.1.2", + "minimatch": "^3.0.4", + "schema-utils": "2.7.0", + "semver": "^7.3.2", + "tapable": "^1.0.0" + }, + "engines": { + "node": ">=10", + "yarn": ">=1.0.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin-v5/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "optional": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/fork-ts-checker-webpack-plugin-v5/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "optional": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/fork-ts-checker-webpack-plugin-v5/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "optional": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin-v5/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "optional": true + }, + "node_modules/fork-ts-checker-webpack-plugin-v5/node_modules/cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dev": true, + "optional": true, + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fork-ts-checker-webpack-plugin-v5/node_modules/deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin-v5/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "optional": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fork-ts-checker-webpack-plugin-v5/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/fork-ts-checker-webpack-plugin-v5/node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "optional": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fork-ts-checker-webpack-plugin-v5/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "optional": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/fork-ts-checker-webpack-plugin-v5/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fork-ts-checker-webpack-plugin-v5/node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "optional": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fork-ts-checker-webpack-plugin-v5/node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/fork-ts-checker-webpack-plugin-v5/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/fork-ts-checker-webpack-plugin-v5/node_modules/schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "dev": true, + "optional": true, + "dependencies": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/fork-ts-checker-webpack-plugin-v5/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "optional": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fork-ts-checker-webpack-plugin-v5/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "optional": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fork-ts-checker-webpack-plugin-v5/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin-v5/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "optional": true + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, "node_modules/form-data": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", @@ -18495,6 +19552,13 @@ "node": ">=6 <7 || >=8" } }, + "node_modules/fs-monkey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", + "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==", + "dev": true, + "optional": true + }, "node_modules/fs-write-stream-atomic": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", @@ -18580,6 +19644,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", @@ -18746,6 +19819,27 @@ "node": ">= 0.4.0" } }, + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-ansi/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/has-bigints": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", @@ -20571,6 +21665,19 @@ "node": ">= 0.6" } }, + "node_modules/memfs": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.2.2.tgz", + "integrity": "sha512-RE0CwmIM3CEvpcdK3rZ19BC4E6hv9kADkMN5rPduRak58cNArWLi/9jFLsa4rhsjfVxMP3v0jO7FHXq7SvFY5Q==", + "dev": true, + "optional": true, + "dependencies": { + "fs-monkey": "1.0.3" + }, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/memory-fs": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", @@ -20629,6 +21736,12 @@ "node": ">= 0.6" } }, + "node_modules/microevent.ts": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/microevent.ts/-/microevent.ts-0.1.1.tgz", + "integrity": "sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g==", + "dev": true + }, "node_modules/micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", @@ -22621,7 +23734,6 @@ "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", "dev": true, - "optional": true, "bin": { "prettier": "bin-prettier.js" }, @@ -22629,6 +23741,19 @@ "node": ">=4" } }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "peer": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/pretty-error": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz", @@ -22817,6 +23942,26 @@ "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", "dev": true }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -23288,6 +24433,16 @@ "node": ">= 4" } }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, "node_modules/rgb-regex": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", @@ -23331,6 +24486,29 @@ "node": ">=0.12.0" } }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/run-queue": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", @@ -24516,6 +25694,15 @@ "node": ">=6" } }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", @@ -25108,6 +26295,83 @@ "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==", "dev": true }, + "node_modules/ts-loader": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-6.2.2.tgz", + "integrity": "sha512-HDo5kXZCBml3EUPcc7RlZOV/JGlLHwppTLEHb3SHnr5V7NXD4klMEkrhJe5wgRbaWsSXi+Y1SIBN/K9B6zWGWQ==", + "dev": true, + "dependencies": { + "chalk": "^2.3.0", + "enhanced-resolve": "^4.0.0", + "loader-utils": "^1.0.2", + "micromatch": "^4.0.0", + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8.6" + }, + "peerDependencies": { + "typescript": "*" + } + }, + "node_modules/ts-loader/node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-loader/node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-loader/node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/ts-loader/node_modules/micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/ts-loader/node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, "node_modules/ts-pnp": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz", @@ -25122,12 +26386,177 @@ } } }, + "node_modules/tsconfig-paths": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.10.1.tgz", + "integrity": "sha512-rETidPDgCpltxF7MjBZlAFPUHv5aHH2MymyPvh+vEyWAED4Eb/WeMbsnD/JDr4OKPOA1TssDHgIcpTN5Kh0p6Q==", + "dev": true, + "dependencies": { + "json5": "^2.2.0", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths-webpack-plugin": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-3.5.1.tgz", + "integrity": "sha512-n5CMlUUj+N5pjBhBACLq4jdr9cPTitySCjIosoQm0zwK99gmrcTGAfY9CwxRFT9+9OleNWXPRUcxsKP4AYExxQ==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.7.0", + "tsconfig-paths": "^3.9.0" + } + }, + "node_modules/tsconfig-paths-webpack-plugin/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/tsconfig-paths-webpack-plugin/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/tsconfig-paths-webpack-plugin/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/tsconfig-paths-webpack-plugin/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/tsconfig-paths-webpack-plugin/node_modules/enhanced-resolve": { + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz", + "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/tsconfig-paths-webpack-plugin/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/tsconfig-paths-webpack-plugin/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tsconfig-paths-webpack-plugin/node_modules/tapable": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", + "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, + "node_modules/tslint": { + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.1.tgz", + "integrity": "sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.8.0", + "tsutils": "^2.29.0" + }, + "bin": { + "tslint": "bin/tslint" + }, + "engines": { + "node": ">=4.8.0" + }, + "peerDependencies": { + "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev" + } + }, + "node_modules/tslint/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "peerDependencies": { + "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" + } + }, "node_modules/tty-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", @@ -25195,6 +26624,19 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, + "node_modules/typescript": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.6.tgz", + "integrity": "sha512-pxnwLxeb/Z5SP80JDRzVjh58KsM6jZHRAOtTpS7sXLS4ogXNKC9ANxHHZqLLeVHZN35jCtI4JdmLLbLiC1kBow==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "node_modules/uglify-js": { "version": "3.4.10", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz", @@ -25473,9 +26915,9 @@ } }, "node_modules/url-parse": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz", - "integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.3.tgz", + "integrity": "sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==", "dev": true, "dependencies": { "querystringify": "^2.1.1", @@ -25609,13 +27051,21 @@ "dev": true }, "node_modules/vue": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.1.4.tgz", - "integrity": "sha512-p8dcdyeCgmaAiZsbLyDkmOLcFGZb/jEVdCLW65V68LRCXTNX8jKsgah2F7OZ/v/Ai2V0Fb1MNO0vz/GFqsPVMA==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.2.tgz", + "integrity": "sha512-D/LuzAV30CgNJYGyNheE/VUs5N4toL2IgmS6c9qeOxvyh0xyn4exyRqizpXIrsvfx34zG9x5gCI2tdRHCGvF9w==", "dependencies": { - "@vue/compiler-dom": "3.1.4", - "@vue/runtime-dom": "3.1.4", - "@vue/shared": "3.1.4" + "@vue/compiler-dom": "3.2.2", + "@vue/runtime-dom": "3.2.2", + "@vue/shared": "3.2.2" + } + }, + "node_modules/vue-class-component": { + "version": "8.0.0-rc.1", + "resolved": "https://registry.npmjs.org/vue-class-component/-/vue-class-component-8.0.0-rc.1.tgz", + "integrity": "sha512-w1nMzsT/UdbDAXKqhwTmSoyuJzUXKrxLE77PCFVuC6syr8acdFDAq116xgvZh9UCuV0h+rlCtxXolr3Hi3HyPQ==", + "peerDependencies": { + "vue": "^3.0.0" } }, "node_modules/vue-eslint-parser": { @@ -25784,9 +27234,9 @@ "dev": true }, "node_modules/vue-next-select": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/vue-next-select/-/vue-next-select-2.7.0.tgz", - "integrity": "sha512-GJdps622YGD/vicDFqWtCOmYuWuIrriovpjnzNV4xWGkZI/b7RpFIJvykWv0Bq7d6wYoaJ59wt3CiV900F4wRw==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/vue-next-select/-/vue-next-select-2.9.0.tgz", + "integrity": "sha512-GjX4pHqZXXitquDeSAtLaf85jXdMUOKyCNzo+EF3xRr4DebGwbST4CtmRvL0TX3EhwLHQjUlAc3JcJX+azpLHg==", "hasInstallScript": true, "engines": { "node": ">=10" @@ -26685,6 +28135,15 @@ "errno": "~0.1.7" } }, + "node_modules/worker-rpc": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/worker-rpc/-/worker-rpc-0.1.1.tgz", + "integrity": "sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg==", + "dev": true, + "dependencies": { + "microevent.ts": "~0.1.1" + } + }, "node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -26824,6 +28283,16 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", @@ -28196,7 +29665,8 @@ "@ivanv/vue-collapse-transition": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@ivanv/vue-collapse-transition/-/vue-collapse-transition-1.0.2.tgz", - "integrity": "sha512-eWEameFXJM/1khcoKbITvKjYYXDP1WKQ/Xf9ItJVPoEjCiOdocR3AgDAERzDrNNg4oWK28gRGi+0ft8Te27zxw==" + "integrity": "sha512-eWEameFXJM/1khcoKbITvKjYYXDP1WKQ/Xf9ItJVPoEjCiOdocR3AgDAERzDrNNg4oWK28gRGi+0ft8Te27zxw==", + "dev": true }, "@mrmlnc/readdir-enhanced": { "version": "2.2.1", @@ -28208,12 +29678,40 @@ "glob-to-regexp": "^0.3.0" } }, + "@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" + }, + "dependencies": { + "@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.stat": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", "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" + } + }, "@soda/friendly-errors-webpack-plugin": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.8.0.tgz", @@ -28315,6 +29813,21 @@ "integrity": "sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg==", "dev": true }, + "@types/lodash": { + "version": "4.14.171", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.171.tgz", + "integrity": "sha512-7eQ2xYLLI/LsicL2nejW9Wyko3lcpN6O/z0ZLHrEQsg280zIdCv1t/0m6UtBjUHokCGBQ3gYTbHzDkZ1xOBwwg==", + "dev": true + }, + "@types/lodash.clonedeep": { + "version": "4.5.6", + "resolved": "https://registry.npmjs.org/@types/lodash.clonedeep/-/lodash.clonedeep-4.5.6.tgz", + "integrity": "sha512-cE1jYr2dEg1wBImvXlNtp0xDoS79rfEdGozQVgliDZj1uERH4k+rmEMTudP9b4VQ8O6nRb5gPqft0QzEQGMQgA==", + "dev": true, + "requires": { + "@types/lodash": "*" + } + }, "@types/mime": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", @@ -28345,6 +29858,13 @@ "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", "dev": true }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true, + "optional": true + }, "@types/q": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", @@ -28437,6 +29957,12 @@ "http-proxy-middleware": "^1.0.0" } }, + "@types/webpack-env": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.16.2.tgz", + "integrity": "sha512-vKx7WNQNZDyJveYcHAm9ZxhqSGLYwoyLhrHjLBOkw3a7cT76sTdjgtwyijhk1MaHyRIuSztcVwrUOO/NEu68Dw==", + "dev": true + }, "@types/webpack-sources": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-2.1.1.tgz", @@ -28456,6 +29982,307 @@ } } }, + "@typescript-eslint/eslint-plugin": { + "version": "4.28.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.5.tgz", + "integrity": "sha512-m31cPEnbuCqXtEZQJOXAHsHvtoDi9OVaeL5wZnO2KZTnkvELk+u6J6jHg+NzvWQxk+87Zjbc4lJS4NHmgImz6Q==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "4.28.5", + "@typescript-eslint/scope-manager": "4.28.5", + "debug": "^4.3.1", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "dependencies": { + "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" + } + }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "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" + } + }, + "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/experimental-utils": { + "version": "4.28.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.5.tgz", + "integrity": "sha512-bGPLCOJAa+j49hsynTaAtQIWg6uZd8VLiPcyDe4QPULsvQwLHGLSGKKcBN8/lBxIX14F74UEMK2zNDI8r0okwA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.28.5", + "@typescript-eslint/types": "4.28.5", + "@typescript-eslint/typescript-estree": "4.28.5", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "dependencies": { + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + } + }, + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } + } + }, + "@typescript-eslint/parser": { + "version": "4.28.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.28.5.tgz", + "integrity": "sha512-NPCOGhTnkXGMqTznqgVbA5LqVsnw+i3+XA1UKLnAb+MG1Y1rP4ZSK9GX0kJBmAZTMIktf+dTwXToT6kFwyimbw==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "4.28.5", + "@typescript-eslint/types": "4.28.5", + "@typescript-eslint/typescript-estree": "4.28.5", + "debug": "^4.3.1" + } + }, + "@typescript-eslint/scope-manager": { + "version": "4.28.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.28.5.tgz", + "integrity": "sha512-PHLq6n9nTMrLYcVcIZ7v0VY1X7dK309NM8ya9oL/yG8syFINIMHxyr2GzGoBYUdv3NUfCOqtuqps0ZmcgnZTfQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.28.5", + "@typescript-eslint/visitor-keys": "4.28.5" + } + }, + "@typescript-eslint/types": { + "version": "4.28.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.28.5.tgz", + "integrity": "sha512-MruOu4ZaDOLOhw4f/6iudyks/obuvvZUAHBDSW80Trnc5+ovmViLT2ZMDXhUV66ozcl6z0LJfKs1Usldgi/WCA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "4.28.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.5.tgz", + "integrity": "sha512-FzJUKsBX8poCCdve7iV7ShirP8V+ys2t1fvamVeD1rWpiAnIm550a+BX/fmTHrjEpQJ7ZAn+Z7ZZwJjytk9rZw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.28.5", + "@typescript-eslint/visitor-keys": "4.28.5", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "dependencies": { + "@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 + }, + "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 + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "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" + } + }, + "fast-glob": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "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" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + } + }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "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" + } + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, + "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 + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "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" + } + }, + "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/visitor-keys": { + "version": "4.28.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.5.tgz", + "integrity": "sha512-dva/7Rr+EkxNWdJWau26xU/0slnFlkh88v3TsyTgRS/IIYFi5iIfpCFM4ikw0vQTFUR9FYSSyqgK4w64gsgxhg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.28.5", + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } + } + }, "@vue/babel-helper-vue-jsx-merge-props": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.2.1.tgz", @@ -28672,6 +30499,25 @@ "@vue/cli-shared-utils": "^4.5.13" } }, + "@vue/cli-plugin-typescript": { + "version": "4.5.13", + "resolved": "https://registry.npmjs.org/@vue/cli-plugin-typescript/-/cli-plugin-typescript-4.5.13.tgz", + "integrity": "sha512-CpLlIdFNV1gn9uC4Yh6QgWI42uk2x5Z3cb2ScxNSwWsR1vgSdr0/1DdNzoBm68aP8RUtnHHO/HZfPnvXiq42xA==", + "dev": true, + "requires": { + "@types/webpack-env": "^1.15.2", + "@vue/cli-shared-utils": "^4.5.13", + "cache-loader": "^4.1.0", + "fork-ts-checker-webpack-plugin": "^3.1.1", + "fork-ts-checker-webpack-plugin-v5": "npm:fork-ts-checker-webpack-plugin@^5.0.11", + "globby": "^9.2.0", + "thread-loader": "^2.1.3", + "ts-loader": "^6.2.2", + "tslint": "^5.20.1", + "webpack": "^4.0.0", + "yorkie": "^2.0.0" + } + }, "@vue/cli-plugin-vuex": { "version": "4.5.13", "resolved": "https://registry.npmjs.org/@vue/cli-plugin-vuex/-/cli-plugin-vuex-4.5.13.tgz", @@ -28781,13 +30627,13 @@ } }, "@vue/compiler-core": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.1.4.tgz", - "integrity": "sha512-TnUz+1z0y74O/A4YKAbzsdUfamyHV73MihrEfvettWpm9bQKVoZd1nEmR1cGN9LsXWlwAvVQBetBlWdOjmQO5Q==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.2.tgz", + "integrity": "sha512-QhCI0ZU5nAR0LMcLgzW3v75374tIrHGp8XG5CzJS7Nsy+iuignbE4MZ2XJfh5TGIrtpuzfWA4eTIfukZf/cRdg==", "requires": { "@babel/parser": "^7.12.0", "@babel/types": "^7.12.0", - "@vue/shared": "3.1.4", + "@vue/shared": "3.2.2", "estree-walker": "^2.0.1", "source-map": "^0.6.1" }, @@ -28800,27 +30646,27 @@ } }, "@vue/compiler-dom": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.1.4.tgz", - "integrity": "sha512-3tG2ScHkghhUBuFwl9KgyZhrS8CPFZsO7hUDekJgIp5b1OMkROr4AvxHu6rRMl4WkyvYkvidFNBS2VfOnwa6Kw==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.2.tgz", + "integrity": "sha512-ggcc+NV/ENIE0Uc3TxVE/sKrhYVpLepMAAmEiQ047332mbKOvUkowz4TTFZ+YkgOIuBOPP0XpCxmCMg7p874mA==", "requires": { - "@vue/compiler-core": "3.1.4", - "@vue/shared": "3.1.4" + "@vue/compiler-core": "3.2.2", + "@vue/shared": "3.2.2" } }, "@vue/compiler-sfc": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.1.4.tgz", - "integrity": "sha512-4KDQg60Khy3SgnF+V/TB2NZqzmM4TyGRmzsxqG1SebGdMSecCweFDSlI/F1vDYk6dKiCHgmpoT9A1sLxswkJ0A==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.2.tgz", + "integrity": "sha512-hrtqpQ5L6IPn5v7yVRo7uvLcQxv0z1+KBjZBWMBOcrXz4t+PKUxU/SWd6Tl9T8FDmYlunzKUh6lcx+2CLo6f5A==", "dev": true, "requires": { "@babel/parser": "^7.13.9", "@babel/types": "^7.13.0", "@types/estree": "^0.0.48", - "@vue/compiler-core": "3.1.4", - "@vue/compiler-dom": "3.1.4", - "@vue/compiler-ssr": "3.1.4", - "@vue/shared": "3.1.4", + "@vue/compiler-core": "3.2.2", + "@vue/compiler-dom": "3.2.2", + "@vue/compiler-ssr": "3.2.2", + "@vue/shared": "3.2.2", "consolidate": "^0.16.0", "estree-walker": "^2.0.1", "hash-sum": "^2.0.0", @@ -28912,13 +30758,13 @@ } }, "@vue/compiler-ssr": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.1.4.tgz", - "integrity": "sha512-Box8fCuCFPp0FuimIswjDkjwiSDCBkHvt/xVALyFkYCiIMWv2eR53fIjmlsnEHhcBuZ+VgRC+UanCTcKvSA1gA==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.2.tgz", + "integrity": "sha512-rVl1agMFhdEN3Go0bCriXo+3cysxKIuRP0yh1Wd8ysRrKfAmokyDhUA8PrGSq2Ymj/LdZTh+4OKfj3p2+C+hlA==", "dev": true, "requires": { - "@vue/compiler-dom": "3.1.4", - "@vue/shared": "3.1.4" + "@vue/compiler-dom": "3.2.2", + "@vue/shared": "3.2.2" } }, "@vue/component-compiler-utils": { @@ -28977,6 +30823,24 @@ } } }, + "@vue/eslint-config-prettier": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@vue/eslint-config-prettier/-/eslint-config-prettier-6.0.0.tgz", + "integrity": "sha512-wFQmv45c3ige5EA+ngijq40YpVcIkAy0Lihupnsnd1Dao5CBbPyfCzqtejFLZX1EwH/kCJdpz3t6s+5wd3+KxQ==", + "dev": true, + "requires": { + "eslint-config-prettier": "^6.0.0" + } + }, + "@vue/eslint-config-typescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@vue/eslint-config-typescript/-/eslint-config-typescript-7.0.0.tgz", + "integrity": "sha512-UxUlvpSrFOoF8aQ+zX1leYiEBEm7CZmXYn/ZEM1zwSadUzpamx56RB4+Htdjisv1mX2tOjBegNUqH3kz2OL+Aw==", + "dev": true, + "requires": { + "vue-eslint-parser": "^7.0.0" + } + }, "@vue/preload-webpack-plugin": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@vue/preload-webpack-plugin/-/preload-webpack-plugin-1.1.2.tgz", @@ -28985,36 +30849,36 @@ "requires": {} }, "@vue/reactivity": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.1.4.tgz", - "integrity": "sha512-YDlgii2Cr9yAoKVZFzgY4j0mYlVT73986X3e5SPp6ifqckSEoFSUWXZK2Tb53TB/9qO29BEEbspnKD3m3wAwkA==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.2.tgz", + "integrity": "sha512-IHjhtmrhK6dzacj/EnLQDWOaA3HuzzVk6w84qgV8EpS4uWGIJXiRalMRg6XvGW2ykJvIl3pLsF0aBFlTMRiLOA==", "requires": { - "@vue/shared": "3.1.4" + "@vue/shared": "3.2.2" } }, "@vue/runtime-core": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.1.4.tgz", - "integrity": "sha512-qmVJgJuFxfT7M4qHQ4M6KqhKC66fjuswK+aBivE8dWiZ2rtIGl9gtJGpwqwjQEcKEBTOfvvrtrwBncYArJUO8Q==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.2.tgz", + "integrity": "sha512-/aUk1+GO/VPX0oVxhbzSWE1zrf3/wGCsO1ALNisVokYftKqfqLDjbJHE6mrI2hx3MiuwbHrWjJClkGUVTIOPEQ==", "requires": { - "@vue/reactivity": "3.1.4", - "@vue/shared": "3.1.4" + "@vue/reactivity": "3.2.2", + "@vue/shared": "3.2.2" } }, "@vue/runtime-dom": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.1.4.tgz", - "integrity": "sha512-vbmwgTxku1BU87Kw7r29adv0OIrDXCW0PslOPQT0O/9R5SqcXgS94Yj6zsztDjvghegenwIAPNLlDR1Auh5s+w==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.2.tgz", + "integrity": "sha512-1Le/NpCfawCOfePfJezvWUF+oCVLU8N+IHN4oFDOxRe6/PgHNJ+yT+YdxFifBfI+TIAoXI/9PsnqzmJZV+xsmw==", "requires": { - "@vue/runtime-core": "3.1.4", - "@vue/shared": "3.1.4", + "@vue/runtime-core": "3.2.2", + "@vue/shared": "3.2.2", "csstype": "^2.6.8" } }, "@vue/shared": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.1.4.tgz", - "integrity": "sha512-6O45kZAmkLvzGLToBxEz4lR2W6kXohCtebV2UxjH9GXjd8X9AhEn68FN9eNanFtWNzvgw1hqd6HkPRVQalqf7Q==" + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.2.tgz", + "integrity": "sha512-dvYb318tk9uOzHtSaT3WII/HscQSIRzoCZ5GyxEb3JlkEXASpAUAQwKnvSe2CudnF8XHFRTB7VITWSnWNLZUtA==" }, "@vue/web-component-wrapper": { "version": "1.3.0", @@ -29495,6 +31359,13 @@ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "optional": true + }, "atob": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", @@ -29528,6 +31399,65 @@ "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", "dev": true }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, "babel-eslint": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", @@ -29952,6 +31882,12 @@ "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", "dev": true }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, "builtin-status-codes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", @@ -31442,6 +33378,12 @@ "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", "dev": true }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, "diffie-hellman": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", @@ -31875,6 +33817,15 @@ } } }, + "eslint-config-prettier": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.15.0.tgz", + "integrity": "sha512-a1+kOYLR8wMGustcgAjdydMsQ2A/2ipRPwRKUmfYaSxc9ZPcrku080Ctl6zrZzZNs/U82MjSv+qKREkoq3bJaw==", + "dev": true, + "requires": { + "get-stdin": "^6.0.0" + } + }, "eslint-loader": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-2.2.1.tgz", @@ -31888,6 +33839,16 @@ "rimraf": "^2.6.1" } }, + "eslint-plugin-prettier": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz", + "integrity": "sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw==", + "dev": true, + "peer": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, "eslint-plugin-vue": { "version": "7.12.1", "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-7.12.1.tgz", @@ -32341,6 +34302,13 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true, + "peer": true + }, "fast-glob": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", @@ -32367,6 +34335,15 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "fastq": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.1.tgz", + "integrity": "sha512-HOnr8Mc60eNYl1gzwp6r5RoUyAn5/glBolUzP/Ez6IFVPMPirxn/9phgL6zhOtaTy7ISwPvQ+wT+hfcRZh/bzw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, "faye-websocket": { "version": "0.11.4", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", @@ -32561,6 +34538,236 @@ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", "dev": true }, + "fork-ts-checker-webpack-plugin": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-3.1.1.tgz", + "integrity": "sha512-DuVkPNrM12jR41KM2e+N+styka0EgLkTnXmNcXdgOM37vtGeY+oCBK/Jx0hzSeEU6memFCtWb4htrHPMDfwwUQ==", + "dev": true, + "requires": { + "babel-code-frame": "^6.22.0", + "chalk": "^2.4.1", + "chokidar": "^3.3.0", + "micromatch": "^3.1.10", + "minimatch": "^3.0.4", + "semver": "^5.6.0", + "tapable": "^1.0.0", + "worker-rpc": "^0.1.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "fork-ts-checker-webpack-plugin-v5": { + "version": "npm:fork-ts-checker-webpack-plugin@5.2.1", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-5.2.1.tgz", + "integrity": "sha512-SVi+ZAQOGbtAsUWrZvGzz38ga2YqjWvca1pXQFUArIVXqli0lLoDQ8uS0wg0kSpcwpZmaW5jVCZXQebkyUQSsw==", + "dev": true, + "optional": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@types/json-schema": "^7.0.5", + "chalk": "^4.1.0", + "cosmiconfig": "^6.0.0", + "deepmerge": "^4.2.2", + "fs-extra": "^9.0.0", + "memfs": "^3.1.2", + "minimatch": "^3.0.4", + "schema-utils": "2.7.0", + "semver": "^7.3.2", + "tapable": "^1.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "optional": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "optional": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "optional": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "optional": true + }, + "cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dev": true, + "optional": true, + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + } + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true, + "optional": true + }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "optional": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "optional": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "optional": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "optional": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "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, + "optional": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "optional": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "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, + "optional": true + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "optional": true + }, + "schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "dev": true, + "optional": true, + "requires": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "optional": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "optional": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "optional": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "optional": true + } + } + }, "form-data": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", @@ -32614,6 +34821,13 @@ "universalify": "^0.1.0" } }, + "fs-monkey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", + "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==", + "dev": true, + "optional": true + }, "fs-write-stream-atomic": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", @@ -32683,6 +34897,12 @@ "has-symbols": "^1.0.1" } }, + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true + }, "get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", @@ -32817,6 +35037,23 @@ "function-bind": "^1.1.1" } }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + } + } + }, "has-bigints": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", @@ -34224,6 +36461,16 @@ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", "dev": true }, + "memfs": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.2.2.tgz", + "integrity": "sha512-RE0CwmIM3CEvpcdK3rZ19BC4E6hv9kADkMN5rPduRak58cNArWLi/9jFLsa4rhsjfVxMP3v0jO7FHXq7SvFY5Q==", + "dev": true, + "optional": true, + "requires": { + "fs-monkey": "1.0.3" + } + }, "memory-fs": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", @@ -34275,6 +36522,12 @@ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", "dev": true }, + "microevent.ts": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/microevent.ts/-/microevent.ts-0.1.1.tgz", + "integrity": "sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g==", + "dev": true + }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", @@ -35926,8 +38179,17 @@ "version": "1.19.1", "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", "dev": true, - "optional": true + "peer": true, + "requires": { + "fast-diff": "^1.1.2" + } }, "pretty-error": { "version": "2.1.2", @@ -36092,6 +38354,12 @@ "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", "dev": true }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -36465,6 +38733,12 @@ "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", "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 + }, "rgb-regex": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", @@ -36502,6 +38776,15 @@ "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", "dev": true }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, "run-queue": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", @@ -37496,6 +39779,12 @@ "ansi-regex": "^4.1.0" } }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", @@ -37973,18 +40262,203 @@ "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==", "dev": true }, + "ts-loader": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-6.2.2.tgz", + "integrity": "sha512-HDo5kXZCBml3EUPcc7RlZOV/JGlLHwppTLEHb3SHnr5V7NXD4klMEkrhJe5wgRbaWsSXi+Y1SIBN/K9B6zWGWQ==", + "dev": true, + "requires": { + "chalk": "^2.3.0", + "enhanced-resolve": "^4.0.0", + "loader-utils": "^1.0.2", + "micromatch": "^4.0.0", + "semver": "^6.0.0" + }, + "dependencies": { + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, "ts-pnp": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz", "integrity": "sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==", "dev": true }, + "tsconfig-paths": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.10.1.tgz", + "integrity": "sha512-rETidPDgCpltxF7MjBZlAFPUHv5aHH2MymyPvh+vEyWAED4Eb/WeMbsnD/JDr4OKPOA1TssDHgIcpTN5Kh0p6Q==", + "dev": true, + "requires": { + "json5": "^2.2.0", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + } + }, + "tsconfig-paths-webpack-plugin": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-3.5.1.tgz", + "integrity": "sha512-n5CMlUUj+N5pjBhBACLq4jdr9cPTitySCjIosoQm0zwK99gmrcTGAfY9CwxRFT9+9OleNWXPRUcxsKP4AYExxQ==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.7.0", + "tsconfig-paths": "^3.9.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "enhanced-resolve": { + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz", + "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "tapable": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", + "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", + "dev": true + } + } + }, "tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, + "tslint": { + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.1.tgz", + "integrity": "sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.8.0", + "tsutils": "^2.29.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, "tty-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", @@ -38037,6 +40511,12 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, + "typescript": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.6.tgz", + "integrity": "sha512-pxnwLxeb/Z5SP80JDRzVjh58KsM6jZHRAOtTpS7sXLS4ogXNKC9ANxHHZqLLeVHZN35jCtI4JdmLLbLiC1kBow==", + "dev": true + }, "uglify-js": { "version": "3.4.10", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz", @@ -38266,9 +40746,9 @@ } }, "url-parse": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz", - "integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.3.tgz", + "integrity": "sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==", "dev": true, "requires": { "querystringify": "^2.1.1", @@ -38378,15 +40858,21 @@ "dev": true }, "vue": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.1.4.tgz", - "integrity": "sha512-p8dcdyeCgmaAiZsbLyDkmOLcFGZb/jEVdCLW65V68LRCXTNX8jKsgah2F7OZ/v/Ai2V0Fb1MNO0vz/GFqsPVMA==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.2.tgz", + "integrity": "sha512-D/LuzAV30CgNJYGyNheE/VUs5N4toL2IgmS6c9qeOxvyh0xyn4exyRqizpXIrsvfx34zG9x5gCI2tdRHCGvF9w==", "requires": { - "@vue/compiler-dom": "3.1.4", - "@vue/runtime-dom": "3.1.4", - "@vue/shared": "3.1.4" + "@vue/compiler-dom": "3.2.2", + "@vue/runtime-dom": "3.2.2", + "@vue/shared": "3.2.2" } }, + "vue-class-component": { + "version": "8.0.0-rc.1", + "resolved": "https://registry.npmjs.org/vue-class-component/-/vue-class-component-8.0.0-rc.1.tgz", + "integrity": "sha512-w1nMzsT/UdbDAXKqhwTmSoyuJzUXKrxLE77PCFVuC6syr8acdFDAq116xgvZh9UCuV0h+rlCtxXolr3Hi3HyPQ==", + "requires": {} + }, "vue-eslint-parser": { "version": "7.7.2", "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.7.2.tgz", @@ -38511,9 +40997,9 @@ } }, "vue-next-select": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/vue-next-select/-/vue-next-select-2.7.0.tgz", - "integrity": "sha512-GJdps622YGD/vicDFqWtCOmYuWuIrriovpjnzNV4xWGkZI/b7RpFIJvykWv0Bq7d6wYoaJ59wt3CiV900F4wRw==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/vue-next-select/-/vue-next-select-2.9.0.tgz", + "integrity": "sha512-GjX4pHqZXXitquDeSAtLaf85jXdMUOKyCNzo+EF3xRr4DebGwbST4CtmRvL0TX3EhwLHQjUlAc3JcJX+azpLHg==", "requires": {} }, "vue-sortable": { @@ -39244,6 +41730,15 @@ "errno": "~0.1.7" } }, + "worker-rpc": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/worker-rpc/-/worker-rpc-0.1.1.tgz", + "integrity": "sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg==", + "dev": true, + "requires": { + "microevent.ts": "~0.1.1" + } + }, "wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -39355,6 +41850,13 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "optional": true + }, "yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", diff --git a/package.json b/package.json index b2db6c3..e65641f 100644 --- a/package.json +++ b/package.json @@ -8,44 +8,49 @@ "lint": "vue-cli-service lint" }, "dependencies": { - "@ivanv/vue-collapse-transition": "^1.0.2", "core-js": "^3.6.5", "lodash.clonedeep": "^4.5.0", - "vue": "^3.1.4", - "vue-next-select": "^2.7.0", + "vue": "^3.2.2", + "vue-class-component": "^8.0.0-rc.1", + "vue-next-select": "^2.9.0", "vue-sortable": "github:Netbel/vue-sortable#master-fix", "vue-textarea-autosize": "^1.1.1", "vue-transition-expand": "^0.1.0" }, "devDependencies": { + "@ivanv/vue-collapse-transition": "^1.0.2", + "@types/lodash.clonedeep": "^4.5.6", + "@typescript-eslint/eslint-plugin": "^4.18.0", + "@typescript-eslint/parser": "^4.18.0", "@vue/cli-plugin-babel": "~4.5.0", "@vue/cli-plugin-eslint": "~4.5.0", + "@vue/cli-plugin-typescript": "~4.5.0", "@vue/cli-service": "~4.5.0", - "@vue/compiler-sfc": "^3.0.0-beta.1", + "@vue/compiler-sfc": "^3.2.2", + "@vue/eslint-config-prettier": "^6.0.0", + "@vue/eslint-config-typescript": "^7.0.0", "babel-eslint": "^10.1.0", "eslint": "^6.7.2", "eslint-plugin-vue": "^7.0.0-alpha.0", + "prettier": "^1.19.1", "raw-loader": "^4.0.2", "sass": "^1.36.0", - "sass-loader": "^10.2.0" - }, - "eslintConfig": { - "root": true, - "env": { - "node": true - }, - "extends": [ - "plugin:vue/vue3-essential", - "eslint:recommended" - ], - "parserOptions": { - "parser": "babel-eslint" - }, - "rules": {} + "sass-loader": "^10.2.0", + "tsconfig-paths-webpack-plugin": "^3.5.1", + "typescript": "~4.1.5" }, "browserslist": [ "> 1%", "last 2 versions", "not dead" - ] + ], + "gitHooks": { + "pre-commit": "lint-staged" + }, + "lint-staged": { + "*.{js,vue}": [ + "vue-cli-service lint", + "git add" + ] + } } diff --git a/src/App.vue b/src/App.vue index 1e09e8c..4000f51 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,53 +1,54 @@ - diff --git a/src/components/features/Achievement.vue b/src/components/features/Achievement.vue index 96288e4..4c4614b 100644 --- a/src/components/features/Achievement.vue +++ b/src/components/features/Achievement.vue @@ -1,52 +1,66 @@ - + diff --git a/src/components/features/Bar.vue b/src/components/features/Bar.vue index e6151a9..6c40f22 100644 --- a/src/components/features/Bar.vue +++ b/src/components/features/Bar.vue @@ -1,100 +1,104 @@ - diff --git a/src/components/features/Buyables.vue b/src/components/features/Buyables.vue index 97de3db..5683b24 100644 --- a/src/components/features/Buyables.vue +++ b/src/components/features/Buyables.vue @@ -1,68 +1,90 @@ - diff --git a/src/components/features/Challenge.vue b/src/components/features/Challenge.vue index 2d56188..ef57ed0 100644 --- a/src/components/features/Challenge.vue +++ b/src/components/features/Challenge.vue @@ -1,79 +1,84 @@ - diff --git a/src/components/features/Challenges.vue b/src/components/features/Challenges.vue index bded8a6..7f78f71 100644 --- a/src/components/features/Challenges.vue +++ b/src/components/features/Challenges.vue @@ -1,36 +1,41 @@ - - + diff --git a/src/components/features/Clickable.vue b/src/components/features/Clickable.vue index 55f594e..74ab28a 100644 --- a/src/components/features/Clickable.vue +++ b/src/components/features/Clickable.vue @@ -1,73 +1,95 @@ - diff --git a/src/components/features/DefaultChallengeDisplay.vue b/src/components/features/DefaultChallengeDisplay.vue index 67c6b19..49b8cf5 100644 --- a/src/components/features/DefaultChallengeDisplay.vue +++ b/src/components/features/DefaultChallengeDisplay.vue @@ -1,46 +1,52 @@ - - + diff --git a/src/components/features/DefaultPrestigeButtonDisplay.vue b/src/components/features/DefaultPrestigeButtonDisplay.vue index f900784..ba48e24 100644 --- a/src/components/features/DefaultPrestigeButtonDisplay.vue +++ b/src/components/features/DefaultPrestigeButtonDisplay.vue @@ -1,77 +1,79 @@ - - + diff --git a/src/components/features/DefaultUpgradeDisplay.vue b/src/components/features/DefaultUpgradeDisplay.vue index f9ae1c4..f788552 100644 --- a/src/components/features/DefaultUpgradeDisplay.vue +++ b/src/components/features/DefaultUpgradeDisplay.vue @@ -1,53 +1,56 @@ - - + diff --git a/src/components/features/Grid.vue b/src/components/features/Grid.vue index 9b0d16d..9d011c9 100644 --- a/src/components/features/Grid.vue +++ b/src/components/features/Grid.vue @@ -1,30 +1,34 @@ - - + diff --git a/src/components/features/GridCell.vue b/src/components/features/GridCell.vue new file mode 100644 index 0000000..2b2e312 --- /dev/null +++ b/src/components/features/GridCell.vue @@ -0,0 +1,97 @@ + + + + + diff --git a/src/components/features/Gridable.vue b/src/components/features/Gridable.vue deleted file mode 100644 index 57e92e7..0000000 --- a/src/components/features/Gridable.vue +++ /dev/null @@ -1,77 +0,0 @@ - - - - - diff --git a/src/components/features/Infobox.vue b/src/components/features/Infobox.vue index 658826a..4e06790 100644 --- a/src/components/features/Infobox.vue +++ b/src/components/features/Infobox.vue @@ -1,93 +1,96 @@ - diff --git a/src/components/features/MainDisplay.vue b/src/components/features/MainDisplay.vue index 622fae7..3f031ea 100644 --- a/src/components/features/MainDisplay.vue +++ b/src/components/features/MainDisplay.vue @@ -1,50 +1,53 @@ - - + diff --git a/src/components/features/MarkNode.vue b/src/components/features/MarkNode.vue index 4ad93bb..6e852c5 100644 --- a/src/components/features/MarkNode.vue +++ b/src/components/features/MarkNode.vue @@ -1,28 +1,30 @@ - diff --git a/src/components/features/MasterButton.vue b/src/components/features/MasterButton.vue index c7f4b95..6bb6525 100644 --- a/src/components/features/MasterButton.vue +++ b/src/components/features/MasterButton.vue @@ -1,48 +1,50 @@ - - + diff --git a/src/components/features/Milestone.vue b/src/components/features/Milestone.vue index ea7e76a..e286ed8 100644 --- a/src/components/features/Milestone.vue +++ b/src/components/features/Milestone.vue @@ -1,53 +1,58 @@ - + diff --git a/src/components/features/PrestigeButton.vue b/src/components/features/PrestigeButton.vue index 64e287a..cfafc3d 100644 --- a/src/components/features/PrestigeButton.vue +++ b/src/components/features/PrestigeButton.vue @@ -1,48 +1,49 @@ - \ No newline at end of file + diff --git a/src/components/features/RespecButton.vue b/src/components/features/RespecButton.vue index e9c117a..f7fbf15 100644 --- a/src/components/features/RespecButton.vue +++ b/src/components/features/RespecButton.vue @@ -1,90 +1,102 @@ - diff --git a/src/components/features/Subtab.vue b/src/components/features/Subtab.vue new file mode 100644 index 0000000..d4a4ad6 --- /dev/null +++ b/src/components/features/Subtab.vue @@ -0,0 +1,32 @@ + + + + + diff --git a/src/components/features/Upgrade.vue b/src/components/features/Upgrade.vue index 55c6013..f7485a5 100644 --- a/src/components/features/Upgrade.vue +++ b/src/components/features/Upgrade.vue @@ -1,54 +1,65 @@ - + diff --git a/src/components/fields/DangerButton.vue b/src/components/fields/DangerButton.vue index 799396c..48e89f9 100644 --- a/src/components/fields/DangerButton.vue +++ b/src/components/fields/DangerButton.vue @@ -1,76 +1,78 @@ - diff --git a/src/components/fields/FeedbackButton.vue b/src/components/fields/FeedbackButton.vue index 49a77bf..269ec0f 100644 --- a/src/components/fields/FeedbackButton.vue +++ b/src/components/fields/FeedbackButton.vue @@ -1,75 +1,82 @@ - diff --git a/src/components/fields/Select.vue b/src/components/fields/Select.vue index 8a55ae6..4de7c0f 100644 --- a/src/components/fields/Select.vue +++ b/src/components/fields/Select.vue @@ -1,32 +1,42 @@ - diff --git a/src/components/fields/Slider.vue b/src/components/fields/Slider.vue index 0be60e2..92203e5 100644 --- a/src/components/fields/Slider.vue +++ b/src/components/fields/Slider.vue @@ -1,27 +1,35 @@ - diff --git a/src/components/fields/Text.vue b/src/components/fields/Text.vue index 44cd585..c166b5b 100644 --- a/src/components/fields/Text.vue +++ b/src/components/fields/Text.vue @@ -1,47 +1,62 @@ - diff --git a/src/components/fields/Toggle.vue b/src/components/fields/Toggle.vue index 1d69bb0..a90a110 100644 --- a/src/components/fields/Toggle.vue +++ b/src/components/fields/Toggle.vue @@ -1,98 +1,101 @@ - diff --git a/src/components/index.js b/src/components/index.js deleted file mode 100644 index 157bbf8..0000000 --- a/src/components/index.js +++ /dev/null @@ -1,28 +0,0 @@ -// Import and register all components, -// which will allow us to use them in any template strings anywhere in the project - -//import TransitionExpand from 'vue-transition-expand'; -//import 'vue-transition-expand/dist/vue-transition-expand.css'; -import CollapseTransition from '@ivanv/vue-collapse-transition/src/CollapseTransition.vue'; -import VueTextareaAutosize from 'vue-textarea-autosize'; -import Sortable from 'vue-sortable'; -import VueNextSelect from 'vue-next-select'; -import 'vue-next-select/dist/index.css'; - -export function registerComponents(vue) { - /* from files */ - const componentsContext = require.context('./'); - componentsContext.keys().forEach(path => { - const component = componentsContext(path).default; - if (component && !(component.name in vue._context.components)) { - vue.component(component.name, component); - } - }); - - /* from packages */ - //vue.use(TransitionExpand); - vue.component('collapse-transition', CollapseTransition); - vue.use(VueTextareaAutosize); - vue.use(Sortable); - vue.component('vue-select', VueNextSelect); -} diff --git a/src/components/index.ts b/src/components/index.ts new file mode 100644 index 0000000..9619597 --- /dev/null +++ b/src/components/index.ts @@ -0,0 +1,26 @@ +// Import and register all components, +// which will allow us to use them in any template strings anywhere in the project + +import CollapseTransition from "@ivanv/vue-collapse-transition/src/CollapseTransition.vue"; +import VueTextareaAutosize from "vue-textarea-autosize"; +import Sortable from "vue-sortable"; +import VueNextSelect from "vue-next-select"; +import "vue-next-select/dist/index.css"; +import { App } from "vue"; + +export function registerComponents(vue: App): void { + /* from files */ + const componentsContext = require.context("./"); + componentsContext.keys().forEach(path => { + const component = componentsContext(path).default; + if (component && !(component.name in vue._context.components)) { + vue.component(component.name, component); + } + }); + + /* from packages */ + vue.component("collapse-transition", CollapseTransition); + vue.use(VueTextareaAutosize); + vue.use(Sortable); + vue.component("vue-select", VueNextSelect); +} diff --git a/src/components/system/Column.vue b/src/components/system/Column.vue index ef80589..86de362 100644 --- a/src/components/system/Column.vue +++ b/src/components/system/Column.vue @@ -1,13 +1,15 @@ - diff --git a/src/components/system/DefaultLayerTab.vue b/src/components/system/DefaultLayerTab.vue index 444cd19..d464c50 100644 --- a/src/components/system/DefaultLayerTab.vue +++ b/src/components/system/DefaultLayerTab.vue @@ -1,43 +1,42 @@ - - + diff --git a/src/components/system/GameOverScreen.vue b/src/components/system/GameOverScreen.vue index 890f920..bd09e20 100644 --- a/src/components/system/GameOverScreen.vue +++ b/src/components/system/GameOverScreen.vue @@ -1,66 +1,77 @@ - diff --git a/src/components/system/Info.vue b/src/components/system/Info.vue index 1e380b3..455c111 100644 --- a/src/components/system/Info.vue +++ b/src/components/system/Info.vue @@ -1,98 +1,115 @@ - diff --git a/src/components/system/LayerProvider.vue b/src/components/system/LayerProvider.vue index d919e01..3bc6632 100644 --- a/src/components/system/LayerProvider.vue +++ b/src/components/system/LayerProvider.vue @@ -1,24 +1,25 @@ - - + diff --git a/src/components/system/LayerTab.vue b/src/components/system/LayerTab.vue index 91021a6..4f37440 100644 --- a/src/components/system/LayerTab.vue +++ b/src/components/system/LayerTab.vue @@ -1,175 +1,206 @@ - diff --git a/src/components/system/Modal.vue b/src/components/system/Modal.vue index 7f89802..7e79f76 100644 --- a/src/components/system/Modal.vue +++ b/src/components/system/Modal.vue @@ -1,92 +1,106 @@ - diff --git a/src/components/system/NaNScreen.vue b/src/components/system/NaNScreen.vue index e6ab1d0..fecc869 100644 --- a/src/components/system/NaNScreen.vue +++ b/src/components/system/NaNScreen.vue @@ -1,115 +1,137 @@ - diff --git a/src/components/system/Nav.vue b/src/components/system/Nav.vue index 4a195eb..8e54b17 100644 --- a/src/components/system/Nav.vue +++ b/src/components/system/Nav.vue @@ -1,146 +1,174 @@ - diff --git a/src/components/system/Options.vue b/src/components/system/Options.vue index bb8c81b..bf11ba2 100644 --- a/src/components/system/Options.vue +++ b/src/components/system/Options.vue @@ -1,66 +1,93 @@ - diff --git a/src/components/system/Resource.vue b/src/components/system/Resource.vue index b5c89d1..07efe45 100644 --- a/src/components/system/Resource.vue +++ b/src/components/system/Resource.vue @@ -1,18 +1,19 @@ - - + diff --git a/src/components/system/Row.vue b/src/components/system/Row.vue index 8695b2a..cebce4f 100644 --- a/src/components/system/Row.vue +++ b/src/components/system/Row.vue @@ -1,13 +1,15 @@ - diff --git a/src/components/system/Save.vue b/src/components/system/Save.vue index 478f443..cb83e25 100644 --- a/src/components/system/Save.vue +++ b/src/components/system/Save.vue @@ -1,102 +1,127 @@ - diff --git a/src/components/system/SavesManager.vue b/src/components/system/SavesManager.vue index c741fa3..bfbcb5a 100644 --- a/src/components/system/SavesManager.vue +++ b/src/components/system/SavesManager.vue @@ -1,204 +1,290 @@ - diff --git a/src/components/system/Spacer.vue b/src/components/system/Spacer.vue index 2832ebb..fbe1e81 100644 --- a/src/components/system/Spacer.vue +++ b/src/components/system/Spacer.vue @@ -1,21 +1,23 @@ - diff --git a/src/components/system/Sticky.vue b/src/components/system/Sticky.vue index 7caf0b5..325a11d 100644 --- a/src/components/system/Sticky.vue +++ b/src/components/system/Sticky.vue @@ -1,64 +1,73 @@ - \ No newline at end of file + diff --git a/src/components/system/Subtab.vue b/src/components/system/Subtab.vue deleted file mode 100644 index 7a9402a..0000000 --- a/src/components/system/Subtab.vue +++ /dev/null @@ -1,27 +0,0 @@ - - - - - diff --git a/src/components/system/TPS.vue b/src/components/system/TPS.vue index 6f489d8..3715629 100644 --- a/src/components/system/TPS.vue +++ b/src/components/system/TPS.vue @@ -1,28 +1,32 @@ - diff --git a/src/components/system/TabButton.vue b/src/components/system/TabButton.vue index 04ce714..522ac27 100644 --- a/src/components/system/TabButton.vue +++ b/src/components/system/TabButton.vue @@ -1,50 +1,70 @@ - diff --git a/src/components/system/Tabs.vue b/src/components/system/Tabs.vue index b7582e4..94fc880 100644 --- a/src/components/system/Tabs.vue +++ b/src/components/system/Tabs.vue @@ -1,45 +1,60 @@ - @@ -89,6 +104,6 @@ export default { } .tab .modal-body hr { - margin: 7px 0; + margin: 7px 0; } diff --git a/src/components/system/Tooltip.vue b/src/components/system/Tooltip.vue index 4a46f58..f2b2ae7 100644 --- a/src/components/system/Tooltip.vue +++ b/src/components/system/Tooltip.vue @@ -1,66 +1,84 @@ - diff --git a/src/components/system/VerticalRule.vue b/src/components/system/VerticalRule.vue index c2b732d..99377b1 100644 --- a/src/components/system/VerticalRule.vue +++ b/src/components/system/VerticalRule.vue @@ -1,21 +1,23 @@ - diff --git a/src/components/tree/BranchLine.vue b/src/components/tree/BranchLine.vue index 9ceac3c..21fe68c 100644 --- a/src/components/tree/BranchLine.vue +++ b/src/components/tree/BranchLine.vue @@ -1,48 +1,66 @@ - - + diff --git a/src/components/tree/BranchNode.vue b/src/components/tree/BranchNode.vue index 9318e20..f2a63e4 100644 --- a/src/components/tree/BranchNode.vue +++ b/src/components/tree/BranchNode.vue @@ -1,67 +1,115 @@ - diff --git a/src/components/tree/Branches.vue b/src/components/tree/Branches.vue index aff864d..9c763b6 100644 --- a/src/components/tree/Branches.vue +++ b/src/components/tree/Branches.vue @@ -1,95 +1,118 @@ - diff --git a/src/components/tree/Tree.vue b/src/components/tree/Tree.vue index b3b0872..3a522ef 100644 --- a/src/components/tree/Tree.vue +++ b/src/components/tree/Tree.vue @@ -1,75 +1,102 @@ - diff --git a/src/data/layers/aca/a.js b/src/data/layers/aca/a.js deleted file mode 100644 index 871bb58..0000000 --- a/src/data/layers/aca/a.js +++ /dev/null @@ -1,82 +0,0 @@ -import Decimal from '../../../util/bignum'; -import player from '../../../game/player'; - -export default { - id: "a", - startData() { return { - unlocked: true, - points: new Decimal(0), - }}, - color: "yellow", - modal: true, - name: "Achievements", - resource: "achievement power", - row: "side", - tooltip() { // Optional, tooltip displays when the layer is locked - return ("Achievements") - }, - achievementPopups: true, - achievements: { - 11: { - image: "https://unsoftcapped2.github.io/The-Modding-Tree-2/discord.png", - name: "Get me!", - done() {return true}, // This one is a freebie - goalTooltip: "How did this happen?", // Shows when achievement is not completed - doneTooltip: "You did it!", // Showed when the achievement is completed - }, - 12: { - name: "Impossible!", - done() {return false}, - goalTooltip: "Mwahahaha!", // Shows when achievement is not completed - doneTooltip: "HOW????", // Showed when the achievement is completed - style: {'color': '#04e050'}, - }, - 13: { - name: "EIEIO", - done() {return player.f.points.gte(1)}, - tooltip: "Get a farm point.\n\nReward: The dinosaur is now your friend (you can max Farm Points).", // Showed when the achievement is completed - onComplete() {console.log("Bork bork bork!")} - }, - }, - midsection: "", - grids: { - test: { - maxRows: 3, - rows: 2, - cols: 2, - getStartData(cell) { - return cell - }, - getUnlocked() { // Default - return true - }, - getCanClick() { - return player.points.eq(10) - }, - getStyle(cell, data) { - return {'background-color': '#'+ (data*1234%999999)} - }, - click() { // Don't forget onHold - this.data++ - }, - getTitle(cell) { - let direction; - if (cell === '101') { - direction = 'top'; - } else if (cell === '102') { - direction = 'bottom'; - } else if (cell === '201') { - direction = 'left'; - } else if (cell === '202') { - direction = 'right'; - } - return ` -

Gridable #${cell}

-
` - }, - getDisplay(cell, data) { - return data - }, - } - }, -} diff --git a/src/data/layers/aca/a.ts b/src/data/layers/aca/a.ts new file mode 100644 index 0000000..a18fdab --- /dev/null +++ b/src/data/layers/aca/a.ts @@ -0,0 +1,103 @@ +/* eslint-disable */ +import player from "@/game/player"; +import { GridCell } from "@/typings/features/grid"; +import { RawLayer } from "@/typings/layer"; +import Decimal from "@/util/bignum"; + +export default { + id: "a", + startData() { + return { + unlocked: true, + points: new Decimal(0) + }; + }, + color: "yellow", + modal: true, + name: "Achievements", + resource: "achievement power", + row: "side", + tooltip() { + // Optional, tooltip displays when the layer is locked + return "Achievements"; + }, + achievementPopups: true, + achievements: { + data: { + 11: { + image: "https://unsoftcapped2.github.io/The-Modding-Tree-2/discord.png", + name: "Get me!", + done() { + return true; + }, // This one is a freebie + goalTooltip: "How did this happen?", // Shows when achievement is not completed + doneTooltip: "You did it!" // Showed when the achievement is completed + }, + 12: { + name: "Impossible!", + done() { + return false; + }, + goalTooltip: "Mwahahaha!", // Shows when achievement is not completed + doneTooltip: "HOW????", // Showed when the achievement is completed + style: { color: "#04e050" } + }, + 13: { + name: "EIEIO", + done() { + return player.layers.f.points.gte(1); + }, + tooltip: + "Get a farm point.\n\nReward: The dinosaur is now your friend (you can max Farm Points).", // Showed when the achievement is completed + onComplete() { + console.log("Bork bork bork!"); + } + } + } + }, + midsection: "", + grids: { + data: { + test: { + maxRows: 3, + rows: 2, + cols: 2, + getStartData(cell: string) { + return cell; + }, + getUnlocked() { + // Default + return true; + }, + getCanClick() { + return player.points.eq(10); + }, + getStyle(cell) { + return { backgroundColor: "#" + ((Number((this[cell] as GridCell).data) * 1234) % 999999) }; + }, + click(cell) { + // Don't forget onHold + (this[cell] as GridCell).data = ((this[cell] as GridCell).data as number) + 1; + }, + getTitle(cell) { + let direction; + if (cell === "101") { + direction = "top"; + } else if (cell === "102") { + direction = "bottom"; + } else if (cell === "201") { + direction = "left"; + } else if (cell === "202") { + direction = "right"; + } + return ` +

Gridable #${cell}

+
`; + }, + getDisplay(cell) { + return (this[cell] as GridCell).data; + } + } + } + } +} as RawLayer; diff --git a/src/data/layers/aca/c.js b/src/data/layers/aca/c.js deleted file mode 100644 index 97d869f..0000000 --- a/src/data/layers/aca/c.js +++ /dev/null @@ -1,399 +0,0 @@ -import Decimal, { format, formatWhole } from '../../../util/bignum'; -import player from '../../../game/player'; -import { layers } from '../../../game/layers'; -import { hasUpgrade, hasMilestone, getBuyableAmount, setBuyableAmount, upgradeEffect, buyableEffect, challengeCompletions } from '../../../util/features'; -import { resetLayer, resetLayerData } from '../../../util/layers'; -import { UP, RIGHT } from '../../../util/vue'; - -const tmp = layers; - -export default { - id: "c", // This is assigned automatically, both to the layer and all upgrades, etc. Shown here so you know about it - name: "Candies", // This is optional, only used in a few places, If absent it just uses the layer id. - symbol: "C", // This appears on the layer's node. Default is the id with the first letter capitalized - position: 0, // Horizontal position within a row. By default it uses the layer id and sorts in alphabetical order - startData() { return { - unlocked: true, - points: new Decimal(0), - best: new Decimal(0), - total: new Decimal(0), - beep: false, - thingy: "pointy", - otherThingy: 10, - spentOnBuyables: new Decimal(0) - }}, - minWidth: 800, - color: "#4BDC13", - requires: new Decimal(10), // Can be a function that takes requirement increases into account - resource: "lollipops", // Name of prestige currency - baseResource: "points", // Name of resource prestige is based on - baseAmount() {return player.points}, // Get the current amount of baseResource - type: "normal", // normal: cost to gain currency depends on amount gained. static: cost depends on how much you already have - exponent: 0.5, // Prestige currency exponent - base: 5, // Only needed for static layers, base of the formula (b^(x^exp)) - roundUpCost: false, // True if the cost needs to be rounded up (use when baseResource is static?) - - // For normal layers, gain beyond [softcap] points is put to the [softcapPower]th power - softcap: new Decimal(1e100), - softcapPower: new Decimal(0.5), - canBuyMax() {}, // Only needed for static layers with buy max - gainMult() { // Calculate the multiplier for main currency from bonuses - let mult = new Decimal(1) - if (hasUpgrade(this.layer, 166)) mult = mult.times(2) // These upgrades don't exist - if (hasUpgrade(this.layer, 120)) mult = mult.times(upgradeEffect(this.layer, 120)) - return mult - }, - gainExp() { // Calculate the exponent on main currency from bonuses - return new Decimal(1) - }, - row: 0, // Row the layer is in on the tree (0 is the first row) - effect() { - return { // Formulas for any boosts inherent to resources in the layer. Can return a single value instead of an object if there is just one effect - waffleBoost: Decimal.pow(player[this.layer].points, 0.2), - icecreamCap: (player[this.layer].points * 10) - }}, - effectDisplay() { // Optional text to describe the effects - let eff = this.effect; - const waffleBoost = eff.waffleBoost.times(buyableEffect(this.layer, 11).first) - return "which are boosting waffles by "+format(waffleBoost)+" and increasing the Ice Cream cap by "+format(eff.icecreamCap) - }, - infoboxes:{ - coolInfo: { - title: "Lore", - titleStyle: {'color': '#FE0000'}, - body: "DEEP LORE!", - bodyStyle: {'background-color': "#0000EE"} - } - }, - milestones: { - 0: {requirementDisplay: "3 Lollipops", - done() {return player[this.layer].best.gte(3)}, // Used to determine when to give the milestone - effectDisplay: "Unlock the next milestone", - }, - 1: {requirementDisplay: "4 Lollipops", - unlocked() {return hasMilestone(this.layer, 0)}, - done() {return player[this.layer].best.gte(4)}, - effectDisplay: "You can toggle beep and boop (which do nothing)", - optionsDisplay: ` -
- - -
- `, - style() { - if(hasMilestone(this.layer, this.id)) return { - 'background-color': '#1111DD' - }}, - - }, - }, - challenges: { - - 11: { - name: "Fun", - completionLimit: 3, - challengeDescription() {return "Makes the game 0% harder
"+challengeCompletions(this.layer, this.id) + "/" + this.completionLimit + " completions"}, - unlocked() { return player[this.layer].best.gt(0) }, - goalDescription: 'Have 20 points I guess', - canComplete() { - return player.points.gte(20) - }, - rewardEffect() { - let ret = player[this.layer].points.add(1).tetrate(0.02) - return ret; - }, - rewardDisplay() { return format(this.rewardEffect)+"x" }, - countsAs: [12, 21], // Use this for if a challenge includes the effects of other challenges. Being in this challenge "counts as" being in these. - rewardDescription: "Says hi", - onComplete() {console.log("hiii")}, // Called when you successfully complete the challenge - onEnter() {console.log("So challenging")}, - onExit() {console.log("Sweet freedom!")}, - - }, - }, - upgrades: { - - 11: { - title: "Generator of Genericness", - description: "Gain 1 Point every second.", - cost: new Decimal(1), - unlocked() { return player[this.layer].unlocked }, // The upgrade is only visible when this is true - }, - 12: { - description: "Point generation is faster based on your unspent Lollipops.", - cost: new Decimal(1), - unlocked() { return (hasUpgrade(this.layer, 11))}, - effect() { // Calculate bonuses from the upgrade. Can return a single value or an object with multiple values - let ret = player[this.layer].points.add(1).pow(player[this.layer].upgrades.includes(24)?1.1:(player[this.layer].upgrades.includes(14)?0.75:0.5)) - if (ret.gte("1e20000000")) ret = ret.sqrt().times("1e10000000") - return ret; - }, - effectDisplay() { return format(this.effect)+"x" }, // Add formatting to the effect - }, - 13: { - unlocked() { return (hasUpgrade(this.layer, 12))}, - onPurchase() { // This function triggers when the upgrade is purchased - player[this.layer].unlockOrder = 0 - }, - style() { - if (hasUpgrade(this.layer, this.id)) return { - 'background-color': '#1111dd' - } - else if (!this.canAfford) { - return { - 'background-color': '#dd1111' - } - } // Otherwise use the default - }, - canAfford(){return player.points.lte(7)}, - pay(){player.points = player.points.add(7)}, - fullDisplay: "Only buyable with less than 7 points, and gives you 7 more. Unlocks a secret subtab." - }, - 22: { - title: "This upgrade doesn't exist", - description: "Or does it?.", - currencyLocation() {return player[this.layer].buyables}, // The object in player data that the currency is contained in - currencyDisplayName: "exhancers", // Use if using a nonstandard currency - currencyInternalName: 11, // Use if using a nonstandard currency - - cost: new Decimal(3), - unlocked() { return player[this.layer].unlocked }, // The upgrade is only visible when this is true - }, - }, - buyables: { - showRespec: true, - respec() { // Optional, reset things and give back your currency. Having this function makes a respec button appear - player[this.layer].points = player[this.layer].points.add(player[this.layer].spentOnBuyables) // A built-in thing to keep track of this but only keeps a single value - this.reset(); - resetLayer(this.layer, true) // Force a reset - }, - respecText: "Respec Thingies", // Text on Respec button, optional - respecMessage: "Are you sure? Respeccing these doesn't accomplish much.", - 11: { - title: "Exhancers", // Optional, displayed at the top in a larger font - cost() { // cost for buying xth buyable, can be an object if there are multiple currencies - let x = this.amount; - if (x.gte(25)) x = x.pow(2).div(25) - let cost = Decimal.pow(2, x.pow(1.5)) - return cost.floor() - }, - effect() { // Effects of owning x of the items, x is a decimal - let x = this.amount; - let eff = {} - if (x.gte(0)) eff.first = Decimal.pow(25, x.pow(1.1)) - else eff.first = Decimal.pow(1/25, x.times(-1).pow(1.1)) - - if (x.gte(0)) eff.second = x.pow(0.8) - else eff.second = x.times(-1).pow(0.8).times(-1) - return eff; - }, - display() { // Everything else displayed in the buyable button after the title - let data = tmp[this.layer].buyables[this.id] - return "Cost: " + format(data.cost) + " lollipops\n\ - Amount: " + player[this.layer].buyables[this.id] + "/4\n\ - Adds + " + format(data.effect.first) + " things and multiplies stuff by " + format(data.effect.second) - }, - unlocked() { return player[this.layer].unlocked }, - canAfford() { - return player[this.layer].points.gte(tmp[this.layer].buyables[this.id].cost)}, - buy() { - let cost = tmp[this.layer].buyables[this.id].cost - player[this.layer].points = player[this.layer].points.sub(cost) - player[this.layer].buyables[this.id] = player[this.layer].buyables[this.id].add(1) - player[this.layer].spentOnBuyables = player[this.layer].spentOnBuyables.add(cost) // This is a built-in system that you can use for respeccing but it only works with a single Decimal value - }, - buyMax() {}, // You'll have to handle this yourself if you want - style: {'height':'222px'}, - purchaseLimit: new Decimal(4), - sellOne() { - let amount = getBuyableAmount(this.layer, this.id) - if (amount.lte(0)) return // Only sell one if there is at least one - setBuyableAmount(this.layer, this.id, amount.sub(1)) - player[this.layer].points = player[this.layer].points.add(this.cost) - }, - }, - }, - doReset(resettingLayer){ // Triggers when this layer is being reset, along with the layer doing the resetting. Not triggered by lower layers resetting, but is by layers on the same row. - if(layers[resettingLayer].row > this.row) resetLayerData(this.layer, ["points"]) // This is actually the default behavior - }, - automate() { - }, // Do any automation inherent to this layer if appropriate - resetsNothing() {return false}, - onPrestige() { - return - }, // Useful for if you gain secondary resources or have other interesting things happen to this layer when you reset it. You gain the currency after this function ends. - - hotkeys: [ - {key: "c", description: "reset for lollipops or whatever", press(){if (layers[this.layer].canReset) resetLayer(this.layer)}}, - {key: "ctrl+c", description: "respec things", press(){layers[this.layer].buyables.respec()}, unlocked() {return hasUpgrade('c', '22')}} , - ], - increaseUnlockOrder: [], // Array of layer names to have their order increased when this one is first unlocked - - microtabs: { - stuff: { - first: { - display: ` - -
confirmed
` - }, - second: { - embedLayer: "f" - }, - }, - otherStuff: { - // There could be another set of microtabs here - } - }, - - bars: { - longBoi: { - fillStyle: {'background-color' : "#FFFFFF"}, - baseStyle: {'background-color' : "#696969"}, - textStyle: {'color': '#04e050'}, - - borderStyle() {return {}}, - direction: RIGHT, - width: 300, - height: 30, - progress() { - return (player.points.add(1).log(10).div(10)).toNumber() - }, - display() { - return format(player.points) + " / 1e10 points" - }, - unlocked: true, - - }, - tallBoi: { - fillStyle: {'background-color' : "#4BEC13"}, - baseStyle: {'background-color' : "#000000"}, - textStyle: {'text-shadow': '0px 0px 2px #000000'}, - - borderStyle() {return {'border-width': "7px"}}, - direction: UP, - width: 50, - height: 200, - progress() { - return player.points.div(100) - }, - display() { - return formatWhole((player.points.div(1)).min(100)) + "%" - }, - unlocked: true, - - }, - flatBoi: { - fillStyle: {'background-color' : "#FE0102"}, - baseStyle: {'background-color' : "#222222"}, - textStyle: {'text-shadow': '0px 0px 2px #000000'}, - - borderStyle() {return {}}, - direction: UP, - width: 100, - height: 30, - progress() { - return player.c.points.div(50) - }, - unlocked: true, - - }, - }, - - // Optional, lets you format the tab yourself by listing components. You can create your own components in v.js. - subtabs: { - "main tab": { - buttonStyle() {return {'color': 'orange'}}, - notify: true, - display: ` - - - - - -
Name your points!
- - I have {{ format(player.points) }} {{ player.c.thingy }} points! -
- - - - `, - glowColor: "blue", - - }, - thingies: { - resetNotify: true, - style() {return {'background-color': '#222222', '--background': '#222222'}}, - buttonStyle() {return {'border-color': 'orange'}}, - display: ` - - - - - -
Beep
- - - - - - -
- - ` - }, - jail: { - display: ` - - - - - -
Sugar level:
-
- - -
idk
- - -
-
- -
It's jail because "bars"! So funny! Ha ha!
- ` - }, - illuminati: { - unlocked() {return (hasUpgrade("c", 13))}, - display: ` -

C O N F I R M E D

- - -
Adjust how many points H gives you!
- ` - } - - }, - style() {return { - //'background-color': '#3325CC' - }}, - nodeStyle() {return { // Style on the layer node - 'color': '#3325CC', - 'text-decoration': 'underline' - }}, - glowColor: "orange", // If the node is highlighted, it will be this color (default is red) - componentStyles: { - "challenge"() {return {'height': '200px'}}, - "prestige-button"() {return {'color': '#AA66AA'}}, - }, - tooltip() { // Optional, tooltip displays when the layer is unlocked - let tooltip = "{{ formatWhole(player.c.points) }} {{ layers.c.resource }}"; - if (player[this.layer].buyables[11].gt(0)) tooltip += "



{{ formatWhole(player.c.buyables[11]) }} Exhancers
" - return tooltip - }, - shouldNotify() { // Optional, layer will be highlighted on the tree if true. - // Layer will automatically highlight if an upgrade is purchasable. - return (player.c.buyables[11] == 1) - }, - mark: "https://unsoftcapped2.github.io/The-Modding-Tree-2/discord.png", - resetDescription: "Melt your points into ", -}; diff --git a/src/data/layers/aca/c.ts b/src/data/layers/aca/c.ts new file mode 100644 index 0000000..b291172 --- /dev/null +++ b/src/data/layers/aca/c.ts @@ -0,0 +1,573 @@ +/* eslint-disable */ +import { Direction } from "@/game/enums"; +import { layers } from "@/game/layers"; +import player from "@/game/player"; +import { DecimalSource } from "@/lib/break_eternity"; +import { RawLayer } from "@/typings/layer"; +import Decimal, { format, formatWhole } from "@/util/bignum"; +import { + buyableEffect, + challengeCompletions, + getBuyableAmount, + hasMilestone, + hasUpgrade, + setBuyableAmount, + upgradeEffect +} from "@/util/features"; +import { resetLayer, resetLayerData } from "@/util/layers"; + +export default { + id: "c", // This is assigned automatically, both to the layer and all upgrades, etc. Shown here so you know about it + name: "Candies", // This is optional, only used in a few places, If absent it just uses the layer id. + symbol: "C", // This appears on the layer's node. Default is the id with the first letter capitalized + position: 0, // Horizontal position within a row. By default it uses the layer id and sorts in alphabetical order + startData() { + return { + unlocked: true, + points: new Decimal(0), + best: new Decimal(0), + total: new Decimal(0), + beep: false, + thingy: "pointy", + otherThingy: 10, + spentOnBuyables: new Decimal(0) + }; + }, + minWidth: 800, + color: "#4BDC13", + requires: new Decimal(10), // Can be a function that takes requirement increases into account + resource: "lollipops", // Name of prestige currency + baseResource: "points", // Name of resource prestige is based on + baseAmount() { + return player.points; + }, // Get the current amount of baseResource + type: "normal", // normal: cost to gain currency depends on amount gained. static: cost depends on how much you already have + exponent: 0.5, // Prestige currency exponent + base: 5, // Only needed for static layers, base of the formula (b^(x^exp)) + roundUpCost: false, // True if the cost needs to be rounded up (use when baseResource is static?) + + // For normal layers, gain beyond [softcap] points is put to the [softcapPower]th power + softcap: new Decimal(1e100), + softcapPower: new Decimal(0.5), + canBuyMax() {}, // Only needed for static layers with buy max + gainMult() { + // Calculate the multiplier for main currency from bonuses + let mult = new Decimal(1); + /* + if (hasUpgrade(this.layer, 166)) mult = mult.times(2); // These upgrades don't exist + if (hasUpgrade(this.layer, 120)) + mult = mult.times(upgradeEffect(this.layer, 120) as DecimalSource); + */ + return mult; + }, + gainExp() { + // Calculate the exponent on main currency from bonuses + return new Decimal(1); + }, + row: 0, // Row the layer is in on the tree (0 is the first row) + effect() { + return { + // Formulas for any boosts inherent to resources in the layer. Can return a single value instead of an object if there is just one effect + waffleBoost: Decimal.pow(player.layers[this.layer].points, 0.2), + icecreamCap: player.layers[this.layer].points.times(10) + }; + }, + effectDisplay() { + // Optional text to describe the effects + const eff = this.effect as { waffleBoost: Decimal; icecreamCap: Decimal }; + const waffleBoost = eff.waffleBoost.times( + (buyableEffect(this.layer, 11) as { first: Decimal, second: Decimal }).first + ); + return ( + "which are boosting waffles by " + + format(waffleBoost) + + " and increasing the Ice Cream cap by " + + format(eff.icecreamCap) + ); + }, + infoboxes: { + data: { + coolInfo: { + title: "Lore", + titleStyle: { color: "#FE0000" }, + body: "DEEP LORE!", + bodyStyle: { "background-color": "#0000EE" } + } + } + }, + milestones: { + data: { + 0: { + requirementDisplay: "3 Lollipops", + done() { + return (player.layers[this.layer].best as Decimal).gte(3); + }, // Used to determine when to give the milestone + effectDisplay: "Unlock the next milestone" + }, + 1: { + requirementDisplay: "4 Lollipops", + unlocked() { + return hasMilestone(this.layer, 0); + }, + done() { + return (player.layers[this.layer].best as Decimal).gte(4); + }, + effectDisplay: "You can toggle beep and boop (which do nothing)", + optionsDisplay: ` +
+ + +
+ `, + style() { + if (hasMilestone(this.layer, this.id)) + return { + backgroundColor: "#1111DD" + }; + } + } + } + }, + challenges: { + data: { + 11: { + name: "Fun", + completionLimit: 3, + challengeDescription() { + return ( + "Makes the game 0% harder
" + + challengeCompletions(this.layer, this.id) + + "/" + + this.completionLimit + + " completions" + ); + }, + unlocked() { + return (player.layers[this.layer].best as Decimal).gt(0); + }, + goalDescription: "Have 20 points I guess", + canComplete() { + return player.points.gte(20); + }, + effect() { + const ret = player.layers[this.layer].points.add(1).tetrate(0.02); + return ret; + }, + rewardDisplay() { + return format(this.effect as Decimal) + "x"; + }, + countsAs: [12, 21], // Use this for if a challenge includes the effects of other challenges. Being in this challenge "counts as" being in these. + rewardDescription: "Says hi", + onComplete() { + console.log("hiii"); + }, // Called when you successfully complete the challenge + onEnter() { + console.log("So challenging"); + }, + onExit() { + console.log("Sweet freedom!"); + } + } + } + }, + upgrades: { + data: { + 11: { + title: "Generator of Genericness", + description: "Gain 1 Point every second.", + cost: new Decimal(1), + unlocked() { + return player.layers[this.layer].unlocked; + } // The upgrade is only visible when this is true + }, + 12: { + description: + "Point generation is faster based on your unspent Lollipops.", + cost: new Decimal(1), + unlocked() { + return hasUpgrade(this.layer, 11); + }, + effect() { + // Calculate bonuses from the upgrade. Can return a single value or an object with multiple values + let ret = player.layers[this.layer].points + .add(1) + .pow( + player.layers[this.layer].upgrades!.includes(24) + ? 1.1 + : player.layers[this.layer].upgrades!.includes(14) + ? 0.75 + : 0.5 + ); + if (ret.gte("1e20000000")) ret = ret.sqrt().times("1e10000000"); + return ret; + }, + effectDisplay() { + return format(this.effect as Decimal) + "x"; + } // Add formatting to the effect + }, + 13: { + unlocked() { + return hasUpgrade(this.layer, 12); + }, + onPurchase() { + // This function triggers when the upgrade is purchased + player.layers[this.layer].unlockOrder = 0; + }, + style() { + if (hasUpgrade(this.layer, this.id)) + return { + "background-color": "#1111dd" + }; + else if (!this.canAfford) { + return { + "background-color": "#dd1111" + }; + } // Otherwise use the default + }, + canAfford() { + return player.points.lte(7); + }, + pay() { + player.points = player.points.add(7); + }, + fullDisplay: + "Only buyable with less than 7 points, and gives you 7 more. Unlocks a secret subtab." + }, + 22: { + title: "This upgrade doesn't exist", + description: "Or does it?.", + currencyLocation() { + return player.layers[this.layer].buyables; + }, // The object in player data that the currency is contained in + currencyDisplayName: "exhancers", // Use if using a nonstandard currency + currencyInternalName: 11, // Use if using a nonstandard currency + + cost: new Decimal(3), + unlocked() { + return player.layers[this.layer].unlocked; + } // The upgrade is only visible when this is true + } + } + }, + buyables: { + showBRespecButton: true, + respec() { + // Optional, reset things and give back your currency. Having this function makes a respec button appear + player.layers[this.layer].points = player.layers[this.layer].points.add( + player.layers[this.layer].spentOnBuyables as Decimal + ); // A built-in thing to keep track of this but only keeps a single value + this.reset(); + resetLayer(this.layer, true); // Force a reset + }, + respecButtonDisplay: "Respec Thingies", // Text on Respec button, optional + respecWarningDisplay: + "Are you sure? Respeccing these doesn't accomplish much.", + data: { + 11: { + title: "Exhancers", // Optional, displayed at the top in a larger font + cost() { + // cost for buying xth buyable, can be an object if there are multiple currencies + let x = this.amount; + if (x.gte(25)) x = x.pow(2).div(25); + const cost = Decimal.pow(2, x.pow(1.5)); + return cost.floor(); + }, + effect() { + // Effects of owning x of the items, x is a decimal + const x = this.amount; + const eff = {} as { first?: Decimal; second?: Decimal }; + if (x.gte(0)) eff.first = Decimal.pow(25, x.pow(1.1)); + else eff.first = Decimal.pow(1 / 25, x.times(-1).pow(1.1)); + + if (x.gte(0)) eff.second = x.pow(0.8); + else + eff.second = x + .times(-1) + .pow(0.8) + .times(-1); + return eff; + }, + display() { + // Everything else displayed in the buyable button after the title + return ( + "Cost: " + + format(this.cost!) + + " lollipops\n\ + Amount: " + + player.layers[this.layer].buyables![this.id] + + "/4\n\ + Adds + " + + format((this.effect as { first: Decimal; second: Decimal }).first) + + " things and multiplies stuff by " + + format((this.effect as { first: Decimal; second: Decimal }).second) + ); + }, + unlocked() { + return player.layers[this.layer].unlocked; + }, + canAfford() { + return player.layers[this.layer].points.gte(this.cost!); + }, + buy() { + const cost = this.cost!; + player.layers[this.layer].points = player.layers[ + this.layer + ].points.sub(cost); + player.layers[this.layer].buyables![this.id] = player.layers[ + this.layer + ].buyables![this.id].add(1); + player.layers[this.layer].spentOnBuyables = (player.layers[ + this.layer + ].spentOnBuyables as Decimal).add(cost); // This is a built-in system that you can use for respeccing but it only works with a single Decimal value + }, + buyMax() {}, // You'll have to handle this yourself if you want + style: { height: "222px" }, + purchaseLimit: new Decimal(4), + sellOne() { + const amount = getBuyableAmount(this.layer, this.id)!; + if (amount.lte(0)) return; // Only sell one if there is at least one + setBuyableAmount(this.layer, this.id, amount.sub(1)); + player.layers[this.layer].points = player.layers[ + this.layer + ].points.add(this.cost!); + } + } + } + }, + onReset(resettingLayer: string) { + // Triggers when this layer is being reset, along with the layer doing the resetting. Not triggered by lower layers resetting, but is by layers on the same row. + if ( + layers[resettingLayer].row != undefined && + this.row != undefined && + layers[resettingLayer].row! > this.row! + ) + resetLayerData(this.layer, ["points"]); // This is actually the default behavior + }, + automate() {}, // Do any automation inherent to this layer if appropriate + resetsNothing() { + return false; + }, + onPrestige() { + return; + }, // Useful for if you gain secondary resources or have other interesting things happen to this layer when you reset it. You gain the currency after this function ends. + + hotkeys: [ + { + key: "c", + description: "reset for lollipops or whatever", + press() { + if (layers[this.layer].canReset) resetLayer(this.layer); + } + }, + { + key: "ctrl+c", + description: "respec things", + press() { + layers[this.layer].buyables!.respec!(); + }, + unlocked() { + return hasUpgrade("c", "22"); + } + } + ], + increaseUnlockOrder: [], // Array of layer names to have their order increased when this one is first unlocked + + microtabs: { + stuff: { + data: { + first: { + display: ` + +
confirmed
` + }, + second: { + embedLayer: "f" + } + } + }, + otherStuff: { + // There could be another set of microtabs here + data: {} + } + }, + + bars: { + data: { + longBoi: { + fillStyle: { "background-color": "#FFFFFF" }, + baseStyle: { "background-color": "#696969" }, + textStyle: { color: "#04e050" }, + + borderStyle() { + return {}; + }, + direction: Direction.Right, + width: 300, + height: 30, + progress() { + return player.points + .add(1) + .log(10) + .div(10) + .toNumber(); + }, + display() { + return format(player.points) + " / 1e10 points"; + }, + unlocked: true + }, + tallBoi: { + fillStyle: { "background-color": "#4BEC13" }, + baseStyle: { "background-color": "#000000" }, + textStyle: { "text-shadow": "0px 0px 2px #000000" }, + + borderStyle() { + return { "border-width": "7px" }; + }, + direction: Direction.Up, + width: 50, + height: 200, + progress() { + return player.points.div(100); + }, + display() { + return formatWhole(player.points.div(1).min(100)) + "%"; + }, + unlocked: true + }, + flatBoi: { + fillStyle: { "background-color": "#FE0102" }, + baseStyle: { "background-color": "#222222" }, + textStyle: { "text-shadow": "0px 0px 2px #000000" }, + + borderStyle() { + return {}; + }, + direction: Direction.Up, + width: 100, + height: 30, + progress() { + return player.layers.c.points.div(50); + }, + unlocked: true + } + } + }, + + // Optional, lets you format the tab yourself by listing components. You can create your own components in v.js. + subtabs: { + "main tab": { + buttonStyle() { + return { color: "orange" }; + }, + notify: true, + display: ` + + + + + +
Name your points!
+ + I have {{ format(player.points) }} {{ player.layers.c.thingy }} points! +
+ + + + `, + glowColor: "blue" + }, + thingies: { + resetNotify: true, + style() { + return { "background-color": "#222222", "--background": "#222222" }; + }, + buttonStyle() { + return { "border-color": "orange" }; + }, + display: ` + + + + + +
Beep
+ + + + + + +
+ + ` + }, + jail: { + display: ` + + + + + +
Sugar level:
+
+ + +
idk
+ + +
+
+ +
It's jail because "bars"! So funny! Ha ha!
+ ` + }, + illuminati: { + unlocked() { + return hasUpgrade("c", 13); + }, + display: ` +

C O N F I R M E D

+ + +
Adjust how many points H gives you!
+ ` + } + }, + style() { + return { + //'background-color': '#3325CC' + }; + }, + nodeStyle() { + return { + // Style on the layer node + color: "#3325CC", + "text-decoration": "underline" + }; + }, + glowColor: "orange", // If the node is highlighted, it will be this color (default is red) + componentStyles: { + challenge() { + return { height: "200px" }; + }, + "prestige-button"() { + return { color: "#AA66AA" }; + } + }, + tooltip() { + // Optional, tooltip displays when the layer is unlocked + let tooltip = "{{ formatWhole(player.layers.c.points) }} {{ layers.c.resource }}"; + if (player.layers[this.layer].buyables![11].gt(0)) + tooltip += + "



{{ formatWhole(player.layers.c.buyables![11]) }} Exhancers
"; + return tooltip; + }, + shouldNotify() { + // Optional, layer will be highlighted on the tree if true. + // Layer will automatically highlight if an upgrade is purchasable. + return player.layers.c.buyables![11] == new Decimal(1); + }, + mark: "https://unsoftcapped2.github.io/The-Modding-Tree-2/discord.png", + resetDescription: "Melt your points into " +} as RawLayer; diff --git a/src/data/layers/aca/f.js b/src/data/layers/aca/f.js deleted file mode 100644 index 9fd0a54..0000000 --- a/src/data/layers/aca/f.js +++ /dev/null @@ -1,107 +0,0 @@ -import Decimal, { formatWhole } from '../../../util/bignum'; -import player from '../../../game/player'; -import { layers as tmp } from '../../../game/layers'; -import { getClickableState } from '../../../util/features'; - -export default { - id: "f", - infoboxes:{ - coolInfo: { - title: "Lore", - titleStyle: {'color': '#FE0000'}, - body: "DEEP LORE!", - bodyStyle: {'background-color': "#0000EE"} - } - }, - - startData() { return { - unlocked: false, - points: new Decimal(0), - boop: false, - clickables: {[11]: "Start"}, // Optional default Clickable state - }}, - color: "#FE0102", - requires() {return new Decimal(10)}, - resource: "farm points", - baseResource: "points", - baseAmount() {return player.points}, - type: "static", - exponent: 0.5, - base: 3, - roundUpCost: true, - canBuyMax() {return false}, - name: "Farms", - //directMult() {return new Decimal(player.c.otherThingy)}, - - row: 1, - branches: [{ target: "c", 'stroke-width': '25px', 'stroke': 'blue', style: 'filter: blur(5px)' }], // When this layer appears, a branch will appear from this layer to any layers here. Each entry can be a pair consisting of a layer id and a color. - - tooltipLocked() { // Optional, tooltip displays when the layer is locked - return ("This weird farmer dinosaur will only see you if you have at least {{layers.f.requires}} points. You only have {{ formatWhole(player.points) }}") - }, - midsection: '

Bork Bork!
', - // The following are only currently used for "custom" Prestige type: - prestigeButtonDisplay() { //Is secretly HTML - if (!this.canBuyMax) return "Hi! I'm a weird dinosaur and I'll give you a Farm Point in exchange for all of your points and lollipops! (At least " + formatWhole(tmp[this.layer].nextAt) + " points)" - if (this.canBuyMax) return "Hi! I'm a weird dinosaur and I'll give you " + formatWhole(tmp[this.layer].resetGain) + " Farm Points in exchange for all of your points and lollipops! (You'll get another one at " + formatWhole(tmp[this.layer].nextAtDisp) + " points)" - }, - canReset() { - return tmp[this.layer].baseAmount.gte(tmp[this.layer].nextAt) - }, - // This is also non minimal, a Clickable! - clickables: { - - masterButtonClick() { - if (getClickableState(this.layer, 11) == "Borkened...") - player[this.layer].clickables[11] = "Start" - }, - masterButtonDisplay() {return (getClickableState(this.layer, 11) == "Borkened...") ? "Fix the clickable!" : "Does nothing"}, // Text on Respec button, optional - 11: { - title: "Clicky clicky!", // Optional, displayed at the top in a larger font - display() { // Everything else displayed in the buyable button after the title - let data = getClickableState(this.layer, this.id) - return "Current state:
" + data - }, - unlocked() { return player[this.layer].unlocked }, - canClick() { - return getClickableState(this.layer, this.id) !== "Borkened..."}, - click() { - switch(getClickableState(this.layer, this.id)){ - case "Start": - player[this.layer].clickables[this.id] = "A new state!" - break; - case "A new state!": - player[this.layer].clickables[this.id] = "Keep going!" - break; - case "Keep going!": - player[this.layer].clickables[this.id] = "Maybe that's a bit too far..." - break; - case "Maybe that's a bit too far...": - //makeParticles(coolParticle, 4) - player[this.layer].clickables[this.id] = "Borkened..." - break; - default: - player[this.layer].clickables[this.id] = "Start" - break; - } - }, - hold(){ - console.log("Clickkkkk...") - }, - style() { - switch(getClickableState(this.layer, this.id)){ - case "Start": - return {'background-color': 'green'} - case "A new state!": - return {'background-color': 'yellow'} - case "Keep going!": - return {'background-color': 'orange'} - case "Maybe that's a bit too far...": - return {'background-color': 'red'} - default: - return {} - }}, - }, - }, - -} diff --git a/src/data/layers/aca/f.ts b/src/data/layers/aca/f.ts new file mode 100644 index 0000000..95c2bdd --- /dev/null +++ b/src/data/layers/aca/f.ts @@ -0,0 +1,151 @@ +/* eslint-disable */ +import { layers as tmp } from "@/game/layers"; +import player from "@/game/player"; +import { RawLayer } from "@/typings/layer"; +import Decimal, { formatWhole } from "@/util/bignum"; +import { getClickableState } from "@/util/features"; + +export default { + id: "f", + infoboxes: { + data: { + coolInfo: { + title: "Lore", + titleStyle: { color: "#FE0000" }, + body: "DEEP LORE!", + bodyStyle: { "background-color": "#0000EE" } + } + } + }, + + startData() { + return { + unlocked: false, + points: new Decimal(0), + boop: false, + clickables: { [11]: "Start" } // Optional default Clickable state + }; + }, + color: "#FE0102", + requires() { + return new Decimal(10); + }, + resource: "farm points", + baseResource: "points", + baseAmount() { + return player.points; + }, + type: "static", + exponent: 0.5, + base: 3, + roundUpCost: true, + canBuyMax() { + return false; + }, + name: "Farms", + //directMult() {return new Decimal(player.c.otherThingy)}, + + row: 1, + branches: [ + { + target: "c", + "stroke-width": "25px", + stroke: "blue", + style: "filter: blur(5px)" + } + ], // When this layer appears, a branch will appear from this layer to any layers here. Each entry can be a pair consisting of a layer id and a color. + + tooltipLocked() { + // Optional, tooltip displays when the layer is locked + return "This weird farmer dinosaur will only see you if you have at least {{layers.f.requires}} points. You only have {{ formatWhole(player.points) }}"; + }, + midsection: + '

Bork Bork!
', + // The following are only currently used for "custom" Prestige type: + prestigeButtonDisplay() { + //Is secretly HTML + if (!this.canBuyMax) + return ( + "Hi! I'm a weird dinosaur and I'll give you a Farm Point in exchange for all of your points and lollipops! (At least " + + formatWhole(tmp[this.layer].nextAt) + + " points)" + ); + if (this.canBuyMax) + return ( + "Hi! I'm a weird dinosaur and I'll give you " + + formatWhole(tmp[this.layer].resetGain) + + " Farm Points in exchange for all of your points and lollipops! (You'll get another one at " + + formatWhole(tmp[this.layer].nextAt) + + " points)" + ); + }, + canReset() { + return Decimal.gte(tmp[this.layer].baseAmount!, tmp[this.layer].nextAt); + }, + // This is also non minimal, a Clickable! + clickables: { + masterButtonClick() { + if (getClickableState(this.layer, 11) == "Borkened...") + player.layers[this.layer].clickables![11] = "Start"; + }, + masterButtonDisplay() { + return getClickableState(this.layer, 11) == "Borkened..." + ? "Fix the clickable!" + : "Does nothing"; + }, // Text on Respec button, optional + data: { + 11: { + title: "Clicky clicky!", // Optional, displayed at the top in a larger font + display() { + // Everything else displayed in the buyable button after the title + const data = getClickableState(this.layer, this.id); + return "Current state:
" + data; + }, + unlocked() { + return player.layers[this.layer].unlocked; + }, + canClick() { + return getClickableState(this.layer, this.id) !== "Borkened..."; + }, + click() { + switch (getClickableState(this.layer, this.id)) { + case "Start": + player.layers[this.layer].clickables![this.id] = "A new state!"; + break; + case "A new state!": + player.layers[this.layer].clickables![this.id] = "Keep going!"; + break; + case "Keep going!": + player.layers[this.layer].clickables![this.id] = + "Maybe that's a bit too far..."; + break; + case "Maybe that's a bit too far...": + //makeParticles(coolParticle, 4) + player.layers[this.layer].clickables![this.id] = "Borkened..."; + break; + default: + player.layers[this.layer].clickables![this.id] = "Start"; + break; + } + }, + hold() { + console.log("Clickkkkk..."); + }, + style() { + switch (getClickableState(this.layer, this.id)) { + case "Start": + return { "background-color": "green" }; + case "A new state!": + return { "background-color": "yellow" }; + case "Keep going!": + return { "background-color": "orange" }; + case "Maybe that's a bit too far...": + return { "background-color": "red" }; + default: + return {}; + } + } + } + } + } +} as RawLayer; diff --git a/src/data/layers/demo-infinity.js b/src/data/layers/demo-infinity.js deleted file mode 100644 index 1a9765d..0000000 --- a/src/data/layers/demo-infinity.js +++ /dev/null @@ -1,153 +0,0 @@ -import Decimal, { format } from '../../util/bignum'; -import player from '../../game/player'; -import { layers } from '../../game/layers'; -import { hasUpgrade, hasMilestone, getBuyableAmount, setBuyableAmount, hasChallenge } from '../../util/features'; -import { resetLayer } from '../../util/layers'; - -export default { - id: "i", - position: 2, // Horizontal position within a row. By default it uses the layer id and sorts in alphabetical order - startData() { return { - unlocked: false, - points: new Decimal(0), - - }}, - branches: ["p"], - color: "#964B00", - requires(){ - let require = new Decimal(8).plus(player.i.points.div(10).floor().times(2)) - return require - } , // Can be a function that takes requirement increases into account - effectDisplay(){return "Multiplying points and prestige points by "+format(player[this.layer].points.plus(1).pow(hasUpgrade("p",235)?6.9420:1))}, - resource: "Infinity", // Name of prestige currency - baseResource: "pointy points", // Name of resource prestige is based on - baseAmount() {return player.p.buyables[21]}, // Get the current amount of baseResource - type: "custom", // normal: cost to gain currency depends on amount gained. static: cost depends on how much you already have - resetGain(){ - - if (hasMilestone("p",12)){return getBuyableAmount("p",21).div(2).floor().times(2).times(5).sub(30).sub(player.i.points)} - return (player.p.buyables[21].gte(layers.i.requires)?1:0)}, // Prestige currency exponent - getNextAt(){return new Decimal(100)}, - canReset(){return player.p.buyables[21].gte(layers.i.requires)}, - prestigeButtonDisplay(){return "Reset everything for +"+format(layers.i.resetGain)+" Infinity.
You need "+format(layers.i.requires)+" pointy points to reset."}, - row: 1, // Row the layer is in on the tree (0 is the first row) - hotkeys: [ - {key: "i", description: "I: Infinity", press(){if (layers.i.canReset) resetLayer(this.layer)}}, - ], - layerShown(){return player[this.layer].unlocked||new Decimal(player.p.buyables[21]).gte(8)}, - milestones: { - 0: { - requirementDisplay: "2 Infinity points", - effectDisplay: "Keep ALL milestones on reset", - done() { return player[this.layer].points.gte(2) }, - - }, - 1: { - requirementDisplay: "3 Infinity points", - effectDisplay: "Pointy points don't reset generators", - done() { return player[this.layer].points.gte(3) }, - unlocked(){return hasMilestone(this.layer,this.id-1)} - }, - 2: { - requirementDisplay: "4 Infinity points", - effectDisplay: "Start with 6 Time Dilation, 3 Point, and 1 of the other 2 challenges", - done() { return player[this.layer].points.gte(4) }, -unlocked(){return hasMilestone(this.layer,this.id-1)} - }, - 3: { - requirementDisplay: "5 Infinity points", - effectDisplay: "Start with 40 upgrades and 6 boosts", - done() { return player[this.layer].points.gte(5) }, -unlocked(){return hasMilestone(this.layer,this.id-1)} - }, - 4: { - requirementDisplay: "6 Infinity points", - effectDisplay: "You can choose all of the 14th row upgrades, and remove the respec button", - done() { return player[this.layer].points.gte(6) }, -unlocked(){return hasMilestone(this.layer,this.id-1)} - }, - 5: { - requirementDisplay: "8 Infinity points", - effectDisplay: "Keep all upgrades and 7 Time dilation", - done() { return player[this.layer].points.gte(8) }, -unlocked(){return hasMilestone(this.layer,this.id-1)} - }, - 6: { - requirementDisplay: "10 Infinity points", - effectDisplay: "Infinity reset nothing and auto prestige", - done() { return player[this.layer].points.gte(10) }, -unlocked(){return hasMilestone(this.layer,this.id-1)} - }, - }, - resetsNothing(){return hasMilestone(this.layer,6)}, -update(){ - if (hasMilestone(this.layer,0)){ - if (!hasMilestone("p",0)){ - player.p.milestones.push(0) - player.p.milestones.push(1) - player.p.milestones.push(2) - player.p.milestones.push(3) - player.p.milestones.push(4) - player.p.milestones.push(5) - player.p.milestones.push(6) - player.p.milestones.push(7) - player.p.milestones.push(8) - } - } - if (hasMilestone(this.layer,2)){ - if (!hasChallenge("p",11)){ - player.p.challenges[11]=new Decimal(hasMilestone(this.layer,5)?7:6) - player.p.challenges[12]=new Decimal(3) - player.p.challenges[21]=new Decimal(1) - player.p.challenges[22]=new Decimal(1) - } - } - if (hasMilestone(this.layer,3)){ - if (!hasUpgrade("p",71)){ - player.p.upgrades=[11,12,13,14,21,22,23,24,31,32,33,34,41,42,43,44,51,52,53,54,61,62,63,64,71,72,73,74,81,82,83,84,91,92,93,94,101,102,103,104] - } - if (getBuyableAmount("p",11).lt(6)){setBuyableAmount("p",11,new Decimal(6))} - } - if (hasUpgrade(this.layer,13)){ - - for (let i=0;i<(hasUpgrade("p",222)?100:hasUpgrade("p",215)?10:1);i++){ - if (layers.p.buyables[12].canAfford)layers.p.buyables[12].buy() - if (layers.p.buyables[13].canAfford)layers.p.buyables[13].buy() - if (layers.p.buyables[14].canAfford&&layers.p.buyables[14].unlocked())layers.p.buyables[14].buy() - if (layers.p.buyables[21].canAfford)layers.p.buyables[21].buy()} - } - if (hasUpgrade("p",223)){ - if (hasMilestone("p",14))player.p.buyables[22]=player.p.buyables[22].max(player.p.buyables[21].sub(7)) - else if (layers.p.buyables[22].canAfford)layers.p.buyables[22].buy() - } - if (hasMilestone(this.layer,5)&&!hasUpgrade("p",111)){player.p.upgrades=[11,12,13,14,21,22,23,24,31,32,33,34,41,42,43,44,51,52,53,54,61,62,63,64,71,72,73,74,81,82,83,84,91,92,93,94,101,102,103,104,111,121,122,131,132,141,142,143]} - if (hasMilestone(this.layer,6)) { - this.reset(); - } -}, - upgrades:{ - rows: 999, - cols: 5, - 11:{ - title: "Prestige", - description: "Gain 100% of prestige points per second", - cost(){ - return new Decimal(1)}, - unlocked(){return hasMilestone(this.layer,4)} - }, - 12:{ - title: "Automation", - description: "Remove the nerf of upgrade Active", - cost(){ - return new Decimal(2)}, - unlocked(){return hasUpgrade(this.layer,11)} - }, - 13:{ - title: "Pointy", - description: "Automatically buy generators and pointy points", - cost(){ - return new Decimal(5)}, - unlocked(){return hasUpgrade(this.layer,11)} - }, - } - } diff --git a/src/data/layers/demo-infinity.ts b/src/data/layers/demo-infinity.ts new file mode 100644 index 0000000..6e62446 --- /dev/null +++ b/src/data/layers/demo-infinity.ts @@ -0,0 +1,354 @@ +/* eslint-disable */ +import { layers } from "@/game/layers"; +import player from "@/game/player"; +import { Layer, RawLayer } from "@/typings/layer"; +import Decimal, { format } from "@/util/bignum"; +import { + getBuyableAmount, hasChallenge, hasMilestone, hasUpgrade, setBuyableAmount +} from "@/util/features"; +import { resetLayer } from "@/util/layers"; + +export default { + id: "i", + position: 2, // Horizontal position within a row. By default it uses the layer id and sorts in alphabetical order + startData() { + return { + unlocked: false, + points: new Decimal(0) + }; + }, + branches: ["p"], + color: "#964B00", + requires() { + const require = new Decimal(8).plus( + player.layers.i.points + .div(10) + .floor() + .times(2) + ); + return require; + }, // Can be a function that takes requirement increases into account + effectDisplay() { + return ( + "Multiplying points and prestige points by " + + format( + player.layers[this.layer].points + .plus(1) + .pow(hasUpgrade("p", 235) ? 6.942 : 1) + ) + ); + }, + resource: "Infinity", // Name of prestige currency + baseResource: "pointy points", // Name of resource prestige is based on + baseAmount() { + return player.layers.p.buyables![21]; + }, // Get the current amount of baseResource + type: "custom", // normal: cost to gain currency depends on amount gained. static: cost depends on how much you already have + resetGain() { + if (hasMilestone("p", 12)) { + return getBuyableAmount("p", 21)! + .div(2) + .floor() + .times(2) + .times(5) + .sub(30) + .sub(player.layers.i.points); + } + return player.layers.p.buyables![21].gte(layers.i.requires!) ? 1 : 0; + }, // Prestige currency exponent + getNextAt() { + return new Decimal(100); + }, + canReset() { + return player.layers.p.buyables![21].gte(layers.i.requires!); + }, + prestigeButtonDisplay() { + return ( + "Reset everything for +" + + format(layers.i.resetGain) + + " Infinity.
You need " + + format(layers.i.requires!) + + " pointy points to reset." + ); + }, + row: 1, // Row the layer is in on the tree (0 is the first row) + hotkeys: [ + { + key: "i", + description: "I: Infinity", + press() { + if (layers.i.canReset) resetLayer(this.layer); + } + } + ], + layerShown() { + return ( + player.layers[this.layer].unlocked || + new Decimal(player.layers.p.buyables[21]).gte(8) + ); + }, + milestones: { + data: { + 0: { + requirementDisplay: "2 Infinity points", + effectDisplay: "Keep ALL milestones on reset", + done() { + return player.layers[this.layer].points.gte(2); + } + }, + 1: { + requirementDisplay: "3 Infinity points", + effectDisplay: "Pointy points don't reset generators", + done() { + return player.layers[this.layer].points.gte(3); + }, + unlocked() { + return hasMilestone(this.layer, Number(this.id) - 1); + } + }, + 2: { + requirementDisplay: "4 Infinity points", + effectDisplay: + "Start with 6 Time Dilation, 3 Point, and 1 of the other 2 challenges", + done() { + return player.layers[this.layer].points.gte(4); + }, + unlocked() { + return hasMilestone(this.layer, Number(this.id) - 1); + } + }, + 3: { + requirementDisplay: "5 Infinity points", + effectDisplay: "Start with 40 upgrades and 6 boosts", + done() { + return player.layers[this.layer].points.gte(5); + }, + unlocked() { + return hasMilestone(this.layer, Number(this.id) - 1); + } + }, + 4: { + requirementDisplay: "6 Infinity points", + effectDisplay: + "You can choose all of the 14th row upgrades, and remove the respec button", + done() { + return player.layers[this.layer].points.gte(6); + }, + unlocked() { + return hasMilestone(this.layer, Number(this.id) - 1); + } + }, + 5: { + requirementDisplay: "8 Infinity points", + effectDisplay: "Keep all upgrades and 7 Time dilation", + done() { + return player.layers[this.layer].points.gte(8); + }, + unlocked() { + return hasMilestone(this.layer, Number(this.id) - 1); + } + }, + 6: { + requirementDisplay: "10 Infinity points", + effectDisplay: "Infinity reset nothing and auto prestige", + done() { + return player.layers[this.layer].points.gte(10); + }, + unlocked() { + return hasMilestone(this.layer, Number(this.id) - 1); + } + } + } + }, + resetsNothing() { + return hasMilestone(this.layer, 6); + }, + update(this: Layer) { + if (hasMilestone(this.layer, 0)) { + if (!hasMilestone("p", 0)) { + player.layers.p.milestones!.push(0); + player.layers.p.milestones!.push(1); + player.layers.p.milestones!.push(2); + player.layers.p.milestones!.push(3); + player.layers.p.milestones!.push(4); + player.layers.p.milestones!.push(5); + player.layers.p.milestones!.push(6); + player.layers.p.milestones!.push(7); + player.layers.p.milestones!.push(8); + } + } + if (hasMilestone(this.layer, 2)) { + if (!hasChallenge("p", 11)) { + player.layers.p.challenges![11] = new Decimal( + hasMilestone(this.layer, 5) ? 7 : 6 + ); + player.layers.p.challenges![12] = new Decimal(3); + player.layers.p.challenges![21] = new Decimal(1); + player.layers.p.challenges![22] = new Decimal(1); + } + } + if (hasMilestone(this.layer, 3)) { + if (!hasUpgrade("p", 71)) { + player.layers.p.upgrades = [ + 11, + 12, + 13, + 14, + 21, + 22, + 23, + 24, + 31, + 32, + 33, + 34, + 41, + 42, + 43, + 44, + 51, + 52, + 53, + 54, + 61, + 62, + 63, + 64, + 71, + 72, + 73, + 74, + 81, + 82, + 83, + 84, + 91, + 92, + 93, + 94, + 101, + 102, + 103, + 104 + ]; + } + if (getBuyableAmount("p", 11)!.lt(6)) { + setBuyableAmount("p", 11, new Decimal(6)); + } + } + if (hasUpgrade(this.layer, 13)) { + for ( + let i = 0; + i < (hasUpgrade("p", 222) ? 100 : hasUpgrade("p", 215) ? 10 : 1); + i++ + ) { + if (layers.p.buyables!.data[12].canAfford) layers.p.buyables!.data[12].buy(); + if (layers.p.buyables!.data[13].canAfford) layers.p.buyables!.data[13].buy(); + if ( + layers.p.buyables!.data[14].canAfford && + layers.p.buyables!.data[14].unlocked + ) + layers.p.buyables!.data[14].buy(); + if (layers.p.buyables!.data[21].canAfford) layers.p.buyables!.data[21].buy(); + } + } + if (hasUpgrade("p", 223)) { + if (hasMilestone("p", 14)) + player.layers.p.buyables![22] = player.layers.p.buyables![22].max( + player.layers.p.buyables![21].sub(7) + ); + else if (layers.p.buyables!.data[22].canAfford) layers.p.buyables!.data[22].buy(); + } + if (hasMilestone(this.layer, 5) && !hasUpgrade("p", 111)) { + player.layers.p.upgrades = [ + 11, + 12, + 13, + 14, + 21, + 22, + 23, + 24, + 31, + 32, + 33, + 34, + 41, + 42, + 43, + 44, + 51, + 52, + 53, + 54, + 61, + 62, + 63, + 64, + 71, + 72, + 73, + 74, + 81, + 82, + 83, + 84, + 91, + 92, + 93, + 94, + 101, + 102, + 103, + 104, + 111, + 121, + 122, + 131, + 132, + 141, + 142, + 143 + ]; + } + if (hasMilestone(this.layer, 6)) { + this.reset(); + } + }, + upgrades: { + rows: 999, + cols: 5, + data: { + 11: { + title: "Prestige", + description: "Gain 100% of prestige points per second", + cost() { + return new Decimal(1); + }, + unlocked() { + return hasMilestone(this.layer, 4); + } + }, + 12: { + title: "Automation", + description: "Remove the nerf of upgrade Active", + cost() { + return new Decimal(2); + }, + unlocked() { + return hasUpgrade(this.layer, 11); + } + }, + 13: { + title: "Pointy", + description: "Automatically buy generators and pointy points", + cost() { + return new Decimal(5); + }, + unlocked() { + return hasUpgrade(this.layer, 11); + } + } + } + } +} as RawLayer; diff --git a/src/data/layers/demo.js b/src/data/layers/demo.js deleted file mode 100644 index 10a9f70..0000000 --- a/src/data/layers/demo.js +++ /dev/null @@ -1,940 +0,0 @@ -import Decimal, { format } from '../../util/bignum'; -import player from '../../game/player'; -import { layers } from '../../game/layers'; -import { hasUpgrade, hasMilestone, getBuyableAmount, setBuyableAmount, hasChallenge } from '../../util/features'; -import { resetLayer } from '../../util/layers'; - -export default { - id: "p", - position: 2, - startData() { return { - unlocked: true, - points: new Decimal(0), - gp: new Decimal(0), - g: new Decimal(0), - geff: new Decimal(1), - cmult: new Decimal(1), - }}, - color: "#4BDC13", - requires(){ - let require = new Decimal(68.99) - if (hasMilestone(this.layer,0))require=require.plus(0.01) - if (hasUpgrade(this.layer,21))require=require.tetrate(hasUpgrade("p",34)?(new Decimal(1).div(new Decimal(1).plus(layers.p.upgrades[34].effect))):1) - if (hasUpgrade(this.layer,22))require=require.pow(hasUpgrade("p",34)?(new Decimal(1).div(new Decimal(1).plus(layers.p.upgrades[34].effect))):1) - if (hasUpgrade(this.layer,23))require=require.div(hasUpgrade("p",34)?(new Decimal(1).plus(layers.p.upgrades[34].effect)):1) - if (hasUpgrade(this.layer,24))require=require.sub(hasUpgrade("p",34)?(new Decimal(1).plus(layers.p.upgrades[34].effect)):1) - return require.max(1) - }, - resource: "prestige points", - baseResource: "points", - baseAmount() {return player.points}, // Get the current amount of baseResource - type: "normal", // normal: cost to gain currency depends on amount gained. static: cost depends on how much you already have - exponent: 0.5, // Prestige currency exponent - gainMult() { // Calculate the multiplier for main currency from bonuses - let mult = new Decimal(1) - if (hasUpgrade(this.layer,131))mult=mult.times(10) - if (player.i.unlocked)mult=mult.times(player.i.points.plus(1).pow(hasUpgrade("p",235)?6.9420:1)) - if (hasUpgrade(this.layer,222))mult=mult.times(getBuyableAmount(this.layer,22).plus(1)) - if (hasUpgrade("p",231)){ - let asdf = (hasUpgrade("p",132)?player.p.gp.plus(1).pow(new Decimal(1).div(2)):hasUpgrade("p",101)?player.p.gp.plus(1).pow(new Decimal(1).div(3)):hasUpgrade("p",93)?player.p.gp.plus(1).pow(0.2):player.p.gp.plus(1).log10()) - mult=mult.mul(asdf.plus(1)) - } - if (hasMilestone(this.layer,13))mult=mult.mul(new Decimal(2).plus(layers.p.buyables[33].effect).pow(getBuyableAmount(this.layer,32))) - return mult - }, - gainExp() { // Calculate the exponent on main currency from bonuses - return new Decimal(1) - }, - row: 0, // Row the layer is in on the tree (0 is the first row) - hotkeys: [ - {key: "p", description: "P: Reset for prestige points", press(){if (layers.p.canReset) resetLayer(this.layer)}}, - ], - layerShown(){return true}, - upgrades:{ - rows: 999, - cols: 5, - 11:{ - title: "Gain points", - description: "Point generation is increased by 1", - cost(){ - if (hasMilestone(this.layer,2))return new Decimal(1) - return new Decimal(1.00001)}, - unlocked(){return true} - }, - 12:{ - title: "Gain more points", - description: "Point generation is singled", - cost(){return new Decimal(1)}, - unlocked(){return hasUpgrade(this.layer,11)} - }, - 13:{ - title: "Gain more points", - description: "Point generation is lined", - cost(){return new Decimal(1)}, - unlocked(){return hasUpgrade(this.layer,12)} - }, - 14:{ - title: "Gain more points", - description: "Point generation is tetrated by 1", - cost(){return new Decimal(1)}, - unlocked(){return hasUpgrade(this.layer,13)} - }, - 21:{ - title: "Lower prestige requirement", - description: "Prestige point requirement is superrooted by 1", - cost(){return new Decimal(1)}, - unlocked(){return hasUpgrade(this.layer,14)} - }, - 22:{ - title: "Lower prestige requirement more", - description: "Prestige point requirement is line rooted", - cost(){return new Decimal(1)}, - unlocked(){return hasUpgrade(this.layer,21)} - }, - 23:{ - title: "Lower prestige requirement more", - description: "Prestige point requirement is wholed", - cost(){return new Decimal(1)}, - unlocked(){return hasUpgrade(this.layer,22)} - }, - 24:{ - title: "Lower prestige requirement more", - description: "Prestige point requirement is decreased by 1", - cost(){return new Decimal(1)}, - unlocked(){return hasUpgrade(this.layer,23)} - }, - 31:{ - title: "Unlock", - description: "Unlock an upgrade", - cost(){return new Decimal(1)}, - unlocked(){return hasUpgrade(this.layer,24)} - }, - 32:{ - title: "An", - description: "Unlock an upgrade", - cost(){return new Decimal(1)}, - unlocked(){return hasUpgrade(this.layer,31)} - }, - 33:{ - title: "Upgrade", - description: "Unlock an upgrade", - cost(){return new Decimal(1)}, - unlocked(){return hasUpgrade(this.layer,32)} - }, - 34:{ - title: "Increase", - description(){return "Add 0.01 to all above upgrades. Currently: +"+format(this.effect)}, - cost(){return new Decimal(1)}, - unlocked(){return hasUpgrade(this.layer,33)}, - effect(){ - let r = (hasUpgrade("p",41)?new Decimal(0.01).times(layers.p.upgrades[41].effect):new Decimal(0.01)) - r=r.times(new Decimal(1).plus(new Decimal(player[this.layer].challenges[11]).add(1).pow(hasUpgrade(this.layer,121)?1.2:1))) - if (hasUpgrade(this.layer,92)) r=r.plus(new Decimal(0.001).times(player[this.layer].g.plus(1)).min(0.05)) - return r - } - }, - 41:{ - title: "Increase again", - description(){return "Multiply the previous upgrade by 1.01. Currently: x"+format(this.effect)}, - cost(){return new Decimal(1)}, - unlocked(){return hasUpgrade(this.layer,34)}, - effect(){return new Decimal(1.01).pow(hasUpgrade("p",42)?layers.p.upgrades[42].effect:1).times(hasUpgrade("p",63)?2:1)} - }, - 42:{ - title: "Increase again", - description(){return "Exponentiate the previous upgrade by 1.01. Currently: ^"+format(this.effect)}, - cost(){return new Decimal(1)}, - unlocked(){return hasUpgrade(this.layer,41)}, - effect(){return new Decimal(1.01).tetrate(hasUpgrade("p",43)?layers.p.upgrades[43].effect:1).times(hasUpgrade("p",63)?2:1).times(hasUpgrade("p",64)?2:1)} - }, - 43:{ - title: "Increase again", - description(){return "Tetrate the previous upgrade by 1.01. Currently: ^^"+format(this.effect)}, - cost(){return new Decimal(1)}, - unlocked(){return hasUpgrade(this.layer,42)}, - effect(){return new Decimal(1.01).pentate(hasUpgrade("p",44)?layers.p.upgrades[44].effect:1).times(hasUpgrade("p",63)?2:1).times(hasUpgrade("p",64)?2:1)} - }, - 44:{ - title: "Increase again", - description(){return "Pentate the previous upgrade by 1.01. Currently: ^^^"+format(this.effect)}, - cost(){return new Decimal(1)}, - unlocked(){return hasUpgrade(this.layer,43)}, - effect(){return new Decimal(1.01).times(hasUpgrade("p",63)?2:1).times(hasUpgrade("p",64)?2:1)} - }, - 51:{ - title: "Challenging", - description: "This upgrade doesn't unlock a challenge", - cost(){return new Decimal(1)}, - unlocked(){return hasUpgrade(this.layer,44)}, - }, - 52:{ - title: "Not challenging", - description: "This upgrade doesn't add 1 to the completion limit", - cost(){return new Decimal(1)}, - unlocked(){return hasUpgrade(this.layer,51)}, - }, - 53:{ - title: "Not not challenging", - description: "This upgrade doesn't add 1 to the completion limit", - cost(){return new Decimal(1)}, - unlocked(){return hasUpgrade(this.layer,52)}, - }, - 54:{ - title: "(not^3) challenging", - description: "Fix the bug where you can't buy upgrades when you have 1 prestige point", - cost(){return new Decimal(0.99999)}, - unlocked(){return hasUpgrade(this.layer,53)}, - onPurchase(){player.p.points=player.p.points.round()}, - }, - 61:{ - title: "(not^4) challenging", - description: "Doesn't unlock a second challenge", - cost(){return new Decimal(1)}, - unlocked(){return hasUpgrade(this.layer,54)&&hasUpgrade(this.layer,53)}, - }, - 62:{ - title: "Infinity points", - description: "You can now complete Time Dilation 4 more times", - cost(){return new Decimal(1)}, - unlocked(){return hasUpgrade(this.layer,61)}, - }, - 63:{ - title: "Eternity points", - description: "Double all fourth row upgrade effects", - cost(){return new Decimal(1)}, - unlocked(){return hasUpgrade(this.layer,62)}, - }, - 64:{ - title: "Reality points", - description: "Previous upgrade, but only to the last 3 upgrades", - cost(){return new Decimal(1)}, - unlocked(){return hasUpgrade(this.layer,63)}, - }, - 71:{ - title: "1", - description: "Add 1.1 to point gain, but reset all above upgrades", - cost(){return new Decimal(1)}, - unlocked(){return hasUpgrade(this.layer,64)}, - onPurchase(){if (!hasMilestone(this.layer,0)) player[this.layer].upgrades=[71]} - }, - 72:{ - title: "2", - description: "Multiply point gain by 1.1, but reset all above upgrades", - cost(){return new Decimal(2)}, - unlocked(){return hasUpgrade(this.layer,64)&&hasUpgrade(this.layer, this.id-1)}, - onPurchase(){if (!hasMilestone(this.layer,1))player[this.layer].upgrades=[71,72]} - }, - 73:{ - title: "3", - description: "Raise point gain by ^1.1, but reset all above upgrades", - cost(){return new Decimal(4)}, - unlocked(){return hasUpgrade(this.layer,64)&&hasUpgrade(this.layer, this.id-1)}, - onPurchase(){if (!hasMilestone(this.layer,1))player[this.layer].upgrades=[71,72,73]} - }, - 74:{ - title: "4", - description: "Tetrate point gain by 1.1, but reset all above upgrades", - cost(){return new Decimal(8)}, - unlocked(){return hasUpgrade(this.layer,64)&&hasUpgrade(this.layer, this.id-1)}, - onPurchase(){if (!hasMilestone(this.layer,2))player[this.layer].upgrades=[71,72,73,74] - if (hasMilestone(this.layer,1)&&!hasMilestone(this.layer,2)) {player[this.layer].upgrades=[11,12,13,14,21,22,23,24,71,72,73,74]}} - }, - 81:{ - title: "5", - description: "Generator efficiency is increased by 2", - cost(){return new Decimal(1)}, - unlocked(){return hasUpgrade(this.layer,74)&&(player[this.layer].buyables[12].gt(0)||player[this.layer].buyables[21].gt(0))}, - }, - 82:{ - title: "6", - description: "Unlock another way to buy generators", - cost(){return new Decimal(1)}, - unlocked(){return hasUpgrade(this.layer,81)&&(player[this.layer].buyables[12].gt(0)||player[this.layer].buyables[21].gt(0))}, - }, - 83:{ - title: "7", - description: "Generator efficiency is boosted by prestige points", - cost(){return new Decimal(3)}, - unlocked(){return hasUpgrade(this.layer,82)}, - }, - 84:{ - title: "8", - description: "You can complete Point one more time", - cost(){return new Decimal(3)}, - unlocked(){return hasUpgrade(this.layer,83)}, - }, - 91:{ - title: "9", - description: "New Challenge Time", - cost(){return new Decimal(20)}, - unlocked(){return hasUpgrade(this.layer,84)&&new Decimal(player[this.layer].challenges[12]).gte(3)}, - }, - 92:{ - title: "10", - description: "Each of the first 50 generators adds 0.001 to Increase", - cost(){return new Decimal(5)}, - unlocked(){return hasUpgrade(this.layer,91)&&hasChallenge(this.layer,21)}, - }, - 93:{ - title: "11", - description: "Change the tree trunk in generator effect to a hypertessaract root", - cost(){return new Decimal(7)}, - unlocked(){return hasUpgrade(this.layer,92)}, - }, - 94:{ - title: "12", - description: "Unlock a clickable in generators", - cost(){return new Decimal(50)}, - unlocked(){return hasUpgrade(this.layer,93)}, - }, - 101:{ - title: "10th row????", - description: "Decrease the dimensions of 11 by 2", - cost(){return new Decimal(10)}, - unlocked(){return hasUpgrade(this.layer,94)}, - }, - 102:{ - title: "2 Tree Trunks", - description: "Double log of generator points adds to generator efficiency", - cost(){return new Decimal(25)}, - unlocked(){return hasUpgrade(this.layer,101)}, - }, - 103:{ - title: "(not^5) challenging", - description: "Unlock the last challenge", - cost(){return new Decimal(103)}, - unlocked(){return hasUpgrade(this.layer,102)}, - }, - 104:{ - title: "2 layers tree", - description: "Prestige points boost points, and unlock another tab", - cost(){return new Decimal(100)}, - unlocked(){return hasUpgrade(this.layer,103)&&hasChallenge(this.layer,22)}, - }, - 111:{ - title: "not (hardcapped)", - description: "Remove the generator clickable hardcap, and you can only pick one upgrade on each row below this", - cost(){return new Decimal(110)}, - unlocked(){return hasUpgrade(this.layer,104)&&hasMilestone(this.layer,6)}, - }, - 112:{ - title: "Respec button", - description: "Respec all lower upgrades, but you don't get points back", - cost(){return new Decimal(100)}, - unlocked(){return hasUpgrade(this.layer,111)&&(hasUpgrade(this.layer,121)||hasUpgrade(this.layer,122))&&!hasMilestone("i",4)}, - onPurchase(){ - player.p.upgrades=player.p.upgrades.filter(function x(i){return i<112}) - } - }, - 121:{ - title: "Timers", - description: "Raise the Time Dilation reward effect to the 1.2", - cost(){return new Decimal(500)}, - unlocked(){return hasUpgrade(this.layer,111)&&(!hasUpgrade(this.layer,122)||hasMilestone(this.layer,7))}, - }, - 122:{ - title: "Generators", - description: "Decrease the first generator buyable cost scaling base by 2", - cost(){return new Decimal(500)}, - unlocked(){return hasUpgrade(this.layer,111)&&(!hasUpgrade(this.layer,121)||hasMilestone(this.layer,7))}, - }, - 131:{ - title: "Prestige", - description: "Gain 10x more prestige points", - cost(){return new Decimal(5000)}, - unlocked(){return (hasUpgrade(this.layer,121)||hasUpgrade(this.layer,122))&&(!hasUpgrade(this.layer,132)||hasMilestone(this.layer,7))}, - }, - 132:{ - title: "One and a half", - description: "Raise generator effect to the 1.5", - cost(){return new Decimal(5000)}, - unlocked(){return (hasUpgrade(this.layer,121)||hasUpgrade(this.layer,122))&&(!hasUpgrade(this.layer,131)||hasMilestone(this.layer,7))}, - }, - - 141:{ - title: "Active", - description: "Multiply generator efficiency now increases by 1, but it doesn't automatically click.", - cost(){return new Decimal(50000)}, - unlocked(){return (hasUpgrade(this.layer,131)||hasUpgrade(this.layer,132))&&((!hasUpgrade(this.layer,142)&&!hasUpgrade(this.layer,143))||hasMilestone("i",4))}, - }, - 142:{ - title: "Passive", - description: "Gain 5x more points", - cost(){return new Decimal(50000)}, - unlocked(){return (hasUpgrade(this.layer,131)||hasUpgrade(this.layer,132))&&((!hasUpgrade(this.layer,141)&&!hasUpgrade(this.layer,143))||hasMilestone("i",4))}, - }, - 143:{ - title: "Idle", - description: "Hours played multiply generator power", - cost(){return new Decimal(50000)}, - unlocked(){return (hasUpgrade(this.layer,131)||hasUpgrade(this.layer,132))&&((!hasUpgrade(this.layer,142)&&!hasUpgrade(this.layer,141))||hasMilestone("i",4))}, - }, - 211:{ - title: "Prestige", - description: "Pointy points multiply points", - cost(){return new Decimal(1)}, - canAfford(){return getBuyableAmount(this.layer,22).gte(this.cost)}, - pay(){setBuyableAmount(this.layer,22,getBuyableAmount(this.layer,22).sub(this.cost))}, - unlocked(){return (hasMilestone("i",5)&&layers.p.activeSubtab!="Upgrades")}, - }, - 212:{ - title: "Pointy", - description: "Pointy prestige points reduce the cost scaling of pointy points", - cost(){return new Decimal(2)}, - canAfford(){return getBuyableAmount(this.layer,22).gte(this.cost)}, - pay(){setBuyableAmount(this.layer,22,getBuyableAmount(this.layer,22).sub(this.cost))}, - unlocked(){return (hasMilestone("i",5)&&layers.p.activeSubtab!="Upgrades"&&hasUpgrade(this.layer,211))}, - }, - 213:{ - title: "Time", - description: "Generator power also multiplies point gain", - cost(){return new Decimal(6)}, - canAfford(){return getBuyableAmount(this.layer,22).gte(this.cost)}, - pay(){setBuyableAmount(this.layer,22,getBuyableAmount(this.layer,22).sub(this.cost))}, - unlocked(){return (hasMilestone("i",5)&&layers.p.activeSubtab!="Upgrades"&&hasUpgrade(this.layer,212))}, - }, - 214:{ - title: "^0", - description: "Further reduce the pointy point scaling", - cost(){return new Decimal(11)}, - canAfford(){return getBuyableAmount(this.layer,22).gte(this.cost)}, - pay(){setBuyableAmount(this.layer,22,getBuyableAmount(this.layer,22).sub(this.cost))}, - unlocked(){return (hasMilestone("i",5)&&layers.p.activeSubtab!="Upgrades"&&hasUpgrade(this.layer,213))}, - }, - 215:{ - title: "bulk", - description: "Auto-pointy points now buys 10 per tick", - cost(){return new Decimal(27)}, - canAfford(){return getBuyableAmount(this.layer,22).gte(this.cost)}, - pay(){setBuyableAmount(this.layer,22,getBuyableAmount(this.layer,22).sub(this.cost))}, - unlocked(){return (hasMilestone("i",5)&&layers.p.activeSubtab!="Upgrades"&&hasUpgrade(this.layer,214))}, - }, - 221:{ - title: "^-1", - description: "^0 is even more powerful", - cost(){return new Decimal(28)}, - canAfford(){return getBuyableAmount(this.layer,22).gte(this.cost)}, - pay(){setBuyableAmount(this.layer,22,getBuyableAmount(this.layer,22).sub(this.cost))}, - unlocked(){return (hasMilestone("i",5)&&layers.p.activeSubtab!="Upgrades"&&hasUpgrade(this.layer,215))}, - }, - 222:{ - title: "???", - description: "square bulk and pointy prestige points multiply prestige points", - cost(){return new Decimal(90)}, - canAfford(){return getBuyableAmount(this.layer,22).gte(this.cost)}, - pay(){setBuyableAmount(this.layer,22,getBuyableAmount(this.layer,22).sub(this.cost))}, - unlocked(){return (hasMilestone("i",5)&&layers.p.activeSubtab!="Upgrades"&&hasUpgrade(this.layer,221))}, - }, - 223:{ - title: "more automation", - description: "Automatically gain pointy prestige points", - cost(){return new Decimal(96)}, - canAfford(){return getBuyableAmount(this.layer,22).gte(this.cost)}, - pay(){setBuyableAmount(this.layer,22,getBuyableAmount(this.layer,22).sub(this.cost))}, - unlocked(){return (hasMilestone("i",5)&&layers.p.activeSubtab!="Upgrades"&&hasUpgrade(this.layer,222))}, - }, - 224:{ - title: "Generation", - description: "Generator costs are divided by generator effect", - cost(){return new Decimal(100)}, - canAfford(){return getBuyableAmount(this.layer,22).gte(this.cost)}, - pay(){setBuyableAmount(this.layer,22,getBuyableAmount(this.layer,22).sub(this.cost))}, - unlocked(){return (hasMilestone("i",5)&&layers.p.activeSubtab!="Upgrades"&&hasUpgrade(this.layer,223))}, - }, - 225:{ - title: "Boosters", - description: "Unlock boosters (next update)", - cost(){return new Decimal(135)}, - canAfford(){return getBuyableAmount(this.layer,22).gte(this.cost)}, - pay(){setBuyableAmount(this.layer,22,getBuyableAmount(this.layer,22).sub(this.cost))}, - unlocked(){return (hasMilestone("i",5)&&layers.p.activeSubtab!="Upgrades"&&hasUpgrade(this.layer,224))}, - }, - 231:{ - title: "Blue", - description: "The generator effect also affects prestige points", - cost(){return new Decimal(4)}, - canAfford(){return getBuyableAmount(this.layer,23).gte(this.cost)}, - pay(){setBuyableAmount(this.layer,23,getBuyableAmount(this.layer,23).sub(this.cost))}, - unlocked(){return (layers.p.activeSubtab!="Upgrades"&&hasMilestone(this.layer,11))}, - currencyDisplayName: "pointy boosters" - }, - 232:{ - title: "Red", - description: "Unlock a third way to buy generators", - cost(){return new Decimal(5)}, - canAfford(){return getBuyableAmount(this.layer,23).gte(this.cost)}, - pay(){setBuyableAmount(this.layer,23,getBuyableAmount(this.layer,23).sub(this.cost))}, - unlocked(){return (layers.p.activeSubtab!="Upgrades"&&hasMilestone(this.layer,12))}, - currencyDisplayName: "pointy boosters" - }, - 233:{ - title: "Green", - description: "Prestige points do not reset your pointy points and boosters don't reset generators", - cost(){return new Decimal(5)}, - canAfford(){return getBuyableAmount(this.layer,23).gte(this.cost)}, - pay(){setBuyableAmount(this.layer,23,getBuyableAmount(this.layer,23).sub(this.cost))}, - unlocked(){return (layers.p.activeSubtab!="Upgrades"&&hasMilestone(this.layer,12))}, - currencyDisplayName: "pointy boosters" - }, - 234:{ - title: "Yellow", - description: "Divide the cost of the third generator buyable based on boosters", - cost(){return new Decimal(6)}, - canAfford(){return getBuyableAmount(this.layer,23).gte(this.cost)}, - pay(){setBuyableAmount(this.layer,23,getBuyableAmount(this.layer,23).sub(this.cost))}, - unlocked(){return (layers.p.activeSubtab!="Upgrades"&&hasMilestone(this.layer,12))}, - currencyDisplayName: "pointy boosters" - }, - 235:{ - title: "Orange", - description: "Raise the Infinity effect to the 6.9420th power", - cost(){return new Decimal(8)}, - canAfford(){return getBuyableAmount(this.layer,23).gte(this.cost)}, - pay(){setBuyableAmount(this.layer,23,getBuyableAmount(this.layer,23).sub(this.cost))}, - unlocked(){return (layers.p.activeSubtab!="Upgrades"&&hasMilestone(this.layer,12))}, - currencyDisplayName: "pointy boosters" - }, - }, - - clickables: { - rows: 1, - cols: 1, - 11: { - - display() {return "Multiply generator efficiency by "+format(player.p.cmult)+((player.p.cmult.min(100).eq(100)&&!hasUpgrade(this.layer,111))?" (hardcapped)":"")}, - unlocked(){return hasUpgrade("p",94)}, - click(){player.p.cmult=player.p.cmult.plus(hasUpgrade("p",141)?1:0.01) - if (!hasUpgrade(this.layer,111))player.p.cmult=player.p.cmult.min(100) - }, - canClick(){return player.p.cmult.lt(100)||hasUpgrade(this.layer,111)}, - }, - -}, - -challenges:{ - rows: 99, - cols: 2, - 11:{ - name: "Time dilation", - challengeDescription(){return "Point gain exponent is raised to the ^0.75"}, - goal(){return new Decimal(100).times(new Decimal(10).pow(new Decimal(player[this.layer].challenges[this.id]).times(new Decimal(1).sub(new Decimal(layers[this.layer].challenges[12].effect).div(100))).pow(2)))}, - rewardDescription(){return "You have completed this challenge "+player[this.layer].challenges[this.id]+"/"+this.completionLimit+" times. Multiply Increase's effect by challenge completions+1. Currently: x"+format(new Decimal(player[this.layer].challenges[this.id]).add(1).pow(hasUpgrade(this.layer,121)?1.2:1))}, - unlocked(){return hasUpgrade("p",51)||hasChallenge(this.layer,this.id)}, - completionLimit(){ - if (hasUpgrade("p",62))return 7 - if (hasUpgrade("p",53))return 3 - if (hasUpgrade("p",52))return 2 - return 1 - - } - }, - 12:{ - name: "Point", - challengeDescription: "Points are pointed", - goal(){return new Decimal(100)}, - rewardDescription(){return "You have completed this challenge "+player[this.layer].challenges[this.id]+"/"+this.completionLimit+" times, making previous challenge goal scale "+(layers[this.layer].challenges[this.id].effect)+"% slower."}, - unlocked(){return hasUpgrade("p",61)||hasChallenge(this.layer,this.id)}, - effect(){ - if (!hasChallenge(this.layer,this.id)) return 0 - if (player[this.layer].challenges[this.id]==1) return 50 - if (player[this.layer].challenges[this.id]==2) return 60 - if (player[this.layer].challenges[this.id]==3) return 70 - }, - completionLimit(){ - let l=new Decimal(1) - if (hasUpgrade("p",84)) l=l.plus(1) - if (hasMilestone("p",3))l=l.plus(1) - return l - - } - }, - 21:{ - name: "Time Points", - challengeDescription: "You are stuck in all above challenges", - goal(){return new Decimal(308.25)}, - rewardDescription(){return "Lower the first generator buyable cost base by 6"}, - unlocked(){return hasUpgrade("p",91)||hasChallenge(this.layer,this.id)}, - }, - 22:{ - name: "Last Challenge", - challengeDescription: "Generator points do nothing", - goal(){return new Decimal(9999)}, - rewardDescription(){return "Autoclick the clickable and reduce 2 Tree Trunks by 1"}, - unlocked(){return hasUpgrade("p",103)||hasChallenge(this.layer,this.id)}, - } - }, - buyables: { - rows: 99, - cols: 4, - 11: { - cost() { return new Decimal(0)}, - display() { return "Reset all upgrades and challenges, but get a boost. You have reset "+getBuyableAmount(this.layer,this.id)+" times.
"+(getBuyableAmount(this.layer,this.id).eq(6)?"You can't buy more than 6 boosts!":"You need all upgrades to reset.") }, - canAfford() { return (player[this.layer].points.gte(this.cost)&&hasUpgrade(this.layer,74)&&hasUpgrade(this.layer,64))&&getBuyableAmount(this.layer,this.id).lt(6) }, - buy() { - player[this.layer].points = player[this.layer].points.sub(this.cost) - setBuyableAmount(this.layer, this.id, getBuyableAmount(this.layer, this.id).add(1)) - player[this.layer].points=new Decimal(0) - player[this.layer].upgrades=[] - if (hasMilestone(this.layer,1))player[this.layer].upgrades=[11,12,13,14,21,22,23,24] - if (hasMilestone(this.layer,3))player[this.layer].upgrades=[11,12,13,14,21,22,23,24,31,32,33,34,41,42,43,44,51,52,53,54,61,62,63,64] - if (!hasMilestone(this.layer,2)){ - for (let c in layers[this.layer].challenges){ - player[this.layer].challenges[c]=new Decimal(0) - } - } - }, - unlocked(){return (hasUpgrade(this.layer,74)&&hasUpgrade(this.layer,64))||hasMilestone(this.layer,0)} - }, - 12: { - cost() { return new Decimal(1).times(new Decimal(hasChallenge(this.layer,21)?4:10).sub(hasUpgrade(this.layer,122)?2:0).pow(player.p.buyables[this.id])).div(hasUpgrade(this.layer,224)?(hasUpgrade("p",132)?player.p.gp.plus(1).pow(new Decimal(1).div(2)):hasUpgrade("p",101)?player.p.gp.plus(1).pow(new Decimal(1).div(3)):hasUpgrade("p",93)?player.p.gp.plus(1).pow(0.2):player.p.gp.plus(1).log10()):1)}, - display() { return "Buy a generator for "+format(this.cost)+" points" }, - canAfford() { return (player.points.gte(this.cost)&&hasMilestone(this.layer,5)) }, - buy() { - if (!hasMilestone("p",13))player.points = player.points.sub(this.cost) - setBuyableAmount(this.layer, this.id, getBuyableAmount(this.layer, this.id).add(1)) - player[this.layer].g=player[this.layer].g.plus(1) - }, - unlocked(){return (hasMilestone(this.layer,5))} - }, - 13: { - cost() { return new Decimal(1).times(new Decimal(2).pow(player.p.buyables[this.id])).div(hasUpgrade(this.layer,224)?(hasUpgrade("p",132)?player.p.gp.plus(1).pow(new Decimal(1).div(2)):hasUpgrade("p",101)?player.p.gp.plus(1).pow(new Decimal(1).div(3)):hasUpgrade("p",93)?player.p.gp.plus(1).pow(0.2):player.p.gp.plus(1).log10()):1)}, - display() { return "Buy a generator for "+format(this.cost)+" prestige points" }, - canAfford() { return (player.p.points.gte(this.cost)&&hasUpgrade("p",82)) }, - buy() { - if (!hasMilestone("p",13))player.p.points = player.p.points.sub(this.cost) - setBuyableAmount(this.layer, this.id, getBuyableAmount(this.layer, this.id).add(1)) - player[this.layer].g=player[this.layer].g.plus(1) - }, - unlocked(){return (hasUpgrade(this.layer,82))} - }, - 14: { - cost() { return new Decimal(900).mul(new Decimal(1.01).pow(getBuyableAmount(this.layer,this.id))).round().div(hasUpgrade(this.layer,234)?getBuyableAmount(this.layer,23).pow(0.3).plus(1):1)}, - display() { return "Buy a generator for "+format(this.cost)+" Infinity points" }, - canAfford() { return (player.i.points.gte(this.cost)&&hasUpgrade("p",232)) }, - buy() { - if (!hasMilestone("p",13))player.i.points = player.i.points.sub(this.cost).round() - setBuyableAmount(this.layer, this.id, getBuyableAmount(this.layer, this.id).add(1)) - player[this.layer].g=player[this.layer].g.plus(1) - }, - unlocked(){return (hasUpgrade(this.layer,232))} - }, - 21: { - cost() { return new Decimal(20).plus(getBuyableAmount(this.layer, this.id).pow(new Decimal(2).sub(new Decimal(hasUpgrade(this.layer,221)?0.9:hasUpgrade(this.layer,214)?0.6:0.3).times(hasUpgrade(this.layer,212)?(new Decimal(1).sub(new Decimal(0.75).pow(getBuyableAmount(this.layer,22)))):0))))}, - display() { return "Reset your generators for +1 pointy point! Cost: "+format(this.cost)+" Generators" }, - canAfford() { return (player.p.g.gte(this.cost)&&hasUpgrade("p",104)) }, - buy() { - if (!hasMilestone("i",1))player.p.g = new Decimal(0) - setBuyableAmount(this.layer, this.id, getBuyableAmount(this.layer, this.id).add(1)) - if (!hasMilestone("i",1))setBuyableAmount(this.layer,12, new Decimal(0)) - if (!hasMilestone("i",1))setBuyableAmount(this.layer,13, new Decimal(0)) - if (!hasMilestone("i",1))player.p.gp=new Decimal(0) - }, - unlocked(){return (hasUpgrade(this.layer,104))} - }, - 22: { - cost() { return new Decimal(8).plus(getBuyableAmount(this.layer,this.id))}, - display() { return "Gain a pointy prestige point. Cost: "+format(this.cost)+" Pointy Points" }, - canAfford() { return (getBuyableAmount(this.layer,21).gte(this.cost)&&(hasMilestone("i",5))) }, - buy() { - if (!hasUpgrade(this.layer,233))setBuyableAmount(this.layer,21, getBuyableAmount(this.layer,21).sub(this.cost)) - setBuyableAmount(this.layer, this.id, getBuyableAmount(this.layer, this.id).add(1)) - }, - unlocked(){return (hasMilestone("i",5))} - }, - 23: { - cost() { return new Decimal(124).plus(getBuyableAmount(this.layer,this.id).times(2).pow(2))}, - display() { return "Gain a booster. Cost: "+format(this.cost)+" Pointy Points" }, - canAfford() { return (getBuyableAmount(this.layer,21).gte(this.cost)&&(hasMilestone("i",5))) }, - buy() { - if (!hasMilestone(this.layer,15))setBuyableAmount(this.layer,21, getBuyableAmount(this.layer,21).sub(this.cost)) - setBuyableAmount(this.layer, this.id, getBuyableAmount(this.layer, this.id).add(1)) - if (!hasMilestone(this.layer,15)){ - if (!hasMilestone(this.layer,12)){player.p.upgrades=player.p.upgrades.filter((x)=>{return (x<200||x>230)}) - if (hasMilestone(this.layer,11)){player.p.upgrades.push(215);player.p.upgrades.push(225);player.p.upgrades.push(223);player.p.upgrades.push(222)}} - setBuyableAmount("p",21,new Decimal(0)) - setBuyableAmount("p",22,new Decimal(0)) - if (!hasUpgrade("p",233)){ - setBuyableAmount("p",12,new Decimal(0)) - setBuyableAmount("p",13,new Decimal(0)) - setBuyableAmount("p",14,new Decimal(0)) - - player.p.g = new Decimal(0)} - player.p.gp=new Decimal(0)} - }, - unlocked(){return (hasUpgrade("p",225)||getBuyableAmount("p",23).gt(0))} - }, - 31: { - cost() { return new Decimal(1e93).times(new Decimal(1.5).pow(getBuyableAmount(this.layer,this.id))).times(new Decimal(1.1).pow(getBuyableAmount(this.layer,this.id).pow(2)))}, - effect(){return new Decimal(2).plus(layers.p.buyables[33].effect).pow(getBuyableAmount(this.layer,this.id).plus(layers.p.buyables[51].effect))}, - display() { return "Double point gain. \nCurrently: x"+format(this.effect)+"\nCost: "+format(this.cost)+" Prestige points" }, - canAfford() { return (player.p.points.gte(this.cost)&&(hasMilestone("p",13))) }, - buy() { - player.p.points=player.p.points.sub(this.cost) - setBuyableAmount(this.layer, this.id, getBuyableAmount(this.layer, this.id).add(1)) - }, - unlocked(){return (hasMilestone("p",13))} - }, - 32: { - cost() { return new Decimal(1e95).times(new Decimal(2).pow(getBuyableAmount(this.layer,this.id))).times(new Decimal(1.01).pow(getBuyableAmount(this.layer,this.id).pow(2)))}, - display() { return "Double prestige point gain. \nCurrently: x"+format(new Decimal(2).plus(layers.p.buyables[33].effect).pow(getBuyableAmount(this.layer,this.id)))+"\nCost: "+format(this.cost)+" Prestige points" }, - canAfford() { return (player.p.points.gte(this.cost)&&(hasMilestone("p",13))) }, - buy() { - player.p.points=player.p.points.sub(this.cost) - setBuyableAmount(this.layer, this.id, getBuyableAmount(this.layer, this.id).add(1)) - }, - unlocked(){return (hasMilestone("p",13)&&getBuyableAmount(this.layer,31).gte(5))} - }, - 33: { - cost() { return new Decimal(1e100).times(new Decimal(10).pow(getBuyableAmount(this.layer,this.id))).times(new Decimal(1.01).pow(getBuyableAmount(this.layer,this.id).pow(2)))}, - effect(){return new Decimal(0.01).mul(getBuyableAmount(this.layer,this.id)).times(layers.p.buyables[43].effect)}, - display() { return "Add 0.01 to the previous 2 buyable bases. \nCurrently: +"+format(this.effect)+"\nCost: "+format(this.cost)+" Prestige points" }, - canAfford() { return (player.p.points.gte(this.cost)&&(hasMilestone("p",13))) }, - buy() { - player.p.points=player.p.points.sub(this.cost) - setBuyableAmount(this.layer, this.id, getBuyableAmount(this.layer, this.id).add(1)) - }, - unlocked(){return (hasMilestone("p",13)&&(getBuyableAmount(this.layer,this.id).gt(0)||player.p.points.gte(1e100)))} - }, - 41: { - cost() { return new Decimal(1e110).times(new Decimal(10).pow(getBuyableAmount(this.layer,this.id))).times(new Decimal(10).pow(getBuyableAmount(this.layer,this.id).pow(2)))}, - effect(){return new Decimal(0.01).mul(getBuyableAmount(this.layer,this.id).plus(layers.p.buyables[51].effect))}, - display() { return "Add 0.01 to the booster effect base. \nCurrently: +"+format(this.effect)+"\nCost: "+format(this.cost)+" Prestige points" }, - canAfford() { return (player.p.points.gte(this.cost)&&(hasMilestone("p",13))) }, - buy() { - player.p.points=player.p.points.sub(this.cost) - setBuyableAmount(this.layer, this.id, getBuyableAmount(this.layer, this.id).add(1)) - }, - unlocked(){return (hasMilestone("p",13)&&(getBuyableAmount(this.layer,this.id).gt(0)||player.p.points.gte(1e110)))} - }, - 42: { - cost() { let c = new Decimal(1e270).times(new Decimal(2).pow(getBuyableAmount(this.layer,this.id))).times(new Decimal(1.01).pow(getBuyableAmount(this.layer,this.id).pow(2))) - - return c - }, - effect(){ - let f= new Decimal(1.001).pow(getBuyableAmount(this.layer,this.id)) - if (f.gte(1.1))f=f.pow(0.8).times(new Decimal(1.1).pow(0.2)) - if (f.gte(1.35))f=f.pow(0.5).times(new Decimal(1.35).pow(0.5)) - if (f.gte(3))f=new Decimal(3) - return f - }, - display() { return "Raise point gain to the 1.001 \nCurrently: ^"+format(this.effect)+(this.effect.eq(3)?"(hardcapped)":"")+"\nCost: "+format(this.cost)+" Prestige points" }, - canAfford() { return (player.p.points.gte(this.cost)&&(hasMilestone("p",13)))&&this.effect.lt(3) }, - buy() { - player.p.points=player.p.points.sub(this.cost) - setBuyableAmount(this.layer, this.id, getBuyableAmount(this.layer, this.id).add(1)) - }, - unlocked(){return (hasMilestone("p",13)&&(getBuyableAmount(this.layer,this.id).gt(0)||player.p.points.gte(1e270)))} - }, - 43: { - cost() { return new Decimal("1e375").times(new Decimal(10).pow(getBuyableAmount(this.layer,this.id))).times(new Decimal(10).pow(getBuyableAmount(this.layer,this.id).pow(2)))}, - effect(){return new Decimal(0.01).mul(getBuyableAmount(this.layer,this.id)).plus(1)}, - display() { return "Multiply the above buyable effect. \nCurrently: *"+format(this.effect)+"\nCost: "+format(this.cost)+" Prestige points" }, - canAfford() { return (player.p.points.gte(this.cost)&&(hasMilestone("p",13))) }, - buy() { - player.p.points=player.p.points.sub(this.cost) - setBuyableAmount(this.layer, this.id, getBuyableAmount(this.layer, this.id).add(1)) - }, - unlocked(){return (hasMilestone("p",13)&&(getBuyableAmount(this.layer,this.id).gt(0)||player.p.points.gte("1e375")))} - }, - 51: { - cost() { return new Decimal("1e1740").times(new Decimal(10).pow(getBuyableAmount(this.layer,this.id))).times(new Decimal(1e10).pow(getBuyableAmount(this.layer,this.id).pow(2)))}, - effect(){return getBuyableAmount(this.layer,this.id).pow(0.55)}, - display() { return "Add free levels to the above 2 buyables \nCurrently: "+format(this.effect)+"\nCost: "+format(this.cost)+" Prestige points" }, - canAfford() { return (player.p.points.gte(this.cost)&&(hasMilestone("p",13))) }, - buy() { - player.p.points=player.p.points.sub(this.cost) - setBuyableAmount(this.layer, this.id, getBuyableAmount(this.layer, this.id).add(1)) - }, - unlocked(){return (hasMilestone("p",15)&&(getBuyableAmount(this.layer,this.id).gt(0)||player.p.points.gte("1e1700")))} - }, - }, - milestones: { - 0: { - requirementDisplay: "1 reset", - effectDisplay: "Add 0.01 to base point gain and prestige requirement, and 1 doesn't reset upgrades", - done() { return getBuyableAmount("p",11).gte(1) }, - unlocked(){return layers.p.activeSubtab!="Pointy points"} - }, - 1: { - requirementDisplay: "2 resets", - effectDisplay: "
2 and 3 don't reset upgrades, and start with the first 8 upgrades on reset
", - done() { return getBuyableAmount("p",11).gte(2) }, - unlocked(){return hasMilestone(this.layer,this.id-1)&&layers.p.activeSubtab!="Pointy points"} - }, - 2: { - requirementDisplay: "3 resets", - effectDisplay: "
4 doesn't reset upgrades, and permanently fix the bug where you can't buy upgrades when you have 1 prestige point
", - done() { return getBuyableAmount("p",11).gte(3) }, - unlocked(){return hasMilestone(this.layer,this.id-1)&&layers.p.activeSubtab!="Pointy points"} - }, - 3: { - requirementDisplay: "4 resets", - effectDisplay: "Don't reset challenges, add 1 to Point maximum completions, and start with 24 upgrades", - done() { return getBuyableAmount("p",11).gte(4) }, - unlocked(){return hasMilestone(this.layer,this.id-1)&&layers.p.activeSubtab!="Pointy points"} - }, - 4: { - requirementDisplay: "5 resets", - effectDisplay: "Each useless upgrade adds 0.1 to base point gain", - done() { return getBuyableAmount("p",11).gte(5) }, - unlocked(){return hasMilestone(this.layer,this.id-1)&&layers.p.activeSubtab!="Pointy points"} - }, - 5: { - requirementDisplay: "6 resets", - effectDisplay: "Unlock something", - done() { return getBuyableAmount("p",11).gte(6) }, - unlocked(){return hasMilestone(this.layer,this.id-1)&&layers.p.activeSubtab!="Pointy points"} - }, - 6: { - requirementDisplay: "1 pointy point", - effectDisplay: "Unlock the upgrade tree", - done() { return getBuyableAmount("p",21).gte(1) }, - unlocked(){return hasMilestone(this.layer,this.id-1)&&(hasUpgrade(this.layer,104)||player.i.unlocked)&&layers.p.activeSubtab!="Pointy points"} - }, - 7: { - requirementDisplay: "7 pointy points", - effectDisplay: "You can now buy both first and second row upgrade tree upgrades", - done() { return getBuyableAmount("p",21).gte(7) }, - unlocked(){return hasMilestone(this.layer,this.id-1)&&(hasUpgrade(this.layer,111)||player.i.unlocked)&&layers.p.activeSubtab!="Pointy points"} - }, - 8: { - requirementDisplay: "8 pointy points", - effectDisplay: "Unlock another layer", - done() { return getBuyableAmount("p",21).gte(8) }, - unlocked(){return hasMilestone(this.layer,this.id-1)&&(hasUpgrade(this.layer,141)||hasUpgrade(this.layer,143)||hasUpgrade(this.layer,142)||player.i.unlocked)&&layers.p.activeSubtab!="Pointy points"} - }, - 11: { - requirementDisplay: "3 boosters", - effectDisplay: "Keep automation on booster reset", - done() { return getBuyableAmount("p",23).gte(3) }, - unlocked(){return (getBuyableAmount("p",23).gt(0)||hasMilestone(this.layer,this.id))} - }, - 12: { - requirementDisplay: "5 boosters", - effectDisplay: "Keep all prestige upgrades on booster reset and buy max infinity points", - done() { return getBuyableAmount("p",23).gte(5) }, - unlocked(){return (getBuyableAmount("p",23).gt(0)||hasMilestone(this.layer,this.id))} - }, - 13: { - requirementDisplay: "10 boosters", - effectDisplay: "Generators cost nothing", - done() { return getBuyableAmount("p",23).gte(10) }, - unlocked(){return (getBuyableAmount("p",23).gt(0)||hasMilestone(this.layer,this.id))} - }, - 14: { - requirementDisplay: "15 boosters", - effectDisplay: "Auto buy the first 3 buyables and buy max pointy prestige points", - done() { return getBuyableAmount("p",23).gte(15) }, - unlocked(){return (getBuyableAmount("p",41).gt(0)||hasMilestone(this.layer,this.id))} - }, - 15: { - requirementDisplay: "20 boosters", - effectDisplay: "Boosters reset nothing and auto booster", - done() { return getBuyableAmount("p",23).gte(16) }, - unlocked(){return (getBuyableAmount("p",41).gt(0)||hasMilestone(this.layer,this.id))} - }, - }, - passiveGeneration(){return (hasUpgrade("i",11)?1:0)}, - update(diff){ - if (hasMilestone(this.layer,2)&&!hasUpgrade(this.layer,54)){ - player[this.layer].upgrades.push(54) - } - if (hasMilestone(this.layer,1)&&!hasUpgrade(this.layer,11)&&!hasMilestone(this.layer,3)){ - player[this.layer].upgrades=[11,12,13,14,21,22,23,24] - } - if (hasMilestone(this.layer,3)&&!hasUpgrade(this.layer,31)){ - player[this.layer].upgrades=[11,12,13,14,21,22,23,24,31,32,33,34,41,42,43,44,51,52,53,54,61,62,63,64] - } - if (hasMilestone(this.layer,5)){ - player[this.layer].gp=player[this.layer].gp.plus(player.p.g.times(diff).times(player.p.geff)) - } - let geff=new Decimal(1) - if (hasUpgrade("p",81)) geff=geff.plus(2) - if (hasUpgrade("p",102)) geff=geff.plus(hasChallenge("p",22)?player.p.gp.plus(1).log(10):player.p.gp.plus(1).log(10).plus(1).log(10)) - if (hasUpgrade("p",83)) geff=geff.times(player.p.points.plus(1).log(10).plus(1)) - if (hasUpgrade("p",94)) geff=geff.times(player.p.cmult) - if (hasUpgrade("p",104)) geff=geff.times(new Decimal(player.p.buyables[21]).plus(1)) - if (hasUpgrade("p",143)) geff=geff.times(new Decimal(player.timePlayed).div(3600).max(1)) - if (hasUpgrade("p",225)) geff=geff.pow(new Decimal(player.p.buyables[23]).div(10).mul(new Decimal(0.1).plus(layers.p.buyables[41].effect).times(10)).plus(1)) - player.p.geff=geff - if (hasChallenge("p",22)&&(!hasUpgrade("p",141)||hasUpgrade("i",12)))player.p.cmult=player.p.cmult.plus(hasUpgrade("p",141)?1:0.01) - if (!hasUpgrade("p",111)) player.p.cmult=player.p.cmult.min(100) - if (hasMilestone(this.layer,14)){ - if (layers.p.buyables[31].canAfford())layers.p.buyables[31].buy() - if (layers.p.buyables[32].canAfford())layers.p.buyables[32].buy() - if (layers.p.buyables[33].canAfford())layers.p.buyables[33].buy() - } - if (hasMilestone(this.layer,15)){ - if (layers.p.buyables[23].canAfford())layers.p.buyables[23].buy() - } - }, - subtabs: { - "Upgrades": { - display: ` - - - - - - ` - }, - "Challenges": { - unlocked() { return hasUpgrade("p", 51) || hasMilestone("p", 0); }, - display: ` - - - ` - }, - "Buyables and Milestones": { - unlocked(){return hasUpgrade("p",74)||hasMilestone("p",0)}, - display: ` - - - - -
Your boosts are making the point challenge {{ getBuyableAmount('p', 11).plus(1) }}x less pointy
- - ` - }, - "Generators": { - unlocked(){return hasMilestone("p",5)||player.i.points.gte(1)}, - display: ` - -
You have {{ format(player.p.gp) }} generator points, adding {{ format(hasUpgrade("p",132)?player.p.gp.plus(1).pow(new Decimal(1).div(2)):hasUpgrade("p",101)?player.p.gp.plus(1).pow(new Decimal(1).div(3)):hasUpgrade("p",93)?player.p.gp.plus(1).pow(0.2):player.p.gp.plus(1).log10()) }} to point gain
-
You have {{ format(player.p.g) }} generators, generating {{ format(player.p.g.times(player.p.geff)) }} generator points per second
-
Generator efficiency is {{ format(player.p.geff) }}
- - - - ` - }, - "Pointy Points": { - unlocked(){return hasUpgrade("p",104)||player.i.points.gte(1)}, - display: ` -
{{ format(player.p.buyables[21]) }} pointy points
-
My pointy points are multiplying generator efficiency by {{ format(new Decimal(player.p.buyables[21]).plus(1)) }}
- - - -
I have {{ format(player.p.buyables[22]) }} pointy prestige points
- - - - -
I have {{ format(player.p.buyables[23]) }} pointy boosters!
- -
My pointy boosters are raising generator efficiency to the ^{{ format(new Decimal(player.p.buyables[23]).div(10).mul(new Decimal(0.1).plus(layers.p.buyables[41].effect).times(10)).plus(1)) }}
- - -
Booster upgrades
- ` - }, - "Buyables": { - unlocked(){return hasMilestone("p",13)}, - display: ` - - ` - } - } -} \ No newline at end of file diff --git a/src/data/layers/demo.ts b/src/data/layers/demo.ts new file mode 100644 index 0000000..329ac6f --- /dev/null +++ b/src/data/layers/demo.ts @@ -0,0 +1,2301 @@ +/* eslint-disable */ +import { layers } from "@/game/layers"; +import player from "@/game/player"; +import { DecimalSource } from "@/lib/break_eternity"; +import { RawLayer } from "@/typings/layer"; +import Decimal, { format } from "@/util/bignum"; +import { + getBuyableAmount, hasChallenge, hasMilestone, hasUpgrade, setBuyableAmount +} from "@/util/features"; +import { resetLayer } from "@/util/layers"; + +export default { + id: "p", + position: 2, + startData() { + return { + unlocked: true, + points: new Decimal(0), + gp: new Decimal(0), + g: new Decimal(0), + geff: new Decimal(1), + cmult: new Decimal(1) + }; + }, + color: "#4BDC13", + requires() { + let require = new Decimal(68.99); + if (hasMilestone(this.layer, 0)) require = require.plus(0.01); + if (hasUpgrade(this.layer, 21)) + require = require.tetrate( + hasUpgrade("p", 34) + ? new Decimal(1) + .div( + new Decimal(1).plus( + layers.p.upgrades!.data[34].effect as Decimal + ) + ) + .toNumber() + : 1 + ); + if (hasUpgrade(this.layer, 22)) + require = require.pow( + hasUpgrade("p", 34) + ? new Decimal(1).div( + new Decimal(1).plus(layers.p.upgrades!.data[34].effect as Decimal) + ) + : 1 + ); + if (hasUpgrade(this.layer, 23)) + require = require.div( + hasUpgrade("p", 34) + ? new Decimal(1).plus(layers.p.upgrades!.data[34].effect as Decimal) + : 1 + ); + if (hasUpgrade(this.layer, 24)) + require = require.sub( + hasUpgrade("p", 34) + ? new Decimal(1).plus(layers.p.upgrades!.data[34].effect as Decimal) + : 1 + ); + return require.max(1); + }, + resource: "prestige points", + baseResource: "points", + baseAmount() { + return player.points; + }, // Get the current amount of baseResource + type: "normal", // normal: cost to gain currency depends on amount gained. static: cost depends on how much you already have + exponent: 0.5, // Prestige currency exponent + gainMult() { + // Calculate the multiplier for main currency from bonuses + let mult = new Decimal(1); + if (hasUpgrade(this.layer, 131)) mult = mult.times(10); + if (player.layers.i.unlocked) + mult = mult.times( + player.layers.i.points.plus(1).pow(hasUpgrade("p", 235) ? 6.942 : 1) + ); + if (hasUpgrade(this.layer, 222)) + mult = mult.times(getBuyableAmount(this.layer, 22)!.plus(1)); + if (hasUpgrade("p", 231)) { + const asdf = hasUpgrade("p", 132) + ? (player.layers.p.gp as Decimal).plus(1).pow(new Decimal(1).div(2)) + : hasUpgrade("p", 101) + ? (player.layers.p.gp as Decimal).plus(1).pow(new Decimal(1).div(3)) + : hasUpgrade("p", 93) + ? (player.layers.p.gp as Decimal).plus(1).pow(0.2) + : (player.layers.p.gp as Decimal).plus(1).log10(); + mult = mult.mul(asdf.plus(1)); + } + if (hasMilestone(this.layer, 13)) + mult = mult.mul( + new Decimal(2) + .plus(layers.p.buyables!.data[33].effect as Decimal) + .pow(getBuyableAmount(this.layer, 32)!) + ); + return mult; + }, + gainExp() { + // Calculate the exponent on main currency from bonuses + return new Decimal(1); + }, + row: 0, // Row the layer is in on the tree (0 is the first row) + hotkeys: [ + { + key: "p", + description: "P: Reset for prestige points", + press() { + if (layers.p.canReset) resetLayer(this.layer); + } + } + ], + layerShown() { + return true; + }, + upgrades: { + rows: 999, + cols: 5, + data: { + 11: { + title: "Gain points", + description: "Point generation is increased by 1", + cost() { + if (hasMilestone(this.layer, 2)) return new Decimal(1); + return new Decimal(1.00001); + }, + unlocked() { + return true; + } + }, + 12: { + title: "Gain more points", + description: "Point generation is singled", + cost() { + return new Decimal(1); + }, + unlocked() { + return hasUpgrade(this.layer, 11); + } + }, + 13: { + title: "Gain more points", + description: "Point generation is lined", + cost() { + return new Decimal(1); + }, + unlocked() { + return hasUpgrade(this.layer, 12); + } + }, + 14: { + title: "Gain more points", + description: "Point generation is tetrated by 1", + cost() { + return new Decimal(1); + }, + unlocked() { + return hasUpgrade(this.layer, 13); + } + }, + 21: { + title: "Lower prestige requirement", + description: "Prestige point requirement is superrooted by 1", + cost() { + return new Decimal(1); + }, + unlocked() { + return hasUpgrade(this.layer, 14); + } + }, + 22: { + title: "Lower prestige requirement more", + description: "Prestige point requirement is line rooted", + cost() { + return new Decimal(1); + }, + unlocked() { + return hasUpgrade(this.layer, 21); + } + }, + 23: { + title: "Lower prestige requirement more", + description: "Prestige point requirement is wholed", + cost() { + return new Decimal(1); + }, + unlocked() { + return hasUpgrade(this.layer, 22); + } + }, + 24: { + title: "Lower prestige requirement more", + description: "Prestige point requirement is decreased by 1", + cost() { + return new Decimal(1); + }, + unlocked() { + return hasUpgrade(this.layer, 23); + } + }, + 31: { + title: "Unlock", + description: "Unlock an upgrade", + cost() { + return new Decimal(1); + }, + unlocked() { + return hasUpgrade(this.layer, 24); + } + }, + 32: { + title: "An", + description: "Unlock an upgrade", + cost() { + return new Decimal(1); + }, + unlocked() { + return hasUpgrade(this.layer, 31); + } + }, + 33: { + title: "Upgrade", + description: "Unlock an upgrade", + cost() { + return new Decimal(1); + }, + unlocked() { + return hasUpgrade(this.layer, 32); + } + }, + 34: { + title: "Increase", + description() { + return ( + "Add 0.01 to all above upgrades. Currently: +" + + format(this.effect as Decimal) + ); + }, + cost() { + return new Decimal(1); + }, + unlocked() { + return hasUpgrade(this.layer, 33); + }, + effect() { + let r = hasUpgrade("p", 41) + ? new Decimal(0.01).times(layers.p.upgrades!.data[41].effect as Decimal) + : new Decimal(0.01); + r = r.times( + new Decimal(1).plus( + new Decimal(player.layers[this.layer].challenges![11]) + .add(1) + .pow(hasUpgrade(this.layer, 121) ? 1.2 : 1) + ) + ); + if (hasUpgrade(this.layer, 92)) + r = r.plus( + new Decimal(0.001) + .times((player.layers[this.layer].g as Decimal).plus(1)) + .min(0.05) + ); + return r; + } + }, + 41: { + title: "Increase again", + description() { + return ( + "Multiply the previous upgrade by 1.01. Currently: x" + + format(this.effect as Decimal) + ); + }, + cost() { + return new Decimal(1); + }, + unlocked() { + return hasUpgrade(this.layer, 34); + }, + effect() { + return new Decimal(1.01) + .pow(hasUpgrade("p", 42) ? layers.p.upgrades!.data[42].effect as Decimal : 1) + .times(hasUpgrade("p", 63) ? 2 : 1); + } + }, + 42: { + title: "Increase again", + description() { + return ( + "Exponentiate the previous upgrade by 1.01. Currently: ^" + + format(this.effect as Decimal) + ); + }, + cost() { + return new Decimal(1); + }, + unlocked() { + return hasUpgrade(this.layer, 41); + }, + effect() { + return new Decimal(1.01) + .tetrate(hasUpgrade("p", 43) ? (layers.p.upgrades!.data[43].effect as Decimal).toNumber() : 1) + .times(hasUpgrade("p", 63) ? 2 : 1) + .times(hasUpgrade("p", 64) ? 2 : 1); + } + }, + 43: { + title: "Increase again", + description() { + return ( + "Tetrate the previous upgrade by 1.01. Currently: ^^" + + format(this.effect as Decimal) + ); + }, + cost() { + return new Decimal(1); + }, + unlocked() { + return hasUpgrade(this.layer, 42); + }, + effect() { + return new Decimal(1.01) + .pentate(hasUpgrade("p", 44) ? (layers.p.upgrades!.data[44].effect as Decimal).toNumber() : 1) + .times(hasUpgrade("p", 63) ? 2 : 1) + .times(hasUpgrade("p", 64) ? 2 : 1); + } + }, + 44: { + title: "Increase again", + description() { + return ( + "Pentate the previous upgrade by 1.01. Currently: ^^^" + + format(this.effect as Decimal) + ); + }, + cost() { + return new Decimal(1); + }, + unlocked() { + return hasUpgrade(this.layer, 43); + }, + effect() { + return new Decimal(1.01) + .times(hasUpgrade("p", 63) ? 2 : 1) + .times(hasUpgrade("p", 64) ? 2 : 1); + } + }, + 51: { + title: "Challenging", + description: "This upgrade doesn't unlock a challenge", + cost() { + return new Decimal(1); + }, + unlocked() { + return hasUpgrade(this.layer, 44); + } + }, + 52: { + title: "Not challenging", + description: "This upgrade doesn't add 1 to the completion limit", + cost() { + return new Decimal(1); + }, + unlocked() { + return hasUpgrade(this.layer, 51); + } + }, + 53: { + title: "Not not challenging", + description: "This upgrade doesn't add 1 to the completion limit", + cost() { + return new Decimal(1); + }, + unlocked() { + return hasUpgrade(this.layer, 52); + } + }, + 54: { + title: "(not^3) challenging", + description: + "Fix the bug where you can't buy upgrades when you have 1 prestige point", + cost() { + return new Decimal(0.99999); + }, + unlocked() { + return hasUpgrade(this.layer, 53); + }, + onPurchase() { + player.layers.p.points = player.layers.p.points.round(); + } + }, + 61: { + title: "(not^4) challenging", + description: "Doesn't unlock a second challenge", + cost() { + return new Decimal(1); + }, + unlocked() { + return hasUpgrade(this.layer, 54) && hasUpgrade(this.layer, 53); + } + }, + 62: { + title: "Infinity points", + description: "You can now complete Time Dilation 4 more times", + cost() { + return new Decimal(1); + }, + unlocked() { + return hasUpgrade(this.layer, 61); + } + }, + 63: { + title: "Eternity points", + description: "Double all fourth row upgrade effects", + cost() { + return new Decimal(1); + }, + unlocked() { + return hasUpgrade(this.layer, 62); + } + }, + 64: { + title: "Reality points", + description: "Previous upgrade, but only to the last 3 upgrades", + cost() { + return new Decimal(1); + }, + unlocked() { + return hasUpgrade(this.layer, 63); + } + }, + 71: { + title: "1", + description: "Add 1.1 to point gain, but reset all above upgrades", + cost() { + return new Decimal(1); + }, + unlocked() { + return hasUpgrade(this.layer, 64); + }, + onPurchase() { + if (!hasMilestone(this.layer, 0)) + player.layers[this.layer].upgrades = [71]; + } + }, + 72: { + title: "2", + description: "Multiply point gain by 1.1, but reset all above upgrades", + cost() { + return new Decimal(2); + }, + unlocked() { + return ( + hasUpgrade(this.layer, 64) && + hasUpgrade(this.layer, Number(this.id) - 1) + ); + }, + onPurchase() { + if (!hasMilestone(this.layer, 1)) + player.layers[this.layer].upgrades = [71, 72]; + } + }, + 73: { + title: "3", + description: "Raise point gain by ^1.1, but reset all above upgrades", + cost() { + return new Decimal(4); + }, + unlocked() { + return ( + hasUpgrade(this.layer, 64) && + hasUpgrade(this.layer, Number(this.id) - 1) + ); + }, + onPurchase() { + if (!hasMilestone(this.layer, 1)) + player.layers[this.layer].upgrades = [71, 72, 73]; + } + }, + 74: { + title: "4", + description: "Tetrate point gain by 1.1, but reset all above upgrades", + cost() { + return new Decimal(8); + }, + unlocked() { + return ( + hasUpgrade(this.layer, 64) && + hasUpgrade(this.layer, Number(this.id) - 1) + ); + }, + onPurchase() { + if (!hasMilestone(this.layer, 2)) + player.layers[this.layer].upgrades = [71, 72, 73, 74]; + if (hasMilestone(this.layer, 1) && !hasMilestone(this.layer, 2)) { + player.layers[this.layer].upgrades = [ + 11, + 12, + 13, + 14, + 21, + 22, + 23, + 24, + 71, + 72, + 73, + 74 + ]; + } + } + }, + 81: { + title: "5", + description: "Generator efficiency is increased by 2", + cost() { + return new Decimal(1); + }, + unlocked() { + return ( + hasUpgrade(this.layer, 74) && + (player.layers[this.layer].buyables![12].gt(0) || + player.layers[this.layer].buyables![21].gt(0)) + ); + } + }, + 82: { + title: "6", + description: "Unlock another way to buy generators", + cost() { + return new Decimal(1); + }, + unlocked() { + return ( + hasUpgrade(this.layer, 81) && + (player.layers[this.layer].buyables![12].gt(0) || + player.layers[this.layer].buyables![21].gt(0)) + ); + } + }, + 83: { + title: "7", + description: "Generator efficiency is boosted by prestige points", + cost() { + return new Decimal(3); + }, + unlocked() { + return hasUpgrade(this.layer, 82); + } + }, + 84: { + title: "8", + description: "You can complete Point one more time", + cost() { + return new Decimal(3); + }, + unlocked() { + return hasUpgrade(this.layer, 83); + } + }, + 91: { + title: "9", + description: "New Challenge Time", + cost() { + return new Decimal(20); + }, + unlocked() { + return ( + hasUpgrade(this.layer, 84) && + new Decimal(player.layers[this.layer].challenges![12]).gte(3) + ); + } + }, + 92: { + title: "10", + description: + "Each of the first 50 generators adds 0.001 to Increase", + cost() { + return new Decimal(5); + }, + unlocked() { + return hasUpgrade(this.layer, 91) && hasChallenge(this.layer, 21); + } + }, + 93: { + title: "11", + description: + "Change the tree trunk in generator effect to a hypertessaract root", + cost() { + return new Decimal(7); + }, + unlocked() { + return hasUpgrade(this.layer, 92); + } + }, + 94: { + title: "12", + description: "Unlock a clickable in generators", + cost() { + return new Decimal(50); + }, + unlocked() { + return hasUpgrade(this.layer, 93); + } + }, + 101: { + title: "10th row????", + description: "Decrease the dimensions of 11 by 2", + cost() { + return new Decimal(10); + }, + unlocked() { + return hasUpgrade(this.layer, 94); + } + }, + 102: { + title: "2 Tree Trunks", + description: + "Double log of generator points adds to generator efficiency", + cost() { + return new Decimal(25); + }, + unlocked() { + return hasUpgrade(this.layer, 101); + } + }, + 103: { + title: "(not^5) challenging", + description: "Unlock the last challenge", + cost() { + return new Decimal(103); + }, + unlocked() { + return hasUpgrade(this.layer, 102); + } + }, + 104: { + title: "2 layers tree", + description: "Prestige points boost points, and unlock another tab", + cost() { + return new Decimal(100); + }, + unlocked() { + return hasUpgrade(this.layer, 103) && hasChallenge(this.layer, 22); + } + }, + 111: { + title: "not (hardcapped)", + description: + "Remove the generator clickable hardcap, and you can only pick one upgrade on each row below this", + cost() { + return new Decimal(110); + }, + unlocked() { + return hasUpgrade(this.layer, 104) && hasMilestone(this.layer, 6); + } + }, + 112: { + title: "Respec button", + description: "Respec all lower upgrades, but you don't get points back", + cost() { + return new Decimal(100); + }, + unlocked() { + return ( + hasUpgrade(this.layer, 111) && + (hasUpgrade(this.layer, 121) || hasUpgrade(this.layer, 122)) && + !hasMilestone("i", 4) + ); + }, + onPurchase() { + player.layers.p.upgrades = player.layers.p.upgrades!.filter((i: string | number) => { + return Number(i) < 112; + }); + } + }, + 121: { + title: "Timers", + description: "Raise the Time Dilation reward effect to the 1.2", + cost() { + return new Decimal(500); + }, + unlocked() { + return ( + hasUpgrade(this.layer, 111) && + (!hasUpgrade(this.layer, 122) || hasMilestone(this.layer, 7)) + ); + } + }, + 122: { + title: "Generators", + description: + "Decrease the first generator buyable cost scaling base by 2", + cost() { + return new Decimal(500); + }, + unlocked() { + return ( + hasUpgrade(this.layer, 111) && + (!hasUpgrade(this.layer, 121) || hasMilestone(this.layer, 7)) + ); + } + }, + 131: { + title: "Prestige", + description: "Gain 10x more prestige points", + cost() { + return new Decimal(5000); + }, + unlocked() { + return ( + (hasUpgrade(this.layer, 121) || hasUpgrade(this.layer, 122)) && + (!hasUpgrade(this.layer, 132) || hasMilestone(this.layer, 7)) + ); + } + }, + 132: { + title: "One and a half", + description: "Raise generator effect to the 1.5", + cost() { + return new Decimal(5000); + }, + unlocked() { + return ( + (hasUpgrade(this.layer, 121) || hasUpgrade(this.layer, 122)) && + (!hasUpgrade(this.layer, 131) || hasMilestone(this.layer, 7)) + ); + } + }, + + 141: { + title: "Active", + description: + "Multiply generator efficiency now increases by 1, but it doesn't automatically click.", + cost() { + return new Decimal(50000); + }, + unlocked() { + return ( + (hasUpgrade(this.layer, 131) || hasUpgrade(this.layer, 132)) && + ((!hasUpgrade(this.layer, 142) && !hasUpgrade(this.layer, 143)) || + hasMilestone("i", 4)) + ); + } + }, + 142: { + title: "Passive", + description: "Gain 5x more points", + cost() { + return new Decimal(50000); + }, + unlocked() { + return ( + (hasUpgrade(this.layer, 131) || hasUpgrade(this.layer, 132)) && + ((!hasUpgrade(this.layer, 141) && !hasUpgrade(this.layer, 143)) || + hasMilestone("i", 4)) + ); + } + }, + 143: { + title: "Idle", + description: "Hours played multiply generator power", + cost() { + return new Decimal(50000); + }, + unlocked() { + return ( + (hasUpgrade(this.layer, 131) || hasUpgrade(this.layer, 132)) && + ((!hasUpgrade(this.layer, 142) && !hasUpgrade(this.layer, 141)) || + hasMilestone("i", 4)) + ); + } + }, + 211: { + title: "Prestige", + description: "Pointy points multiply points", + cost() { + return new Decimal(1); + }, + canAfford() { + return getBuyableAmount(this.layer, 22)!.gte(this.cost); + }, + pay() { + setBuyableAmount( + this.layer, + 22, + getBuyableAmount(this.layer, 22)!.sub(this.cost) + ); + }, + unlocked() { + return ( + hasMilestone("i", 5) && player.subtabs.p.mainTabs != "Upgrades" + ); + } + }, + 212: { + title: "Pointy", + description: + "Pointy prestige points reduce the cost scaling of pointy points", + cost() { + return new Decimal(2); + }, + canAfford() { + return getBuyableAmount(this.layer, 22)!.gte(this.cost); + }, + pay() { + setBuyableAmount( + this.layer, + 22, + getBuyableAmount(this.layer, 22)!.sub(this.cost) + ); + }, + unlocked() { + return ( + hasMilestone("i", 5) && + player.subtabs.p.mainTabs != "Upgrades" && + hasUpgrade(this.layer, 211) + ); + } + }, + 213: { + title: "Time", + description: "Generator power also multiplies point gain", + cost() { + return new Decimal(6); + }, + canAfford() { + return getBuyableAmount(this.layer, 22)!.gte(this.cost); + }, + pay() { + setBuyableAmount( + this.layer, + 22, + getBuyableAmount(this.layer, 22)!.sub(this.cost) + ); + }, + unlocked() { + return ( + hasMilestone("i", 5) && + player.subtabs.p.mainTabs != "Upgrades" && + hasUpgrade(this.layer, 212) + ); + } + }, + 214: { + title: "^0", + description: "Further reduce the pointy point scaling", + cost() { + return new Decimal(11); + }, + canAfford() { + return getBuyableAmount(this.layer, 22)!.gte(this.cost); + }, + pay() { + setBuyableAmount( + this.layer, + 22, + getBuyableAmount(this.layer, 22)!.sub(this.cost) + ); + }, + unlocked() { + return ( + hasMilestone("i", 5) && + player.subtabs.p.mainTabs != "Upgrades" && + hasUpgrade(this.layer, 213) + ); + } + }, + 215: { + title: "bulk", + description: "Auto-pointy points now buys 10 per tick", + cost() { + return new Decimal(27); + }, + canAfford() { + return getBuyableAmount(this.layer, 22)!.gte(this.cost); + }, + pay() { + setBuyableAmount( + this.layer, + 22, + getBuyableAmount(this.layer, 22)!.sub(this.cost) + ); + }, + unlocked() { + return ( + hasMilestone("i", 5) && + player.subtabs.p.mainTabs != "Upgrades" && + hasUpgrade(this.layer, 214) + ); + } + }, + 221: { + title: "^-1", + description: "^0 is even more powerful", + cost() { + return new Decimal(28); + }, + canAfford() { + return getBuyableAmount(this.layer, 22)!.gte(this.cost); + }, + pay() { + setBuyableAmount( + this.layer, + 22, + getBuyableAmount(this.layer, 22)!.sub(this.cost) + ); + }, + unlocked() { + return ( + hasMilestone("i", 5) && + player.subtabs.p.mainTabs != "Upgrades" && + hasUpgrade(this.layer, 215) + ); + } + }, + 222: { + title: "???", + description: + "square bulk and pointy prestige points multiply prestige points", + cost() { + return new Decimal(90); + }, + canAfford() { + return getBuyableAmount(this.layer, 22)!.gte(this.cost); + }, + pay() { + setBuyableAmount( + this.layer, + 22, + getBuyableAmount(this.layer, 22)!.sub(this.cost) + ); + }, + unlocked() { + return ( + hasMilestone("i", 5) && + player.subtabs.p.mainTabs != "Upgrades" && + hasUpgrade(this.layer, 221) + ); + } + }, + 223: { + title: "more automation", + description: "Automatically gain pointy prestige points", + cost() { + return new Decimal(96); + }, + canAfford() { + return getBuyableAmount(this.layer, 22)!.gte(this.cost); + }, + pay() { + setBuyableAmount( + this.layer, + 22, + getBuyableAmount(this.layer, 22)!.sub(this.cost) + ); + }, + unlocked() { + return ( + hasMilestone("i", 5) && + player.subtabs.p.mainTabs != "Upgrades" && + hasUpgrade(this.layer, 222) + ); + } + }, + 224: { + title: "Generation", + description: "Generator costs are divided by generator effect", + cost() { + return new Decimal(100); + }, + canAfford() { + return getBuyableAmount(this.layer, 22)!.gte(this.cost); + }, + pay() { + setBuyableAmount( + this.layer, + 22, + getBuyableAmount(this.layer, 22)!.sub(this.cost) + ); + }, + unlocked() { + return ( + hasMilestone("i", 5) && + player.subtabs.p.mainTabs != "Upgrades" && + hasUpgrade(this.layer, 223) + ); + } + }, + 225: { + title: "Boosters", + description: "Unlock boosters (next update)", + cost() { + return new Decimal(135); + }, + canAfford() { + return getBuyableAmount(this.layer, 22)!.gte(this.cost); + }, + pay() { + setBuyableAmount( + this.layer, + 22, + getBuyableAmount(this.layer, 22)!.sub(this.cost) + ); + }, + unlocked() { + return ( + hasMilestone("i", 5) && + player.subtabs.p.mainTabs != "Upgrades" && + hasUpgrade(this.layer, 224) + ); + } + }, + 231: { + title: "Blue", + description: "The generator effect also affects prestige points", + cost() { + return new Decimal(4); + }, + canAfford() { + return getBuyableAmount(this.layer, 23)!.gte(this.cost); + }, + pay() { + setBuyableAmount( + this.layer, + 23, + getBuyableAmount(this.layer, 23)!.sub(this.cost) + ); + }, + unlocked() { + return ( + player.subtabs.p.mainTabs != "Upgrades" && + hasMilestone(this.layer, 11) + ); + }, + currencyDisplayName: "pointy boosters" + }, + 232: { + title: "Red", + description: "Unlock a third way to buy generators", + cost() { + return new Decimal(5); + }, + canAfford() { + return getBuyableAmount(this.layer, 23)!.gte(this.cost); + }, + pay() { + setBuyableAmount( + this.layer, + 23, + getBuyableAmount(this.layer, 23)!.sub(this.cost) + ); + }, + unlocked() { + return ( + player.subtabs.p.mainTabs != "Upgrades" && + hasMilestone(this.layer, 12) + ); + }, + currencyDisplayName: "pointy boosters" + }, + 233: { + title: "Green", + description: + "Prestige points do not reset your pointy points and boosters don't reset generators", + cost() { + return new Decimal(5); + }, + canAfford() { + return getBuyableAmount(this.layer, 23)!.gte(this.cost); + }, + pay() { + setBuyableAmount( + this.layer, + 23, + getBuyableAmount(this.layer, 23)!.sub(this.cost) + ); + }, + unlocked() { + return ( + player.subtabs.p.mainTabs != "Upgrades" && + hasMilestone(this.layer, 12) + ); + }, + currencyDisplayName: "pointy boosters" + }, + 234: { + title: "Yellow", + description: + "Divide the cost of the third generator buyable based on boosters", + cost() { + return new Decimal(6); + }, + canAfford() { + return getBuyableAmount(this.layer, 23)!.gte(this.cost); + }, + pay() { + setBuyableAmount( + this.layer, + 23, + getBuyableAmount(this.layer, 23)!.sub(this.cost) + ); + }, + unlocked() { + return ( + player.subtabs.p.mainTabs != "Upgrades" && + hasMilestone(this.layer, 12) + ); + }, + currencyDisplayName: "pointy boosters" + }, + 235: { + title: "Orange", + description: "Raise the Infinity effect to the 6.9420th power", + cost() { + return new Decimal(8); + }, + canAfford() { + return getBuyableAmount(this.layer, 23)!.gte(this.cost); + }, + pay() { + setBuyableAmount( + this.layer, + 23, + getBuyableAmount(this.layer, 23)!.sub(this.cost) + ); + }, + unlocked() { + return ( + player.subtabs.p.mainTabs != "Upgrades" && + hasMilestone(this.layer, 12) + ); + }, + currencyDisplayName: "pointy boosters" + } + } + }, + + clickables: { + rows: 1, + cols: 1, + data: { + 11: { + display() { + return ( + "Multiply generator efficiency by " + + format(player.layers.p.cmult as Decimal) + + ((player.layers.p.cmult as Decimal).min(100).eq(100) && !hasUpgrade(this.layer, 111) + ? " (hardcapped)" + : "") + ); + }, + unlocked() { + return hasUpgrade("p", 94); + }, + click() { + player.layers.p.cmult = (player.layers.p.cmult as Decimal).plus(hasUpgrade("p", 141) ? 1 : 0.01); + if (!hasUpgrade(this.layer, 111)) + player.layers.p.cmult = (player.layers.p.cmult as Decimal).min(100); + }, + canClick() { + return (player.layers.p.cmult as Decimal).lt(100) || hasUpgrade(this.layer, 111); + } + } + } + }, + + challenges: { + rows: 99, + cols: 2, + data: { + 11: { + name: "Time dilation", + challengeDescription() { + return "Point gain exponent is raised to the ^0.75"; + }, + goal() { + return new Decimal(100).times( + new Decimal(10).pow( + new Decimal(player.layers[this.layer].challenges![this.id]) + .times( + new Decimal(1).sub( + new Decimal( + layers[this.layer].challenges!.data[12].effect as number + ).div(100) + ) + ) + .pow(2) + ) + ); + }, + rewardDescription() { + return ( + "You have completed this challenge " + + player.layers[this.layer].challenges![this.id] + + "/" + + this.completionLimit + + " times. Multiply Increase's effect by challenge completions+1. Currently: x" + + format( + new Decimal(player.layers[this.layer].challenges![this.id]) + .add(1) + .pow(hasUpgrade(this.layer, 121) ? 1.2 : 1) + ) + ); + }, + unlocked() { + return hasUpgrade("p", 51) || hasChallenge(this.layer, this.id); + }, + completionLimit() { + if (hasUpgrade("p", 62)) return 7; + if (hasUpgrade("p", 53)) return 3; + if (hasUpgrade("p", 52)) return 2; + return 1; + } + }, + 12: { + name: "Point", + challengeDescription: "Points are pointed", + goal() { + return new Decimal(100); + }, + rewardDescription() { + return ( + "You have completed this challenge " + + player.layers[this.layer].challenges![this.id] + + "/" + + this.completionLimit + + " times, making previous challenge goal scale " + + layers[this.layer].challenges!.data[this.id].effect + + "% slower." + ); + }, + unlocked() { + return hasUpgrade("p", 61) || hasChallenge(this.layer, this.id); + }, + effect() { + if (!hasChallenge(this.layer, this.id)) return 0; + if (player.layers[this.layer].challenges![this.id] == new Decimal(1)) + return 50; + if (player.layers[this.layer].challenges![this.id] == new Decimal(2)) + return 60; + if (player.layers[this.layer].challenges![this.id] == new Decimal(3)) + return 70; + }, + completionLimit() { + let l = new Decimal(1); + if (hasUpgrade("p", 84)) l = l.plus(1); + if (hasMilestone("p", 3)) l = l.plus(1); + return l; + } + }, + 21: { + name: "Time Points", + challengeDescription: "You are stuck in all above challenges", + goal() { + return new Decimal(308.25); + }, + rewardDescription() { + return "Lower the first generator buyable cost base by 6"; + }, + unlocked() { + return hasUpgrade("p", 91) || hasChallenge(this.layer, this.id); + } + }, + 22: { + name: "Last Challenge", + challengeDescription: "Generator points do nothing", + goal() { + return new Decimal(9999); + }, + rewardDescription() { + return "Autoclick the clickable and reduce 2 Tree Trunks by 1"; + }, + unlocked() { + return hasUpgrade("p", 103) || hasChallenge(this.layer, this.id); + } + } + } + }, + buyables: { + rows: 99, + cols: 4, + data: { + 11: { + cost() { + return new Decimal(0); + }, + display() { + return ( + "Reset all upgrades and challenges, but get a boost. You have reset " + + getBuyableAmount(this.layer, this.id) + + " times.
" + + (getBuyableAmount(this.layer, this.id)!.eq(6) + ? "You can't buy more than 6 boosts!" + : "You need all upgrades to reset.") + ); + }, + canAfford() { + return ( + player.layers[this.layer].points.gte(this.cost!) && + hasUpgrade(this.layer, 74) && + hasUpgrade(this.layer, 64) && + getBuyableAmount(this.layer, this.id)!.lt(6) + ); + }, + buy() { + player.layers[this.layer].points = player.layers[ + this.layer + ].points.sub(this.cost!); + setBuyableAmount( + this.layer, + this.id, + getBuyableAmount(this.layer, this.id)!.add(1) + ); + player.layers[this.layer].points = new Decimal(0); + player.layers[this.layer].upgrades = []; + if (hasMilestone(this.layer, 1)) + player.layers[this.layer].upgrades = [ + 11, + 12, + 13, + 14, + 21, + 22, + 23, + 24 + ]; + if (hasMilestone(this.layer, 3)) + player.layers[this.layer].upgrades = [ + 11, + 12, + 13, + 14, + 21, + 22, + 23, + 24, + 31, + 32, + 33, + 34, + 41, + 42, + 43, + 44, + 51, + 52, + 53, + 54, + 61, + 62, + 63, + 64 + ]; + if (!hasMilestone(this.layer, 2)) { + for (const c in layers[this.layer].challenges) { + player.layers[this.layer].challenges![c] = new Decimal(0); + } + } + }, + unlocked() { + return ( + (hasUpgrade(this.layer, 74) && hasUpgrade(this.layer, 64)) || + hasMilestone(this.layer, 0) + ); + } + }, + 12: { + cost() { + return new Decimal(1) + .times( + new Decimal(hasChallenge(this.layer, 21) ? 4 : 10) + .sub(hasUpgrade(this.layer, 122) ? 2 : 0) + .pow(player.layers.p.buyables![this.id]) + ) + .div( + hasUpgrade(this.layer, 224) + ? hasUpgrade("p", 132) + ? (player.layers.p.gp as Decimal).plus(1).pow(new Decimal(1).div(2)) + : hasUpgrade("p", 101) + ? (player.layers.p.gp as Decimal).plus(1).pow(new Decimal(1).div(3)) + : hasUpgrade("p", 93) + ? (player.layers.p.gp as Decimal).plus(1).pow(0.2) + : (player.layers.p.gp as Decimal).plus(1).log10() + : 1 + ); + }, + display() { + return "Buy a generator for " + format(this.cost!) + " points"; + }, + canAfford() { + return player.points.gte(this.cost!) && hasMilestone(this.layer, 5); + }, + buy() { + if (!hasMilestone("p", 13)) + player.points = player.points.sub(this.cost!); + setBuyableAmount( + this.layer, + this.id, + getBuyableAmount(this.layer, this.id)!.add(1) + ); + player.layers[this.layer].g = (player.layers[this.layer].g as Decimal).plus(1); + }, + unlocked() { + return hasMilestone(this.layer, 5); + } + }, + 13: { + cost() { + return new Decimal(1) + .times(new Decimal(2).pow(player.layers.p.buyables![this.id])) + .div( + hasUpgrade(this.layer, 224) + ? hasUpgrade("p", 132) + ? (player.layers.p.gp as Decimal).plus(1).pow(new Decimal(1).div(2)) + : hasUpgrade("p", 101) + ? (player.layers.p.gp as Decimal).plus(1).pow(new Decimal(1).div(3)) + : hasUpgrade("p", 93) + ? (player.layers.p.gp as Decimal).plus(1).pow(0.2) + : (player.layers.p.gp as Decimal).plus(1).log10() + : 1 + ); + }, + display() { + return ( + "Buy a generator for " + format(this.cost!) + " prestige points" + ); + }, + canAfford() { + return player.layers.p.points.gte(this.cost!) && hasUpgrade("p", 82); + }, + buy() { + if (!hasMilestone("p", 13)) + player.layers.p.points = player.layers.p.points.sub(this.cost!); + setBuyableAmount( + this.layer, + this.id, + getBuyableAmount(this.layer, this.id)!.add(1) + ); + player.layers[this.layer].g = (player.layers[this.layer].g as Decimal).plus(1); + }, + unlocked() { + return hasUpgrade(this.layer, 82); + } + }, + 14: { + cost() { + return new Decimal(900) + .mul(new Decimal(1.01).pow(getBuyableAmount(this.layer, this.id)!)) + .round() + .div( + hasUpgrade(this.layer, 234) + ? getBuyableAmount(this.layer, 23)! + .pow(0.3) + .plus(1) + : 1 + ); + }, + display() { + return ( + "Buy a generator for " + format(this.cost!) + " Infinity points" + ); + }, + canAfford() { + return player.layers.i.points.gte(this.cost!) && hasUpgrade("p", 232); + }, + buy() { + if (!hasMilestone("p", 13)) + player.layers.i.points = player.layers.i.points.sub(this.cost!).round(); + setBuyableAmount( + this.layer, + this.id, + getBuyableAmount(this.layer, this.id)!.add(1) + ); + player.layers[this.layer].g = (player.layers[this.layer].g as Decimal).plus(1); + }, + unlocked() { + return hasUpgrade(this.layer, 232); + } + }, + 21: { + cost() { + return new Decimal(20).plus( + getBuyableAmount(this.layer, this.id)!.pow( + new Decimal(2).sub( + new Decimal( + hasUpgrade(this.layer, 221) + ? 0.9 + : hasUpgrade(this.layer, 214) + ? 0.6 + : 0.3 + ).times( + hasUpgrade(this.layer, 212) + ? new Decimal(1).sub( + new Decimal(0.75).pow(getBuyableAmount(this.layer, 22)!) + ) + : 0 + ) + ) + ) + ); + }, + display() { + return ( + "Reset your generators for +1 pointy point! Cost: " + + format(this.cost!) + + " Generators" + ); + }, + canAfford() { + return (player.layers.p.g as Decimal).gte(this.cost!) && hasUpgrade("p", 104); + }, + buy() { + if (!hasMilestone("i", 1)) player.layers.p.g = new Decimal(0); + setBuyableAmount( + this.layer, + this.id, + getBuyableAmount(this.layer, this.id)!.add(1) + ); + if (!hasMilestone("i", 1)) + setBuyableAmount(this.layer, 12, new Decimal(0)); + if (!hasMilestone("i", 1)) + setBuyableAmount(this.layer, 13, new Decimal(0)); + if (!hasMilestone("i", 1)) player.layers.p.gp = new Decimal(0); + }, + unlocked() { + return hasUpgrade(this.layer, 104); + } + }, + 22: { + cost() { + return new Decimal(8).plus(getBuyableAmount(this.layer, this.id)!); + }, + display() { + return ( + "Gain a pointy prestige point. Cost: " + + format(this.cost!) + + " Pointy Points" + ); + }, + canAfford() { + return ( + getBuyableAmount(this.layer, 21)!.gte(this.cost!) && + hasMilestone("i", 5) + ); + }, + buy() { + if (!hasUpgrade(this.layer, 233)) + setBuyableAmount( + this.layer, + 21, + getBuyableAmount(this.layer, 21)!.sub(this.cost!) + ); + setBuyableAmount( + this.layer, + this.id, + getBuyableAmount(this.layer, this.id)!.add(1) + ); + }, + unlocked() { + return hasMilestone("i", 5); + } + }, + 23: { + cost() { + return new Decimal(124).plus( + getBuyableAmount(this.layer, this.id)! + .times(2) + .pow(2) + ); + }, + display() { + return ( + "Gain a booster. Cost: " + format(this.cost!) + " Pointy Points" + ); + }, + canAfford() { + return ( + getBuyableAmount(this.layer, 21)!.gte(this.cost!) && + hasMilestone("i", 5) + ); + }, + buy() { + if (!hasMilestone(this.layer, 15)) + setBuyableAmount( + this.layer, + 21, + getBuyableAmount(this.layer, 21)!.sub(this.cost!) + ); + setBuyableAmount( + this.layer, + this.id, + getBuyableAmount(this.layer, this.id)!.add(1) + ); + if (!hasMilestone(this.layer, 15)) { + if (!hasMilestone(this.layer, 12)) { + player.layers.p.upgrades = player.layers.p.upgrades!.filter((x: string | Number) => { + return Number(x) < 200 || Number(x) > 230; + }); + if (hasMilestone(this.layer, 11)) { + player.layers.p.upgrades.push(215); + player.layers.p.upgrades.push(225); + player.layers.p.upgrades.push(223); + player.layers.p.upgrades.push(222); + } + } + setBuyableAmount("p", 21, new Decimal(0)); + setBuyableAmount("p", 22, new Decimal(0)); + if (!hasUpgrade("p", 233)) { + setBuyableAmount("p", 12, new Decimal(0)); + setBuyableAmount("p", 13, new Decimal(0)); + setBuyableAmount("p", 14, new Decimal(0)); + + player.layers.p.g = new Decimal(0); + } + player.layers.p.gp = new Decimal(0); + } + }, + unlocked() { + return hasUpgrade("p", 225) || getBuyableAmount("p", 23)!.gt(0); + } + }, + 31: { + cost() { + return new Decimal(1e93) + .times(new Decimal(1.5).pow(getBuyableAmount(this.layer, this.id)!)) + .times( + new Decimal(1.1).pow( + getBuyableAmount(this.layer, this.id)!.pow(2) + ) + ); + }, + effect() { + return new Decimal(2) + .plus(layers.p.buyables!.data[33].effect as Decimal) + .pow( + getBuyableAmount(this.layer, this.id)!.plus( + layers.p.buyables!.data[51].effect as Decimal + ) + ); + }, + display() { + return ( + "Double point gain. \nCurrently: x" + + format(this.effect as Decimal) + + "\nCost: " + + format(this.cost!) + + " Prestige points" + ); + }, + canAfford() { + return player.layers.p.points.gte(this.cost!) && hasMilestone("p", 13); + }, + buy() { + player.layers.p.points = player.layers.p.points.sub(this.cost!); + setBuyableAmount( + this.layer, + this.id, + getBuyableAmount(this.layer, this.id)!.add(1) + ); + }, + unlocked() { + return hasMilestone("p", 13); + } + }, + 32: { + cost() { + return new Decimal(1e95) + .times(new Decimal(2).pow(getBuyableAmount(this.layer, this.id)!)) + .times( + new Decimal(1.01).pow( + getBuyableAmount(this.layer, this.id)!.pow(2) + ) + ); + }, + display() { + return ( + "Double prestige point gain. \nCurrently: x" + + format( + new Decimal(2) + .plus(layers.p.buyables!.data[33].effect as Decimal) + .pow(getBuyableAmount(this.layer, this.id)!) + ) + + "\nCost: " + + format(this.cost!) + + " Prestige points" + ); + }, + canAfford() { + return player.layers.p.points.gte(this.cost!) && hasMilestone("p", 13); + }, + buy() { + player.layers.p.points = player.layers.p.points.sub(this.cost!); + setBuyableAmount( + this.layer, + this.id, + getBuyableAmount(this.layer, this.id)!.add(1) + ); + }, + unlocked() { + return ( + hasMilestone("p", 13) && getBuyableAmount(this.layer, 31)!.gte(5) + ); + } + }, + 33: { + cost() { + return new Decimal(1e100) + .times(new Decimal(10).pow(getBuyableAmount(this.layer, this.id)!)) + .times( + new Decimal(1.01).pow( + getBuyableAmount(this.layer, this.id)!.pow(2) + ) + ); + }, + effect() { + return new Decimal(0.01) + .mul(getBuyableAmount(this.layer, this.id)!) + .times(layers.p.buyables!.data[43].effect as Decimal); + }, + display() { + return ( + "Add 0.01 to the previous 2 buyable bases. \nCurrently: +" + + format(this.effect as Decimal) + + "\nCost: " + + format(this.cost!) + + " Prestige points" + ); + }, + canAfford() { + return player.layers.p.points.gte(this.cost!) && hasMilestone("p", 13); + }, + buy() { + player.layers.p.points = player.layers.p.points.sub(this.cost!); + setBuyableAmount( + this.layer, + this.id, + getBuyableAmount(this.layer, this.id)!.add(1) + ); + }, + unlocked() { + return ( + hasMilestone("p", 13) && + (getBuyableAmount(this.layer, this.id)!.gt(0) || + player.layers.p.points.gte(1e100)) + ); + } + }, + 41: { + cost() { + return new Decimal(1e110) + .times(new Decimal(10).pow(getBuyableAmount(this.layer, this.id)!)) + .times( + new Decimal(10).pow(getBuyableAmount(this.layer, this.id)!.pow(2)) + ); + }, + effect() { + return new Decimal(0.01).mul( + getBuyableAmount(this.layer, this.id)!.plus( + layers.p.buyables!.data[51].effect as Decimal + ) + ); + }, + display() { + return ( + "Add 0.01 to the booster effect base. \nCurrently: +" + + format(this.effect as Decimal) + + "\nCost: " + + format(this.cost!) + + " Prestige points" + ); + }, + canAfford() { + return player.layers.p.points.gte(this.cost!) && hasMilestone("p", 13); + }, + buy() { + player.layers.p.points = player.layers.p.points.sub(this.cost!); + setBuyableAmount( + this.layer, + this.id, + getBuyableAmount(this.layer, this.id)!.add(1) + ); + }, + unlocked() { + return ( + hasMilestone("p", 13) && + (getBuyableAmount(this.layer, this.id)!.gt(0) || + player.layers.p.points.gte(1e110)) + ); + } + }, + 42: { + cost() { + const c = new Decimal(1e270) + .times(new Decimal(2).pow(getBuyableAmount(this.layer, this.id)!)) + .times( + new Decimal(1.01).pow( + getBuyableAmount(this.layer, this.id)!.pow(2) + ) + ); + + return c; + }, + effect() { + let f = new Decimal(1.001).pow( + getBuyableAmount(this.layer, this.id)! + ); + if (f.gte(1.1)) f = f.pow(0.8).times(new Decimal(1.1).pow(0.2)); + if (f.gte(1.35)) f = f.pow(0.5).times(new Decimal(1.35).pow(0.5)); + if (f.gte(3)) f = new Decimal(3); + return f; + }, + display() { + return ( + "Raise point gain to the 1.001 \nCurrently: ^" + + format(this.effect as Decimal) + + ((this.effect as Decimal).eq(3) ? "(hardcapped)" : "") + + "\nCost: " + + format(this.cost!) + + " Prestige points" + ); + }, + canAfford() { + return ( + player.layers.p.points.gte(this.cost!) && + hasMilestone("p", 13) && + (this.effect as Decimal).lt(3) + ); + }, + buy() { + player.layers.p.points = player.layers.p.points.sub(this.cost!); + setBuyableAmount( + this.layer, + this.id, + getBuyableAmount(this.layer, this.id)!.add(1) + ); + }, + unlocked() { + return ( + hasMilestone("p", 13) && + (getBuyableAmount(this.layer, this.id)!.gt(0) || + player.layers.p.points.gte(1e270)) + ); + } + }, + 43: { + cost() { + return new Decimal("1e375") + .times(new Decimal(10).pow(getBuyableAmount(this.layer, this.id)!)) + .times( + new Decimal(10).pow(getBuyableAmount(this.layer, this.id)!.pow(2)) + ); + }, + effect() { + return new Decimal(0.01) + .mul(getBuyableAmount(this.layer, this.id)!) + .plus(1); + }, + display() { + return ( + "Multiply the above buyable effect. \nCurrently: *" + + format(this.effect as Decimal) + + "\nCost: " + + format(this.cost!) + + " Prestige points" + ); + }, + canAfford() { + return player.layers.p.points.gte(this.cost!) && hasMilestone("p", 13); + }, + buy() { + player.layers.p.points = player.layers.p.points.sub(this.cost!); + setBuyableAmount( + this.layer, + this.id, + getBuyableAmount(this.layer, this.id)!.add(1) + ); + }, + unlocked() { + return ( + hasMilestone("p", 13) && + (getBuyableAmount(this.layer, this.id)!.gt(0) || + player.layers.p.points.gte("1e375")) + ); + } + }, + 51: { + cost() { + return new Decimal("1e1740") + .times(new Decimal(10).pow(getBuyableAmount(this.layer, this.id)!)) + .times( + new Decimal(1e10).pow( + getBuyableAmount(this.layer, this.id)!.pow(2) + ) + ); + }, + effect() { + return getBuyableAmount(this.layer, this.id)!.pow(0.55); + }, + display() { + return ( + "Add free levels to the above 2 buyables \nCurrently: " + + format(this.effect as Decimal) + + "\nCost: " + + format(this.cost!) + + " Prestige points" + ); + }, + canAfford() { + return player.layers.p.points.gte(this.cost!) && hasMilestone("p", 13); + }, + buy() { + player.layers.p.points = player.layers.p.points.sub(this.cost!); + setBuyableAmount( + this.layer, + this.id, + getBuyableAmount(this.layer, this.id)!.add(1) + ); + }, + unlocked() { + return ( + hasMilestone("p", 15) && + (getBuyableAmount(this.layer, this.id)!.gt(0) || + player.layers.p.points.gte("1e1700")) + ); + } + } + } + }, + milestones: { + data: { + 0: { + requirementDisplay: "1 reset", + effectDisplay: + "Add 0.01 to base point gain and prestige requirement, and 1 doesn't reset upgrades", + done() { + return getBuyableAmount("p", 11)!.gte(1); + }, + unlocked() { + return layers.p.activeSubtab?.id == "Pointy points"; + } + }, + 1: { + requirementDisplay: "2 resets", + effectDisplay: + "
2 and 3 don't reset upgrades, and start with the first 8 upgrades on reset
", + done() { + return getBuyableAmount("p", 11)!.gte(2); + }, + unlocked() { + return ( + hasMilestone(this.layer, Number(this.id) - 1) && + layers.p.activeSubtab?.id == "Pointy points" + ); + } + }, + 2: { + requirementDisplay: "3 resets", + effectDisplay: + "
4 doesn't reset upgrades, and permanently fix the bug where you can't buy upgrades when you have 1 prestige point
", + done() { + return getBuyableAmount("p", 11)!.gte(3); + }, + unlocked() { + return ( + hasMilestone(this.layer, Number(this.id) - 1) && + layers.p.activeSubtab?.id == "Pointy points" + ); + } + }, + 3: { + requirementDisplay: "4 resets", + effectDisplay: + "Don't reset challenges, add 1 to Point maximum completions, and start with 24 upgrades", + done() { + return getBuyableAmount("p", 11)!.gte(4); + }, + unlocked() { + return ( + hasMilestone(this.layer, Number(this.id) - 1) && + layers.p.activeSubtab?.id == "Pointy points" + ); + } + }, + 4: { + requirementDisplay: "5 resets", + effectDisplay: "Each useless upgrade adds 0.1 to base point gain", + done() { + return getBuyableAmount("p", 11)!.gte(5); + }, + unlocked() { + return ( + hasMilestone(this.layer, Number(this.id) - 1) && + layers.p.activeSubtab?.id == "Pointy points" + ); + } + }, + 5: { + requirementDisplay: "6 resets", + effectDisplay: "Unlock something", + done() { + return getBuyableAmount("p", 11)!.gte(6); + }, + unlocked() { + return ( + hasMilestone(this.layer, Number(this.id) - 1) && + layers.p.activeSubtab?.id == "Pointy points" + ); + } + }, + 6: { + requirementDisplay: "1 pointy point", + effectDisplay: "Unlock the upgrade tree", + done() { + return getBuyableAmount("p", 21)!.gte(1); + }, + unlocked() { + return ( + hasMilestone(this.layer, Number(this.id) - 1) && + (hasUpgrade(this.layer, 104) || player.layers.i.unlocked) && + layers.p.activeSubtab?.id == "Pointy points" + ); + } + }, + 7: { + requirementDisplay: "7 pointy points", + effectDisplay: + "You can now buy both first and second row upgrade tree upgrades", + done() { + return getBuyableAmount("p", 21)!.gte(7); + }, + unlocked() { + return ( + hasMilestone(this.layer, Number(this.id) - 1) && + (hasUpgrade(this.layer, 111) || player.layers.i.unlocked) && + layers.p.activeSubtab?.id == "Pointy points" + ); + } + }, + 8: { + requirementDisplay: "8 pointy points", + effectDisplay: "Unlock another layer", + done() { + return getBuyableAmount("p", 21)!.gte(8); + }, + unlocked() { + return ( + hasMilestone(this.layer, Number(this.id) - 1) && + (hasUpgrade(this.layer, 141) || + hasUpgrade(this.layer, 143) || + hasUpgrade(this.layer, 142) || + player.layers.i.unlocked) && + layers.p.activeSubtab?.id == "Pointy points" + ); + } + }, + 11: { + requirementDisplay: "3 boosters", + effectDisplay: "Keep automation on booster reset", + done() { + return getBuyableAmount("p", 23)!.gte(3); + }, + unlocked() { + return ( + getBuyableAmount("p", 23)!.gt(0) || + hasMilestone(this.layer, this.id) + ); + } + }, + 12: { + requirementDisplay: "5 boosters", + effectDisplay: + "Keep all prestige upgrades on booster reset and buy max infinity points", + done() { + return getBuyableAmount("p", 23)!.gte(5); + }, + unlocked() { + return ( + getBuyableAmount("p", 23)!.gt(0) || + hasMilestone(this.layer, this.id) + ); + } + }, + 13: { + requirementDisplay: "10 boosters", + effectDisplay: "Generators cost nothing", + done() { + return getBuyableAmount("p", 23)!.gte(10); + }, + unlocked() { + return ( + getBuyableAmount("p", 23)!.gt(0) || + hasMilestone(this.layer, this.id) + ); + } + }, + 14: { + requirementDisplay: "15 boosters", + effectDisplay: + "Auto buy the first 3 buyables and buy max pointy prestige points", + done() { + return getBuyableAmount("p", 23)!.gte(15); + }, + unlocked() { + return ( + getBuyableAmount("p", 41)!.gt(0) || + hasMilestone(this.layer, this.id) + ); + } + }, + 15: { + requirementDisplay: "20 boosters", + effectDisplay: "Boosters reset nothing and auto booster", + done() { + return getBuyableAmount("p", 23)!.gte(16); + }, + unlocked() { + return ( + getBuyableAmount("p", 41)!.gt(0) || + hasMilestone(this.layer, this.id) + ); + } + } + } + }, + passiveGeneration() { + return hasUpgrade("i", 11) ? 1 : 0; + }, + update(diff) { + if (hasMilestone(this.layer, 2) && !hasUpgrade(this.layer, 54)) { + player.layers[this.layer].upgrades!.push(54); + } + if ( + hasMilestone(this.layer, 1) && + !hasUpgrade(this.layer, 11) && + !hasMilestone(this.layer, 3) + ) { + player.layers[this.layer].upgrades = [11, 12, 13, 14, 21, 22, 23, 24]; + } + if (hasMilestone(this.layer, 3) && !hasUpgrade(this.layer, 31)) { + player.layers[this.layer].upgrades = [ + 11, + 12, + 13, + 14, + 21, + 22, + 23, + 24, + 31, + 32, + 33, + 34, + 41, + 42, + 43, + 44, + 51, + 52, + 53, + 54, + 61, + 62, + 63, + 64 + ]; + } + if (hasMilestone(this.layer, 5)) { + player.layers[this.layer].gp = (player.layers[this.layer].gp as Decimal).plus( + (player.layers.p.g as Decimal).times(diff).times(player.layers.p.geff as Decimal) + ); + } + let geff = new Decimal(1); + if (hasUpgrade("p", 81)) geff = geff.plus(2); + if (hasUpgrade("p", 102)) + geff = geff.plus( + hasChallenge("p", 22) + ? (player.layers.p.gp as Decimal).plus(1).log(10) + : (player.layers.p.gp as Decimal) + .plus(1) + .log(10) + .plus(1) + .log(10) + ); + if (hasUpgrade("p", 83)) + geff = geff.times( + player.layers.p.points + .plus(1) + .log(10) + .plus(1) + ); + if (hasUpgrade("p", 94)) geff = geff.times(player.layers.p.cmult as Decimal); + if (hasUpgrade("p", 104)) + geff = geff.times(new Decimal(player.layers.p.buyables![21]).plus(1)); + if (hasUpgrade("p", 143)) + geff = geff.times(new Decimal(player.timePlayed).div(3600).max(1)); + if (hasUpgrade("p", 225)) + geff = geff.pow( + new Decimal(player.layers.p.buyables![23]) + .div(10) + .mul( + new Decimal(0.1) + .plus(layers.p.buyables!.data[41].effect as Decimal) + .times(10) + ) + .plus(1) + ); + player.layers.p.geff = geff; + if (hasChallenge("p", 22) && (!hasUpgrade("p", 141) || hasUpgrade("i", 12))) + player.layers.p.cmult = (player.layers.p.cmult as Decimal).plus(hasUpgrade("p", 141) ? 1 : 0.01); + if (!hasUpgrade("p", 111)) player.layers.p.cmult = (player.layers.p.cmult as Decimal).min(100); + if (hasMilestone(this.layer, 14)) { + if (layers.p.buyables!.data[31].canAfford) + layers.p.buyables!.data[31].buy(); + if (layers.p.buyables!.data[32].canAfford) + layers.p.buyables!.data[32].buy(); + if (layers.p.buyables!.data[33].canAfford) + layers.p.buyables!.data[33].buy(); + } + if (hasMilestone(this.layer, 15)) { + if (layers.p.buyables!.data[23].canAfford) + layers.p.buyables!.data[23].buy(); + } + }, + subtabs: { + Upgrades: { + display: ` + + + + + + ` + }, + Challenges: { + unlocked() { + return hasUpgrade("p", 51) || hasMilestone("p", 0); + }, + display: ` + + + ` + }, + "Buyables and Milestones": { + unlocked() { + return hasUpgrade("p", 74) || hasMilestone("p", 0); + }, + display: ` + + + + +
Your boosts are making the point challenge {{ getBuyableAmount('p', 11).plus(1) }}x less pointy
+ + ` + }, + Generators: { + unlocked() { + return hasMilestone("p", 5) || player.layers.i.points.gte(1); + }, + display: ` + +
You have {{ format(player.layers.p.gp) }} generator points, adding {{ format(hasUpgrade("p",132)?player.layers.p.gp.plus(1).pow(new Decimal(1).div(2)):hasUpgrade("p",101)?player.layers.p.gp.plus(1).pow(new Decimal(1).div(3)):hasUpgrade("p",93)?player.layers.p.gp.plus(1).pow(0.2):player.layers.p.gp.plus(1).log10()) }} to point gain
+
You have {{ format(player.layers.p.g) }} generators, generating {{ format(player.layers.p.g.times(player.layers.p.geff)) }} generator points per second
+
Generator efficiency is {{ format(player.layers.p.geff) }}
+ + + + ` + }, + "Pointy Points": { + unlocked() { + return hasUpgrade("p", 104) || player.layers.i.points.gte(1); + }, + display: ` +
{{ format(player.layers.p.buyables![21]) }} pointy points
+
My pointy points are multiplying generator efficiency by {{ format(new Decimal(player.layers.p.buyables![21]).plus(1)) }}
+ + + +
I have {{ format(player.layers.p.buyables![22]) }} pointy prestige points
+ + + + +
I have {{ format(player.layers.p.buyables![23]) }} pointy boosters!
+ +
My pointy boosters are raising generator efficiency to the ^{{ format(new Decimal(player.layers.p.buyables![23]).div(10).mul(new Decimal(0.1).plus(layers.p.buyables[41].effect).times(10)).plus(1)) }}
+ + +
Booster upgrades
+ ` + }, + Buyables: { + unlocked() { + return hasMilestone("p", 13); + }, + display: ` + + ` + } + } +} as RawLayer; diff --git a/src/data/mod.js b/src/data/mod.js deleted file mode 100644 index eb16b35..0000000 --- a/src/data/mod.js +++ /dev/null @@ -1,120 +0,0 @@ -import { computed } from 'vue'; -import { hasUpgrade, upgradeEffect, hasMilestone, inChallenge, getBuyableAmount } from '../util/features'; -import { layers } from '../game/layers'; -import player from '../game/player'; -import Decimal from '../util/bignum'; - -// Import initial layers -import f from './layers/aca/f.js'; -import c from './layers/aca/c.js'; -import a from './layers/aca/a.js'; -import demoLayer from './layers/demo.js'; -import demoInfinityLayer from './layers/demo-infinity.js'; -const g = { - id: "g", - symbol: "TH", - branches: ["c"], - color: '#6d3678', - shown: true, - canClick() {return player.points.gte(10)}, - tooltip: "Thanos your points", - click() { - player.points = player.points.div(2); - console.log(this.layer); - } -}; -const h = { - id: "h", - branches: ["g", () => ({ target: 'flatBoi', featureType: 'bar', endOffset: { x: -50 + 100 * layers.c.bars.flatBoi.progress.toNumber() } })], - tooltip() {return "Restore your points to {{ player.c.otherThingy }}"}, - row: "side", - position: 3, - canClick() {return player.points.lt(player.c.otherThingy)}, - click() {player.points = new Decimal(player.c.otherThingy)} -}; -const spook = { - id: "spook", - row: 1, - layerShown: "ghost", -}; - -const main = { - id: 'main', - display: ` -
Game Paused
-
Dev Speed: {{ format(player.devSpeed) }}x
-
Offline Time: {{ formatTime(player.offTime.remain) }}
-
- You have -

{{ format(player.points) }}

- points -
-
- ({{ player.oompsMag != 0 ? format(player.oomps) + " OOM" + (player.oompsMag < 0 ? "^OOM" : player.oompsMag > 1 ? "^" + player.oompsMag : "") + "s" : formatSmall(pointGain) }}/sec) -
- - `, - name: "Tree" -}; - -export const getInitialLayers = () => [ main, f, c, a, g, h, spook, demoLayer, demoInfinityLayer ]; - -export function getStartingData() { - return { - points: new Decimal(10), - } -} - -export const hasWon = computed(() => { - return false; -}); - -export const pointGain = computed(() => { - if(!hasUpgrade("c", 11)) - return new Decimal(0); - let gain = new Decimal(3.19) - if (hasUpgrade("c", 12)) gain = gain.times(upgradeEffect("c", 12)) - if (hasMilestone("p",0))gain=gain.plus(0.01) - if (hasMilestone("p",4)){ - if (hasUpgrade("p",12))gain=gain.plus(0.1) - if (hasUpgrade("p",13))gain=gain.plus(0.1) - if (hasUpgrade("p",14))gain=gain.plus(0.1) - if (hasUpgrade("p",21))gain=gain.plus(0.1) - if (hasUpgrade("p",22))gain=gain.plus(0.1) - if (hasUpgrade("p",23))gain=gain.plus(0.1) - if (hasUpgrade("p",31))gain=gain.plus(0.1) - if (hasUpgrade("p",32))gain=gain.plus(0.1) - if (hasUpgrade("p",33))gain=gain.plus(0.1) - } - if (hasUpgrade("p",11))gain=gain.plus(hasUpgrade("p",34)?(new Decimal(1).plus(layers.p.upgrades[34].effect)):1) - if (hasUpgrade("p",12))gain=gain.times(hasUpgrade("p",34)?(new Decimal(1).plus(layers.p.upgrades[34].effect)):1) - if (hasUpgrade("p",13))gain=gain.pow(hasUpgrade("p",34)?(new Decimal(1).plus(layers.p.upgrades[34].effect)):1) - if (hasUpgrade("p",14))gain=gain.tetrate(hasUpgrade("p",34)?(new Decimal(1).plus(layers.p.upgrades[34].effect)):1) - - if (hasUpgrade("p",71)) gain=gain.plus(1.1) - if (hasUpgrade("p",72)) gain=gain.times(1.1) - if (hasUpgrade("p",73)) gain=gain.pow(1.1) - if (hasUpgrade("p",74)) gain=gain.tetrate(1.1) - if (hasMilestone("p",5)&&!inChallenge("p",22)){ - let asdf = (hasUpgrade("p",132)?player.p.gp.plus(1).pow(new Decimal(1).div(2)):hasUpgrade("p",101)?player.p.gp.plus(1).pow(new Decimal(1).div(3)):hasUpgrade("p",93)?player.p.gp.plus(1).pow(0.2):player.p.gp.plus(1).log10()) - gain=gain.plus(asdf) - if (hasUpgrade("p",213))gain=gain.mul(asdf.plus(1)) - } - if (hasUpgrade("p",104)) gain=gain.times(player.p.points.plus(1).pow(0.5)) - if (hasUpgrade("p",142))gain=gain.times(5) - if (player.i.unlocked)gain=gain.times(player.i.points.plus(1).pow(hasUpgrade("p",235)?6.9420:1)) - if (inChallenge("p",11)||inChallenge("p",21))gain=new Decimal(10).pow(gain.log10().pow(0.75)) - if (inChallenge("p",12)||inChallenge("p",21))gain=gain.pow(new Decimal(1).sub(new Decimal(1).div(getBuyableAmount("p",11).plus(1)))) - if (hasUpgrade("p",211))gain=gain.times(getBuyableAmount("p",21).plus(1)) - if (hasMilestone("p",13))gain=gain.times(layers.p.buyables[31].effect) - if (hasMilestone("p",13))gain=gain.pow(layers.p.buyables[42].effect) - return gain; -}); - -/* eslint-disable-next-line no-unused-vars */ -export function update(delta) { -} - -/* eslint-disable-next-line no-unused-vars */ -export function fixOldSave(oldVersion, playerData) { -} diff --git a/src/data/mod.ts b/src/data/mod.ts new file mode 100644 index 0000000..6dfbc4e --- /dev/null +++ b/src/data/mod.ts @@ -0,0 +1,187 @@ +import { layers } from "@/game/layers"; +import player from "@/game/player"; +import { RawLayer } from "@/typings/layer"; +import { PlayerData } from "@/typings/player"; +import Decimal from "@/util/bignum"; +import { + getBuyableAmount, + hasMilestone, + hasUpgrade, + inChallenge, + upgradeEffect +} from "@/util/features"; +import { computed } from "vue"; +import a from "./layers/aca/a"; +import c from "./layers/aca/c"; +import f from "./layers/aca/f"; +import demoLayer from "./layers/demo"; +import demoInfinityLayer from "./layers/demo-infinity"; + +// Import initial layers + +const g = { + id: "g", + symbol: "TH", + branches: ["c"], + color: "#6d3678", + shown: true, + canClick() { + return player.points.gte(10); + }, + tooltip: "Thanos your points", + click() { + player.points = player.points.div(2); + console.log(this.layer); + } +} as RawLayer; +const h = { + id: "h", + branches: [ + "g", + () => ({ + target: "flatBoi", + featureType: "bar", + endOffset: { + x: + -50 + + 100 * + (layers.c.bars!.data.flatBoi.progress instanceof Number + ? (layers.c.bars!.data.flatBoi.progress as number) + : (layers.c.bars!.data.flatBoi.progress as Decimal).toNumber()) + } + }) + ], + tooltip() { + return "Restore your points to {{ player.c.otherThingy }}"; + }, + row: "side", + position: 3, + canClick() { + return player.points.lt(player.layers.c.otherThingy as Decimal); + }, + click() { + player.points = new Decimal(player.layers.c.otherThingy as Decimal); + } +} as RawLayer; +const spook = { + id: "spook", + row: 1, + layerShown: "ghost" +} as RawLayer; + +const main = { + id: "main", + display: ` +
Game Paused
+
Dev Speed: {{ format(player.devSpeed) }}x
+
Offline Time: {{ formatTime(player.offTime.remain) }}
+
+ You have +

{{ format(player.points) }}

+ points +
+
+ ({{ player.oompsMag != 0 ? format(player.oomps) + " OOM" + (player.oompsMag < 0 ? "^OOM" : player.oompsMag > 1 ? "^" + player.oompsMag : "") + "s" : formatSmall(pointGain) }}/sec) +
+ + `, + name: "Tree" +} as RawLayer; + +export const getInitialLayers = ( + /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ + playerData: Partial +): Array => [main, f, c, a, g, h, spook, demoLayer, demoInfinityLayer]; + +export function getStartingData(): Record { + return { + points: new Decimal(10) + }; +} + +export const hasWon = computed(() => { + return false; +}); + +export const pointGain = computed(() => { + if (!hasUpgrade("c", 11)) return new Decimal(0); + let gain = new Decimal(3.19); + if (hasUpgrade("c", 12)) gain = gain.times(upgradeEffect("c", 12) as Decimal); + if (hasMilestone("p", 0)) gain = gain.plus(0.01); + if (hasMilestone("p", 4)) { + if (hasUpgrade("p", 12)) gain = gain.plus(0.1); + if (hasUpgrade("p", 13)) gain = gain.plus(0.1); + if (hasUpgrade("p", 14)) gain = gain.plus(0.1); + if (hasUpgrade("p", 21)) gain = gain.plus(0.1); + if (hasUpgrade("p", 22)) gain = gain.plus(0.1); + if (hasUpgrade("p", 23)) gain = gain.plus(0.1); + if (hasUpgrade("p", 31)) gain = gain.plus(0.1); + if (hasUpgrade("p", 32)) gain = gain.plus(0.1); + if (hasUpgrade("p", 33)) gain = gain.plus(0.1); + } + if (hasUpgrade("p", 11)) + gain = gain.plus( + hasUpgrade("p", 34) + ? new Decimal(1).plus(layers.p.upgrades!.data[34].effect as Decimal) + : 1 + ); + if (hasUpgrade("p", 12)) + gain = gain.times( + hasUpgrade("p", 34) + ? new Decimal(1).plus(layers.p.upgrades!.data[34].effect as Decimal) + : 1 + ); + if (hasUpgrade("p", 13)) + gain = gain.pow( + hasUpgrade("p", 34) + ? new Decimal(1).plus(layers.p.upgrades!.data[34].effect as Decimal) + : 1 + ); + if (hasUpgrade("p", 14)) + gain = gain.tetrate( + hasUpgrade("p", 34) + ? new Decimal(1).plus(layers.p.upgrades!.data[34].effect as Decimal).toNumber() + : 1 + ); + + if (hasUpgrade("p", 71)) gain = gain.plus(1.1); + if (hasUpgrade("p", 72)) gain = gain.times(1.1); + if (hasUpgrade("p", 73)) gain = gain.pow(1.1); + if (hasUpgrade("p", 74)) gain = gain.tetrate(1.1); + if (hasMilestone("p", 5) && !inChallenge("p", 22)) { + const asdf = hasUpgrade("p", 132) + ? (player.layers.p.gp as Decimal).plus(1).pow(new Decimal(1).div(2)) + : hasUpgrade("p", 101) + ? (player.layers.p.gp as Decimal).plus(1).pow(new Decimal(1).div(3)) + : hasUpgrade("p", 93) + ? (player.layers.p.gp as Decimal).plus(1).pow(0.2) + : (player.layers.p.gp as Decimal).plus(1).log10(); + gain = gain.plus(asdf); + if (hasUpgrade("p", 213)) gain = gain.mul(asdf.plus(1)); + } + if (hasUpgrade("p", 104)) gain = gain.times(player.layers.p.points.plus(1).pow(0.5)); + if (hasUpgrade("p", 142)) gain = gain.times(5); + if (player.layers.i.unlocked) + gain = gain.times(player.layers.i.points.plus(1).pow(hasUpgrade("p", 235) ? 6.942 : 1)); + if (inChallenge("p", 11) || inChallenge("p", 21)) + gain = new Decimal(10).pow(gain.log10().pow(0.75)); + if (inChallenge("p", 12) || inChallenge("p", 21)) + gain = gain.pow(new Decimal(1).sub(new Decimal(1).div(getBuyableAmount("p", 11)!.plus(1)))); + if (hasUpgrade("p", 211)) gain = gain.times(getBuyableAmount("p", 21)!.plus(1)); + if (hasMilestone("p", 13)) gain = gain.times(layers.p.buyables!.data[31].effect as Decimal); + if (hasMilestone("p", 13)) gain = gain.pow(layers.p.buyables!.data[42].effect as Decimal); + return gain; +}); + +/* eslint-disable @typescript-eslint/no-unused-vars */ +// eslint-disable-next-line @typescript-eslint/no-empty-function +export function update(delta: Decimal): void {} +/* eslint-enable @typescript-eslint/no-unused-vars */ + +/* eslint-disable @typescript-eslint/no-unused-vars */ +export function fixOldSave( + oldVersion: string | undefined, + playerData: Partial + // eslint-disable-next-line @typescript-eslint/no-empty-function +): void {} +/* eslint-enable @typescript-eslint/no-unused-vars */ diff --git a/src/data/themes.js b/src/data/themes.js deleted file mode 100644 index d8fbffd..0000000 --- a/src/data/themes.js +++ /dev/null @@ -1,52 +0,0 @@ -const defaultTheme = { - variables: { - "--background": "#0f0f0f", - "--background-tooltip": "rgba(0, 0, 0, 0.75)", - "--secondary-background": "#0f0f0f", - "--color": "#dfdfdf", - "--points": "#ffffff", - "--locked": "#bf8f8f", - "--bought": "#77bf5f", - "--link": "#02f2f2", - "--separator": "#dfdfdf", - "--border-radius": "25%", - "--danger": "rgb(220, 53, 69)", - "--modal-border": "solid 2px var(--color)", - "--feature-margin": "0px", - }, - stackedInfoboxes: false, - floatingTabs: true -}; - -export default { - classic: defaultTheme, - paper: { - ...defaultTheme, - variables: { - ...defaultTheme.variables, - "--background": "#2a323d", - "--secondary-background": "#333c4a", - "--locked": "#3a3e45", - "--bought": "#5C8A58", - "--separator": "#333c4a", - "--border-radius": "4px", - "--modal-border": "", - "--feature-margin": "5px", - }, - stackedInfoboxes: true, - floatingTabs: false - }, - aqua: { - ...defaultTheme, - variables: { - ...defaultTheme.variables, - "--background": "#001f3f", - "--background-tooltip": "rgba(0, 15, 31, 0.75)", - "--secondary-background": "#001f3f", - "--color": "#bfdfff", - "--points": "#dfefff", - "--locked": "#c4a7b3", - "--separator": "#bfdfff" - } - } -}; diff --git a/src/data/themes.ts b/src/data/themes.ts new file mode 100644 index 0000000..35b8eaa --- /dev/null +++ b/src/data/themes.ts @@ -0,0 +1,60 @@ +import { Theme } from "@/typings/theme"; + +const defaultTheme: Theme = { + variables: { + "--background": "#0f0f0f", + "--background-tooltip": "rgba(0, 0, 0, 0.75)", + "--secondary-background": "#0f0f0f", + "--color": "#dfdfdf", + "--points": "#ffffff", + "--locked": "#bf8f8f", + "--bought": "#77bf5f", + "--link": "#02f2f2", + "--separator": "#dfdfdf", + "--border-radius": "25%", + "--danger": "rgb(220, 53, 69)", + "--modal-border": "solid 2px var(--color)", + "--feature-margin": "0px" + }, + stackedInfoboxes: false, + floatingTabs: true +}; + +export enum Themes { + Classic = "classic", + Paper = "paper", + Aqua = "aqua" +} + +export default { + classic: defaultTheme, + paper: { + ...defaultTheme, + variables: { + ...defaultTheme.variables, + "--background": "#2a323d", + "--secondary-background": "#333c4a", + "--locked": "#3a3e45", + "--bought": "#5C8A58", + "--separator": "#333c4a", + "--border-radius": "4px", + "--modal-border": "", + "--feature-margin": "5px" + }, + stackedInfoboxes: true, + floatingTabs: false + } as Theme, + aqua: { + ...defaultTheme, + variables: { + ...defaultTheme.variables, + "--background": "#001f3f", + "--background-tooltip": "rgba(0, 15, 31, 0.75)", + "--secondary-background": "#001f3f", + "--color": "#bfdfff", + "--points": "#dfefff", + "--locked": "#c4a7b3", + "--separator": "#bfdfff" + } + } as Theme +} as Record; diff --git a/src/game/enums.ts b/src/game/enums.ts new file mode 100644 index 0000000..f175079 --- /dev/null +++ b/src/game/enums.ts @@ -0,0 +1,30 @@ +export enum LayerType { + Static = "static", + Normal = "normal", + Custom = "custom", + None = "none" +} + +export enum Direction { + Up = "Up", + Down = "Down", + Left = "Left", + Right = "Right", + Default = "Up" +} + +export enum MilestoneDisplay { + All = "all", + Last = "last", + Configurable = "configurable", + Incomplete = "incomplete", + None = "none" +} + +export enum ImportingStatus { + NotImporting = "NOT_IMPORTING", + Importing = "IMPORTING", + Failed = "FAILED", + WrongID = "WRONG_ID", + Force = "FORCE" +} diff --git a/src/game/gameLoop.js b/src/game/gameLoop.js deleted file mode 100644 index 7849245..0000000 --- a/src/game/gameLoop.js +++ /dev/null @@ -1,156 +0,0 @@ -import { update as modUpdate, hasWon, pointGain } from '../data/mod'; -import Decimal from '../util/bignum'; -import modInfo from '../data/modInfo.json'; -import { layers } from './layers'; -import player from './player'; - -function updatePopups(/* diff */) { - // TODO -} - -function updateParticles(/* diff */) { - // TODO -} - -function updateOOMPS(diff) { - if (player.points != undefined) { - player.oompsMag = 0; - if (player.points.lte(new Decimal(1e100))) { - player.lastPoints = player.points; - return; - } - - let curr = player.points; - let prev = player.lastPoints || new Decimal(0); - player.lastPoints = curr; - if (curr.gt(prev)) { - if (curr.gte("10^^8")) { - curr = curr.slog(1e10); - prev = prev.slog(1e10); - player.oomps = curr.sub(prev).div(diff); - player.oompsMag = -1; - } else { - while (curr.div(prev).log(10).div(diff).gte("100") && player.oompsMag <= 5 && prev.gt(0)) { - curr = curr.log(10); - prev = prev.log(10); - player.oomps = curr.sub(prev).div(diff); - player.oompsMag++; - } - } - } - } -} - -function updateLayers(diff) { - // Update each active layer - const activeLayers = Object.keys(layers).filter(layer => !layers[layer].deactivated); - activeLayers.forEach(layer => { - if (player[layer].resetTime != undefined) { - player[layer].resetTime = player[layer].resetTime.add(diff); - } - if (layers[layer].passiveGeneration) { - player[layer].points = - player[layer].points.add(Decimal.times(layers[layer].resetGain, layers[layer].passiveGeneration).times(diff)); - } - layers[layer].update?.(diff); - }); - // Automate each active layer - activeLayers.forEach(layer => { - if (layers[layer].autoReset && layers[layer].canReset) { - layers[layer].reset(); - } - layers[layer].automate?.(); - if (layers[layer].upgrades && layers[layer].autoUpgrade) { - Object.values(layers[layer].upgrades).forEach(upgrade => upgrade.buy()); - } - }); - // Check each active layer for newly unlocked achievements or milestones - activeLayers.forEach(layer => { - if (layers[layer].milestones) { - Object.values(layers[layer].milestones).forEach(milestone => { - if (milestone.unlocked !== false && !milestone.earned && milestone.done) { - player[layer].milestones.push(milestone.id); - milestone.onComplete?.(); - // TODO popup notification - player[layer].lastMilestone = milestone.id; - } - }); - } - if (layers[layer].achievements) { - Object.values(layers[layer].achievements).forEach(achievement => { - if (achievement.unlocked !== false && !achievement.earned && achievement.done) { - player[layer].achievements.push(achievement.id); - achievement.onComplete?.(); - // TODO popup notification - } - }); - } - }); -} - -function update() { - let now = Date.now(); - let diff = (now - player.time) / 1e3; - player.time = now; - let trueDiff = diff; - - // Always update UI - updatePopups(trueDiff); - updateParticles(trueDiff); - player.lastTenTicks.push(trueDiff); - if (player.lastTenTicks.length > 10) { - player.lastTenTicks = player.lastTenTicks.slice(1); - } - - // Stop here if the game is paused on the win screen - if (hasWon.value && !player.keepGoing) { - return; - } - // Stop here if the player had a NaN value - if (player.hasNaN) { - return; - } - - diff = new Decimal(diff).max(0); - - // Add offline time if any - if (player.offTime != undefined) { - if (player.offTime.remain > modInfo.offlineLimit * 3600) { - player.offTime.remain = modInfo.offlineLimit * 3600; - } - if (player.offTime.remain > 0 && player.devSpeed !== 0) { - let offlineDiff = Math.max(player.offTime.remain / 10, diff); - player.offTime.remain -= offlineDiff; - diff = diff.add(offlineDiff); - } else if (player.devSpeed === 0) { - player.offTime.remain += diff.toNumber(); - } - if (!player.offlineProd || player.offTime.remain <= 0) { - player.offTime = undefined; - } - } - - // Cap at max tick length - diff = Decimal.min(diff, modInfo.maxTickLength); - - // Apply dev speed - if (player.devSpeed != undefined) { - diff = diff.times(player.devSpeed); - } - - // Update - if (diff.eq(0)) { - return; - } - player.timePlayed = player.timePlayed.add(diff); - if (player.points != undefined) { - player.points = player.points.add(Decimal.times(pointGain.value, diff)); - } - modUpdate(diff); - updateOOMPS(trueDiff); - updateLayers(diff); -} - -export default function startGameLoop() { - setInterval(update, 50); -} diff --git a/src/game/gameLoop.ts b/src/game/gameLoop.ts new file mode 100644 index 0000000..f197526 --- /dev/null +++ b/src/game/gameLoop.ts @@ -0,0 +1,171 @@ +import { hasWon, pointGain, update as modUpdate } from "@/data/mod"; +import modInfo from "@/data/modInfo.json"; +import Decimal, { DecimalSource } from "@/util/bignum"; +import { layers } from "./layers"; +import player from "./player"; + +/* eslint-disable-next-line @typescript-eslint/no-unused-vars */ +function updatePopups(diff: number) { + // TODO +} + +/* eslint-disable-next-line @typescript-eslint/no-unused-vars */ +function updateParticles(diff: number) { + // TODO +} + +function updateOOMPS(diff: DecimalSource) { + if (player.points != undefined) { + player.oompsMag = 0; + if (player.points.lte(new Decimal(1e100))) { + player.lastPoints = player.points; + return; + } + + let curr = player.points; + let prev = (player.lastPoints as Decimal) || new Decimal(0); + player.lastPoints = curr; + if (curr.gt(prev)) { + if (curr.gte("10^^8")) { + curr = curr.slog(1e10); + prev = prev.slog(1e10); + player.oomps = curr.sub(prev).div(diff); + player.oompsMag = -1; + } else { + while ( + curr + .div(prev) + .log(10) + .div(diff) + .gte("100") && + player.oompsMag <= 5 && + prev.gt(0) + ) { + curr = curr.log(10); + prev = prev.log(10); + player.oomps = curr.sub(prev).div(diff); + player.oompsMag++; + } + } + } + } +} + +function updateLayers(diff: DecimalSource) { + // Update each active layer + const activeLayers = Object.keys(layers).filter(layer => !layers[layer].deactivated); + activeLayers.forEach(layer => { + if (player.layers[layer].resetTime != undefined) { + player.layers[layer].resetTime = player.layers[layer].resetTime.add(diff); + } + if (layers[layer].passiveGeneration) { + const passiveGeneration = + typeof layers[layer].passiveGeneration == "boolean" + ? 1 + : (layers[layer].passiveGeneration as DecimalSource); + player.layers[layer].points = player.layers[layer].points.add( + Decimal.times(layers[layer].resetGain, passiveGeneration).times(diff) + ); + } + layers[layer].update?.(diff); + }); + // Automate each active layer + activeLayers.forEach(layer => { + if (layers[layer].autoReset && layers[layer].canReset) { + layers[layer].reset(); + } + layers[layer].automate?.(); + if (layers[layer].upgrades && layers[layer].autoUpgrade) { + Object.values(layers[layer].upgrades!.data).forEach(upgrade => upgrade.buy()); + } + }); + // Check each active layer for newly unlocked achievements or milestones + activeLayers.forEach(layer => { + if (layers[layer].milestones) { + Object.values(layers[layer].milestones!.data).forEach(milestone => { + if (milestone.unlocked !== false && !milestone.earned && milestone.done) { + player.layers[layer].milestones.push(milestone.id); + milestone.onComplete?.(); + // TODO popup notification + player.layers[layer].lastMilestone = milestone.id; + } + }); + } + if (layers[layer].achievements) { + Object.values(layers[layer].achievements!.data).forEach(achievement => { + if (achievement.unlocked !== false && !achievement.earned && achievement.done) { + player.layers[layer].achievements.push(achievement.id); + achievement.onComplete?.(); + // TODO popup notification + } + }); + } + }); +} + +function update() { + const now = Date.now(); + let diff: DecimalSource = (now - player.time) / 1e3; + player.time = now; + const trueDiff = diff; + + // Always update UI + updatePopups(trueDiff); + updateParticles(trueDiff); + player.lastTenTicks.push(trueDiff); + if (player.lastTenTicks.length > 10) { + player.lastTenTicks = player.lastTenTicks.slice(1); + } + + // Stop here if the game is paused on the win screen + if (hasWon.value && !player.keepGoing) { + return; + } + // Stop here if the player had a NaN value + if (player.hasNaN) { + return; + } + + diff = new Decimal(diff).max(0); + + // Add offline time if any + if (player.offlineTime != undefined) { + if (player.offlineTime.gt(modInfo.offlineLimit * 3600)) { + player.offlineTime = new Decimal(modInfo.offlineLimit * 3600); + } + if (player.offlineTime.gt(0) && player.devSpeed !== 0) { + const offlineDiff = Decimal.max(player.offlineTime.div(10), diff); + player.offlineTime = player.offlineTime.sub(offlineDiff); + diff = diff.add(offlineDiff); + } else if (player.devSpeed === 0) { + player.offlineTime = player.offlineTime.add(diff); + } + if (!player.offlineProd || player.offlineTime.lt(0)) { + player.offlineTime = null; + } + } + + // Cap at max tick length + diff = Decimal.min(diff, modInfo.maxTickLength); + + // Apply dev speed + if (player.devSpeed != undefined) { + diff = diff.times(player.devSpeed); + } + + // Update + if (diff.eq(0)) { + return; + } + player.timePlayed = player.timePlayed.add(diff); + if (player.points != undefined) { + player.points = player.points.add(Decimal.times(pointGain.value, diff)); + } + modUpdate(diff); + updateOOMPS(trueDiff); + updateLayers(diff); +} + +export default function startGameLoop(): void { + setInterval(update, 50); +} diff --git a/src/game/layers.js b/src/game/layers.js deleted file mode 100644 index af6d6c7..0000000 --- a/src/game/layers.js +++ /dev/null @@ -1,452 +0,0 @@ -import clone from 'lodash.clonedeep'; -import { isFunction, isPlainObject } from '../util/common'; -import { createProxy, createGridProxy } from '../util/proxies'; -import playerProxy from './player'; -import Decimal from '../util/bignum'; -import { noCache, getStartingBuyables, getStartingClickables, getStartingChallenges, defaultLayerProperties } from '../util/layers'; -import { applyPlayerData } from '../util/save'; -import { isRef } from 'vue'; - -export const layers = {}; -export const hotkeys = []; -window.layers = layers; - -export function addLayer(layer, player = null) { - player = player || playerProxy; - - // Check for required properties - if (!('id' in layer)) { - console.error(`Cannot add layer without a "id" property!`, layer); - return; - } - if (layer.type === "static" || layer.type === "normal") { - const missingProperty = [ 'baseAmount', 'requires' ].find(prop => !(prop in layer)); - if (missingProperty) { - console.error(`Cannot add layer without a "${missingProperty}" property!`, layer); - return; - } - } - - // Clone object to prevent modifying the original - layer = clone(layer); - - player[layer.id] = applyPlayerData({ - upgrades: [], - achievements: [], - milestones: [], - infoboxes: {}, - buyables: getStartingBuyables(layer), - clickables: getStartingClickables(layer), - challenges: getStartingChallenges(layer), - grids: {}, - ...layer.startData?.() - }, player[layer.id]); - - // Set default property values - layer = Object.assign({}, defaultLayerProperties, layer); - layer.layer = layer.id; - if (layer.type === "static" && (layer.base == undefined || Decimal.lte(layer.base, 1))) { - layer.base = 2; - } - - // Process each feature - for (let property of uncachedProperties) { - if (layer[property] && !isRef(layer.property)) { - layer[property].forceCached = false; - } - } - for (let property of gridProperties) { - if (layer[property]) { - setRowCol(layer[property]); - } - } - for (let property of featureProperties) { - if (layer[property]) { - setupFeature(layer.id, layer[property]); - } - } - if (layer.upgrades) { - for (let id in layer.upgrades) { - if (isPlainObject(layer.upgrades[id])) { - layer.upgrades[id].bought = function() { - return !layer.deactivated && playerProxy[layer.id].upgrades.some(upgrade => upgrade == id); - } - setDefault(layer.upgrades[id], 'canAfford', function() { - if (this.currencyInternalName) { - let name = this.currencyInternalName; - if (this.currencyLocation) { - return !(this.currencyLocation[name].lt(this.cost)); - } else if (this.currencyLayer) { - let lr = this.currencyLayer; - return !(playerProxy[lr][name].lt(this.cost)); - } else { - return !(playerProxy[name].lt(this.cost)); - } - } else { - return !(playerProxy[this.layer].points.lt(this.cost)) - } - }); - setDefault(layer.upgrades[id], 'pay', function() { - if (this.bought || !this.canAfford) { - return; - } - if (this.currencyInternalName) { - let name = this.currencyInternalName - if (this.currencyLocation) { - if (this.currencyLocation[name].lt(this.cost)) { - return; - } - this.currencyLocation[name] = this.currencyLocation[name].sub(this.cost); - } else if (this.currencyLayer) { - let lr = this.currencyLayer; - if (playerProxy[lr][name].lt(this.cost)) { - return; - } - playerProxy[lr][name] = playerProxy[lr][name].sub(this.cost); - } else { - if (playerProxy[name].lt(this.cost)) { - return; - } - playerProxy[name] = playerProxy[name].sub(this.cost); - } - } else { - if (playerProxy[this.layer].points.lt(this.cost)) { - return; - } - playerProxy[this.layer].points = playerProxy[this.layer].points.sub(this.cost); - } - }, false); - setDefault(layer.upgrades[id], 'buy', function() { - if (this.bought || !this.canAfford) { - return; - } - this.pay(); - playerProxy[this.layer].upgrades.push(this.id); - this.onPurchase?.(); - }, false); - } - } - } - if (layer.achievements) { - for (let id in layer.achievements) { - if (isPlainObject(layer.achievements[id])) { - layer.achievements[id].earned = function() { - return !layer.deactivated && playerProxy[layer.id].achievements.some(achievement => achievement == id); - } - setDefault(layer.achievements[id], 'onComplete', null, false); - } - } - } - if (layer.challenges) { - layer.activeChallenge = function() { - return Object.values(this.challenges).find(challenge => challenge.active); - } - for (let id in layer.challenges) { - if (isPlainObject(layer.challenges[id])) { - layer.challenges[id].shown = function() { - return this.unlocked !== false && (playerProxy.hideChallenges === false || !this.maxed); - } - layer.challenges[id].completed = function() { - return !layer.deactivated && playerProxy[layer.id].challenges[id]?.gt(0); - } - layer.challenges[id].completions = function() { - return playerProxy[layer.id].challenges[id]; - } - layer.challenges[id].maxed = function() { - return !layer.deactivated && Decimal.gte(playerProxy[layer.id].challenges[id], this.completionLimit); - } - layer.challenges[id].active = function() { - return !layer.deactivated && playerProxy[layer.id].activeChallenge === id; - } - layer.challenges[id].toggle = noCache(function() { - let exiting = playerProxy[layer.id].activeChallenge === id; - if (exiting) { - if (this.canComplete && !this.maxed) { - let completions = this.canComplete; - if (completions === true) { - completions = 1; - } - playerProxy[layer.id].challenges[id] = - Decimal.min(playerProxy[layer.id].challenges[id].add(completions), this.completionLimit); - this.onComplete?.(); - } - playerProxy[layer.id].activeChallenge = null; - this.onExit?.(); - layer.reset(true); - } else if (!exiting && this.canStart) { - layer.reset(true); - playerProxy[layer.id].activeChallenge = id; - this.onEnter?.(); - } - }); - setDefault(layer.challenges[id], 'onComplete', null, false); - setDefault(layer.challenges[id], 'onEnter', null, false); - setDefault(layer.challenges[id], 'onExit', null, false); - setDefault(layer.challenges[id], 'canStart', true); - setDefault(layer.challenges[id], 'completionLimit', new Decimal(1)); - setDefault(layer.challenges[id], 'mark', function() { - return Decimal.gt(this.completionLimit, 1) && this.maxed; - }); - setDefault(layer.challenges[id], 'canComplete', function() { - if (!this.active) { - return false; - } - if (this.currencyInternalName) { - let name = this.currencyInternalName; - if (this.currencyLocation) { - return !(this.currencyLocation[name].lt(this.goal)); - } else if (this.currencyLayer) { - let lr = this.currencyLayer; - return !(playerProxy[lr][name].lt(this.goal)); - } else { - return !(playerProxy[name].lt(this.goal)); - } - } else { - return !(playerProxy.points.lt(this.goal)); - } - }); - } - } - } - if (layer.buyables) { - setDefault(layer.buyables, 'respec', null, false); - setDefault(layer.buyables, 'reset', function() { - playerProxy[this.layer].buyables = getStartingBuyables(layer); - }, false); - for (let id in layer.buyables) { - if (isPlainObject(layer.buyables[id])) { - layer.buyables[id].amount = function() { - return playerProxy[layer.id].buyables[id]; - } - layer.buyables[id].amountSet = function(amount) { - playerProxy[layer.id].buyables[id] = amount; - } - layer.buyables[id].canBuy = function() { - return !layer.deactivated && this.unlocked !== false && this.canAfford !== false && - Decimal.lt(playerProxy[layer.id].buyables[id], this.purchaseLimit); - } - setDefault(layer.buyables[id], 'purchaseLimit', new Decimal(Infinity)); - setDefault(layer.buyables[id], 'sellOne', null, false); - setDefault(layer.buyables[id], 'sellAll', null, false); - if (layer.buyables[id].cost != undefined) { - setDefault(layer.buyables[id], 'buy', function() { - if (this.canBuy) { - playerProxy[this.layer].points = playerProxy[this.layer].points.sub(this.cost()); - this.amount = this.amount.add(1); - } - }, false); - } - } - } - } - if (layer.clickables) { - layer.clickables.layer = layer.id; - setDefault(layer.clickables, 'masterButtonClick', null, false); - if (layer.clickables.masterButtonDisplay != undefined) { - setDefault(layer.clickables, 'showMaster', true); - } - for (let id in layer.clickables) { - if (isPlainObject(layer.clickables[id])) { - layer.clickables[id].state = function() { - return playerProxy[layer.id].clickables[id]; - } - layer.clickables[id].stateSet = function(state) { - playerProxy[layer.id].clickables[id] = state; - } - setDefault(layer.clickables[id], 'click', null, false); - setDefault(layer.clickables[id], 'hold', null, false); - } - } - } - if (layer.milestones) { - for (let id in layer.milestones) { - if (isPlainObject(layer.milestones[id])) { - layer.milestones[id].earned = function() { - return !layer.deactivated && playerProxy[layer.id].milestones.some(milestone => milestone == id); - } - layer.milestones[id].shown = function() { - if (!this.unlocked) { - return false; - } - switch (playerProxy.msDisplay) { - default: - case "all": - return true; - case "last": - return this.optionsDisplay || !this.earned || - playerProxy[this.layer].milestones[playerProxy[this.layer].milestones.length - 1] === this.id; - case "configurable": - return this.optionsDisplay || !this.earned; - case "incomplete": - return !this.earned; - case "none": - return false; - } - } - } - } - } - if (layer.grids) { - for (let id in layer.grids) { - if (isPlainObject(layer.grids[id])) { - setDefault(player[layer.id].grids, id, {}); - layer.grids[id].getData = function(cell) { - if (playerProxy[layer.id].grids[id][cell] != undefined) { - return playerProxy[layer.id].grids[id][cell]; - } - if (isFunction(this.getStartData)) { - return this.getStartData(cell); - } - return this.getStartData; - } - layer.grids[id].dataSet = function(cell, data) { - playerProxy[layer.id].grids[id][cell] = data; - } - setDefault(layer.grids[id], 'getUnlocked', true, false); - setDefault(layer.grids[id], 'getCanClick', true, false); - setDefault(layer.grids[id], 'getStartData', "", false); - setDefault(layer.grids[id], 'getStyle', null, false); - setDefault(layer.grids[id], 'click', null, false); - setDefault(layer.grids[id], 'hold', null, false); - setDefault(layer.grids[id], 'getTitle', null, false); - setDefault(layer.grids[id], 'getDisplay', null, false); - layer.grids[id] = createGridProxy(layer.grids[id]); - } - } - } - if (layer.subtabs) { - layer.activeSubtab = function() { - if (layer.subtabs[playerProxy.subtabs[layer.id].mainTabs] && - layer.subtabs[playerProxy.subtabs[layer.id].mainTabs].unlocked !== false) { - return layer.subtabs[playerProxy.subtabs[layer.id].mainTabs]; - } - // Default to first unlocked tab - return Object.values(layer.subtabs).find(subtab => subtab.unlocked !== false); - } - setDefault(player, 'subtabs', {}); - setDefault(player.subtabs, layer.id, {}); - setDefault(player.subtabs[layer.id], 'mainTabs', Object.keys(layer.subtabs)[0]); - for (let id in layer.subtabs) { - if (isPlainObject(layer.subtabs[id])) { - layer.subtabs[id].active = function() { - return playerProxy.subtabs[this.layer].mainTabs === this.id; - } - } - } - } - if (layer.microtabs) { - setDefault(player, 'subtabs', {}); - setDefault(player.subtabs, layer.id, {}); - for (let family in layer.microtabs) { - layer.microtabs[family].activeMicrotab = function() { - if (this[playerProxy.subtabs[this.layer][family]] && this[playerProxy.subtabs[this.layer][family]].unlocked !== false) { - return this[playerProxy.subtabs[this.layer][family]]; - } - // Default to first unlocked tab - return this[Object.keys(this).find(microtab => microtab !== 'activeMicrotab' && this[microtab].unlocked !== false)]; - } - setDefault(player.subtabs[layer.id], family, Object.keys(layer.microtabs[family]).find(tab => tab !== 'activeMicrotab')); - layer.microtabs[family].layer = layer.id; - layer.microtabs[family].family = family; - for (let id in layer.microtabs[family]) { - if (isPlainObject(layer.microtabs[family][id])) { - layer.microtabs[family][id].layer = layer.id; - layer.microtabs[family][id].family = family; - layer.microtabs[family][id].id = id; - layer.microtabs[family][id].active = function() { - return playerProxy.subtabs[this.layer][this.family] === this.id; - } - } - } - } - } - if (layer.hotkeys) { - for (let id in layer.hotkeys) { - if (isPlainObject(layer.hotkeys[id])) { - setDefault(layer.hotkeys[id], 'press', null, false); - setDefault(layer.hotkeys[id], 'unlocked', function() { - return layer.unlocked; - }); - } - } - } - - // Create layer proxy - layer = createProxy(layer); - - // Register layer - layers[layer.id] = layer; - - // Register hotkeys - if (layer.hotkeys) { - for (let id in layer.hotkeys) { - hotkeys[layer.hotkeys[id].key] = layer.hotkeys[id]; - } - } -} - -export function removeLayer(layer) { - // Un-set hotkeys - if (layers[layer].hotkeys) { - for (let id in layers[layer].hotkeys) { - delete hotkeys[id]; - } - } - - delete layers[layer]; -} - -export function reloadLayer(layer) { - removeLayer(layer.id); - - // Re-create layer - addLayer(layer); -} - -const uncachedProperties = [ 'startData', 'click', 'update', 'reset', 'hardReset' ]; -const gridProperties = [ 'upgrades', 'achievements', 'challenges', 'buyables', 'clickables' ]; -const featureProperties = [ 'upgrades', 'achievements', 'challenges', 'buyables', 'clickables', 'milestones', 'bars', - 'infoboxes', 'grids', 'hotkeys', 'subtabs' ]; - -function setRowCol(features) { - if (features.rows && features.cols) { - return - } - let maxRow = 0; - let maxCol = 0; - for (let id in features) { - if (!isNaN(id)) { - if (Math.floor(id / 10) > maxRow) { - maxRow = Math.floor(id / 10); - } - if (id % 10 > maxCol) { - maxCol = id % 10; - } - } - } - features.rows = maxRow; - features.cols = maxCol; -} - -function setupFeature(layer, features) { - features.layer = layer; - for (let id in features) { - const feature = features[id]; - if (isPlainObject(feature)) { - feature.id = id; - feature.layer = layer; - if (feature.unlocked == undefined) { - feature.unlocked = true; - } - } - } -} - -function setDefault(object, key, value, forceCached) { - if (object[key] == undefined && value != undefined) { - object[key] = value; - } - if (object[key] != undefined && isFunction(object[key]) && forceCached != undefined) { - object[key].forceCached = forceCached; - } -} diff --git a/src/game/layers.ts b/src/game/layers.ts new file mode 100644 index 0000000..2ce627a --- /dev/null +++ b/src/game/layers.ts @@ -0,0 +1,604 @@ +import { CacheableFunction } from "@/typings/cacheableFunction"; +import { Achievement } from "@/typings/features/achievement"; +import { Buyable } from "@/typings/features/buyable"; +import { Challenge } from "@/typings/features/challenge"; +import { Clickable } from "@/typings/features/clickable"; +import { + Feature, + Features, + GridFeatures, + RawFeature, + RawFeatures, + RawGridFeatures +} from "@/typings/features/feature"; +import { Grid } from "@/typings/features/grid"; +import { Hotkey } from "@/typings/features/hotkey"; +import { Milestone } from "@/typings/features/milestone"; +import { Microtab, Subtab } from "@/typings/features/subtab"; +import { Upgrade } from "@/typings/features/upgrade"; +import { Layer, RawLayer } from "@/typings/layer"; +import { PlayerData } from "@/typings/player"; +import { State } from "@/typings/state"; +import Decimal, { DecimalSource } from "@/util/bignum"; +import { isFunction } from "@/util/common"; +import { + defaultLayerProperties, + getStartingBuyables, + getStartingChallenges, + getStartingClickables, + noCache +} from "@/util/layers"; +import { createGridProxy, createLayerProxy } from "@/util/proxies"; +import { applyPlayerData } from "@/util/save"; +import clone from "lodash.clonedeep"; +import { isRef } from "vue"; +import { default as playerProxy } from "./player"; + +export const layers: Record> = {}; +export const hotkeys: Hotkey[] = []; +window.layers = layers; + +export function addLayer(layer: RawLayer, player?: Partial): void { + player = player || playerProxy; + + // Check for required properties + if (!("id" in layer)) { + console.error(`Cannot add layer without a "id" property!`, layer); + return; + } + if (layer.type === "static" || layer.type === "normal") { + const missingProperty = ["baseAmount", "requires"].find(prop => !(prop in layer)); + if (missingProperty) { + console.error(`Cannot add layer without a "${missingProperty}" property!`, layer); + return; + } + } + + // Clone object to prevent modifying the original + layer = clone(layer); + + setDefault(player, "layers", {}); + player.layers![layer.id] = applyPlayerData( + { + points: new Decimal(0), + unlocked: false, + resetTime: new Decimal(0), + upgrades: [], + achievements: [], + milestones: [], + infoboxes: {}, + buyables: getStartingBuyables(layer.buyables?.data), + clickables: getStartingClickables(layer.clickables?.data), + challenges: getStartingChallenges(layer.challenges?.data), + grids: {}, + confirmRespecBuyables: false, + ...(layer.startData?.() || {}) + }, + player.layers![layer.id] + ); + + // Set default property values + layer = Object.assign({}, defaultLayerProperties, layer); + layer.layer = layer.id; + if (layer.type === "static" && layer.base == undefined) { + layer.base = 2; + } + + // Process each feature + const uncachedProperties = ["startData", "click", "update", "reset", "hardReset"]; + for (const property of uncachedProperties) { + if (layer[property] && !isRef(layer.property) && isFunction(layer[property])) { + (layer[property] as CacheableFunction).forceCached = false; + } + } + if (layer.upgrades) { + setupFeatures< + RawGridFeatures, Upgrade>, + GridFeatures, + Upgrade + >(layer.id, layer.upgrades!); + setRowCol(layer.upgrades); + for (const id in layer.upgrades.data) { + layer.upgrades.data[id].bought = function() { + return ( + !layers[this.layer].deactivated && + playerProxy.layers[this.layer].upgrades.some( + (upgrade: string | number) => upgrade == id + ) + ); + }; + setDefault(layer.upgrades.data[id], "canAfford", function() { + if (this.currencyInternalName) { + const name = this.currencyInternalName; + if (this.currencyLocation) { + return !Decimal.lt(this.currencyLocation[name], this.cost); + } else if (this.currencyLayer) { + return !Decimal.lt( + playerProxy.layers[this.currencyLayer][name] as DecimalSource, + this.cost + ); + } else { + return !Decimal.lt(playerProxy[name] as DecimalSource, this.cost); + } + } else { + return !playerProxy.layers[this.layer].points.lt(this.cost); + } + }); + setDefault( + layer.upgrades.data[id], + "pay", + function() { + if (this.bought || !this.canAfford) { + return; + } + if (this.currencyInternalName) { + const name = this.currencyInternalName; + if (this.currencyLocation) { + if (Decimal.lt(this.currencyLocation[name], this.cost)) { + return; + } + this.currencyLocation[name] = Decimal.sub( + this.currencyLocation[name], + this.cost + ); + } else if (this.currencyLayer) { + const lr = this.currencyLayer; + if ( + Decimal.lt(playerProxy.layers[lr][name] as DecimalSource, this.cost) + ) { + return; + } + playerProxy.layers[lr][name] = Decimal.sub( + playerProxy.layers[lr][name] as DecimalSource, + this.cost + ); + } else { + if (Decimal.lt(playerProxy[name] as DecimalSource, this.cost)) { + return; + } + playerProxy[name] = Decimal.sub( + playerProxy[name] as DecimalSource, + this.cost + ); + } + } else { + if (playerProxy.layers[this.layer].points.lt(this.cost)) { + return; + } + playerProxy.layers[this.layer].points = playerProxy.layers[ + this.layer + ].points.sub(this.cost); + } + }, + false + ); + setDefault( + layer.upgrades.data[id], + "buy", + function() { + if (this.bought || !this.canAfford) { + return; + } + this.pay(); + playerProxy.layers[this.layer].upgrades.push(this.id); + this.onPurchase?.(); + }, + false + ); + setDefault(layer.upgrades.data[id], "onPurchase", undefined, false); + } + } + if (layer.achievements) { + setupFeatures< + RawGridFeatures, Achievement>, + GridFeatures, + Achievement + >(layer.id, layer.achievements!); + setRowCol(layer.achievements); + for (const id in layer.achievements.data) { + layer.achievements.data[id].earned = function() { + return ( + !layers[this.layer].deactivated && + playerProxy.layers[this.layer].achievements.some( + (achievement: string | number) => achievement == id + ) + ); + }; + setDefault(layer.achievements.data[id], "onComplete", undefined, false); + } + } + if (layer.challenges) { + setupFeatures< + RawGridFeatures, Challenge>, + GridFeatures, + Challenge + >(layer.id, layer.challenges); + setRowCol(layer.challenges); + layer.activeChallenge = function() { + return Object.values(this.challenges!.data).find( + (challenge: Challenge) => challenge.active + ); + }; + for (const id in layer.challenges.data) { + layer.challenges.data[id].shown = function() { + return ( + this.unlocked !== false && (playerProxy.hideChallenges === false || !this.maxed) + ); + }; + layer.challenges.data[id].completed = function() { + return ( + !layers[this.layer].deactivated && + playerProxy.layers[this.layer].challenges[id]?.gt(0) + ); + }; + layer.challenges.data[id].completions = function() { + return playerProxy.layers[this.layer].challenges[id]; + }; + layer.challenges.data[id].maxed = function() { + return ( + !layers[this.layer].deactivated && + Decimal.gte(playerProxy.layers[this.layer].challenges[id], this.completionLimit) + ); + }; + layer.challenges.data[id].active = function() { + return ( + !layers[this.layer].deactivated && + playerProxy.layers[this.layer].activeChallenge === id + ); + }; + layer.challenges.data[id].toggle = noCache(function(this: Challenge) { + const exiting = playerProxy.layers[this.layer].activeChallenge === id; + if (exiting) { + if (this.canComplete && !this.maxed) { + let completions: boolean | DecimalSource = this.canComplete; + if (completions === true) { + completions = 1; + } + playerProxy.layers[this.layer].challenges[id] = Decimal.min( + playerProxy.layers[this.layer].challenges[id].add(completions), + this.completionLimit + ); + this.onComplete?.(); + } + playerProxy.layers[this.layer].activeChallenge = null; + this.onExit?.(); + layers[this.layer].reset(true); + } else if (!exiting && this.canStart) { + layers[this.layer].reset(true); + playerProxy.layers[this.layer].activeChallenge = id; + this.onEnter?.(); + } + }); + setDefault(layer.challenges.data[id], "onComplete", undefined, false); + setDefault(layer.challenges.data[id], "onEnter", undefined, false); + setDefault(layer.challenges.data[id], "onExit", undefined, false); + setDefault(layer.challenges.data[id], "canStart", true); + setDefault(layer.challenges.data[id], "completionLimit", new Decimal(1)); + setDefault(layer.challenges.data[id], "mark", function() { + return Decimal.gt(this.completionLimit, 1) && this.maxed; + }); + setDefault(layer.challenges.data[id], "canComplete", function() { + if (!this.active) { + return false; + } + if (this.currencyInternalName) { + const name = this.currencyInternalName; + if (this.currencyLocation) { + return !Decimal.lt(this.currencyLocation[name], this.goal); + } else if (this.currencyLayer) { + const lr = this.currencyLayer; + return !Decimal.lt( + playerProxy.layers[lr][name] as DecimalSource, + this.goal + ); + } else { + return !Decimal.lt(playerProxy[name] as DecimalSource, this.goal); + } + } else { + return !playerProxy.points.lt(this.goal); + } + }); + } + } + if (layer.buyables) { + setupFeatures< + RawGridFeatures, Buyable>, + GridFeatures, + Buyable + >(layer.id, layer.buyables); + setRowCol(layer.buyables); + setDefault(layer.buyables, "respec", undefined, false); + setDefault( + layer.buyables, + "reset", + function(this: NonNullable) { + playerProxy.layers[this.layer].buyables = getStartingBuyables(layer.buyables?.data); + }, + false + ); + for (const id in layer.buyables.data) { + layer.buyables.data[id].amount = function() { + return playerProxy.layers[this.layer].buyables[id]; + }; + layer.buyables.data[id].amountSet = function(amount: Decimal) { + playerProxy.layers[this.layer].buyables[id] = amount; + }; + layer.buyables.data[id].canBuy = function() { + return ( + !layers[this.layer].deactivated && + this.unlocked !== false && + this.canAfford !== false && + Decimal.lt(playerProxy.layers[this.layer].buyables[id], this.purchaseLimit) + ); + }; + setDefault(layer.buyables.data[id], "purchaseLimit", new Decimal(Infinity)); + setDefault(layer.buyables.data[id], "sellOne", undefined, false); + setDefault(layer.buyables.data[id], "sellAll", undefined, false); + if (layer.buyables.data[id].cost != undefined) { + setDefault( + layer.buyables.data[id], + "buy", + function() { + if (this.canBuy) { + playerProxy.layers[this.layer].points = playerProxy.layers[ + this.layer + ].points.sub(this.cost!); + this.amount = this.amount.add(1); + } + }, + false + ); + } + } + } + if (layer.clickables) { + setupFeatures< + RawGridFeatures, Clickable>, + GridFeatures, + Clickable + >(layer.id, layer.clickables); + setRowCol(layer.clickables); + setDefault(layer.clickables, "masterButtonClick", undefined, false); + if (layer.clickables.masterButtonDisplay != undefined) { + setDefault(layer.clickables, "showMasterButton", true); + } + for (const id in layer.clickables.data) { + layer.clickables.data[id].state = function() { + return playerProxy.layers[this.layer].clickables[id]; + }; + layer.clickables.data[id].stateSet = function(state: State) { + playerProxy.layers[this.layer].clickables[id] = state; + }; + setDefault(layer.clickables.data[id], "canClick", true); + setDefault(layer.clickables.data[id], "click", undefined, false); + setDefault(layer.clickables.data[id], "hold", undefined, false); + } + } + if (layer.milestones) { + setupFeatures, Milestone>, Features, Milestone>( + layer.id, + layer.milestones + ); + for (const id in layer.milestones.data) { + layer.milestones.data[id].earned = function() { + return ( + !layer.deactivated && + playerProxy.layers[this.layer].milestones.some( + (milestone: string | number) => milestone == id + ) + ); + }; + layer.milestones.data[id].shown = function() { + if (!this.unlocked) { + return false; + } + switch (playerProxy.msDisplay) { + default: + case "all": + return true; + case "last": + return ( + this.optionsDisplay || + !this.earned || + playerProxy.layers[this.layer].milestones[ + playerProxy.layers[this.layer].milestones.length - 1 + ] === this.id + ); + case "configurable": + return this.optionsDisplay || !this.earned; + case "incomplete": + return !this.earned; + case "none": + return false; + } + }; + setDefault(layer.milestones.data[id], "done", false); + } + } + if (layer.grids) { + setupFeatures, Grid>, Features, Grid>( + layer.id, + layer.grids + ); + for (const id in layer.grids.data) { + setDefault(player.layers![layer.id].grids, id, {}); + layer.grids.data[id].getData = function(cell): State { + if (playerProxy.layers[this.layer].grids[id][cell] != undefined) { + return playerProxy.layers[this.layer].grids[id][cell]; + } + if (isFunction(this.getStartData)) { + return (this.getStartData as (this: Grid, cell: string | number) => State)( + cell + ); + } + return this.getStartData; + }; + layer.grids.data[id].setData = function(cell, data) { + playerProxy.layers[this.layer].grids[id][cell] = data; + }; + setDefault(layer.grids.data[id], "getUnlocked", true, false); + setDefault(layer.grids.data[id], "getCanClick", true, false); + setDefault(layer.grids.data[id], "getStartData", "", false); + setDefault(layer.grids.data[id], "getStyle", undefined, false); + setDefault(layer.grids.data[id], "click", undefined, false); + setDefault(layer.grids.data[id], "hold", undefined, false); + setDefault(layer.grids.data[id], "getTitle", undefined, false); + layer.grids.data[id] = createGridProxy(layer.grids.data[id]) as Grid; + } + } + if (layer.subtabs) { + layer.activeSubtab = function() { + if ( + layers[this.layer].subtabs![playerProxy.subtabs[this.layer].mainTabs!] && + layers[this.layer].subtabs![playerProxy.subtabs[this.layer].mainTabs!].unlocked !== + false + ) { + return layers[this.layer].subtabs![playerProxy.subtabs[this.layer].mainTabs!]; + } + // Default to first unlocked tab + return Object.values(layers[this.layer].subtabs!).find( + (subtab: Subtab) => subtab.unlocked !== false + ); + }; + setDefault(player, "subtabs", {}); + setDefault(player.subtabs!, layer.id, {}); + setDefault(player.subtabs![layer.id], "mainTabs", Object.keys(layer.subtabs)[0]); + for (const id in layer.subtabs) { + layer.subtabs[id].active = function() { + return playerProxy.subtabs[this.layer].mainTabs === this.id; + }; + } + } + if (layer.microtabs) { + setDefault(player, "subtabs", {}); + setDefault(player.subtabs!, layer.id, {}); + for (const family in layer.microtabs) { + if (Object.keys(layer.microtabs[family]).length === 0) { + console.warn( + "Cannot create microtab family with 0 tabs", + layer.id, + family, + layer.microtabs[family] + ); + continue; + } + layer.microtabs[family].activeMicrotab = function() { + if ( + this.data[playerProxy.subtabs[this.layer as string][family]] && + this.data[playerProxy.subtabs[this.layer as string][family]].unlocked !== false + ) { + return this[playerProxy.subtabs[this.layer as string][family]]; + } + // Default to first unlocked tab + const firstUnlocked: string | undefined = Object.keys(this).find( + microtab => + microtab !== "activeMicrotab" && this.data[microtab].unlocked !== false + ); + return firstUnlocked != undefined ? this[firstUnlocked] : undefined; + }; + setDefault( + player.subtabs![layer.id], + family, + Object.keys(layer.microtabs[family]).find(tab => tab !== "activeMicrotab")! + ); + layer.microtabs[family].layer = layer.id; + layer.microtabs[family].family = family; + for (const id in layer.microtabs[family].data) { + const microtab: RawFeature = layer.microtabs[family].data[id]; + microtab.layer = layer.id; + microtab.family = family; + microtab.id = id; + microtab.active = function() { + return playerProxy.subtabs[this.layer][this.family] === this.id; + }; + } + } + } + if (layer.hotkeys) { + for (const id in layer.hotkeys) { + setDefault(layer.hotkeys[id], "press", undefined, false); + setDefault(layer.hotkeys[id], "unlocked", function() { + return layers[this.layer].unlocked; + }); + } + } + + // Create layer proxy + layer = createLayerProxy(layer) as Layer; + + // Register layer + layers[layer.id] = layer as Layer; + + // Register hotkeys + if (layers[layer.id].hotkeys) { + for (const hotkey of layers[layer.id].hotkeys!) { + hotkeys.push(hotkey); + } + } +} + +export function removeLayer(layer: string): void { + // Un-set hotkeys + if (layers[layer].hotkeys) { + for (const hotkey of Object.values(layers[layer].hotkeys!)) { + const index = hotkeys.indexOf(hotkey); + if (index >= 0) { + hotkeys.splice(index, 1); + } + } + } + + delete layers[layer]; +} + +export function reloadLayer(layer: Layer): void { + removeLayer(layer.id); + + // Re-create layer + addLayer(layer); +} + +function setRowCol, S extends Feature>(features: RawGridFeatures) { + if (features.rows && features.cols) { + return; + } + let maxRow = 0; + let maxCol = 0; + for (const id in features) { + const index = Number(id); + if (!isNaN(index)) { + if (Math.floor(index / 10) > maxRow) { + maxRow = Math.floor(index / 10); + } + if (index % 10 > maxCol) { + maxCol = index % 10; + } + } + } + features.rows = maxRow; + features.cols = maxCol; +} + +function setupFeatures, R extends Features, S extends Feature>( + layer: string, + features: T +) { + features.layer = layer; + for (const id in features.data) { + const feature = features.data[id]; + (feature as Feature).id = id; + (feature as Feature).layer = layer; + if (feature.unlocked == undefined) { + (feature as Feature).unlocked = true; + } + } +} + +function setDefault(object: T, key: K, value: T[K], forceCached?: boolean) { + if (object[key] == undefined && value != undefined) { + object[key] = value; + } + if (object[key] != undefined && isFunction(object[key]) && forceCached != undefined) { + Object.assign(object[key], { forceCached }); + } +} diff --git a/src/game/player.js b/src/game/player.js deleted file mode 100644 index 59e2190..0000000 --- a/src/game/player.js +++ /dev/null @@ -1,52 +0,0 @@ -import { reactive } from 'vue'; -import { isPlainObject } from '../util/common'; -import Decimal from '../util/bignum'; - -const state = reactive({}); - -const playerHandler = { - get(target, key) { - if (key === '__state' || key === '__path') { - return target[key]; - } - if (target.__state[key] == undefined) { - return; - } - if (isPlainObject(target.__state[key]) && !(target.__state[key] instanceof Decimal)) { - if (target.__state[key] !== target[key]?.__state) { - const path = [ ...target.__path, key ]; - target[key] = new Proxy({ __state: target.__state[key], __path: path }, playerHandler); - } - return target[key]; - } - - return target.__state[key]; - }, - set(target, property, value, receiver) { - if (!state.hasNaN && ((typeof value === 'number' && isNaN(value)) || (value instanceof Decimal && (isNaN(value.sign) || isNaN(value.layer) || isNaN(value.mag))))) { - const currentValue = target.__state[property]; - if (!((typeof currentValue === 'number' && isNaN(currentValue)) || (currentValue instanceof Decimal && (isNaN(currentValue.sign) || isNaN(currentValue.layer) || isNaN(currentValue.mag))))) { - state.autosave = false; - state.hasNaN = true; - state.NaNPath = [ ...target.__path, property ]; - state.NaNReceiver = receiver; - console.error(`Attempted to set NaN value`, [ ...target.__path, property ], target.__state); - throw 'Attempted to set NaN value. See above for details'; - } - } - target.__state[property] = value; - if (property === 'points') { - if (target.__state.best != undefined) { - target.__state.best = Decimal.max(target.__state.best, value); - } - if (target.__state.total != undefined) { - const diff = Decimal.sub(value, target.__state.points); - if (diff.gt(0)) { - target.__state.total = target.__state.total.add(diff); - } - } - } - return true; - } -}; -export default window.player = new Proxy({ __state: state, __path: [ 'player' ] }, playerHandler); diff --git a/src/game/player.ts b/src/game/player.ts new file mode 100644 index 0000000..c1f0e2a --- /dev/null +++ b/src/game/player.ts @@ -0,0 +1,112 @@ +import { Themes } from "@/data/themes"; +import { PlayerData } from "@/typings/player"; +import Decimal from "@/util/bignum"; +import { isPlainObject } from "@/util/common"; +import { reactive } from "vue"; +import { ImportingStatus, MilestoneDisplay } from "./enums"; + +const state = reactive({ + id: "", + points: new Decimal(0), + oomps: new Decimal(0), + oompsMag: 0, + name: "", + tabs: [], + time: -1, + autosave: true, + offlineProd: true, + offlineTime: null, + timePlayed: new Decimal(0), + keepGoing: false, + lastTenTicks: [], + showTPS: true, + msDisplay: MilestoneDisplay.All, + hideChallenges: false, + theme: Themes.Paper, + subtabs: {}, + minimized: {}, + modID: "", + modVersion: "", + hasNaN: false, + NaNPath: [], + NaNReceiver: null, + importing: ImportingStatus.NotImporting, + saveToImport: "", + saveToExport: "", + layers: {} +}); + +const playerHandler: ProxyHandler> = { + get(target: Record, key: string): any { + if (key === "__state" || key === "__path") { + return target[key]; + } + if (target.__state[key] == undefined) { + return; + } + if (isPlainObject(target.__state[key]) && !(target.__state[key] instanceof Decimal)) { + if (target.__state[key] !== target[key]?.__state) { + const path = [...target.__path, key]; + target[key] = new Proxy( + { __state: target.__state[key], __path: path }, + playerHandler + ); + } + return target[key]; + } + + return target.__state[key]; + }, + set( + target: Record, + property: string, + value: any, + receiver: ProxyConstructor + ): boolean { + if ( + !state.hasNaN && + ((typeof value === "number" && isNaN(value)) || + (value instanceof Decimal && + (isNaN(value.sign) || isNaN(value.layer) || isNaN(value.mag)))) + ) { + const currentValue = target.__state[property]; + if ( + !( + (typeof currentValue === "number" && isNaN(currentValue)) || + (currentValue instanceof Decimal && + (isNaN(currentValue.sign) || + isNaN(currentValue.layer) || + isNaN(currentValue.mag))) + ) + ) { + state.autosave = false; + state.hasNaN = true; + state.NaNPath = [...target.__path, property]; + state.NaNReceiver = (receiver as unknown) as Record; + console.error( + `Attempted to set NaN value`, + [...target.__path, property], + target.__state + ); + throw "Attempted to set NaN value. See above for details"; + } + } + target.__state[property] = value; + if (property === "points") { + if (target.__state.best != undefined) { + target.__state.best = Decimal.max(target.__state.best, value); + } + if (target.__state.total != undefined) { + const diff = Decimal.sub(value, target.__state.points); + if (diff.gt(0)) { + target.__state.total = target.__state.total.add(diff); + } + } + } + return true; + } +}; +export default window.player = new Proxy( + { __state: state, __path: ["player"] }, + playerHandler +) as PlayerData; diff --git a/src/lib/break_eternity.js b/src/lib/break_eternity.js deleted file mode 100644 index 857f825..0000000 --- a/src/lib/break_eternity.js +++ /dev/null @@ -1,2 +0,0 @@ -/* eslint-disable */ -"use strict";function _instanceof(t,r){return null!=r&&"undefined"!=typeof Symbol&&r[Symbol.hasInstance]?!!r[Symbol.hasInstance](t):t instanceof r}function _typeof(t){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}!function(t,r){"object"===("undefined"==typeof exports?"undefined":_typeof(exports))&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define(r):(t=t||self).Decimal=r()}(void 0,function(){var t=Math.log10(9e15),r=function(){for(var t=[],r=-323;r<=308;r++)t.push(Number("1e"+r));return function(r){return t[r+323]}}(),i=function(t){return h.fromValue_noAlloc(t)},e=function(t,r,i){return h.fromComponents(t,r,i)},n=function(t,r,i){return h.fromComponents_noNormalize(t,r,i)},a=function(t,r){var i=r+1,e=Math.ceil(Math.log10(Math.abs(t))),n=Math.round(t*Math.pow(10,i-e))*Math.pow(10,e-i);return parseFloat(n.toFixed(Math.max(i-e,0)))},s=function(t){return Math.sign(t)*Math.log10(Math.abs(t))},o=function(t){var r,i,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1e-10;if(!Number.isFinite(t))return t;if(0===t)return t;if(1===t)return.5671432904097838;r=t<10?0:Math.log(t)-Math.log(Math.log(t));for(var n=0;n<100;++n){if(i=(t*Math.exp(-r)+r*r)/(r+1),Math.abs(i-r)1&&void 0!==arguments[1]?arguments[1]:2,e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:n(1,0,1);return i(t).tetrate(r,e)},h.iteratedexp=function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:2,e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:n(1,0,1);return i(t).iteratedexp(r,e)},h.iteratedlog=function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:10,e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1;return i(t).iteratedlog(r,e)},h.layeradd10=function(t,r){return i(t).layeradd10(r)},h.layeradd=function(t,r){var e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:10;return i(t).layeradd(r,e)},h.slog=function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:10;return i(t).slog(r)},h.lambertw=function(t){return i(t).lambertw()},h.ssqrt=function(t){return i(t).ssqrt()},h.pentate=function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:2,e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:n(1,0,1);return i(t).pentate(r,e)},h.affordGeometricSeries=function(t,r,e,n){return this.affordGeometricSeries_core(i(t),i(r),i(e),n)},h.sumGeometricSeries=function(t,r,e,n){return this.sumGeometricSeries_core(t,i(r),i(e),n)},h.affordArithmeticSeries=function(t,r,e,n){return this.affordArithmeticSeries_core(i(t),i(r),i(e),i(n))},h.sumArithmeticSeries=function(t,r,e,n){return this.sumArithmeticSeries_core(i(t),i(r),i(e),i(n))},h.efficiencyOfPurchase=function(t,r,e){return this.efficiencyOfPurchase_core(i(t),i(r),i(e))},h.randomDecimalForTesting=function(t){if(20*Math.random()<1)return n(0,0,0);var r=Math.random()>.5?1:-1;if(20*Math.random()<1)return n(r,0,1);var i=Math.floor(Math.random()*(t+1)),a=0===i?616*Math.random()-308:16*Math.random();Math.random()>.9&&(a=Math.trunc(a));var s=Math.pow(10,a);return Math.random()>.9&&(s=Math.trunc(s)),e(r,i,s)},h.affordGeometricSeries_core=function(t,r,i,e){var n=r.mul(i.pow(e));return h.floor(t.div(n).mul(i.sub(1)).add(1).log10().div(i.log10()))},h.sumGeometricSeries_core=function(t,r,i,e){return r.mul(i.pow(e)).mul(h.sub(1,i.pow(t))).div(h.sub(1,i))},h.affordArithmeticSeries_core=function(t,r,i,e){var n=r.add(e.mul(i)).sub(i.div(2)),a=n.pow(2);return n.neg().add(a.add(i.mul(t).mul(2)).sqrt()).div(i).floor()},h.sumArithmeticSeries_core=function(t,r,i,e){var n=r.add(e.mul(i));return t.div(2).mul(n.mul(2).plus(t.sub(1).mul(i)))},h.efficiencyOfPurchase_core=function(t,r,i){return t.div(r).add(t.div(i))},h.prototype.normalize=function(){if(0===this.sign||0===this.mag&&0===this.layer)return this.sign=0,this.mag=0,this.layer=0,this;if(0===this.layer&&this.mag<0&&(this.mag=-this.mag,this.sign=-this.sign),0===this.layer&&this.mag<1/9e15)return this.layer+=1,this.mag=Math.log10(this.mag),this;var r=Math.abs(this.mag),i=Math.sign(this.mag);if(r>=9e15)return this.layer+=1,this.mag=i*Math.log10(r),this;for(;r0;)this.layer-=1,0===this.layer?this.mag=Math.pow(10,this.mag):(this.mag=i*Math.pow(10,r),r=Math.abs(this.mag),i=Math.sign(this.mag));return 0===this.layer&&(this.mag<0?(this.mag=-this.mag,this.sign=-this.sign):0===this.mag&&(this.sign=0)),this},h.prototype.fromComponents=function(t,r,i){return this.sign=t,this.layer=r,this.mag=i,this.normalize(),this},h.prototype.fromComponents_noNormalize=function(t,r,i){return this.sign=t,this.layer=r,this.mag=i,this},h.prototype.fromMantissaExponent=function(t,r){return this.layer=1,this.sign=Math.sign(t),t=Math.abs(t),this.mag=r+Math.log10(t),this.normalize(),this},h.prototype.fromMantissaExponent_noNormalize=function(t,r){return this.fromMantissaExponent(t,r),this},h.prototype.fromDecimal=function(t){return this.sign=t.sign,this.layer=t.layer,this.mag=t.mag,this},h.prototype.fromNumber=function(t){return this.mag=Math.abs(t),this.sign=Math.sign(t),this.layer=0,this.normalize(),this};h.prototype.fromString=function(t){var r=(t=t.replace(",","")).split("^^^");if(2===r.length){var n=parseFloat(r[0]),a=parseFloat(r[1]),o=1;if(2===(l=r[1].split(";")).length){o=parseFloat(l[1]);isFinite(o)||(o=1)}if(isFinite(n)&&isFinite(a)){var u=h.pentate(n,a,o);return this.sign=u.sign,this.layer=u.layer,this.mag=u.mag,this}}var g=t.split("^^");if(2===g.length){var l;n=parseFloat(g[0]),a=parseFloat(g[1]);if(2===(l=g[1].split(";")).length){o=parseFloat(l[1]);isFinite(o)||(o=1)}if(isFinite(n)&&isFinite(a)){u=h.tetrate(n,a,o);return this.sign=u.sign,this.layer=u.layer,this.mag=u.mag,this}}var m,f=t.split("^");if(2===f.length){n=parseFloat(f[0]);var c=parseFloat(f[1]);if(isFinite(n)&&isFinite(c)){u=h.pow(n,c);return this.sign=u.sign,this.layer=u.layer,this.mag=u.mag,this}}if(2===(m=(t=t.trim().toLowerCase()).split("pt")).length){n=10,a=parseFloat(m[0]),m[1]=m[1].replace("(",""),m[1]=m[1].replace(")","");o=parseFloat(m[1]);if(isFinite(o)||(o=1),isFinite(n)&&isFinite(a)){u=h.tetrate(n,a,o);return this.sign=u.sign,this.layer=u.layer,this.mag=u.mag,this}}if(2===(m=t.split("p")).length){n=10,a=parseFloat(m[0]),m[1]=m[1].replace("(",""),m[1]=m[1].replace(")","");o=parseFloat(m[1]);if(isFinite(o)||(o=1),isFinite(n)&&isFinite(a)){u=h.tetrate(n,a,o);return this.sign=u.sign,this.layer=u.layer,this.mag=u.mag,this}}var p=t.split("e"),y=p.length-1;if(0===y){var d=parseFloat(t);if(isFinite(d))return this.fromNumber(d)}else if(1===y){d=parseFloat(t);if(isFinite(d)&&0!==d)return this.fromNumber(d)}var M=t.split("e^");if(2===M.length){this.sign=1,"-"==M[0].charAt(0)&&(this.sign=-1);for(var b="",N=0;N=43&&v<=57||101===v))return this.layer=parseFloat(b),this.mag=parseFloat(M[1].substr(N+1)),this.normalize(),this;b+=M[1].charAt(N)}}if(y<1)return this.sign=0,this.layer=0,this.mag=0,this;var _=parseFloat(p[0]);if(0===_)return this.sign=0,this.layer=0,this.mag=0,this;c=parseFloat(p[p.length-1]);if(y>=2){var F=parseFloat(p[p.length-2]);isFinite(F)&&(c*=Math.sign(F),c+=s(F))}if(isFinite(_))if(1===y)this.sign=Math.sign(_),this.layer=1,this.mag=c+Math.log10(Math.abs(_));else{if(this.sign=Math.sign(_),this.layer=y,2===y){u=h.mul(e(1,2,c),i(_));return this.sign=u.sign,this.layer=u.layer,this.mag=u.mag,this}this.mag=c}else this.sign="-"===p[0]?-1:1,this.layer=y,this.mag=c;return this.normalize(),this},h.prototype.fromValue=function(t){return _instanceof(t,h)?this.fromDecimal(t):"number"==typeof t?this.fromNumber(t):"string"==typeof t?this.fromString(t):(this.sign=0,this.layer=0,this.mag=0,this)},h.prototype.toNumber=function(){return Number.isFinite(this.layer)?0===this.layer?this.sign*this.mag:1===this.layer?this.sign*Math.pow(10,this.mag):this.mag>0?this.sign>0?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:0:Number.NaN},h.prototype.mantissaWithDecimalPlaces=function(t){return isNaN(this.m)?Number.NaN:0===this.m?0:a(this.m,t)},h.prototype.magnitudeWithDecimalPlaces=function(t){return isNaN(this.mag)?Number.NaN:0===this.mag?0:a(this.mag,t)},h.prototype.toString=function(){return 0===this.layer?this.mag<1e21&&this.mag>1e-7||0===this.mag?(this.sign*this.mag).toString():this.m+"e"+this.e:1===this.layer?this.m+"e"+this.e:this.layer<=5?(-1===this.sign?"-":"")+"e".repeat(this.layer)+this.mag:(-1===this.sign?"-":"")+"(e^"+this.layer+")"+this.mag},h.prototype.toExponential=function(t){return 0===this.layer?(this.sign*this.mag).toExponential(t):this.toStringWithDecimalPlaces(t)},h.prototype.toFixed=function(t){return 0===this.layer?(this.sign*this.mag).toFixed(t):this.toStringWithDecimalPlaces(t)},h.prototype.toPrecision=function(t){return this.e<=-7?this.toExponential(t-1):t>this.e?this.toFixed(t-this.exponent-1):this.toExponential(t-1)},h.prototype.valueOf=function(){return this.toString()},h.prototype.toJSON=function(){return this.toString()},h.prototype.toStringWithDecimalPlaces=function(t){return 0===this.layer?this.mag<1e21&&this.mag>1e-7||0===this.mag?(this.sign*this.mag).toFixed(t):a(this.m,t)+"e"+a(this.e,t):1===this.layer?a(this.m,t)+"e"+a(this.e,t):this.layer<=5?(-1===this.sign?"-":"")+"e".repeat(this.layer)+a(this.mag,t):(-1===this.sign?"-":"")+"(e^"+this.layer+")"+a(this.mag,t)},h.prototype.abs=function(){return n(0===this.sign?0:1,this.layer,this.mag)},h.prototype.neg=function(){return n(-this.sign,this.layer,this.mag)},h.prototype.negate=function(){return this.neg()},h.prototype.negated=function(){return this.neg()},h.prototype.sign=function(){return this.sign},h.prototype.sgn=function(){return this.sign},h.prototype.round=function(){return this.mag<0?h.dZero:0===this.layer?e(this.sign,0,Math.round(this.mag)):this},h.prototype.floor=function(){return this.mag<0?h.dZero:0===this.layer?e(this.sign,0,Math.floor(this.mag)):this},h.prototype.ceil=function(){return this.mag<0?h.dZero:0===this.layer?e(this.sign,0,Math.ceil(this.mag)):this},h.prototype.trunc=function(){return this.mag<0?h.dZero:0===this.layer?e(this.sign,0,Math.trunc(this.mag)):this},h.prototype.add=function(t){var r,a,s=i(t);if(!Number.isFinite(this.layer))return this;if(!Number.isFinite(s.layer))return s;if(0===this.sign)return s;if(0===s.sign)return this;if(this.sign===-s.sign&&this.layer===s.layer&&this.mag===s.mag)return n(0,0,0);if(this.layer>=2||s.layer>=2)return this.maxabs(s);if(h.cmpabs(this,s)>0?(r=this,a=s):(r=s,a=this),0===r.layer&&0===a.layer)return i(r.sign*r.mag+a.sign*a.mag);var o=r.layer*Math.sign(r.mag),u=a.layer*Math.sign(a.mag);if(o-u>=2)return r;if(0===o&&-1===u){if(Math.abs(a.mag-Math.log10(r.mag))>17)return r;var g=Math.pow(10,Math.log10(r.mag)-a.mag),l=a.sign+r.sign*g;return e(Math.sign(l),1,a.mag+Math.log10(Math.abs(l)))}if(1===o&&0===u){if(Math.abs(r.mag-Math.log10(a.mag))>17)return r;g=Math.pow(10,r.mag-Math.log10(a.mag)),l=a.sign+r.sign*g;return e(Math.sign(l),1,Math.log10(a.mag)+Math.log10(Math.abs(l)))}if(Math.abs(r.mag-a.mag)>17)return r;g=Math.pow(10,r.mag-a.mag),l=a.sign+r.sign*g;return e(Math.sign(l),1,a.mag+Math.log10(Math.abs(l)))},h.prototype.plus=function(t){return this.add(t)},h.prototype.sub=function(t){return this.add(i(t).neg())},h.prototype.subtract=function(t){return this.sub(t)},h.prototype.minus=function(t){return this.sub(t)},h.prototype.mul=function(t){var r,a,s=i(t);if(!Number.isFinite(this.layer))return this;if(!Number.isFinite(s.layer))return s;if(0===this.sign||0===s.sign)return n(0,0,0);if(this.layer===s.layer&&this.mag===-s.mag)return n(this.sign*s.sign,0,1);if(this.layer>s.layer||this.layer==s.layer&&Math.abs(this.mag)>Math.abs(s.mag)?(r=this,a=s):(r=s,a=this),0===r.layer&&0===a.layer)return i(r.sign*a.sign*r.mag*a.mag);if(r.layer>=3||r.layer-a.layer>=2)return e(r.sign*a.sign,r.layer,r.mag);if(1===r.layer&&0===a.layer)return e(r.sign*a.sign,1,r.mag+Math.log10(a.mag));if(1===r.layer&&1===a.layer)return e(r.sign*a.sign,1,r.mag+a.mag);if(2===r.layer&&1===a.layer){var o=e(Math.sign(r.mag),r.layer-1,Math.abs(r.mag)).add(e(Math.sign(a.mag),a.layer-1,Math.abs(a.mag)));return e(r.sign*a.sign,o.layer+1,o.sign*o.mag)}if(2===r.layer&&2===a.layer){o=e(Math.sign(r.mag),r.layer-1,Math.abs(r.mag)).add(e(Math.sign(a.mag),a.layer-1,Math.abs(a.mag)));return e(r.sign*a.sign,o.layer+1,o.sign*o.mag)}throw Error("Bad arguments to mul: "+this+", "+t)},h.prototype.multiply=function(t){return this.mul(t)},h.prototype.times=function(t){return this.mul(t)},h.prototype.div=function(t){var r=i(t);return this.mul(r.recip())},h.prototype.divide=function(t){return this.div(t)},h.prototype.divideBy=function(t){return this.div(t)},h.prototype.dividedBy=function(t){return this.div(t)},h.prototype.recip=function(){return 0===this.mag?h.dNaN:0===this.layer?e(this.sign,0,1/this.mag):e(this.sign,this.layer,-this.mag)},h.prototype.reciprocal=function(){return this.recip()},h.prototype.reciprocate=function(){return this.recip()},h.prototype.cmp=function(t){var r=i(t);return this.sign>r.sign?1:this.sign0?this.layer:-this.layer,n=r.mag>0?r.layer:-r.layer;return e>n?1:er.mag?1:this.mag0?r:this},h.prototype.clamp=function(t,r){return this.max(t).min(r)},h.prototype.clampMin=function(t){return this.max(t)},h.prototype.clampMax=function(t){return this.min(t)},h.prototype.cmp_tolerance=function(t,r){var e=i(t);return this.eq_tolerance(e,r)?0:this.cmp(e)},h.prototype.compare_tolerance=function(t,r){return this.cmp_tolerance(t,r)},h.prototype.eq_tolerance=function(t,r){var e=i(t);if(null==r&&(r=1e-7),this.sign!==e.sign)return!1;if(Math.abs(this.layer-e.layer)>1)return!1;var n=this.mag,a=e.mag;return this.layer>e.layer&&(a=s(a)),this.layer0?e(Math.sign(this.mag),this.layer-1,Math.abs(this.mag)):e(1,0,Math.log10(this.mag))},h.prototype.log10=function(){return this.sign<=0?h.dNaN:this.layer>0?e(Math.sign(this.mag),this.layer-1,Math.abs(this.mag)):e(this.sign,0,Math.log10(this.mag))},h.prototype.log=function(t){return t=i(t),this.sign<=0?h.dNaN:t.sign<=0?h.dNaN:1===t.sign&&0===t.layer&&1===t.mag?h.dNaN:0===this.layer&&0===t.layer?e(this.sign,0,Math.log(this.mag)/Math.log(t.mag)):h.div(this.log10(),t.log10())},h.prototype.log2=function(){return this.sign<=0?h.dNaN:0===this.layer?e(this.sign,0,Math.log2(this.mag)):1===this.layer?e(Math.sign(this.mag),0,3.321928094887362*Math.abs(this.mag)):2===this.layer?e(Math.sign(this.mag),1,Math.abs(this.mag)+.5213902276543247):e(Math.sign(this.mag),this.layer-1,Math.abs(this.mag))},h.prototype.ln=function(){return this.sign<=0?h.dNaN:0===this.layer?e(this.sign,0,Math.log(this.mag)):1===this.layer?e(Math.sign(this.mag),0,2.302585092994046*Math.abs(this.mag)):2===this.layer?e(Math.sign(this.mag),1,Math.abs(this.mag)+.36221568869946325):e(Math.sign(this.mag),this.layer-1,Math.abs(this.mag))},h.prototype.logarithm=function(t){return this.log(t)},h.prototype.pow=function(t){var r=this,e=i(t);if(0===r.sign)return r;if(1===r.sign&&0===r.layer&&1===r.mag)return r;if(0===e.sign)return n(1,0,1);if(1===e.sign&&0===e.layer&&1===e.mag)return r;var a=r.absLog10().mul(e).pow10();return-1===this.sign&&e.toNumber()%2==1?a.neg():a},h.prototype.pow10=function(){if(!Number.isFinite(this.layer)||!Number.isFinite(this.mag))return h.dNaN;var t=this;if(0===t.layer){var r=Math.pow(10,t.sign*t.mag);if(Number.isFinite(r)&&Math.abs(r)>.1)return e(1,0,r);if(0===t.sign)return h.dOne;t=n(t.sign,t.layer+1,Math.log10(t.mag))}return t.sign>0&&t.mag>0?e(t.sign,t.layer+1,t.mag):t.sign<0&&t.mag>0?e(-t.sign,t.layer+1,-t.mag):h.dOne},h.prototype.pow_base=function(t){return i(t).pow(this)},h.prototype.root=function(t){var r=i(t);return this.pow(r.recip())},h.prototype.factorial=function(){return this.mag<0?this.toNumber().add(1).gamma():0===this.layer?this.add(1).gamma():1===this.layer?h.exp(h.mul(this,h.ln(this).sub(1))):h.exp(this)},h.prototype.gamma=function(){if(this.mag<0)return this.recip();if(0===this.layer){if(this.lt(n(1,0,24)))return i(function(t){if(!isFinite(t))return t;if(t<-50)return t===Math.trunc(t)?Number.NEGATIVE_INFINITY:0;for(var r=1;t<10;)r*=t,++t;var i=.9189385332046727;i+=(.5+(t-=1))*Math.log(t),i-=t;var e=t*t,n=t;return i+=1/(12*n),i+=1/(360*(n*=e)),i+=1/(1260*(n*=e)),i+=1/(1680*(n*=e)),i+=1/(1188*(n*=e)),i+=691/(360360*(n*=e)),i+=7/(1092*(n*=e)),i+=3617/(122400*(n*=e)),Math.exp(i)/r}(this.sign*this.mag));var t=this.mag-1,r=.9189385332046727;r+=(t+.5)*Math.log(t);var e=t*t,a=t,s=12*a,o=1/s,u=(r-=t)+o;if(u===r)return h.exp(r);if((u=(r=u)-(o=1/(s=360*(a*=e))))===r)return h.exp(r);r=u;var g=1/(s=1260*(a*=e));return r+=g,r-=g=1/(s=1680*(a*=e)),h.exp(r)}return 1===this.layer?h.exp(h.mul(this,h.ln(this).sub(1))):h.exp(this)},h.prototype.lngamma=function(){return this.gamma().ln()},h.prototype.exp=function(){return this.mag<0?h.dOne:0===this.layer&&this.mag<=709.7?i(Math.exp(this.sign*this.mag)):0===this.layer?e(1,1,this.sign*Math.log10(Math.E)*this.mag):1===this.layer?e(1,2,this.sign*(Math.log10(.4342944819032518)+this.mag)):e(1,this.layer+1,this.sign*this.mag)},h.prototype.sqr=function(){return this.pow(2)},h.prototype.sqrt=function(){if(0===this.layer)return i(Math.sqrt(this.sign*this.mag));if(1===this.layer)return e(1,2,Math.log10(this.mag)-.3010299956639812);var t=h.div(n(this.sign,this.layer-1,this.mag),n(1,0,2));return t.layer+=1,t.normalize(),t},h.prototype.cube=function(){return this.pow(3)},h.prototype.cbrt=function(){return this.pow(1/3)},h.prototype.tetrate=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:2,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:n(1,0,1);if(t===Number.POSITIVE_INFINITY){var e=h.ln(this).neg();return e.lambertw().div(e)}if(t<0)return h.iteratedlog(r,this,-t);r=i(r);var a=t-(t=Math.trunc(t));0!==a&&(r.eq(h.dOne)?(++t,r=new h(a)):r=this.eq(10)?r.layeradd10(a):r.layeradd(a,this));for(var s=0;s3)return n(r.sign,r.layer+(t-s-1),r.mag);if(s>100)return r}return r},h.prototype.iteratedexp=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:2,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:n(1,0,1);return this.tetrate(t,r)},h.prototype.iteratedlog=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:10,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;if(r<0)return h.tetrate(t,-r,this);t=i(t);var e=i(this),n=r-(r=Math.trunc(r));if(e.layer-t.layer>3){var a=Math.min(r,e.layer-t.layer-3);r-=a,e.layer-=a}for(var s=0;s100)return e}return n>0&&n<1&&(e=t.eq(10)?e.layeradd10(-n):e.layeradd(-n,t)),e},h.prototype.slog=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:10;if(this.mag<0)return h.dNegOne;t=i(t);var r=0,e=i(this);if(e.layer-t.layer>3){var n=e.layer-t.layer-3;r+=n,e.layer-=n}for(var a=0;a<100;++a)if(e.lt(h.dZero))e=h.pow(t,e),r-=1;else{if(e.lte(h.dOne))return i(r+e.toNumber()-1);r+=1,e=h.log(e,t)}return i(r)},h.prototype.layeradd10=function(t){t=h.fromValue_noAlloc(t).toNumber();var r,e=i(this);t>=1&&(t-=r=Math.trunc(t),e.layer+=r);if(t<=-1&&(t-=r=Math.trunc(t),e.layer+=r,e.layer<0))for(var n=0;n<100;++n){if(e.layer++,e.mag=Math.log10(e.mag),!isFinite(e.mag))return e;if(e.layer>=0)break}if(t>0){for(var a=0;Number.isFinite(e.mag)&&e.mag<10;)e.mag=Math.pow(10,e.mag),++a;for(e.mag>1e10&&(e.mag=Math.log10(e.mag),e.layer++),(s=Math.log10(Math.log(1e10)/Math.log(e.mag),10))0;)e.mag=Math.log10(e.mag),--a}else if(t<0){for(a=0;Number.isFinite(e.mag)&&e.mag<10;)e.mag=Math.pow(10,e.mag),++a;var s;for(e.mag>1e10&&(e.mag=Math.log10(e.mag),e.layer++),(s=Math.log10(1/Math.log10(e.mag)))>t&&(e.mag=1e10,e.layer--,t-=s),e.mag=Math.pow(e.mag,Math.pow(10,t));a>0;)e.mag=Math.log10(e.mag),--a}for(;e.layer<0;)e.layer++,e.mag=Math.log10(e.mag);return e.normalize(),e},h.prototype.layeradd=function(t,r){var i=this.slog(r).toNumber()+t;return i>=0?h.tetrate(r,i):Number.isFinite(i)?i>=-1?h.log(h.tetrate(r,i+1),r):void h.log(h.log(h.tetrate(r,i+2),r),r):h.dNaN},h.prototype.lambertw=function(){if(this.lt(-.3678794411710499))throw Error("lambertw is unimplemented for results less than -1, sorry!");return this.mag<0?i(o(this.toNumber())):0===this.layer?i(o(this.sign*this.mag)):1===this.layer?u(this):2===this.layer?u(this):this.layer>=3?n(this.sign,this.layer-1,this.mag):void 0};var u=function(t){var r,i,e,n,a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1e-10;if(!Number.isFinite(t.mag))return t;if(0===t)return t;if(1===t)return.5671432904097838;h.abs(t);r=h.ln(t);for(var s=0;s<100;++s){if(i=h.exp(-r),e=r.sub(t.mul(i)),n=r.sub(e.div(r.add(1).sub(r.add(2).mul(e).div(h.mul(2,r).add(2))))),h.abs(n.sub(r)).lt(h.abs(n).mul(a)))return n;r=n}throw Error("Iteration failed to converge: "+t)};return h.prototype.ssqrt=function(){if(1==this.sign&&this.layer>=3)return n(this.sign,this.layer-1,this.mag);var t=this.ln();return t.div(t.lambertw())},h.prototype.pentate=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:2,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:n(1,0,1);r=i(r);var e=t-(t=Math.trunc(t));0!==e&&(r.eq(h.dOne)?(++t,r=new h(e)):r=this.eq(10)?r.layeradd10(e):r.layeradd(e,this));for(var a=0;a10)return r}return r},h.prototype.sin=function(){return this.mag<0?this:0===this.layer?i(Math.sin(this.sign*this.mag)):n(0,0,0)},h.prototype.cos=function(){return this.mag<0?h.dOne:0===this.layer?i(Math.cos(this.sign*this.mag)):n(0,0,0)},h.prototype.tan=function(){return this.mag<0?this:0===this.layer?i(Math.tan(this.sign*this.mag)):n(0,0,0)},h.prototype.asin=function(){return this.mag<0?this:0===this.layer?i(Math.asin(this.sign*this.mag)):n(Number.NaN,Number.NaN,Number.NaN)},h.prototype.acos=function(){return this.mag<0?i(Math.acos(this.toNumber())):0===this.layer?i(Math.acos(this.sign*this.mag)):n(Number.NaN,Number.NaN,Number.NaN)},h.prototype.atan=function(){return this.mag<0?this:0===this.layer?i(Math.atan(this.sign*this.mag)):i(Math.atan(Infinity*this.sign))},h.prototype.sinh=function(){return this.exp().sub(this.negate().exp()).div(2)},h.prototype.cosh=function(){return this.exp().add(this.negate().exp()).div(2)},h.prototype.tanh=function(){return this.sinh().div(this.cosh())},h.prototype.asinh=function(){return h.ln(this.add(this.sqr().add(1).sqrt()))},h.prototype.acosh=function(){return h.ln(this.add(this.sqr().sub(1).sqrt()))},h.prototype.atanh=function(){return this.abs().gte(1)?n(Number.NaN,Number.NaN,Number.NaN):h.ln(this.add(1).div(i(1).sub(this))).div(2)},h.prototype.ascensionPenalty=function(t){return 0===t?this:this.root(h.pow(10,t))},h.prototype.egg=function(){return this.add(9)},h.prototype.lessThanOrEqualTo=function(t){return this.cmp(t)<1},h.prototype.lessThan=function(t){return this.cmp(t)<0},h.prototype.greaterThanOrEqualTo=function(t){return this.cmp(t)>-1},h.prototype.greaterThan=function(t){return this.cmp(t)>0},h}();return h.dZero=n(0,0,0),h.dOne=n(1,0,1),h.dNegOne=n(-1,0,1),h.dTwo=n(1,0,2),h.dTen=n(1,0,10),h.dNaN=n(Number.NaN,Number.NaN,Number.NaN),h.dInf=n(1,Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY),h.dNegInf=n(-1,Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY),h.dNumberMax=e(1,0,Number.MAX_VALUE),h.dNumberMin=e(1,0,Number.MIN_VALUE),h}); \ No newline at end of file diff --git a/src/lib/break_eternity.ts b/src/lib/break_eternity.ts new file mode 100644 index 0000000..91fdd71 --- /dev/null +++ b/src/lib/break_eternity.ts @@ -0,0 +1,2717 @@ +/* eslint-disable @typescript-eslint/no-this-alias */ +/* eslint-disable prettier/prettier */ +export type CompareResult = -1 | 0 | 1; + +const MAX_SIGNIFICANT_DIGITS = 17; //Maximum number of digits of precision to assume in Number + +const EXP_LIMIT = 9e15; //If we're ABOVE this value, increase a layer. (9e15 is close to the largest integer that can fit in a Number.) + +const LAYER_DOWN: number = Math.log10(9e15); + +const FIRST_NEG_LAYER = 1 / 9e15; //At layer 0, smaller non-zero numbers than this become layer 1 numbers with negative mag. After that the pattern continues as normal. + +const NUMBER_EXP_MAX = 308; //The largest exponent that can appear in a Number, though not all mantissas are valid here. + +const NUMBER_EXP_MIN = -324; //The smallest exponent that can appear in a Number, though not all mantissas are valid here. + +const MAX_ES_IN_A_ROW = 5; //For default toString behaviour, when to swap from eee... to (e^n) syntax. + +const IGNORE_COMMAS = true; +const COMMAS_ARE_DECIMAL_POINTS = false; + +const powerOf10 = (function () { + // We need this lookup table because Math.pow(10, exponent) + // when exponent's absolute value is large is slightly inaccurate. + // You can fix it with the power of math... or just make a lookup table. + // Faster AND simpler + const powersOf10: number[] = []; + + for (let i = NUMBER_EXP_MIN + 1; i <= NUMBER_EXP_MAX; i++) { + powersOf10.push(Number("1e" + i)); + } + + const indexOf0InPowersOf10 = 323; + return function (power: number) { + return powersOf10[power + indexOf0InPowersOf10]; + }; +})(); + +const D = function D(value: DecimalSource): Decimal { + return Decimal.fromValue_noAlloc(value); +}; + +const FC = function (sign: number, layer: number, mag: number) { + return Decimal.fromComponents(sign, layer, mag); +}; + +const FC_NN = function FC_NN(sign: number, layer: number, mag: number) { + return Decimal.fromComponents_noNormalize(sign, layer, mag); +}; + +const ME = function ME(mantissa: number, exponent: number) { + return Decimal.fromMantissaExponent(mantissa, exponent); +}; + +const ME_NN = function ME_NN(mantissa: number, exponent: number) { + return Decimal.fromMantissaExponent_noNormalize(mantissa, exponent); +}; + +const decimalPlaces = function decimalPlaces(value: number, places: number): number { + const len = places + 1; + const numDigits = Math.ceil(Math.log10(Math.abs(value))); + const rounded = Math.round(value * Math.pow(10, len - numDigits)) * Math.pow(10, numDigits - len); + return parseFloat(rounded.toFixed(Math.max(len - numDigits, 0))); +}; + +const f_maglog10 = function (n: number) { + return Math.sign(n) * Math.log10(Math.abs(n)); +}; + +//from HyperCalc source code +const f_gamma = function (n: number) { + if (!isFinite(n)) { + return n; + } + if (n < -50) { + if (n === Math.trunc(n)) { + return Number.NEGATIVE_INFINITY; + } + return 0; + } + + let scal1 = 1; + while (n < 10) { + scal1 = scal1 * n; + ++n; + } + + n -= 1; + let l = 0.9189385332046727; //0.5*Math.log(2*Math.PI) + l = l + (n + 0.5) * Math.log(n); + l = l - n; + const n2 = n * n; + let np = n; + l = l + 1 / (12 * np); + np = np * n2; + l = l + 1 / (360 * np); + np = np * n2; + l = l + 1 / (1260 * np); + np = np * n2; + l = l + 1 / (1680 * np); + np = np * n2; + l = l + 1 / (1188 * np); + np = np * n2; + l = l + 691 / (360360 * np); + np = np * n2; + l = l + 7 / (1092 * np); + np = np * n2; + l = l + 3617 / (122400 * np); + + return Math.exp(l) / scal1; +}; + +const _twopi = 6.2831853071795864769252842; // 2*pi +const _EXPN1 = 0.36787944117144232159553; // exp(-1) +const OMEGA = 0.56714329040978387299997; // W(1, 0) +//from https://math.stackexchange.com/a/465183 +// The evaluation can become inaccurate very close to the branch point +const f_lambertw = function (z: number, tol = 1e-10): number { + let w; + let wn; + + if (!Number.isFinite(z)) { + return z; + } + if (z === 0) { + return z; + } + if (z === 1) { + return OMEGA; + } + + if (z < 10) { + w = 0; + } else { + w = Math.log(z) - Math.log(Math.log(z)); + } + + for (let i = 0; i < 100; ++i) { + wn = (z * Math.exp(-w) + w * w) / (w + 1); + if (Math.abs(wn - w) < tol * Math.abs(wn)) { + return wn; + } else { + w = wn; + } + } + + throw Error(`Iteration failed to converge: ${z.toString()}`); + //return Number.NaN; +}; + +//from https://github.com/scipy/scipy/blob/8dba340293fe20e62e173bdf2c10ae208286692f/scipy/special/lambertw.pxd +// The evaluation can become inaccurate very close to the branch point +// at ``-1/e``. In some corner cases, `lambertw` might currently +// fail to converge, or can end up on the wrong branch. +function d_lambertw(z: Decimal, tol = 1e-10): Decimal { + let w; + let ew, wew, wewz, wn; + + if (!Number.isFinite(z.mag)) { + return z; + } + if (z === Decimal.dZero) { + return z; + } + if (z === Decimal.dOne) { + //Split out this case because the asymptotic series blows up + return D(OMEGA); + } + + const absz = Decimal.abs(z); + //Get an initial guess for Halley's method + w = Decimal.ln(z); + + //Halley's method; see 5.9 in [1] + + for (let i = 0; i < 100; ++i) { + ew = Decimal.exp(-w); + wewz = w.sub(z.mul(ew)); + wn = w.sub(wewz.div(w.add(1).sub(w.add(2).mul(wewz).div(Decimal.mul(2, w).add(2))))); + if (Decimal.abs(wn.sub(w)).lt(Decimal.abs(wn).mul(tol))) { + return wn; + } else { + w = wn; + } + } + + throw Error(`Iteration failed to converge: ${z.toString()}`); + //return Decimal.dNaN; +} + +export type DecimalSource = Decimal | number | string; + +/** + * The Decimal's value is simply mantissa * 10^exponent. + */ +export default class Decimal { + public static readonly dZero = FC_NN(0, 0, 0); + public static readonly dOne = FC_NN(1, 0, 1); + public static readonly dNegOne = FC_NN(-1, 0, 1); + public static readonly dTwo = FC_NN(1, 0, 2); + public static readonly dTen = FC_NN(1, 0, 10); + public static readonly dNaN = FC_NN(Number.NaN, Number.NaN, Number.NaN); + public static readonly dInf = FC_NN(1, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY); + public static readonly dNegInf = FC_NN(-1, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY); + public static readonly dNumberMax = FC(1, 0, Number.MAX_VALUE); + public static readonly dNumberMin = FC(1, 0, Number.MIN_VALUE); + + public sign: number = Number.NaN; + public mag: number = Number.NaN; + public layer: number = Number.NaN; + + constructor(value?: DecimalSource) { + this.sign = Number.NaN; + this.layer = Number.NaN; + this.mag = Number.NaN; + + if (value instanceof Decimal) { + this.fromDecimal(value); + } else if (typeof value === "number") { + this.fromNumber(value); + } else if (typeof value === "string") { + this.fromString(value); + } else { + this.sign = 0; + this.layer = 0; + this.mag = 0; + } + } + + get m(): number { + if (this.sign === 0) { + return 0; + } else if (this.layer === 0) { + const exp = Math.floor(Math.log10(this.mag)); + //handle special case 5e-324 + let man; + if (this.mag === 5e-324) { + man = 5; + } else { + man = this.mag / powerOf10(exp); + } + return this.sign * man; + } else if (this.layer === 1) { + const residue = this.mag - Math.floor(this.mag); + return this.sign * Math.pow(10, residue); + } else { + //mantissa stops being relevant past 1e9e15 / ee15.954 + return this.sign; + } + } + + set m(value: number) { + if (this.layer <= 2) { + this.fromMantissaExponent(value, this.e); + } else { + //don't even pretend mantissa is meaningful + this.sign = Math.sign(value); + if (this.sign === 0) { + this.layer === 0; + this.exponent === 0; + } + } + } + + get e(): number { + if (this.sign === 0) { + return 0; + } else if (this.layer === 0) { + return Math.floor(Math.log10(this.mag)); + } else if (this.layer === 1) { + return Math.floor(this.mag); + } else if (this.layer === 2) { + return Math.floor(Math.sign(this.mag) * Math.pow(10, Math.abs(this.mag))); + } else { + return this.mag * Number.POSITIVE_INFINITY; + } + } + set e(value: number) { + this.fromMantissaExponent(this.m, value); + } + + get s(): number { + return this.sign; + } + set s(value: number) { + if (value === 0) { + this.sign = 0; + this.layer = 0; + this.mag = 0; + } else { + this.sign = value; + } + } + + // Object.defineProperty(Decimal.prototype, "mantissa", { + get mantissa(): number { + return this.m; + } + + set mantissa(value: number) { + this.m = value; + } + + get exponent(): number { + return this.e; + } + set exponent(value: number) { + this.e = value; + } + + public static fromComponents(sign: number, layer: number, mag: number): Decimal { + return new Decimal().fromComponents(sign, layer, mag); + } + + public static fromComponents_noNormalize(sign: number, layer: number, mag: number): Decimal { + return new Decimal().fromComponents_noNormalize(sign, layer, mag); + } + + public static fromMantissaExponent(mantissa: number, exponent: number): Decimal { + return new Decimal().fromMantissaExponent(mantissa, exponent); + } + + public static fromMantissaExponent_noNormalize(mantissa: number, exponent: number): Decimal { + return new Decimal().fromMantissaExponent_noNormalize(mantissa, exponent); + } + + public static fromDecimal(value: Decimal): Decimal { + return new Decimal().fromDecimal(value); + } + + public static fromNumber(value: number): Decimal { + return new Decimal().fromNumber(value); + } + + public static fromString(value: string): Decimal { + return new Decimal().fromString(value); + } + + public static fromValue(value: DecimalSource): Decimal { + return new Decimal().fromValue(value); + } + + public static fromValue_noAlloc(value: DecimalSource): Decimal { + return value instanceof Decimal ? value : new Decimal(value); + } + + public static abs(value: DecimalSource): Decimal { + return D(value).abs(); + } + + public static neg(value: DecimalSource): Decimal { + return D(value).neg(); + } + + public static negate(value: DecimalSource): Decimal { + return D(value).neg(); + } + + public static negated(value: DecimalSource): Decimal { + return D(value).neg(); + } + + public static sign(value: DecimalSource): number { + return D(value).sign; + } + + public static sgn(value: DecimalSource): number { + return D(value).sign; + } + + public static round(value: DecimalSource): Decimal { + return D(value).round(); + } + + public static floor(value: DecimalSource): Decimal { + return D(value).floor(); + } + + public static ceil(value: DecimalSource): Decimal { + return D(value).ceil(); + } + + public static trunc(value: DecimalSource): Decimal { + return D(value).trunc(); + } + + public static add(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).add(other); + } + + public static plus(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).add(other); + } + + public static sub(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).sub(other); + } + + public static subtract(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).sub(other); + } + + public static minus(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).sub(other); + } + + public static mul(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).mul(other); + } + + public static multiply(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).mul(other); + } + + public static times(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).mul(other); + } + + public static div(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).div(other); + } + + public static divide(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).div(other); + } + + public static recip(value: DecimalSource): Decimal { + return D(value).recip(); + } + + public static reciprocal(value: DecimalSource): Decimal { + return D(value).recip(); + } + + public static reciprocate(value: DecimalSource): Decimal { + return D(value).reciprocate(); + } + + public static cmp(value: DecimalSource, other: DecimalSource): CompareResult { + return D(value).cmp(other); + } + + public static cmpabs(value: DecimalSource, other: DecimalSource): CompareResult { + return D(value).cmpabs(other); + } + + public static compare(value: DecimalSource, other: DecimalSource): CompareResult { + return D(value).cmp(other); + } + + public static eq(value: DecimalSource, other: DecimalSource): boolean { + return D(value).eq(other); + } + + public static equals(value: DecimalSource, other: DecimalSource): boolean { + return D(value).eq(other); + } + + public static neq(value: DecimalSource, other: DecimalSource): boolean { + return D(value).neq(other); + } + + public static notEquals(value: DecimalSource, other: DecimalSource): boolean { + return D(value).notEquals(other); + } + + public static lt(value: DecimalSource, other: DecimalSource): boolean { + return D(value).lt(other); + } + + public static lte(value: DecimalSource, other: DecimalSource): boolean { + return D(value).lte(other); + } + + public static gt(value: DecimalSource, other: DecimalSource): boolean { + return D(value).gt(other); + } + + public static gte(value: DecimalSource, other: DecimalSource): boolean { + return D(value).gte(other); + } + + public static max(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).max(other); + } + + public static min(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).min(other); + } + + public static minabs(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).minabs(other); + } + + public static maxabs(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).maxabs(other); + } + + public static clamp(value: DecimalSource, min: DecimalSource, max: DecimalSource): Decimal { + return D(value).clamp(min, max); + } + + public static clampMin(value: DecimalSource, min: DecimalSource): Decimal { + return D(value).clampMin(min); + } + + public static clampMax(value: DecimalSource, max: DecimalSource): Decimal { + return D(value).clampMax(max); + } + + public static cmp_tolerance( + value: DecimalSource, + other: DecimalSource, + tolerance: number + ): CompareResult { + return D(value).cmp_tolerance(other, tolerance); + } + + public static compare_tolerance( + value: DecimalSource, + other: DecimalSource, + tolerance: number + ): CompareResult { + return D(value).cmp_tolerance(other, tolerance); + } + + public static eq_tolerance( + value: DecimalSource, + other: DecimalSource, + tolerance: number + ): boolean { + return D(value).eq_tolerance(other, tolerance); + } + + public static equals_tolerance( + value: DecimalSource, + other: DecimalSource, + tolerance: number + ): boolean { + return D(value).eq_tolerance(other, tolerance); + } + + public static neq_tolerance( + value: DecimalSource, + other: DecimalSource, + tolerance: number + ): boolean { + return D(value).neq_tolerance(other, tolerance); + } + + public static notEquals_tolerance( + value: DecimalSource, + other: DecimalSource, + tolerance: number + ): boolean { + return D(value).notEquals_tolerance(other, tolerance); + } + + public static lt_tolerance( + value: DecimalSource, + other: DecimalSource, + tolerance: number + ): boolean { + return D(value).lt_tolerance(other, tolerance); + } + + public static lte_tolerance( + value: DecimalSource, + other: DecimalSource, + tolerance: number + ): boolean { + return D(value).lte_tolerance(other, tolerance); + } + + public static gt_tolerance( + value: DecimalSource, + other: DecimalSource, + tolerance: number + ): boolean { + return D(value).gt_tolerance(other, tolerance); + } + + public static gte_tolerance( + value: DecimalSource, + other: DecimalSource, + tolerance: number + ): boolean { + return D(value).gte_tolerance(other, tolerance); + } + + public static pLog10(value: DecimalSource): Decimal { + return D(value).pLog10(); + } + + public static absLog10(value: DecimalSource): Decimal { + return D(value).absLog10(); + } + + public static log10(value: DecimalSource): Decimal { + return D(value).log10(); + } + + public static log(value: DecimalSource, base: DecimalSource): Decimal { + return D(value).log(base); + } + + public static log2(value: DecimalSource): Decimal { + return D(value).log2(); + } + + public static ln(value: DecimalSource): Decimal { + return D(value).ln(); + } + + public static logarithm(value: DecimalSource, base: DecimalSource): Decimal { + return D(value).logarithm(base); + } + + public static pow(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).pow(other); + } + + public static pow10(value: DecimalSource): Decimal { + return D(value).pow10(); + } + + public static root(value: DecimalSource, other: DecimalSource): Decimal { + return D(value).root(other); + } + + public static factorial(value: DecimalSource, _other?: never): Decimal { + return D(value).factorial(); + } + + public static gamma(value: DecimalSource, _other?: never): Decimal { + return D(value).gamma(); + } + + public static lngamma(value: DecimalSource, _other?: never): Decimal { + return D(value).lngamma(); + } + + public static exp(value: DecimalSource): Decimal { + return D(value).exp(); + } + + public static sqr(value: DecimalSource): Decimal { + return D(value).sqr(); + } + + public static sqrt(value: DecimalSource): Decimal { + return D(value).sqrt(); + } + + public static cube(value: DecimalSource): Decimal { + return D(value).cube(); + } + + public static cbrt(value: DecimalSource): Decimal { + return D(value).cbrt(); + } + + public static tetrate( + value: DecimalSource, + height = 2, + payload: DecimalSource = FC_NN(1, 0, 1) + ): Decimal { + return D(value).tetrate(height, payload); + } + + public static iteratedexp(value: DecimalSource, height = 2, payload = FC_NN(1, 0, 1)): Decimal { + return D(value).iteratedexp(height, payload); + } + + public static iteratedlog(value: DecimalSource, base: DecimalSource = 10, times = 1): Decimal { + return D(value).iteratedlog(base, times); + } + + public static layeradd10(value: DecimalSource, diff: DecimalSource): Decimal { + return D(value).layeradd10(diff); + } + + public static layeradd(value: DecimalSource, diff: number, base = 10): Decimal { + return D(value).layeradd(diff, base); + } + + public static slog(value: DecimalSource, base = 10): Decimal { + return D(value).slog(base); + } + + public static lambertw(value: DecimalSource): Decimal { + return D(value).lambertw(); + } + + public static ssqrt(value: DecimalSource): Decimal { + return D(value).ssqrt(); + } + + public static pentate( + value: DecimalSource, + height = 2, + payload: DecimalSource = FC_NN(1, 0, 1) + ): Decimal { + return D(value).pentate(height, payload); + } + + /** + * If you're willing to spend 'resourcesAvailable' and want to buy something + * with exponentially increasing cost each purchase (start at priceStart, + * multiply by priceRatio, already own currentOwned), how much of it can you buy? + * Adapted from Trimps source code. + */ + + public static affordGeometricSeries( + resourcesAvailable: DecimalSource, + priceStart: DecimalSource, + priceRatio: DecimalSource, + currentOwned: DecimalSource + ): Decimal { + return this.affordGeometricSeries_core( + D(resourcesAvailable), + D(priceStart), + D(priceRatio), + currentOwned + ); + } + /** + * How much resource would it cost to buy (numItems) items if you already have currentOwned, + * the initial price is priceStart and it multiplies by priceRatio each purchase? + */ + + public static sumGeometricSeries( + numItems: DecimalSource, + priceStart: DecimalSource, + priceRatio: DecimalSource, + currentOwned: DecimalSource + ): Decimal { + return this.sumGeometricSeries_core(numItems, D(priceStart), D(priceRatio), currentOwned); + } + /** + * If you're willing to spend 'resourcesAvailable' and want to buy something with additively + * increasing cost each purchase (start at priceStart, add by priceAdd, already own currentOwned), + * how much of it can you buy? + */ + + public static affordArithmeticSeries( + resourcesAvailable: DecimalSource, + priceStart: DecimalSource, + priceAdd: DecimalSource, + currentOwned: DecimalSource + ): Decimal { + return this.affordArithmeticSeries_core( + D(resourcesAvailable), + D(priceStart), + D(priceAdd), + D(currentOwned) + ); + } + /** + * How much resource would it cost to buy (numItems) items if you already have currentOwned, + * the initial price is priceStart and it adds priceAdd each purchase? + * Adapted from http://www.mathwords.com/a/arithmetic_series.htm + */ + + public static sumArithmeticSeries( + numItems: DecimalSource, + priceStart: DecimalSource, + priceAdd: DecimalSource, + currentOwned: DecimalSource + ): Decimal { + return this.sumArithmeticSeries_core(D(numItems), D(priceStart), D(priceAdd), D(currentOwned)); + } + /** + * When comparing two purchases that cost (resource) and increase your resource/sec by (deltaRpS), + * the lowest efficiency score is the better one to purchase. + * From Frozen Cookies: + * http://cookieclicker.wikia.com/wiki/Frozen_Cookies_(JavaScript_Add-on)#Efficiency.3F_What.27s_that.3F + */ + + public static efficiencyOfPurchase( + cost: DecimalSource, + currentRpS: DecimalSource, + deltaRpS: DecimalSource + ): Decimal { + return this.efficiencyOfPurchase_core(D(cost), D(currentRpS), D(deltaRpS)); + } + + public static randomDecimalForTesting(maxLayers: number): Decimal { + // NOTE: This doesn't follow any kind of sane random distribution, so use this for testing purposes only. + //5% of the time, return 0 + if (Math.random() * 20 < 1) { + return FC_NN(0, 0, 0); + } + + const randomsign = Math.random() > 0.5 ? 1 : -1; + + //5% of the time, return 1 or -1 + if (Math.random() * 20 < 1) { + return FC_NN(randomsign, 0, 1); + } + + //pick a random layer + const layer = Math.floor(Math.random() * (maxLayers + 1)); + + let randomexp = layer === 0 ? Math.random() * 616 - 308 : Math.random() * 16; + //10% of the time, make it a simple power of 10 + if (Math.random() > 0.9) { + randomexp = Math.trunc(randomexp); + } + let randommag = Math.pow(10, randomexp); + //10% of the time, trunc mag + if (Math.random() > 0.9) { + randommag = Math.trunc(randommag); + } + return FC(randomsign, layer, randommag); + } + + public static affordGeometricSeries_core( + resourcesAvailable: Decimal, + priceStart: Decimal, + priceRatio: Decimal, + currentOwned: DecimalSource + ): Decimal { + const actualStart = priceStart.mul(priceRatio.pow(currentOwned)); + return Decimal.floor( + resourcesAvailable + .div(actualStart) + .mul(priceRatio.sub(1)) + .add(1) + .log10() + .div(priceRatio.log10()) + ); + } + + public static sumGeometricSeries_core( + numItems: DecimalSource, + priceStart: Decimal, + priceRatio: Decimal, + currentOwned: DecimalSource + ): Decimal { + return priceStart + .mul(priceRatio.pow(currentOwned)) + .mul(Decimal.sub(1, priceRatio.pow(numItems))) + .div(Decimal.sub(1, priceRatio)); + } + + public static affordArithmeticSeries_core( + resourcesAvailable: Decimal, + priceStart: Decimal, + priceAdd: Decimal, + currentOwned: Decimal + ): Decimal { + // n = (-(a-d/2) + sqrt((a-d/2)^2+2dS))/d + // where a is actualStart, d is priceAdd and S is resourcesAvailable + // then floor it and you're done! + const actualStart = priceStart.add(currentOwned.mul(priceAdd)); + const b = actualStart.sub(priceAdd.div(2)); + const b2 = b.pow(2); + return b + .neg() + .add(b2.add(priceAdd.mul(resourcesAvailable).mul(2)).sqrt()) + .div(priceAdd) + .floor(); + } + + public static sumArithmeticSeries_core( + numItems: Decimal, + priceStart: Decimal, + priceAdd: Decimal, + currentOwned: Decimal + ): Decimal { + const actualStart = priceStart.add(currentOwned.mul(priceAdd)); // (n/2)*(2*a+(n-1)*d) + + return numItems.div(2).mul(actualStart.mul(2).plus(numItems.sub(1).mul(priceAdd))); + } + + public static efficiencyOfPurchase_core( + cost: Decimal, + currentRpS: Decimal, + deltaRpS: Decimal + ): Decimal { + return cost.div(currentRpS).add(cost.div(deltaRpS)); + } + + public normalize(): this { + /* + PSEUDOCODE: + Whenever we are partially 0 (sign is 0 or mag and layer is 0), make it fully 0. + Whenever we are at or hit layer 0, extract sign from negative mag. + If layer === 0 and mag < FIRST_NEG_LAYER (1/9e15), shift to 'first negative layer' (add layer, log10 mag). + While abs(mag) > EXP_LIMIT (9e15), layer += 1, mag = maglog10(mag). + While abs(mag) < LAYER_DOWN (15.954) and layer > 0, layer -= 1, mag = pow(10, mag). + + When we're done, all of the following should be true OR one of the numbers is not IsFinite OR layer is not IsInteger (error state): + Any 0 is totally zero (0, 0, 0). + Anything layer 0 has mag 0 OR mag > 1/9e15 and < 9e15. + Anything layer 1 or higher has abs(mag) >= 15.954 and < 9e15. + We will assume in calculations that all Decimals are either erroneous or satisfy these criteria. (Otherwise: Garbage in, garbage out.) + */ + if (this.sign === 0 || (this.mag === 0 && this.layer === 0)) { + this.sign = 0; + this.mag = 0; + this.layer = 0; + return this; + } + + if (this.layer === 0 && this.mag < 0) { + //extract sign from negative mag at layer 0 + this.mag = -this.mag; + this.sign = -this.sign; + } + + //Handle shifting from layer 0 to negative layers. + if (this.layer === 0 && this.mag < FIRST_NEG_LAYER) { + this.layer += 1; + this.mag = Math.log10(this.mag); + return this; + } + + let absmag = Math.abs(this.mag); + let signmag = Math.sign(this.mag); + + if (absmag >= EXP_LIMIT) { + this.layer += 1; + this.mag = signmag * Math.log10(absmag); + return this; + } else { + while (absmag < LAYER_DOWN && this.layer > 0) { + this.layer -= 1; + if (this.layer === 0) { + this.mag = Math.pow(10, this.mag); + } else { + this.mag = signmag * Math.pow(10, absmag); + absmag = Math.abs(this.mag); + signmag = Math.sign(this.mag); + } + } + if (this.layer === 0) { + if (this.mag < 0) { + //extract sign from negative mag at layer 0 + this.mag = -this.mag; + this.sign = -this.sign; + } else if (this.mag === 0) { + //excessive rounding can give us all zeroes + this.sign = 0; + } + } + } + + return this; + } + + public fromComponents(sign: number, layer: number, mag: number): this { + this.sign = sign; + this.layer = layer; + this.mag = mag; + + this.normalize(); + return this; + } + + public fromComponents_noNormalize(sign: number, layer: number, mag: number): this { + this.sign = sign; + this.layer = layer; + this.mag = mag; + return this; + } + + public fromMantissaExponent(mantissa: number, exponent: number): this { + this.layer = 1; + this.sign = Math.sign(mantissa); + mantissa = Math.abs(mantissa); + this.mag = exponent + Math.log10(mantissa); + + this.normalize(); + return this; + } + + public fromMantissaExponent_noNormalize(mantissa: number, exponent: number): this { + //The idea of 'normalizing' a break_infinity.js style Decimal doesn't really apply. So just do the same thing. + this.fromMantissaExponent(mantissa, exponent); + return this; + } + + public fromDecimal(value: Decimal): this { + this.sign = value.sign; + this.layer = value.layer; + this.mag = value.mag; + return this; + } + + public fromNumber(value: number): this { + this.mag = Math.abs(value); + this.sign = Math.sign(value); + this.layer = 0; + this.normalize(); + return this; + } + + public fromString(value: string): Decimal { + if (IGNORE_COMMAS) { + value = value.replace(",", ""); + } else if (COMMAS_ARE_DECIMAL_POINTS) { + value = value.replace(",", "."); + } + + //Handle x^^^y format. + const pentationparts = value.split("^^^"); + if (pentationparts.length === 2) { + const base = parseFloat(pentationparts[0]); + const height = parseFloat(pentationparts[1]); + const heightparts = pentationparts[1].split(";"); + let payload = 1; + if (heightparts.length === 2) { + payload = parseFloat(heightparts[1]); + if (!isFinite(payload)) { + payload = 1; + } + } + if (isFinite(base) && isFinite(height)) { + const result = Decimal.pentate(base, height, payload); + this.sign = result.sign; + this.layer = result.layer; + this.mag = result.mag; + return this; + } + } + + //Handle x^^y format. + const tetrationparts = value.split("^^"); + if (tetrationparts.length === 2) { + const base = parseFloat(tetrationparts[0]); + const height = parseFloat(tetrationparts[1]); + const heightparts = tetrationparts[1].split(";"); + let payload = 1; + if (heightparts.length === 2) { + payload = parseFloat(heightparts[1]); + if (!isFinite(payload)) { + payload = 1; + } + } + if (isFinite(base) && isFinite(height)) { + const result = Decimal.tetrate(base, height, payload); + this.sign = result.sign; + this.layer = result.layer; + this.mag = result.mag; + return this; + } + } + + //Handle x^y format. + const powparts = value.split("^"); + if (powparts.length === 2) { + const base = parseFloat(powparts[0]); + const exponent = parseFloat(powparts[1]); + if (isFinite(base) && isFinite(exponent)) { + const result = Decimal.pow(base, exponent); + this.sign = result.sign; + this.layer = result.layer; + this.mag = result.mag; + return this; + } + } + + //Handle various cases involving it being a Big Number. + value = value.trim().toLowerCase(); + + //handle X PT Y format. + let base; + let height; + let ptparts = value.split("pt"); + if (ptparts.length === 2) { + base = 10; + height = parseFloat(ptparts[0]); + ptparts[1] = ptparts[1].replace("(", ""); + ptparts[1] = ptparts[1].replace(")", ""); + let payload = parseFloat(ptparts[1]); + if (!isFinite(payload)) { + payload = 1; + } + if (isFinite(base) && isFinite(height)) { + const result = Decimal.tetrate(base, height, payload); + this.sign = result.sign; + this.layer = result.layer; + this.mag = result.mag; + return this; + } + } + + //handle XpY format (it's the same thing just with p). + ptparts = value.split("p"); + if (ptparts.length === 2) { + base = 10; + height = parseFloat(ptparts[0]); + ptparts[1] = ptparts[1].replace("(", ""); + ptparts[1] = ptparts[1].replace(")", ""); + let payload = parseFloat(ptparts[1]); + if (!isFinite(payload)) { + payload = 1; + } + if (isFinite(base) && isFinite(height)) { + const result = Decimal.tetrate(base, height, payload); + this.sign = result.sign; + this.layer = result.layer; + this.mag = result.mag; + return this; + } + } + + const parts = value.split("e"); + const ecount = parts.length - 1; + + //Handle numbers that are exactly floats (0 or 1 es). + if (ecount === 0) { + const numberAttempt = parseFloat(value); + if (isFinite(numberAttempt)) { + return this.fromNumber(numberAttempt); + } + } else if (ecount === 1) { + //Very small numbers ("2e-3000" and so on) may look like valid floats but round to 0. + const numberAttempt = parseFloat(value); + if (isFinite(numberAttempt) && numberAttempt !== 0) { + return this.fromNumber(numberAttempt); + } + } + + //Handle new (e^N)X format. + const newparts = value.split("e^"); + if (newparts.length === 2) { + this.sign = 1; + if (newparts[0].charAt(0) == "-") { + this.sign = -1; + } + let layerstring = ""; + for (let i = 0; i < newparts[1].length; ++i) { + const chrcode = newparts[1].charCodeAt(i); + if ((chrcode >= 43 && chrcode <= 57) || chrcode === 101) { + //is "0" to "9" or "+" or "-" or "." or "e" (or "," or "/") + layerstring += newparts[1].charAt(i); + } //we found the end of the layer count + else { + this.layer = parseFloat(layerstring); + this.mag = parseFloat(newparts[1].substr(i + 1)); + this.normalize(); + return this; + } + } + } + + if (ecount < 1) { + this.sign = 0; + this.layer = 0; + this.mag = 0; + return this; + } + const mantissa = parseFloat(parts[0]); + if (mantissa === 0) { + this.sign = 0; + this.layer = 0; + this.mag = 0; + return this; + } + let exponent = parseFloat(parts[parts.length - 1]); + //handle numbers like AeBeC and AeeeeBeC + if (ecount >= 2) { + const me = parseFloat(parts[parts.length - 2]); + if (isFinite(me)) { + exponent *= Math.sign(me); + exponent += f_maglog10(me); + } + } + + //Handle numbers written like eee... (N es) X + if (!isFinite(mantissa)) { + this.sign = parts[0] === "-" ? -1 : 1; + this.layer = ecount; + this.mag = exponent; + } + //Handle numbers written like XeY + else if (ecount === 1) { + this.sign = Math.sign(mantissa); + this.layer = 1; + //Example: 2e10 is equal to 10^log10(2e10) which is equal to 10^(10+log10(2)) + this.mag = exponent + Math.log10(Math.abs(mantissa)); + } + //Handle numbers written like Xeee... (N es) Y + else { + this.sign = Math.sign(mantissa); + this.layer = ecount; + if (ecount === 2) { + const result = Decimal.mul(FC(1, 2, exponent), D(mantissa)); + this.sign = result.sign; + this.layer = result.layer; + this.mag = result.mag; + return this; + } else { + //at eee and above, mantissa is too small to be recognizable! + this.mag = exponent; + } + } + + this.normalize(); + return this; + } + + public fromValue(value: DecimalSource): Decimal { + if (value instanceof Decimal) { + return this.fromDecimal(value); + } + + if (typeof value === "number") { + return this.fromNumber(value); + } + + if (typeof value === "string") { + return this.fromString(value); + } + + this.sign = 0; + this.layer = 0; + this.mag = 0; + return this; + } + + public toNumber(): number { + if (!Number.isFinite(this.layer)) { + return Number.NaN; + } + if (this.layer === 0) { + return this.sign * this.mag; + } else if (this.layer === 1) { + return this.sign * Math.pow(10, this.mag); + } //overflow for any normalized Decimal + else { + return this.mag > 0 + ? this.sign > 0 + ? Number.POSITIVE_INFINITY + : Number.NEGATIVE_INFINITY + : 0; + } + } + + public mantissaWithDecimalPlaces(places: number): number { + // https://stackoverflow.com/a/37425022 + if (isNaN(this.m)) { + return Number.NaN; + } + + if (this.m === 0) { + return 0; + } + + return decimalPlaces(this.m, places); + } + + public magnitudeWithDecimalPlaces(places: number): number { + // https://stackoverflow.com/a/37425022 + if (isNaN(this.mag)) { + return Number.NaN; + } + + if (this.mag === 0) { + return 0; + } + + return decimalPlaces(this.mag, places); + } + + public toString(): string { + if (this.layer === 0) { + if ((this.mag < 1e21 && this.mag > 1e-7) || this.mag === 0) { + return (this.sign * this.mag).toString(); + } + return this.m + "e" + this.e; + } else if (this.layer === 1) { + return this.m + "e" + this.e; + } else { + //layer 2+ + if (this.layer <= MAX_ES_IN_A_ROW) { + return (this.sign === -1 ? "-" : "") + "e".repeat(this.layer) + this.mag; + } else { + return (this.sign === -1 ? "-" : "") + "(e^" + this.layer + ")" + this.mag; + } + } + } + + public toExponential(places: number): string { + if (this.layer === 0) { + return (this.sign * this.mag).toExponential(places); + } + return this.toStringWithDecimalPlaces(places); + } + + public toFixed(places: number): string { + if (this.layer === 0) { + return (this.sign * this.mag).toFixed(places); + } + return this.toStringWithDecimalPlaces(places); + } + + public toPrecision(places: number): string { + if (this.e <= -7) { + return this.toExponential(places - 1); + } + + if (places > this.e) { + return this.toFixed(places - this.exponent - 1); + } + + return this.toExponential(places - 1); + } + + public valueOf(): string { + return this.toString(); + } + + public toJSON(): string { + return this.toString(); + } + + public toStringWithDecimalPlaces(places: number): string { + if (this.layer === 0) { + if ((this.mag < 1e21 && this.mag > 1e-7) || this.mag === 0) { + return (this.sign * this.mag).toFixed(places); + } + return decimalPlaces(this.m, places) + "e" + decimalPlaces(this.e, places); + } else if (this.layer === 1) { + return decimalPlaces(this.m, places) + "e" + decimalPlaces(this.e, places); + } else { + //layer 2+ + if (this.layer <= MAX_ES_IN_A_ROW) { + return ( + (this.sign === -1 ? "-" : "") + "e".repeat(this.layer) + decimalPlaces(this.mag, places) + ); + } else { + return ( + (this.sign === -1 ? "-" : "") + "(e^" + this.layer + ")" + decimalPlaces(this.mag, places) + ); + } + } + } + + public abs(): Decimal { + return FC_NN(this.sign === 0 ? 0 : 1, this.layer, this.mag); + } + + public neg(): Decimal { + return FC_NN(-this.sign, this.layer, this.mag); + } + + public negate(): Decimal { + return this.neg(); + } + + public negated(): Decimal { + return this.neg(); + } + + // public sign () { + // return this.sign; + // } + + public sgn(): number { + return this.sign; + } + + public round(): this | Decimal { + if (this.mag < 0) { + return Decimal.dZero; + } + if (this.layer === 0) { + return FC(this.sign, 0, Math.round(this.mag)); + } + return this; + } + + public floor(): this | Decimal { + if (this.mag < 0) { + return Decimal.dZero; + } + if (this.layer === 0) { + return FC(this.sign, 0, Math.floor(this.mag)); + } + return this; + } + + public ceil(): this | Decimal { + if (this.mag < 0) { + return Decimal.dZero; + } + if (this.layer === 0) { + return FC(this.sign, 0, Math.ceil(this.mag)); + } + return this; + } + + public trunc(): this | Decimal { + if (this.mag < 0) { + return Decimal.dZero; + } + if (this.layer === 0) { + return FC(this.sign, 0, Math.trunc(this.mag)); + } + return this; + } + + public add(value: DecimalSource): this | Decimal { + const decimal = D(value); + + //inf/nan check + if (!Number.isFinite(this.layer)) { + return this; + } + if (!Number.isFinite(decimal.layer)) { + return decimal; + } + + //Special case - if one of the numbers is 0, return the other number. + if (this.sign === 0) { + return decimal; + } + if (decimal.sign === 0) { + return this; + } + + //Special case - Adding a number to its negation produces 0, no matter how large. + if (this.sign === -decimal.sign && this.layer === decimal.layer && this.mag === decimal.mag) { + return FC_NN(0, 0, 0); + } + + let a; + let b; + + //Special case: If one of the numbers is layer 2 or higher, just take the bigger number. + if (this.layer >= 2 || decimal.layer >= 2) { + return this.maxabs(decimal); + } + + if (Decimal.cmpabs(this, decimal) > 0) { + a = this; + b = decimal; + } else { + a = decimal; + b = this; + } + + if (a.layer === 0 && b.layer === 0) { + return D(a.sign * a.mag + b.sign * b.mag); + } + + const layera = a.layer * Math.sign(a.mag); + const layerb = b.layer * Math.sign(b.mag); + + //If one of the numbers is 2+ layers higher than the other, just take the bigger number. + if (layera - layerb >= 2) { + return a; + } + + if (layera === 0 && layerb === -1) { + if (Math.abs(b.mag - Math.log10(a.mag)) > MAX_SIGNIFICANT_DIGITS) { + return a; + } else { + const magdiff = Math.pow(10, Math.log10(a.mag) - b.mag); + const mantissa = b.sign + a.sign * magdiff; + return FC(Math.sign(mantissa), 1, b.mag + Math.log10(Math.abs(mantissa))); + } + } + + if (layera === 1 && layerb === 0) { + if (Math.abs(a.mag - Math.log10(b.mag)) > MAX_SIGNIFICANT_DIGITS) { + return a; + } else { + const magdiff = Math.pow(10, a.mag - Math.log10(b.mag)); + const mantissa = b.sign + a.sign * magdiff; + return FC(Math.sign(mantissa), 1, Math.log10(b.mag) + Math.log10(Math.abs(mantissa))); + } + } + + if (Math.abs(a.mag - b.mag) > MAX_SIGNIFICANT_DIGITS) { + return a; + } else { + const magdiff = Math.pow(10, a.mag - b.mag); + const mantissa = b.sign + a.sign * magdiff; + return FC(Math.sign(mantissa), 1, b.mag + Math.log10(Math.abs(mantissa))); + } + + throw Error("Bad arguments to add: " + this + ", " + value); + } + + public plus(value: DecimalSource): Decimal { + return this.add(value); + } + + public sub(value: DecimalSource): Decimal { + return this.add(D(value).neg()); + } + + public subtract(value: DecimalSource): Decimal { + return this.sub(value); + } + + public minus(value: DecimalSource): Decimal { + return this.sub(value); + } + + public mul(value: DecimalSource): Decimal { + const decimal = D(value); + + //inf/nan check + if (!Number.isFinite(this.layer)) { + return this; + } + if (!Number.isFinite(decimal.layer)) { + return decimal; + } + + //Special case - if one of the numbers is 0, return 0. + if (this.sign === 0 || decimal.sign === 0) { + return FC_NN(0, 0, 0); + } + + //Special case - Multiplying a number by its own reciprocal yields +/- 1, no matter how large. + if (this.layer === decimal.layer && this.mag === -decimal.mag) { + return FC_NN(this.sign * decimal.sign, 0, 1); + } + + let a; + let b; + + //Which number is bigger in terms of its multiplicative distance from 1? + if ( + this.layer > decimal.layer || + (this.layer == decimal.layer && Math.abs(this.mag) > Math.abs(decimal.mag)) + ) { + a = this; + b = decimal; + } else { + a = decimal; + b = this; + } + + if (a.layer === 0 && b.layer === 0) { + return D(a.sign * b.sign * a.mag * b.mag); + } + + //Special case: If one of the numbers is layer 3 or higher or one of the numbers is 2+ layers bigger than the other, just take the bigger number. + if (a.layer >= 3 || a.layer - b.layer >= 2) { + return FC(a.sign * b.sign, a.layer, a.mag); + } + + if (a.layer === 1 && b.layer === 0) { + return FC(a.sign * b.sign, 1, a.mag + Math.log10(b.mag)); + } + + if (a.layer === 1 && b.layer === 1) { + return FC(a.sign * b.sign, 1, a.mag + b.mag); + } + + if (a.layer === 2 && b.layer === 1) { + const newmag = FC(Math.sign(a.mag), a.layer - 1, Math.abs(a.mag)).add( + FC(Math.sign(b.mag), b.layer - 1, Math.abs(b.mag)) + ); + return FC(a.sign * b.sign, newmag.layer + 1, newmag.sign * newmag.mag); + } + + if (a.layer === 2 && b.layer === 2) { + const newmag = FC(Math.sign(a.mag), a.layer - 1, Math.abs(a.mag)).add( + FC(Math.sign(b.mag), b.layer - 1, Math.abs(b.mag)) + ); + return FC(a.sign * b.sign, newmag.layer + 1, newmag.sign * newmag.mag); + } + + throw Error("Bad arguments to mul: " + this + ", " + value); + } + + public multiply(value: DecimalSource): Decimal { + return this.mul(value); + } + + public times(value: DecimalSource): Decimal { + return this.mul(value); + } + + public div(value: DecimalSource): Decimal { + const decimal = D(value); + return this.mul(decimal.recip()); + } + + public divide(value: DecimalSource): Decimal { + return this.div(value); + } + + public divideBy(value: DecimalSource): Decimal { + return this.div(value); + } + + public dividedBy(value: DecimalSource): Decimal { + return this.div(value); + } + + public recip(): Decimal { + if (this.mag === 0) { + return Decimal.dNaN; + } else if (this.layer === 0) { + return FC(this.sign, 0, 1 / this.mag); + } else { + return FC(this.sign, this.layer, -this.mag); + } + } + + public reciprocal(): Decimal { + return this.recip(); + } + + public reciprocate(): Decimal { + return this.recip(); + } + + /** + * -1 for less than value, 0 for equals value, 1 for greater than value + */ + public cmp(value: DecimalSource): CompareResult { + const decimal = D(value); + if (this.sign > decimal.sign) { + return 1; + } + if (this.sign < decimal.sign) { + return -1; + } + return (this.sign * this.cmpabs(value)) as CompareResult; + } + + public cmpabs(value: DecimalSource): CompareResult { + const decimal = D(value); + const layera = this.mag > 0 ? this.layer : -this.layer; + const layerb = decimal.mag > 0 ? decimal.layer : -decimal.layer; + if (layera > layerb) { + return 1; + } + if (layera < layerb) { + return -1; + } + if (this.mag > decimal.mag) { + return 1; + } + if (this.mag < decimal.mag) { + return -1; + } + return 0; + } + + public compare(value: DecimalSource): CompareResult { + return this.cmp(value); + } + + public eq(value: DecimalSource): boolean { + const decimal = D(value); + return this.sign === decimal.sign && this.layer === decimal.layer && this.mag === decimal.mag; + } + + public equals(value: DecimalSource): boolean { + return this.eq(value); + } + + public neq(value: DecimalSource): boolean { + return !this.eq(value); + } + + public notEquals(value: DecimalSource): boolean { + return this.neq(value); + } + + public lt(value: DecimalSource): boolean { + const decimal = D(value); // FIXME: Remove? + return this.cmp(value) === -1; + } + + public lte(value: DecimalSource): boolean { + return !this.gt(value); + } + + public gt(value: DecimalSource): boolean { + const decimal = D(value); // FIXME: Remove? + return this.cmp(value) === 1; + } + + public gte(value: DecimalSource): boolean { + return !this.lt(value); + } + + public max(value: DecimalSource): Decimal { + const decimal = D(value); + return this.lt(decimal) ? decimal : this; + } + + public min(value: DecimalSource): Decimal { + const decimal = D(value); + return this.gt(decimal) ? decimal : this; + } + + public maxabs(value: DecimalSource): Decimal { + const decimal = D(value); + return this.cmpabs(decimal) < 0 ? decimal : this; + } + + public minabs(value: DecimalSource): Decimal { + const decimal = D(value); + return this.cmpabs(decimal) > 0 ? decimal : this; + } + + public clamp(min: DecimalSource, max: DecimalSource): Decimal { + return this.max(min).min(max); + } + + public clampMin(min: DecimalSource): Decimal { + return this.max(min); + } + + public clampMax(max: DecimalSource): Decimal { + return this.min(max); + } + + public cmp_tolerance(value: DecimalSource, tolerance: number): CompareResult { + const decimal = D(value); + return this.eq_tolerance(decimal, tolerance) ? 0 : this.cmp(decimal); + } + + public compare_tolerance(value: DecimalSource, tolerance: number): CompareResult { + return this.cmp_tolerance(value, tolerance); + } + + /** + * Tolerance is a relative tolerance, multiplied by the greater of the magnitudes of the two arguments. + * For example, if you put in 1e-9, then any number closer to the + * larger number than (larger number)*1e-9 will be considered equal. + */ + public eq_tolerance(value: DecimalSource, tolerance: number): boolean { + const decimal = D(value); // https://stackoverflow.com/a/33024979 + if (tolerance == null) { + tolerance = 1e-7; + } + //Numbers that are too far away are never close. + if (this.sign !== decimal.sign) { + return false; + } + if (Math.abs(this.layer - decimal.layer) > 1) { + return false; + } + // return abs(a-b) <= tolerance * max(abs(a), abs(b)) + let magA = this.mag; + let magB = decimal.mag; + if (this.layer > decimal.layer) { + magB = f_maglog10(magB); + } + if (this.layer < decimal.layer) { + magA = f_maglog10(magA); + } + return Math.abs(magA - magB) <= tolerance * Math.max(Math.abs(magA), Math.abs(magB)); + } + + public equals_tolerance(value: DecimalSource, tolerance: number): boolean { + return this.eq_tolerance(value, tolerance); + } + + public neq_tolerance(value: DecimalSource, tolerance: number): boolean { + return !this.eq_tolerance(value, tolerance); + } + + public notEquals_tolerance(value: DecimalSource, tolerance: number): boolean { + return this.neq_tolerance(value, tolerance); + } + + public lt_tolerance(value: DecimalSource, tolerance: number): boolean { + const decimal = D(value); + return !this.eq_tolerance(decimal, tolerance) && this.lt(decimal); + } + + public lte_tolerance(value: DecimalSource, tolerance: number): boolean { + const decimal = D(value); + return this.eq_tolerance(decimal, tolerance) || this.lt(decimal); + } + + public gt_tolerance(value: DecimalSource, tolerance: number): boolean { + const decimal = D(value); + return !this.eq_tolerance(decimal, tolerance) && this.gt(decimal); + } + + public gte_tolerance(value: DecimalSource, tolerance: number): boolean { + const decimal = D(value); + return this.eq_tolerance(decimal, tolerance) || this.gt(decimal); + } + + public pLog10(): Decimal { + if (this.lt(Decimal.dZero)) { + return Decimal.dZero; + } + return this.log10(); + } + + public absLog10(): Decimal { + if (this.sign === 0) { + return Decimal.dNaN; + } else if (this.layer > 0) { + return FC(Math.sign(this.mag), this.layer - 1, Math.abs(this.mag)); + } else { + return FC(1, 0, Math.log10(this.mag)); + } + } + + public log10(): Decimal { + if (this.sign <= 0) { + return Decimal.dNaN; + } else if (this.layer > 0) { + return FC(Math.sign(this.mag), this.layer - 1, Math.abs(this.mag)); + } else { + return FC(this.sign, 0, Math.log10(this.mag)); + } + } + + public log(base: DecimalSource): Decimal { + base = D(base); + if (this.sign <= 0) { + return Decimal.dNaN; + } + if (base.sign <= 0) { + return Decimal.dNaN; + } + if (base.sign === 1 && base.layer === 0 && base.mag === 1) { + return Decimal.dNaN; + } else if (this.layer === 0 && base.layer === 0) { + return FC(this.sign, 0, Math.log(this.mag) / Math.log(base.mag)); + } + + return Decimal.div(this.log10(), base.log10()); + } + + public log2(): Decimal { + if (this.sign <= 0) { + return Decimal.dNaN; + } else if (this.layer === 0) { + return FC(this.sign, 0, Math.log2(this.mag)); + } else if (this.layer === 1) { + return FC(Math.sign(this.mag), 0, Math.abs(this.mag) * 3.321928094887362); //log2(10) + } else if (this.layer === 2) { + return FC(Math.sign(this.mag), 1, Math.abs(this.mag) + 0.5213902276543247); //-log10(log10(2)) + } else { + return FC(Math.sign(this.mag), this.layer - 1, Math.abs(this.mag)); + } + } + + public ln(): Decimal { + if (this.sign <= 0) { + return Decimal.dNaN; + } else if (this.layer === 0) { + return FC(this.sign, 0, Math.log(this.mag)); + } else if (this.layer === 1) { + return FC(Math.sign(this.mag), 0, Math.abs(this.mag) * 2.302585092994046); //ln(10) + } else if (this.layer === 2) { + return FC(Math.sign(this.mag), 1, Math.abs(this.mag) + 0.36221568869946325); //log10(log10(e)) + } else { + return FC(Math.sign(this.mag), this.layer - 1, Math.abs(this.mag)); + } + } + + public logarithm(base: DecimalSource): Decimal { + return this.log(base); + } + + public pow(value: DecimalSource): Decimal { + const decimal = D(value); + const a = this; + const b = decimal; + + //special case: if a is 0, then return 0 + if (a.sign === 0) { + return a; + } + //special case: if a is 1, then return 1 + if (a.sign === 1 && a.layer === 0 && a.mag === 1) { + return a; + } + //special case: if b is 0, then return 1 + if (b.sign === 0) { + return FC_NN(1, 0, 1); + } + //special case: if b is 1, then return a + if (b.sign === 1 && b.layer === 0 && b.mag === 1) { + return a; + } + + const result = a.absLog10().mul(b).pow10(); + + if (this.sign === -1 && b.toNumber() % 2 === 1) { + return result.neg(); + } + + return result; + } + + public pow10(): Decimal { + /* + There are four cases we need to consider: + 1) positive sign, positive mag (e15, ee15): +1 layer (e.g. 10^15 becomes e15, 10^e15 becomes ee15) + 2) negative sign, positive mag (-e15, -ee15): +1 layer but sign and mag sign are flipped (e.g. 10^-15 becomes e-15, 10^-e15 becomes ee-15) + 3) positive sign, negative mag (e-15, ee-15): layer 0 case would have been handled in the Math.pow check, so just return 1 + 4) negative sign, negative mag (-e-15, -ee-15): layer 0 case would have been handled in the Math.pow check, so just return 1 + */ + + if (!Number.isFinite(this.layer) || !Number.isFinite(this.mag)) { + return Decimal.dNaN; + } + + let a = this; + + //handle layer 0 case - if no precision is lost just use Math.pow, else promote one layer + if (a.layer === 0) { + const newmag = Math.pow(10, a.sign * a.mag); + if (Number.isFinite(newmag) && Math.abs(newmag) > 0.1) { + return FC(1, 0, newmag); + } else { + if (a.sign === 0) { + return Decimal.dOne; + } else { + a = FC_NN(a.sign, a.layer + 1, Math.log10(a.mag)) as this; + } + } + } + + //handle all 4 layer 1+ cases individually + if (a.sign > 0 && a.mag > 0) { + return FC(a.sign, a.layer + 1, a.mag); + } + if (a.sign < 0 && a.mag > 0) { + return FC(-a.sign, a.layer + 1, -a.mag); + } + //both the negative mag cases are identical: one +/- rounding error + return Decimal.dOne; + } + + public pow_base(value: DecimalSource): Decimal { + return D(value).pow(this); + } + + public root(value: DecimalSource): Decimal { + const decimal = D(value); + return this.pow(decimal.recip()); + } + + public factorial(): Decimal { + if (this.mag < 0) { + return this.add(1).gamma(); + } else if (this.layer === 0) { + return this.add(1).gamma(); + } else if (this.layer === 1) { + return Decimal.exp(Decimal.mul(this, Decimal.ln(this).sub(1))); + } else { + return Decimal.exp(this); + } + } + + //from HyperCalc source code + public gamma(): Decimal { + if (this.mag < 0) { + return this.recip(); + } else if (this.layer === 0) { + if (this.lt(FC_NN(1, 0, 24))) { + return D(f_gamma(this.sign * this.mag)); + } + + const t = this.mag - 1; + let l = 0.9189385332046727; //0.5*Math.log(2*Math.PI) + l = l + (t + 0.5) * Math.log(t); + l = l - t; + const n2 = t * t; + let np = t; + let lm = 12 * np; + let adj = 1 / lm; + let l2 = l + adj; + if (l2 === l) { + return Decimal.exp(l); + } + + l = l2; + np = np * n2; + lm = 360 * np; + adj = 1 / lm; + l2 = l - adj; + if (l2 === l) { + return Decimal.exp(l); + } + + l = l2; + np = np * n2; + lm = 1260 * np; + let lt = 1 / lm; + l = l + lt; + np = np * n2; + lm = 1680 * np; + lt = 1 / lm; + l = l - lt; + return Decimal.exp(l); + } else if (this.layer === 1) { + return Decimal.exp(Decimal.mul(this, Decimal.ln(this).sub(1))); + } else { + return Decimal.exp(this); + } + } + + public lngamma(): Decimal { + return this.gamma().ln(); + } + + public exp(): Decimal { + if (this.mag < 0) { + return Decimal.dOne; + } + if (this.layer === 0 && this.mag <= 709.7) { + return D(Math.exp(this.sign * this.mag)); + } else if (this.layer === 0) { + return FC(1, 1, this.sign * Math.log10(Math.E) * this.mag); + } else if (this.layer === 1) { + return FC(1, 2, this.sign * (Math.log10(0.4342944819032518) + this.mag)); + } else { + return FC(1, this.layer + 1, this.sign * this.mag); + } + } + + public sqr(): Decimal { + return this.pow(2); + } + + public sqrt(): Decimal { + if (this.layer === 0) { + return D(Math.sqrt(this.sign * this.mag)); + } else if (this.layer === 1) { + return FC(1, 2, Math.log10(this.mag) - 0.3010299956639812); + } else { + const result = Decimal.div(FC_NN(this.sign, this.layer - 1, this.mag), FC_NN(1, 0, 2)); + result.layer += 1; + result.normalize(); + return result; + } + } + + public cube(): Decimal { + return this.pow(3); + } + + public cbrt(): Decimal { + return this.pow(1 / 3); + } + + //Tetration/tetrate: The result of exponentiating 'this' to 'this' 'height' times in a row. https://en.wikipedia.org/wiki/Tetration + //If payload != 1, then this is 'iterated exponentiation', the result of exping (payload) to base (this) (height) times. https://andydude.github.io/tetration/archives/tetration2/ident.html + //Works with negative and positive real heights. + public tetrate(height = 2, payload: DecimalSource = FC_NN(1, 0, 1)): Decimal { + if (height === Number.POSITIVE_INFINITY) { + //Formula for infinite height power tower. + const negln = Decimal.ln(this).neg(); + return negln.lambertw().div(negln); + } + + if (height < 0) { + return Decimal.iteratedlog(payload, this, -height); + } + + payload = D(payload); + const oldheight = height; + height = Math.trunc(height); + const fracheight = oldheight - height; + + if (fracheight !== 0) { + if (payload.eq(Decimal.dOne)) { + ++height; + payload = new Decimal(fracheight); + } else { + if (this.eq(10)) { + payload = payload.layeradd10(fracheight); + } else { + payload = payload.layeradd(fracheight, this); + } + } + } + + for (let i = 0; i < height; ++i) { + payload = this.pow(payload); + //bail if we're NaN + if (!isFinite(payload.layer) || !isFinite(payload.mag)) { + return payload; + } + //shortcut + if (payload.layer - this.layer > 3) { + return FC_NN(payload.sign, payload.layer + (height - i - 1), payload.mag); + } + //give up after 100 iterations if nothing is happening + if (i > 100) { + return payload; + } + } + return payload; + } + + //iteratedexp/iterated exponentiation: - all cases handled in tetrate, so just call it + public iteratedexp(height = 2, payload = FC_NN(1, 0, 1)): Decimal { + return this.tetrate(height, payload); + } + + //iterated log/repeated log: The result of applying log(base) 'times' times in a row. Approximately equal to subtracting (times) from the number's slog representation. Equivalent to tetrating to a negative height. + //Works with negative and positive real heights. + public iteratedlog(base: DecimalSource = 10, times = 1): Decimal { + if (times < 0) { + return Decimal.tetrate(base, -times, this); + } + + base = D(base); + let result = D(this); + const fulltimes = times; + times = Math.trunc(times); + const fraction = fulltimes - times; + if (result.layer - base.layer > 3) { + const layerloss = Math.min(times, result.layer - base.layer - 3); + times -= layerloss; + result.layer -= layerloss; + } + + for (let i = 0; i < times; ++i) { + result = result.log(base); + //bail if we're NaN + if (!isFinite(result.layer) || !isFinite(result.mag)) { + return result; + } + //give up after 100 iterations if nothing is happening + if (i > 100) { + return result; + } + } + + //handle fractional part + if (fraction > 0 && fraction < 1) { + if (base.eq(10)) { + result = result.layeradd10(-fraction); + } else { + result = result.layeradd(-fraction, base); + } + } + + return result; + } + + //Super-logarithm, one of tetration's inverses, tells you what size power tower you'd have to tetrate base to to get number. By definition, will never be higher than 1.8e308 in break_eternity.js, since a power tower 1.8e308 numbers tall is the largest representable number. + // https://en.wikipedia.org/wiki/Super-logarithm + public slog(base: DecimalSource = 10): Decimal { + if (this.mag < 0) { + return Decimal.dNegOne; + } + + base = D(base); + + let result = 0; + let copy = D(this); + if (copy.layer - base.layer > 3) { + const layerloss = copy.layer - base.layer - 3; + result += layerloss; + copy.layer -= layerloss; + } + + for (let i = 0; i < 100; ++i) { + if (copy.lt(Decimal.dZero)) { + copy = Decimal.pow(base, copy); + result -= 1; + } else if (copy.lte(Decimal.dOne)) { + return D(result + copy.toNumber() - 1); //<-- THIS IS THE CRITICAL FUNCTION + //^ Also have to change tetrate payload handling and layeradd10 if this is changed! + } else { + result += 1; + copy = Decimal.log(copy, base); + } + } + return D(result); + } + + //Approximations taken from the excellent paper https://web.archive.org/web/20090201164836/http://tetration.itgo.com/paper.html ! + //Not using for now unless I can figure out how to use it in all the related functions. + /*var slog_criticalfunction_1 = function(x, z) { + z = z.toNumber(); + return -1 + z; + } + + var slog_criticalfunction_2 = function(x, z) { + z = z.toNumber(); + var lnx = x.ln(); + if (lnx.layer === 0) + { + lnx = lnx.toNumber(); + return -1 + z*2*lnx/(1+lnx) - z*z*(1-lnx)/(1+lnx); + } + else + { + var term1 = lnx.mul(z*2).div(lnx.add(1)); + var term2 = Decimal.sub(1, lnx).mul(z*z).div(lnx.add(1)); + Decimal.dNegOne.add(Decimal.sub(term1, term2)); + } + } + + var slog_criticalfunction_3 = function(x, z) { + z = z.toNumber(); + var lnx = x.ln(); + var lnx2 = lnx.sqr(); + var lnx3 = lnx.cube(); + if (lnx.layer === 0 && lnx2.layer === 0 && lnx3.layer === 0) + { + lnx = lnx.toNumber(); + lnx2 = lnx2.toNumber(); + lnx3 = lnx3.toNumber(); + + var term1 = 6*z*(lnx+lnx3); + var term2 = 3*z*z*(3*lnx2-2*lnx3); + var term3 = 2*z*z*z*(1-lnx-2*lnx2+lnx3); + var top = term1+term2+term3; + var bottom = 2+4*lnx+5*lnx2+2*lnx3; + + return -1 + top/bottom; + } + else + { + var term1 = (lnx.add(lnx3)).mul(6*z); + var term2 = (lnx2.mul(3).sub(lnx3.mul(2))).mul(3*z*z); + var term3 = (Decimal.dOne.sub(lnx).sub(lnx2.mul(2)).add(lnx3)).mul(2*z*z*z); + var top = term1.add(term2).add(term3); + var bottom = new Decimal(2).add(lnx.mul(4)).add(lnx2.mul(5)).add(lnx3.mul(2)); + + return Decimal.dNegOne.add(top.div(bottom)); + } + }*/ + + //Function for adding/removing layers from a Decimal, even fractional layers (e.g. its slog10 representation). + //Everything continues to use the linear approximation ATM. + public layeradd10(diff: DecimalSource): Decimal { + diff = Decimal.fromValue_noAlloc(diff).toNumber(); + const result = D(this); + if (diff >= 1) { + const layeradd = Math.trunc(diff); + diff -= layeradd; + result.layer += layeradd; + } + if (diff <= -1) { + const layeradd = Math.trunc(diff); + diff -= layeradd; + result.layer += layeradd; + if (result.layer < 0) { + for (let i = 0; i < 100; ++i) { + result.layer++; + result.mag = Math.log10(result.mag); + if (!isFinite(result.mag)) { + return result; + } + if (result.layer >= 0) { + break; + } + } + } + } + + //layeradd10: like adding 'diff' to the number's slog(base) representation. Very similar to tetrate base 10 and iterated log base 10. Also equivalent to adding a fractional amount to the number's layer in its break_eternity.js representation. + if (diff > 0) { + let subtractlayerslater = 0; + //Ironically, this edge case would be unnecessary if we had 'negative layers'. + while (Number.isFinite(result.mag) && result.mag < 10) { + result.mag = Math.pow(10, result.mag); + ++subtractlayerslater; + } + + //A^(10^B) === C, solve for B + //B === log10(logA(C)) + + if (result.mag > 1e10) { + result.mag = Math.log10(result.mag); + result.layer++; + } + + //Note that every integer slog10 value, the formula changes, so if we're near such a number, we have to spend exactly enough layerdiff to hit it, and then use the new formula. + const diffToNextSlog = Math.log10(Math.log(1e10) / Math.log(result.mag)); + if (diffToNextSlog < diff) { + result.mag = Math.log10(1e10); + result.layer++; + diff -= diffToNextSlog; + } + + result.mag = Math.pow(result.mag, Math.pow(10, diff)); + + while (subtractlayerslater > 0) { + result.mag = Math.log10(result.mag); + --subtractlayerslater; + } + } else if (diff < 0) { + let subtractlayerslater = 0; + + while (Number.isFinite(result.mag) && result.mag < 10) { + result.mag = Math.pow(10, result.mag); + ++subtractlayerslater; + } + + if (result.mag > 1e10) { + result.mag = Math.log10(result.mag); + result.layer++; + } + + const diffToNextSlog = Math.log10(1 / Math.log10(result.mag)); + if (diffToNextSlog > diff) { + result.mag = 1e10; + result.layer--; + diff -= diffToNextSlog; + } + + result.mag = Math.pow(result.mag, Math.pow(10, diff)); + + while (subtractlayerslater > 0) { + result.mag = Math.log10(result.mag); + --subtractlayerslater; + } + } + + while (result.layer < 0) { + result.layer++; + result.mag = Math.log10(result.mag); + } + result.normalize(); + return result; + } + + //layeradd: like adding 'diff' to the number's slog(base) representation. Very similar to tetrate base 'base' and iterated log base 'base'. + public layeradd(diff: number, base: DecimalSource): Decimal { + const slogthis = this.slog(base).toNumber(); + const slogdest = slogthis + diff; + if (slogdest >= 0) { + return Decimal.tetrate(base, slogdest); + } else if (!Number.isFinite(slogdest)) { + return Decimal.dNaN; + } else if (slogdest >= -1) { + return Decimal.log(Decimal.tetrate(base, slogdest + 1), base); + } else { + return Decimal.log(Decimal.log(Decimal.tetrate(base, slogdest + 2), base), base); + } + } + + //The Lambert W function, also called the omega function or product logarithm, is the solution W(x) === x*e^x. + // https://en.wikipedia.org/wiki/Lambert_W_function + //Some special values, for testing: https://en.wikipedia.org/wiki/Lambert_W_function#Special_values + public lambertw(): Decimal { + if (this.lt(-0.3678794411710499)) { + throw Error("lambertw is unimplemented for results less than -1, sorry!"); + } else if (this.mag < 0) { + return D(f_lambertw(this.toNumber())); + } else if (this.layer === 0) { + return D(f_lambertw(this.sign * this.mag)); + } else if (this.layer === 1) { + return d_lambertw(this); + } else if (this.layer === 2) { + return d_lambertw(this); + } + if (this.layer >= 3) { + return FC_NN(this.sign, this.layer - 1, this.mag); + } + + throw "Unhandled behavior in lambertw()"; + } + + //The super square-root function - what number, tetrated to height 2, equals this? + //Other sroots are possible to calculate probably through guess and check methods, this one is easy though. + // https://en.wikipedia.org/wiki/Tetration#Super-root + public ssqrt(): Decimal { + if (this.sign == 1 && this.layer >= 3) { + return FC_NN(this.sign, this.layer - 1, this.mag); + } + const lnx = this.ln(); + return lnx.div(lnx.lambertw()); + } + /* + +Unit tests for tetrate/iteratedexp/iteratedlog/layeradd10/layeradd/slog: + +for (var i = 0; i < 1000; ++i) +{ + var first = Math.random()*100; + var both = Math.random()*100; + var expected = first+both+1; + var result = new Decimal(10).layeradd10(first).layeradd10(both).slog(); + if (Number.isFinite(result.mag) && !Decimal.eq_tolerance(expected, result)) + { + console.log(first + ", " + both); + } +} + +for (var i = 0; i < 1000; ++i) +{ + var first = Math.random()*100; + var both = Math.random()*100; + first += both; + var expected = first-both+1; + var result = new Decimal(10).layeradd10(first).layeradd10(-both).slog(); + if (Number.isFinite(result.mag) && !Decimal.eq_tolerance(expected, result)) + { + console.log(first + ", " + both); + } +} + +for (var i = 0; i < 1000; ++i) +{ + var first = Math.random()*100; + var both = Math.random()*100; + var base = Math.random()*8+2; + var expected = first+both+1; + var result = new Decimal(base).layeradd(first, base).layeradd(both, base).slog(base); + if (Number.isFinite(result.mag) && !Decimal.eq_tolerance(expected, result)) + { + console.log(first + ", " + both); + } +} + +for (var i = 0; i < 1000; ++i) +{ + var first = Math.random()*100; + var both = Math.random()*100; + var base = Math.random()*8+2; + first += both; + var expected = first-both+1; + var result = new Decimal(base).layeradd(first, base).layeradd(-both, base).slog(base); + if (Number.isFinite(result.mag) && !Decimal.eq_tolerance(expected, result)) + { + console.log(first + ", " + both); + } +} + +for (var i = 0; i < 1000; ++i) +{ +var first = Math.round((Math.random()*30))/10; +var both = Math.round((Math.random()*30))/10; +var tetrateonly = Decimal.tetrate(10, first); +var tetrateandlog = Decimal.tetrate(10, first+both).iteratedlog(10, both); +if (!Decimal.eq_tolerance(tetrateonly, tetrateandlog)) +{ + console.log(first + ", " + both); +} +} + +for (var i = 0; i < 1000; ++i) +{ +var first = Math.round((Math.random()*30))/10; +var both = Math.round((Math.random()*30))/10; +var base = Math.random()*8+2; +var tetrateonly = Decimal.tetrate(base, first); +var tetrateandlog = Decimal.tetrate(base, first+both).iteratedlog(base, both); +if (!Decimal.eq_tolerance(tetrateonly, tetrateandlog)) +{ + console.log(first + ", " + both); +} +} + +for (var i = 0; i < 1000; ++i) +{ +var first = Math.round((Math.random()*30))/10; +var both = Math.round((Math.random()*30))/10; +var base = Math.random()*8+2; +var tetrateonly = Decimal.tetrate(base, first, base); +var tetrateandlog = Decimal.tetrate(base, first+both, base).iteratedlog(base, both); +if (!Decimal.eq_tolerance(tetrateonly, tetrateandlog)) +{ + console.log(first + ", " + both); +} +} + +for (var i = 0; i < 1000; ++i) +{ + var xex = new Decimal(-0.3678794411710499+Math.random()*100); + var x = Decimal.lambertw(xex); + if (!Decimal.eq_tolerance(xex, x.mul(Decimal.exp(x)))) + { + console.log(xex); + } +} + +for (var i = 0; i < 1000; ++i) +{ + var xex = new Decimal(-0.3678794411710499+Math.exp(Math.random()*100)); + var x = Decimal.lambertw(xex); + if (!Decimal.eq_tolerance(xex, x.mul(Decimal.exp(x)))) + { + console.log(xex); + } +} + +for (var i = 0; i < 1000; ++i) +{ + var a = Decimal.randomDecimalForTesting(Math.random() > 0.5 ? 0 : 1); + var b = Decimal.randomDecimalForTesting(Math.random() > 0.5 ? 0 : 1); + if (Math.random() > 0.5) { a = a.recip(); } + if (Math.random() > 0.5) { b = b.recip(); } + var c = a.add(b).toNumber(); + if (Number.isFinite(c) && !Decimal.eq_tolerance(c, a.toNumber()+b.toNumber())) + { + console.log(a + ", " + b); + } +} + +for (var i = 0; i < 100; ++i) +{ + var a = Decimal.randomDecimalForTesting(Math.round(Math.random()*4)); + var b = Decimal.randomDecimalForTesting(Math.round(Math.random()*4)); + if (Math.random() > 0.5) { a = a.recip(); } + if (Math.random() > 0.5) { b = b.recip(); } + var c = a.mul(b).toNumber(); + if (Number.isFinite(c) && Number.isFinite(a.toNumber()) && Number.isFinite(b.toNumber()) && a.toNumber() != 0 && b.toNumber() != 0 && c != 0 && !Decimal.eq_tolerance(c, a.toNumber()*b.toNumber())) + { + console.log("Test 1: " + a + ", " + b); + } + else if (!Decimal.mul(a.recip(), b.recip()).eq_tolerance(Decimal.mul(a, b).recip())) + { + console.log("Test 3: " + a + ", " + b); + } +} + +for (var i = 0; i < 10; ++i) +{ + var a = Decimal.randomDecimalForTesting(Math.round(Math.random()*4)); + var b = Decimal.randomDecimalForTesting(Math.round(Math.random()*4)); + if (Math.random() > 0.5 && a.sign !== 0) { a = a.recip(); } + if (Math.random() > 0.5 && b.sign !== 0) { b = b.recip(); } + var c = a.pow(b); + var d = a.root(b.recip()); + var e = a.pow(b.recip()); + var f = a.root(b); + + if (!c.eq_tolerance(d) && a.sign !== 0 && b.sign !== 0) + { + console.log("Test 1: " + a + ", " + b); + } + if (!e.eq_tolerance(f) && a.sign !== 0 && b.sign !== 0) + { + console.log("Test 2: " + a + ", " + b); + } +} + +for (var i = 0; i < 10; ++i) +{ + var a = Math.round(Math.random()*18-9); + var b = Math.round(Math.random()*100-50); + var c = Math.round(Math.random()*18-9); + var d = Math.round(Math.random()*100-50); + console.log("Decimal.pow(Decimal.fromMantissaExponent(" + a + ", " + b + "), Decimal.fromMantissaExponent(" + c + ", " + d + ")).toString()"); +} + +*/ + + //Pentation/pentate: The result of tetrating 'height' times in a row. An absurdly strong operator - Decimal.pentate(2, 4.28) and Decimal.pentate(10, 2.37) are already too huge for break_eternity.js! + // https://en.wikipedia.org/wiki/Pentation + public pentate(height = 2, payload: DecimalSource = FC_NN(1, 0, 1)): Decimal { + payload = D(payload); + const oldheight = height; + height = Math.trunc(height); + const fracheight = oldheight - height; + + //I have no idea if this is a meaningful approximation for pentation to continuous heights, but it is monotonic and continuous. + if (fracheight !== 0) { + if (payload.eq(Decimal.dOne)) { + ++height; + payload = new Decimal(fracheight); + } else { + if (this.eq(10)) { + payload = payload.layeradd10(fracheight); + } else { + payload = payload.layeradd(fracheight, this); + } + } + } + + for (let i = 0; i < height; ++i) { + payload = this.tetrate(payload.toNumber()); + //bail if we're NaN + if (!isFinite(payload.layer) || !isFinite(payload.mag)) { + return payload; + } + //give up after 10 iterations if nothing is happening + if (i > 10) { + return payload; + } + } + + return payload; + } + + // trig functions! + public sin(): this | Decimal { + if (this.mag < 0) { + return this; + } + if (this.layer === 0) { + return D(Math.sin(this.sign * this.mag)); + } + return FC_NN(0, 0, 0); + } + + public cos(): Decimal { + if (this.mag < 0) { + return Decimal.dOne; + } + if (this.layer === 0) { + return D(Math.cos(this.sign * this.mag)); + } + return FC_NN(0, 0, 0); + } + + public tan(): this | Decimal { + if (this.mag < 0) { + return this; + } + if (this.layer === 0) { + return D(Math.tan(this.sign * this.mag)); + } + return FC_NN(0, 0, 0); + } + + public asin(): this | Decimal { + if (this.mag < 0) { + return this; + } + if (this.layer === 0) { + return D(Math.asin(this.sign * this.mag)); + } + return FC_NN(Number.NaN, Number.NaN, Number.NaN); + } + + public acos(): Decimal { + if (this.mag < 0) { + return D(Math.acos(this.toNumber())); + } + if (this.layer === 0) { + return D(Math.acos(this.sign * this.mag)); + } + return FC_NN(Number.NaN, Number.NaN, Number.NaN); + } + + public atan(): this | Decimal { + if (this.mag < 0) { + return this; + } + if (this.layer === 0) { + return D(Math.atan(this.sign * this.mag)); + } + return D(Math.atan(this.sign * 1.8e308)); + } + + public sinh(): Decimal { + return this.exp().sub(this.negate().exp()).div(2); + } + + public cosh(): Decimal { + return this.exp().add(this.negate().exp()).div(2); + } + + public tanh(): Decimal { + return this.sinh().div(this.cosh()); + } + + public asinh(): Decimal { + return Decimal.ln(this.add(this.sqr().add(1).sqrt())); + } + + public acosh(): Decimal { + return Decimal.ln(this.add(this.sqr().sub(1).sqrt())); + } + + public atanh(): Decimal { + if (this.abs().gte(1)) { + return FC_NN(Number.NaN, Number.NaN, Number.NaN); + } + + return Decimal.ln(this.add(1).div(D(1).sub(this))).div(2); + } + + /** + * Joke function from Realm Grinder + */ + public ascensionPenalty(ascensions: DecimalSource): Decimal { + if (ascensions === 0) { + return this; + } + + return this.root(Decimal.pow(10, ascensions)); + } + + /** + * Joke function from Cookie Clicker. It's 'egg' + */ + public egg(): Decimal { + return this.add(9); + } + + public lessThanOrEqualTo(other: DecimalSource): boolean { + return this.cmp(other) < 1; + } + + public lessThan(other: DecimalSource): boolean { + return this.cmp(other) < 0; + } + + public greaterThanOrEqualTo(other: DecimalSource): boolean { + return this.cmp(other) > -1; + } + + public greaterThan(other: DecimalSource): boolean { + return this.cmp(other) > 0; + } + + // return Decimal; +} + +// return Decimal; diff --git a/src/main.js b/src/main.js deleted file mode 100644 index 4b86f58..0000000 --- a/src/main.js +++ /dev/null @@ -1,22 +0,0 @@ -import { createApp } from 'vue'; -import App from './App'; -import { load } from './util/save'; -import { setVue } from './util/vue'; -import gameLoop from './game/gameLoop'; -import { registerComponents } from './components/index'; -import modInfo from './data/modInfo.json'; - -requestAnimationFrame(async () => { - await load(); - - // Create Vue - const vue = window.vue = createApp({ - ...App - }); - setVue(vue); - registerComponents(vue); - vue.mount('#app'); - document.title = modInfo.title; - - gameLoop(); -}); diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..4f0f07d --- /dev/null +++ b/src/main.ts @@ -0,0 +1,22 @@ +import { createApp } from "vue"; +import App from "./App.vue"; +import { load } from "./util/save"; +import { setVue } from "./util/vue"; +import gameLoop from "./game/gameLoop"; +import { registerComponents } from "./components/index"; +import modInfo from "./data/modInfo.json"; + +requestAnimationFrame(async () => { + await load(); + + // Create Vue + const vue = (window.vue = createApp({ + ...App + })); + setVue(vue); + registerComponents(vue); + vue.mount("#app"); + document.title = modInfo.title; + + gameLoop(); +}); diff --git a/src/shims-vue.d.ts b/src/shims-vue.d.ts new file mode 100644 index 0000000..dbd3fb9 --- /dev/null +++ b/src/shims-vue.d.ts @@ -0,0 +1,6 @@ +/* eslint-disable */ +declare module '*.vue' { + import type { defineComponent } from 'vue'; + const component: ReturnType; + export default component; +} diff --git a/src/typings/branches.d.ts b/src/typings/branches.d.ts new file mode 100644 index 0000000..93b263b --- /dev/null +++ b/src/typings/branches.d.ts @@ -0,0 +1,28 @@ +import { ComponentPublicInstance } from "vue"; + +export interface BranchLink { + start: string; + end: string; + options: string | BranchOptions; +} + +export interface BranchNode { + x?: number; + y?: number; + component: ComponentPublicInstance; + element: HTMLElement; +} + +export interface BranchOptions { + target?: string; + featureType?: string; + stroke?: string; + "stroke-width"?: string; + startOffset?: Position; + endOffset?: Position; +} + +export interface Position { + x: number; + y: number; +} diff --git a/src/typings/cacheableFunction.d.ts b/src/typings/cacheableFunction.d.ts new file mode 100644 index 0000000..2e7efdd --- /dev/null +++ b/src/typings/cacheableFunction.d.ts @@ -0,0 +1,3 @@ +export interface CacheableFunction extends Function { + forceCached?: boolean; +} diff --git a/src/typings/component.d.ts b/src/typings/component.d.ts new file mode 100644 index 0000000..5b3c011 --- /dev/null +++ b/src/typings/component.d.ts @@ -0,0 +1,3 @@ +import { ComponentOptions } from "vue"; + +export type CoercableComponent = string | ComponentOptions; diff --git a/src/typings/computable.d.ts b/src/typings/computable.d.ts new file mode 100644 index 0000000..a622ee9 --- /dev/null +++ b/src/typings/computable.d.ts @@ -0,0 +1,5 @@ +export type Computable = { + [K in keyof T]: + | ((this: T) => T[K]) + | (NonNullable extends (..._: infer A) => infer R ? (this: T, ..._: A) => R : T[K]); +}; diff --git a/src/typings/features/achievement.d.ts b/src/typings/features/achievement.d.ts new file mode 100644 index 0000000..7633bbb --- /dev/null +++ b/src/typings/features/achievement.d.ts @@ -0,0 +1,16 @@ +import { CoercableComponent } from "@/component"; +import { State } from "../state"; +import { Feature } from "./feature"; + +export interface Achievement extends Feature { + earned: boolean; + onComplete?: () => void; + effect?: State; + display?: CoercableComponent; + name?: CoercableComponent; + style?: Partial; + image?: string; + doneTooltip?: CoercableComponent; + goalTooltip?: CoercableComponent; + tooltip?: CoercableComponent; +} diff --git a/src/typings/features/bar.d.ts b/src/typings/features/bar.d.ts new file mode 100644 index 0000000..b6b80ed --- /dev/null +++ b/src/typings/features/bar.d.ts @@ -0,0 +1,15 @@ +import { CoercableComponent } from "@/component"; +import Decimal from "@/util/bignum"; +import { Feature } from "./feature"; + +export interface Bar extends Feature { + width: number; + height: number; + style: Partial; + borderStyle: Partial; + baseStyle: Partial; + textStyle: Partial; + fillStyle: Partial; + progress: number | Decimal; + display: CoercableComponent; +} diff --git a/src/typings/features/buyable.d.ts b/src/typings/features/buyable.d.ts new file mode 100644 index 0000000..165bf89 --- /dev/null +++ b/src/typings/features/buyable.d.ts @@ -0,0 +1,20 @@ +import { CoercableComponent } from "@/typings/component"; +import { State } from "@/typings/state"; +import Decimal, { DecimalSource } from "@/util/bignum"; +import { Feature } from "./feature"; + +export interface Buyable extends Feature { + amount: Decimal; + amountSet?: (amount: Decimal) => void; + canBuy: boolean; + canAfford: boolean; + effect?: State; + purchaseLimit: DecimalSource; + sellOne?: () => void; + sellAll?: () => void; + cost?: DecimalSource; + buy: () => void; + title?: CoercableComponent; + display: CoercableComponent; + style?: Partial; +} diff --git a/src/typings/features/challenge.d.ts b/src/typings/features/challenge.d.ts new file mode 100644 index 0000000..e083dce --- /dev/null +++ b/src/typings/features/challenge.d.ts @@ -0,0 +1,34 @@ +import { CoercableComponent } from "@/typings/component"; +import { State } from "@/typings/state"; +import { DecimalSource } from "@/util/bignum"; +import { Feature } from "./feature"; + +export interface Challenge extends Feature { + shown: boolean; + completed: boolean; + completions: DecimalSource; + maxed: boolean; + active: boolean; + effect?: State; + canStart: boolean; + canComplete: boolean; + completionLimit: DecimalSource; + mark: boolean | string; + goal: DecimalSource; + currencyInternalName?: string; + currencyDisplayName?: string; + currencyLocation?: { [key: string]: DecimalSource }; + currencyLayer?: string; + titleDisplay?: CoercableComponent; + name?: CoercableComponent; + fullDisplay?: CoercableComponent; + style?: Partial; + challengeDescription: CoercableComponent; + goalDescription?: CoercableComponent; + rewardDescription: CoercableComponent; + rewardDisplay?: CoercableComponent; + toggle: () => void; + onComplete?: () => void; + onExit?: () => void; + onEnter?: () => void; +} diff --git a/src/typings/features/clickable.d.ts b/src/typings/features/clickable.d.ts new file mode 100644 index 0000000..051649f --- /dev/null +++ b/src/typings/features/clickable.d.ts @@ -0,0 +1,15 @@ +import { CoercableComponent } from "@/typings/component"; +import { State } from "@/typings/state"; +import { Feature } from "./feature"; + +export interface Clickable extends Feature { + state: State; + stateSet: (state: State) => void; + effect?: State; + canClick: boolean; + click?: () => void; + hold?: () => void; + style?: Partial; + title?: CoercableComponent; + display: CoercableComponent; +} diff --git a/src/typings/features/feature.d.ts b/src/typings/features/feature.d.ts new file mode 100644 index 0000000..4fa74ea --- /dev/null +++ b/src/typings/features/feature.d.ts @@ -0,0 +1,34 @@ +import { Computable } from "@/typings/computable"; + +export type RawFeature = Partial>; + +export interface Feature { + id: string; + layer: string; + unlocked: boolean; + [key: string]: unknown; +} + +export interface RawFeatures, S extends Feature> + extends Partial, "data">>, + ThisType { + layer?: string; + data: Record>; +} + +export interface Features { + layer: string; + data: Record; + [key: string]: unknown; +} + +export interface GridFeatures extends Features { + rows: number; + cols: number; +} + +export interface RawGridFeatures, S extends Feature> + extends RawFeatures { + rows?: number; + cols?: number; +} diff --git a/src/typings/features/grid.d.ts b/src/typings/features/grid.d.ts new file mode 100644 index 0000000..61c4021 --- /dev/null +++ b/src/typings/features/grid.d.ts @@ -0,0 +1,33 @@ +import { State } from "@/typings/state"; +import { Feature } from "./feature"; + +export interface Grid extends Feature { + maxRows: number; + rows: number; + cols: number; + getData?: (cell: string | number) => State; + setData?: (cell: string | number, data: State) => void; + getUnlocked: boolean | ((cell: string | number) => boolean); + getCanClick: boolean | ((cell: string | number) => boolean); + getStartData: State | ((cell: string | number) => State); + getStyle?: + | Partial + | ((cell: string | number) => Partial | undefined); + click?: (cell: string | number) => void; + hold?: (cell: string | number) => void; + getTitle?: string | ((cell: string | number) => string); + getDisplay: string | ((cell: string | number) => string); +} + +export interface GridCell extends Feature { + data: State; + dataSet: (data: State) => void; + effect?: State; + unlocked: boolean; + canClick: boolean; + style?: Partial; + click?: () => void; + hold?: () => void; + title?: string; + display: string; +} diff --git a/src/typings/features/hotkey.d.ts b/src/typings/features/hotkey.d.ts new file mode 100644 index 0000000..bec6a5c --- /dev/null +++ b/src/typings/features/hotkey.d.ts @@ -0,0 +1,8 @@ +import { Feature } from "./feature"; + +export interface Hotkey extends Feature { + unlocked: boolean; + press: () => void; + description: string; + key: string; +} diff --git a/src/typings/features/infobox.d.ts b/src/typings/features/infobox.d.ts new file mode 100644 index 0000000..9eb08fd --- /dev/null +++ b/src/typings/features/infobox.d.ts @@ -0,0 +1,11 @@ +import { CoercableComponent } from "@/component"; +import { Feature } from "./feature"; + +export interface Infobox extends Feature { + borderColor?: string; + style?: Partial; + titleStyle?: Partial; + bodyStyle?: Partial; + title?: CoercableComponent; + body: CoercableComponent; +} diff --git a/src/typings/features/milestone.d.ts b/src/typings/features/milestone.d.ts new file mode 100644 index 0000000..5659415 --- /dev/null +++ b/src/typings/features/milestone.d.ts @@ -0,0 +1,12 @@ +import { Feature } from "./feature"; + +export interface Milestone extends Feature { + earned: boolean; + shown: boolean; + done: boolean; + style?: Partial; + requirementDisplay?: CoercableComponent; + effectDisplay?: CoercableComponent; + optionsDisplay?: CoercableComponent; + onComplete?: () => void; +} diff --git a/src/typings/features/subtab.d.ts b/src/typings/features/subtab.d.ts new file mode 100644 index 0000000..0937f8e --- /dev/null +++ b/src/typings/features/subtab.d.ts @@ -0,0 +1,35 @@ +import { CoercableComponent } from "@/typings/component"; +import { Feature, RawFeature } from "./feature"; + +export interface Subtab extends Feature { + notify?: boolean; + prestigeNotify?: boolean; + glowColor?: string; + active: boolean; + unlocked?: boolean; + embedLayer?: boolean; + display?: CoercableComponent; + style?: Partial; + buttonStyle?: Partial; +} + +export interface Microtab extends Feature { + family: string; + notify?: boolean; + prestigeNotify?: boolean; + glowColor?: string; + active: boolean; + embedLayer?: string; + display?: CoercableComponent; + style?: Partial; +} + +export type RawMicrotabFamily = Omit, "data"> & { + data: Record>; +}; + +export interface MicrotabFamily extends Feature { + activeMicrotab: Microtab | undefined; + family: string; + data: Record; +} diff --git a/src/typings/features/upgrade.d.ts b/src/typings/features/upgrade.d.ts new file mode 100644 index 0000000..efcfb3f --- /dev/null +++ b/src/typings/features/upgrade.d.ts @@ -0,0 +1,23 @@ +import { CoercableComponent } from "@/component"; +import { State } from "@/typings/state"; +import { DecimalSource } from "@/util/bignum"; +import { Feature } from "./feature"; + +export interface Upgrade extends Feature { + bought: boolean; + canAfford: boolean; + pay: () => void; + buy: () => void; + cost: DecimalSource; + currencyInternalName?: string | number; + currencyLocation?: { [key: string]: DecimalSource }; + currencyLayer?: string; + onPurchase?: () => void; + title?: CoercableComponent; + description: CoercableComponent; + effect?: State; + effectDisplay?: CoercableComponent; + currencyDisplayName?: string; + style?: Partial; + fullDisplay?: CoercableComponent; +} diff --git a/src/typings/global.d.ts b/src/typings/global.d.ts new file mode 100644 index 0000000..6bec3c7 --- /dev/null +++ b/src/typings/global.d.ts @@ -0,0 +1,27 @@ +import Decimal, { DecimalSource } from "@/util/bignum"; +import { App } from "vue"; +import { PlayerData } from "./player"; + +declare global { + interface Window { + vue: App; + save: () => void; + hardReset: () => void; + layers: Dictionary; + player: PlayerData; + Decimal: typeof Decimal; + exponentialFormat: ( + num: DecimalSource, + precision: number, + mantissa: boolean = true + ) => string; + commaFormat: (num: DecimalSource, precision: number) => string; + regularFormat: (num: DecimalSource, precision: number) => string; + format: (num: DecimalSource, precision?: number, small?: boolean) => string; + formatWhole: (num: DecimalSource) => string; + formatTime: (s: number) => string; + toPlaces: (x: DecimalSource, precision: number, maxAccepted: DecimalSource) => string; + formatSmall: (x: DecimalSource, precision?: number) => string; + invertOOM: (x: DecimalSource) => Decimal; + } +} diff --git a/src/typings/layer.d.ts b/src/typings/layer.d.ts new file mode 100644 index 0000000..a03bd14 --- /dev/null +++ b/src/typings/layer.d.ts @@ -0,0 +1,146 @@ +import { LayerType } from "@/game/layers"; +import Decimal, { DecimalSource } from "@/util/bignum"; +import { CoercableComponent } from "./component"; +import { Achievement } from "./features/achievement"; +import { Bar } from "./features/bar"; +import { Buyable } from "./features/buyable"; +import { Challenge } from "./features/challenge"; +import { Clickable } from "./features/clickable"; +import { + Feature, + Features, + GridFeatures, + RawFeature, + RawFeatures, + RawGridFeatures +} from "./features/feature"; +import { Grid } from "./features/grid"; +import { Hotkey } from "./features/hotkey"; +import { Infobox } from "./features/infobox"; +import { Milestone } from "./features/milestone"; +import { MicrotabFamily, RawMicrotabFamily, Subtab } from "./features/subtab"; +import { Upgrade } from "./features/upgrade"; +import { State } from "./state"; + +export interface RawLayer extends RawFeature { + id: string; + componentStyles?: RawComponentStyles; + achievements?: RawGridFeatures, Achievement>; + bars?: RawFeatures, Bar>; + buyables?: RawGridFeatures, Buyable>; + challenges?: RawGridFeatures, Challenge>; + clickables?: RawGridFeatures, Clickable>; + grids?: RawFeatures, Grid>; + hotkeys?: RawFeature[]; + infoboxes?: RawFeatures, Infoboxe>; + milestones?: RawFeatures, Milestone>; + subtabs?: Record>; + microtabs?: Record; + upgrades?: RawGridFeatures, Upgrade>; + startData?: () => Record; +} + +export interface Layer extends Feature { + id: string; + name?: string; + type: LayerType; + row?: number | string; + position?: number; + deactivated?: boolean; + baseResource?: string; + baseAmount?: DecimalSource; + requires?: DecimalSource; + base?: DecimalSource; + exponent?: DecimalSource; + effect?: State; + effectDisplay?: CoercableComponent; + resetDescription?: string; + component?: CoercableComponent; + midsection?: CoercableComponent; + style?: Partial; + nodeStyle?: Partial; + display?: CoercableComponent; + shown: boolean; + layerShown: boolean | "ghost"; + color: string; + glowColor: string; + minWidth: number; + displayRow: number | string; + symbol: string; + canClick?: boolean; + trueGlowColor: string; + resetGain: Decimal; + gainMult?: DecimalSource; + directMult?: DecimalSource; + gainExp?: DecimalSource; + softcap?: DecimalSource; + softcapPower?: DecimalSource; + passiveGeneration?: DecimalSource | boolean; + autoReset?: boolean; + resetsNothing?: boolean; + autoUpgrade?: boolean; + resource: string; + showNextAt?: boolean; + nextAt: Decimal; + nextAtMax: Decimal; + canReset: boolean; + prestigeButtonDisplay?: CoercableComponent; + notify: boolean; + tooltip?: CoercableComponent; + tooltipLocked?: CoercableComponent; + resetNotify: boolean; + componentStyles?: ComponentStyles; + increaseUnlockOrder?: Array; + achievements?: GridFeatures; + bars?: Features; + buyables?: GridFeatures & { + respec?: () => void; + reset: () => void; + respecButtonDisplay?: CoercableComponent; + respecWarningDisplay?: CoercableComponent; + showRespecButton?: boolean; + }; + challenges?: GridFeatures; + activeChallenge?: Challenge | undefined; + clickables?: GridFeatures & { + masterButtonClick?: () => void; + masterButtonDisplay?: CoercableComponent; + showMasterButton?: boolean; + }; + grids?: Features; + hotkeys?: Hotkey[]; + infoboxes?: Features; + milestones?: Features; + subtabs?: Record; + activeSubtab?: Subtab | undefined; + microtabs?: Record; + upgrades?: GridFeatures; + startData?: () => Record; + click?: () => void; + automate?: () => void; + reset: (force?: boolean) => void; + onReset: (resettingLayer: string) => void; + onPrestige?: (resetGain: Decimal) => void; + hardReset: (keep?: Array) => void; + update?: (diff: DecimalSource) => void; +} + +export type RawComponentStyles = Partial>; +export interface ComponentStyles { + achievement?: Partial; + bar?: Partial; + buyable?: Partial; + clickable?: Partial; + challenge?: Partial; + "grid-cell"?: Partial; + infobox?: Partial; + "infobox-title"?: Partial; + "infobox-body"?: Partial; + "main-display"?: Partial; + "master-button"?: Partial; + milestone?: Partial; + "prestige-button"?: Partial; + "respec-button"?: Partial; + upgrade?: Partial; + "tab-button"?: Partial; +} diff --git a/src/typings/player.d.ts b/src/typings/player.d.ts new file mode 100644 index 0000000..f45c2cc --- /dev/null +++ b/src/typings/player.d.ts @@ -0,0 +1,66 @@ +import { Themes } from "@/data/themes"; +import { DecimalSource } from "@/lib/break_eternity"; +import Decimal from "@/util/bignum"; +import { MilestoneDisplay } from "./features/milestone"; +import { State } from "./state"; + +export interface ModSaveData { + active?: string; + saves?: string[]; +} + +export interface PlayerData { + id: string; + devSpeed?: DecimalSource; + points: Decimal; + oomps: Decimal; + oompsMag: number; + name: string; + tabs: Array; + time: number; + autosave: boolean; + offlineProd: boolean; + offlineTime: Decimal | null; + timePlayed: Decimal; + keepGoing: boolean; + lastTenTicks: Array; + showTPS: boolean; + msDisplay: MilestoneDisplay; + hideChallenges: boolean; + theme: Themes; + subtabs: { + [index: string]: { + mainTabs?: string; + [index: string]: string; + }; + }; + minimized: Record; + modID: string; + modVersion: string; + hasNaN: boolean; + NaNPath?: Array; + NaNReceiver?: Record | null; + importing: ImportingStatus; + saveToImport: string; + saveToExport: string; + layers: Record; + [index: string]: unknown; +} + +export interface LayerSaveData { + points: Decimal; + unlocked: boolean; + unlockOrder?: number; + forceTooltip?: boolean; + resetTime: Decimal; + upgrades: Array; + achievements: Array; + milestones: Array; + infoboxes: Record; + buyables: Record; + clickables: Record; + challenges: Record; + grids: Record>; + confirmRespecBuyables: boolean; + [index: string]: unknown; +} diff --git a/src/typings/state.d.ts b/src/typings/state.d.ts new file mode 100644 index 0000000..30465fb --- /dev/null +++ b/src/typings/state.d.ts @@ -0,0 +1,2 @@ +// eslint-disable-next-line @typescript-eslint/ban-types +export type State = string | number | boolean | object; diff --git a/src/typings/theme.d.ts b/src/typings/theme.d.ts new file mode 100644 index 0000000..d05ddbb --- /dev/null +++ b/src/typings/theme.d.ts @@ -0,0 +1,7 @@ +export interface Theme { + variables: { + [index: string]: string; + }; + stackedInfoboxes: boolean; + floatingTabs: boolean; +} diff --git a/src/util/bignum.js b/src/util/bignum.ts similarity index 64% rename from src/util/bignum.js rename to src/util/bignum.ts index 1adfabe..e4ab5ff 100644 --- a/src/util/bignum.js +++ b/src/util/bignum.ts @@ -1,19 +1,22 @@ // Import Decimal and numberUtils from a different file to globally change which big num library gets used // This way switching out big number libraries just needs to happen here, not every file that needs big numbers -import Decimal, * as numberUtils from '../util/break_eternity'; +import { DecimalSource as RawDecimalSource } from "@/lib/break_eternity"; +import Decimal, * as numberUtils from "@/util/break_eternity"; export const { - exponentialFormat, - commaFormat, - regularFormat, - format, - formatWhole, - formatTime, - toPlaces, - formatSmall, - invertOOM + exponentialFormat, + commaFormat, + regularFormat, + format, + formatWhole, + formatTime, + toPlaces, + formatSmall, + invertOOM } = numberUtils; +export type DecimalSource = RawDecimalSource; + window.Decimal = Decimal; window.exponentialFormat = exponentialFormat; window.commaFormat = commaFormat; diff --git a/src/util/break_eternity.js b/src/util/break_eternity.js deleted file mode 100644 index d71bcd0..0000000 --- a/src/util/break_eternity.js +++ /dev/null @@ -1,143 +0,0 @@ -import Decimal from '../lib/break_eternity'; -import modInfo from '../data/modInfo'; - -export default Decimal; - -const decimalOne = new Decimal(1); - -export function exponentialFormat(num, precision, mantissa = true) { - let e = num.log10().floor(); - let m = num.div(Decimal.pow(10, e)); - if(m.toStringWithDecimalPlaces(precision) === 10) { - m = decimalOne; - e = e.add(1); - } - e = (e.gte(1e9) ? format(e, Math.max(Math.max(precision, 3), modInfo.defaultDecimalsShown)) : (e.gte(10000) ? commaFormat(e, 0) : e.toStringWithDecimalPlaces(0))) - if (mantissa) { - return m.toStringWithDecimalPlaces(precision)+"e"+e; - } else { - return "e"+e; - } -} - -export function commaFormat(num, precision) { - if (num === null || num === undefined) { - return "NaN"; - } - if (num.mag < 0.001) { - return (0).toFixed(precision); - } - let init = num.toStringWithDecimalPlaces(precision) - let portions = init.split(".") - portions[0] = portions[0].replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,") - if (portions.length == 1) return portions[0] - return portions[0] + "." + portions[1] -} - -export function regularFormat(num, precision) { - if (num === null || num === undefined) { - return "NaN"; - } - if (num.mag < 0.0001) { - return (0).toFixed(precision); - } - if (num.mag < 0.1 && precision !== 0) { - precision = Math.max(Math.max(precision, 4), modInfo.defaultDecimalsShown); - } - return num.toStringWithDecimalPlaces(precision); -} - -export function format(decimal, precision = null, small) { - if (precision == null) precision = modInfo.defaultDecimalsShown; - small = small || modInfo.allowSmall; - decimal = new Decimal(decimal); - if (isNaN(decimal.sign)||isNaN(decimal.layer)||isNaN(decimal.mag)) { - //player.hasNaN = true; - return "NaN"; - } - if (decimal.sign<0) { - return "-"+format(decimal.neg(), precision); - } - if (decimal.mag === Number.POSITIVE_INFINITY) { - return "Infinity"; - } - if (decimal.gte("eeee1000")) { - const slog = decimal.slog(); - if (slog.gte(1e6)) { - return "F" + format(slog.floor()); - } else { - return Decimal.pow(10, slog.sub(slog.floor())).toStringWithDecimalPlaces(3) + "F" + commaFormat(slog.floor(), 0); - } - } else if (decimal.gte("1e100000")) { - return exponentialFormat(decimal, 0, false); - } else if (decimal.gte("1e1000")) { - return exponentialFormat(decimal, 0); - } else if (decimal.gte(1e9)) { - return exponentialFormat(decimal, precision); - } else if (decimal.gte(1e3)) { - return commaFormat(decimal, 0); - } else if (decimal.gte(0.001) || !small) { - return regularFormat(decimal, precision); - } else if (decimal.eq(0)) { - return (0).toFixed(precision); - } - - decimal = invertOOM(decimal); - if (decimal.lt("1e1000")){ - const val = exponentialFormat(decimal, precision); - return val.replace(/([^(?:e|F)]*)$/, '-$1'); - } else { - return format(decimal, precision) + "⁻¹"; - } -} - -export function formatWhole(decimal) { - decimal = new Decimal(decimal); - if (decimal.sign<0) { - return "-"+formatWhole(decimal.neg()); - } - if (decimal.gte(1e9)) { - return format(decimal); - } - if (decimal.lte(0.98) && !decimal.eq(0)) { - return format(decimal); - } - return format(decimal, 0); -} - -export function formatTime(s) { - if (s<60) { - return format(s)+"s"; - } else if (s<3600) { - return formatWhole(Math.floor(s/60))+"m "+format(s%60)+"s"; - } else if (s<86400) { - return formatWhole(Math.floor(s/3600))+"h "+formatWhole(Math.floor(s/60)%60)+"m "+format(s%60)+"s"; - } else if (s<31536000) { - return formatWhole(Math.floor(s/84600)%365)+"d " + formatWhole(Math.floor(s/3600)%24)+"h "+formatWhole(Math.floor(s/60)%60)+"m "+format(s%60)+"s"; - } else { - return formatWhole(Math.floor(s/31536000))+"y "+formatWhole(Math.floor(s/84600)%365)+"d " + formatWhole(Math.floor(s/3600)%24)+"h "+formatWhole(Math.floor(s/60)%60)+"m "+format(s%60)+"s"; - } -} - -export function toPlaces(x, precision, maxAccepted) { - x = new Decimal(x); - let result = x.toStringWithDecimalPlaces(precision); - if (new Decimal(result).gte(maxAccepted)) { - result = new Decimal(maxAccepted - Math.pow(0.1, precision)).toStringWithDecimalPlaces(precision); - } - return result; -} - -// Will also display very small numbers -export function formatSmall(x, precision = null) { - return format(x, precision, true); -} - -export function invertOOM(x){ - let e = x.log10().ceil(); - let m = x.div(Decimal.pow(10, e)); - e = e.neg(); - x = new Decimal(10).pow(e).times(m); - - return x; -} diff --git a/src/util/break_eternity.ts b/src/util/break_eternity.ts new file mode 100644 index 0000000..9a92169 --- /dev/null +++ b/src/util/break_eternity.ts @@ -0,0 +1,186 @@ +import Decimal, { DecimalSource } from "@/lib/break_eternity"; +import modInfo from "@/data/modInfo.json"; + +export default Decimal; + +const decimalOne = new Decimal(1); + +export function exponentialFormat(num: DecimalSource, precision: number, mantissa = true): string { + let e = Decimal.log10(num).floor(); + let m = Decimal.div(num, Decimal.pow(10, e)); + if (m.toStringWithDecimalPlaces(precision) === "10") { + m = decimalOne; + e = e.add(1); + } + const eString = e.gte(1e9) + ? format(e, Math.max(Math.max(precision, 3), modInfo.defaultDecimalsShown)) + : e.gte(10000) + ? commaFormat(e, 0) + : e.toStringWithDecimalPlaces(0); + if (mantissa) { + return m.toStringWithDecimalPlaces(precision) + "e" + eString; + } else { + return "e" + eString; + } +} + +export function commaFormat(num: DecimalSource, precision: number): string { + if (num === null || num === undefined) { + return "NaN"; + } + num = new Decimal(num); + if (num.mag < 0.001) { + return (0).toFixed(precision); + } + const init = num.toStringWithDecimalPlaces(precision); + const portions = init.split("."); + portions[0] = portions[0].replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,"); + if (portions.length == 1) return portions[0]; + return portions[0] + "." + portions[1]; +} + +export function regularFormat(num: DecimalSource, precision: number): string { + if (num === null || num === undefined) { + return "NaN"; + } + num = new Decimal(num); + if (num.mag < 0.0001) { + return (0).toFixed(precision); + } + if (num.mag < 0.1 && precision !== 0) { + precision = Math.max(Math.max(precision, 4), modInfo.defaultDecimalsShown); + } + return num.toStringWithDecimalPlaces(precision); +} + +export function format(num: DecimalSource, precision?: number, small?: boolean): string { + if (precision == null) precision = modInfo.defaultDecimalsShown; + small = small || modInfo.allowSmall; + num = new Decimal(num); + if (isNaN(num.sign) || isNaN(num.layer) || isNaN(num.mag)) { + return "NaN"; + } + if (num.sign < 0) { + return "-" + format(num.neg(), precision); + } + if (num.mag === Number.POSITIVE_INFINITY) { + return "Infinity"; + } + if (num.gte("eeee1000")) { + const slog = num.slog(); + if (slog.gte(1e6)) { + return "F" + format(slog.floor()); + } else { + return ( + Decimal.pow(10, slog.sub(slog.floor())).toStringWithDecimalPlaces(3) + + "F" + + commaFormat(slog.floor(), 0) + ); + } + } else if (num.gte("1e100000")) { + return exponentialFormat(num, 0, false); + } else if (num.gte("1e1000")) { + return exponentialFormat(num, 0); + } else if (num.gte(1e9)) { + return exponentialFormat(num, precision); + } else if (num.gte(1e3)) { + return commaFormat(num, 0); + } else if (num.gte(0.001) || !small) { + return regularFormat(num, precision); + } else if (num.eq(0)) { + return (0).toFixed(precision); + } + + num = invertOOM(num); + if (num.lt("1e1000")) { + const val = exponentialFormat(num, precision); + return val.replace(/([^(?:e|F)]*)$/, "-$1"); + } else { + return format(num, precision) + "⁻¹"; + } +} + +export function formatWhole(num: DecimalSource): string { + num = new Decimal(num); + if (num.sign < 0) { + return "-" + formatWhole(num.neg()); + } + if (num.gte(1e9)) { + return format(num); + } + if (num.lte(0.98) && !num.eq(0)) { + return format(num); + } + return format(num, 0); +} + +export function formatTime(s: DecimalSource): string { + if (Decimal.gt(s, 2 ^ 51)) { + // integer precision limit + return format(Decimal.div(s, 31536000)) + "y"; + } + s = new Decimal(s).toNumber(); + if (s < 60) { + return format(s) + "s"; + } else if (s < 3600) { + return formatWhole(Math.floor(s / 60)) + "m " + format(s % 60) + "s"; + } else if (s < 86400) { + return ( + formatWhole(Math.floor(s / 3600)) + + "h " + + formatWhole(Math.floor(s / 60) % 60) + + "m " + + format(s % 60) + + "s" + ); + } else if (s < 31536000) { + return ( + formatWhole(Math.floor(s / 84600) % 365) + + "d " + + formatWhole(Math.floor(s / 3600) % 24) + + "h " + + formatWhole(Math.floor(s / 60) % 60) + + "m " + + format(s % 60) + + "s" + ); + } else { + return ( + formatWhole(Math.floor(s / 31536000)) + + "y " + + formatWhole(Math.floor(s / 84600) % 365) + + "d " + + formatWhole(Math.floor(s / 3600) % 24) + + "h " + + formatWhole(Math.floor(s / 60) % 60) + + "m " + + format(s % 60) + + "s" + ); + } +} + +export function toPlaces(x: DecimalSource, precision: number, maxAccepted: DecimalSource): string { + x = new Decimal(x); + let result = x.toStringWithDecimalPlaces(precision); + if (new Decimal(result).gte(maxAccepted)) { + result = Decimal.sub(maxAccepted, Math.pow(0.1, precision)).toStringWithDecimalPlaces( + precision + ); + } + return result; +} + +// Will also display very small numbers +export function formatSmall(x: DecimalSource, precision?: number): string { + return format(x, precision, true); +} + +export function invertOOM(x: DecimalSource): Decimal { + let e = Decimal.log10(x).ceil(); + const m = Decimal.div(x, Decimal.pow(10, e)); + e = e.neg(); + x = new Decimal(10).pow(e).times(m); + + return x; +} diff --git a/src/util/common.js b/src/util/common.js deleted file mode 100644 index d36f05e..0000000 --- a/src/util/common.js +++ /dev/null @@ -1,24 +0,0 @@ -import Decimal from './bignum'; - -// Reference: https://stackoverflow.com/questions/7225407/convert-camelcasetext-to-sentence-case-text -export function camelToTitle(camel) { - let title = camel.replace(/([A-Z])/g, " $1"); - title = title.charAt(0).toUpperCase() + title.slice(1); - return title; -} - -export function isPlainObject(object) { - return Object.prototype.toString.call(object) === '[object Object]'; -} - -export function isFunction(func) { - return typeof func === 'function'; -} - -export function softcap(value, cap, power = 0.5) { - if (value.lte(cap)) { - return value; - } else { - return value.pow(power).times(cap.pow(Decimal.sub(1, power))); - } -} diff --git a/src/util/common.ts b/src/util/common.ts new file mode 100644 index 0000000..638a8ce --- /dev/null +++ b/src/util/common.ts @@ -0,0 +1,30 @@ +import { DecimalSource } from "@/util/bignum"; +import Decimal from "./bignum"; + +// Reference: +// https://stackoverflow.com/questions/7225407/convert-camelcasetext-to-sentence-case-text +export function camelToTitle(camel: string): string { + let title = camel.replace(/([A-Z])/g, " $1"); + title = title.charAt(0).toUpperCase() + title.slice(1); + return title; +} + +export function isPlainObject(object: any): boolean { + return Object.prototype.toString.call(object) === "[object Object]"; +} + +export function isFunction(func: any): boolean { + return typeof func === "function"; +} + +export function softcap( + value: DecimalSource, + cap: DecimalSource, + power: DecimalSource = 0.5 +): Decimal { + if (Decimal.lte(value, cap)) { + return new Decimal(value); + } else { + return Decimal.pow(value, power).times(Decimal.pow(cap, Decimal.sub(1, power))); + } +} diff --git a/src/util/features.js b/src/util/features.js deleted file mode 100644 index ef99368..0000000 --- a/src/util/features.js +++ /dev/null @@ -1,77 +0,0 @@ -import { layers } from '../game/layers'; - -export function hasUpgrade(layer, id) { - return layers[layer]?.upgrades?.[id]?.bought; -} - -export function hasMilestone(layer, id) { - return layers[layer]?.milestones?.[id]?.earned; -} - -export function hasAchievement(layer, id) { - return layers[layer]?.achievements?.[id]?.earned; -} - -export function hasChallenge(layer, id) { - return layers[layer]?.challenges?.[id]?.completed; -} - -export function maxedChallenge(layer, id) { - return layers[layer]?.challenges?.[id]?.maxed; -} - -export function challengeCompletions(layer, id) { - return layers[layer]?.challenges?.[id]?.completions; -} - -export function inChallenge(layer, id) { - return layers[layer]?.challenges?.[id]?.active; -} - -export function getBuyableAmount(layer, id) { - return layers[layer]?.buyables?.[id]?.amount; -} - -export function setBuyableAmount(layer, id, amt) { - layers[layer].buyables[id].amount = amt; -} - -export function getClickableState(layer, id) { - return layers[layer]?.clickables?.[id]?.state; -} - -export function setClickableState(layer, id, state) { - layers[layer].clickables[id].state = state; -} - -export function getGridData(layer, id, cell) { - return layers[layer]?.grids?.[id]?.[cell]; -} - -export function setGridData(layer, id, cell, data) { - layers[layer].grids[id][cell] = data; -} - -export function upgradeEffect(layer, id) { - return layers[layer]?.upgrades?.[id]?.effect; -} - -export function challengeEffect(layer, id) { - return layers[layer]?.challenges?.[id]?.rewardEffect; -} - -export function buyableEffect(layer, id) { - return layers[layer]?.buyables?.[id]?.effect; -} - -export function clickableEffect(layer, id) { - return layers[layer]?.clickables?.[id]?.effect; -} - -export function achievementEffect(layer, id) { - return layers[layer]?.achievements?.[id]?.effect; -} - -export function gridEffect(layer, id, cell) { - return layers[layer]?.grids?.[id]?.[cell]?.effect; -} diff --git a/src/util/features.ts b/src/util/features.ts new file mode 100644 index 0000000..8e31c71 --- /dev/null +++ b/src/util/features.ts @@ -0,0 +1,89 @@ +import { layers } from "@/game/layers"; +import { GridCell } from "@/typings/features/grid"; +import { State } from "@/typings/state"; +import Decimal, { DecimalSource } from "@/util/bignum"; + +export function hasUpgrade(layer: string, id: string | number): boolean | undefined { + return layers[layer].upgrades?.data[id].bought; +} + +export function hasMilestone(layer: string, id: string | number): boolean | undefined { + return layers[layer].milestones?.data[id].earned; +} + +export function hasAchievement(layer: string, id: string | number): boolean | undefined { + return layers[layer].achievements?.data[id].earned; +} + +export function hasChallenge(layer: string, id: string | number): boolean | undefined { + return layers[layer].challenges?.data[id].completed; +} + +export function maxedChallenge(layer: string, id: string | number): boolean | undefined { + return layers[layer].challenges?.data[id].maxed; +} + +export function challengeCompletions( + layer: string, + id: string | number +): DecimalSource | undefined { + return layers[layer].challenges?.data[id].completions; +} + +export function inChallenge(layer: string, id: string | number): boolean | undefined { + return layers[layer].challenges?.data[id].active; +} + +export function getBuyableAmount(layer: string, id: string | number): Decimal | undefined { + return layers[layer].buyables?.data[id].amount; +} + +export function setBuyableAmount(layer: string, id: string | number, amt: Decimal): void { + if (layers[layer].buyables?.data[id]) { + layers[layer].buyables!.data[id].amount = amt; + } +} + +export function getClickableState(layer: string, id: string | number): State | undefined { + return layers[layer].clickables?.data[id].state; +} + +export function setClickableState(layer: string, id: string | number, state: State): void { + if (layers[layer].clickables?.data[id]) { + layers[layer].clickables!.data[id].state = state; + } +} + +export function getGridData(layer: string, id: string | number, cell: string): State | undefined { + return (layers[layer].grids?.data[id][cell] as GridCell).effect; +} + +export function setGridData(layer: string, id: string | number, cell: string, data: State): void { + if (layers[layer].grids?.data[id][cell]) { + layers[layer].grids!.data[id][cell] = data; + } +} + +export function upgradeEffect(layer: string, id: string | number): State | undefined { + return layers[layer].upgrades?.data[id].effect; +} + +export function challengeEffect(layer: string, id: string | number): State | undefined { + return layers[layer].challenges?.data[id].effect; +} + +export function buyableEffect(layer: string, id: string | number): State | undefined { + return layers[layer].buyables?.data[id].effect; +} + +export function clickableEffect(layer: string, id: string | number): State | undefined { + return layers[layer].clickables?.data[id].effect; +} + +export function achievementEffect(layer: string, id: string | number): State | undefined { + return layers[layer].achievements?.data[id].effect; +} + +export function gridEffect(layer: string, id: string, cell: string | number): State | undefined { + return (layers[layer].grids?.data[id][cell] as GridCell).effect; +} diff --git a/src/util/layers.js b/src/util/layers.js deleted file mode 100644 index 5d9c0cb..0000000 --- a/src/util/layers.js +++ /dev/null @@ -1,313 +0,0 @@ -import Decimal from './bignum'; -import { isPlainObject } from './common'; -import { layers, hotkeys } from '../game/layers'; -import player from '../game/player'; - -export function resetLayer(layer, force = false) { - layers[layer].reset(force); -} - -export function hardReset(layer, keep = []) { - layers[layer].hardReset(keep); -} - -export function cache(func) { - func.forceCached = true; - return func; -} - -export function noCache(func) { - func.forceCached = false; - return func; -} - -export function getStartingBuyables(layer) { - return layer.buyables && Object.keys(layer.buyables).reduce((acc, curr) => { - if (isPlainObject(layer.buyables[curr])) { - acc[curr] = new Decimal(0); - } - return acc; - }, {}); -} - -export function getStartingClickables(layer) { - return layer.clickables && Object.keys(layer.clickables).reduce((acc, curr) => { - if (isPlainObject(layer.clickables[curr])) { - acc[curr] = ""; - } - return acc; - }, {}); -} - -export function getStartingChallenges(layer) { - return layer.challenges && Object.keys(layer.challenges).reduce((acc, curr) => { - if (isPlainObject(layer.challenges[curr])) { - acc[curr] = new Decimal(0); - } - return acc; - }, {}); -} - -export function resetLayerData(layer, keep = []) { - keep.push('unlocked', 'forceTooltip', 'noRespecConfirm'); - const keptData = keep.reduce((acc, curr) => { - acc[curr] = player[layer][curr]; - return acc; - }, {}); - - player.upgrades = []; - player.achievements = []; - player.milestones = []; - player.infoboxes = {}; - - player[layer].buyables = getStartingBuyables(layers[layer]); - player[layer].clickables = getStartingClickables(layers[layer]); - player[layer].challenges = getStartingChallenges(layers[layer]); - - Object.assign(player[layer], layers[layer].startData?.()); - - for (let item in keptData) { - player[layer][item] = keptData[item]; - } -} - -export function resetRow(row, ignore) { - Object.values(layers).filter(layer => layer.row === row && layer.layer !== ignore).forEach(layer => layer.hardReset()); -} - -export const defaultLayerProperties = { - type: "none", - shown: true, - layerShown: true, - glowColor: "red", - minWidth: 640, - displayRow() { - return this.row; - }, - symbol() { - return this.id; - }, - unlocked() { - if (player[this.id].unlocked) { - return true; - } - if (this.type !== "none" && this.canReset && this.layerShown) { - return true; - } - return false; - }, - trueGlowColor() { - if (this.subtabs) { - for (let subtab of Object.values(this.subtabs)) { - if (subtab.notify) { - return subtab.glowColor || "red"; - } - } - } - if (this.microtabs) { - for (let microtab of Object.values(this.microtabs)) { - if (microtab.notify) { - return microtab.glowColor || "red"; - } - } - } - return this.glowColor || "red"; - }, - resetGain() { - if (this.type === "none" || this.type === "custom") { - return new Decimal(0); - } - if (this.gainExp?.eq(0)) { - return new Decimal(0); - } - if (this.baseAmount.lt(this.requires)) { - return new Decimal(0); - } - if (this.type === "static") { - if (!this.canBuyMax) { - return new Decimal(1); - } - let gain = this.baseAmount.div(this.requires).div(this.gainMult || 1).max(1).log(this.base) - .times(this.gainExp || 1).pow(Decimal.pow(this.exponent || 1, -1)); - gain = gain.times(this.directMult || 1); - return gain.floor().sub(player[this.layer].points).add(1).max(1); - } - if (this.type === "normal") { - let gain = this.baseAmount.div(this.requires).pow(this.exponent || 1).times(this.gainMult || 1) - .pow(this.gainExp || 1); - if (this.softcap && gain.gte(this.softcap)) { - gain = gain.pow(this.softcapPower).times(this.softcap.pow(Decimal.sub(1, this.softcapPower))); - } - gain = gain.times(this.directMult || 1); - return gain.floor().max(0); - } - // Unknown prestige type - return new Decimal(0); - }, - nextAt() { - if (this.type === "none" || this.type === "custom") { - return new Decimal(Infinity); - } - if (this.gainMult?.lte(0) || this.gainExp?.lte(0)) { - return new Decimal(Infinity); - } - if (this.type === "static") { - const amount = player[this.layer].points.div(this.directMult || 1); - const extraCost = Decimal.pow(this.base, amount.pow(this.exponent || 1).div(this.gainExp || 1)) - .times(this.gainMult || 1); - let cost = extraCost.times(this.requires).max(this.requires); - if (this.roundUpCost) { - cost = cost.ceil(); - } - return cost; - } - if (this.type === "normal") { - let next = this.resetGain.add(1).div(this.directMult || 1); - if (this.softcap && next.gte(this.softcap)) { - next = next.div(this.softcap.pow(Decimal.sub(1, this.softcapPower))) - .pow(Decimal.div(1, this.softcapPower)); - } - next = next.root(this.gainExp || 1).div(this.gainMult || 1).root(this.exponent || 1) - .times(this.requires).max(this.requires); - if (this.roundUpCost) { - next = next.ceil(); - } - return next; - } - // Unknown prestige type - return new Decimal(0); - }, - nextAtMax() { - if (!this.canBuyMax || this.type !== "static") { - return this.nextAt; - } - const amount = player[this.layer].points.plus(this.resetGain).div(this.directMult || 1); - const extraCost = Decimal.pow(this.base, amount.pow(this.exponent || 1).div(this.gainExp || 1)) - .times(this.gainMult || 1); - let cost = extraCost.times(this.requires).max(this.requires); - if (this.roundUpCost) { - cost = cost.ceil(); - } - return cost; - }, - canReset() { - if (this.type === "normal") { - return this.baseAmount.gte(this.requires); - } - if (this.type === "static") { - return this.baseAmount.gte(this.nextAt); - } - return false; - }, - notify() { - if (this.upgrades) { - if (Object.values(this.upgrades).some(upgrade => upgrade.canAfford && !upgrade.bought && upgrade.unlocked)) { - return true; - } - } - if (this.activeChallenge?.canComplete) { - return true; - } - if (this.subtabs) { - if (Object.values(this.subtabs).some(subtab => subtab.notify)) { - return true; - } - } - if (this.microtabs) { - if (Object.values(this.microtabs).some(subtab => subtab.notify)) { - return true; - } - } - - return false; - }, - resetNotify() { - if (this.subtabs) { - if (Object.values(this.subtabs).some(subtab => subtab.prestigeNotify)) { - return true; - } - } - if (this.microtabs) { - if (Object.values(this.microtabs).some(microtab => microtab.prestigeNotify)) { - return true; - } - } - if (this.autoPrestige || this.passiveGeneration) { - return false; - } - if (this.type === "static") { - return this.canReset; - } - if (this.type === "normal") { - return this.canReset && this.resetGain.gte(player[this.layer].points.div(10)); - } - return false; - }, - reset(force = false) { - if (this.type === 'none') { - return; - } - if (!force) { - if (!this.canReset) { - return; - } - this.onPrestige?.(this.resetGain); - if (player[this.layer].points != undefined) { - player[this.layer].points = player[this.layer].points.add(this.resetGain); - } - if (!player[this.layer].unlocked) { - player[this.layer].unlocked = true; - if (this.increaseUnlockOrder) { - for (let layer in this.increaseUnlockOrder) { - player[layer].unlockOrder = (player[layer].unlockOrder || 0) + 1; - } - } - } - } - - if (this.resetsNothing) { - return; - } - - Object.values(layers).forEach(layer => { - if (this.row >= layer.row && (!force || this !== layer)) { - this.activeChallenge?.toggle(); - } - }); - - player.points = new Decimal(0); - - for (let row = this.row - 1; row >= 0; row--) { - resetRow(row, this.layer); - } - resetRow('side', this.layer); - - if (player[this.layer].resetTime != undefined) { - player[this.layer].resetTime = 0; - } - }, - hardReset(keep = []) { - if (!isNaN(this.row)) { - resetLayerData(this.layer, keep); - } - } -}; - -document.onkeydown = function(e) { - if (player.hasWon && !player.keepGoing) { - return; - } - let key = e.key; - if (e.shiftKey) { - key = "shift+" + key; - } - if (e.ctrlKey) { - key = "ctrl+" + key; - } - if (hotkeys[key]) { - e.preventDefault(); - if (hotkeys[key].unlocked) { - hotkeys[key].press?.(); - } - } -} diff --git a/src/util/layers.ts b/src/util/layers.ts new file mode 100644 index 0000000..5bbb2e2 --- /dev/null +++ b/src/util/layers.ts @@ -0,0 +1,390 @@ +import { hotkeys, layers } from "@/game/layers"; +import player from "@/game/player"; +import { CacheableFunction } from "@/typings/cacheableFunction"; +import { Buyable } from "@/typings/features/buyable"; +import { Challenge } from "@/typings/features/challenge"; +import { Clickable } from "@/typings/features/clickable"; +import { RawFeature } from "@/typings/features/feature"; +import { MicrotabFamily, Subtab } from "@/typings/features/subtab"; +import { Layer, RawLayer } from "@/typings/layer"; +import { State } from "@/typings/state"; +import Decimal from "./bignum"; + +export function resetLayer(layer: string, force = false): void { + layers[layer].reset(force); +} + +export function hardReset(layer: string, keep: Array = []): void { + layers[layer].hardReset(keep); +} + +// eslint-disable-next-line @typescript-eslint/ban-types +export function cache(func: T): T & CacheableFunction { + return Object.assign(func, { forceCached: true }); +} + +// eslint-disable-next-line @typescript-eslint/ban-types +export function noCache(func: T): T & CacheableFunction { + return Object.assign(func, { forceCached: false }); +} + +export function getStartingBuyables( + buyables?: Record | Record> | undefined +): Record { + return buyables + ? Object.keys(buyables).reduce((acc: Record, curr: string): Record< + string, + Decimal + > => { + acc[curr] = new Decimal(0); + return acc; + }, {}) + : {}; +} + +export function getStartingClickables( + clickables?: Record | Record> | undefined +): Record { + return clickables + ? Object.keys(clickables).reduce((acc: Record, curr: string): Record< + string, + State + > => { + acc[curr] = ""; + return acc; + }, {}) + : {}; +} + +export function getStartingChallenges( + challenges?: Record | Record> | undefined +): Record { + return challenges + ? Object.keys(challenges).reduce((acc: Record, curr: string): Record< + string, + Decimal + > => { + acc[curr] = new Decimal(0); + return acc; + }, {}) + : {}; +} + +export function resetLayerData(layer: string, keep: Array = []): void { + keep.push("unlocked", "forceTooltip", "noRespecConfirm"); + const keptData = keep.reduce((acc: Record, curr: string): Record => { + acc[curr] = player.layers[layer][curr]; + return acc; + }, {}); + + player.upgrades = []; + player.achievements = []; + player.milestones = []; + player.infoboxes = {}; + + player.layers[layer].buyables = getStartingBuyables(layers[layer].buyables?.data); + player.layers[layer].clickables = getStartingClickables(layers[layer].clickables?.data); + player.layers[layer].challenges = getStartingChallenges(layers[layer].challenges?.data); + + Object.assign(player.layers[layer], layers[layer].startData?.()); + + for (const item in keptData) { + player.layers[layer][item] = keptData[item]; + } +} + +export function resetRow(row: string | number | undefined, ignore?: string): void { + Object.values(layers) + .filter(layer => layer.row === row && layer.layer !== ignore) + .forEach(layer => layer.hardReset()); +} + +export const defaultLayerProperties = { + type: "none", + shown: true, + layerShown: true, + glowColor: "red", + minWidth: 640, + displayRow() { + return this.row; + }, + symbol() { + return this.id; + }, + unlocked() { + if (player.layers[this.id].unlocked) { + return true; + } + if (this.type !== "none" && this.canReset && this.layerShown) { + return true; + } + return false; + }, + trueGlowColor() { + if (this.subtabs) { + for (const subtab of Object.values(this.subtabs)) { + if (subtab.notify) { + return subtab.glowColor || "red"; + } + } + } + if (this.microtabs) { + for (const microtabFamily of Object.values(this.microtabs)) { + for (const microtab of Object.values(microtabFamily.data)) { + if (microtab.notify) { + return microtab.glowColor || "red"; + } + } + } + } + return this.glowColor || "red"; + }, + resetGain() { + if (this.type === "none" || this.type === "custom") { + return new Decimal(0); + } + if (this.gainExp && Decimal.eq(this.gainExp, 0)) { + return new Decimal(0); + } + if (Decimal.lt(this.baseAmount!, this.requires!)) { + return new Decimal(0); + } + if (this.type === "static") { + if (!this.canBuyMax) { + return new Decimal(1); + } + let gain = Decimal.div(this.baseAmount!, this.requires!) + .div(this.gainMult || 1) + .max(1) + .log(this.base!) + .times(this.gainExp || 1) + .pow(Decimal.pow(this.exponent || 1, -1)); + gain = gain.times(this.directMult || 1); + return gain + .floor() + .sub(player.layers[this.layer].points) + .add(1) + .max(1); + } + if (this.type === "normal") { + let gain = Decimal.div(this.baseAmount!, this.requires!) + .pow(this.exponent || 1) + .times(this.gainMult || 1) + .pow(this.gainExp || 1); + if (this.softcap && this.softcapPower && gain.gte(this.softcap)) { + gain = gain + .pow(this.softcapPower) + .times(Decimal.pow(this.softcap, Decimal.sub(1, this.softcapPower))); + } + gain = gain.times(this.directMult || 1); + return gain.floor().max(0); + } + // Unknown prestige type + return new Decimal(0); + }, + nextAt() { + if (this.type === "none" || this.type === "custom") { + return new Decimal(Infinity); + } + if ( + (this.gainMult && Decimal.lte(this.gainMult, 0)) || + (this.gainExp && Decimal.lte(this.gainExp, 0)) + ) { + return new Decimal(Infinity); + } + if (this.type === "static") { + const amount = player.layers[this.layer].points.div(this.directMult || 1); + const extraCost = Decimal.pow( + this.base!, + amount.pow(this.exponent || 1).div(this.gainExp || 1) + ).times(this.gainMult || 1); + let cost = extraCost.times(this.requires!).max(this.requires!); + if (this.roundUpCost) { + cost = cost.ceil(); + } + return cost; + } + if (this.type === "normal") { + let next = this.resetGain.add(1).div(this.directMult || 1); + if (this.softcap && this.softcapPower && next.gte(this.softcap)) { + next = next + .div(Decimal.pow(this.softcap, Decimal.sub(1, this.softcapPower))) + .pow(Decimal.div(1, this.softcapPower)); + } + next = next + .root(this.gainExp || 1) + .div(this.gainMult || 1) + .root(this.exponent || 1) + .times(this.requires!) + .max(this.requires!); + if (this.roundUpCost) { + next = next.ceil(); + } + return next; + } + // Unknown prestige type + return new Decimal(0); + }, + nextAtMax() { + if (!this.canBuyMax || this.type !== "static") { + return this.nextAt; + } + const amount = player.layers[this.layer].points + .plus(this.resetGain) + .div(this.directMult || 1); + const extraCost = Decimal.pow( + this.base!, + amount.pow(this.exponent || 1).div(this.gainExp || 1) + ).times(this.gainMult || 1); + let cost = extraCost.times(this.requires!).max(this.requires!); + if (this.roundUpCost) { + cost = cost.ceil(); + } + return cost; + }, + canReset() { + if (this.type === "normal") { + return Decimal.gte(this.baseAmount!, this.requires!); + } + if (this.type === "static") { + return Decimal.gte(this.baseAmount!, this.nextAt); + } + return false; + }, + notify() { + if (this.upgrades) { + if ( + Object.values(this.upgrades.data).some( + upgrade => upgrade.canAfford && !upgrade.bought && upgrade.unlocked + ) + ) { + return true; + } + } + if (this.activeChallenge?.canComplete) { + return true; + } + if (this.subtabs) { + if (Object.values(this.subtabs).some(subtab => subtab.notify)) { + return true; + } + } + if (this.microtabs) { + for (const microtabFamily of Object.values(this.microtabs)) { + if (Object.values(microtabFamily.data).some(subtab => subtab.notify)) { + return true; + } + } + } + + return false; + }, + resetNotify() { + if (this.subtabs) { + if (Object.values(this.subtabs).some(subtab => subtab.prestigeNotify)) { + return true; + } + } + if (this.microtabs) { + for (const microtabFamily of Object.values(this.microtabs)) { + if (Object.values(microtabFamily.data).some(subtab => subtab.prestigeNotify)) { + return true; + } + } + } + if (this.autoPrestige || this.passiveGeneration) { + return false; + } + if (this.type === "static") { + return this.canReset; + } + if (this.type === "normal") { + return this.canReset && this.resetGain.gte(player.layers[this.layer].points.div(10)); + } + return false; + }, + reset(force = false) { + if (this.type === "none") { + return; + } + if (!force) { + if (!this.canReset) { + return; + } + this.onPrestige?.(this.resetGain); + if (player.layers[this.layer].points != undefined) { + player.layers[this.layer].points = player.layers[this.layer].points.add( + this.resetGain + ); + } + if (!player.layers[this.layer].unlocked) { + player.layers[this.layer].unlocked = true; + if (this.increaseUnlockOrder) { + for (const layer in this.increaseUnlockOrder) { + player.layers[layer].unlockOrder = + (player.layers[layer].unlockOrder || 0) + 1; + } + } + } + } + + if (this.resetsNothing) { + return; + } + + Object.values(layers) + .filter(layer => typeof layer.row === "number") + .forEach(layer => { + if ((this.row as number) >= (layer.row as number) && (!force || this !== layer)) { + this.activeChallenge?.toggle(); + } + }); + + player.points = new Decimal(0); + + Object.values(layers) + .sort((a, b) => { + if (typeof a.row !== "number" || typeof b.row !== "number") { + return 0; + } + return a.row - b.row; + }) + .forEach(layer => layer.onReset(this.layer)); + + if (player.layers[this.layer].resetTime != undefined) { + player.layers[this.layer].resetTime = new Decimal(0); + } + }, + onReset(resettingLayer: string) { + if ( + typeof layers[resettingLayer].row === "number" && + typeof this.row === "number" && + (layers[resettingLayer].row as number) > this.row + ) { + this.hardReset(); + } + }, + hardReset(keep = []) { + if (!isNaN(Number(this.row))) { + resetLayerData(this.layer, keep); + } + } +} as Omit & Partial> & ThisType; + +document.onkeydown = function(e) { + if (player.hasWon && !player.keepGoing) { + return; + } + let key = e.key; + if (e.shiftKey) { + key = "shift+" + key; + } + if (e.ctrlKey) { + key = "ctrl+" + key; + } + const hotkey = hotkeys.find(hotkey => hotkey.key === key); + if (hotkey && hotkey.unlocked) { + e.preventDefault(); + hotkey.press?.(); + } +}; diff --git a/src/util/proxies.js b/src/util/proxies.js deleted file mode 100644 index 6638cf5..0000000 --- a/src/util/proxies.js +++ /dev/null @@ -1,149 +0,0 @@ -import { isFunction, isPlainObject } from './common'; -import Decimal from './bignum'; -import { isRef, computed } from 'vue'; - -export function createProxy(object) { - if (object.isProxy) { - console.warn("Creating a proxy out of a proxy! This may cause unintentional function calls and stack overflows."); - } - const objectProxy = new Proxy(object, mainHandler); - travel(createProxy, object, objectProxy); - return objectProxy; -} - -// TODO cache grid values? Currently they'll be calculated every render they're visible -export function createGridProxy(object) { - if (object.isProxy) { - console.warn("Creating a proxy out of a proxy! This may cause unintentional function calls and stack overflows."); - } - const objectProxy = new Proxy(object, gridHandler); - travel(createGridProxy, object, objectProxy); - return objectProxy; -} - -function travel(callback, object, objectProxy) { - for (let key in object) { - if (object[key] == undefined || object[key].isProxy) { - continue; - } - if (isFunction(object[key])) { - if ((object[key].length !== 0 && object[key].forceCached !== true) || object[key].forceCached === false) { - continue; - } - object[key] = computed(object[key].bind(objectProxy)); - } else if ((isPlainObject(object[key]) || Array.isArray(object[key])) && !(object[key] instanceof Decimal)) { - object[key] = callback(object[key]); - } - } -} - -const mainHandler = { - get(target, key, receiver) { - if (key === 'isProxy') { - return true; - } - - if (target[key] == undefined) { - return; - } - - if (isRef(target[key])) { - return target[key].value; - } else if (target[key].isProxy || target[key] instanceof Decimal) { - return target[key]; - } else if ((isPlainObject(target[key]) || Array.isArray(target[key])) && key.slice(0, 2) !== '__') { - console.warn("Creating proxy outside `createProxy`. This may cause issues when calling proxied functions.", - target, key); - target[key] = new Proxy(target[key], mainHandler); - return target[key]; - } else if (isFunction(target[key])) { - return target[key].bind(receiver); - } - return target[key]; - }, - set(target, key, value, receiver) { - if (`${key}Set` in target && isFunction(target[`${key}Set`]) && target[`${key}Set`].length < 2) { - target[`${key}Set`].call(receiver, value); - return true; - } else { - console.warn(`No setter for "${key}".`, target); - } - } -}; - -const gridHandler = { - get(target, key, receiver) { - if (key === 'isProxy') { - return true; - } - - if (isRef(target[key])) { - return target[key].value; - } else if (target[key] && (target[key].isProxy || target[key] instanceof Decimal)) { - return target[key]; - } else if (isPlainObject(target[key]) || Array.isArray(target[key])) { - console.warn("Creating proxy outside `createProxy`. This may cause issues when calling proxied functions.", - target, key); - target[key] = new Proxy(target[key], mainHandler); - return target[key]; - } else if (isFunction(target[key])) { - return target[key].bind(receiver); - } - if (typeof key !== 'symbol' && !isNaN(key)) { - target[key] = new Proxy(target, getCellHandler(key)); - } - return target[key]; - }, - set(target, key, value, receiver) { - if (`${key}Set` in target && isFunction(target[`${key}Set`]) && target[`${key}Set`].length < 2) { - target[`${key}Set`].call(receiver, value); - return true; - } else { - console.warn(`No setter for "${key}".`, target); - } - } -}; - -function getCellHandler(id) { - return { - get(target, key, receiver) { - if (key === 'isProxy') { - return true; - } - - let prop = target[key]; - - if (isFunction(prop) && prop.forceCached === false) { - return () => prop.call(receiver, id, target.getData(id)); - } - if (prop != undefined || key.slice == undefined) { - return prop; - } - - key = key.slice(0, 1).toUpperCase() + key.slice(1); - prop = target[`get${key}`]; - if (isFunction(prop)) { - return prop.call(receiver, id, target.getData(id)); - } else if (prop != undefined) { - return prop; - } - - prop = target[`on${key}`]; - if (isFunction(prop)) { - return () => prop.call(receiver, id, target.getData(id)); - } else if (prop != undefined) { - return prop; - } - - return target[key]; - }, - set(target, key, value, receiver) { - if (`${key}Set` in target && isFunction(target[`${key}Set`]) && target[`${key}Set`].length < 3) { - target[`${key}Set`].call(receiver, id, value); - return true; - } else { - console.warn(`No setter for "${key}".`, target); - } - } - }; -} diff --git a/src/util/proxies.ts b/src/util/proxies.ts new file mode 100644 index 0000000..57fa533 --- /dev/null +++ b/src/util/proxies.ts @@ -0,0 +1,187 @@ +import { computed, isRef } from "vue"; +import Decimal from "./bignum"; +import { isFunction, isPlainObject } from "./common"; + +export function createLayerProxy(object: Record): Record { + if (object.isProxy) { + console.warn( + "Creating a proxy out of a proxy! This may cause unintentional function calls and stack overflows." + ); + } + const objectProxy = new Proxy(object, layerHandler); + travel(createLayerProxy, object, objectProxy); + return objectProxy; +} + +// TODO cache grid values? Currently they'll be calculated every render they're visible +export function createGridProxy(object: Record): Record { + if (object.isProxy) { + console.warn( + "Creating a proxy out of a proxy! This may cause unintentional function calls and stack overflows." + ); + } + const objectProxy = new Proxy(object, gridHandler); + travel(createGridProxy, object, objectProxy); + return objectProxy; +} + +function travel( + callback: (object: Record) => void, + object: Record, + objectProxy: Record +) { + for (const key in object) { + if (object[key] == undefined || object[key].isProxy) { + continue; + } + if (isFunction(object[key])) { + if ( + (object[key].length !== 0 && object[key].forceCached !== true) || + object[key].forceCached === false + ) { + continue; + } + object[key] = computed(object[key].bind(objectProxy)); + } else if ( + (isPlainObject(object[key]) || Array.isArray(object[key])) && + !(object[key] instanceof Decimal) + ) { + object[key] = callback(object[key]); + } + } +} + +const layerHandler: ProxyHandler> = { + get(target: Record, key: string, receiver: typeof Proxy): any { + if (key === "isProxy") { + return true; + } + + if (target[key] == undefined) { + return; + } + + if (isRef(target[key])) { + return target[key].value; + } else if (target[key].isProxy || target[key] instanceof Decimal) { + return target[key]; + } else if ( + (isPlainObject(target[key]) || Array.isArray(target[key])) && + key.slice(0, 2) !== "__" + ) { + console.warn( + "Creating proxy outside `createProxy`. This may cause issues when calling proxied functions.", + target, + key + ); + target[key] = new Proxy(target[key], layerHandler); + return target[key]; + } else if (isFunction(target[key])) { + return target[key].bind(receiver); + } + return target[key]; + }, + set(target: Record, key: string, value: any, receiver: typeof Proxy): boolean { + if ( + `${key}Set` in target && + isFunction(target[`${key}Set`]) && + target[`${key}Set`].length < 2 + ) { + target[`${key}Set`].call(receiver, value); + return true; + } else { + console.warn(`No setter for "${key}".`, target); + return false; + } + } +}; + +const gridHandler: ProxyHandler> = { + get(target: Record, key: string, receiver: typeof Proxy): any { + if (key === "isProxy") { + return true; + } + + if (isRef(target[key])) { + return target[key].value; + } else if (target[key] && (target[key].isProxy || target[key] instanceof Decimal)) { + return target[key]; + } else if (isPlainObject(target[key]) || Array.isArray(target[key])) { + console.warn( + "Creating proxy outside `createProxy`. This may cause issues when calling proxied functions.", + target, + key + ); + target[key] = new Proxy(target[key], layerHandler); + return target[key]; + } else if (isFunction(target[key])) { + return target[key].bind(receiver); + } + if (typeof key !== "symbol" && !isNaN(Number(key))) { + target[key] = new Proxy(target, getCellHandler(key)); + } + return target[key]; + }, + set(target: Record, key: string, value: any, receiver: typeof Proxy): boolean { + if ( + `${key}Set` in target && + isFunction(target[`${key}Set`]) && + target[`${key}Set`].length < 2 + ) { + target[`${key}Set`].call(receiver, value); + return true; + } else { + console.warn(`No setter for "${key}".`, target); + return false; + } + } +}; + +function getCellHandler(id: string) { + return { + get(target: Record, key: string, receiver: typeof Proxy): any { + if (key === "isProxy") { + return true; + } + + let prop = target[key]; + + if (isFunction(prop) && prop.forceCached === false) { + return () => prop.call(receiver, id, target.getData(id)); + } + if (prop != undefined || key.slice == undefined) { + return prop; + } + + key = key.slice(0, 1).toUpperCase() + key.slice(1); + prop = target[`get${key}`]; + if (isFunction(prop)) { + return prop.call(receiver, id, target.getData(id)); + } else if (prop != undefined) { + return prop; + } + + prop = target[`on${key}`]; + if (isFunction(prop)) { + return () => prop.call(receiver, id, target.getData(id)); + } else if (prop != undefined) { + return prop; + } + + return target[key]; + }, + set(target: Record, key: string, value: any, receiver: typeof Proxy): boolean { + if ( + `${key}Set` in target && + isFunction(target[`${key}Set`]) && + target[`${key}Set`].length < 3 + ) { + target[`${key}Set`].call(receiver, id, value); + return true; + } else { + console.warn(`No setter for "${key}".`, target); + return false; + } + } + }; +} diff --git a/src/util/save.js b/src/util/save.js deleted file mode 100644 index 3cc865a..0000000 --- a/src/util/save.js +++ /dev/null @@ -1,160 +0,0 @@ -import modInfo from '../data/modInfo'; -import { getStartingData, getInitialLayers, fixOldSave } from '../data/mod'; -import player from '../game/player'; -import Decimal from './bignum'; - -export const NOT_IMPORTING = false; -export const IMPORTING = true; -export const IMPORTING_FAILED = "FAILED"; -export const IMPORTING_WRONG_ID = "WRONG_ID"; -export const IMPORTING_FORCE = "FORCE"; - -export function getInitialStore(playerData = {}) { - return applyPlayerData({ - id: `${modInfo.id}-0`, - name: "Default Save", - tabs: modInfo.initialTabs.slice(), - time: Date.now(), - autosave: true, - offlineProd: true, - timePlayed: new Decimal(0), - keepGoing: false, - lastTenTicks: [], - showTPS: true, - msDisplay: "all", - hideChallenges: false, - theme: "paper", - subtabs: {}, - minimized: {}, - modID: modInfo.id, - modVersion: modInfo.versionNumber, - ...getStartingData(), - - // Values that don't get loaded/saved - hasNaN: false, - NaNPath: [], - NaNReceiver: null, - importing: NOT_IMPORTING, - saveToImport: "", - saveToExport: "" - }, playerData); -} - -export function save() { - /* eslint-disable-next-line no-unused-vars */ - let { hasNaN, NaNPath, NaNReceiver, importing, saveToImport, saveToExport, ...playerData } = player.__state; - player.saveToExport = btoa(unescape(encodeURIComponent(JSON.stringify(playerData)))); - - localStorage.setItem(player.id, player.saveToExport); -} - -export async function load() { - try { - let modData = localStorage.getItem(modInfo.id); - if (modData == null) { - await loadSave(newSave()); - return; - } - modData = JSON.parse(decodeURIComponent(escape(atob(modData)))); - if (modData?.active == null) { - await loadSave(newSave()); - return; - } - const save = localStorage.getItem(modData.active); - const playerData = JSON.parse(decodeURIComponent(escape(atob(save)))); - if (playerData.modID !== modInfo.id) { - await loadSave(newSave()); - return; - } - playerData.id = modData.active; - await loadSave(playerData); - } catch (e) { - await loadSave(newSave()); - } -} - -export async function newSave() { - const id = getUniqueID(); - const playerData = getInitialStore({ id }); - localStorage.setItem(id, btoa(unescape(encodeURIComponent(JSON.stringify(playerData))))); - - if (!localStorage.getItem(modInfo.id)) { - const modData = { active: id, saves: [ id ] }; - localStorage.setItem(modInfo.id, btoa(unescape(encodeURIComponent(JSON.stringify(modData))))); - } else { - const modData = JSON.parse(decodeURIComponent(escape(atob(localStorage.getItem(modInfo.id))))); - modData.saves.push(id); - localStorage.setItem(modInfo.id, btoa(unescape(encodeURIComponent(JSON.stringify(modData))))); - } - - return playerData; -} - -export function getUniqueID() { - let id, i = 0; - do { - id = `${modInfo.id}-${i++}`; - } while (localStorage.getItem(id)); - return id; -} - -export async function loadSave(playerData) { - const { layers, removeLayer, addLayer } = await import('../game/layers'); - - for (let layer in layers) { - removeLayer(layer); - } - getInitialLayers(playerData).forEach(layer => addLayer(layer, playerData)); - - playerData = getInitialStore(playerData); - if (playerData.offlineProd) { - if (playerData.offTime === undefined) - playerData.offTime = { remain: 0 }; - playerData.offTime.remain += (Date.now() - playerData.time) / 1000; - } - playerData.time = Date.now(); - if (playerData.modVersion !== modInfo.versionNumber) { - fixOldSave(playerData.modVersion, playerData); - } - - Object.assign(player, playerData); - for (let prop in player) { - if (!(prop in playerData) && !(prop in layers) && prop !== '__state' && prop !== '__path') { - delete player[prop]; - } - } -} - -export function applyPlayerData(target, source, destructive = false) { - for (let prop in source) { - if (target[prop] == null) { - target[prop] = source[prop]; - } else if (target[prop] instanceof Decimal) { - target[prop] = new Decimal(source[prop]); - } else if (Array.isArray(target[prop]) || typeof target[prop] === 'object') { - target[prop] = applyPlayerData(target[prop], source[prop], destructive); - } else { - target[prop] = source[prop]; - } - } - if (destructive) { - for (let prop in target) { - if (!(prop in source)) { - delete target[prop]; - } - } - } - return target; -} - -setInterval(() => { - if (player.autosave) { - save(); - } -}, 1000); -window.onbeforeunload = () => { - if (player.autosave) { - save(); - } -}; -window.save = save; diff --git a/src/util/save.ts b/src/util/save.ts new file mode 100644 index 0000000..ccf6a53 --- /dev/null +++ b/src/util/save.ts @@ -0,0 +1,191 @@ +import { fixOldSave, getInitialLayers, getStartingData } from "@/data/mod"; +import modInfo from "@/data/modInfo.json"; +import { Themes } from "@/data/themes"; +import { ImportingStatus, MilestoneDisplay } from "@/game/enums"; +import player from "@/game/player"; +import { ModSaveData, PlayerData } from "@/typings/player"; +import Decimal from "./bignum"; + +export function getInitialStore(playerData: Partial = {}): PlayerData { + return applyPlayerData( + { + id: `${modInfo.id}-0`, + points: new Decimal(0), + oomps: new Decimal(0), + oompsMag: 0, + name: "Default Save", + tabs: modInfo.initialTabs.slice(), + time: Date.now(), + autosave: true, + offlineProd: true, + timePlayed: new Decimal(0), + keepGoing: false, + lastTenTicks: [], + showTPS: true, + msDisplay: MilestoneDisplay.All, + hideChallenges: false, + theme: Themes.Paper, + subtabs: {}, + minimized: {}, + modID: modInfo.id, + modVersion: modInfo.versionNumber, + layers: {}, + ...getStartingData(), + + // Values that don't get loaded/saved + hasNaN: false, + NaNPath: [], + NaNReceiver: null, + importing: ImportingStatus.NotImporting, + saveToImport: "", + saveToExport: "" + }, + playerData + ) as PlayerData; +} + +export function save(): void { + /* eslint-disable @typescript-eslint/no-unused-vars */ + const { + hasNaN, + NaNPath, + NaNReceiver, + importing, + saveToImport, + saveToExport, + ...playerData + } = player.__state as PlayerData; + /* eslint-enable @typescript-eslint/no-unused-vars */ + player.saveToExport = btoa(unescape(encodeURIComponent(JSON.stringify(playerData)))); + + localStorage.setItem(player.id, player.saveToExport); +} + +export async function load(): Promise { + try { + let modData: string | ModSaveData | null = localStorage.getItem(modInfo.id); + if (modData == null) { + await loadSave(newSave()); + return; + } + modData = JSON.parse(decodeURIComponent(escape(atob(modData)))) as ModSaveData; + if (modData?.active == null) { + await loadSave(newSave()); + return; + } + const save = localStorage.getItem(modData.active); + if (save == null) { + await loadSave(newSave()); + return; + } + const playerData = JSON.parse(decodeURIComponent(escape(atob(save)))); + if (playerData.modID !== modInfo.id) { + await loadSave(newSave()); + return; + } + playerData.id = modData.active; + await loadSave(playerData); + } catch (e) { + await loadSave(newSave()); + } +} + +export function newSave(): PlayerData { + const id = getUniqueID(); + const playerData = getInitialStore({ id }); + localStorage.setItem(id, btoa(unescape(encodeURIComponent(JSON.stringify(playerData))))); + + const rawModData = localStorage.getItem(modInfo.id); + if (rawModData == null) { + const modData = { active: id, saves: [id] }; + localStorage.setItem( + modInfo.id, + btoa(unescape(encodeURIComponent(JSON.stringify(modData)))) + ); + } else { + const modData = JSON.parse(decodeURIComponent(escape(atob(rawModData)))); + modData.saves.push(id); + localStorage.setItem( + modInfo.id, + btoa(unescape(encodeURIComponent(JSON.stringify(modData)))) + ); + } + + return playerData; +} + +export function getUniqueID(): string { + let id, + i = 0; + do { + id = `${modInfo.id}-${i++}`; + } while (localStorage.getItem(id)); + return id; +} + +export async function loadSave(playerData: Partial): Promise { + const { layers, removeLayer, addLayer } = await import("../game/layers"); + + for (const layer in layers) { + removeLayer(layer); + } + getInitialLayers(playerData).forEach(layer => addLayer(layer, playerData)); + + playerData = getInitialStore(playerData); + if (playerData.offlineProd && playerData.time) { + if (playerData.offlineTime == undefined) playerData.offlineTime = new Decimal(0); + playerData.offlineTime = playerData.offlineTime.add((Date.now() - playerData.time) / 1000); + } + playerData.time = Date.now(); + if (playerData.modVersion !== modInfo.versionNumber) { + fixOldSave(playerData.modVersion, playerData); + } + + Object.assign(player, playerData); + for (const prop in player) { + if (!(prop in playerData) && !(prop in layers) && prop !== "__state" && prop !== "__path") { + delete player.layers[prop]; + } + } +} + +export function applyPlayerData>( + target: T, + source: T, + destructive = false +): T { + for (const prop in source) { + if (target[prop] == null) { + target[prop] = source[prop]; + } else if (target[prop as string] instanceof Decimal) { + target[prop as keyof T] = new Decimal(source[prop]) as any; + } else if (Array.isArray(target[prop]) || typeof target[prop] === "object") { + target[prop] = applyPlayerData(target[prop], source[prop], destructive); + } else { + target[prop] = source[prop]; + } + } + if (destructive) { + for (const prop in target) { + if (!(prop in source)) { + delete target[prop]; + } + } + } + return target; +} + +setInterval(() => { + if (player.autosave) { + save(); + } +}, 1000); +window.onbeforeunload = () => { + if (player.autosave) { + save(); + } +}; +window.save = save; +window.hardReset = () => { + loadSave(newSave()); +}; diff --git a/src/util/vue.js b/src/util/vue.js deleted file mode 100644 index 4b0dbb4..0000000 --- a/src/util/vue.js +++ /dev/null @@ -1,57 +0,0 @@ -import player from '../game/player'; -import { layers } from '../game/layers'; -import { hasWon, pointGain } from '../data/mod'; -import { hasUpgrade, hasMilestone, hasAchievement, hasChallenge, maxedChallenge, challengeCompletions, inChallenge, getBuyableAmount, setBuyableAmount, getClickableState, setClickableState, getGridData, setGridData, upgradeEffect, challengeEffect, buyableEffect, clickableEffect, achievementEffect, gridEffect } from './features'; -import Decimal, * as numberUtils from './bignum'; - -let vue; -export function setVue(vm) { - vue = vm; -} - -// Pass in various data that the template could potentially use -const data = function() { - return { Decimal, player, layers, hasWon, pointGain, ...numberUtils }; -} -export function coerceComponent(component, defaultWrapper = 'span') { - if (typeof component === 'number') { - component = "" + component; - } - if (typeof component === 'string') { - component = component.trim(); - if (!(component in vue._context.components)) { - if (component.charAt(0) !== '<') { - component = `<${defaultWrapper}>${component}`; - } - - return { template: component, data, inject: [ 'tab' ], methods: { hasUpgrade, hasMilestone, hasAchievement, hasChallenge, maxedChallenge, challengeCompletions, inChallenge, getBuyableAmount, setBuyableAmount, getClickableState, setClickableState, getGridData, setGridData, upgradeEffect, challengeEffect, buyableEffect, clickableEffect, achievementEffect, gridEffect } }; - } - } - return component; -} - -export function getFiltered(objects, filter = null) { - if (filter) { - filter = filter.map(v => v.toString()); - return Object.keys(objects) - .filter(key => filter.includes(key)) - .reduce((acc, curr) => { - acc[curr] = objects[curr]; - return acc; - }, {}); - } - return objects; -} - -export function mapState(properties = []) { - return properties.reduce((acc, curr) => { - acc[curr] = () => player[curr]; - return acc; - }, {}); -} - -export const UP = 'UP'; -export const DOWN = 'DOWN'; -export const LEFT = 'LEFT'; -export const RIGHT = 'RIGHT'; -export const DEFAULT = 'DEFAULT'; diff --git a/src/util/vue.ts b/src/util/vue.ts new file mode 100644 index 0000000..28f12ad --- /dev/null +++ b/src/util/vue.ts @@ -0,0 +1,114 @@ +import { hasWon, pointGain } from "@/data/mod"; +import { layers } from "@/game/layers"; +import player from "@/game/player"; +import { App, Component, ComponentOptions, defineComponent, inject } from "vue"; +import Decimal, * as numberUtils from "./bignum"; +import { + achievementEffect, + buyableEffect, + challengeCompletions, + challengeEffect, + clickableEffect, + getBuyableAmount, + getClickableState, + getGridData, + gridEffect, + hasAchievement, + hasChallenge, + hasMilestone, + hasUpgrade, + inChallenge, + maxedChallenge, + setBuyableAmount, + setClickableState, + setGridData, + upgradeEffect +} from "./features"; + +let vue: App; +export function setVue(vm: App): void { + vue = vm; +} + +// Pass in various data that the template could potentially use +const data = function(): Record { + return { Decimal, player, layers, hasWon, pointGain, ...numberUtils }; +}; +export function coerceComponent( + component: string | ComponentOptions, + defaultWrapper = "span" +): Component | string { + if (typeof component === "string") { + component = component.trim(); + if (!(component in vue._context.components)) { + if (component.charAt(0) !== "<") { + component = `<${defaultWrapper}>${component}`; + } + + return defineComponent({ + template: component, + data, + inject: ["tab"], + methods: { + hasUpgrade, + hasMilestone, + hasAchievement, + hasChallenge, + maxedChallenge, + challengeCompletions, + inChallenge, + getBuyableAmount, + setBuyableAmount, + getClickableState, + setClickableState, + getGridData, + setGridData, + upgradeEffect, + challengeEffect, + buyableEffect, + clickableEffect, + achievementEffect, + gridEffect + } + }); + } + } + return component; +} + +export function getFiltered( + objects: Record, + filter?: Array +): Record { + if (filter != null) { + filter = filter.map(v => v.toString()); + return Object.keys(objects) + .filter(key => filter!.includes(key)) + .reduce((acc: Record, curr: string) => { + acc[curr] = objects[curr]; + return acc; + }, {}); + } + return objects; +} + +export function mapState(properties: Array = []): Record { + return properties.reduce((acc: Record, curr: string): Record< + string, + unknown + > => { + acc[curr] = () => player[curr]; + return acc; + }, {}); +} + +export const InjectLayerMixin = { + props: { + layer: { + type: String, + default(): string { + return (inject("tab") as { layer: string }).layer; + } + } + } +}; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..3c80063 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,43 @@ +{ + "compilerOptions": { + "target": "esnext", + "module": "esnext", + "strict": true, + "checkJs": false, + "jsx": "preserve", + "importHelpers": true, + "moduleResolution": "node", + "resolveJsonModule": true, + "experimentalDecorators": true, + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "sourceMap": true, + "baseUrl": ".", + "types": [ + "webpack-env" + ], + "paths": { + "@/*": [ + "src/*" + ] + }, + "lib": [ + "esnext", + "dom", + "dom.iterable", + "scripthost" + ] + }, + "include": [ + "src/**/*.ts", + "src/**/*.tsx", + "src/**/*.vue", + "tests/**/*.ts", + "tests/**/*.tsx" + ], + "exclude": [ + "node_modules" + ] +} diff --git a/vue.config.js b/vue.config.js index 7d30f61..b707485 100644 --- a/vue.config.js +++ b/vue.config.js @@ -1,4 +1,11 @@ module.exports = { - publicPath: process.env.NODE_ENV === 'production' ? '/The-Modding-Tree-X' : '/', - runtimeCompiler: true + publicPath: process.env.NODE_ENV === "production" ? "/The-Modding-Tree-X" : "/", + runtimeCompiler: true, + chainWebpack(config) { + config.resolve.alias.delete("@"); + config.resolve + .plugin("tsconfig-paths") + // eslint-disable-next-line @typescript-eslint/no-var-requires + .use(require("tsconfig-paths-webpack-plugin")); + } };