diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..fe00236 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 3 +trim_trailing_whitespace = true + +[.html] +indent_size = 2 diff --git a/colors.json b/colors.json new file mode 100644 index 0000000..64f1e9f --- /dev/null +++ b/colors.json @@ -0,0 +1,18 @@ +{ + "grid": { + "background": "#000", + "primary": "#0d6efd" + }, + "unit": { + "red": { + "primary": "#c40000", + "active": "#ff6868", + "disabled": "#ff686880" + }, + "blue": { + "primary": "#4e90e6", + "active": "#71afff", + "disabled": "#71afff80" + } + } +} diff --git a/gameConfig.ts b/gameConfig.ts new file mode 100644 index 0000000..e06065f --- /dev/null +++ b/gameConfig.ts @@ -0,0 +1,10 @@ +import { Orientation } from "honeycomb-grid"; + +export default { + hex: { + dimensions: 30, + origin: "topLeft", + orientation: Orientation.FLAT, + }, + fps: 30, +} as const; diff --git a/index.html b/index.html index 3d08438..6ff5e97 100644 --- a/index.html +++ b/index.html @@ -2,12 +2,17 @@ - - Vite App + Battle Simulator -
- +
+
+

+ +
+
+
+ diff --git a/main.js b/main.js deleted file mode 100644 index d2f2a5a..0000000 --- a/main.js +++ /dev/null @@ -1,23 +0,0 @@ -import * as PIXI from 'pixi.js'; -import { defineHex, Grid, rectangle } from 'honeycomb-grid' - -// you may want the origin to be the top left corner of a hex's bounding box -// instead of its center (which is the default) -const Hex = defineHex({ dimensions: 30, origin: 'topLeft' }) -const grid = new Grid(Hex, rectangle({ width: 10, height: 10 })) - -const app = new PIXI.Application({ backgroundAlpha: 0 }) -const graphics = new PIXI.Graphics() - -document.body.appendChild(app.view) -graphics.lineStyle(1, 0x999999) - -grid.forEach(renderHex) -app.stage.addChild(graphics) - -function renderHex(hex) { - // PIXI.Polygon happens to be compatible with hex.corners - graphics.drawShape( - new PIXI.Polygon(hex.corners) - ) -} \ No newline at end of file diff --git a/notes.md b/notes.md new file mode 100644 index 0000000..00d026d --- /dev/null +++ b/notes.md @@ -0,0 +1,28 @@ +Playground Roadmap + +1. [x] Init project with boardgame.io & PIXI.js. +2. [x] Create the board with numbers. +3. [x] Add player and movement. +4. [x] Add multiplayer and win condition (technical back-end). +5. [ ] Add multiple units for each player. +6. [ ] Add icon +7. [ ] Represent powers into HP bar (?) +8. [ ] Push playground into main. + +Multiple Units +Logic: +1. Select which unit to move + 1. Must be your own unit + 2. Must not do an action before +2. Mark the unit as selected in the client +3. Execute an action for the unit + 1. Move + 2. Fight +4. Mark the unit as "done" (already done an action) +5. Loop to (1) until all units have completed an action +6. End Turn, go to another player + +Low Level Logic: +1. Select unit to move + - Set unit ID to activeUnitID +2. diff --git a/package-lock.json b/package-lock.json index 5aff014..78c9a69 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,19 +7,31 @@ "": { "name": "battle-simulator", "version": "0.0.0", - "license": "ISC", "dependencies": { + "boardgame.io": "^0.50.2", "honeycomb-grid": "^4.1.5", - "pixi.js": "^7.3.2" + "pixi.js": "^8.1.6" }, "devDependencies": { - "vite": "^5.0.8" + "typescript": "^5.2.2", + "vite": "^5.2.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", + "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.10.tgz", - "integrity": "sha512-Q+mk96KJ+FZ30h9fsJl+67IjNJm3x2eX+GBWGmocAKgzp27cowCOOqSdscX80s0SpdFXZnIv/+1xD1EctFx96Q==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", "cpu": [ "ppc64" ], @@ -33,9 +45,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.10.tgz", - "integrity": "sha512-7W0bK7qfkw1fc2viBfrtAEkDKHatYfHzr/jKAHNr9BvkYDXPcC6bodtm8AyLJNNuqClLNaeTLuwURt4PRT9d7w==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", "cpu": [ "arm" ], @@ -49,9 +61,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.10.tgz", - "integrity": "sha512-1X4CClKhDgC3by7k8aOWZeBXQX8dHT5QAMCAQDArCLaYfkppoARvh0fit3X2Qs+MXDngKcHv6XXyQCpY0hkK1Q==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", "cpu": [ "arm64" ], @@ -65,9 +77,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.10.tgz", - "integrity": "sha512-O/nO/g+/7NlitUxETkUv/IvADKuZXyH4BHf/g/7laqKC4i/7whLpB0gvpPc2zpF0q9Q6FXS3TS75QHac9MvVWw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", "cpu": [ "x64" ], @@ -81,9 +93,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.10.tgz", - "integrity": "sha512-YSRRs2zOpwypck+6GL3wGXx2gNP7DXzetmo5pHXLrY/VIMsS59yKfjPizQ4lLt5vEI80M41gjm2BxrGZ5U+VMA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", "cpu": [ "arm64" ], @@ -97,9 +109,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.10.tgz", - "integrity": "sha512-alfGtT+IEICKtNE54hbvPg13xGBe4GkVxyGWtzr+yHO7HIiRJppPDhOKq3zstTcVf8msXb/t4eavW3jCDpMSmA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", "cpu": [ "x64" ], @@ -113,9 +125,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.10.tgz", - "integrity": "sha512-dMtk1wc7FSH8CCkE854GyGuNKCewlh+7heYP/sclpOG6Cectzk14qdUIY5CrKDbkA/OczXq9WesqnPl09mj5dg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", "cpu": [ "arm64" ], @@ -129,9 +141,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.10.tgz", - "integrity": "sha512-G5UPPspryHu1T3uX8WiOEUa6q6OlQh6gNl4CO4Iw5PS+Kg5bVggVFehzXBJY6X6RSOMS8iXDv2330VzaObm4Ag==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", "cpu": [ "x64" ], @@ -145,9 +157,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.10.tgz", - "integrity": "sha512-j6gUW5aAaPgD416Hk9FHxn27On28H4eVI9rJ4az7oCGTFW48+LcgNDBN+9f8rKZz7EEowo889CPKyeaD0iw9Kg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", "cpu": [ "arm" ], @@ -161,9 +173,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.10.tgz", - "integrity": "sha512-QxaouHWZ+2KWEj7cGJmvTIHVALfhpGxo3WLmlYfJ+dA5fJB6lDEIg+oe/0//FuyVHuS3l79/wyBxbHr0NgtxJQ==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", "cpu": [ "arm64" ], @@ -177,9 +189,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.10.tgz", - "integrity": "sha512-4ub1YwXxYjj9h1UIZs2hYbnTZBtenPw5NfXCRgEkGb0b6OJ2gpkMvDqRDYIDRjRdWSe/TBiZltm3Y3Q8SN1xNg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", "cpu": [ "ia32" ], @@ -193,9 +205,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.10.tgz", - "integrity": "sha512-lo3I9k+mbEKoxtoIbM0yC/MZ1i2wM0cIeOejlVdZ3D86LAcFXFRdeuZmh91QJvUTW51bOK5W2BznGNIl4+mDaA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", "cpu": [ "loong64" ], @@ -209,9 +221,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.10.tgz", - "integrity": "sha512-J4gH3zhHNbdZN0Bcr1QUGVNkHTdpijgx5VMxeetSk6ntdt+vR1DqGmHxQYHRmNb77tP6GVvD+K0NyO4xjd7y4A==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", "cpu": [ "mips64el" ], @@ -225,9 +237,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.10.tgz", - "integrity": "sha512-tgT/7u+QhV6ge8wFMzaklOY7KqiyitgT1AUHMApau32ZlvTB/+efeCtMk4eXS+uEymYK249JsoiklZN64xt6oQ==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", "cpu": [ "ppc64" ], @@ -241,9 +253,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.10.tgz", - "integrity": "sha512-0f/spw0PfBMZBNqtKe5FLzBDGo0SKZKvMl5PHYQr3+eiSscfJ96XEknCe+JoOayybWUFQbcJTrk946i3j9uYZA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", "cpu": [ "riscv64" ], @@ -257,9 +269,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.10.tgz", - "integrity": "sha512-pZFe0OeskMHzHa9U38g+z8Yx5FNCLFtUnJtQMpwhS+r4S566aK2ci3t4NCP4tjt6d5j5uo4h7tExZMjeKoehAA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", "cpu": [ "s390x" ], @@ -273,9 +285,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.10.tgz", - "integrity": "sha512-SpYNEqg/6pZYoc+1zLCjVOYvxfZVZj6w0KROZ3Fje/QrM3nfvT2llI+wmKSrWuX6wmZeTapbarvuNNK/qepSgA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", "cpu": [ "x64" ], @@ -289,9 +301,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.10.tgz", - "integrity": "sha512-ACbZ0vXy9zksNArWlk2c38NdKg25+L9pr/mVaj9SUq6lHZu/35nx2xnQVRGLrC1KKQqJKRIB0q8GspiHI3J80Q==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", "cpu": [ "x64" ], @@ -305,9 +317,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.10.tgz", - "integrity": "sha512-PxcgvjdSjtgPMiPQrM3pwSaG4kGphP+bLSb+cihuP0LYdZv1epbAIecHVl5sD3npkfYBZ0ZnOjR878I7MdJDFg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", "cpu": [ "x64" ], @@ -321,9 +333,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.10.tgz", - "integrity": "sha512-ZkIOtrRL8SEJjr+VHjmW0znkPs+oJXhlJbNwfI37rvgeMtk3sxOQevXPXjmAPZPigVTncvFqLMd+uV0IBSEzqA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", "cpu": [ "x64" ], @@ -337,9 +349,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.10.tgz", - "integrity": "sha512-+Sa4oTDbpBfGpl3Hn3XiUe4f8TU2JF7aX8cOfqFYMMjXp6ma6NJDztl5FDG8Ezx0OjwGikIHw+iA54YLDNNVfw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", "cpu": [ "arm64" ], @@ -353,9 +365,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.10.tgz", - "integrity": "sha512-EOGVLK1oWMBXgfttJdPHDTiivYSjX6jDNaATeNOaCOFEVcfMjtbx7WVQwPSE1eIfCp/CaSF2nSrDtzc4I9f8TQ==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", "cpu": [ "ia32" ], @@ -369,9 +381,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.10.tgz", - "integrity": "sha512-whqLG6Sc70AbU73fFYvuYzaE4MNMBIlR1Y/IrUeOXFrWHxBEjjbZaQ3IXIQS8wJdAzue2GwYZCjOrgrU1oUHoA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", "cpu": [ "x64" ], @@ -384,43 +396,31 @@ "node": ">=12" } }, - "node_modules/@pixi/accessibility": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/accessibility/-/accessibility-7.3.2.tgz", - "integrity": "sha512-MdkU22HTauRvq9cMeWZIQGaDDa86sr+m12rKNdLV+FaDQgP/AhP+qCVpK7IKeJa9BrWGXaYMw/vueij7HkyDSA==", - "peerDependencies": { - "@pixi/core": "7.3.2", - "@pixi/display": "7.3.2", - "@pixi/events": "7.3.2" - } - }, - "node_modules/@pixi/app": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/app/-/app-7.3.2.tgz", - "integrity": "sha512-3YRFSMvAxDebAz3/JJv+2jzbPkT8cHC0IHmmLRN8krDL1pZV+YjMLgMwN/Oeyv5TSbwNqnrF5su5whNkRaxeZQ==", - "peerDependencies": { - "@pixi/core": "7.3.2", - "@pixi/display": "7.3.2" - } - }, - "node_modules/@pixi/assets": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/assets/-/assets-7.3.2.tgz", - "integrity": "sha512-yteq6ptAxA09EcwU9D9hl7qr5yWIqy+c2PsXkTDkc76vTAwIamLY3KxLq2aR5y1U4L4O6aHFJd26uNhHcuTPmw==", + "node_modules/@koa/cors": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/@koa/cors/-/cors-3.4.3.tgz", + "integrity": "sha512-WPXQUaAeAMVaLTEFpoq3T2O1C+FstkjJnDQqy95Ck1UdILajsRhu6mhJ8H2f4NFPRBoCNN+qywTJfq/gGki5mw==", "dependencies": { - "@types/css-font-loading-module": "^0.0.7" + "vary": "^1.1.2" }, - "peerDependencies": { - "@pixi/core": "7.3.2", - "@pixi/utils": "7.3.2" + "engines": { + "node": ">= 8.0.0" } }, - "node_modules/@pixi/color": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/color/-/color-7.3.2.tgz", - "integrity": "sha512-jur5PvdOtUBEUTjmPudW5qdQq6yYGlVGsi3HyhasJw14bN+GKJwiCKgIsyrsiNL5HBUXmje4ICwQohf6BqKqxA==", + "node_modules/@koa/router": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/@koa/router/-/router-10.1.1.tgz", + "integrity": "sha512-ORNjq5z4EmQPriKbR0ER3k4Gh7YGNhWDL7JBW+8wXDrHLbWYKYSJaOJ9aN06npF5tbTxe2JBOsurpJDAvjiXKw==", + "deprecated": "**IMPORTANT 10x+ PERFORMANCE UPGRADE**: Please upgrade to v12.0.1+ as we have fixed an issue with debuglog causing 10x slower router benchmark performance, see https://github.com/koajs/router/pull/173", "dependencies": { - "@pixi/colord": "^2.9.6" + "debug": "^4.1.1", + "http-errors": "^1.7.3", + "koa-compose": "^4.1.0", + "methods": "^1.1.2", + "path-to-regexp": "^6.1.0" + }, + "engines": { + "node": ">= 8.0.0" } }, "node_modules/@pixi/colord": { @@ -428,311 +428,10 @@ "resolved": "https://registry.npmjs.org/@pixi/colord/-/colord-2.9.6.tgz", "integrity": "sha512-nezytU2pw587fQstUu1AsJZDVEynjskwOL+kibwcdxsMBFqPsFFNA7xl0ii/gXuDi6M0xj3mfRJj8pBSc2jCfA==" }, - "node_modules/@pixi/compressed-textures": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/compressed-textures/-/compressed-textures-7.3.2.tgz", - "integrity": "sha512-J3ENMHDPQO6CJRei55gqI0WmiZJIK6SgsW5AEkShT0aAe5miEBSomv70pXw/58ru+4/Hx8cXjamsGt4aQB2D0Q==", - "peerDependencies": { - "@pixi/assets": "7.3.2", - "@pixi/core": "7.3.2" - } - }, - "node_modules/@pixi/constants": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/constants/-/constants-7.3.2.tgz", - "integrity": "sha512-Q8W3ncsFxmfgC5EtokpG92qJZabd+Dl+pbQAdHwiPY3v+8UNq77u4VN2qtl1Z04864hCcg7AStIYEDrzqTLF6Q==" - }, - "node_modules/@pixi/core": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/core/-/core-7.3.2.tgz", - "integrity": "sha512-Pta3ee8MtJ3yKxGXzglBWgwbEOKMB6Eth+FpLTjL0rgxiqTB550YX6jsNEQQAzcGjCBlO3rC/IF57UZ2go/X6w==", - "dependencies": { - "@pixi/color": "7.3.2", - "@pixi/constants": "7.3.2", - "@pixi/extensions": "7.3.2", - "@pixi/math": "7.3.2", - "@pixi/runner": "7.3.2", - "@pixi/settings": "7.3.2", - "@pixi/ticker": "7.3.2", - "@pixi/utils": "7.3.2", - "@types/offscreencanvas": "^2019.6.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/pixijs" - } - }, - "node_modules/@pixi/display": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/display/-/display-7.3.2.tgz", - "integrity": "sha512-cY5AnZ3TWt5GYGx4e5AQ2/2U9kP+RorBg/O30amJ+8e9bFk9rS8cjh/DDq/hc4lql96BkXAInTl40eHnAML5lQ==", - "peerDependencies": { - "@pixi/core": "7.3.2" - } - }, - "node_modules/@pixi/events": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/events/-/events-7.3.2.tgz", - "integrity": "sha512-Moca9epu8jk1wIQCdVYjhz2pD9Ol21m50wvWUKvpgt9yM/AjkCLSDt8HO/PmTpavDrkhx5pVVWeDDA6FyUNaGA==", - "peerDependencies": { - "@pixi/core": "7.3.2", - "@pixi/display": "7.3.2" - } - }, - "node_modules/@pixi/extensions": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/extensions/-/extensions-7.3.2.tgz", - "integrity": "sha512-Qw84ADfvmVu4Mwj+zTik/IEEK9lWS5n4trbrpQCcEZ+Mb8oRAXWvKz199mi1s7+LaZXDqeCY1yr2PHQaFf1KBA==" - }, - "node_modules/@pixi/extract": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/extract/-/extract-7.3.2.tgz", - "integrity": "sha512-KsoflvQZV/XD8A8xbtRnmI4reYekbI4MOi7ilwQe5tMz6O1mO7IzrSukxkSMD02f6SpbAqbi7a1EayTjvY0ECQ==", - "peerDependencies": { - "@pixi/core": "7.3.2" - } - }, - "node_modules/@pixi/filter-alpha": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/filter-alpha/-/filter-alpha-7.3.2.tgz", - "integrity": "sha512-nZMdn310wH5ZK1slwv3X4qT8eLoAGO7SgYGCy5IsMtpCtNObzE9XA4tAfhXrjihyzPS9KvszgAbnv1Qpfh0/uw==", - "peerDependencies": { - "@pixi/core": "7.3.2" - } - }, - "node_modules/@pixi/filter-blur": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/filter-blur/-/filter-blur-7.3.2.tgz", - "integrity": "sha512-unu3zhwHMhN+iAe7Td2rK40i2UJ2GOhzWK+6jcU3ZkMOsFCT5kgBoMRTejeQVcvCs6GoYK8imbkE7mXt05Vj6A==", - "peerDependencies": { - "@pixi/core": "7.3.2" - } - }, - "node_modules/@pixi/filter-color-matrix": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/filter-color-matrix/-/filter-color-matrix-7.3.2.tgz", - "integrity": "sha512-rbyjes/9SMoV9jjPiK0sLMkmLfN8D17GoTJIfq/KLv1x9646W5fL2QSKkN04UkZ+020ndWvIOxK1S97tvRyCfg==", - "peerDependencies": { - "@pixi/core": "7.3.2" - } - }, - "node_modules/@pixi/filter-displacement": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/filter-displacement/-/filter-displacement-7.3.2.tgz", - "integrity": "sha512-ZHl7Sfb8JYd9Z6j96OHCC0NhMKhhXJRE5AbkSDohjEMVCK1BV5rDGAHV8WVt/2MJ/j83CXUpydzyMhdM4lMchg==", - "peerDependencies": { - "@pixi/core": "7.3.2" - } - }, - "node_modules/@pixi/filter-fxaa": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/filter-fxaa/-/filter-fxaa-7.3.2.tgz", - "integrity": "sha512-9brtlxDnQTZk2XiFBKdBK9e+8CX9LdxxcL7LRpjEyiHuAPvTlQgu9B85LrJ4GzWKqJJKaIIZBzhIoiCLUnfeXg==", - "peerDependencies": { - "@pixi/core": "7.3.2" - } - }, - "node_modules/@pixi/filter-noise": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/filter-noise/-/filter-noise-7.3.2.tgz", - "integrity": "sha512-F8GQQ20n7tCjThX6GCXckiXz2YffOCxicTJ0oat9aVDZh+sVsAxYX0aKSdHh0hhv18F0yuc6tPsSL5DYb63xFg==", - "peerDependencies": { - "@pixi/core": "7.3.2" - } - }, - "node_modules/@pixi/graphics": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-7.3.2.tgz", - "integrity": "sha512-PhU6j1yub4tH/s+/gqByzgZ3mLv1mfb6iGXbquycg3+WypcxHZn0opFtI/axsazaQ9SEaWxw1m3i40WG5ANH5g==", - "peerDependencies": { - "@pixi/core": "7.3.2", - "@pixi/display": "7.3.2", - "@pixi/sprite": "7.3.2" - } - }, - "node_modules/@pixi/math": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/math/-/math-7.3.2.tgz", - "integrity": "sha512-dutoZ0IVJ5ME7UtYNo2szu4D7qsgtJB7e3ylujBVu7BOP2e710BVtFwFSFV768N14h9H5roGnuzVoDiJac2u+w==" - }, - "node_modules/@pixi/mesh": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/mesh/-/mesh-7.3.2.tgz", - "integrity": "sha512-LFkt7ELYXQLgbgHpjl68j6JD5ejUwma8zoPn2gqSBbY+6pK/phjvV1Wkh76muF46VvNulgXF0+qLIDdCsfrDaA==", - "peerDependencies": { - "@pixi/core": "7.3.2", - "@pixi/display": "7.3.2" - } - }, - "node_modules/@pixi/mesh-extras": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/mesh-extras/-/mesh-extras-7.3.2.tgz", - "integrity": "sha512-s/tg9TsTZZxLEdCDKWnBChDGkc041HCTP7ykJv4fEROzb9B0lskULYyvv+/YNNKa2Ugb9WnkMknpOdOXCpjyyg==", - "peerDependencies": { - "@pixi/core": "7.3.2", - "@pixi/mesh": "7.3.2" - } - }, - "node_modules/@pixi/mixin-cache-as-bitmap": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/mixin-cache-as-bitmap/-/mixin-cache-as-bitmap-7.3.2.tgz", - "integrity": "sha512-bZRlyUN5+9kCUjn67V0IFtYIrbmx9Vs4sMOmXyrX3Q4B4gPLE46IzZz3v0IVaTjp32udlQztfJalIaWbuqgb3A==", - "peerDependencies": { - "@pixi/core": "7.3.2", - "@pixi/display": "7.3.2", - "@pixi/sprite": "7.3.2" - } - }, - "node_modules/@pixi/mixin-get-child-by-name": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/mixin-get-child-by-name/-/mixin-get-child-by-name-7.3.2.tgz", - "integrity": "sha512-mbUi3WxXrkViH7qOgjk4fu2BN36NwNb7u+Fy1J5dS8Bntj57ZVKmEV9PbUy0zYjXE8rVmeAvSu/2kbn5n9UutQ==", - "peerDependencies": { - "@pixi/display": "7.3.2" - } - }, - "node_modules/@pixi/mixin-get-global-position": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/mixin-get-global-position/-/mixin-get-global-position-7.3.2.tgz", - "integrity": "sha512-1nhWbBgmw6rK7yQJxzeI9yjKYYEkM5i3pee8qVu4YWo3b1xWVQA7osQG7aGM/4qywDkXaA1ZvciA5hfg6f4Q5Q==", - "peerDependencies": { - "@pixi/core": "7.3.2", - "@pixi/display": "7.3.2" - } - }, - "node_modules/@pixi/particle-container": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/particle-container/-/particle-container-7.3.2.tgz", - "integrity": "sha512-JYc4j4z97KmxyLp+1Lg0SNi8hy6RxcBBNQGk+CSLNXeDWxx3hykT5gj/ORX1eXyzHh1ZCG1XzeVS9Yr8QhlFHA==", - "peerDependencies": { - "@pixi/core": "7.3.2", - "@pixi/display": "7.3.2", - "@pixi/sprite": "7.3.2" - } - }, - "node_modules/@pixi/prepare": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/prepare/-/prepare-7.3.2.tgz", - "integrity": "sha512-aLPAXSYLUhMwxzJtn9m0TSZe+dQlZCt09QNBqYbSi8LZId54QMDyvfBb4zBOJZrD2xAZgYL5RIJuKHwZtFX6lQ==", - "peerDependencies": { - "@pixi/core": "7.3.2", - "@pixi/display": "7.3.2", - "@pixi/graphics": "7.3.2", - "@pixi/text": "7.3.2" - } - }, - "node_modules/@pixi/runner": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-7.3.2.tgz", - "integrity": "sha512-maKotoKJCQiQGBJwfM+iYdQKjrPN/Tn9+72F4WIf706zp/5vKoxW688Rsktg5BX4Mcn7ZkZvcJYTxj2Mv87lFA==" - }, - "node_modules/@pixi/settings": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-7.3.2.tgz", - "integrity": "sha512-vtxzuARDTbFe0fRYSqB53B+mPpX7v+QjjnCUmVMVvZiWr3QcngMWVml6c6dQDln7IakWoKZRrNG4FpggvDgLVg==", - "dependencies": { - "@pixi/constants": "7.3.2", - "@types/css-font-loading-module": "^0.0.7", - "ismobilejs": "^1.1.0" - } - }, - "node_modules/@pixi/sprite": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-7.3.2.tgz", - "integrity": "sha512-IpWTKXExJNXVcY7ITopJ+JW48DahdbCo/81D2IYzBImq3jyiJM2Km5EoJgvAM5ZQ3Ev3KPPIBzYLD+HoPWcxdw==", - "peerDependencies": { - "@pixi/core": "7.3.2", - "@pixi/display": "7.3.2" - } - }, - "node_modules/@pixi/sprite-animated": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/sprite-animated/-/sprite-animated-7.3.2.tgz", - "integrity": "sha512-j9pyUe4cefxE9wecNfbWQyL5fBQKvCGYaOA0DE1X46ukBHrIuhA8u3jg2X3N3r4IcbVvxpWFYDrDsWXWeiBmSw==", - "peerDependencies": { - "@pixi/core": "7.3.2", - "@pixi/sprite": "7.3.2" - } - }, - "node_modules/@pixi/sprite-tiling": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/sprite-tiling/-/sprite-tiling-7.3.2.tgz", - "integrity": "sha512-tWVVb/rMIx5AczfUrVxa0dZaIufP5C0IOL7IGfFUDQqDu5JSAUC0mwLe4F12jAXBVsqYhCGYx5bIHbPiI5vcSQ==", - "peerDependencies": { - "@pixi/core": "7.3.2", - "@pixi/display": "7.3.2", - "@pixi/sprite": "7.3.2" - } - }, - "node_modules/@pixi/spritesheet": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/spritesheet/-/spritesheet-7.3.2.tgz", - "integrity": "sha512-UkwqrPYDqrEdK5ub9qn/9VBvt5caA8ffV5iYR6ssCvrpaQovBKmS+b5pr/BYf8xNTExDpR3OmPIo8iDEYWWLuw==", - "peerDependencies": { - "@pixi/assets": "7.3.2", - "@pixi/core": "7.3.2" - } - }, - "node_modules/@pixi/text": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/text/-/text-7.3.2.tgz", - "integrity": "sha512-LdtNj+K5tPB/0UcDcO52M/C7xhwFTGFhtdF42fPhRuJawM23M3zm1Y8PapXv+mury+IxCHT1w30YlAi0qTVpKQ==", - "peerDependencies": { - "@pixi/core": "7.3.2", - "@pixi/sprite": "7.3.2" - } - }, - "node_modules/@pixi/text-bitmap": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/text-bitmap/-/text-bitmap-7.3.2.tgz", - "integrity": "sha512-p8KLgtZSPowWU/Zj+GVtfsUT8uGYo4TtKKYbLoWuxkRA5Pc1+4C9/rV/EOSFfoZIdW5C+iFg5VxRgBllUQf+aA==", - "peerDependencies": { - "@pixi/assets": "7.3.2", - "@pixi/core": "7.3.2", - "@pixi/display": "7.3.2", - "@pixi/mesh": "7.3.2", - "@pixi/text": "7.3.2" - } - }, - "node_modules/@pixi/text-html": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/text-html/-/text-html-7.3.2.tgz", - "integrity": "sha512-IYhBWEPOvqUtlHkS5/c1Hseuricj5jrrGd21ivcvHmcnK/x2m+CRGvvzeBp1mqoYBnDbQVrD2wSXSe4Dv9tEJA==", - "peerDependencies": { - "@pixi/core": "7.3.2", - "@pixi/display": "7.3.2", - "@pixi/sprite": "7.3.2", - "@pixi/text": "7.3.2" - } - }, - "node_modules/@pixi/ticker": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-7.3.2.tgz", - "integrity": "sha512-5kIPhBeXwDJohCzKzJJ6T7f1oAGbHAgeiwOjlTO+9lNXUX8ZPj0407V3syuF+64kFqJzIBCznBRpI+fmT4c9SA==", - "dependencies": { - "@pixi/extensions": "7.3.2", - "@pixi/settings": "7.3.2", - "@pixi/utils": "7.3.2" - } - }, - "node_modules/@pixi/utils": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-7.3.2.tgz", - "integrity": "sha512-KhNvj9YcY7Zi2dTKZgDpx8C6OxKKR541vwtG6JgdBZZYDeMBOIghN2Vi5zn4diW5BhDfHBmdSJ1wZXEtE2MDwg==", - "dependencies": { - "@pixi/color": "7.3.2", - "@pixi/constants": "7.3.2", - "@pixi/settings": "7.3.2", - "@types/earcut": "^2.1.0", - "earcut": "^2.2.4", - "eventemitter3": "^4.0.0", - "url": "^0.11.0" - } - }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.1.tgz", - "integrity": "sha512-6vMdBZqtq1dVQ4CWdhFwhKZL6E4L1dV6jUjuBvsavvNJSppzi6dLBbuV+3+IyUREaj9ZFvQefnQm28v4OCXlig==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz", + "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==", "cpu": [ "arm" ], @@ -743,9 +442,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.9.1.tgz", - "integrity": "sha512-Jto9Fl3YQ9OLsTDWtLFPtaIMSL2kwGyGoVCmPC8Gxvym9TCZm4Sie+cVeblPO66YZsYH8MhBKDMGZ2NDxuk/XQ==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz", + "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==", "cpu": [ "arm64" ], @@ -756,9 +455,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.9.1.tgz", - "integrity": "sha512-LtYcLNM+bhsaKAIGwVkh5IOWhaZhjTfNOkGzGqdHvhiCUVuJDalvDxEdSnhFzAn+g23wgsycmZk1vbnaibZwwA==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz", + "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==", "cpu": [ "arm64" ], @@ -769,9 +468,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.9.1.tgz", - "integrity": "sha512-KyP/byeXu9V+etKO6Lw3E4tW4QdcnzDG/ake031mg42lob5tN+5qfr+lkcT/SGZaH2PdW4Z1NX9GHEkZ8xV7og==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz", + "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==", "cpu": [ "x64" ], @@ -782,9 +481,22 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.9.1.tgz", - "integrity": "sha512-Yqz/Doumf3QTKplwGNrCHe/B2p9xqDghBZSlAY0/hU6ikuDVQuOUIpDP/YcmoT+447tsZTmirmjgG3znvSCR0Q==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz", + "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz", + "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==", "cpu": [ "arm" ], @@ -795,9 +507,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.9.1.tgz", - "integrity": "sha512-u3XkZVvxcvlAOlQJ3UsD1rFvLWqu4Ef/Ggl40WAVCuogf4S1nJPHh5RTgqYFpCOvuGJ7H5yGHabjFKEZGExk5Q==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz", + "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==", "cpu": [ "arm64" ], @@ -808,9 +520,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.9.1.tgz", - "integrity": "sha512-0XSYN/rfWShW+i+qjZ0phc6vZ7UWI8XWNz4E/l+6edFt+FxoEghrJHjX1EY/kcUGCnZzYYRCl31SNdfOi450Aw==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz", + "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==", "cpu": [ "arm64" ], @@ -820,10 +532,23 @@ "linux" ] }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz", + "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.9.1.tgz", - "integrity": "sha512-LmYIO65oZVfFt9t6cpYkbC4d5lKHLYv5B4CSHRpnANq0VZUQXGcCPXHzbCXCz4RQnx7jvlYB1ISVNCE/omz5cw==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz", + "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==", "cpu": [ "riscv64" ], @@ -833,10 +558,23 @@ "linux" ] }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz", + "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.1.tgz", - "integrity": "sha512-kr8rEPQ6ns/Lmr/hiw8sEVj9aa07gh1/tQF2Y5HrNCCEPiCBGnBUt9tVusrcBBiJfIt1yNaXN6r1CCmpbFEDpg==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", + "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==", "cpu": [ "x64" ], @@ -847,9 +585,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.9.1.tgz", - "integrity": "sha512-t4QSR7gN+OEZLG0MiCgPqMWZGwmeHhsM4AkegJ0Kiy6TnJ9vZ8dEIwHw1LcZKhbHxTY32hp9eVCMdR3/I8MGRw==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz", + "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==", "cpu": [ "x64" ], @@ -860,9 +598,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.9.1.tgz", - "integrity": "sha512-7XI4ZCBN34cb+BH557FJPmh0kmNz2c25SCQeT9OiFWEgf8+dL6ZwJ8f9RnUIit+j01u07Yvrsuu1rZGxJCc51g==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz", + "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==", "cpu": [ "arm64" ], @@ -873,9 +611,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.9.1.tgz", - "integrity": "sha512-yE5c2j1lSWOH5jp+Q0qNL3Mdhr8WuqCNVjc6BxbVfS5cAS6zRmdiw7ktb8GNpDCEUJphILY6KACoFoRtKoqNQg==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz", + "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==", "cpu": [ "ia32" ], @@ -886,9 +624,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.9.1.tgz", - "integrity": "sha512-PyJsSsafjmIhVgaI1Zdj7m8BB8mMckFah/xbpplObyHfiXzKcI5UOUXRyOdHW7nz4DpMCuzLnF7v5IWHenCwYA==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz", + "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==", "cpu": [ "x64" ], @@ -898,204 +636,1096 @@ "win32" ] }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==" + }, + "node_modules/@types/accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/component-emitter": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.14.tgz", + "integrity": "sha512-lmPil1g82wwWg/qHSxMWkSKyJGQOK+ejXeMAAWyxNtVUD0/Ycj2maL63RAqpxVfdtvTfZkRnqzB0A9ft59y69g==" + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/content-disposition": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.8.tgz", + "integrity": "sha512-QVSSvno3dE0MgO76pJhmv4Qyi/j0Yk9pBp0Y7TJ2Tlj+KCgJWY6qX7nnxCOLkZ3VYRSIk1WTxCvwUSdx6CCLdg==" + }, + "node_modules/@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" + }, + "node_modules/@types/cookies": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.9.0.tgz", + "integrity": "sha512-40Zk8qR147RABiQ7NQnBzWzDcjKzNrntB5BAmeGCb2p/MIyOE+4BVvc17wumsUqUw00bJYqoXFHYygQnEFh4/Q==", + "dependencies": { + "@types/connect": "*", + "@types/express": "*", + "@types/keygrip": "*", + "@types/node": "*" + } + }, + "node_modules/@types/cors": { + "version": "2.8.17", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", + "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/css-font-loading-module": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/@types/css-font-loading-module/-/css-font-loading-module-0.0.7.tgz", - "integrity": "sha512-nl09VhutdjINdWyXxHWN/w9zlNCfr60JUqJbd24YXUuCwgeL0TpFSdElCwb6cxfB6ybE19Gjj4g0jsgkXxKv1Q==" + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/@types/css-font-loading-module/-/css-font-loading-module-0.0.12.tgz", + "integrity": "sha512-x2tZZYkSxXqWvTDgveSynfjq/T2HyiZHXb00j/+gy19yp70PHCizM48XFdjBCWH7eHBD0R5i/pw9yMBP/BH5uA==" }, "node_modules/@types/earcut": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@types/earcut/-/earcut-2.1.4.tgz", "integrity": "sha512-qp3m9PPz4gULB9MhjGID7wpo3gJ4bTGXm7ltNDsmOvsPduTeHp8wSW9YckBj3mljeOh4F0m2z/0JKAALRKbmLQ==" }, - "node_modules/@types/offscreencanvas": { - "version": "2019.7.3", - "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.3.tgz", - "integrity": "sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A==" - }, - "node_modules/call-bind": { + "node_modules/@types/estree": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", "dependencies": { - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" } }, - "node_modules/define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "node_modules/@types/express-serve-static-core": { + "version": "4.19.3", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.3.tgz", + "integrity": "sha512-KOzM7MhcBFlmnlr/fzISFF5vGWVSvN6fTd4T+ExOt08bA/dA5kpSzY52nMsI1KDFmUREpJelPYyuslLRSjjgCg==", "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" } }, - "node_modules/earcut": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz", - "integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==" - }, - "node_modules/esbuild": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.10.tgz", - "integrity": "sha512-S1Y27QGt/snkNYrRcswgRFqZjaTG5a5xM3EQo97uNBnH505pdzSNe/HLBq1v0RO7iK/ngdbhJB6mDAp0OK+iUA==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.19.10", - "@esbuild/android-arm": "0.19.10", - "@esbuild/android-arm64": "0.19.10", - "@esbuild/android-x64": "0.19.10", - "@esbuild/darwin-arm64": "0.19.10", - "@esbuild/darwin-x64": "0.19.10", - "@esbuild/freebsd-arm64": "0.19.10", - "@esbuild/freebsd-x64": "0.19.10", - "@esbuild/linux-arm": "0.19.10", - "@esbuild/linux-arm64": "0.19.10", - "@esbuild/linux-ia32": "0.19.10", - "@esbuild/linux-loong64": "0.19.10", - "@esbuild/linux-mips64el": "0.19.10", - "@esbuild/linux-ppc64": "0.19.10", - "@esbuild/linux-riscv64": "0.19.10", - "@esbuild/linux-s390x": "0.19.10", - "@esbuild/linux-x64": "0.19.10", - "@esbuild/netbsd-x64": "0.19.10", - "@esbuild/openbsd-x64": "0.19.10", - "@esbuild/sunos-x64": "0.19.10", - "@esbuild/win32-arm64": "0.19.10", - "@esbuild/win32-ia32": "0.19.10", - "@esbuild/win32-x64": "0.19.10" + "node_modules/@types/formidable": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/formidable/-/formidable-2.0.6.tgz", + "integrity": "sha512-L4HcrA05IgQyNYJj6kItuIkXrInJvsXTPC5B1i64FggWKKqSL+4hgt7asiSNva75AoLQjq29oPxFfU4GAQ6Z2w==", + "dependencies": { + "@types/node": "*" } }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + "node_modules/@types/http-assert": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.5.tgz", + "integrity": "sha512-4+tE/lwdAahgZT1g30Jkdm9PzFRde0xwxBNUyRsCitRvCQB90iuA2uJYdUnhnANRcqGXaWOGY4FEoxeElNAK2g==" }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/@types/keygrip": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.6.tgz", + "integrity": "sha512-lZuNAY9xeJt7Bx4t4dx0rYCDqGPW8RXhQZK1td7d4H6E9zYbLoOtjBvfwdTKpsyxQI/2jv+armjX/RW+ZNpXOQ==" + }, + "node_modules/@types/koa": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.15.0.tgz", + "integrity": "sha512-7QFsywoE5URbuVnG3loe03QXuGajrnotr3gQkXcEBShORai23MePfFYdhz90FEtBBpkyIYQbVD+evKtloCgX3g==", + "dependencies": { + "@types/accepts": "*", + "@types/content-disposition": "*", + "@types/cookies": "*", + "@types/http-assert": "*", + "@types/http-errors": "*", + "@types/keygrip": "*", + "@types/koa-compose": "*", + "@types/node": "*" + } + }, + "node_modules/@types/koa__router": { + "version": "8.0.11", + "resolved": "https://registry.npmjs.org/@types/koa__router/-/koa__router-8.0.11.tgz", + "integrity": "sha512-WXgKWpBsbS14kzmzD9LeFapOIa678h7zvUHxDwXwSx4ETKXhXLVUAToX6jZ/U7EihM7qwyD9W/BZvB0MRu7MTQ==", + "dependencies": { + "@types/koa": "*" } }, - "node_modules/get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "node_modules/@types/koa-compose": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@types/koa-compose/-/koa-compose-3.2.8.tgz", + "integrity": "sha512-4Olc63RY+MKvxMwVknCUDhRQX1pFQoBZ/lXcRLP69PQkEpze/0cr8LNqJQe5NFb/b19DWi2a5bTi2VAlQzhJuA==", "dependencies": { - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@types/koa": "*" } }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + }, + "node_modules/@types/node": { + "version": "20.14.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz", + "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==", "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "undici-types": "~5.26.4" } }, - "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "node_modules/@types/qs": { + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", "dependencies": { - "get-intrinsic": "^1.2.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@types/mime": "^1", + "@types/node": "*" } }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" } }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "node_modules/@webgpu/types": { + "version": "0.1.42", + "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.42.tgz", + "integrity": "sha512-uvJtt4OD1Vjdebrrz3kNLgpOicYbikwnM8WPG6YD2lkCOHDtPdEtCINJFIFtbOCtPfA8SreR/vKyUNbAt92IwQ==" + }, + "node_modules/@xmldom/xmldom": { + "version": "0.8.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", + "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=10.0.0" } }, - "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dependencies": { - "function-bind": "^1.1.2" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" }, "engines": { - "node": ">= 0.4" + "node": ">= 0.6" } }, - "node_modules/honeycomb-grid": { - "version": "4.1.5", + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + }, + "node_modules/base64-arraybuffer": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", + "integrity": "sha512-a1eIFi4R9ySrbiMuyTGx5e92uRH5tQY6kArNcFaKBUleIoLjdjBg7Zxm3Mqm3Kmkf27HLR/1fnxX9q8GQ7Iavg==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, + "node_modules/boardgame.io": { + "version": "0.50.2", + "resolved": "https://registry.npmjs.org/boardgame.io/-/boardgame.io-0.50.2.tgz", + "integrity": "sha512-oEcgtiDidTk2Mvweg3issGxOxMwOTTPlkHMoLexQ0LTQJXl60P3vA026SLYy313nrHM6s/vK7qE7TavMFxyC0g==", + "funding": [ + "https://github.com/boardgameio/boardgame.io?sponsor=1", + { + "type": "opencollective", + "url": "https://opencollective.com/boardgameio" + } + ], + "dependencies": { + "@koa/cors": "^3.1.0", + "@koa/router": "^10.1.1", + "@types/koa": "^2.13.4", + "@types/koa__router": "^8.0.8", + "flatted": "^3.2.1", + "immer": "^9.0.5", + "koa": "^2.13.3", + "koa-body": "^5.0.0", + "koa-socket-2": "^2.0.0", + "lodash.isplainobject": "^4.0.6", + "nanoid": "^3.1.30", + "p-queue": "^6.6.2", + "prop-types": "^15.5.10", + "react-cookies": "^0.1.0", + "redux": "^4.1.0", + "rfc6902": "^5.0.0", + "setimmediate": "^1.0.5", + "socket.io": "^4.5.0", + "socket.io-client": "^4.1.3", + "svelte": "^3.41.0", + "svelte-json-tree-auto": "^0.1.0", + "ts-toolbelt": "^6.3.6" + }, + "engines": { + "node": ">=10.0", + "npm": ">=6.0" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cache-content-type": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-content-type/-/cache-content-type-1.0.1.tgz", + "integrity": "sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==", + "dependencies": { + "mime-types": "^2.1.18", + "ylru": "^1.2.0" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/co-body": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/co-body/-/co-body-5.2.0.tgz", + "integrity": "sha512-sX/LQ7LqUhgyaxzbe7IqwPeTr2yfpfUIQ/dgpKo6ZI4y4lpQA0YxAomWIY+7I7rHWcG02PG+OuPREzMW/5tszQ==", + "dependencies": { + "inflation": "^2.0.0", + "qs": "^6.4.0", + "raw-body": "^2.2.0", + "type-is": "^1.6.14" + } + }, + "node_modules/component-emitter": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha512-+IJOX0OqlHCszo2mBUq+SrEbCj6w7Kpffqx60zYbPTFaO4+yYgRjHwcZNpWvaTylDHaV7PPmBHzSecZiMhtPgw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookies": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.9.1.tgz", + "integrity": "sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==", + "dependencies": { + "depd": "~2.0.0", + "keygrip": "~1.1.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cookies/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==" + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" + }, + "node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/dezalgo": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", + "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", + "dependencies": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, + "node_modules/earcut": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz", + "integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/engine.io": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.4.tgz", + "integrity": "sha512-KdVSDKhVKyOi+r5uEabrDLZw2qXStVvCsEB/LN3mw4WFi6Gx50jTyuxYVCwAAC0U46FdnzP/ScKRBTXb/NiEOg==", + "dependencies": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.11.0" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/engine.io-client": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.3.tgz", + "integrity": "sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.11.0", + "xmlhttprequest-ssl": "~2.0.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz", + "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io/node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==" + }, + "node_modules/formidable": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz", + "integrity": "sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==", + "dependencies": { + "dezalgo": "^1.0.4", + "hexoid": "^1.0.0", + "once": "^1.4.0", + "qs": "^6.11.0" + }, + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hexoid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", + "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==", + "engines": { + "node": ">=8" + } + }, + "node_modules/honeycomb-grid": { + "version": "4.1.5", "resolved": "https://registry.npmjs.org/honeycomb-grid/-/honeycomb-grid-4.1.5.tgz", "integrity": "sha512-VrnQwu5dHuzqK3wFhLD9EURmLSyEWb0teiHhDJq6WdK0MrFsEtKNYT1HLzXOLe2X1acU8Y9hhK7wWfIiGK1G5w==", "engines": { - "node": ">=16" + "node": ">=16" + } + }, + "node_modules/http-assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.5.0.tgz", + "integrity": "sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==", + "dependencies": { + "deep-equal": "~1.0.1", + "http-errors": "~1.8.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/immer": { + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/inflation": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/inflation/-/inflation-2.1.0.tgz", + "integrity": "sha512-t54PPJHG1Pp7VQvxyVCJ9mBbjG3Hqryges9bXoOO6GExCPa+//i/d5GSuFtpx3ALLd7lgIAur6zrIlBQyJuMlQ==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ismobilejs": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ismobilejs/-/ismobilejs-1.1.1.tgz", + "integrity": "sha512-VaFW53yt8QO61k2WJui0dHf4SlL8lxBofUuUmwBo0ljPk0Drz2TiuDW4jo3wDcv41qy/SxrJ+VAzJ/qYqsmzRw==" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/keygrip": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz", + "integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==", + "dependencies": { + "tsscmp": "1.0.6" + }, + "engines": { + "node": ">= 0.6" } }, - "node_modules/ismobilejs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ismobilejs/-/ismobilejs-1.1.1.tgz", - "integrity": "sha512-VaFW53yt8QO61k2WJui0dHf4SlL8lxBofUuUmwBo0ljPk0Drz2TiuDW4jo3wDcv41qy/SxrJ+VAzJ/qYqsmzRw==" + "node_modules/koa": { + "version": "2.15.3", + "resolved": "https://registry.npmjs.org/koa/-/koa-2.15.3.tgz", + "integrity": "sha512-j/8tY9j5t+GVMLeioLaxweJiKUayFhlGqNTzf2ZGwL0ZCQijd2RLHK0SLW5Tsko8YyyqCZC2cojIb0/s62qTAg==", + "dependencies": { + "accepts": "^1.3.5", + "cache-content-type": "^1.0.0", + "content-disposition": "~0.5.2", + "content-type": "^1.0.4", + "cookies": "~0.9.0", + "debug": "^4.3.2", + "delegates": "^1.0.0", + "depd": "^2.0.0", + "destroy": "^1.0.4", + "encodeurl": "^1.0.2", + "escape-html": "^1.0.3", + "fresh": "~0.5.2", + "http-assert": "^1.3.0", + "http-errors": "^1.6.3", + "is-generator-function": "^1.0.7", + "koa-compose": "^4.1.0", + "koa-convert": "^2.0.0", + "on-finished": "^2.3.0", + "only": "~0.0.2", + "parseurl": "^1.3.2", + "statuses": "^1.5.0", + "type-is": "^1.6.16", + "vary": "^1.1.2" + }, + "engines": { + "node": "^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4" + } + }, + "node_modules/koa-body": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/koa-body/-/koa-body-5.0.0.tgz", + "integrity": "sha512-nHwEODrQGiyKBILCWO8QSS40C87cKr2cp3y/Cw8u9Z8w5t0CdSkGm3+y9WK5BIAlPpo9tTw5RtSbxpVyG79vmw==", + "dependencies": { + "@types/formidable": "^2.0.4", + "co-body": "^5.1.1", + "formidable": "^2.0.1" + } + }, + "node_modules/koa-compose": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-4.1.0.tgz", + "integrity": "sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==" + }, + "node_modules/koa-convert": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/koa-convert/-/koa-convert-2.0.0.tgz", + "integrity": "sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA==", + "dependencies": { + "co": "^4.6.0", + "koa-compose": "^4.1.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/koa-socket-2": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/koa-socket-2/-/koa-socket-2-2.0.0.tgz", + "integrity": "sha512-YSy9nYtd4/CR9bChAeL9/3lb17ietphRFgNTAwOkhrCOHFZuOPv+dMORK3sxSJygiIqH5ugJyc2/4Ek1Hc5eVA==", + "dependencies": { + "koa-compose": "^4.1.0", + "socket.io": "^3.0.2" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/koa-socket-2/node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/koa-socket-2/node_modules/engine.io": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.1.2.tgz", + "integrity": "sha512-t5z6zjXuVLhXDMiFJPYsPOWEER8B0tIsD3ETgw19S1yg9zryvUfY3Vhtk3Gf4sihw/bQGIqQ//gjvVlu+Ca0bQ==", + "dependencies": { + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~4.0.0", + "ws": "~7.4.2" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/koa-socket-2/node_modules/engine.io-parser": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.3.tgz", + "integrity": "sha512-xEAAY0msNnESNPc00e19y5heTPX4y/TJ36gr8t1voOaNmTojP9b3oK3BbJLFufW2XFPQaaijpFewm2g2Um3uqA==", + "dependencies": { + "base64-arraybuffer": "0.1.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/koa-socket-2/node_modules/socket.io": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.1.2.tgz", + "integrity": "sha512-JubKZnTQ4Z8G4IZWtaAZSiRP3I/inpy8c/Bsx2jrwGrTbKeVU5xd6qkKMHpChYeM3dWZSO0QACiGK+obhBNwYw==", + "dependencies": { + "@types/cookie": "^0.4.0", + "@types/cors": "^2.8.8", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "debug": "~4.3.1", + "engine.io": "~4.1.0", + "socket.io-adapter": "~2.1.0", + "socket.io-parser": "~4.0.3" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/koa-socket-2/node_modules/socket.io-adapter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz", + "integrity": "sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg==" + }, + "node_modules/koa-socket-2/node_modules/socket.io-parser": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.5.tgz", + "integrity": "sha512-sNjbT9dX63nqUFIOv95tTVm6elyIU4RvB1m8dOeZt+IgWwcWklFDOdmGcfo3zSiRsnR/3pJkjY5lfoGqEe4Eig==", + "dependencies": { + "@types/component-emitter": "^1.2.10", + "component-emitter": "~1.3.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/koa-socket-2/node_modules/ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/koa/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/nanoid": { "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true, "funding": [ { "type": "github", @@ -1109,6 +1739,22 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", @@ -1117,57 +1763,113 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/picocolors": { + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/only": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/only/-/only-0.0.2.tgz", + "integrity": "sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ==" + }, + "node_modules/p-finally": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "engines": { + "node": ">=4" + } }, - "node_modules/pixi.js": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/pixi.js/-/pixi.js-7.3.2.tgz", - "integrity": "sha512-GJickUrT3UcBInGT1CU6cv2oktCdocE5QM74CD3t+weiJPPWIzleNlp7zrBR5QIDdU6bEO8CUgUXH2Y9QvlCMw==", - "dependencies": { - "@pixi/accessibility": "7.3.2", - "@pixi/app": "7.3.2", - "@pixi/assets": "7.3.2", - "@pixi/compressed-textures": "7.3.2", - "@pixi/core": "7.3.2", - "@pixi/display": "7.3.2", - "@pixi/events": "7.3.2", - "@pixi/extensions": "7.3.2", - "@pixi/extract": "7.3.2", - "@pixi/filter-alpha": "7.3.2", - "@pixi/filter-blur": "7.3.2", - "@pixi/filter-color-matrix": "7.3.2", - "@pixi/filter-displacement": "7.3.2", - "@pixi/filter-fxaa": "7.3.2", - "@pixi/filter-noise": "7.3.2", - "@pixi/graphics": "7.3.2", - "@pixi/mesh": "7.3.2", - "@pixi/mesh-extras": "7.3.2", - "@pixi/mixin-cache-as-bitmap": "7.3.2", - "@pixi/mixin-get-child-by-name": "7.3.2", - "@pixi/mixin-get-global-position": "7.3.2", - "@pixi/particle-container": "7.3.2", - "@pixi/prepare": "7.3.2", - "@pixi/sprite": "7.3.2", - "@pixi/sprite-animated": "7.3.2", - "@pixi/sprite-tiling": "7.3.2", - "@pixi/spritesheet": "7.3.2", - "@pixi/text": "7.3.2", - "@pixi/text-bitmap": "7.3.2", - "@pixi/text-html": "7.3.2" + "node_modules/p-queue": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "dependencies": { + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + }, + "engines": { + "node": ">=8" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/pixijs" + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/parse-svg-path": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz", + "integrity": "sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ==" + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", + "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==" + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true + }, + "node_modules/pixi.js": { + "version": "8.1.6", + "resolved": "https://registry.npmjs.org/pixi.js/-/pixi.js-8.1.6.tgz", + "integrity": "sha512-FZT/dLZ9Tdw8eN6odgunSQHORsgHcvLlfOWm7cpR4ZxVGPRqFgDQ4hXpwVxeY9UK4PZtlJ4U910H1QZ4XNLJxg==", + "dependencies": { + "@pixi/colord": "^2.9.6", + "@types/css-font-loading-module": "^0.0.12", + "@types/earcut": "^2.1.4", + "@webgpu/types": "^0.1.40", + "@xmldom/xmldom": "^0.8.10", + "earcut": "^2.2.4", + "eventemitter3": "^5.0.1", + "ismobilejs": "^1.1.1", + "parse-svg-path": "^0.1.2" } }, + "node_modules/pixi.js/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + }, "node_modules/postcss": { - "version": "8.4.32", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz", - "integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==", + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", "dev": true, "funding": [ { @@ -1186,23 +1888,28 @@ "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "source-map-js": "^1.2.0" }, "engines": { "node": "^10 || ^12 || >=14" } }, - "node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } }, "node_modules/qs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", - "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "version": "6.12.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.1.tgz", + "integrity": "sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==", "dependencies": { - "side-channel": "^1.0.4" + "side-channel": "^1.0.6" }, "engines": { "node": ">=0.6" @@ -1211,11 +1918,91 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/react-cookies": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/react-cookies/-/react-cookies-0.1.1.tgz", + "integrity": "sha512-PP75kJ4vtoHuuTdq0TAD3RmlAv7vuDQh9fkC4oDlhntgs9vX1DmREomO0Y1mcQKR9nMZ6/zxoflaMJ3MAmF5KQ==", + "dependencies": { + "cookie": "^0.3.1", + "object-assign": "^4.1.1" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/rfc6902": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/rfc6902/-/rfc6902-5.1.1.tgz", + "integrity": "sha512-8rKImbe8GTXJ7cl9v+sF3U0WQ9aaSBn4fEcGP1VJakWN335ufj75ctvWXEhrzecGRxXpY6pEFbcdWzesjV7bFg==" + }, "node_modules/rollup": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.9.1.tgz", - "integrity": "sha512-pgPO9DWzLoW/vIhlSoDByCzcpX92bKEorbgXuZrqxByte3JFk2xSW2JEeAcyLc9Ru9pqcNNW+Ob7ntsk2oT/Xw==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz", + "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==", "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, "bin": { "rollup": "dist/bin/rollup" }, @@ -1224,76 +2011,250 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.9.1", - "@rollup/rollup-android-arm64": "4.9.1", - "@rollup/rollup-darwin-arm64": "4.9.1", - "@rollup/rollup-darwin-x64": "4.9.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.9.1", - "@rollup/rollup-linux-arm64-gnu": "4.9.1", - "@rollup/rollup-linux-arm64-musl": "4.9.1", - "@rollup/rollup-linux-riscv64-gnu": "4.9.1", - "@rollup/rollup-linux-x64-gnu": "4.9.1", - "@rollup/rollup-linux-x64-musl": "4.9.1", - "@rollup/rollup-win32-arm64-msvc": "4.9.1", - "@rollup/rollup-win32-ia32-msvc": "4.9.1", - "@rollup/rollup-win32-x64-msvc": "4.9.1", + "@rollup/rollup-android-arm-eabi": "4.18.0", + "@rollup/rollup-android-arm64": "4.18.0", + "@rollup/rollup-darwin-arm64": "4.18.0", + "@rollup/rollup-darwin-x64": "4.18.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.18.0", + "@rollup/rollup-linux-arm-musleabihf": "4.18.0", + "@rollup/rollup-linux-arm64-gnu": "4.18.0", + "@rollup/rollup-linux-arm64-musl": "4.18.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0", + "@rollup/rollup-linux-riscv64-gnu": "4.18.0", + "@rollup/rollup-linux-s390x-gnu": "4.18.0", + "@rollup/rollup-linux-x64-gnu": "4.18.0", + "@rollup/rollup-linux-x64-musl": "4.18.0", + "@rollup/rollup-win32-arm64-msvc": "4.18.0", + "@rollup/rollup-win32-ia32-msvc": "4.18.0", + "@rollup/rollup-win32-x64-msvc": "4.18.0", "fsevents": "~2.3.2" } }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "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/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, "node_modules/set-function-length": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", - "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dependencies": { - "define-data-property": "^1.1.1", - "get-intrinsic": "^1.2.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" } }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/socket.io": { + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz", + "integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==", + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "cors": "~2.8.5", + "debug": "~4.3.2", + "engine.io": "~6.5.2", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.4.tgz", + "integrity": "sha512-wDNHGXGewWAjQPt3pyeYBtpWSq9cLE5UW1ZUPL/2eGK9jtse/FpXib7epSTsz0Q0m+6sg6Y4KtcFTlah1bdOVg==", + "dependencies": { + "debug": "~4.3.4", + "ws": "~8.11.0" + } + }, + "node_modules/socket.io-client": { + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.5.tgz", + "integrity": "sha512-sJ/tqHOCe7Z50JCBCXrsY3I2k03iOiUe+tj1OmKeD2lXPiGH/RUCdTZFoqVyN7l1MnpIzPrGtLcijffmeouNlQ==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/url": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz", - "integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==", + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/svelte": { + "version": "3.59.2", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.59.2.tgz", + "integrity": "sha512-vzSyuGr3eEoAtT/A6bmajosJZIUWySzY2CzB3w2pgPvnkUjGqlDnsNnA0PMO+mMAhuyMul6C2uuZzY6ELSkzyA==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/svelte-json-tree-auto": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/svelte-json-tree-auto/-/svelte-json-tree-auto-0.1.0.tgz", + "integrity": "sha512-XDUBTV/BNStd/9WJDndzxQ9KqhoNoZBxkOo1H1d29qKW+YxG6eRrt2Yp0Cv/6KLKDtFLhJ9huJpqpOSe4yMG0Q==" + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ts-toolbelt": { + "version": "6.15.5", + "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-6.15.5.tgz", + "integrity": "sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A==" + }, + "node_modules/tsscmp": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", + "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==", + "engines": { + "node": ">=0.6.x" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dependencies": { - "punycode": "^1.4.1", - "qs": "^6.11.2" + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typescript": { + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" } }, "node_modules/vite": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.10.tgz", - "integrity": "sha512-2P8J7WWgmc355HUMlFrwofacvr98DAjoE52BfdbwQtyLH06XKwaL/FMnmKM2crF0iX4MpmMKoDlNCB1ok7zHCw==", + "version": "5.2.13", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.13.tgz", + "integrity": "sha512-SSq1noJfY9pR3I1TUENL3rQYDQCFqgD+lM6fTRAM8Nv6Lsg5hDLaXkjETVeBt+7vZBCMoibD+6IWnT2mJ+Zb/A==", "dev": true, "dependencies": { - "esbuild": "^0.19.3", - "postcss": "^8.4.32", - "rollup": "^4.2.0" + "esbuild": "^0.20.1", + "postcss": "^8.4.38", + "rollup": "^4.13.0" }, "bin": { "vite": "bin/vite.js" @@ -1339,6 +2300,47 @@ "optional": true } } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", + "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ylru": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ylru/-/ylru-1.4.0.tgz", + "integrity": "sha512-2OQsPNEmBCvXuFlIni/a+Rn+R2pHW9INm0BxXJ4hVDA8TirqMj+J/Rp9ItLatT/5pZqWwefVrTQcHpixsxnVlA==", + "engines": { + "node": ">= 4.0.0" + } } } } diff --git a/package.json b/package.json index fc354a1..68786fd 100644 --- a/package.json +++ b/package.json @@ -5,23 +5,16 @@ "type": "module", "scripts": { "dev": "vite", - "build": "vite build", + "build": "tsc && vite build", "preview": "vite preview" }, - "repository": { - "type": "git", - "url": "git+https://github.com/7GCraft/battle-simulator.git" - }, - "author": "", - "license": "ISC", - "bugs": { - "url": "https://github.com/7GCraft/battle-simulator/issues" - }, "devDependencies": { - "vite": "^5.0.8" + "typescript": "^5.2.2", + "vite": "^5.2.0" }, "dependencies": { + "boardgame.io": "^0.50.2", "honeycomb-grid": "^4.1.5", - "pixi.js": "^7.3.2" + "pixi.js": "^8.1.6" } } diff --git a/public/vite.svg b/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/App.bak.ts b/src/App.bak.ts new file mode 100644 index 0000000..a8cf5f4 --- /dev/null +++ b/src/App.bak.ts @@ -0,0 +1,162 @@ +import { Client } from "boardgame.io/client"; +import { BattleSimulator } from "./Game"; +import { + ClientState as ServerState, + _ClientImpl, +} from "boardgame.io/dist/types/src/client/client"; +import MapTile from "./model/MapTile"; +import { Grid } from "honeycomb-grid"; +import * as PIXI from "pixi.js"; +import Unit from "./model/Unit"; +import { GameState } from "./types/GameState"; +import ClickHandler from "./client/ClickHandler"; +import DebugPanel from "./client/DebugPanel"; +import { ClientState } from "./types/ClientState"; +import UnitBuilder from "./model/builder/unit-builder"; +import EndTurnHandler from "./client/EndTurnHandler"; +import { getUnitFromId } from "./util/game-state"; +import Renderer from "./Renderer"; + +class BattleSimulatorClient { + client: _ClientImpl; + pixiApp: PIXI.Application; + grid: Grid; + units: Map; + clientState: ClientState; + renderer: Renderer; + + constructor(pixiApp: PIXI.Application) { + this.client = Client({ game: BattleSimulator }); + this.client.start(); + this.pixiApp = pixiApp; + this.renderer = new Renderer(pixiApp); + this.grid = this.createBoard(); + this.units = this.createUnits(); + const clientState = { + selectedUnit: null, + markedUnitIds: new Set(), + }; + + // FOR DEV & DEBUG + const debugPanel = new DebugPanel("#debug-panel"); + this.clientState = debugPanel.watch(clientState); + + // FOR PRODUCTION + // this.clientState = clientState; + + this.attachListeners(); + this.client.subscribe((state) => this.update(state)); + } + + createBoard() { + const initialState = this.client.getInitialState(); + const cells = initialState.G.cells; + + // Temporary code to draw grid here + const grid = Grid.fromIterable( + cells.map((cell) => MapTile.create(cell.coordinates, cell.cellNumber)) + ); + + grid.forEach((tile) => pixiApp.stage.addChild(tile.render())); + return grid; + } + + createUnits() { + const initialState = this.client.getInitialState(); + const gameUnits = initialState.G.units; + const units = new Map(); + + gameUnits.forEach((unit) => { + const unitTile = Unit.create( + unit.id, + 0, + this.grid.getHex(unit.position)!, + unit.playerID == "0" ? "blue" : "red" + ); + pixiApp.stage.addChild(UnitBuilder.renderPrimary(unitTile)); + units.set(unit.id, unitTile); + }); + + return units; + } + + attachListeners() { + const clickHandler = new ClickHandler( + this.client, + this.grid, + this.clientState + ); + + this.pixiApp.canvas.addEventListener("click", ({ offsetX, offsetY }) => + clickHandler.handle(offsetX, offsetY) + ); + + const endTurnHandler = new EndTurnHandler(this.client, this.clientState); + + document + .querySelector("#end-turn-button") + ?.addEventListener("click", () => { + const confirm = window.confirm( + "Are you sure you want to end the turn?" + ); + + if (confirm) endTurnHandler.handle(); + }); + } + + update(state: ServerState) { + if (state === null) return; + const renderedUnitIDs = this.units.keys(); + + for (const unitID of renderedUnitIDs) { + const unit = this.units.get(unitID)!; + unit.destroy(); + + const unitState = getUnitFromId(state.G.units, unitID); + if (unitState == null || !unitState.isAlive) { + this.units.delete(unitID); + continue; + } + + const newUnitPosition = unitState.position; + const tile = this.grid.getHex(newUnitPosition)!; + const newUnit = Unit.create( + unitState.id, + unitState.power, + tile, + unitState.playerID == "0" ? "blue" : "red" + ); + + if (this.clientState.markedUnitIds.has(unitState.id)) { + pixiApp.stage.addChild(UnitBuilder.renderPrimary(newUnit)); + } else { + pixiApp.stage.addChild(UnitBuilder.renderDisabled(newUnit)); + } + + tile.cellNumber = 0; + tile.render(); + + this.units.set(unitID, newUnit); + } + + if (state.ctx.gameover) { + const textGameOverElement = document.querySelector("#game-over-text")!; + textGameOverElement.textContent = + state.ctx.gameover.winner !== undefined + ? `Player ${state.ctx.gameover.winner} Win!` + : "It's a Draw!"; + } + } +} + +const pixiApp = new PIXI.Application(); +await pixiApp.init({ backgroundAlpha: 0 }); + +document + .querySelector("#game")! + .insertBefore(pixiApp.canvas, document.querySelector("#end-turn-button")); + +// Debug Only +globalThis.__PIXI_APP__ = pixiApp; + +const app = new BattleSimulatorClient(pixiApp); diff --git a/src/App.ts b/src/App.ts new file mode 100644 index 0000000..50f6645 --- /dev/null +++ b/src/App.ts @@ -0,0 +1,126 @@ +import { Client } from "boardgame.io/client"; +import { BattleSimulator } from "./Game"; +import { _ClientImpl } from "boardgame.io/dist/types/src/client/client"; +import { Grid, Hex } from "honeycomb-grid"; +import * as PIXI from "pixi.js"; +import { GameState } from "./types/GameState"; +import DebugPanel from "./client/DebugPanel"; +import { ClientState, ServerState } from "./types/ClientState"; +import Renderer from "./Renderer"; +import MapGenerator from "./render/map-generator"; +import UnitGenerator from "./render/unit-generator"; +import ClickHandler from "./client/ClickHandler"; +import { UnitGameEvent } from "./types/model/base/game-event"; + +class BattleSimulatorClient { + client: _ClientImpl; + pixiApp: PIXI.Application; + grid: Grid; + clientState: ClientState; + renderer: Renderer; + + constructor(pixiApp: PIXI.Application) { + this.client = Client({ game: BattleSimulator }); + this.client.start(); + const initialStates = this.client.getInitialState(); + + const [grid, _] = new MapGenerator( + initialStates.G.cells, + pixiApp + ).generate(); + this.grid = grid; + + const [units, unitIdToClientUnitId] = new UnitGenerator( + initialStates.G.units, + initialStates.ctx.currentPlayer, + pixiApp + ).generate(); + + this.pixiApp = pixiApp; + this.renderer = new Renderer(pixiApp, units); + + const clientState: ClientState = { + units: units, + unitIdToClientUnitId: unitIdToClientUnitId, + selectedUnit: null, + markedUnitIds: new Set(), + }; + + // FOR DEV & DEBUG + // BUGGED BECAUSE ERROR WHEN DEALING WITH CIRCULAR REFERENCES + // const excludeLists = new Set(["units"]); + // const debugPanel = new DebugPanel("#debug-panel", excludeLists); + // this.clientState = debugPanel.watch(clientState); + + // FOR PRODUCTION + this.clientState = clientState; + + this.attachListeners(); + this.client.subscribe((state) => this.update(state)); + } + + attachListeners() { + const clickHandler = new ClickHandler( + this.client, + this.grid, + this.clientState, + this.renderer + ); + + this.pixiApp.canvas.addEventListener("click", ({ offsetX, offsetY }) => + clickHandler.handle(offsetX, offsetY) + ); + } + + update(state: ServerState) { + // When an invalid move happens, it sends update 2 times to the client + // This logic is used because the first update will contain "transients" property + if (state === null || state.hasOwnProperty("transients")) return; + + console.log(state.plugins.gameEvent); + + const gameEventState = state.plugins.gameEvent; + const lastErrorMessage = + gameEventState.api?.lastErrorMessage || + gameEventState.data.lastErrorMessage; + + if (lastErrorMessage !== null) { + alert(lastErrorMessage); + return; + } + + if (gameEventState.data.eventQueue.length === 0) return; + + for (const pushedEvent of gameEventState.data.eventQueue) { + const serverUnit = state.G.units.filter( + (unitState) => unitState.id === pushedEvent.unit_id + )[0]!; + const clientUnitId = this.clientState.unitIdToClientUnitId.get( + pushedEvent.unit_id + )!; + const clientUnit = this.clientState.units.get(clientUnitId)!; + + if (pushedEvent.event === UnitGameEvent.Move) { + clientUnit.state.position = serverUnit.position; + this.renderer.addEvent(clientUnitId, "move", serverUnit.position); + } + } + + const selectedUnit = this.clientState.selectedUnit!; + this.renderer.addEvent(selectedUnit.id, "selected", false); + this.clientState.markedUnitIds.add(selectedUnit.id); + this.clientState.selectedUnit = null; + } +} + +const pixiApp = new PIXI.Application(); +await pixiApp.init({ backgroundAlpha: 0 }); + +document + .querySelector("#game")! + .insertBefore(pixiApp.canvas, document.querySelector("#end-turn-button")); + +// Debug Only +globalThis.__PIXI_APP__ = pixiApp; + +const app = new BattleSimulatorClient(pixiApp); diff --git a/src/Game.ts b/src/Game.ts new file mode 100644 index 0000000..546f842 --- /dev/null +++ b/src/Game.ts @@ -0,0 +1,43 @@ +import { Game } from "boardgame.io"; +import { mockBoard, mockUnits } from "./temp/board-mocker"; +import { GameState } from "./types/GameState"; +import MoveController from "./controller/move-controller"; +import FightController from "./controller/fight-controller"; +import GameEventPlugin from "./plugins/game-event-plugin"; + +export const BattleSimulator: Game = { + setup: () => { + const cells = mockBoard(); + const units = mockUnits(cells, 2, 2); + const unitCountByPlayer: Record = {}; + for (let i = 0; i < 2; i++) unitCountByPlayer[i.toString()] = 2; + + return { + cells: cells, + units: units, + unitCountByPlayer, + }; + }, + minPlayers: 2, + maxPlayers: 2, + plugins: [GameEventPlugin()], + turn: { + // minMoves: 1, + // maxMoves: 1, + }, + moves: { + ...MoveController.publish(), + ...FightController.publish(), + }, + endIf: ({ G, ctx }) => { + let aboveZeroUnitPlayerIds = []; + for (let i = 0; i < ctx.numPlayers; i++) { + if (G.unitCountByPlayer[i.toString()] > 0) + aboveZeroUnitPlayerIds.push(i.toString()); + } + + if (aboveZeroUnitPlayerIds.length == 0) return { draw: true }; + if (aboveZeroUnitPlayerIds.length == 1) + return { winner: aboveZeroUnitPlayerIds[0] }; + }, +}; diff --git a/src/Renderer.ts b/src/Renderer.ts new file mode 100644 index 0000000..5f85e17 --- /dev/null +++ b/src/Renderer.ts @@ -0,0 +1,52 @@ +import gameConfig from "../gameConfig"; +import type { Application } from "pixi.js"; +import { + RenderEvent, + RenderEventParamMap, +} from "./types/model/base/render-event"; +import Unit from "./render/model/unit/unit"; + +class Renderer { + events: RenderEvent[]; + pixiApp: Application; + units: Map; + + constructor(app: Application, units: Map) { + this.pixiApp = app; + this.events = []; + this.units = units; + + let lastTick = performance.now(); + + this.pixiApp.ticker.add((delta: number) => { + const now = performance.now(); + const tickLimit = 1000 / gameConfig.fps; + + if (now - lastTick >= tickLimit) { + this.processEvents(delta); + + lastTick = now; + } + }); + } + + processEvents(delta: number) { + for (const event of this.events) { + const unit = this.units.get(event.object_id); + if (unit === undefined) continue; + unit.consume(event.event, event.parameter); + } + + this.events = []; + } + + addEvent( + object_id: string, + event: E, + parameter: RenderEventParamMap[E] + ) { + this.events.push({ object_id, event, parameter }); + } +} + +export default Renderer; diff --git a/src/client/ClickHandler.ts b/src/client/ClickHandler.ts new file mode 100644 index 0000000..766f288 --- /dev/null +++ b/src/client/ClickHandler.ts @@ -0,0 +1,143 @@ +import { _ClientImpl } from "boardgame.io/dist/types/src/client/client"; +import { Grid, Hex, PartialCubeCoordinates } from "honeycomb-grid"; +import { GameState } from "../types/GameState"; +import { getUnitsFromClientUnitsAndCoord } from "../util/board"; +import { ClientState } from "../types/ClientState"; +import { UnitState } from "../types/model/unit-state"; +import Renderer from "../Renderer"; +import Unit from "../render/model/unit/unit"; + +export default class ClickHandler { + gameClient: _ClientImpl; + grid: Grid; + clientState: ClientState; + renderer: Renderer; + + constructor( + gameClient: _ClientImpl, + grid: Grid, + clientState: ClientState, + renderer: Renderer + ) { + this.gameClient = gameClient; + this.grid = grid; + this.clientState = clientState; + this.renderer = renderer; + } + + handle(offsetX: number, offsetY: number) { + const tile = this.grid.pointToHex( + { x: offsetX, y: offsetY }, + { allowOutside: false } + ); + + if (tile === undefined) { + if (this.clientState.selectedUnit != null) { + this.renderer.addEvent( + this.clientState.selectedUnit!.id, + "selected", + false + ); + this.clientState.selectedUnit = null; + } + + return; + } + + const state = this.gameClient.getState(); + if (state == null) return; + + const coordinate = { q: tile.q, r: tile.r }; + const unitsOnCoord = getUnitsFromClientUnitsAndCoord( + [...this.clientState.units.values()], + coordinate + ); + + if (this.clientState.selectedUnit == null) { + const isUnitSelected = this.resolveSelection( + state.ctx.currentPlayer, + unitsOnCoord + ); + + if (isUnitSelected) { + this.renderer.addEvent( + this.clientState.selectedUnit!.id, + "selected", + true + ); + } + + return; + } + + const target = unitsOnCoord.filter((unit) => unit.state.isAlive).shift(); + + // let isActionSuccessful = false; + if (target == null || !target.state.isAlive) { + this.handleMovement(coordinate); + } + // else { + // isActionSuccessful = this.handleFighting(target); + // } + + // if (isActionSuccessful) { + // this.clientState.markedUnitIds.add(this.clientState.selectedUnit.id); + // this.renderer.addEvent( + // this.clientState.selectedUnit!.id, + // "selected", + // false + // ); + // this.clientState.selectedUnit = null; + // } + } + + resolveSelection(currentPlayerId: string, unitsOnCoord: Unit[]) { + const firstLivingUnit = unitsOnCoord + .filter((unit) => unit.state.isAlive) + .shift(); + + if (firstLivingUnit == null) return false; + if (firstLivingUnit.state.playerID != currentPlayerId) { + alert("Please select your own unit!"); + return false; + } + + if (this.clientState.markedUnitIds.has(firstLivingUnit.id)) { + alert("This unit has done an action, choose another unit!"); + return false; + } + + this.clientState.selectedUnit = firstLivingUnit; + return true; + } + + handleMovement(coordinate: PartialCubeCoordinates) { + const selectedUnit = this.clientState.selectedUnit; + if (selectedUnit === null) { + alert("No unit is being selected!"); + return false; + } + + this.gameClient.moves.moveUnit(selectedUnit.state.id, coordinate); + + return true; + } + + // handleFighting(target: UnitState) { + // const selectedUnit = this.clientState.selectedUnit; + // if (selectedUnit === null) { + // alert("No unit is being selected!"); + // return false; + // } + + // if (selectedUnit.playerID === target.playerID) { + // // Validation may be removed in the future + // alert("You cannot attack your own unit!"); + // return false; + // } + + // this.gameClient.moves.fight(selectedUnit.id, target.id); + + // return true; + // } +} diff --git a/src/client/DebugPanel.ts b/src/client/DebugPanel.ts new file mode 100644 index 0000000..94510e4 --- /dev/null +++ b/src/client/DebugPanel.ts @@ -0,0 +1,61 @@ +import { ClientState } from "../types/ClientState"; + +export default class DebugPanel { + debugPanelElement: Element; + excludeLists: Set; + + constructor(panelSelector: string, excludeLists: Set) { + this.debugPanelElement = document.querySelector(panelSelector)!; + this.excludeLists = excludeLists; + } + + watch(clientState: ClientState) { + this.debugPanelElement.innerHTML = + this.getHtmlContentFromState(clientState); + return new Proxy(clientState, { + set: (t, p, v) => { + Reflect.set(t, p, v); + this.debugPanelElement.innerHTML = this.getHtmlContentFromState(t); + return true; + }, + }); + } + + getHtmlContentFromState(state: ClientState) { + let html = ""; + for (const prop in state) { + const val = state[prop as keyof ClientState]; + const content = this.excludeLists.has(prop) + ? "NOT SHOWN" + : this.getStringContentFrom(val); + html += `${prop}: ${content}
`; + } + return html; + } + + getStringContentFrom(val: any): string { + if (typeof val === "string") return `"${val}"`; + if (typeof val === "number") return val.toString(); + if (typeof val === "boolean") return val ? "true" : "false"; + if (val instanceof Set) { + const items = [...val.values()] + .map((item) => this.getStringContentFrom(item)) + .join(); + return `Set(${val.size}) [${items}]`; + } + + if (val instanceof Map) { + const items = [...val.entries()] + .map( + (item) => + `${this.getStringContentFrom( + item[0] + )}: ${this.getStringContentFrom(item[1])}` + ) + .join(); + return `Map(${val.size}) {${items}}`; + } + + return JSON.stringify(val); + } +} diff --git a/src/client/EndTurnHandler.ts b/src/client/EndTurnHandler.ts new file mode 100644 index 0000000..9d894d3 --- /dev/null +++ b/src/client/EndTurnHandler.ts @@ -0,0 +1,18 @@ +import { _ClientImpl } from "boardgame.io/dist/types/src/client/client"; +import { GameState } from "../types/GameState"; +import { ClientState } from "../types/ClientState"; + +export default class EndTurnHandler { + gameClient: _ClientImpl; + clientState: ClientState; + + constructor(gameClient: _ClientImpl, clientState: ClientState) { + this.gameClient = gameClient; + this.clientState = clientState; + } + + handle() { + this.gameClient.events.endTurn?.(); + this.clientState.markedUnitIds.clear(); + } +} diff --git a/src/controller/fight-controller.ts b/src/controller/fight-controller.ts new file mode 100644 index 0000000..f3b9b5c --- /dev/null +++ b/src/controller/fight-controller.ts @@ -0,0 +1,49 @@ +import { Move } from "boardgame.io"; +import { GameState } from "../types/GameState"; +import TileHex from "../model/Base/TileHex"; +import { distance } from "honeycomb-grid"; +import { INVALID_MOVE } from "boardgame.io/core"; +import { getUnitFromId } from "../util/game-state"; + +const fight: Move = ( + { G }, + selectedUnitID: string, + targetUnitID: string +) => { + const selectedUnit = getUnitFromId(G.units, selectedUnitID); + const targetUnit = getUnitFromId(G.units, targetUnitID); + if (selectedUnit == null || targetUnit == null) return INVALID_MOVE; + + const dist = distance( + TileHex.settings, + selectedUnit.position, + targetUnit.position + ); + if (dist > 1) return INVALID_MOVE; + + const high = + selectedUnit.power > targetUnit.power ? selectedUnit : targetUnit; + const low = + selectedUnit.power > targetUnit.power ? targetUnit : selectedUnit; + + high.power -= low.power; + low.power = 0; + + if (high.power === 0) { + high.isAlive = false; + G.unitCountByPlayer[high.playerID]--; + } + + low.isAlive = false; + G.unitCountByPlayer[low.playerID]--; +}; + +class FightController { + static publish() { + return { + fight, + }; + } +} + +export default FightController; diff --git a/src/controller/move-controller.ts b/src/controller/move-controller.ts new file mode 100644 index 0000000..e403c5a --- /dev/null +++ b/src/controller/move-controller.ts @@ -0,0 +1,55 @@ +import { PartialCubeCoordinates, distance, toCube } from "honeycomb-grid"; +import { INVALID_MOVE } from "boardgame.io/core"; +import { Move } from "boardgame.io"; +import { GameState } from "../types/GameState"; +import TileHex from "../model/Base/TileHex"; +import { getUnitFromId } from "../util/game-state"; +import { UnitGameEvent } from "../types/model/base/game-event"; + +const moveUnit: Move = ( + { G, playerID, ...plugins }, + unitID: string, + target: PartialCubeCoordinates +) => { + const unit = getUnitFromId(G.units, unitID); + if (unit == null) { + plugins.gameEvent.lastErrorMessage = "No unit is being selected!"; + return INVALID_MOVE; + } + + const dist = distance(TileHex.settings, unit.position, target); + if (dist > 1 || dist == 0) { + plugins.gameEvent.lastErrorMessage = + "This unit can only move exactly one tile!"; + return INVALID_MOVE; + } + unit.position = target; + + const currCoordinates = toCube(TileHex.settings, target); + const targetCell = G.cells.filter((cell) => { + return ( + currCoordinates.q === cell.coordinates.q && + currCoordinates.r === cell.coordinates.r + ); + })[0]; + + if (targetCell.cellNumber > 0) { + unit.power += targetCell.cellNumber; + targetCell.cellNumber = 0; + } + + plugins.gameEvent.enqueue({ + unit_id: unit.id, + event: UnitGameEvent.Move, + }); +}; + +class MoveController { + static publish() { + return { + moveUnit, + }; + } +} + +export default MoveController; diff --git a/src/model/Base/TileHex.ts b/src/model/Base/TileHex.ts new file mode 100644 index 0000000..85e5189 --- /dev/null +++ b/src/model/Base/TileHex.ts @@ -0,0 +1,6 @@ +import { defineHex } from "honeycomb-grid"; +import gameConfig from "../../../gameConfig"; + +const TileHex = defineHex(gameConfig.hex); + +export default TileHex; diff --git a/src/model/Base/UnitHex.ts b/src/model/Base/UnitHex.ts new file mode 100644 index 0000000..99792d5 --- /dev/null +++ b/src/model/Base/UnitHex.ts @@ -0,0 +1,7 @@ +// Temporary class because player is now rendered using hex +import { defineHex } from "honeycomb-grid"; +import gameConfig from "../../../gameConfig"; + +const UnitHex = defineHex({ ...gameConfig.hex, dimensions: 30 }); + +export default UnitHex; diff --git a/src/model/MapTile.ts b/src/model/MapTile.ts new file mode 100644 index 0000000..ec08ea3 --- /dev/null +++ b/src/model/MapTile.ts @@ -0,0 +1,42 @@ +import { PartialCubeCoordinates } from "honeycomb-grid"; +import { grid as gridColor } from "../../colors.json"; +import * as PIXI from "pixi.js"; +import BaseHex from "./Base/TileHex"; + +class MapTile extends BaseHex { + cellNumber!: number; + graphic!: PIXI.Graphics; + + static create(coordinates: PartialCubeCoordinates, cellNumber: number) { + const hex = new MapTile(coordinates); + hex.cellNumber = cellNumber; + hex.graphic = new PIXI.Graphics(); + return hex; + } + + render() { + this.graphic.clear(); + + let cellColor = gridColor.background; + if (this.cellNumber > 0) { + cellColor = gridColor.primary; + } + + this.graphic + .poly(this.corners) + .fill({ color: cellColor }) + .stroke({ width: 1, color: "#999999" }); + + this.graphic.removeChildren(); + if (this.cellNumber > 0) { + const text = new PIXI.Text({ text: this.cellNumber }); + text.x = this.x - text.width / 2; + text.y = this.y - text.height / 2; + this.graphic.addChild(text); + } + + return this.graphic; + } +} + +export default MapTile; diff --git a/src/model/Unit.ts b/src/model/Unit.ts new file mode 100644 index 0000000..5cf1145 --- /dev/null +++ b/src/model/Unit.ts @@ -0,0 +1,71 @@ +import UnitHex from "./Base/UnitHex"; +import MapTile from "./MapTile"; +import * as PIXI from "pixi.js"; +import { unit as unitColor } from "../../colors.json"; +import { PlayerTeamColor } from "../types/config/colors"; + +// class Player { +class Unit extends UnitHex { + unitID!: string; + power!: number; + positionTile!: MapTile; + colorKey!: PlayerTeamColor; + graphic!: PIXI.Graphics; + + // Temporary Create function for Hex Player + static create( + unitID: string, + power: number, + initialTile: MapTile, + colorKey: PlayerTeamColor + ) { + const hex = new Unit({ q: initialTile.q, r: initialTile.r }); + hex.unitID = unitID; + hex.power = power; + hex.positionTile = initialTile; + hex.colorKey = colorKey; + hex.graphic = new PIXI.Graphics(); + return hex; + } + + drawPoly() { + // Turns original hex corner into shrinked corner + // => Linear Transformation - Scaling + // https://gamemath.com/book/matrixtransforms.html + const scale = 4 / 5; + const newCorners = this.corners.map((p) => ({ + x: (p.x - this.x) * scale + this.x, + y: (p.y - this.y) * scale + this.y, + })); + + this.graphic.poly(newCorners).stroke({ width: 1, color: "#999999" }); + + return this; + } + + fillColorStyle(style: "primary" | "active" | "disabled") { + const color = unitColor[this.colorKey][style]; + this.graphic.fill({ color }); + return this; + } + + addText() { + const text = new PIXI.Text({ text: this.power }); + text.x = this.x - text.width / 2; + text.y = this.y - text.height / 2; + this.graphic.addChild(text); + } + + reset() { + this.graphic.removeChildren(); + this.graphic.clear(); + return this; + } + + destroy() { + this.reset(); + this.graphic.destroy(); + } +} + +export default Unit; diff --git a/src/model/builder/unit-builder.ts b/src/model/builder/unit-builder.ts new file mode 100644 index 0000000..b0840c4 --- /dev/null +++ b/src/model/builder/unit-builder.ts @@ -0,0 +1,18 @@ +import Unit from "../Unit"; + +export default class UnitBuilder { + static renderPrimary(unit: Unit) { + unit.reset().drawPoly().fillColorStyle("primary").addText(); + return unit.graphic; + } + + static renderActive(unit: Unit) { + unit.reset().drawPoly().fillColorStyle("active").addText(); + return unit.graphic; + } + + static renderDisabled(unit: Unit) { + unit.reset().drawPoly().fillColorStyle("disabled").addText(); + return unit.graphic; + } +} diff --git a/src/plugins/game-event-plugin.ts b/src/plugins/game-event-plugin.ts new file mode 100644 index 0000000..ca53754 --- /dev/null +++ b/src/plugins/game-event-plugin.ts @@ -0,0 +1,54 @@ +import { GameEvent } from "../types/model/base/game-event"; +import { Plugin } from "boardgame.io"; + +export interface GameEventData { + lastErrorMessage: string | null; + eventQueue: GameEvent[]; // If this slows the game, change data structure to queue instead +} + +export interface GameEventAPI extends GameEventData { + enqueue(event: GameEvent): void; + dequeue(): GameEvent | null; +} + +export interface GameEventPlugin { + gameEvent: GameEventAPI; +} + +const GameEventPlugin = (): Plugin => ({ + name: "gameEvent", + setup: () => ({ lastErrorMessage: null, eventQueue: [] }), + flush: ({ api }) => ({ + lastErrorMessage: api.lastErrorMessage, + eventQueue: api.eventQueue, + }), + api: () => { + const eventQueue: GameEvent[] = []; + + const enqueue = (event: GameEvent) => { + eventQueue.push(event); + }; + + const dequeue = () => { + if (eventQueue.length === 0) return null; + return eventQueue.splice(0, 1)[0]; + }; + + return { + lastErrorMessage: null, + eventQueue, + enqueue, + dequeue, + }; + }, + // fnWrap: + // (move, moveType) => + // ({ G, gameEvent, ...rest }, ...args) => { + // console.log(moveType); + // const result = move({ G, gameEvent, ...rest }, ...args); + // if (result !== INVALID_MOVE) gameEvent.lastErrorMessage = null; + // return G; + // }, +}); + +export default GameEventPlugin; diff --git a/src/render/map-generator.ts b/src/render/map-generator.ts new file mode 100644 index 0000000..3ecb220 --- /dev/null +++ b/src/render/map-generator.ts @@ -0,0 +1,30 @@ +import { Grid } from "honeycomb-grid"; +import { MapTileState } from "../types/model/map-tile-state"; +import { Application } from "pixi.js"; +import Tile from "./model/map/tile"; +import MapTileHex from "./model/base/map-tile-hex"; + +export default class MapGenerator { + tileStates: MapTileState[]; + pixiApp: Application; + + constructor(tileStates: MapTileState[], pixiApp: Application) { + this.tileStates = tileStates; + this.pixiApp = pixiApp; + } + + generate(): [Grid, Tile[]] { + const tiles = this.tileStates.map( + (tileState) => new Tile(tileState.coordinates, tileState.cellNumber) + ); + + const hexGrid = Grid.fromIterable(tiles.map((tile) => tile.hex)); + + tiles.forEach((tile) => { + tile.drawBase().displayCellNumber(); + this.pixiApp.stage.addChild(tile.graphic); + }); + + return [hexGrid, tiles]; + } +} diff --git a/src/render/model/base/map-tile-hex.ts b/src/render/model/base/map-tile-hex.ts new file mode 100644 index 0000000..eb51154 --- /dev/null +++ b/src/render/model/base/map-tile-hex.ts @@ -0,0 +1,4 @@ +import { defineHex } from "honeycomb-grid"; +import gameConfig from "../../../../gameConfig"; + +export default class MapTileHex extends defineHex(gameConfig.hex) {} diff --git a/src/render/model/base/unit-hex.ts b/src/render/model/base/unit-hex.ts new file mode 100644 index 0000000..8f22a32 --- /dev/null +++ b/src/render/model/base/unit-hex.ts @@ -0,0 +1,7 @@ +import { defineHex } from "honeycomb-grid"; +import gameConfig from "../../../../gameConfig"; + +export default class UnitHex extends defineHex({ + ...gameConfig.hex, + dimensions: 30, +}) {} diff --git a/src/render/model/entity.ts b/src/render/model/entity.ts new file mode 100644 index 0000000..34ffe82 --- /dev/null +++ b/src/render/model/entity.ts @@ -0,0 +1,47 @@ +import { Graphics } from "pixi.js"; +import { + EntityEventParamMap, + RenderEventHandler, +} from "../../types/model/base/render-event"; + +export default abstract class Entity implements RenderEventHandler { + id: string; + graphic: Graphics; + state: T; + eventHandlers: Record void>; + + constructor(id: string, state: T) { + this.id = id; + this.graphic = new Graphics(); + this.state = state; + this.eventHandlers = {}; + this.addSubscribers(); + } + + reset() { + this.graphic.removeChildren(); + this.graphic.clear(); + return this; + } + + destroy() { + this.reset(); + this.graphic.destroy(); + } + + abstract addSubscribers(): void; + + addSubscriber( + event: E, + handler: (parameter: EntityEventParamMap[E]) => void + ): void { + this.eventHandlers[event] = handler; + } + + consume( + event: E, + parameter: EntityEventParamMap[E] + ) { + this.eventHandlers[event](parameter); + } +} diff --git a/src/render/model/map/tile.ts b/src/render/model/map/tile.ts new file mode 100644 index 0000000..152bc25 --- /dev/null +++ b/src/render/model/map/tile.ts @@ -0,0 +1,75 @@ +import { Hex, PartialCubeCoordinates } from "honeycomb-grid"; +import { grid as gridColor } from "../../../../colors.json"; +import MapTileHex from "../base/map-tile-hex"; +import { Graphics, Text } from "pixi.js"; +import { + EntityEventParamMap, + RenderEventHandler, +} from "../../../types/model/base/render-event"; + +export default class Tile implements RenderEventHandler { + hex: Hex; + cellNumber: number; + graphic: Graphics; + eventHandlers: Record void>; + + constructor(coordinates: PartialCubeCoordinates, cellNumber: number) { + this.hex = new MapTileHex(coordinates); + this.cellNumber = cellNumber; + this.graphic = new Graphics(); + this.eventHandlers = {}; + this.addSubscribers(); + } + + drawBase() { + let cellColor = gridColor.background; + if (this.cellNumber > 0) { + cellColor = gridColor.primary; + } + + this.graphic + .poly(this.hex.corners) + .fill({ color: cellColor }) + .stroke({ width: 1, color: "#999999" }); + + return this; + } + + displayCellNumber() { + if (this.cellNumber > 0) { + const text = new Text({ text: this.cellNumber }); + text.x = this.hex.x - text.width / 2; + text.y = this.hex.y - text.height / 2; + this.graphic.addChild(text); + } + + return this; + } + + reset() { + this.graphic.removeChildren(); + this.graphic.clear(); + return this; + } + + destroy() { + this.reset(); + this.graphic.destroy(); + } + + addSubscribers(): void {} + + addSubscriber( + event: E, + handler: (parameter: EntityEventParamMap[E]) => void + ): void { + this.eventHandlers[event] = handler; + } + + consume( + event: E, + parameter: EntityEventParamMap[E] + ) { + this.eventHandlers[event](parameter); + } +} diff --git a/src/render/model/unit/unit.ts b/src/render/model/unit/unit.ts new file mode 100644 index 0000000..f05fea3 --- /dev/null +++ b/src/render/model/unit/unit.ts @@ -0,0 +1,67 @@ +import { Hex } from "honeycomb-grid"; +import Entity from "../entity"; +import UnitHex from "../base/unit-hex"; +import { UnitState } from "../../../types/model/unit-state"; +import { unit as unitColor } from "../../../../colors.json"; +import { Text } from "pixi.js"; + +export default class Unit extends Entity { + hex: Hex; + isSelected: boolean; + + constructor(id: string, gameState: UnitState) { + super(id, gameState); + this.hex = new UnitHex(gameState.position); + this.isSelected = false; + } + + drawBase() { + // Turns original hex corner into shrinked corner + // => Linear Transformation - Scaling + // https://gamemath.com/book/matrixtransforms.html + const scale = 4 / 5; + const newCorners = this.hex.corners.map((p) => ({ + x: (p.x - this.hex.x) * scale + this.hex.x, + y: (p.y - this.hex.y) * scale + this.hex.y, + })); + + this.graphic.poly(newCorners).stroke({ width: 1, color: "#999999" }); + + return this; + } + + fill(style: "primary" | "active" | "disabled") { + const colorKey = this.state.playerID === "0" ? "blue" : "red"; + const color = unitColor[colorKey][style]; + this.graphic.fill({ color }); + return this; + } + + displayPower() { + const text = new Text({ text: this.state.power }); + text.x = this.hex.x - text.width / 2; + text.y = this.hex.y - text.height / 2; + this.graphic.addChild(text); + return this; + } + + addSubscribers() { + this.addSubscriber("selected", (isSelected) => { + if (isSelected) this.reset().drawBase().fill("primary").displayPower(); + else this.reset().drawBase().fill("active").displayPower(); + }); + + this.addSubscriber("move", (coordinate) => { + // this.state.position.q = coordinate.q!; + // this.state.position.r = coordinate.r!; + + const delta = { + q: coordinate.q! - this.hex.q, + r: coordinate.r! - this.hex.r, + }; + + this.hex = this.hex.translate(delta); + this.reset().drawBase().fill("primary").displayPower(); + }); + } +} diff --git a/src/render/unit-generator.ts b/src/render/unit-generator.ts new file mode 100644 index 0000000..e70f2c5 --- /dev/null +++ b/src/render/unit-generator.ts @@ -0,0 +1,45 @@ +import { Application } from "pixi.js"; +import { UnitState } from "../types/model/unit-state"; +import Unit from "./model/unit/unit"; +import idGenerator from "../util/id-generator"; + +export default class UnitGenerator { + unitStates: UnitState[]; + startingPlayerId: string; + pixiApp: Application; + + constructor( + unitStates: UnitState[], + startingPlayerId: string, + pixiApp: Application + ) { + this.unitStates = unitStates; + this.startingPlayerId = startingPlayerId; + this.pixiApp = pixiApp; + } + + generate(): [Map, Map] { + const units = new Map(); + const unitIdToClientUnitId = new Map(); + this.unitStates.forEach((unitState) => { + // Just to make TypeScript happy + const generatedIdObj = idGenerator.next(); + const generatedId = generatedIdObj.done ? "" : generatedIdObj.value; + + // MUST DO THIS! Because `unitState` is from `const initialStates` which is constant & readonly. + const unit = new Unit(generatedId, { ...unitState }); + + let fillStyle: "primary" | "active" = "primary"; + if (unitState.playerID === this.startingPlayerId) { + fillStyle = "active"; + } + + unit.drawBase().fill(fillStyle).displayPower(); + this.pixiApp.stage.addChild(unit.graphic); + units.set(generatedId, unit); + unitIdToClientUnitId.set(unitState.id, generatedId); + }); + + return [units, unitIdToClientUnitId]; + } +} diff --git a/src/temp/board-mocker.ts b/src/temp/board-mocker.ts new file mode 100644 index 0000000..b6b4b61 --- /dev/null +++ b/src/temp/board-mocker.ts @@ -0,0 +1,60 @@ +import { toCube } from "honeycomb-grid"; +import TileHex from "../model/Base/TileHex"; +import { MapTileState } from "../types/model/map-tile-state"; +import { UnitState } from "../types/model/unit-state"; + +function getRandomInt(min: number, max: number) { + const minCeiled = Math.ceil(min); + const maxFloored = Math.floor(max); + return Math.floor(Math.random() * (maxFloored - minCeiled) + minCeiled); +} + +export const mockBoard = (): MapTileState[] => { + return Array.from(Array(10), (_, i) => + Array.from(Array(10), (_, j) => ({ + coordinates: toCube(TileHex.settings, { row: i, col: j }), + cellNumber: Math.random() * 3 < 1 ? 1 : 0, + })) + ).flat(); +}; + +export const mockUnits = ( + board: MapTileState[], + playerCount: number, + unitPerPlayerCount: number +): UnitState[] => { + const availablePositions = board.filter((tile) => tile.cellNumber === 0); + const mockUnits: UnitState[] = []; + + for (let i = 0; i < playerCount * unitPerPlayerCount; i++) { + const randomTileIdx = getRandomInt(0, availablePositions.length); + mockUnits.push({ + id: i.toString(), + playerID: (i % 2).toString(), + power: 1, + position: availablePositions.splice(randomTileIdx, 1)[0].coordinates, + isAlive: true, + }); + } + + return mockUnits; +}; + +export const multiplyMatrix = (mat1: number[][], mat2: number[][]) => { + const n1 = mat1.length, + m1 = mat1[0].length, + n2 = mat2.length, + m2 = mat2[0].length; + if (m1 !== n2) throw "Invalid matrix size"; + + const res = Array.from(Array(n1), () => Array(m2).fill(0)); + for (let i = 0; i < n1; i++) { + for (let j = 0; j < m2; j++) { + let temp = 0; + for (let k = 0; k < m1; k++) temp += mat1[i][k] * mat2[k][j]; + res[i][j] = temp; + } + } + + return res; +}; diff --git a/src/types/ClientState.d.ts b/src/types/ClientState.d.ts new file mode 100644 index 0000000..406fb31 --- /dev/null +++ b/src/types/ClientState.d.ts @@ -0,0 +1,27 @@ +import { ClientState as BaseServerState } from "boardgame.io/dist/types/src/client/client"; +import Unit from "../render/model/unit/unit"; +import { DefaultPluginAPIs } from "boardgame.io"; +import { + GameEventAPI, + GameEventData, + GameEventPlugin, +} from "../plugins/game-event-plugin"; + +export declare type ClientState = { + units: Map; + unitIdToClientUnitId: Map; + selectedUnit: Unit | null; + markedUnitIds: Set; // Need better name +}; + +type PluginData = { + api?: A; + data: D; +}; + +export type ServerState = BaseServerState & { + plugins: { + gameEvent: PluginData; + // There are other plugin data, but will only add ours + }; +}; diff --git a/src/types/GameState.ts b/src/types/GameState.ts new file mode 100644 index 0000000..0294fef --- /dev/null +++ b/src/types/GameState.ts @@ -0,0 +1,8 @@ +import { MapTileState } from "./model/map-tile-state"; +import { UnitState } from "./model/unit-state"; + +export declare type GameState = { + cells: MapTileState[]; + units: UnitState[]; + unitCountByPlayer: Record; +}; diff --git a/src/types/config/colors.d.ts b/src/types/config/colors.d.ts new file mode 100644 index 0000000..58c3a64 --- /dev/null +++ b/src/types/config/colors.d.ts @@ -0,0 +1,4 @@ +import * as Config from "../../../colors.json"; + +export type Player = typeof Config.unit; +export type PlayerTeamColor = keyof typeof Config.unit; diff --git a/src/types/model/base/game-event.ts b/src/types/model/base/game-event.ts new file mode 100644 index 0000000..181fcab --- /dev/null +++ b/src/types/model/base/game-event.ts @@ -0,0 +1,10 @@ +export enum UnitGameEvent { + Move, + Damaged, + Die, +} + +export interface GameEvent { + unit_id: string; // May need to change to entity_id in the future + event: UnitGameEvent; +} diff --git a/src/types/model/base/render-event.d.ts b/src/types/model/base/render-event.d.ts new file mode 100644 index 0000000..a5c4a03 --- /dev/null +++ b/src/types/model/base/render-event.d.ts @@ -0,0 +1,58 @@ +import { PartialCubeCoordinates } from "honeycomb-grid"; + +export interface EntityEventParamMap { + selected: boolean; + move: PartialCubeCoordinates; + damaged: number; + die: void; +} + +export interface MapTileEventParamMap {} + +export interface RenderEventParamMap + extends EntityEventParamMap, + MapTileEventParamMap {} + +// export interface RenderEvent { +// object_id: string; +// name: K; +// parameter: RenderEventParamMap[K]; +// } + +// export interface EventHandlers { +// [event: E]: (parameter: RenderEventParamMap[E]) => void; +// } + +export interface RenderEventHandler { + eventHandlers: Record void>; // Nuclear option + + // NONE OF THIS SHIT WORKS + // eventHandlers: { + // [E in RenderEventParamMap]: (parameter: RenderEventParamMap[E]) => void; + // }; + // eventHandlers: Record< + // Partial, + // (parameter: RenderEventParamMap[keyof RenderEventParamMap]) => void + // >; + // eventHandlers: EventHandlers; + // eventHandlers: Map< + // keyof RenderEventParamMap, + // (parameter: RenderEventParamMap[keyof RenderEventParamMap]) => void + // >; + + addSubscribers(): void; + addSubscriber( + event: E, + handler: (parameter: EntityEventParamMap[E]) => void + ): void; + consume( + event: E, + parameter: EntityEventParamMap[E] + ); +} + +export interface RenderEvent { + object_id: string; + event: E; + parameter: RenderEventParamMap[E]; +} diff --git a/src/types/model/map-tile-state.d.ts b/src/types/model/map-tile-state.d.ts new file mode 100644 index 0000000..0afaf38 --- /dev/null +++ b/src/types/model/map-tile-state.d.ts @@ -0,0 +1,6 @@ +import { PartialCubeCoordinates } from "honeycomb-grid"; + +export declare type MapTileState = { + cellNumber: number; + coordinates: PartialCubeCoordinates; +}; diff --git a/src/types/model/unit-state.d.ts b/src/types/model/unit-state.d.ts new file mode 100644 index 0000000..9206bcc --- /dev/null +++ b/src/types/model/unit-state.d.ts @@ -0,0 +1,9 @@ +import { PartialCubeCoordinates } from "honeycomb-grid"; + +export declare type UnitState = { + id: string; + playerID: string; + position: PartialCubeCoordinates; + power: number; + isAlive: boolean; +}; diff --git a/src/util/board.ts b/src/util/board.ts new file mode 100644 index 0000000..923fe25 --- /dev/null +++ b/src/util/board.ts @@ -0,0 +1,15 @@ +import { PartialCubeCoordinates } from "honeycomb-grid"; +import Unit from "../render/model/unit/unit"; + +export const getUnitsFromClientUnitsAndCoord = ( + units: Unit[], + coordinate: PartialCubeCoordinates +) => { + const filtered = units.filter( + (unit) => + unit.state.position.q === coordinate.q && + unit.state.position.r === coordinate.r + ); + + return filtered; +}; diff --git a/src/util/game-state.ts b/src/util/game-state.ts new file mode 100644 index 0000000..3ffb8de --- /dev/null +++ b/src/util/game-state.ts @@ -0,0 +1,6 @@ +import { UnitState } from "../types/model/unit-state"; + +export const getUnitFromId = (units: UnitState[], unitID: string) => { + const filteredUnits = units.filter((unit) => unit.id == unitID); + return filteredUnits.length === 0 ? null : filteredUnits[0]; +}; diff --git a/src/util/id-generator.ts b/src/util/id-generator.ts new file mode 100644 index 0000000..d812bec --- /dev/null +++ b/src/util/id-generator.ts @@ -0,0 +1,11 @@ +function* generateId() { + let curr = 1; + while (true) { + yield curr.toString(); + curr++; + } +} + +const idGenerator = generateId(); + +export default idGenerator; diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..75abdef --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"] +}