diff --git a/package-lock.json b/package-lock.json index 0834b90..3ce031a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -59,7 +59,7 @@ "jsdom": "^20.0.0", "prettier": "^2.5.1", "typescript": "4.8.4", - "vitest": "^0.17.1", + "vitest": "^0.26.3", "vue-tsc": "^0.38.1" }, "engines": { @@ -1619,6 +1619,166 @@ "resolved": "https://registry.npmjs.org/@cush/relative/-/relative-1.0.0.tgz", "integrity": "sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA==" }, + "node_modules/@esbuild/android-arm": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.16.14.tgz", + "integrity": "sha512-u0rITLxFIeYAvtJXBQNhNuV4YZe+MD1YvIWT7Nicj8hZAtRVZk2PgNH6KclcKDVHz1ChLKXRfX7d7tkbQBUfrg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.16.14.tgz", + "integrity": "sha512-hTqB6Iq13pW4xaydeqQrs8vPntUnMjbkq+PgGiBMi69eYk74naG2ftHWqKnxn874kNrt5Or3rQ0PJutx2doJuQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.16.14.tgz", + "integrity": "sha512-jir51K4J0K5Rt0KOcippjSNdOl7akKDVz5I6yrqdk4/m9y+rldGptQUF7qU4YpX8U61LtR+w2Tu2Ph+K/UaJOw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.16.14.tgz", + "integrity": "sha512-vrlaP81IuwPaw1fyX8fHCmivP3Gr73ojVEZy+oWJLAiZVcG8o8Phwun/XDnYIFUHxIoUnMFEpg9o38MIvlw8zw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.16.14.tgz", + "integrity": "sha512-KV1E01eC2hGYA2qzFDRCK4wdZCRUvMwCNcobgpiiOzp5QXpJBqFPdxI69j8vvzuU7oxFXDgANwEkXvpeQqyOyg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.14.tgz", + "integrity": "sha512-xRM1RQsazSvL42BNa5XC7ytD4ZDp0ZyJcH7aB0SlYUcHexJUKiDNKR7dlRVlpt6W0DvoRPU2nWK/9/QWS4u2fw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.16.14.tgz", + "integrity": "sha512-7ALTAn6YRRf1O6fw9jmn0rWmOx3XfwDo7njGtjy1LXhDGUjTY/vohEPM3ii5MQ411vJv1r498EEx2aBQTJcrEw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.16.14.tgz", + "integrity": "sha512-X6xULug66ulrr4IzrW7qq+eq9n4MtEyagdWvj4o4cmWr+JXOT47atjpDF9j5M2zHY0UQBmqnHhwl+tXpkpIb2w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.16.14.tgz", + "integrity": "sha512-TLh2OcbBUQcMYRH4GbiDkDZfZ4t1A3GgmeXY27dHSI6xrU7IkO00MGBiJySmEV6sH3Wa6pAN6UtaVL0DwkGW4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.16.14.tgz", + "integrity": "sha512-oBZkcZ56UZDFCAfE3Fd/Jgy10EoS7Td77NzNGenM+HSY8BkdQAcI9VF9qgwdOLZ+tuftWD7UqZ26SAhtvA3XhA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@esbuild/linux-loong64": { "version": "0.14.54", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz", @@ -1634,6 +1794,182 @@ "node": ">=12" } }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.16.14.tgz", + "integrity": "sha512-kJ2iEnikUOdC1SiTGbH0fJUgpZwa0ITDTvj9EHf9lm3I0hZ4Yugsb3M6XSl696jVxrEocLe519/8CbSpQWFSrg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.16.14.tgz", + "integrity": "sha512-kclKxvZvX5YhykwlJ/K9ljiY4THe5vXubXpWmr7q3Zu3WxKnUe1VOZmhkEZlqtnJx31GHPEV4SIG95IqTdfgfg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.16.14.tgz", + "integrity": "sha512-fdwP9Dc+Kx/cZwp9T9kNqjAE/PQjfrxbio4rZ3XnC3cVvZBjuxpkiyu/tuCwt6SbAK5th6AYNjFdEV9kGC020A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.16.14.tgz", + "integrity": "sha512-++fw3P4fQk9nqvdzbANRqimKspL8pDCnSpXomyhV7V/ISha/BZIYvZwLBWVKp9CVWKwWPJ4ktsezuLIvlJRHqA==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.16.14.tgz", + "integrity": "sha512-TomtswAuzBf2NnddlrS4W01Tv85RM9YtATB3OugY6On0PLM4Ksz5qvQKVAjtzPKoLgL1FiZtfc8mkZc4IgoMEA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.16.14.tgz", + "integrity": "sha512-U06pfx8P5CqyoPNfqIJmnf+5/r4mJ1S62G4zE6eOjS59naQcxi6GnscUCPH3b+hRG0qdKoGX49RAyiqW+M9aSw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.16.14.tgz", + "integrity": "sha512-/Jl8XVaWEZNu9rZw+n792GIBupQwHo6GDoapHSb/2xp/Ku28eK6QpR2O9cPBkzHH4OOoMH0LB6zg/qczJ5TTGg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.16.14.tgz", + "integrity": "sha512-2iI7D34uTbDn/TaSiUbEHz+fUa8KbN90vX5yYqo12QGpu6T8Jl+kxODsWuMCwoTVlqUpwfPV22nBbFPME9OPtw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.16.14.tgz", + "integrity": "sha512-SjlM7AHmQVTiGBJE/nqauY1aDh80UBsXZ94g4g60CDkrDMseatiqALVcIuElg4ZSYzJs8hsg5W6zS2zLpZTVgg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.16.14.tgz", + "integrity": "sha512-z06t5zqk8ak0Xom5HG81z2iOQ1hNWYsFQp3sczVLVx+dctWdgl80tNRyTbwjaFfui2vFO12dfE3trCTvA+HO4g==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.16.14.tgz", + "integrity": "sha512-ED1UpWcM6lAbalbbQ9TrGqJh4Y9TaASUvu8bI/0mgJcxhSByJ6rbpgqRhxYMaQ682WfA71nxUreaTO7L275zrw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint/eslintrc": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.0.tgz", @@ -5240,6 +5576,12 @@ "node": ">=6" } }, + "node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -5439,6 +5781,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/mlly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.0.0.tgz", + "integrity": "sha512-QL108Hwt+u9bXdWgOI0dhzZfACovn5Aen4Xvc8Jasd9ouRH4NjnrXEiyP3nVvJo91zPlYjVRckta0Nt2zfoR6g==", + "dev": true, + "dependencies": { + "acorn": "^8.8.1", + "pathe": "^1.0.0", + "pkg-types": "^1.0.0", + "ufo": "^1.0.0" + } + }, + "node_modules/mlly/node_modules/pathe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.0.0.tgz", + "integrity": "sha512-nPdMG0Pd09HuSsr7QOKUXO2Jr9eqaDiZvDwdyIhNG5SHYujkQHYKDfGQkulBxvbDHz8oHLsTgKN86LSwYzSHAg==", + "dev": true + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -5664,6 +6024,12 @@ "node": ">=8" } }, + "node_modules/pathe": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-0.2.0.tgz", + "integrity": "sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw==", + "dev": true + }, "node_modules/pathval": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", @@ -5697,6 +6063,23 @@ "node": ">= 6" } }, + "node_modules/pkg-types": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.1.tgz", + "integrity": "sha512-jHv9HB+Ho7dj6ItwppRDDl0iZRYBD0jsakHXtFgoLr+cHSF6xC+QL54sJmWxyGxOLYSHm0afhXhXcQDQqH9z8g==", + "dev": true, + "dependencies": { + "jsonc-parser": "^3.2.0", + "mlly": "^1.0.0", + "pathe": "^1.0.0" + } + }, + "node_modules/pkg-types/node_modules/pathe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.0.0.tgz", + "integrity": "sha512-nPdMG0Pd09HuSsr7QOKUXO2Jr9eqaDiZvDwdyIhNG5SHYujkQHYKDfGQkulBxvbDHz8oHLsTgKN86LSwYzSHAg==", + "dev": true + }, "node_modules/postcss": { "version": "8.4.20", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.20.tgz", @@ -6279,6 +6662,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strip-literal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.0.0.tgz", + "integrity": "sha512-5o4LsH1lzBzO9UFH63AJ2ad2/S2AVx6NtjOcaz+VTT2h1RiRvbipW72z8M/lxEhcPHDBQwpDrnTF7sXy/7OwCQ==", + "dev": true, + "dependencies": { + "acorn": "^8.8.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/sucrase": { "version": "3.29.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.29.0.tgz", @@ -6422,19 +6817,25 @@ "node": ">=0.8" } }, + "node_modules/tinybench": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.3.1.tgz", + "integrity": "sha512-hGYWYBMPr7p4g5IarQE7XhlyWveh1EKhy4wUBS1LrHXCKYgvz+4/jCqgmJqZxxldesn05vccrtME2RLLZNW7iA==", + "dev": true + }, "node_modules/tinypool": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.2.4.tgz", - "integrity": "sha512-Vs3rhkUH6Qq1t5bqtb816oT+HeJTXfwt2cbPH17sWHIYKTotQIFPk3tf2fgqRrVyMDVOc1EnPgzIxfIulXVzwQ==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.3.0.tgz", + "integrity": "sha512-NX5KeqHOBZU6Bc0xj9Vr5Szbb1j8tUHIeD18s41aDJaPeC5QTdEhK0SpdpUrZlj2nv5cctNcSjaKNanXlfcVEQ==", "dev": true, "engines": { "node": ">=14.0.0" } }, "node_modules/tinyspy": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-0.3.3.tgz", - "integrity": "sha512-gRiUR8fuhUf0W9lzojPf1N1euJYA30ISebSfgca8z76FOvXtVXqd5ojEIaKLWbDQhAaC3ibxZIjqbyi4ybjcTw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-1.0.2.tgz", + "integrity": "sha512-bSGlgwLBYf7PnUsQ6WOc6SJ3pGOcd+d8AA6EUnLDDM0kWEstC1JIlSZA3UNliDXhd9ABoS7hiRBDCu+XP/sf1Q==", "dev": true, "engines": { "node": ">=14.0.0" @@ -6568,6 +6969,12 @@ "node": ">=4.2.0" } }, + "node_modules/ufo": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.0.1.tgz", + "integrity": "sha512-boAm74ubXHY7KJQZLlXrtMz52qFvpsbOxDcZOnw/Wf+LS4Mmyu7JxmzD4tDLtUQtmZECypJ0FrCz4QIe6dvKRA==", + "dev": true + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -6740,6 +7147,147 @@ } } }, + "node_modules/vite-node": { + "version": "0.26.3", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.26.3.tgz", + "integrity": "sha512-Te2bq0Bfvq6XiO718I+1EinMjpNYKws6SNHKOmVbILAQimKoZKDd+IZLlkaYcBXPpK3HFe2U80k8Zw+m3w/a2w==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "mlly": "^1.0.0", + "pathe": "^0.2.0", + "source-map": "^0.6.1", + "source-map-support": "^0.5.21", + "vite": "^3.0.0 || ^4.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": ">=v14.16.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-loong64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.16.14.tgz", + "integrity": "sha512-udz/aEHTcuHP+xdWOJmZ5C9RQXHfZd/EhCnTi1Hfay37zH3lBxn/fNs85LA9HlsniFw2zccgcbrrTMKk7Cn1Qg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/esbuild": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.16.14.tgz", + "integrity": "sha512-6xAn3O6ZZyoxZAEkwfI9hw4cEqSr/o1ViJtnkvImVkblmUN65Md04o0S/7H1WNu1XGf1Cjij/on7VO4psIYjkw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.16.14", + "@esbuild/android-arm64": "0.16.14", + "@esbuild/android-x64": "0.16.14", + "@esbuild/darwin-arm64": "0.16.14", + "@esbuild/darwin-x64": "0.16.14", + "@esbuild/freebsd-arm64": "0.16.14", + "@esbuild/freebsd-x64": "0.16.14", + "@esbuild/linux-arm": "0.16.14", + "@esbuild/linux-arm64": "0.16.14", + "@esbuild/linux-ia32": "0.16.14", + "@esbuild/linux-loong64": "0.16.14", + "@esbuild/linux-mips64el": "0.16.14", + "@esbuild/linux-ppc64": "0.16.14", + "@esbuild/linux-riscv64": "0.16.14", + "@esbuild/linux-s390x": "0.16.14", + "@esbuild/linux-x64": "0.16.14", + "@esbuild/netbsd-x64": "0.16.14", + "@esbuild/openbsd-x64": "0.16.14", + "@esbuild/sunos-x64": "0.16.14", + "@esbuild/win32-arm64": "0.16.14", + "@esbuild/win32-ia32": "0.16.14", + "@esbuild/win32-x64": "0.16.14" + } + }, + "node_modules/vite-node/node_modules/rollup": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.9.1.tgz", + "integrity": "sha512-GswCYHXftN8ZKGVgQhTFUJB/NBXxrRGgO2NCy6E8s1rwEJ4Q9/VttNqcYfEvx4dTo4j58YqdC3OVztPzlKSX8w==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/vite-node/node_modules/vite": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.0.4.tgz", + "integrity": "sha512-xevPU7M8FU0i/80DMR+YhgrzR5KS2ORy1B4xcX/cXLsvnUWvfHuqMmVU6N0YiJ4JWGRJJsLCgjEzKjG9/GKoSw==", + "dev": true, + "dependencies": { + "esbuild": "^0.16.3", + "postcss": "^8.4.20", + "resolve": "^1.22.1", + "rollup": "^3.7.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, "node_modules/vite-plugin-pwa": { "version": "0.12.8", "resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-0.12.8.tgz", @@ -6776,20 +7324,26 @@ } }, "node_modules/vitest": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.17.1.tgz", - "integrity": "sha512-d6NsFC6FPmZ5XdiSYfW5rwJ/b8060wqe2steNNlVbhO69HWma6CucIm5g7PXlCSkmKvrdEbUsZHPAarlH83VGw==", + "version": "0.26.3", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.26.3.tgz", + "integrity": "sha512-FmHxU9aUCxTi23keF3vxb/Qp0lYXaaJ+jRLGOUmMS3qVTOJvgGE+f1VArupA6pEhaG2Ans4X+zV9dqM5WISMbg==", "dev": true, "dependencies": { - "@types/chai": "^4.3.1", + "@types/chai": "^4.3.4", "@types/chai-subset": "^1.3.3", "@types/node": "*", - "chai": "^4.3.6", + "acorn": "^8.8.1", + "acorn-walk": "^8.2.0", + "chai": "^4.3.7", "debug": "^4.3.4", - "local-pkg": "^0.4.1", - "tinypool": "^0.2.1", - "tinyspy": "^0.3.3", - "vite": "^2.9.12 || ^3.0.0-0" + "local-pkg": "^0.4.2", + "source-map": "^0.6.1", + "strip-literal": "^1.0.0", + "tinybench": "^2.3.1", + "tinypool": "^0.3.0", + "tinyspy": "^1.0.2", + "vite": "^3.0.0 || ^4.0.0", + "vite-node": "0.26.3" }, "bin": { "vitest": "vitest.mjs" @@ -6802,8 +7356,8 @@ }, "peerDependencies": { "@edge-runtime/vm": "*", + "@vitest/browser": "*", "@vitest/ui": "*", - "c8": "*", "happy-dom": "*", "jsdom": "*" }, @@ -6811,10 +7365,10 @@ "@edge-runtime/vm": { "optional": true }, - "@vitest/ui": { + "@vitest/browser": { "optional": true }, - "c8": { + "@vitest/ui": { "optional": true }, "happy-dom": { @@ -6825,6 +7379,124 @@ } } }, + "node_modules/vitest/node_modules/@esbuild/linux-loong64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.16.14.tgz", + "integrity": "sha512-udz/aEHTcuHP+xdWOJmZ5C9RQXHfZd/EhCnTi1Hfay37zH3lBxn/fNs85LA9HlsniFw2zccgcbrrTMKk7Cn1Qg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/esbuild": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.16.14.tgz", + "integrity": "sha512-6xAn3O6ZZyoxZAEkwfI9hw4cEqSr/o1ViJtnkvImVkblmUN65Md04o0S/7H1WNu1XGf1Cjij/on7VO4psIYjkw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.16.14", + "@esbuild/android-arm64": "0.16.14", + "@esbuild/android-x64": "0.16.14", + "@esbuild/darwin-arm64": "0.16.14", + "@esbuild/darwin-x64": "0.16.14", + "@esbuild/freebsd-arm64": "0.16.14", + "@esbuild/freebsd-x64": "0.16.14", + "@esbuild/linux-arm": "0.16.14", + "@esbuild/linux-arm64": "0.16.14", + "@esbuild/linux-ia32": "0.16.14", + "@esbuild/linux-loong64": "0.16.14", + "@esbuild/linux-mips64el": "0.16.14", + "@esbuild/linux-ppc64": "0.16.14", + "@esbuild/linux-riscv64": "0.16.14", + "@esbuild/linux-s390x": "0.16.14", + "@esbuild/linux-x64": "0.16.14", + "@esbuild/netbsd-x64": "0.16.14", + "@esbuild/openbsd-x64": "0.16.14", + "@esbuild/sunos-x64": "0.16.14", + "@esbuild/win32-arm64": "0.16.14", + "@esbuild/win32-ia32": "0.16.14", + "@esbuild/win32-x64": "0.16.14" + } + }, + "node_modules/vitest/node_modules/rollup": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.9.1.tgz", + "integrity": "sha512-GswCYHXftN8ZKGVgQhTFUJB/NBXxrRGgO2NCy6E8s1rwEJ4Q9/VttNqcYfEvx4dTo4j58YqdC3OVztPzlKSX8w==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/vitest/node_modules/vite": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.0.4.tgz", + "integrity": "sha512-xevPU7M8FU0i/80DMR+YhgrzR5KS2ORy1B4xcX/cXLsvnUWvfHuqMmVU6N0YiJ4JWGRJJsLCgjEzKjG9/GKoSw==", + "dev": true, + "dependencies": { + "esbuild": "^0.16.3", + "postcss": "^8.4.20", + "resolve": "^1.22.1", + "rollup": "^3.7.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, "node_modules/vue": { "version": "3.2.45", "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.45.tgz", @@ -8444,12 +9116,159 @@ "resolved": "https://registry.npmjs.org/@cush/relative/-/relative-1.0.0.tgz", "integrity": "sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA==" }, + "@esbuild/android-arm": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.16.14.tgz", + "integrity": "sha512-u0rITLxFIeYAvtJXBQNhNuV4YZe+MD1YvIWT7Nicj8hZAtRVZk2PgNH6KclcKDVHz1ChLKXRfX7d7tkbQBUfrg==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.16.14.tgz", + "integrity": "sha512-hTqB6Iq13pW4xaydeqQrs8vPntUnMjbkq+PgGiBMi69eYk74naG2ftHWqKnxn874kNrt5Or3rQ0PJutx2doJuQ==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.16.14.tgz", + "integrity": "sha512-jir51K4J0K5Rt0KOcippjSNdOl7akKDVz5I6yrqdk4/m9y+rldGptQUF7qU4YpX8U61LtR+w2Tu2Ph+K/UaJOw==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.16.14.tgz", + "integrity": "sha512-vrlaP81IuwPaw1fyX8fHCmivP3Gr73ojVEZy+oWJLAiZVcG8o8Phwun/XDnYIFUHxIoUnMFEpg9o38MIvlw8zw==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.16.14.tgz", + "integrity": "sha512-KV1E01eC2hGYA2qzFDRCK4wdZCRUvMwCNcobgpiiOzp5QXpJBqFPdxI69j8vvzuU7oxFXDgANwEkXvpeQqyOyg==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.14.tgz", + "integrity": "sha512-xRM1RQsazSvL42BNa5XC7ytD4ZDp0ZyJcH7aB0SlYUcHexJUKiDNKR7dlRVlpt6W0DvoRPU2nWK/9/QWS4u2fw==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.16.14.tgz", + "integrity": "sha512-7ALTAn6YRRf1O6fw9jmn0rWmOx3XfwDo7njGtjy1LXhDGUjTY/vohEPM3ii5MQ411vJv1r498EEx2aBQTJcrEw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.16.14.tgz", + "integrity": "sha512-X6xULug66ulrr4IzrW7qq+eq9n4MtEyagdWvj4o4cmWr+JXOT47atjpDF9j5M2zHY0UQBmqnHhwl+tXpkpIb2w==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.16.14.tgz", + "integrity": "sha512-TLh2OcbBUQcMYRH4GbiDkDZfZ4t1A3GgmeXY27dHSI6xrU7IkO00MGBiJySmEV6sH3Wa6pAN6UtaVL0DwkGW4Q==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.16.14.tgz", + "integrity": "sha512-oBZkcZ56UZDFCAfE3Fd/Jgy10EoS7Td77NzNGenM+HSY8BkdQAcI9VF9qgwdOLZ+tuftWD7UqZ26SAhtvA3XhA==", + "dev": true, + "optional": true + }, "@esbuild/linux-loong64": { "version": "0.14.54", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz", "integrity": "sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==", "optional": true }, + "@esbuild/linux-mips64el": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.16.14.tgz", + "integrity": "sha512-kJ2iEnikUOdC1SiTGbH0fJUgpZwa0ITDTvj9EHf9lm3I0hZ4Yugsb3M6XSl696jVxrEocLe519/8CbSpQWFSrg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.16.14.tgz", + "integrity": "sha512-kclKxvZvX5YhykwlJ/K9ljiY4THe5vXubXpWmr7q3Zu3WxKnUe1VOZmhkEZlqtnJx31GHPEV4SIG95IqTdfgfg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.16.14.tgz", + "integrity": "sha512-fdwP9Dc+Kx/cZwp9T9kNqjAE/PQjfrxbio4rZ3XnC3cVvZBjuxpkiyu/tuCwt6SbAK5th6AYNjFdEV9kGC020A==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.16.14.tgz", + "integrity": "sha512-++fw3P4fQk9nqvdzbANRqimKspL8pDCnSpXomyhV7V/ISha/BZIYvZwLBWVKp9CVWKwWPJ4ktsezuLIvlJRHqA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.16.14.tgz", + "integrity": "sha512-TomtswAuzBf2NnddlrS4W01Tv85RM9YtATB3OugY6On0PLM4Ksz5qvQKVAjtzPKoLgL1FiZtfc8mkZc4IgoMEA==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.16.14.tgz", + "integrity": "sha512-U06pfx8P5CqyoPNfqIJmnf+5/r4mJ1S62G4zE6eOjS59naQcxi6GnscUCPH3b+hRG0qdKoGX49RAyiqW+M9aSw==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.16.14.tgz", + "integrity": "sha512-/Jl8XVaWEZNu9rZw+n792GIBupQwHo6GDoapHSb/2xp/Ku28eK6QpR2O9cPBkzHH4OOoMH0LB6zg/qczJ5TTGg==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.16.14.tgz", + "integrity": "sha512-2iI7D34uTbDn/TaSiUbEHz+fUa8KbN90vX5yYqo12QGpu6T8Jl+kxODsWuMCwoTVlqUpwfPV22nBbFPME9OPtw==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.16.14.tgz", + "integrity": "sha512-SjlM7AHmQVTiGBJE/nqauY1aDh80UBsXZ94g4g60CDkrDMseatiqALVcIuElg4ZSYzJs8hsg5W6zS2zLpZTVgg==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.16.14.tgz", + "integrity": "sha512-z06t5zqk8ak0Xom5HG81z2iOQ1hNWYsFQp3sczVLVx+dctWdgl80tNRyTbwjaFfui2vFO12dfE3trCTvA+HO4g==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.16.14.tgz", + "integrity": "sha512-ED1UpWcM6lAbalbbQ9TrGqJh4Y9TaASUvu8bI/0mgJcxhSByJ6rbpgqRhxYMaQ682WfA71nxUreaTO7L275zrw==", + "dev": true, + "optional": true + }, "@eslint/eslintrc": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.0.tgz", @@ -10938,6 +11757,12 @@ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz", "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==" }, + "jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, "jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -11089,6 +11914,26 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==" }, + "mlly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.0.0.tgz", + "integrity": "sha512-QL108Hwt+u9bXdWgOI0dhzZfACovn5Aen4Xvc8Jasd9ouRH4NjnrXEiyP3nVvJo91zPlYjVRckta0Nt2zfoR6g==", + "dev": true, + "requires": { + "acorn": "^8.8.1", + "pathe": "^1.0.0", + "pkg-types": "^1.0.0", + "ufo": "^1.0.0" + }, + "dependencies": { + "pathe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.0.0.tgz", + "integrity": "sha512-nPdMG0Pd09HuSsr7QOKUXO2Jr9eqaDiZvDwdyIhNG5SHYujkQHYKDfGQkulBxvbDHz8oHLsTgKN86LSwYzSHAg==", + "dev": true + } + } + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -11257,6 +12102,12 @@ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true }, + "pathe": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-0.2.0.tgz", + "integrity": "sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw==", + "dev": true + }, "pathval": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", @@ -11278,6 +12129,25 @@ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==" }, + "pkg-types": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.1.tgz", + "integrity": "sha512-jHv9HB+Ho7dj6ItwppRDDl0iZRYBD0jsakHXtFgoLr+cHSF6xC+QL54sJmWxyGxOLYSHm0afhXhXcQDQqH9z8g==", + "dev": true, + "requires": { + "jsonc-parser": "^3.2.0", + "mlly": "^1.0.0", + "pathe": "^1.0.0" + }, + "dependencies": { + "pathe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.0.0.tgz", + "integrity": "sha512-nPdMG0Pd09HuSsr7QOKUXO2Jr9eqaDiZvDwdyIhNG5SHYujkQHYKDfGQkulBxvbDHz8oHLsTgKN86LSwYzSHAg==", + "dev": true + } + } + }, "postcss": { "version": "8.4.20", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.20.tgz", @@ -11668,6 +12538,15 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" }, + "strip-literal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.0.0.tgz", + "integrity": "sha512-5o4LsH1lzBzO9UFH63AJ2ad2/S2AVx6NtjOcaz+VTT2h1RiRvbipW72z8M/lxEhcPHDBQwpDrnTF7sXy/7OwCQ==", + "dev": true, + "requires": { + "acorn": "^8.8.1" + } + }, "sucrase": { "version": "3.29.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.29.0.tgz", @@ -11775,16 +12654,22 @@ "thenify": ">= 3.1.0 < 4" } }, + "tinybench": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.3.1.tgz", + "integrity": "sha512-hGYWYBMPr7p4g5IarQE7XhlyWveh1EKhy4wUBS1LrHXCKYgvz+4/jCqgmJqZxxldesn05vccrtME2RLLZNW7iA==", + "dev": true + }, "tinypool": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.2.4.tgz", - "integrity": "sha512-Vs3rhkUH6Qq1t5bqtb816oT+HeJTXfwt2cbPH17sWHIYKTotQIFPk3tf2fgqRrVyMDVOc1EnPgzIxfIulXVzwQ==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.3.0.tgz", + "integrity": "sha512-NX5KeqHOBZU6Bc0xj9Vr5Szbb1j8tUHIeD18s41aDJaPeC5QTdEhK0SpdpUrZlj2nv5cctNcSjaKNanXlfcVEQ==", "dev": true }, "tinyspy": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-0.3.3.tgz", - "integrity": "sha512-gRiUR8fuhUf0W9lzojPf1N1euJYA30ISebSfgca8z76FOvXtVXqd5ojEIaKLWbDQhAaC3ibxZIjqbyi4ybjcTw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-1.0.2.tgz", + "integrity": "sha512-bSGlgwLBYf7PnUsQ6WOc6SJ3pGOcd+d8AA6EUnLDDM0kWEstC1JIlSZA3UNliDXhd9ABoS7hiRBDCu+XP/sf1Q==", "dev": true }, "to-fast-properties": { @@ -11875,6 +12760,12 @@ "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", "dev": true }, + "ufo": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.0.1.tgz", + "integrity": "sha512-boAm74ubXHY7KJQZLlXrtMz52qFvpsbOxDcZOnw/Wf+LS4Mmyu7JxmzD4tDLtUQtmZECypJ0FrCz4QIe6dvKRA==", + "dev": true + }, "unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -11984,6 +12875,81 @@ "rollup": ">=2.59.0 <2.78.0" } }, + "vite-node": { + "version": "0.26.3", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.26.3.tgz", + "integrity": "sha512-Te2bq0Bfvq6XiO718I+1EinMjpNYKws6SNHKOmVbILAQimKoZKDd+IZLlkaYcBXPpK3HFe2U80k8Zw+m3w/a2w==", + "dev": true, + "requires": { + "debug": "^4.3.4", + "mlly": "^1.0.0", + "pathe": "^0.2.0", + "source-map": "^0.6.1", + "source-map-support": "^0.5.21", + "vite": "^3.0.0 || ^4.0.0" + }, + "dependencies": { + "@esbuild/linux-loong64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.16.14.tgz", + "integrity": "sha512-udz/aEHTcuHP+xdWOJmZ5C9RQXHfZd/EhCnTi1Hfay37zH3lBxn/fNs85LA9HlsniFw2zccgcbrrTMKk7Cn1Qg==", + "dev": true, + "optional": true + }, + "esbuild": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.16.14.tgz", + "integrity": "sha512-6xAn3O6ZZyoxZAEkwfI9hw4cEqSr/o1ViJtnkvImVkblmUN65Md04o0S/7H1WNu1XGf1Cjij/on7VO4psIYjkw==", + "dev": true, + "requires": { + "@esbuild/android-arm": "0.16.14", + "@esbuild/android-arm64": "0.16.14", + "@esbuild/android-x64": "0.16.14", + "@esbuild/darwin-arm64": "0.16.14", + "@esbuild/darwin-x64": "0.16.14", + "@esbuild/freebsd-arm64": "0.16.14", + "@esbuild/freebsd-x64": "0.16.14", + "@esbuild/linux-arm": "0.16.14", + "@esbuild/linux-arm64": "0.16.14", + "@esbuild/linux-ia32": "0.16.14", + "@esbuild/linux-loong64": "0.16.14", + "@esbuild/linux-mips64el": "0.16.14", + "@esbuild/linux-ppc64": "0.16.14", + "@esbuild/linux-riscv64": "0.16.14", + "@esbuild/linux-s390x": "0.16.14", + "@esbuild/linux-x64": "0.16.14", + "@esbuild/netbsd-x64": "0.16.14", + "@esbuild/openbsd-x64": "0.16.14", + "@esbuild/sunos-x64": "0.16.14", + "@esbuild/win32-arm64": "0.16.14", + "@esbuild/win32-ia32": "0.16.14", + "@esbuild/win32-x64": "0.16.14" + } + }, + "rollup": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.9.1.tgz", + "integrity": "sha512-GswCYHXftN8ZKGVgQhTFUJB/NBXxrRGgO2NCy6E8s1rwEJ4Q9/VttNqcYfEvx4dTo4j58YqdC3OVztPzlKSX8w==", + "dev": true, + "requires": { + "fsevents": "~2.3.2" + } + }, + "vite": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.0.4.tgz", + "integrity": "sha512-xevPU7M8FU0i/80DMR+YhgrzR5KS2ORy1B4xcX/cXLsvnUWvfHuqMmVU6N0YiJ4JWGRJJsLCgjEzKjG9/GKoSw==", + "dev": true, + "requires": { + "esbuild": "^0.16.3", + "fsevents": "~2.3.2", + "postcss": "^8.4.20", + "resolve": "^1.22.1", + "rollup": "^3.7.0" + } + } + } + }, "vite-plugin-pwa": { "version": "0.12.8", "resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-0.12.8.tgz", @@ -12009,20 +12975,87 @@ } }, "vitest": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.17.1.tgz", - "integrity": "sha512-d6NsFC6FPmZ5XdiSYfW5rwJ/b8060wqe2steNNlVbhO69HWma6CucIm5g7PXlCSkmKvrdEbUsZHPAarlH83VGw==", + "version": "0.26.3", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.26.3.tgz", + "integrity": "sha512-FmHxU9aUCxTi23keF3vxb/Qp0lYXaaJ+jRLGOUmMS3qVTOJvgGE+f1VArupA6pEhaG2Ans4X+zV9dqM5WISMbg==", "dev": true, "requires": { - "@types/chai": "^4.3.1", + "@types/chai": "^4.3.4", "@types/chai-subset": "^1.3.3", "@types/node": "*", - "chai": "^4.3.6", + "acorn": "^8.8.1", + "acorn-walk": "^8.2.0", + "chai": "^4.3.7", "debug": "^4.3.4", - "local-pkg": "^0.4.1", - "tinypool": "^0.2.1", - "tinyspy": "^0.3.3", - "vite": "^2.9.12 || ^3.0.0-0" + "local-pkg": "^0.4.2", + "source-map": "^0.6.1", + "strip-literal": "^1.0.0", + "tinybench": "^2.3.1", + "tinypool": "^0.3.0", + "tinyspy": "^1.0.2", + "vite": "^3.0.0 || ^4.0.0", + "vite-node": "0.26.3" + }, + "dependencies": { + "@esbuild/linux-loong64": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.16.14.tgz", + "integrity": "sha512-udz/aEHTcuHP+xdWOJmZ5C9RQXHfZd/EhCnTi1Hfay37zH3lBxn/fNs85LA9HlsniFw2zccgcbrrTMKk7Cn1Qg==", + "dev": true, + "optional": true + }, + "esbuild": { + "version": "0.16.14", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.16.14.tgz", + "integrity": "sha512-6xAn3O6ZZyoxZAEkwfI9hw4cEqSr/o1ViJtnkvImVkblmUN65Md04o0S/7H1WNu1XGf1Cjij/on7VO4psIYjkw==", + "dev": true, + "requires": { + "@esbuild/android-arm": "0.16.14", + "@esbuild/android-arm64": "0.16.14", + "@esbuild/android-x64": "0.16.14", + "@esbuild/darwin-arm64": "0.16.14", + "@esbuild/darwin-x64": "0.16.14", + "@esbuild/freebsd-arm64": "0.16.14", + "@esbuild/freebsd-x64": "0.16.14", + "@esbuild/linux-arm": "0.16.14", + "@esbuild/linux-arm64": "0.16.14", + "@esbuild/linux-ia32": "0.16.14", + "@esbuild/linux-loong64": "0.16.14", + "@esbuild/linux-mips64el": "0.16.14", + "@esbuild/linux-ppc64": "0.16.14", + "@esbuild/linux-riscv64": "0.16.14", + "@esbuild/linux-s390x": "0.16.14", + "@esbuild/linux-x64": "0.16.14", + "@esbuild/netbsd-x64": "0.16.14", + "@esbuild/openbsd-x64": "0.16.14", + "@esbuild/sunos-x64": "0.16.14", + "@esbuild/win32-arm64": "0.16.14", + "@esbuild/win32-ia32": "0.16.14", + "@esbuild/win32-x64": "0.16.14" + } + }, + "rollup": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.9.1.tgz", + "integrity": "sha512-GswCYHXftN8ZKGVgQhTFUJB/NBXxrRGgO2NCy6E8s1rwEJ4Q9/VttNqcYfEvx4dTo4j58YqdC3OVztPzlKSX8w==", + "dev": true, + "requires": { + "fsevents": "~2.3.2" + } + }, + "vite": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.0.4.tgz", + "integrity": "sha512-xevPU7M8FU0i/80DMR+YhgrzR5KS2ORy1B4xcX/cXLsvnUWvfHuqMmVU6N0YiJ4JWGRJJsLCgjEzKjG9/GKoSw==", + "dev": true, + "requires": { + "esbuild": "^0.16.3", + "fsevents": "~2.3.2", + "postcss": "^8.4.20", + "resolve": "^1.22.1", + "rollup": "^3.7.0" + } + } } }, "vue": { diff --git a/package.json b/package.json index 7fbc500..f4c5a03 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "jsdom": "^20.0.0", "prettier": "^2.5.1", "typescript": "4.8.4", - "vitest": "^0.17.1", + "vitest": "^0.26.3", "vue-tsc": "^0.38.1" }, "engines": { diff --git a/src/game/formulas.ts b/src/game/formulas.ts new file mode 100644 index 0000000..e9e96f5 --- /dev/null +++ b/src/game/formulas.ts @@ -0,0 +1,1136 @@ +import Decimal, { DecimalSource } from "util/bignum"; +import { convertComputable, ProcessedComputable } from "util/computed"; +import { unref } from "vue"; + +export type FormulaSource = ProcessedComputable | Formula; +export type InvertibleFormulaSource = ProcessedComputable | InvertibleFormula; + +export type InvertibleFormula = Formula & { invertible: true }; +export type VariableFormula = InvertibleFormula & { hasVariable: true }; + +function F(value: InvertibleFormulaSource): InvertibleFormula; +function F(value: FormulaSource): Formula; +function F(value: FormulaSource) { + return value instanceof Formula + ? value + : new Formula( + () => new Decimal(unref(value)), + value => new Decimal(value) + ); +} + +function processFormulaSource(value: FormulaSource) { + return value instanceof Formula ? value : convertComputable(value); +} + +function unrefFormulaSource(value: Formula | ProcessedComputable) { + return value instanceof Formula ? value.evaluate() : unref(value); +} + +export default class Formula { + public readonly invertible: boolean; + public readonly hasVariable: boolean; + public readonly evaluate: () => Decimal; + public readonly invert: (value: DecimalSource) => Decimal; + + constructor( + evaluate: () => Decimal, + invert?: (value: DecimalSource) => Decimal, + hasVariable = false + ) { + this.invertible = invert != null; + this.hasVariable = hasVariable; + this.evaluate = evaluate; + this.invert = invert ?? (() => Decimal.dNaN); + } + + public static constant(value: InvertibleFormulaSource): InvertibleFormula { + return F(value); + } + + public static variable(value: ProcessedComputable): VariableFormula { + return new Formula( + () => new Decimal(unref(value)), + value => new Decimal(value), + true + ) as VariableFormula; + } + + public static abs(value: FormulaSource) { + return F(value).abs(); + } + + public static neg(value: InvertibleFormulaSource): InvertibleFormula; + public static neg(value: FormulaSource): Formula; + public static neg(value: FormulaSource) { + return F(value).neg(); + } + + public static negate(value: InvertibleFormulaSource): InvertibleFormula; + public static negate(value: FormulaSource): Formula; + public static negate(value: FormulaSource) { + return F(value).neg(); + } + + public static negated(value: InvertibleFormulaSource): InvertibleFormula; + public static negated(value: FormulaSource): Formula; + public static negated(value: FormulaSource) { + return F(value).neg(); + } + + public static sign(value: FormulaSource) { + return F(value).sign(); + } + + public static sgn(value: FormulaSource) { + return F(value).sign(); + } + + public static round(value: FormulaSource) { + return F(value).round(); + } + + public static floor(value: FormulaSource) { + return F(value).floor(); + } + + public static ceil(value: FormulaSource) { + return F(value).ceil(); + } + + public static trunc(value: FormulaSource) { + return F(value).trunc(); + } + + public static add( + value: InvertibleFormulaSource, + other: InvertibleFormulaSource + ): InvertibleFormula; + public static add(value: FormulaSource, other: FormulaSource): Formula; + public static add(value: FormulaSource, other: FormulaSource) { + return F(value).add(other); + } + + public static plus( + value: InvertibleFormulaSource, + other: InvertibleFormulaSource + ): InvertibleFormula; + public static plus(value: FormulaSource, other: FormulaSource): Formula; + public static plus(value: FormulaSource, other: FormulaSource) { + return F(value).add(other); + } + + public static sub( + value: InvertibleFormulaSource, + other: InvertibleFormulaSource + ): InvertibleFormula; + public static sub(value: FormulaSource, other: FormulaSource): Formula; + public static sub(value: FormulaSource, other: FormulaSource) { + return F(value).sub(other); + } + + public static subtract( + value: InvertibleFormulaSource, + other: InvertibleFormulaSource + ): InvertibleFormula; + public static subtract(value: FormulaSource, other: FormulaSource): Formula; + public static subtract(value: FormulaSource, other: FormulaSource) { + return F(value).sub(other); + } + + public static minus( + value: InvertibleFormulaSource, + other: InvertibleFormulaSource + ): InvertibleFormula; + public static minus(value: FormulaSource, other: FormulaSource): Formula; + public static minus(value: FormulaSource, other: FormulaSource) { + return F(value).sub(other); + } + + public static mul( + value: InvertibleFormulaSource, + other: InvertibleFormulaSource + ): InvertibleFormula; + public static mul(value: FormulaSource, other: FormulaSource): Formula; + public static mul(value: FormulaSource, other: FormulaSource) { + return F(value).mul(other); + } + + public static multiply( + value: InvertibleFormulaSource, + other: InvertibleFormulaSource + ): InvertibleFormula; + public static multiply(value: FormulaSource, other: FormulaSource): Formula; + public static multiply(value: FormulaSource, other: FormulaSource) { + return F(value).mul(other); + } + + public static times( + value: InvertibleFormulaSource, + other: InvertibleFormulaSource + ): InvertibleFormula; + public static times(value: FormulaSource, other: FormulaSource): Formula; + public static times(value: FormulaSource, other: FormulaSource) { + return F(value).mul(other); + } + + public static div( + value: InvertibleFormulaSource, + other: InvertibleFormulaSource + ): InvertibleFormula; + public static div(value: FormulaSource, other: FormulaSource): Formula; + public static div(value: FormulaSource, other: FormulaSource) { + return F(value).div(other); + } + + public static divide( + value: InvertibleFormulaSource, + other: InvertibleFormulaSource + ): InvertibleFormula; + public static divide(value: FormulaSource, other: FormulaSource): Formula; + public static divide(value: FormulaSource, other: FormulaSource) { + return F(value).div(other); + } + + public static recip(value: InvertibleFormulaSource): InvertibleFormula; + public static recip(value: FormulaSource): Formula; + public static recip(value: FormulaSource) { + return F(value).recip(); + } + + public static reciprocal(value: InvertibleFormulaSource): InvertibleFormula; + public static reciprocal(value: FormulaSource): Formula; + public static reciprocal(value: FormulaSource) { + return F(value).recip(); + } + + public static reciprocate(value: InvertibleFormulaSource): InvertibleFormula; + public static reciprocate(value: FormulaSource): Formula; + public static reciprocate(value: FormulaSource) { + return F(value).reciprocate(); + } + + public static max(value: FormulaSource, other: FormulaSource) { + return F(value).max(other); + } + + public static min(value: FormulaSource, other: FormulaSource) { + return F(value).min(other); + } + + public static minabs(value: FormulaSource, other: FormulaSource) { + return F(value).minabs(other); + } + + public static maxabs(value: FormulaSource, other: FormulaSource) { + return F(value).maxabs(other); + } + + public static clamp(value: FormulaSource, min: FormulaSource, max: FormulaSource) { + return F(value).clamp(min, max); + } + + public static clampMin(value: FormulaSource, min: FormulaSource) { + return F(value).clampMin(min); + } + + public static clampMax(value: FormulaSource, max: FormulaSource) { + return F(value).clampMax(max); + } + + public static pLog10(value: InvertibleFormulaSource): InvertibleFormula; + public static pLog10(value: FormulaSource): Formula; + public static pLog10(value: FormulaSource) { + return F(value).pLog10(); + } + + public static absLog10(value: InvertibleFormulaSource): InvertibleFormula; + public static absLog10(value: FormulaSource): Formula; + public static absLog10(value: FormulaSource) { + return F(value).absLog10(); + } + + public static log10(value: InvertibleFormulaSource): InvertibleFormula; + public static log10(value: FormulaSource): Formula; + public static log10(value: FormulaSource) { + return F(value).log10(); + } + + public static log( + value: InvertibleFormulaSource, + base: InvertibleFormulaSource + ): InvertibleFormula; + public static log(value: FormulaSource, base: FormulaSource): Formula; + public static log(value: FormulaSource, base: FormulaSource) { + return F(value).log(base); + } + + public static logarithm( + value: InvertibleFormulaSource, + base: InvertibleFormulaSource + ): InvertibleFormula; + public static logarithm(value: FormulaSource, base: FormulaSource): Formula; + public static logarithm(value: FormulaSource, base: FormulaSource) { + return F(value).log(base); + } + + public static log2(value: InvertibleFormulaSource): InvertibleFormula; + public static log2(value: FormulaSource): Formula; + public static log2(value: FormulaSource) { + return F(value).log2(); + } + + public static ln(value: InvertibleFormulaSource): InvertibleFormula; + public static ln(value: FormulaSource): Formula; + public static ln(value: FormulaSource) { + return F(value).ln(); + } + + public static pow( + value: InvertibleFormulaSource, + other: InvertibleFormulaSource + ): InvertibleFormula; + public static pow(value: FormulaSource, other: FormulaSource): Formula; + public static pow(value: FormulaSource, other: FormulaSource) { + return F(value).pow(other); + } + + public static pow10(value: InvertibleFormulaSource): InvertibleFormula; + public static pow10(value: FormulaSource): Formula; + public static pow10(value: FormulaSource) { + return F(value).pow10(); + } + + public static pow_base( + value: InvertibleFormulaSource, + other: InvertibleFormulaSource + ): InvertibleFormula; + public static pow_base(value: FormulaSource, other: FormulaSource): Formula; + public static pow_base(value: FormulaSource, other: FormulaSource) { + return F(value).pow_base(other); + } + + public static root( + value: InvertibleFormulaSource, + other: InvertibleFormulaSource + ): InvertibleFormula; + public static root(value: FormulaSource, other: FormulaSource): Formula; + public static root(value: FormulaSource, other: FormulaSource) { + return F(value).root(other); + } + + public static factorial(value: FormulaSource) { + return F(value).factorial(); + } + + public static gamma(value: FormulaSource) { + return F(value).gamma(); + } + + public static lngamma(value: FormulaSource) { + return F(value).lngamma(); + } + + public static exp(value: InvertibleFormulaSource): InvertibleFormula; + public static exp(value: FormulaSource): Formula; + public static exp(value: FormulaSource) { + return F(value).exp(); + } + + public static sqr(value: InvertibleFormulaSource): InvertibleFormula; + public static sqr(value: FormulaSource): Formula; + public static sqr(value: FormulaSource) { + return F(value).sqr(); + } + + public static sqrt(value: InvertibleFormulaSource): InvertibleFormula; + public static sqrt(value: FormulaSource): Formula; + public static sqrt(value: FormulaSource) { + return F(value).sqrt(); + } + + public static cube(value: InvertibleFormulaSource): InvertibleFormula; + public static cube(value: FormulaSource): Formula; + public static cube(value: FormulaSource) { + return F(value).cube(); + } + + public static cbrt(value: InvertibleFormulaSource): InvertibleFormula; + public static cbrt(value: FormulaSource): Formula; + public static cbrt(value: FormulaSource) { + return F(value).cbrt(); + } + + public static tetrate( + value: InvertibleFormulaSource, + height?: InvertibleFormulaSource, + payload?: InvertibleFormulaSource + ): InvertibleFormula; + public static tetrate( + value: FormulaSource, + height?: FormulaSource, + payload?: FormulaSource + ): Formula; + public static tetrate( + value: FormulaSource, + height: FormulaSource = 2, + payload: FormulaSource = Decimal.fromComponents_noNormalize(1, 0, 1) + ) { + return F(value).tetrate(height, payload); + } + + public static iteratedexp( + value: InvertibleFormulaSource, + height?: InvertibleFormulaSource, + payload?: InvertibleFormulaSource + ): InvertibleFormula; + public static iteratedexp( + value: FormulaSource, + height?: FormulaSource, + payload?: FormulaSource + ): Formula; + public static iteratedexp( + value: FormulaSource, + height: FormulaSource = 2, + payload: FormulaSource = Decimal.fromComponents_noNormalize(1, 0, 1) + ) { + return F(value).iteratedexp(height, payload); + } + + public static iteratedlog( + value: FormulaSource, + base: FormulaSource = 10, + times: FormulaSource = 1 + ) { + return F(value).iteratedlog(base, times); + } + + public static slog( + value: InvertibleFormulaSource, + base?: InvertibleFormulaSource + ): InvertibleFormula; + public static slog(value: FormulaSource, base?: FormulaSource): Formula; + public static slog(value: FormulaSource, base: FormulaSource = 10) { + return F(value).slog(base); + } + + public static layeradd10(value: FormulaSource, diff: FormulaSource) { + return F(value).layeradd10(diff); + } + + public static layeradd( + value: InvertibleFormulaSource, + diff: InvertibleFormulaSource, + base?: InvertibleFormulaSource + ): InvertibleFormula; + public static layeradd( + value: FormulaSource, + diff: FormulaSource, + base?: FormulaSource + ): Formula; + public static layeradd(value: FormulaSource, diff: FormulaSource, base: FormulaSource = 10) { + return F(value).layeradd(diff, base); + } + + public static lambertw(value: InvertibleFormulaSource): InvertibleFormula; + public static lambertw(value: FormulaSource): Formula; + public static lambertw(value: FormulaSource) { + return F(value).lambertw(); + } + + public static ssqrt(value: InvertibleFormulaSource): InvertibleFormula; + public static ssqrt(value: FormulaSource): Formula; + public static ssqrt(value: FormulaSource) { + return F(value).ssqrt(); + } + + public static pentate( + value: FormulaSource, + height: FormulaSource = 2, + payload: FormulaSource = Decimal.fromComponents_noNormalize(1, 0, 1) + ) { + return F(value).pentate(height, payload); + } + + public static sin(value: InvertibleFormulaSource): InvertibleFormula; + public static sin(value: FormulaSource): Formula; + public static sin(value: FormulaSource) { + return F(value).sin(); + } + + public static cos(value: InvertibleFormulaSource): InvertibleFormula; + public static cos(value: FormulaSource): Formula; + public static cos(value: FormulaSource) { + return F(value).cos(); + } + + public static tan(value: InvertibleFormulaSource): InvertibleFormula; + public static tan(value: FormulaSource): Formula; + public static tan(value: FormulaSource) { + return F(value).tan(); + } + + public static asin(value: InvertibleFormulaSource): InvertibleFormula; + public static asin(value: FormulaSource): Formula; + public static asin(value: FormulaSource) { + return F(value).asin(); + } + + public static acos(value: InvertibleFormulaSource): InvertibleFormula; + public static acos(value: FormulaSource): Formula; + public static acos(value: FormulaSource) { + return F(value).acos(); + } + + public static atan(value: InvertibleFormulaSource): InvertibleFormula; + public static atan(value: FormulaSource): Formula; + public static atan(value: FormulaSource) { + return F(value).atan(); + } + + public static sinh(value: InvertibleFormulaSource): InvertibleFormula; + public static sinh(value: FormulaSource): Formula; + public static sinh(value: FormulaSource) { + return F(value).sinh(); + } + + public static cosh(value: InvertibleFormulaSource): InvertibleFormula; + public static cosh(value: FormulaSource): Formula; + public static cosh(value: FormulaSource) { + return F(value).cosh(); + } + + public static tanh(value: InvertibleFormulaSource): InvertibleFormula; + public static tanh(value: FormulaSource): Formula; + public static tanh(value: FormulaSource) { + return F(value).tanh(); + } + + public static asinh(value: InvertibleFormulaSource): InvertibleFormula; + public static asinh(value: FormulaSource): Formula; + public static asinh(value: FormulaSource) { + return F(value).asinh(); + } + + public static acosh(value: InvertibleFormulaSource): InvertibleFormula; + public static acosh(value: FormulaSource): Formula; + public static acosh(value: FormulaSource) { + return F(value).acosh(); + } + + public static atanh(value: InvertibleFormulaSource): InvertibleFormula; + public static atanh(value: FormulaSource): Formula; + public static atanh(value: FormulaSource) { + return F(value).atanh(); + } + + public abs() { + return new Formula(() => this.evaluate().abs()); + } + + public neg(this: InvertibleFormula): InvertibleFormula; + public neg(this: Formula): Formula; + public neg() { + return new Formula( + () => this.evaluate().neg(), + value => Decimal.neg(value) + ); + } + + public negate(this: InvertibleFormula): InvertibleFormula; + public negate(this: Formula): Formula; + public negate() { + return this.neg(); + } + + public negated(this: InvertibleFormula): InvertibleFormula; + public negated(this: Formula): Formula; + public negated() { + return this.neg(); + } + + public sign() { + return new Formula(() => new Decimal(this.evaluate().sign)); + } + + public sgn() { + return this.sign(); + } + + public round() { + return new Formula(() => this.evaluate().round()); + } + + public floor() { + return new Formula(() => this.evaluate().floor()); + } + + public ceil() { + return new Formula(() => this.evaluate().ceil()); + } + + public trunc() { + return new Formula(() => this.evaluate().trunc()); + } + + public add(this: InvertibleFormula, value: FormulaSource): InvertibleFormula; + public add(this: Formula, value: FormulaSource): Formula; + public add(value: FormulaSource) { + const v = processFormulaSource(value); + return new Formula( + () => this.evaluate().add(unrefFormulaSource(v)), + (v instanceof Formula && !v.invertible) || !this.invertible + ? undefined + : value => Decimal.sub(value, unrefFormulaSource(v)) + ); + } + + public plus(this: InvertibleFormula, value: FormulaSource): InvertibleFormula; + public plus(this: Formula, value: FormulaSource): Formula; + public plus(value: FormulaSource) { + return this.add(value); + } + + public sub(this: InvertibleFormula, value: FormulaSource): InvertibleFormula; + public sub(this: Formula, value: FormulaSource): Formula; + public sub(value: FormulaSource) { + const v = processFormulaSource(value); + return new Formula( + () => this.evaluate().sub(unrefFormulaSource(v)), + (v instanceof Formula && !v.invertible) || !this.invertible + ? undefined + : value => Decimal.add(value, unrefFormulaSource(v)) + ); + } + + public subtract(this: InvertibleFormula, value: FormulaSource): InvertibleFormula; + public subtract(this: Formula, value: FormulaSource): Formula; + public subtract(value: FormulaSource) { + return this.sub(value); + } + + public minus(this: InvertibleFormula, value: FormulaSource): InvertibleFormula; + public minus(this: Formula, value: FormulaSource): Formula; + public minus(value: FormulaSource) { + return this.sub(value); + } + + public mul(this: InvertibleFormula, value: FormulaSource): InvertibleFormula; + public mul(this: Formula, value: FormulaSource): Formula; + public mul(value: FormulaSource) { + const v = processFormulaSource(value); + return new Formula( + () => this.evaluate().mul(unrefFormulaSource(v)), + (v instanceof Formula && !v.invertible) || !this.invertible + ? undefined + : value => Decimal.div(value, unrefFormulaSource(v)) + ); + } + + public multiply(this: InvertibleFormula, value: FormulaSource): InvertibleFormula; + public multiply(this: Formula, value: FormulaSource): Formula; + public multiply(value: FormulaSource) { + return this.mul(value); + } + + public times(this: InvertibleFormula, value: FormulaSource): InvertibleFormula; + public times(this: Formula, value: FormulaSource): Formula; + public times(value: FormulaSource) { + return this.mul(value); + } + + public div(this: InvertibleFormula, value: FormulaSource): InvertibleFormula; + public div(this: Formula, value: FormulaSource): Formula; + public div(value: FormulaSource) { + const v = processFormulaSource(value); + return new Formula( + () => this.evaluate().div(unrefFormulaSource(v)), + (v instanceof Formula && !v.invertible) || !this.invertible + ? undefined + : value => Decimal.mul(value, unrefFormulaSource(v)) + ); + } + + public divide(this: InvertibleFormula, value: FormulaSource): InvertibleFormula; + public divide(this: Formula, value: FormulaSource): Formula; + public divide(value: FormulaSource) { + return this.div(value); + } + + public divideBy(this: InvertibleFormula, value: FormulaSource): InvertibleFormula; + public divideBy(this: Formula, value: FormulaSource): Formula; + public divideBy(value: FormulaSource) { + return this.div(value); + } + + public dividedBy(this: InvertibleFormula, value: FormulaSource): InvertibleFormula; + public dividedBy(this: Formula, value: FormulaSource): Formula; + public dividedBy(value: FormulaSource) { + return this.div(value); + } + + public recip(this: InvertibleFormula): InvertibleFormula; + public recip(this: Formula): Formula; + public recip() { + return new Formula( + () => this.evaluate().recip(), + !this.invertible ? undefined : value => Decimal.recip(value) + ); + } + + public reciprocal(this: InvertibleFormula): InvertibleFormula; + public reciprocal(this: Formula): Formula; + public reciprocal() { + return this.recip(); + } + + public reciprocate(this: InvertibleFormula): InvertibleFormula; + public reciprocate(this: Formula): Formula; + public reciprocate() { + return this.recip(); + } + + public max(value: FormulaSource) { + const v = processFormulaSource(value); + return new Formula(() => this.evaluate().max(unrefFormulaSource(v))); + } + + public min(value: FormulaSource) { + const v = processFormulaSource(value); + return new Formula(() => this.evaluate().min(unrefFormulaSource(v))); + } + + public maxabs(value: FormulaSource) { + const v = processFormulaSource(value); + return new Formula(() => this.evaluate().maxabs(unrefFormulaSource(v))); + } + + public minabs(value: FormulaSource) { + const v = processFormulaSource(value); + return new Formula(() => this.evaluate().minabs(unrefFormulaSource(v))); + } + + public clamp(min: FormulaSource, max: FormulaSource) { + const minValue = processFormulaSource(min); + const maxValue = processFormulaSource(max); + return new Formula(() => + this.evaluate().clamp(unrefFormulaSource(minValue), unrefFormulaSource(maxValue)) + ); + } + + public clampMin(value: FormulaSource) { + const v = processFormulaSource(value); + return new Formula(() => this.evaluate().clampMin(unrefFormulaSource(v))); + } + + public clampMax(value: FormulaSource) { + const v = processFormulaSource(value); + return new Formula(() => this.evaluate().clampMax(unrefFormulaSource(v))); + } + + public pLog10(this: InvertibleFormula): InvertibleFormula; + public pLog10(this: Formula): Formula; + public pLog10() { + return new Formula(() => this.evaluate().pLog10()); + } + + public absLog10(this: InvertibleFormula): InvertibleFormula; + public absLog10(this: Formula): Formula; + public absLog10() { + return new Formula(() => this.evaluate().absLog10()); + } + + public log10(this: InvertibleFormula): InvertibleFormula; + public log10(this: Formula): Formula; + public log10() { + return new Formula( + () => this.evaluate().log10(), + !this.invertible ? undefined : value => Decimal.pow10(value) + ); + } + + public log(this: InvertibleFormula, value: FormulaSource): InvertibleFormula; + public log(this: Formula, value: FormulaSource): Formula; + public log(value: FormulaSource) { + const v = processFormulaSource(value); + return new Formula( + () => this.evaluate().log(unrefFormulaSource(v)), + (v instanceof Formula && !v.invertible) || !this.invertible + ? undefined + : value => Decimal.pow(unrefFormulaSource(v), value) + ); + } + + public logarithm(this: InvertibleFormula, value: FormulaSource): InvertibleFormula; + public logarithm(this: Formula, value: FormulaSource): Formula; + public logarithm(value: FormulaSource) { + return this.log(value); + } + + public log2(this: InvertibleFormula): InvertibleFormula; + public log2(this: Formula): Formula; + public log2() { + return new Formula( + () => this.evaluate().log2(), + !this.invertible ? undefined : value => Decimal.pow(2, value) + ); + } + + public ln(this: InvertibleFormula): InvertibleFormula; + public ln(this: Formula): Formula; + public ln() { + return new Formula( + () => this.evaluate().ln(), + !this.invertible ? undefined : value => Decimal.exp(value) + ); + } + + public pow(this: InvertibleFormula, value: FormulaSource): InvertibleFormula; + public pow(this: Formula, value: FormulaSource): Formula; + public pow(value: FormulaSource) { + const v = processFormulaSource(value); + return new Formula( + () => this.evaluate().pow(unrefFormulaSource(v)), + (v instanceof Formula && !v.invertible) || !this.invertible + ? undefined + : value => Decimal.root(value, unrefFormulaSource(v)) + ); + } + + public pow10(this: InvertibleFormula): InvertibleFormula; + public pow10(this: Formula): Formula; + public pow10() { + return new Formula( + () => this.evaluate().pow10(), + !this.invertible ? undefined : value => Decimal.root(value, 10) + ); + } + + public pow_base(this: InvertibleFormula, value: FormulaSource): InvertibleFormula; + public pow_base(this: Formula, value: FormulaSource): Formula; + public pow_base(value: FormulaSource) { + const v = processFormulaSource(value); + return new Formula( + () => this.evaluate().pow_base(unrefFormulaSource(v)), + (v instanceof Formula && !v.invertible) || !this.invertible + ? undefined + : value => Decimal.root(unrefFormulaSource(v), value) + ); + } + + public root(this: InvertibleFormula, value: FormulaSource): InvertibleFormula; + public root(this: Formula, value: FormulaSource): Formula; + public root(value: FormulaSource) { + const v = processFormulaSource(value); + return new Formula( + () => this.evaluate().root(unrefFormulaSource(v)), + (v instanceof Formula && !v.invertible) || !this.invertible + ? undefined + : value => Decimal.pow(value, unrefFormulaSource(v)) + ); + } + + public factorial() { + return new Formula(() => this.evaluate().factorial()); + } + + public gamma() { + return new Formula(() => this.evaluate().gamma()); + } + public lngamma() { + return new Formula(() => this.evaluate().lngamma()); + } + + public exp(this: InvertibleFormula): InvertibleFormula; + public exp(this: Formula): Formula; + public exp() { + return new Formula( + () => this.evaluate().exp(), + !this.invertible ? undefined : value => Decimal.ln(value) + ); + } + + public sqr(this: InvertibleFormula): InvertibleFormula; + public sqr(this: Formula): Formula; + public sqr() { + return this.pow(2); + } + + public sqrt(this: InvertibleFormula): InvertibleFormula; + public sqrt(this: Formula): Formula; + public sqrt() { + return this.root(2); + } + + public cube(this: InvertibleFormula): InvertibleFormula; + public cube(this: Formula): Formula; + public cube() { + return this.pow(3); + } + + public cbrt(this: InvertibleFormula): InvertibleFormula; + public cbrt(this: Formula): Formula; + public cbrt() { + return this.pow(1 / 3); + } + + public tetrate( + this: InvertibleFormula, + height?: FormulaSource, + payload?: FormulaSource + ): InvertibleFormula; + public tetrate(this: Formula, height?: FormulaSource, payload?: FormulaSource): Formula; + public tetrate( + height: FormulaSource = 2, + payload: FormulaSource = Decimal.fromComponents_noNormalize(1, 0, 1) + ) { + const heightValue = processFormulaSource(height); + const payloadValue = processFormulaSource(payload); + return new Formula( + () => + this.evaluate().tetrate( + Decimal.min(1e308, unrefFormulaSource(heightValue)).toNumber(), + unrefFormulaSource(payloadValue) + ), + (heightValue instanceof Formula && !heightValue.invertible) || + (payloadValue instanceof Formula && !payloadValue.invertible) || + !this.invertible + ? undefined + : value => + Decimal.slog( + value, + Decimal.min(1e308, unrefFormulaSource(heightValue)).toNumber() + ) + ); + } + + public iteratedexp( + this: InvertibleFormula, + height?: FormulaSource, + payload?: FormulaSource + ): InvertibleFormula; + public iteratedexp(this: Formula, height?: FormulaSource, payload?: FormulaSource): Formula; + public iteratedexp( + height: FormulaSource = 2, + payload: FormulaSource = Decimal.fromComponents_noNormalize(1, 0, 1) + ) { + const heightValue = processFormulaSource(height); + const payloadValue = processFormulaSource(payload); + return new Formula( + () => + this.evaluate().iteratedexp( + Decimal.min(1e308, unrefFormulaSource(heightValue)).toNumber(), + new Decimal(unrefFormulaSource(payloadValue)) + ), + (heightValue instanceof Formula && !heightValue.invertible) || + (payloadValue instanceof Formula && !payloadValue.invertible) || + !this.invertible + ? undefined + : value => + Decimal.iteratedlog( + value, + Math.E, + Decimal.min(1e308, unrefFormulaSource(heightValue)).toNumber() + ) + ); + } + + public iteratedlog(base: FormulaSource = 10, times: FormulaSource = 1) { + const baseValue = processFormulaSource(base); + const timesValue = processFormulaSource(times); + return new Formula(() => + this.evaluate().iteratedlog( + unrefFormulaSource(baseValue), + Decimal.min(1e308, unrefFormulaSource(timesValue)).toNumber() + ) + ); + } + + public slog(base: FormulaSource = 10) { + const baseValue = processFormulaSource(base); + return new Formula( + () => + this.evaluate().slog(Decimal.min(1e308, unrefFormulaSource(baseValue)).toNumber()), + (baseValue instanceof Formula && !baseValue.invertible) || !this.invertible + ? undefined + : value => + Decimal.tetrate( + value, + Decimal.min(1e308, unrefFormulaSource(baseValue)).toNumber() + ) + ); + } + + public layeradd10(diff: FormulaSource) { + const diffValue = processFormulaSource(diff); + return new Formula(() => this.evaluate().layeradd10(unrefFormulaSource(diffValue))); + } + + public layeradd( + this: InvertibleFormula, + diff: FormulaSource, + base: FormulaSource + ): InvertibleFormula; + public layeradd(this: Formula, diff: FormulaSource, base: FormulaSource): Formula; + public layeradd(diff: FormulaSource, base: FormulaSource) { + const diffValue = processFormulaSource(diff); + const baseValue = processFormulaSource(base); + return new Formula( + () => + this.evaluate().layeradd( + Decimal.min(1e308, unrefFormulaSource(diffValue)).toNumber(), + unrefFormulaSource(baseValue) + ), + (diffValue instanceof Formula && !diffValue.invertible) || + (diffValue instanceof Formula && !diffValue.invertible) || + !this.invertible + ? undefined + : value => + Decimal.layeradd( + value, + Decimal.min(1e308, unrefFormulaSource(diffValue)).negate().toNumber(), + unrefFormulaSource(baseValue) + ) + ); + } + + public lambertw(this: InvertibleFormula): InvertibleFormula; + public lambertw(this: Formula): Formula; + public lambertw() { + return new Formula( + () => this.evaluate().lambertw(), + !this.invertible ? undefined : value => Decimal.pow(Math.E, value).times(value) + ); + } + + public ssqrt(this: InvertibleFormula): InvertibleFormula; + public ssqrt(this: Formula): Formula; + public ssqrt() { + return new Formula( + () => this.evaluate().ssqrt(), + !this.invertible ? undefined : value => Decimal.tetrate(value, 2) + ); + } + + public pentate( + height: FormulaSource = 2, + payload: FormulaSource = Decimal.fromComponents_noNormalize(1, 0, 1) + ) { + const heightValue = processFormulaSource(height); + const payloadValue = processFormulaSource(payload); + return new Formula(() => + this.evaluate().pentate( + Decimal.min(1e308, unrefFormulaSource(heightValue)).toNumber(), + unrefFormulaSource(payloadValue) + ) + ); + } + + public sin(this: InvertibleFormula): InvertibleFormula; + public sin(this: Formula): Formula; + public sin() { + return new Formula( + () => this.evaluate().sin(), + !this.invertible ? undefined : value => Decimal.asin(value) + ); + } + + public cos(this: InvertibleFormula): InvertibleFormula; + public cos(this: Formula): Formula; + public cos() { + return new Formula( + () => this.evaluate().cos(), + !this.invertible ? undefined : value => Decimal.acos(value) + ); + } + + public tan(this: InvertibleFormula): InvertibleFormula; + public tan(this: Formula): Formula; + public tan() { + return new Formula( + () => this.evaluate().tan(), + !this.invertible ? undefined : value => Decimal.atan(value) + ); + } + + public asin(this: InvertibleFormula): InvertibleFormula; + public asin(this: Formula): Formula; + public asin() { + return new Formula( + () => this.evaluate().asin(), + !this.invertible ? undefined : value => Decimal.sin(value) + ); + } + + public acos(this: InvertibleFormula): InvertibleFormula; + public acos(this: Formula): Formula; + public acos() { + return new Formula( + () => this.evaluate().acos(), + !this.invertible ? undefined : value => Decimal.cos(value) + ); + } + + public atan(this: InvertibleFormula): InvertibleFormula; + public atan(this: Formula): Formula; + public atan() { + return new Formula( + () => this.evaluate().atan(), + !this.invertible ? undefined : value => Decimal.tan(value) + ); + } + + public sinh(this: InvertibleFormula): InvertibleFormula; + public sinh(this: Formula): Formula; + public sinh() { + return new Formula( + () => this.evaluate().sinh(), + !this.invertible ? undefined : value => Decimal.asinh(value) + ); + } + + public cosh(this: InvertibleFormula): InvertibleFormula; + public cosh(this: Formula): Formula; + public cosh() { + return new Formula( + () => this.evaluate().cosh(), + !this.invertible ? undefined : value => Decimal.acosh(value) + ); + } + + public tanh(this: InvertibleFormula): InvertibleFormula; + public tanh(this: Formula): Formula; + public tanh() { + return new Formula( + () => this.evaluate().tanh(), + !this.invertible ? undefined : value => Decimal.atanh(value) + ); + } + + public asinh(this: InvertibleFormula): InvertibleFormula; + public asinh(this: Formula): Formula; + public asinh() { + return new Formula( + () => this.evaluate().asinh(), + !this.invertible ? undefined : value => Decimal.sinh(value) + ); + } + + public acosh(this: InvertibleFormula): InvertibleFormula; + public acosh(this: Formula): Formula; + public acosh() { + return new Formula( + () => this.evaluate().acosh(), + !this.invertible ? undefined : value => Decimal.cosh(value) + ); + } + + public atanh(this: InvertibleFormula): InvertibleFormula; + public atanh(this: Formula): Formula; + public atanh() { + return new Formula( + () => this.evaluate().atanh(), + !this.invertible ? undefined : value => Decimal.tanh(value) + ); + } +} diff --git a/src/lib/break_eternity.ts b/src/lib/break_eternity.ts index b2d71be..a1d957c 100644 --- a/src/lib/break_eternity.ts +++ b/src/lib/break_eternity.ts @@ -344,16 +344,16 @@ 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 static dZero: Decimal; + public static dOne: Decimal; + public static dNegOne: Decimal; + public static dTwo: Decimal; + public static dTen: Decimal; + public static dNaN: Decimal; + public static dInf: Decimal; + public static dNegInf: Decimal; + public static dNumberMax: Decimal; + public static dNumberMin: Decimal; private static fromStringCache = new LRUCache(DEFAULT_FROM_STRING_CACHE_SIZE); @@ -705,7 +705,7 @@ export default class Decimal { public static eq_tolerance( value: DecimalSource, other: DecimalSource, - tolerance: number + tolerance?: number ): boolean { return D(value).eq_tolerance(other, tolerance); } @@ -713,7 +713,7 @@ export default class Decimal { public static equals_tolerance( value: DecimalSource, other: DecimalSource, - tolerance: number + tolerance?: number ): boolean { return D(value).eq_tolerance(other, tolerance); } @@ -858,7 +858,7 @@ export default class Decimal { return D(value).layeradd10(diff); } - public static layeradd(value: DecimalSource, diff: number, base = 10): Decimal { + public static layeradd(value: DecimalSource, diff: number, base: DecimalSource = 10): Decimal { return D(value).layeradd(diff, base); } @@ -2037,7 +2037,7 @@ export default class Decimal { * 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 { + public eq_tolerance(value: DecimalSource, tolerance?: number): boolean { const decimal = D(value); // https://stackoverflow.com/a/33024979 if (tolerance == null) { tolerance = 1e-7; @@ -2961,6 +2961,19 @@ export default class Decimal { // return Decimal; } +// Assign these after the Decimal is assigned because vitest had issues otherwise +// If we can figure out why, we can make these readonly properties instead +Decimal.dZero = FC_NN(0, 0, 0); +Decimal.dOne = FC_NN(1, 0, 1); +Decimal.dNegOne = FC_NN(-1, 0, 1); +Decimal.dTwo = FC_NN(1, 0, 2); +Decimal.dTen = FC_NN(1, 0, 10); +Decimal.dNaN = FC_NN(Number.NaN, Number.NaN, Number.NaN); +Decimal.dInf = FC_NN(1, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY); +Decimal.dNegInf = FC_NN(-1, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY); +Decimal.dNumberMax = FC(1, 0, Number.MAX_VALUE); +Decimal.dNumberMin = FC(1, 0, Number.MIN_VALUE); + // return Decimal; // Optimise Decimal aliases. diff --git a/tests/game/formulas.test.ts b/tests/game/formulas.test.ts new file mode 100644 index 0000000..565ec76 --- /dev/null +++ b/tests/game/formulas.test.ts @@ -0,0 +1,365 @@ +import Formula, { InvertibleFormula } from "game/formulas"; +import Decimal, { DecimalSource } from "util/bignum"; +import { beforeAll, describe, expect, test } from "vitest"; +import { ref } from "vue"; + +type FormulaFunctions = keyof Formula & keyof typeof Formula & keyof typeof Decimal; + +interface FixedLengthArray extends ArrayLike { + length: L; +} + +function compare_tolerance(value: DecimalSource) { + return (other: DecimalSource) => Decimal.eq_tolerance(value, other); +} + +function testConstant( + desc: string, + formulaFunc: () => InvertibleFormula, + expectedValue: DecimalSource = 10 +) { + describe(desc, () => { + let formula: Formula; + beforeAll(() => { + formula = formulaFunc(); + }); + test("evaluates correctly", () => expect(formula.evaluate()).toEqual(expectedValue)); + test("inverts correctly", () => expect(formula.invert(10)).toEqual(expectedValue)); + test("is invertible", () => expect(formula.invertible).toBe(true)); + test("is not marked as having a variable", () => expect(formula.hasVariable).toBe(false)); + }); +} + +// Utility function that will test all the different +// It's a lot of tests, but I'd rather be exhaustive +function testFormula( + functionNames: readonly T[], + args: Readonly["length"]>>, + invertible = true +) { + let value: Decimal; + + beforeAll(() => { + value = testValueFormulas[args[0]].evaluate(); + }); + + functionNames.forEach(name => { + let testName = name + "("; + for (let i = 0; i < args.length; i++) { + if (i !== 0) { + testName += ", "; + } + testName += testValues[args[i]]; + } + testName += ")"; + describe(testName, () => { + let expectedEvaluation: Decimal | undefined; + let formulaArgs: Formula[]; + let staticFormula: Formula; + let instanceFormula: Formula; + beforeAll(() => { + for (let i = 0; i < args.length; i++) { + formulaArgs.push(testValueFormulas[args[i]]); + } + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + staticFormula = Formula[name](...formulaArgs); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + instanceFormula = formulaArgs[0][name](...formulaArgs.slice(1)); + + try { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + expectedEvaluation = Decimal[name](...args); + } catch { + // If this is an invalid Decimal operation, then ignore this test case + return; + } + }); + + test("Static formula is not marked as having a variable", () => + expect(staticFormula.hasVariable).toBe(false)); + test("Static function evaluates correctly", () => + expectedEvaluation != null && + expect(staticFormula.evaluate()).toSatisfy(compare_tolerance(expectedEvaluation))); + test("Static function invertible", () => + expect(staticFormula.invertible).toBe(invertible)); + if (invertible) { + test("Static function inverts correctly", () => + expectedEvaluation != null && + !Decimal.isNaN(expectedEvaluation) && + expect(staticFormula.invert(expectedEvaluation)).toSatisfy( + compare_tolerance(value) + )); + } + + // Do those tests again but for non-static methods + test("Instance formula is not marked as having a variable", () => + expect(instanceFormula.hasVariable).toBe(false)); + test("Instance function evaluates correctly", () => + expectedEvaluation != null && + expect(instanceFormula.evaluate()).toSatisfy( + compare_tolerance(expectedEvaluation) + )); + test("Instance function invertible", () => + expect(instanceFormula.invertible).toBe(invertible)); + if (invertible) { + test("Instance function inverts correctly", () => + expectedEvaluation != null && + !Decimal.isNaN(expectedEvaluation) && + expect(instanceFormula.invert(expectedEvaluation)).toSatisfy( + compare_tolerance(value) + )); + } + }); + }); +} + +const testValues = [-2.5, -1, -0.1, 0, 0.1, 1, 2.5] as const; +let testValueFormulas: InvertibleFormula[] = []; + +const invertibleZeroParamFunctionNames = [ + ["neg", "negate", "negated"], + ["recip", "reciprocal", "reciprocate"], + ["log10"], + ["log2"], + ["ln"], + ["pow10"], + ["exp"], + ["sqr"], + ["sqrt"], + ["cube"], + ["cbrt"], + ["lambertw"], + ["ssqrt"], + ["sin"], + ["cos"], + ["tan"], + ["asin"], + ["acos"], + ["atan"], + ["sinh"], + ["cosh"], + ["tanh"], + ["asinh"], + ["acosh"], + ["atanh"] +] as const; + +const nonInvertibleZeroParamFunctionNames = [ + ["abs"], + ["sign", "sgn"], + ["round"], + ["floor"], + ["ceil"], + ["trunc"], + ["pLog10"], + ["absLog10"], + ["factorial"], + ["gamma"], + ["lngamma"] +] as const; + +const invertibleOneParamFunctionNames = [ + ["add", "plus"], + ["sub", "subtract", "minus"], + ["mul", "multiply", "times"], + ["div", "divide"], + ["log", "logarithm"], + ["pow"], + ["root"], + ["slog"] +] as const; + +const nonInvertibleOneParamFunctionNames = [ + ["max"], + ["min"], + ["maxabs"], + ["minabs"], + ["clampMin"], + ["clampMax"], + ["layeradd10"] +] as const; + +const invertibleTwoParamFunctionNames = [["tetrate"]] as const; + +const nonInvertibleTwoParamFunctionNames = [ + ["clamp"], + ["iteratedexp"], + ["iteratedlog"], + ["layeradd"], + ["pentate"] +] as const; + +describe("Creating Formulas", () => { + beforeAll(() => { + testValueFormulas = testValues.map(v => Formula.constant(v)); + }); + + describe("Constants", () => { + testConstant("number", () => Formula.constant(10)); + testConstant("string", () => Formula.constant("10")); + testConstant("formula", () => Formula.constant(Formula.constant(10))); + testConstant("decimal", () => Formula.constant(new Decimal("1e400")), "1e400"); + testConstant("ref", () => Formula.constant(ref(10))); + }); + + describe("Invertible 0-param", () => { + invertibleZeroParamFunctionNames.forEach(names => { + for (let i = 0; i < testValues.length; i++) { + testFormula(names, [i] as const); + } + }); + }); + describe("Non-Invertible 0-param", () => { + nonInvertibleZeroParamFunctionNames.forEach(names => { + for (let i = 0; i < testValues.length; i++) { + testFormula(names, [i] as const, false); + } + }); + }); + describe("Invertible 1-param", () => { + invertibleOneParamFunctionNames.forEach(names => { + for (let i = 0; i < testValues.length; i++) { + for (let j = 0; j < testValues.length; j++) { + testFormula(names, [i, j] as const); + } + } + }); + }); + describe("Non-Invertible 1-param", () => { + nonInvertibleOneParamFunctionNames.forEach(names => { + for (let i = 0; i < testValues.length; i++) { + for (let j = 0; j < testValues.length; j++) { + testFormula(names, [i, j] as const, false); + } + } + }); + }); + describe("Invertible 2-param", () => { + invertibleTwoParamFunctionNames.forEach(names => { + for (let i = 0; i < testValues.length; i++) { + for (let j = 0; j < testValues.length; j++) { + for (let k = 0; k < testValues.length; k++) { + testFormula(names, [i, j, k] as const); + } + } + } + }); + }); + describe("Non-Invertible 2-param", () => { + nonInvertibleTwoParamFunctionNames.forEach(names => { + for (let i = 0; i < testValues.length; i++) { + for (let j = 0; j < testValues.length; j++) { + for (let k = 0; k < testValues.length; k++) { + testFormula(names, [i, j, k] as const, false); + } + } + } + }); + }); + + describe("Variables", () => { + let variable: Formula; + let constant: Formula; + beforeAll(() => { + variable = Formula.variable(10); + constant = Formula.constant(10); + }); + + test("Created variable is marked as a variable", () => + expect(variable.hasVariable).toBe(true)); + test("Evaluate() returns variable's value", () => + expect(variable.evaluate()).toSatisfy(compare_tolerance(10))); + test("Invert() is pass-through", () => + expect(variable.invert(100)).toSatisfy(compare_tolerance(100))); + + test("Nested variable is marked as having a variable", () => + expect(variable.add(10).div(3).pow(2).hasVariable).toBe(false)); + test("Nested non-variable is marked as not having a variable", () => + expect(constant.add(10).div(3).pow(2).hasVariable).toBe(false)); + + describe("Invertible Formulas correctly calculate when they contain a variable", () => { + function checkFormula(formula: Formula, expectedBool = true) { + expect(formula.invertible).toBe(expectedBool); + expect(formula.hasVariable).toBe(expectedBool); + } + invertibleZeroParamFunctionNames.flat().forEach(name => { + describe(name, () => { + test(`${name}(var) is marked as invertible and having a variable`, () => + checkFormula(Formula[name](variable))); + }); + }); + invertibleOneParamFunctionNames.flat().forEach(name => { + describe(name, () => { + test(`${name}(var, const) is marked as invertible and having a variable`, () => + checkFormula(Formula[name](variable, constant))); + test(`${name}(const, var) is marked as invertible and having a variable`, () => + checkFormula(Formula[name](constant, variable))); + test(`${name}(var, var) is marked as not invertible and not having a variable`, () => + checkFormula(Formula[name](variable, variable), false)); + }); + }); + invertibleTwoParamFunctionNames.flat().forEach(name => { + describe(name, () => { + test(`${name}(var, const, const) is marked as invertible and having a variable`, () => + checkFormula(Formula[name](variable, constant, constant))); + test(`${name}(const, var, const) is marked as invertible and having a variable`, () => + checkFormula(Formula[name](constant, variable, constant))); + test(`${name}(const, const, var) is marked as invertible and having a variable`, () => + checkFormula(Formula[name](constant, constant, variable))); + test(`${name}(var, var, const) is marked as not invertible and not having a variable`, () => + checkFormula(Formula[name](variable, variable, constant), false)); + test(`${name}(var, const, var) is marked as not invertible and not having a variable`, () => + checkFormula(Formula[name](variable, constant, variable), false)); + test(`${name}(const, var, var) is marked as not invertible and not having a variable`, () => + checkFormula(Formula[name](constant, variable, variable), false)); + test(`${name}(var, var, var) is marked as not invertible and not having a variable`, () => + checkFormula(Formula[name](variable, variable, variable), false)); + }); + }); + }); + + describe("Non-Invertible Formulas never marked as having a variable", () => { + function checkFormula(formula: Formula) { + expect(formula.invertible).toBe(false); + expect(formula.hasVariable).toBe(false); + } + nonInvertibleZeroParamFunctionNames.flat().forEach(name => { + describe(name, () => { + test(`${name}(var) is marked as not invertible and not having a variable`, () => + checkFormula(Formula[name](variable))); + }); + }); + nonInvertibleOneParamFunctionNames.flat().forEach(name => { + describe(name, () => { + test(`${name}(var, const) is marked as not invertible and not having a variable`, () => + checkFormula(Formula[name](variable, constant))); + test(`${name}(const, var) is marked as not invertible and not having a variable`, () => + checkFormula(Formula[name](constant, variable))); + test(`${name}(var, var) is marked as not invertible and not having a variable`, () => + checkFormula(Formula[name](variable, variable))); + }); + }); + nonInvertibleTwoParamFunctionNames.flat().forEach(name => { + describe(name, () => { + test(`${name}(var, const, const) is marked as invertible and having a variable`, () => + checkFormula(Formula[name](variable, constant, constant))); + test(`${name}(const, var, const) is marked as invertible and having a variable`, () => + checkFormula(Formula[name](constant, variable, constant))); + test(`${name}(const, const, var) is marked as invertible and having a variable`, () => + checkFormula(Formula[name](constant, constant, variable))); + test(`${name}(var, var, const) is marked as not invertible and not having a variable`, () => + checkFormula(Formula[name](variable, variable, constant))); + test(`${name}(var, const, var) is marked as not invertible and not having a variable`, () => + checkFormula(Formula[name](variable, constant, variable))); + test(`${name}(const, var, var) is marked as not invertible and not having a variable`, () => + checkFormula(Formula[name](constant, variable, variable))); + test(`${name}(var, var, var) is marked as not invertible and not having a variable`, () => + checkFormula(Formula[name](variable, variable, variable))); + }); + }); + }); + }); +});