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 @@
-
-
-
- {{ buttonText }}
-
-
-
-
-
-
+
+
+
+ {{ buttonText }}
+
+
+
+
+
+
-
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 @@
-
- Goal:
- Reward:
-
+
+ Goal:
+ Reward:
+
-
-
+
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 @@
-
- {{ resetDescription }}{{ resetGain }}
- {{ resource }}
-
- {{ nextAt }}
-
+
+ {{ resetDescription }}{{ resetGain }}
+ {{ resource }}
+
+ {{ nextAt }}
+
-
-
+
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 @@
-
-
-
- Currently:
-
- Cost: {{ cost }} {{ costResource }}
-
+
+
+
+ Currently:
+
+ Cost: {{ cost }} {{ costResource }}
+
-
-
+
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 @@
-
- You have
-
- {{ resource }}
- ,
-
-
+
+ You have
+
+ {{ resource
+ }}
+ ,
+
+
-
-
+
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 @@
-
-
-
-
-
-
-
-
-
- Confirm Respec
-
-
-
- Are you sure you want to respec? This will force you to do a {{ name }} respec as well!
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+ Confirm Respec
+
+
+
+
+
+
+
+
+
+
+
-
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 @@
-
- Are you sure?
-
- Yes
-
-
- No
-
+
+ Are you sure?
+
+ Yes
+
+
+ No
+
-
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 @@
-
- {{ title }}
-
-
+
+ {{ title }}
+
+
-
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 @@
-
- {{ title }}
-
- $emit('change', parseInt(e.target.value))" :min="min" :max="max" />
-
-
+
+ {{ title }}
+
+ $emit('change', parseInt(e.target.value))"
+ :min="min"
+ :max="max"
+ />
+
+
-
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 @@
-
-
- {{ title }}
-
+
+
+ {{ title }}
+
-
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 @@
-
-
-
-
-
-
-
It took you {{ timePlayed }} to beat the game.
-
-
Please check the Discord to discuss the game or to check for new content updates!
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
It took you {{ timePlayed }} to beat the game.
+
+
+ Please check the Discord to discuss the game or to check for new content
+ updates!
+
+
+
+
+
+
+
+
+
-
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 @@
-
-
-
-
-
-
-
- By {{ author }}
-
-
- Made in TMT-X, by thepaperpilot with inspiration from Acameada, Jacorb, and Aarex
-
-
-
Changelog
-
-
-
-
-
-
-
Time Played: {{ timePlayed }}
-
-
-
Hotkeys
-
- {{ key.key }}: {{ key.description }}
-
-
-
-
-
+
+
+
+
+
+
+
By {{ author }}
+
+ Made in TMT-X, by thepaperpilot with inspiration from Acameada, Jacorb, and
+ Aarex
+
+
+
+ Changelog
+
+
+
+
+
+
+
+
Time Played: {{ timePlayed }}
+
+
+
Hotkeys
+
+ {{ key.key }}: {{ key.description }}
+
+
+
+
+
-
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 @@
-
-
-
+
+
+
+ ←
+
+
+ {{ name }}
+
+
+
+ ▼
+
+
+
-
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 @@
-
-
-
-
-
-
-
-
-
- default body
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+ default body
+
+
+
+
+
+
+
+
+
-
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 @@
-
-
-
-
-
- Attempted to assign "{{ path }}" to NaN (previously {{ format(previous) }}). Auto-saving has been {{ autosave ? 'enabled' : 'disabled' }}. Check the console for more details, and consider sharing it with the developers on discord.
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+ Attempted to assign "{{ path }}" to NaN (previously {{ format(previous) }}).
+ Auto-saving has been {{ autosave ? "enabled" : "disabled" }}. Check the console for
+ more details, and consider sharing it with the developers on discord.
+
+
+
+
+
+
+
+
+
+
+
+
-
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 @@
-
-
-
{{ title }}
-
- v{{ version }}
-
-
-
-
-
-
-
- i
-
-
-
- library_books
-
-
-
-
-
-
-
-
-
-
- v{{ version }}
-
-
- library_books
-
-
-
-
-
- i
-
-
-
-
-
-
-
-
-
+
+
+
{{ title }}
+
+ v{{ version }}
+
+
+
+
+
+
+
+ i
+
+
+
+ library_books
+
+
+
+
+
+
+
+
+
+
+ v{{ version }}
+
+
+ library_books
+
+
+
+
+
+ i
+
+
+
+
+
+
+
+
+
-
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 @@
-
- {{ amount }}
-
+
+ {{ amount }}
+
-
-
+
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 @@
-
-
drag_handle
-
-
- content_paste
-
-
- content_copy
-
-
- edit
-
-
- delete
-
-
-
-
- check
-
-
- close
-
-
-
-
- {{ save.name }}
-
-
v{{ save.modVersion }}
-
Last played {{ dateFormat.format(time) }}
-
-
-
-
-
- Error: Failed to load save with id {{ save.id }}
-
-
+
+
drag_handle
+
+
+ content_paste
+
+
+ content_copy
+
+
+ edit
+
+
+ delete
+
+
+
+
+ check
+
+
+ close
+
+
+
+
+ {{ save.name }}
+
+
v{{ save.modVersion }}
+
Last played {{ dateFormat.format(time) }}
+
+
+
+
+
Error: Failed to load save with id {{ save.id }}
+
-
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 @@
-
-
- Saves Manager
-
-
- editSave(save.id, name)" @duplicate="duplicateSave(save.id)" @delete="deleteSave(save.id)" />
-
-
-
-
-
+
+
+ Saves Manager
+
+
+ editSave(save.id, name)"
+ @duplicate="duplicateSave(save.id)"
+ @delete="deleteSave(save.id)"
+ />
+
+
+
+
+
-
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 @@
-
- TPS: {{ tps }}
-
+ TPS: {{ tps }}
-
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 @@
-
- {{ text }}
-
+
+ {{ text }}
+
-
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 @@
-
-
-
-
-
-
-
- {{ modalHeader }}
-
-
+
+
+
+
+
+
+
+ {{ modalHeader }}
+
+
-
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: `
-
- player.c.beep = value" />
- player.f.boop = value" />
-
- `,
- 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: `
-
-
-
-
- 'HI'
- Name your points!
- player.c.thingy = value" :field="false" />
- 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: `
-
-
-
- player.c.beep = value" />
-
- 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!
- player.c.otherThingy = value" :min="1" :max="30" />`
- }
-
- },
- 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: `
+
+ player.layers.c.beep = value" />
+ player.layers.f.boop = value" />
+
+ `,
+ 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: `
+
+
+
+
+ 'HI'
+ Name your points!
+ player.layers.c.thingy = value" :field="false" />
+ 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: `
+
+
+
+ player.layers.c.beep = value" />
+
+ 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!
+ player.c.otherThingy = value" :min="1" :max="30" />`
+ }
+ },
+ 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}${defaultWrapper}>`;
- }
-
- 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}${defaultWrapper}>`;
+ }
+
+ 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"));
+ }
};