diff --git a/.vscode/tasks.json b/.vscode/tasks.json index ca74a57d..6c66309e 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -25,10 +25,20 @@ }, }, { - "label": "viewer server+esbuild", + "label": "webgl-worker", + "type": "shell", + "command": "node buildWorkers.mjs -w", + "problemMatcher": "$esbuild-watch", + "presentation": { + "reveal": "silent" + }, + }, + { + "label": "viewer server+esbuild+workers", "dependsOn": [ "viewer-server", - "viewer-esbuild" + "viewer-esbuild", + "webgl-worker" ], "dependsOrder": "parallel", } diff --git a/buildWorkers.mjs b/buildWorkers.mjs new file mode 100644 index 00000000..ecee7978 --- /dev/null +++ b/buildWorkers.mjs @@ -0,0 +1,59 @@ +// main worker file intended for computing world geometry is built using prismarine-viewer/buildWorker.mjs +import { build, context } from 'esbuild' +import fs from 'fs' +import path from 'path' + +const watch = process.argv.includes('-w') + +const result = await (watch ? context : build)({ + bundle: true, + platform: 'browser', + entryPoints: ['prismarine-viewer/examples/webgpuRendererWorker.ts'], + outdir: 'prismarine-viewer/public/', + sourcemap: watch ? 'inline' : 'external', + minify: !watch, + treeShaking: true, + logLevel: 'info', + alias: { + 'three': './node_modules/three/src/Three.js', + events: 'events', // make explicit + buffer: 'buffer', + 'fs': 'browserfs/dist/shims/fs.js', + http: 'http-browserify', + perf_hooks: './src/perf_hooks_replacement.js', + crypto: './src/crypto.js', + stream: 'stream-browserify', + net: 'net-browserify', + assert: 'assert', + dns: './src/dns.js' + }, + plugins: [ + { + name: 'writeOutput', + setup (build) { + build.onEnd(({ outputFiles }) => { + for (const file of outputFiles) { + for (const dir of ['prismarine-viewer/public', 'dist']) { + const baseName = path.basename(file.path) + fs.writeFileSync(path.join(dir, baseName), file.contents) + } + } + }) + } + } + ], + loader: { + '.vert': 'text', + '.frag': 'text', + '.wgsl': 'text', + }, + mainFields: [ + 'browser', 'module', 'main' + ], + keepNames: true, + write: false, +}) + +if (watch) { + await result.watch() +} diff --git a/cypress/e2e/performance.spec.ts b/cypress/e2e/performance.spec.ts new file mode 100644 index 00000000..f2fc4d46 --- /dev/null +++ b/cypress/e2e/performance.spec.ts @@ -0,0 +1,25 @@ +import { cleanVisit, setOptions } from './shared' + +it('Loads & renders singleplayer', () => { + cleanVisit('/?singleplayer=1') + setOptions({ + renderDistance: 2 + }) + // wait for .initial-loader to disappear + cy.get('.initial-loader', { timeout: 20_000 }).should('not.exist') + cy.window() + .its('performance') + .invoke('mark', 'worldLoad') + + cy.document().then({ timeout: 20_000 }, doc => { + return new Cypress.Promise(resolve => { + doc.addEventListener('cypress-world-ready', resolve) + }) + }).then(() => { + const duration = cy.window() + .its('performance') + .invoke('measure', 'modalOpen') + .its('duration') + cy.log('Duration', duration) + }) +}) diff --git a/package.json b/package.json index 91b42f87..313bf911 100644 --- a/package.json +++ b/package.json @@ -6,11 +6,11 @@ "dev-rsbuild": "rsbuild dev", "dev-proxy": "node server.js", "start": "run-p dev-rsbuild dev-proxy", - "start-watch-script": "nodemon -w rsbuild.config.ts --watch", - "build": "rsbuild build", - "build-analyze": "BUNDLE_ANALYZE=true rsbuild build", + "build": "node buildWorkers.mjs && rsbuild build", + "build-analyze": "BUNDLE_ANALYZE=true rsbuild build && node buildWorkers.mjs", "check-build": "tsx scripts/genShims.ts && tsc && pnpm build", "test:cypress": "cypress run", + "test:cypress:perf": "cypress run --spec cypress/e2e/perf.spec.ts --browser edge", "test-unit": "vitest", "test:e2e": "start-test http-get://localhost:8080 test:cypress", "prod-start": "node server.js --prod", @@ -20,12 +20,13 @@ "storybook": "storybook dev -p 6006", "build-storybook": "storybook build && node scripts/build.js moveStorybookFiles", "start-experiments": "vite --config experiments/vite.config.ts --host", - "watch-other-workers": "echo NOT IMPLEMENTED", + "watch-other-workers": "node buildWorkers.mjs -w", "build-mesher": "node prismarine-viewer/buildMesherWorker.mjs", "watch-mesher": "pnpm build-mesher -w", "run-playground": "run-p watch-mesher watch-other-workers playground-server watch-playground", "run-all": "run-p start run-playground", "playground-server": "live-server --port=9090 prismarine-viewer/public", + "start-watch-script": "nodemon -w rsbuild.config.ts --watch", "watch-playground": "node prismarine-viewer/esbuild.mjs -w" }, "keywords": [ @@ -51,6 +52,7 @@ "@types/react": "^18.2.20", "@types/react-dom": "^18.2.7", "@types/wicg-file-system-access": "^2023.10.2", + "@webgpu/types": "^0.1.44", "@xmcl/text-component": "^2.1.3", "@zardoy/react-util": "^0.2.4", "@zardoy/utils": "^0.0.11", @@ -72,6 +74,7 @@ "google-drive-browserfs": "github:zardoy/browserfs#google-drive", "jszip": "^3.10.1", "lodash-es": "^4.17.21", + "math.gl": "^4.0.0", "minecraft-data": "3.65.0", "minecraft-protocol": "github:PrismarineJS/node-minecraft-protocol#master", "mineflayer-item-map-downloader": "github:zardoy/mineflayer-item-map-downloader", @@ -99,6 +102,7 @@ "stats.js": "^0.17.0", "tabbable": "^6.2.0", "title-case": "3.x", + "twgl.js": "^5.5.4", "ua-parser-js": "^1.0.37", "use-typed-event-listener": "^4.0.2", "valtio": "^1.11.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9acc2311..ee53af06 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -65,6 +65,9 @@ importers: '@types/wicg-file-system-access': specifier: ^2023.10.2 version: 2023.10.2 + '@webgpu/types': + specifier: ^0.1.44 + version: 0.1.44 '@xmcl/text-component': specifier: ^2.1.3 version: 2.1.3 @@ -128,6 +131,9 @@ importers: lodash-es: specifier: ^4.17.21 version: 4.17.21 + math.gl: + specifier: ^4.0.0 + version: 4.0.1 minecraft-data: specifier: 3.65.0 version: 3.65.0 @@ -209,6 +215,9 @@ importers: title-case: specifier: 3.x version: 3.0.3 + twgl.js: + specifier: ^5.5.4 + version: 5.5.4 ua-parser-js: specifier: ^1.0.37 version: 1.0.37 @@ -236,7 +245,7 @@ importers: version: 1.4.4(cypress@10.11.0) systeminformation: specifier: ^5.21.22 - version: 5.22.7 + version: 5.21.24 devDependencies: '@rsbuild/core': specifier: 1.0.1-beta.4 @@ -318,7 +327,7 @@ importers: version: 8.50.0 eslint-config-zardoy: specifier: ^0.2.17 - version: 0.2.17(eslint-plugin-react-hooks@4.6.0(eslint@8.50.0))(eslint-plugin-react@7.34.1(eslint@8.50.0))(eslint@8.50.0)(typescript@5.5.4) + version: 0.2.17(eslint-plugin-react-hooks@4.6.0(eslint@8.50.0))(eslint-plugin-react@7.33.2(eslint@8.50.0))(eslint@8.50.0)(typescript@5.5.4) events: specifier: ^3.3.0 version: 3.3.0 @@ -409,6 +418,9 @@ importers: lil-gui: specifier: ^0.18.2 version: 0.18.2 + live-server: + specifier: ^1.2.2 + version: 1.2.2 minecraft-wrap: specifier: ^1.3.0 version: 1.5.1(encoding@0.1.13) @@ -482,12 +494,12 @@ packages: resolution: {integrity: sha512-Xk1sIhyNC/esHGGVjL/niHLowM0csl/kFO5uawBy4IrWwy0o1G8LGt3jP6nmWGz+USxeeqbihAmp/oVZju6wug==} hasBin: true - '@azure/msal-common@14.9.0': - resolution: {integrity: sha512-yzBPRlWPnTBeixxLNI3BBIgF5/bHpbhoRVuuDBnYjCyWRavaPUsKAHUDYLqpGkBLDciA6TCc6GOxN4/S3WiSxg==} + '@azure/msal-common@14.7.0': + resolution: {integrity: sha512-WexujW5jKWib7xtIxR7fEVyd5xcA3FNwenELy2HO4YC/ivTFdsEcDhtpKQuRUHqXRwxoqBblyZzTAhBm4v6fHA==} engines: {node: '>=0.8.0'} - '@azure/msal-node@2.7.0': - resolution: {integrity: sha512-wXD8LkUvHICeSWZydqg6o8Yvv+grlBEcmLGu+QEI4FcwFendbTEZrlSygnAXXSOCVaGAirWLchca35qrgpO6Jw==} + '@azure/msal-node@2.6.3': + resolution: {integrity: sha512-ojjJqUwb297T5Tcln4PbJANFEqRXfbQXcyOrtdr1HQYIo+dSuCT/o0nG6bFVihf6fcNykDwJLCQPVXzTkx/oGg==} engines: {node: '>=16'} '@babel/code-frame@7.22.13': @@ -1161,8 +1173,8 @@ packages: resolution: {integrity: sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA==} engines: {node: '>=6.9.0'} - '@babel/runtime@7.24.5': - resolution: {integrity: sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==} + '@babel/runtime@7.23.9': + resolution: {integrity: sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==} engines: {node: '>=6.9.0'} '@babel/template@7.22.5': @@ -1707,17 +1719,23 @@ packages: '@floating-ui/core@1.5.0': resolution: {integrity: sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg==} + '@floating-ui/core@1.6.0': + resolution: {integrity: sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==} + '@floating-ui/dom@1.5.3': resolution: {integrity: sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==} + '@floating-ui/dom@1.6.1': + resolution: {integrity: sha512-iA8qE43/H5iGozC3W0YSnVSW42Vh522yyM1gj+BqRwVsTNOyr231PsXDaV04yT39PsO0QL2QpbI/M0ZaLUQgRQ==} + '@floating-ui/react-dom@2.0.2': resolution: {integrity: sha512-5qhlDvjaLmAst/rKb3VdlCinwTF4EYMiVxuuc/HVUjs46W0zgtbMmAZ1UTsDrRTxRmUEzl92mOtWbeeXL26lSQ==} peerDependencies: react: ^18.2.0 react-dom: '>=16.8.0' - '@floating-ui/react-dom@2.0.9': - resolution: {integrity: sha512-q0umO0+LQK4+p6aGyvzASqKbKOJcAHJ7ycE9CuUvfx3s9zTHWmGJTPOIlM/hmSBfUfg/XfY5YhLBLR/LHwShQQ==} + '@floating-ui/react-dom@2.0.8': + resolution: {integrity: sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==} peerDependencies: react: ^18.2.0 react-dom: '>=16.8.0' @@ -1731,6 +1749,9 @@ packages: '@floating-ui/utils@0.1.6': resolution: {integrity: sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==} + '@floating-ui/utils@0.2.1': + resolution: {integrity: sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==} + '@gar/promisify@1.1.3': resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==} @@ -1983,6 +2004,12 @@ packages: resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==} hasBin: true + '@math.gl/core@4.0.1': + resolution: {integrity: sha512-9IewNjR9V66o+gYIIq5agFoHy6ZT6DRpRGQBfsUpZz4glAqOjVt64he8GGzjpmqfT+kKT4qwQ7nQl/hZLF15qA==} + + '@math.gl/types@4.0.1': + resolution: {integrity: sha512-E9qBKAjVBiZD8Is7TbygiLGtYBP3GSLus6RUJSuzFQegdYXeVagvrs4UkBJxhrRAxw4crfH0Tq7IhTMKuuJNQw==} + '@mdx-js/react@2.3.0': resolution: {integrity: sha512-zQH//gdOmuu7nt2oJR29vFhDv88oGPmVw6BggmrHeMI+xgEkp1B2dX9/bMBSYtK0dyLX/aOmesKS09g222K1/g==} peerDependencies: @@ -2981,8 +3008,8 @@ packages: '@types/pretty-hrtime@1.0.1': resolution: {integrity: sha512-VjID5MJb1eGKthz2qUerWT8+R4b9N+CHvGCzg9fn4kWZgaF9AhdYikQio3R7wV8YY1NsQKPaCwKz1Yff+aHNUQ==} - '@types/prop-types@15.7.12': - resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==} + '@types/prop-types@15.7.11': + resolution: {integrity: sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==} '@types/prop-types@15.7.5': resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} @@ -3005,8 +3032,8 @@ packages: '@types/react@18.2.20': resolution: {integrity: sha512-WKNtmsLWJM/3D5mG4U84cysVY31ivmyw85dE84fOCk5Hx78wezB/XEjVPWl2JTZ5FkEeaTJf+VgUAUn3PE7Isw==} - '@types/readable-stream@4.0.12': - resolution: {integrity: sha512-SCaw+bs9o/HCX1eTa3glTcQgW1oPxof49mqP2Qikik3xzTimNv2M4p43BQHhBuf7CwOJdQW0s1SrWU3MZxz6lw==} + '@types/readable-stream@4.0.10': + resolution: {integrity: sha512-AbUKBjcC8SHmImNi4yK2bbjogQlkFSg7shZCcicxPQapniOlajG8GCc39lvXzCWX4lLRRs7DM3VAeSlqmEVZUA==} '@types/resolve@1.17.1': resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} @@ -3219,6 +3246,9 @@ packages: '@webassemblyjs/wast-printer@1.12.1': resolution: {integrity: sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==} + '@webgpu/types@0.1.44': + resolution: {integrity: sha512-JDpYJN5E/asw84LTYhKyvPpxGnD+bAKPtpW9Ilurf7cZpxaTbxkQcGwOd7jgB9BPBrTYQ+32ufo4HiuomTjHNQ==} + '@xboxreplay/errors@0.1.0': resolution: {integrity: sha512-Tgz1d/OIPDWPeyOvuL5+aai5VCcqObhPnlI3skQuf80GVF3k1I0lPCnGC+8Cm5PV9aLBT5m8qPcJoIUQ2U4y9g==} @@ -3425,10 +3455,21 @@ packages: any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + anymatch@2.0.0: + resolution: {integrity: sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==} + anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} + apache-crypt@1.2.6: + resolution: {integrity: sha512-072WetlM4blL8PREJVeY+WHiUh1R5VNt2HfceGS8aKqttPHcmqE5pkKuXPz/ULmJOFkc8Hw3kfKl6vy7Qka6DA==} + engines: {node: '>=8'} + + apache-md5@1.1.8: + resolution: {integrity: sha512-FCAJojipPn0bXjuEpjOOOMN8FZDkxfWWp4JGN9mifU2IhxvKyXZYqpzPHdnTSUpmPDy+tsslB6Z1g+Vg6nVbYA==} + engines: {node: '>=8'} + app-root-dir@1.0.2: resolution: {integrity: sha512-jlpIfsOoNoafl92Sz//64uQHGSyMrD2vYG5d8o2a4qGvyNCvXur7bzIsWtAC/6flI2RYAp3kv8rsfBtaLm7w0g==} @@ -3456,6 +3497,18 @@ packages: resolution: {integrity: sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ==} engines: {node: '>=10'} + arr-diff@4.0.0: + resolution: {integrity: sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==} + engines: {node: '>=0.10.0'} + + arr-flatten@1.1.0: + resolution: {integrity: sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==} + engines: {node: '>=0.10.0'} + + arr-union@3.1.0: + resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==} + engines: {node: '>=0.10.0'} + array-buffer-byte-length@1.0.0: resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} @@ -3470,17 +3523,13 @@ packages: resolution: {integrity: sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==} engines: {node: '>= 0.4'} - array-includes@3.1.8: - resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} - engines: {node: '>= 0.4'} - array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} - array.prototype.findlast@1.2.5: - resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} - engines: {node: '>= 0.4'} + array-unique@0.3.2: + resolution: {integrity: sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==} + engines: {node: '>=0.10.0'} array.prototype.flat@1.3.2: resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} @@ -3490,9 +3539,6 @@ packages: resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} engines: {node: '>= 0.4'} - array.prototype.toreversed@1.1.2: - resolution: {integrity: sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==} - array.prototype.tosorted@1.1.3: resolution: {integrity: sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==} @@ -3533,6 +3579,10 @@ packages: assertion-error@1.1.0: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + assign-symbols@1.0.0: + resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==} + engines: {node: '>=0.10.0'} + ast-types@0.14.2: resolution: {integrity: sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA==} engines: {node: '>=4'} @@ -3549,6 +3599,9 @@ packages: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} + async-each@1.0.6: + resolution: {integrity: sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==} + async-limiter@1.0.1: resolution: {integrity: sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==} @@ -3558,6 +3611,9 @@ packages: async@3.2.5: resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==} + asynciterator.prototype@1.0.0: + resolution: {integrity: sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==} + asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} @@ -3565,6 +3621,11 @@ packages: resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} engines: {node: '>= 4.0.0'} + atob@2.1.2: + resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} + engines: {node: '>= 4.5.0'} + hasBin: true + available-typed-arrays@1.0.5: resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} engines: {node: '>= 0.4'} @@ -3633,13 +3694,23 @@ packages: resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==} engines: {node: ^4.5.0 || >= 5.9} + base@0.11.2: + resolution: {integrity: sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==} + engines: {node: '>=0.10.0'} + basic-auth@2.0.1: resolution: {integrity: sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==} engines: {node: '>= 0.8'} + batch@0.6.1: + resolution: {integrity: sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==} + bcrypt-pbkdf@1.0.2: resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} + bcryptjs@2.4.3: + resolution: {integrity: sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==} + better-opn@3.0.2: resolution: {integrity: sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==} engines: {node: '>=12.0.0'} @@ -3648,6 +3719,10 @@ packages: resolution: {integrity: sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==} engines: {node: '>=0.6'} + binary-extensions@1.13.1: + resolution: {integrity: sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==} + engines: {node: '>=0.10.0'} + binary-extensions@2.2.0: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} engines: {node: '>=8'} @@ -3700,6 +3775,10 @@ packages: brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + braces@2.3.2: + resolution: {integrity: sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==} + engines: {node: '>=0.10.0'} + braces@3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} engines: {node: '>=8'} @@ -3804,6 +3883,10 @@ packages: resolution: {integrity: sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + cache-base@1.0.1: + resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==} + engines: {node: '>=0.10.0'} + cachedir@2.4.0: resolution: {integrity: sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==} engines: {node: '>=6'} @@ -3882,6 +3965,10 @@ packages: resolution: {integrity: sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==} engines: {node: '>= 0.8.0'} + chokidar@2.1.8: + resolution: {integrity: sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==} + deprecated: Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies + chokidar@3.5.3: resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} engines: {node: '>= 8.10.0'} @@ -3904,6 +3991,10 @@ packages: cipher-base@1.0.4: resolution: {integrity: sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==} + class-utils@0.3.6: + resolution: {integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==} + engines: {node: '>=0.10.0'} + classnames@2.5.1: resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} @@ -3950,10 +4041,14 @@ packages: resolution: {integrity: sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==} engines: {node: '>=6'} - clsx@2.1.1: - resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + clsx@2.1.0: + resolution: {integrity: sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==} engines: {node: '>=6'} + collection-visit@1.0.0: + resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==} + engines: {node: '>=0.10.0'} + color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} @@ -4037,6 +4132,10 @@ packages: confusing-browser-globals@1.0.11: resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==} + connect@3.7.0: + resolution: {integrity: sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==} + engines: {node: '>= 0.10.0'} + console-browserify@1.2.0: resolution: {integrity: sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==} @@ -4078,6 +4177,10 @@ packages: resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} engines: {node: '>= 0.6'} + copy-descriptor@0.1.1: + resolution: {integrity: sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==} + engines: {node: '>=0.10.0'} + copy-to-clipboard@3.3.3: resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==} @@ -4254,6 +4357,10 @@ packages: decode-named-character-reference@1.0.2: resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} + decode-uri-component@0.2.2: + resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} + engines: {node: '>=0.10'} + decompress-response@4.2.1: resolution: {integrity: sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==} engines: {node: '>=8'} @@ -4300,6 +4407,18 @@ packages: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} + define-property@0.2.5: + resolution: {integrity: sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==} + engines: {node: '>=0.10.0'} + + define-property@1.0.0: + resolution: {integrity: sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==} + engines: {node: '>=0.10.0'} + + define-property@2.0.2: + resolution: {integrity: sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==} + engines: {node: '>=0.10.0'} + defu@6.1.2: resolution: {integrity: sha512-+uO4+qr7msjNNWKYPHqN/3+Dx3NFkmIzayk2L1MyZQlvgZb/J1A0fo410dpKrN2SnqFjt8n4JL8fDJE0wIgjFQ==} @@ -4314,6 +4433,10 @@ packages: delegates@1.0.0: resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + depd@1.1.2: + resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} + engines: {node: '>= 0.6'} + depd@2.0.0: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} @@ -4561,8 +4684,8 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} - es-iterator-helpers@1.0.19: - resolution: {integrity: sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==} + es-iterator-helpers@1.0.17: + resolution: {integrity: sha512-lh7BsUqelv4KUbR5a/ZTaGGIMLCjPGPqJ6q+Oq24YP0RdyptX1uzm4vvaqzk7Zx3bpl/76YLTTDj9L7uYQ92oQ==} engines: {node: '>= 0.4'} es-module-lexer@0.9.3: @@ -4755,8 +4878,8 @@ packages: peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 - eslint-plugin-react@7.34.1: - resolution: {integrity: sha512-N97CxlouPT1AHt8Jn0mhhN2RrADlUAsk1/atcT2KyA/l9Q/E6ll7OIGwNumFmWfZ9skV3XXccYS19h80rHtgkw==} + eslint-plugin-react@7.33.2: + resolution: {integrity: sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==} engines: {node: '>=4'} peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 @@ -4841,6 +4964,9 @@ packages: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} + event-stream@3.3.4: + resolution: {integrity: sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==} + event-target-shim@5.0.1: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} @@ -4877,6 +5003,10 @@ packages: resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} engines: {node: '>=6'} + expand-brackets@2.1.4: + resolution: {integrity: sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==} + engines: {node: '>=0.10.0'} + expand-template@2.0.3: resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} engines: {node: '>=6'} @@ -4894,9 +5024,21 @@ packages: resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==} engines: {node: '>= 0.10.0'} + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + + extend-shallow@3.0.2: + resolution: {integrity: sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==} + engines: {node: '>=0.10.0'} + extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + extglob@2.0.4: + resolution: {integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==} + engines: {node: '>=0.10.0'} + extract-zip@1.7.0: resolution: {integrity: sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==} hasBin: true @@ -4935,6 +5077,10 @@ packages: fastq@1.15.0: resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} + faye-websocket@0.11.4: + resolution: {integrity: sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==} + engines: {node: '>=0.8.0'} + fb-watchman@2.0.2: resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} @@ -4972,10 +5118,18 @@ packages: resolution: {integrity: sha512-6RS9gDchbn+qWmtV2uSjo5vmKizgfCQeb5jKmqx8HyzA3MoLqqyQxN+QcjkGBJt7FjJ9qFce67Auyya5rRRbpw==} engines: {node: '>= 10.4.0'} + fill-range@4.0.0: + resolution: {integrity: sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==} + engines: {node: '>=0.10.0'} + fill-range@7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} engines: {node: '>=8'} + finalhandler@1.1.2: + resolution: {integrity: sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==} + engines: {node: '>= 0.8'} + finalhandler@1.2.0: resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} engines: {node: '>= 0.8'} @@ -5026,6 +5180,15 @@ packages: debug: optional: true + follow-redirects@1.15.5: + resolution: {integrity: sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + follow-redirects@1.15.6: resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} engines: {node: '>=4.0'} @@ -5038,6 +5201,10 @@ packages: for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + for-in@1.0.2: + resolution: {integrity: sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==} + engines: {node: '>=0.10.0'} + foreground-child@2.0.0: resolution: {integrity: sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==} engines: {node: '>=8.0.0'} @@ -5068,10 +5235,17 @@ packages: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} + fragment-cache@0.2.1: + resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==} + engines: {node: '>=0.10.0'} + fresh@0.5.2: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} + from@0.1.7: + resolution: {integrity: sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==} + fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} @@ -5101,6 +5275,12 @@ packages: fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + fsevents@1.2.13: + resolution: {integrity: sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==} + engines: {node: '>= 4.0'} + os: [darwin] + deprecated: The v1 package contains DANGEROUS / INSECURE binaries. Upgrade to safe fsevents v2 + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -5183,6 +5363,10 @@ packages: get-tsconfig@4.7.2: resolution: {integrity: sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==} + get-value@2.0.6: + resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==} + engines: {node: '>=0.10.0'} + getos@3.2.1: resolution: {integrity: sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==} @@ -5203,6 +5387,9 @@ packages: resolution: {integrity: sha512-yBbfpChOtFvg5D+KtMaBFvj6yt3vUnheNAH+UrQH2TfDB8kr0tERdL0Tjhe0W7xJ6jR6ftQBluTZR9jXUnKe8g==} engines: {node: '>=14.0.0'} + glob-parent@3.1.0: + resolution: {integrity: sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -5251,10 +5438,6 @@ packages: resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} engines: {node: '>= 0.4'} - globalthis@1.0.4: - resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} - engines: {node: '>= 0.4'} - globby@11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} @@ -5334,6 +5517,22 @@ packages: has-unicode@2.0.1: resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} + has-value@0.3.1: + resolution: {integrity: sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==} + engines: {node: '>=0.10.0'} + + has-value@1.0.0: + resolution: {integrity: sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==} + engines: {node: '>=0.10.0'} + + has-values@0.1.4: + resolution: {integrity: sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==} + engines: {node: '>=0.10.0'} + + has-values@1.0.0: + resolution: {integrity: sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==} + engines: {node: '>=0.10.0'} + has@1.0.3: resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} engines: {node: '>= 0.4.0'} @@ -5388,16 +5587,27 @@ packages: resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} engines: {node: '>=8'} + http-auth@3.1.3: + resolution: {integrity: sha512-Jbx0+ejo2IOx+cRUYAGS1z6RGc6JfYUNkysZM4u4Sfk1uLlGv814F7/PIjQQAuThLdAWxb74JMGd5J8zex1VQg==} + engines: {node: '>=4.6.1'} + http-browserify@1.7.0: resolution: {integrity: sha512-Irf/LJXmE3cBzU1eaR4+NEX6bmVLqt1wkmDiA7kBwH7zmb0D8kBAXsDmQ88hhj/qv9iEZKlyGx/hrMcFi8sOHw==} http-cache-semantics@4.1.1: resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} + http-errors@1.6.3: + resolution: {integrity: sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==} + engines: {node: '>= 0.6'} + http-errors@2.0.0: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} + http-parser-js@0.5.8: + resolution: {integrity: sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==} + http-proxy-agent@5.0.0: resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} engines: {node: '>= 6'} @@ -5498,6 +5708,9 @@ packages: inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + inherits@2.0.3: + resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} + inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -5533,6 +5746,10 @@ packages: resolution: {integrity: sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==} engines: {node: '>=8'} + is-accessor-descriptor@1.0.1: + resolution: {integrity: sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==} + engines: {node: '>= 0.10'} + is-arguments@1.1.1: resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} engines: {node: '>= 0.4'} @@ -5557,6 +5774,10 @@ packages: is-bigint@1.0.4: resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + is-binary-path@1.0.1: + resolution: {integrity: sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==} + engines: {node: '>=0.10.0'} + is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} @@ -5565,6 +5786,9 @@ packages: resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} engines: {node: '>= 0.4'} + is-buffer@1.1.6: + resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} + is-builtin-module@3.2.1: resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} engines: {node: '>=6'} @@ -5583,6 +5807,10 @@ packages: is-core-module@2.13.1: resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + is-data-descriptor@1.0.1: + resolution: {integrity: sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==} + engines: {node: '>= 0.4'} + is-data-view@1.0.1: resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} engines: {node: '>= 0.4'} @@ -5594,11 +5822,27 @@ packages: is-deflate@1.0.0: resolution: {integrity: sha512-YDoFpuZWu1VRXlsnlYMzKyVRITXj7Ej/V9gXQ2/pAe7X1J7M/RNOqaIYi6qUn+B7nGyB9pDXrv02dsB58d2ZAQ==} + is-descriptor@0.1.7: + resolution: {integrity: sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==} + engines: {node: '>= 0.4'} + + is-descriptor@1.0.3: + resolution: {integrity: sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==} + engines: {node: '>= 0.4'} + is-docker@2.2.1: resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} engines: {node: '>=8'} hasBin: true + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + + is-extendable@1.0.1: + resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==} + engines: {node: '>=0.10.0'} + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -5617,6 +5861,10 @@ packages: resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} engines: {node: '>= 0.4'} + is-glob@3.1.0: + resolution: {integrity: sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==} + engines: {node: '>=0.10.0'} + is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -5636,9 +5884,8 @@ packages: is-lambda@1.0.1: resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} - is-map@2.0.3: - resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} - engines: {node: '>= 0.4'} + is-map@2.0.2: + resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==} is-module@1.0.0: resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} @@ -5659,6 +5906,10 @@ packages: resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} engines: {node: '>= 0.4'} + is-number@3.0.0: + resolution: {integrity: sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==} + engines: {node: '>=0.10.0'} + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -5699,9 +5950,8 @@ packages: resolution: {integrity: sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==} engines: {node: '>=0.10.0'} - is-set@2.0.3: - resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} - engines: {node: '>= 0.4'} + is-set@2.0.2: + resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==} is-shared-array-buffer@1.0.2: resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} @@ -5737,16 +5987,22 @@ packages: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} - is-weakmap@2.0.2: - resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} - engines: {node: '>= 0.4'} + is-weakmap@2.0.1: + resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==} is-weakref@1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} - is-weakset@2.0.3: - resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==} - engines: {node: '>= 0.4'} + is-weakset@2.0.2: + resolution: {integrity: sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==} + + is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + + is-wsl@1.1.0: + resolution: {integrity: sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==} + engines: {node: '>=4'} is-wsl@2.2.0: resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} @@ -5767,6 +6023,10 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + isobject@2.1.0: + resolution: {integrity: sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==} + engines: {node: '>=0.10.0'} + isobject@3.0.1: resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} engines: {node: '>=0.10.0'} @@ -5948,6 +6208,14 @@ packages: keyv@4.5.3: resolution: {integrity: sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==} + kind-of@3.2.2: + resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} + engines: {node: '>=0.10.0'} + + kind-of@4.0.0: + resolution: {integrity: sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==} + engines: {node: '>=0.10.0'} + kind-of@6.0.3: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} @@ -5996,6 +6264,11 @@ packages: enquirer: optional: true + live-server@1.2.2: + resolution: {integrity: sha512-t28HXLjITRGoMSrCOv4eZ88viHaBVIjKjdI5PO92Vxlu+twbk6aE0t7dVIaz6ZWkjPilYFV6OSdMYl9ybN2B4w==} + engines: {node: '>=0.10.0'} + hasBin: true + load-bmfont@1.4.1: resolution: {integrity: sha512-8UyQoYmdRDy81Brz6aLAUhfZLwr5zV0L3taTQ4hju7m6biuwiWiJXjPhBJxbUQJA8PrkvJ/7Enqmwk2sM14soA==} @@ -6140,6 +6413,10 @@ packages: makeerror@1.0.12: resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + map-cache@0.2.2: + resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} + engines: {node: '>=0.10.0'} + map-obj@1.0.1: resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} engines: {node: '>=0.10.0'} @@ -6151,6 +6428,13 @@ packages: map-or-similar@1.5.0: resolution: {integrity: sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==} + map-stream@0.1.0: + resolution: {integrity: sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==} + + map-visit@1.0.0: + resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==} + engines: {node: '>=0.10.0'} + markdown-it@14.0.0: resolution: {integrity: sha512-seFjF0FIcPt4P9U39Bq1JYblX0KZCjDLFFQPHpL5AzHpqPEKtosxmdq/LTVZnjfH7tjt9BxStm+wXcDBNuYmzw==} hasBin: true @@ -6161,6 +6445,9 @@ packages: peerDependencies: react: ^18.2.0 + math.gl@4.0.1: + resolution: {integrity: sha512-Yvw1HfmsDePxwhCBvGT8teyPN0mwxcxUaWLoDaRuZYxoUYa9HRg+6ywBS+yXopC0wIS9MFi+BCVKP8hdJpaJjw==} + mc-assets@0.2.5: resolution: {integrity: sha512-HZ4Q1zqbib2ySSorCb+vMkBZAGXTTZIlcSfGq/L15fkg+l+KKslLSivWfFlCXdg9bzGc0x5WeQN3kKWfZmyuFg==} engines: {node: '>=18.0.0'} @@ -6299,6 +6586,10 @@ packages: micromark@4.0.0: resolution: {integrity: sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==} + micromatch@3.1.10: + resolution: {integrity: sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==} + engines: {node: '>=0.10.0'} + micromatch@4.0.5: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} engines: {node: '>=8.6'} @@ -6447,6 +6738,10 @@ packages: resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} engines: {node: '>= 8'} + mixin-deep@1.3.2: + resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==} + engines: {node: '>=0.10.0'} + mkdirp-classic@0.5.3: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} @@ -6477,6 +6772,10 @@ packages: moo@0.5.2: resolution: {integrity: sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==} + morgan@1.10.0: + resolution: {integrity: sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==} + engines: {node: '>= 0.8.0'} + mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} @@ -6512,6 +6811,10 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + nanomatch@1.2.13: + resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==} + engines: {node: '>=0.10.0'} + napi-build-utils@1.0.2: resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==} @@ -6622,6 +6925,10 @@ packages: resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==} engines: {node: '>=10'} + normalize-path@2.1.1: + resolution: {integrity: sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==} + engines: {node: '>=0.10.0'} + normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -6649,6 +6956,10 @@ packages: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} + object-copy@0.1.0: + resolution: {integrity: sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==} + engines: {node: '>=0.10.0'} + object-inspect@1.12.3: resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} @@ -6663,6 +6974,10 @@ packages: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} + object-visit@1.0.1: + resolution: {integrity: sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==} + engines: {node: '>=0.10.0'} + object.assign@4.1.4: resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} engines: {node: '>= 0.4'} @@ -6671,17 +6986,20 @@ packages: resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} engines: {node: '>= 0.4'} - object.entries@1.1.8: - resolution: {integrity: sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==} + object.entries@1.1.7: + resolution: {integrity: sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==} engines: {node: '>= 0.4'} - object.fromentries@2.0.8: - resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + object.fromentries@2.0.7: + resolution: {integrity: sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==} engines: {node: '>= 0.4'} - object.hasown@1.1.4: - resolution: {integrity: sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==} - engines: {node: '>= 0.4'} + object.hasown@1.1.3: + resolution: {integrity: sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==} + + object.pick@1.3.0: + resolution: {integrity: sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==} + engines: {node: '>=0.10.0'} object.values@1.1.7: resolution: {integrity: sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==} @@ -6694,6 +7012,10 @@ packages: omggif@1.0.10: resolution: {integrity: sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==} + on-finished@2.3.0: + resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==} + engines: {node: '>= 0.8'} + on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} @@ -6717,6 +7039,11 @@ packages: resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==} hasBin: true + opn@6.0.0: + resolution: {integrity: sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==} + engines: {node: '>=8'} + deprecated: The package has been renamed to `open` + optionator@0.9.3: resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} engines: {node: '>= 0.8.0'} @@ -6815,12 +7142,19 @@ packages: pascal-case@3.1.2: resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} + pascalcase@0.1.1: + resolution: {integrity: sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==} + engines: {node: '>=0.10.0'} + path-browserify@1.0.1: resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} path-case@3.0.4: resolution: {integrity: sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==} + path-dirname@1.0.2: + resolution: {integrity: sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==} + path-exists-cli@2.0.0: resolution: {integrity: sha512-qGr0A87KYCznmvabblxyxnzA/MtPZ28wH+4SCMP4tjTFAbzqwvs5xpUZExAYzq5OgHe5vIswzdH5iosCb8YF/Q==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -6874,6 +7208,9 @@ packages: pathval@1.1.1: resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + pause-stream@0.0.11: + resolution: {integrity: sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==} + pbkdf2@3.1.2: resolution: {integrity: sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==} engines: {node: '>=0.12'} @@ -6970,6 +7307,10 @@ packages: resolution: {integrity: sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==} engines: {node: '>= 0.12.0'} + posix-character-classes@0.1.1: + resolution: {integrity: sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==} + engines: {node: '>=0.10.0'} + possible-typed-array-names@1.0.0: resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} engines: {node: '>= 0.4'} @@ -7020,8 +7361,8 @@ packages: resolution: {integrity: sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==} engines: {node: '>= 0.8'} - prismarine-auth@2.4.2: - resolution: {integrity: sha512-Cq4woGobnFYYfMBDh1WITW+Vs98toN91qAFBvBitwV7IwJaiSAh2Nl+WPUEGeg5eLBoSPpSyCVT8P2oi7Cav8g==} + prismarine-auth@2.4.1: + resolution: {integrity: sha512-DwDI3Ucxf/eThJJo5QVzlywFrJulL1fK1z6F8bybvddim8YgudRksQc3w4cE2m0hPPHfE1BRd5lh1NpedrixMQ==} prismarine-biome@1.3.0: resolution: {integrity: sha512-GY6nZxq93mTErT7jD7jt8YS1aPrOakbJHh39seYsJFXvueIOdHAmW16kYQVrTVMW5MlWLQVxV/EquRwOgr4MnQ==} @@ -7189,6 +7530,10 @@ packages: proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + proxy-middleware@0.15.0: + resolution: {integrity: sha512-EGCG8SeoIRVMhsqHQUdDigB2i7qU7fCsWASwn54+nPutYO8n4q6EiwMzyfWlC+dzRFExP+kvcnDFdBDHoZBU7Q==} + engines: {node: '>=0.8.0'} + psl@1.9.0: resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} @@ -7465,6 +7810,10 @@ packages: resolution: {integrity: sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + readdirp@2.2.1: + resolution: {integrity: sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==} + engines: {node: '>=0.10'} + readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} @@ -7507,6 +7856,10 @@ packages: regenerator-transform@0.15.2: resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} + regex-not@1.0.2: + resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==} + engines: {node: '>=0.10.0'} + regexp-tree@0.1.27: resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} hasBin: true @@ -7550,6 +7903,17 @@ packages: remark@15.0.1: resolution: {integrity: sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A==} + remove-trailing-separator@1.1.0: + resolution: {integrity: sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==} + + repeat-element@1.1.4: + resolution: {integrity: sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==} + engines: {node: '>=0.10.0'} + + repeat-string@1.6.1: + resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} + engines: {node: '>=0.10'} + request-progress@3.0.0: resolution: {integrity: sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==} @@ -7578,6 +7942,10 @@ packages: resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + resolve-url@0.2.1: + resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==} + deprecated: https://github.com/lydell/resolve-url#deprecated + resolve@1.22.4: resolution: {integrity: sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==} hasBin: true @@ -7674,6 +8042,9 @@ packages: resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} engines: {node: '>= 0.4'} + safe-regex@1.1.0: + resolution: {integrity: sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==} + safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} @@ -7734,6 +8105,10 @@ packages: serialize-javascript@6.0.2: resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + serve-index@1.9.1: + resolution: {integrity: sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==} + engines: {node: '>= 0.8.0'} + serve-static@1.15.0: resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} engines: {node: '>= 0.8.0'} @@ -7749,17 +8124,20 @@ packages: resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==} engines: {node: '>= 0.4'} - set-function-name@2.0.2: - resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} - engines: {node: '>= 0.4'} - set-harmonic-interval@1.0.1: resolution: {integrity: sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g==} engines: {node: '>=6.9'} + set-value@2.0.1: + resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} + engines: {node: '>=0.10.0'} + setimmediate@1.0.5: resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + setprototypeof@1.1.0: + resolution: {integrity: sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==} + setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} @@ -7801,10 +8179,6 @@ packages: resolution: {integrity: sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==} engines: {node: '>= 0.4'} - side-channel@1.0.6: - resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} - engines: {node: '>= 0.4'} - siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -7859,6 +8233,18 @@ packages: snake-case@3.0.4: resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} + snapdragon-node@2.1.1: + resolution: {integrity: sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==} + engines: {node: '>=0.10.0'} + + snapdragon-util@3.0.1: + resolution: {integrity: sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==} + engines: {node: '>=0.10.0'} + + snapdragon@0.8.2: + resolution: {integrity: sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==} + engines: {node: '>=0.10.0'} + socket.io-adapter@1.1.2: resolution: {integrity: sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==} @@ -7906,9 +8292,17 @@ packages: resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} engines: {node: '>=0.10.0'} + source-map-resolve@0.5.3: + resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==} + deprecated: See https://github.com/lydell/source-map-resolve#deprecated + source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + source-map-url@0.4.1: + resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==} + deprecated: See https://github.com/lydell/source-map-url#deprecated + source-map@0.5.6: resolution: {integrity: sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==} engines: {node: '>=0.10.0'} @@ -7944,6 +8338,13 @@ packages: spdx-license-ids@3.0.13: resolution: {integrity: sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==} + split-string@3.1.0: + resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==} + engines: {node: '>=0.10.0'} + + split@0.3.3: + resolution: {integrity: sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==} + sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} @@ -7971,12 +8372,20 @@ packages: stacktrace-js@2.0.2: resolution: {integrity: sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==} + static-extend@0.1.2: + resolution: {integrity: sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==} + engines: {node: '>=0.10.0'} + stats-gl@1.0.5: resolution: {integrity: sha512-XimMxvwnf1Qf5KwebhcoA34kcX+fWEkIl0QjNkCbu4IpoyDMMsOajExn7FIq5w569k45+LhmsuRlGSrsvmGdNw==} stats.js@0.17.0: resolution: {integrity: sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw==} + statuses@1.5.0: + resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} + engines: {node: '>= 0.6'} + statuses@2.0.1: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} @@ -7994,6 +8403,9 @@ packages: stream-browserify@3.0.0: resolution: {integrity: sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==} + stream-combiner@0.0.4: + resolution: {integrity: sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==} + stream-http@3.2.0: resolution: {integrity: sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==} @@ -8014,10 +8426,6 @@ packages: string.prototype.matchall@4.0.10: resolution: {integrity: sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==} - string.prototype.matchall@4.0.11: - resolution: {integrity: sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==} - engines: {node: '>= 0.4'} - string.prototype.padend@3.1.4: resolution: {integrity: sha512-67otBXoksdjsnXXRUq+KMVTdlVRZ2af422Y0aTyTjVaoQkGr3mxl2Bc5emi7dOQ3OGVVQQskmLEWwFXwommpNw==} engines: {node: '>= 0.4'} @@ -8117,8 +8525,8 @@ packages: synchronous-promise@2.0.17: resolution: {integrity: sha512-AsS729u2RHUfEra9xJrE39peJcc2stq2+poBXX8bcM08Y6g9j/i/PUzwNQqkaJde7Ntg1TO7bSREbR5sdosQ+g==} - systeminformation@5.22.7: - resolution: {integrity: sha512-AWxlP05KeHbpGdgvZkcudJpsmChc2Y5Eo/GvxG/iUA/Aws5LZKHAMSeAo+V+nD+nxWZaxrwpWcnx4SH3oxNL3A==} + systeminformation@5.21.24: + resolution: {integrity: sha512-xQada8ByGGFoRXJaUptGgddn3i7IjtSdqNdCKzB8xkzsM7pHnfLYBWxkPdGzhZ0Z/l+W1yo+aZQZ74d2isj8kw==} engines: {node: '>=8.0.0'} os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android] hasBin: true @@ -8268,10 +8676,22 @@ packages: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} + to-object-path@0.3.0: + resolution: {integrity: sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==} + engines: {node: '>=0.10.0'} + + to-regex-range@2.1.1: + resolution: {integrity: sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==} + engines: {node: '>=0.10.0'} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + to-regex@3.0.2: + resolution: {integrity: sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==} + engines: {node: '>=0.10.0'} + tocbot@4.21.2: resolution: {integrity: sha512-R5Muhi/TUu4i4snWVrMgNoXyJm2f8sJfdgIkQvqb+cuIXQEIMAiWGWgCgYXHqX4+XiS/Bnm7IYZ9Zy6NVe6lhw==} @@ -8338,6 +8758,9 @@ packages: tweetnacl@0.14.5: resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} + twgl.js@5.5.4: + resolution: {integrity: sha512-6kFOmijOpmblTN9CCwOTCxK4lPg7rCyQjLuub6EMOlEp89Ex6yUcsMjsmH7andNPL2NE3XmHdqHeP5gVKKPhxw==} + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -8472,6 +8895,10 @@ packages: unified@11.0.4: resolution: {integrity: sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==} + union-value@1.0.1: + resolution: {integrity: sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==} + engines: {node: '>=0.10.0'} + union@0.5.0: resolution: {integrity: sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==} engines: {node: '>= 0.8.0'} @@ -8521,6 +8948,9 @@ packages: resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} engines: {node: '>= 10.0.0'} + unix-crypt-td-js@1.1.4: + resolution: {integrity: sha512-8rMeVYWSIyccIJscb9NdCfZKSRBKYTeVnwmiRYT2ulE3qd1RaDQ0xQDP+rI3ccIWbhu/zuo5cgN8z73belNZgw==} + unpipe@1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} @@ -8528,6 +8958,10 @@ packages: unplugin@1.5.0: resolution: {integrity: sha512-9ZdRwbh/4gcm1JTOkp9lAkIDrtOyOxgHmY7cjuwI8L/2RTikMcVG25GsZwNAgRuap3iDw2jeq7eoqtAsz5rW3A==} + unset-value@1.0.0: + resolution: {integrity: sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==} + engines: {node: '>=0.10.0'} + untildify@4.0.0: resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} engines: {node: '>=8'} @@ -8557,6 +8991,10 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + urix@0.1.0: + resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==} + deprecated: Please see https://github.com/lydell/urix#deprecated + url-join@4.0.1: resolution: {integrity: sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==} @@ -8612,6 +9050,10 @@ packages: typescript: optional: true + use@3.1.1: + resolution: {integrity: sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==} + engines: {node: '>=0.10.0'} + utf8-byte-length@1.0.4: resolution: {integrity: sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA==} @@ -8631,6 +9073,11 @@ packages: uuid-1345@1.0.2: resolution: {integrity: sha512-bA5zYZui+3nwAc0s3VdGQGBfbVsJLVX7Np7ch2aqcEWFi5lsAEcmO3+lx3djM1npgpZI8KY2FITZ2uYTnYUYyw==} + uuid@3.4.0: + resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} + deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. + hasBin: true + uuid@8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true @@ -8822,6 +9269,14 @@ packages: resolution: {integrity: sha512-gnmRz++suzmvxtp3ehQts6s2JtAGPuDPjA1F3a9ckNpG1kYdYuHWYpazoAnL9FS5/B21tKlhkorbdCXat0+4xQ==} engines: {node: '>=6.0.0', npm: '>=3.10.0'} + websocket-driver@0.7.4: + resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==} + engines: {node: '>=0.8.0'} + + websocket-extensions@0.1.4: + resolution: {integrity: sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==} + engines: {node: '>=0.8.0'} + whatwg-encoding@2.0.0: resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} engines: {node: '>=12'} @@ -8842,9 +9297,8 @@ packages: resolution: {integrity: sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==} engines: {node: '>= 0.4'} - which-collection@1.0.2: - resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} - engines: {node: '>= 0.4'} + which-collection@1.0.1: + resolution: {integrity: sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==} which-typed-array@1.1.11: resolution: {integrity: sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==} @@ -9108,11 +9562,11 @@ snapshots: dependencies: default-browser-id: 3.0.0 - '@azure/msal-common@14.9.0': {} + '@azure/msal-common@14.7.0': {} - '@azure/msal-node@2.7.0': + '@azure/msal-node@2.6.3': dependencies: - '@azure/msal-common': 14.9.0 + '@azure/msal-common': 14.7.0 jsonwebtoken: 9.0.2 uuid: 8.3.2 @@ -9911,7 +10365,7 @@ snapshots: dependencies: regenerator-runtime: 0.14.0 - '@babel/runtime@7.24.5': + '@babel/runtime@7.23.9': dependencies: regenerator-runtime: 0.14.0 @@ -10312,20 +10766,29 @@ snapshots: dependencies: '@floating-ui/utils': 0.1.6 + '@floating-ui/core@1.6.0': + dependencies: + '@floating-ui/utils': 0.2.1 + '@floating-ui/dom@1.5.3': dependencies: '@floating-ui/core': 1.5.0 '@floating-ui/utils': 0.1.6 + '@floating-ui/dom@1.6.1': + dependencies: + '@floating-ui/core': 1.6.0 + '@floating-ui/utils': 0.2.1 + '@floating-ui/react-dom@2.0.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: '@floating-ui/dom': 1.5.3 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - '@floating-ui/react-dom@2.0.9(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@floating-ui/react-dom@2.0.8(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: - '@floating-ui/dom': 1.5.3 + '@floating-ui/dom': 1.6.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -10339,6 +10802,8 @@ snapshots: '@floating-ui/utils@0.1.6': {} + '@floating-ui/utils@0.2.1': {} + '@gar/promisify@1.1.3': optional: true @@ -10771,6 +11236,12 @@ snapshots: - supports-color optional: true + '@math.gl/core@4.0.1': + dependencies: + '@math.gl/types': 4.0.1 + + '@math.gl/types@4.0.1': {} + '@mdx-js/react@2.3.0(react@18.2.0)': dependencies: '@types/mdx': 2.0.8 @@ -10797,12 +11268,12 @@ snapshots: '@mui/base@5.0.0-beta.40(@types/react@18.2.20)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: - '@babel/runtime': 7.24.5 - '@floating-ui/react-dom': 2.0.9(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@babel/runtime': 7.23.9 + '@floating-ui/react-dom': 2.0.8(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@mui/types': 7.2.14(@types/react@18.2.20) '@mui/utils': 5.15.14(@types/react@18.2.20)(react@18.2.0) '@popperjs/core': 2.11.8 - clsx: 2.1.1 + clsx: 2.1.0 prop-types: 15.8.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -10815,8 +11286,8 @@ snapshots: '@mui/utils@5.15.14(@types/react@18.2.20)(react@18.2.0)': dependencies: - '@babel/runtime': 7.24.5 - '@types/prop-types': 15.7.12 + '@babel/runtime': 7.23.9 + '@types/prop-types': 15.7.11 prop-types: 15.8.1 react: 18.2.0 react-is: 18.2.0 @@ -12221,7 +12692,7 @@ snapshots: '@types/pretty-hrtime@1.0.1': {} - '@types/prop-types@15.7.12': {} + '@types/prop-types@15.7.11': {} '@types/prop-types@15.7.5': {} @@ -12245,7 +12716,7 @@ snapshots: '@types/scheduler': 0.16.3 csstype: 3.1.2 - '@types/readable-stream@4.0.12': + '@types/readable-stream@4.0.10': dependencies: '@types/node': 20.12.8 safe-buffer: 5.1.2 @@ -12553,6 +13024,8 @@ snapshots: '@webassemblyjs/ast': 1.12.1 '@xtuc/long': 4.2.2 + '@webgpu/types@0.1.44': {} + '@xboxreplay/errors@0.1.0': {} '@xboxreplay/xboxlive-auth@3.3.3(debug@4.3.4)': @@ -12788,11 +13261,24 @@ snapshots: any-promise@1.3.0: {} + anymatch@2.0.0: + dependencies: + micromatch: 3.1.10 + normalize-path: 2.1.1 + transitivePeerDependencies: + - supports-color + anymatch@3.1.3: dependencies: normalize-path: 3.0.0 picomatch: 2.3.1 + apache-crypt@1.2.6: + dependencies: + unix-crypt-td-js: 1.1.4 + + apache-md5@1.1.8: {} + app-root-dir@1.0.2: {} aproba@2.0.0: @@ -12823,6 +13309,12 @@ snapshots: dependencies: tslib: 2.6.2 + arr-diff@4.0.0: {} + + arr-flatten@1.1.0: {} + + arr-union@3.1.0: {} + array-buffer-byte-length@1.0.0: dependencies: call-bind: 1.0.2 @@ -12843,25 +13335,9 @@ snapshots: get-intrinsic: 1.2.1 is-string: 1.0.7 - array-includes@3.1.8: - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.23.3 - es-object-atoms: 1.0.0 - get-intrinsic: 1.2.4 - is-string: 1.0.7 - array-union@2.1.0: {} - array.prototype.findlast@1.2.5: - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.23.3 - es-errors: 1.3.0 - es-object-atoms: 1.0.0 - es-shim-unscopables: 1.0.2 + array-unique@0.3.2: {} array.prototype.flat@1.3.2: dependencies: @@ -12877,13 +13353,6 @@ snapshots: es-abstract: 1.22.2 es-shim-unscopables: 1.0.0 - array.prototype.toreversed@1.1.2: - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.23.3 - es-shim-unscopables: 1.0.2 - array.prototype.tosorted@1.1.3: dependencies: call-bind: 1.0.7 @@ -12951,6 +13420,8 @@ snapshots: assertion-error@1.1.0: {} + assign-symbols@1.0.0: {} + ast-types@0.14.2: dependencies: tslib: 2.6.2 @@ -12966,6 +13437,8 @@ snapshots: astral-regex@2.0.0: optional: true + async-each@1.0.6: {} + async-limiter@1.0.1: {} async@2.6.4: @@ -12974,10 +13447,16 @@ snapshots: async@3.2.5: {} + asynciterator.prototype@1.0.0: + dependencies: + has-symbols: 1.0.3 + asynckit@0.4.0: {} at-least-node@1.0.0: {} + atob@2.1.2: {} + available-typed-arrays@1.0.5: {} available-typed-arrays@1.0.7: @@ -12992,7 +13471,7 @@ snapshots: axios@0.21.4(debug@4.3.4): dependencies: - follow-redirects: 1.15.6(debug@4.3.4) + follow-redirects: 1.15.5(debug@4.3.4) transitivePeerDependencies: - debug @@ -13062,21 +13541,37 @@ snapshots: base64id@2.0.0: {} + base@0.11.2: + dependencies: + cache-base: 1.0.1 + class-utils: 0.3.6 + component-emitter: 1.3.0 + define-property: 1.0.0 + isobject: 3.0.1 + mixin-deep: 1.3.2 + pascalcase: 0.1.1 + basic-auth@2.0.1: dependencies: safe-buffer: 5.1.2 + batch@0.6.1: {} + bcrypt-pbkdf@1.0.2: dependencies: tweetnacl: 0.14.5 optional: true + bcryptjs@2.4.3: {} + better-opn@3.0.2: dependencies: open: 8.4.2 big-integer@1.6.51: {} + binary-extensions@1.13.1: {} + binary-extensions@2.2.0: {} bindings@1.5.0: @@ -13158,6 +13653,21 @@ snapshots: dependencies: balanced-match: 1.0.2 + braces@2.3.2: + dependencies: + arr-flatten: 1.1.0 + array-unique: 0.3.2 + extend-shallow: 2.0.1 + fill-range: 4.0.0 + isobject: 3.0.1 + repeat-element: 1.1.4 + snapdragon: 0.8.2 + snapdragon-node: 2.1.1 + split-string: 3.1.0 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + braces@3.0.2: dependencies: fill-range: 7.0.1 @@ -13304,6 +13814,18 @@ snapshots: - bluebird optional: true + cache-base@1.0.1: + dependencies: + collection-visit: 1.0.0 + component-emitter: 1.3.0 + get-value: 2.0.6 + has-value: 1.0.0 + isobject: 3.0.1 + set-value: 2.0.1 + to-object-path: 0.3.0 + union-value: 1.0.1 + unset-value: 1.0.0 + cachedir@2.4.0: optional: true @@ -13422,6 +13944,24 @@ snapshots: check-more-types@2.24.0: optional: true + chokidar@2.1.8: + dependencies: + anymatch: 2.0.0 + async-each: 1.0.6 + braces: 2.3.2 + glob-parent: 3.1.0 + inherits: 2.0.4 + is-binary-path: 1.0.1 + is-glob: 4.0.3 + normalize-path: 3.0.0 + path-is-absolute: 1.0.1 + readdirp: 2.2.1 + upath: 1.2.0 + optionalDependencies: + fsevents: 1.2.13 + transitivePeerDependencies: + - supports-color + chokidar@3.5.3: dependencies: anymatch: 3.1.3 @@ -13447,6 +13987,13 @@ snapshots: inherits: 2.0.4 safe-buffer: 5.2.1 + class-utils@0.3.6: + dependencies: + arr-union: 3.1.0 + define-property: 0.2.5 + isobject: 3.0.1 + static-extend: 0.1.2 + classnames@2.5.1: {} clean-regexp@1.0.0: @@ -13495,7 +14042,12 @@ snapshots: clsx@1.1.1: {} - clsx@2.1.1: {} + clsx@2.1.0: {} + + collection-visit@1.0.0: + dependencies: + map-visit: 1.0.0 + object-visit: 1.0.1 color-convert@1.9.3: dependencies: @@ -13547,8 +14099,7 @@ snapshots: component-emitter@1.2.1: optional: true - component-emitter@1.3.0: - optional: true + component-emitter@1.3.0: {} component-inherit@0.0.3: optional: true @@ -13580,6 +14131,15 @@ snapshots: confusing-browser-globals@1.0.11: {} + connect@3.7.0: + dependencies: + debug: 2.6.9 + finalhandler: 1.1.2 + parseurl: 1.3.3 + utils-merge: 1.0.1 + transitivePeerDependencies: + - supports-color + console-browserify@1.2.0: {} console-control-strings@1.1.0: @@ -13620,6 +14180,8 @@ snapshots: cookie@0.5.0: {} + copy-descriptor@0.1.1: {} + copy-to-clipboard@3.3.3: dependencies: toggle-selection: 1.0.6 @@ -13876,6 +14438,8 @@ snapshots: dependencies: character-entities: 2.0.2 + decode-uri-component@0.2.2: {} + decompress-response@4.2.1: dependencies: mimic-response: 2.1.0 @@ -13924,6 +14488,19 @@ snapshots: has-property-descriptors: 1.0.0 object-keys: 1.1.1 + define-property@0.2.5: + dependencies: + is-descriptor: 0.1.7 + + define-property@1.0.0: + dependencies: + is-descriptor: 1.0.3 + + define-property@2.0.2: + dependencies: + is-descriptor: 1.0.3 + isobject: 3.0.1 + defu@6.1.2: {} del@6.1.1: @@ -13942,6 +14519,8 @@ snapshots: delegates@1.0.0: optional: true + depd@1.1.2: {} + depd@2.0.0: {} dequal@1.0.0: {} @@ -14189,7 +14768,7 @@ snapshots: dependencies: '@types/cookie': 0.4.1 '@types/cors': 2.8.15 - '@types/node': 20.12.8 + '@types/node': 20.8.0 accepts: 1.3.8 base64id: 2.0.0 cookie: 0.4.2 @@ -14292,7 +14871,7 @@ snapshots: function.prototype.name: 1.1.6 get-intrinsic: 1.2.4 get-symbol-description: 1.0.2 - globalthis: 1.0.4 + globalthis: 1.0.3 gopd: 1.0.1 has-property-descriptors: 1.0.2 has-proto: 1.0.3 @@ -14330,8 +14909,9 @@ snapshots: es-errors@1.3.0: {} - es-iterator-helpers@1.0.19: + es-iterator-helpers@1.0.17: dependencies: + asynciterator.prototype: 1.0.0 call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.23.3 @@ -14339,7 +14919,7 @@ snapshots: es-set-tostringtag: 2.0.3 function-bind: 1.1.2 get-intrinsic: 1.2.4 - globalthis: 1.0.4 + globalthis: 1.0.3 has-property-descriptors: 1.0.2 has-proto: 1.0.3 has-symbols: 1.0.3 @@ -14502,10 +15082,10 @@ snapshots: dependencies: eslint: 8.50.0 - eslint-config-xo-react@0.27.0(eslint-plugin-react-hooks@4.6.0(eslint@8.50.0))(eslint-plugin-react@7.34.1(eslint@8.50.0))(eslint@8.50.0): + eslint-config-xo-react@0.27.0(eslint-plugin-react-hooks@4.6.0(eslint@8.50.0))(eslint-plugin-react@7.33.2(eslint@8.50.0))(eslint@8.50.0): dependencies: eslint: 8.50.0 - eslint-plugin-react: 7.34.1(eslint@8.50.0) + eslint-plugin-react: 7.33.2(eslint@8.50.0) eslint-plugin-react-hooks: 4.6.0(eslint@8.50.0) eslint-config-xo-typescript@1.0.1(@typescript-eslint/eslint-plugin@6.1.0(@typescript-eslint/parser@6.7.3(eslint@8.50.0)(typescript@5.5.4))(eslint@8.50.0)(typescript@5.5.4))(@typescript-eslint/parser@6.7.3(eslint@8.50.0)(typescript@5.5.4))(eslint@8.50.0)(typescript@5.5.4): @@ -14520,7 +15100,7 @@ snapshots: confusing-browser-globals: 1.0.11 eslint: 8.50.0 - eslint-config-zardoy@0.2.17(eslint-plugin-react-hooks@4.6.0(eslint@8.50.0))(eslint-plugin-react@7.34.1(eslint@8.50.0))(eslint@8.50.0)(typescript@5.5.4): + eslint-config-zardoy@0.2.17(eslint-plugin-react-hooks@4.6.0(eslint@8.50.0))(eslint-plugin-react@7.33.2(eslint@8.50.0))(eslint@8.50.0)(typescript@5.5.4): dependencies: '@rushstack/eslint-patch': 1.4.0 '@typescript-eslint/eslint-plugin': 6.1.0(@typescript-eslint/parser@6.7.3(eslint@8.50.0)(typescript@5.5.4))(eslint@8.50.0)(typescript@5.5.4) @@ -14528,7 +15108,7 @@ snapshots: eslint: 8.50.0 eslint-config-prettier: 8.10.0(eslint@8.50.0) eslint-config-xo: 0.43.1(eslint@8.50.0) - eslint-config-xo-react: 0.27.0(eslint-plugin-react-hooks@4.6.0(eslint@8.50.0))(eslint-plugin-react@7.34.1(eslint@8.50.0))(eslint@8.50.0) + eslint-config-xo-react: 0.27.0(eslint-plugin-react-hooks@4.6.0(eslint@8.50.0))(eslint-plugin-react@7.33.2(eslint@8.50.0))(eslint@8.50.0) eslint-config-xo-typescript: 1.0.1(@typescript-eslint/eslint-plugin@6.1.0(@typescript-eslint/parser@6.7.3(eslint@8.50.0)(typescript@5.5.4))(eslint@8.50.0)(typescript@5.5.4))(@typescript-eslint/parser@6.7.3(eslint@8.50.0)(typescript@5.5.4))(eslint@8.50.0)(typescript@5.5.4) eslint-plugin-eslint-comments: 3.2.0(eslint@8.50.0) eslint-plugin-import: 2.27.5(@typescript-eslint/parser@6.7.3(eslint@8.50.0)(typescript@5.5.4))(eslint@8.50.0) @@ -14612,27 +15192,25 @@ snapshots: dependencies: eslint: 8.50.0 - eslint-plugin-react@7.34.1(eslint@8.50.0): + eslint-plugin-react@7.33.2(eslint@8.50.0): dependencies: - array-includes: 3.1.8 - array.prototype.findlast: 1.2.5 + array-includes: 3.1.7 array.prototype.flatmap: 1.3.2 - array.prototype.toreversed: 1.1.2 array.prototype.tosorted: 1.1.3 doctrine: 2.1.0 - es-iterator-helpers: 1.0.19 + es-iterator-helpers: 1.0.17 eslint: 8.50.0 estraverse: 5.3.0 jsx-ast-utils: 3.3.5 minimatch: 3.1.2 - object.entries: 1.1.8 - object.fromentries: 2.0.8 - object.hasown: 1.1.4 + object.entries: 1.1.7 + object.fromentries: 2.0.7 + object.hasown: 1.1.3 object.values: 1.2.0 prop-types: 15.8.1 resolve: 2.0.0-next.5 semver: 6.3.1 - string.prototype.matchall: 4.0.11 + string.prototype.matchall: 4.0.10 eslint-plugin-sonarjs@0.19.0(eslint@8.50.0): dependencies: @@ -14753,6 +15331,16 @@ snapshots: etag@1.8.1: {} + event-stream@3.3.4: + dependencies: + duplexer: 0.1.2 + from: 0.1.7 + map-stream: 0.1.0 + pause-stream: 0.0.11 + split: 0.3.3 + stream-combiner: 0.0.4 + through: 2.3.8 + event-target-shim@5.0.1: {} eventemitter2@6.4.7: @@ -14802,6 +15390,18 @@ snapshots: exit-hook@2.2.1: {} + expand-brackets@2.1.4: + dependencies: + debug: 2.6.9 + define-property: 0.2.5 + extend-shallow: 2.0.1 + posix-character-classes: 0.1.1 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + expand-template@2.0.3: {} exponential-backoff@3.1.1: @@ -14851,8 +15451,30 @@ snapshots: transitivePeerDependencies: - supports-color + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + + extend-shallow@3.0.2: + dependencies: + assign-symbols: 1.0.0 + is-extendable: 1.0.1 + extend@3.0.2: {} + extglob@2.0.4: + dependencies: + array-unique: 0.3.2 + define-property: 1.0.0 + expand-brackets: 2.1.4 + extend-shallow: 2.0.1 + fragment-cache: 0.2.1 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + extract-zip@1.7.0: dependencies: concat-stream: 1.6.2 @@ -14899,6 +15521,10 @@ snapshots: dependencies: reusify: 1.0.4 + faye-websocket@0.11.4: + dependencies: + websocket-driver: 0.7.4 + fb-watchman@2.0.2: dependencies: bser: 2.1.1 @@ -14937,10 +15563,29 @@ snapshots: filesize@10.0.12: {} + fill-range@4.0.0: + dependencies: + extend-shallow: 2.0.1 + is-number: 3.0.0 + repeat-string: 1.6.1 + to-regex-range: 2.1.1 + fill-range@7.0.1: dependencies: to-regex-range: 5.0.1 + finalhandler@1.1.2: + dependencies: + debug: 2.6.9 + encodeurl: 1.0.2 + escape-html: 1.0.3 + on-finished: 2.3.0 + parseurl: 1.3.3 + statuses: 1.5.0 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + finalhandler@1.2.0: dependencies: debug: 2.6.9 @@ -14997,6 +15642,10 @@ snapshots: optionalDependencies: debug: 4.3.4(supports-color@8.1.1) + follow-redirects@1.15.5(debug@4.3.4): + optionalDependencies: + debug: 4.3.4(supports-color@8.1.1) + follow-redirects@1.15.6(debug@4.3.4): optionalDependencies: debug: 4.3.4(supports-color@8.1.1) @@ -15005,6 +15654,8 @@ snapshots: dependencies: is-callable: 1.2.7 + for-in@1.0.2: {} + foreground-child@2.0.0: dependencies: cross-spawn: 7.0.3 @@ -15050,8 +15701,14 @@ snapshots: forwarded@0.2.0: {} + fragment-cache@0.2.1: + dependencies: + map-cache: 0.2.2 + fresh@0.5.2: {} + from@0.1.7: {} + fs-constants@1.0.0: {} fs-extra@10.1.0: @@ -15088,6 +15745,12 @@ snapshots: fs.realpath@1.0.0: {} + fsevents@1.2.13: + dependencies: + bindings: 1.5.0 + nan: 2.18.0 + optional: true + fsevents@2.3.3: optional: true @@ -15181,6 +15844,8 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 + get-value@2.0.6: {} + getos@3.2.1: dependencies: async: 3.2.5 @@ -15221,6 +15886,11 @@ snapshots: - supports-color optional: true + glob-parent@3.1.0: + dependencies: + is-glob: 3.1.0 + path-dirname: 1.0.2 + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -15283,11 +15953,6 @@ snapshots: dependencies: define-properties: 1.2.1 - globalthis@1.0.4: - dependencies: - define-properties: 1.2.1 - gopd: 1.0.1 - globby@11.1.0: dependencies: array-union: 2.1.0 @@ -15373,6 +16038,25 @@ snapshots: has-unicode@2.0.1: optional: true + has-value@0.3.1: + dependencies: + get-value: 2.0.6 + has-values: 0.1.4 + isobject: 2.1.0 + + has-value@1.0.0: + dependencies: + get-value: 2.0.6 + has-values: 1.0.0 + isobject: 3.0.1 + + has-values@0.1.4: {} + + has-values@1.0.0: + dependencies: + is-number: 3.0.0 + kind-of: 4.0.0 + has@1.0.3: dependencies: function-bind: 1.1.1 @@ -15431,6 +16115,13 @@ snapshots: html-tags@3.3.1: {} + http-auth@3.1.3: + dependencies: + apache-crypt: 1.2.6 + apache-md5: 1.1.8 + bcryptjs: 2.4.3 + uuid: 3.4.0 + http-browserify@1.7.0: dependencies: Base64: 0.2.1 @@ -15438,6 +16129,13 @@ snapshots: http-cache-semantics@4.1.1: {} + http-errors@1.6.3: + dependencies: + depd: 1.1.2 + inherits: 2.0.3 + setprototypeof: 1.1.0 + statuses: 1.5.0 + http-errors@2.0.0: dependencies: depd: 2.0.0 @@ -15446,6 +16144,8 @@ snapshots: statuses: 2.0.1 toidentifier: 1.0.1 + http-parser-js@0.5.8: {} + http-proxy-agent@5.0.0: dependencies: '@tootallnate/once': 2.0.0 @@ -15568,6 +16268,8 @@ snapshots: once: 1.4.0 wrappy: 1.0.2 + inherits@2.0.3: {} + inherits@2.0.4: {} ini@1.3.8: {} @@ -15590,7 +16292,7 @@ snapshots: dependencies: es-errors: 1.3.0 hasown: 2.0.2 - side-channel: 1.0.6 + side-channel: 1.0.5 invariant@2.2.4: dependencies: @@ -15602,6 +16304,10 @@ snapshots: is-absolute-url@3.0.3: {} + is-accessor-descriptor@1.0.1: + dependencies: + hasown: 2.0.1 + is-arguments@1.1.1: dependencies: call-bind: 1.0.2 @@ -15630,6 +16336,10 @@ snapshots: dependencies: has-bigints: 1.0.2 + is-binary-path@1.0.1: + dependencies: + binary-extensions: 1.13.1 + is-binary-path@2.1.0: dependencies: binary-extensions: 2.2.0 @@ -15639,6 +16349,8 @@ snapshots: call-bind: 1.0.2 has-tostringtag: 1.0.0 + is-buffer@1.1.6: {} + is-builtin-module@3.2.1: dependencies: builtin-modules: 3.3.0 @@ -15658,6 +16370,10 @@ snapshots: dependencies: hasown: 2.0.2 + is-data-descriptor@1.0.1: + dependencies: + hasown: 2.0.1 + is-data-view@1.0.1: dependencies: is-typed-array: 1.1.13 @@ -15668,8 +16384,24 @@ snapshots: is-deflate@1.0.0: {} + is-descriptor@0.1.7: + dependencies: + is-accessor-descriptor: 1.0.1 + is-data-descriptor: 1.0.1 + + is-descriptor@1.0.3: + dependencies: + is-accessor-descriptor: 1.0.1 + is-data-descriptor: 1.0.1 + is-docker@2.2.1: {} + is-extendable@0.1.1: {} + + is-extendable@1.0.1: + dependencies: + is-plain-object: 2.0.4 + is-extglob@2.1.1: {} is-finalizationregistry@1.0.2: @@ -15685,6 +16417,10 @@ snapshots: dependencies: has-tostringtag: 1.0.0 + is-glob@3.1.0: + dependencies: + is-extglob: 2.1.1 + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 @@ -15702,7 +16438,7 @@ snapshots: is-lambda@1.0.1: optional: true - is-map@2.0.3: {} + is-map@2.0.2: {} is-module@1.0.0: {} @@ -15719,6 +16455,10 @@ snapshots: dependencies: has-tostringtag: 1.0.0 + is-number@3.0.0: + dependencies: + kind-of: 3.2.2 + is-number@7.0.0: {} is-obj@1.0.1: {} @@ -15744,7 +16484,7 @@ snapshots: is-regexp@1.0.0: {} - is-set@2.0.3: {} + is-set@2.0.2: {} is-shared-array-buffer@1.0.2: dependencies: @@ -15777,17 +16517,21 @@ snapshots: is-unicode-supported@0.1.0: {} - is-weakmap@2.0.2: {} + is-weakmap@2.0.1: {} is-weakref@1.0.2: dependencies: call-bind: 1.0.2 - is-weakset@2.0.3: + is-weakset@2.0.2: dependencies: call-bind: 1.0.7 get-intrinsic: 1.2.4 + is-windows@1.0.2: {} + + is-wsl@1.1.0: {} + is-wsl@2.2.0: dependencies: is-docker: 2.2.1 @@ -15804,6 +16548,10 @@ snapshots: isexe@2.0.0: {} + isobject@2.1.0: + dependencies: + isarray: 1.0.0 + isobject@3.0.1: {} isstream@0.1.2: @@ -15838,7 +16586,7 @@ snapshots: get-intrinsic: 1.2.4 has-symbols: 1.0.3 reflect.getprototypeof: 1.0.6 - set-function-name: 2.0.2 + set-function-name: 2.0.1 jackspeak@2.3.0: dependencies: @@ -16032,7 +16780,7 @@ snapshots: jsx-ast-utils@3.3.5: dependencies: - array-includes: 3.1.8 + array-includes: 3.1.7 array.prototype.flat: 1.3.2 object.assign: 4.1.5 object.values: 1.2.0 @@ -16059,6 +16807,14 @@ snapshots: dependencies: json-buffer: 3.0.1 + kind-of@3.2.2: + dependencies: + is-buffer: 1.1.6 + + kind-of@4.0.0: + dependencies: + is-buffer: 1.1.6 + kind-of@6.0.3: {} kleur@3.0.3: {} @@ -16107,6 +16863,24 @@ snapshots: enquirer: 2.4.1 optional: true + live-server@1.2.2: + dependencies: + chokidar: 2.1.8 + colors: 1.4.0 + connect: 3.7.0 + cors: 2.8.5 + event-stream: 3.3.4 + faye-websocket: 0.11.4 + http-auth: 3.1.3 + morgan: 1.10.0 + object-assign: 4.1.1 + opn: 6.0.0 + proxy-middleware: 0.15.0 + send: 0.18.0 + serve-index: 1.9.1 + transitivePeerDependencies: + - supports-color + load-bmfont@1.4.1: dependencies: buffer-equal: 0.0.1 @@ -16269,12 +17043,20 @@ snapshots: dependencies: tmpl: 1.0.5 + map-cache@0.2.2: {} + map-obj@1.0.1: {} map-obj@4.3.0: {} map-or-similar@1.5.0: {} + map-stream@0.1.0: {} + + map-visit@1.0.0: + dependencies: + object-visit: 1.0.1 + markdown-it@14.0.0: dependencies: argparse: 2.0.1 @@ -16288,6 +17070,10 @@ snapshots: dependencies: react: 18.2.0 + math.gl@4.0.1: + dependencies: + '@math.gl/core': 4.0.1 + mc-assets@0.2.5: {} md5-file@4.0.0: {} @@ -16518,6 +17304,24 @@ snapshots: transitivePeerDependencies: - supports-color + micromatch@3.1.10: + dependencies: + arr-diff: 4.0.0 + array-unique: 0.3.2 + braces: 2.3.2 + define-property: 2.0.2 + extend-shallow: 3.0.2 + extglob: 2.0.4 + fragment-cache: 0.2.1 + kind-of: 6.0.3 + nanomatch: 1.2.13 + object.pick: 1.3.0 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + micromatch@4.0.5: dependencies: braces: 3.0.2 @@ -16565,7 +17369,7 @@ snapshots: minecraft-protocol@https://codeload.github.com/PrismarineJS/node-minecraft-protocol/tar.gz/495eed56ab230b2615596590064671356d86a2dc(patch_hash=7otpchsbv7hxsuis4rrrwdtbve)(encoding@0.1.13): dependencies: - '@types/readable-stream': 4.0.12 + '@types/readable-stream': 4.0.10 aes-js: 3.1.2 buffer-equal: 1.0.1 debug: 4.3.4(supports-color@8.1.1) @@ -16576,7 +17380,7 @@ snapshots: minecraft-folder-path: 1.2.0 node-fetch: 2.7.0(encoding@0.1.13) node-rsa: 0.4.2 - prismarine-auth: 2.4.2(encoding@0.1.13) + prismarine-auth: 2.4.1(encoding@0.1.13) prismarine-chat: 1.10.1 prismarine-nbt: 2.5.0 prismarine-realms: 1.3.2(encoding@0.1.13) @@ -16590,7 +17394,7 @@ snapshots: minecraft-protocol@https://codeload.github.com/PrismarineJS/node-minecraft-protocol/tar.gz/7057ad979b416192ada235f2f4e3b5eb26af5fa1(patch_hash=7otpchsbv7hxsuis4rrrwdtbve)(encoding@0.1.13): dependencies: - '@types/readable-stream': 4.0.12 + '@types/readable-stream': 4.0.10 aes-js: 3.1.2 buffer-equal: 1.0.1 debug: 4.3.4(supports-color@8.1.1) @@ -16601,7 +17405,7 @@ snapshots: minecraft-folder-path: 1.2.0 node-fetch: 2.7.0(encoding@0.1.13) node-rsa: 0.4.2 - prismarine-auth: 2.4.2(encoding@0.1.13) + prismarine-auth: 2.4.1(encoding@0.1.13) prismarine-chat: 1.10.1 prismarine-nbt: 2.5.0 prismarine-realms: 1.3.2(encoding@0.1.13) @@ -16766,6 +17570,11 @@ snapshots: minipass: 3.3.6 yallist: 4.0.0 + mixin-deep@1.3.2: + dependencies: + for-in: 1.0.2 + is-extendable: 1.0.1 + mkdirp-classic@0.5.3: {} mkdirp@0.3.0: @@ -16792,6 +17601,16 @@ snapshots: moo@0.5.2: {} + morgan@1.10.0: + dependencies: + basic-auth: 2.0.1 + debug: 2.6.9 + depd: 2.0.0 + on-finished: 2.3.0 + on-headers: 1.0.2 + transitivePeerDependencies: + - supports-color + mri@1.2.0: {} ms@2.0.0: {} @@ -16826,6 +17645,22 @@ snapshots: nanoid@3.3.7: {} + nanomatch@1.2.13: + dependencies: + arr-diff: 4.0.0 + array-unique: 0.3.2 + define-property: 2.0.2 + extend-shallow: 3.0.2 + fragment-cache: 0.2.1 + is-windows: 1.0.2 + kind-of: 6.0.3 + object.pick: 1.3.0 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + napi-build-utils@1.0.2: {} natural-compare-lite@1.4.0: {} @@ -16963,6 +17798,10 @@ snapshots: semver: 7.6.0 validate-npm-package-license: 3.0.4 + normalize-path@2.1.1: + dependencies: + remove-trailing-separator: 1.1.0 + normalize-path@3.0.0: {} npm-run-all@4.1.5: @@ -17003,6 +17842,12 @@ snapshots: object-assign@4.1.1: {} + object-copy@0.1.0: + dependencies: + copy-descriptor: 0.1.1 + define-property: 0.2.5 + kind-of: 3.2.2 + object-inspect@1.12.3: {} object-inspect@1.13.1: {} @@ -17014,6 +17859,10 @@ snapshots: object-keys@1.1.1: {} + object-visit@1.0.1: + dependencies: + isobject: 3.0.1 + object.assign@4.1.4: dependencies: call-bind: 1.0.2 @@ -17028,24 +17877,26 @@ snapshots: has-symbols: 1.0.3 object-keys: 1.1.1 - object.entries@1.1.8: - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-object-atoms: 1.0.0 - - object.fromentries@2.0.8: + object.entries@1.1.7: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.23.3 - es-object-atoms: 1.0.0 - object.hasown@1.1.4: + object.fromentries@2.0.7: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + + object.hasown@1.1.3: dependencies: define-properties: 1.2.1 es-abstract: 1.23.3 - es-object-atoms: 1.0.0 + + object.pick@1.3.0: + dependencies: + isobject: 3.0.1 object.values@1.1.7: dependencies: @@ -17062,6 +17913,10 @@ snapshots: omggif@1.0.10: optional: true + on-finished@2.3.0: + dependencies: + ee-first: 1.1.1 + on-finished@2.4.1: dependencies: ee-first: 1.1.1 @@ -17084,6 +17939,10 @@ snapshots: opener@1.5.2: {} + opn@6.0.0: + dependencies: + is-wsl: 1.1.0 + optionator@0.9.3: dependencies: '@aashutoshrathi/word-wrap': 1.2.6 @@ -17203,6 +18062,8 @@ snapshots: no-case: 3.0.4 tslib: 2.6.2 + pascalcase@0.1.1: {} + path-browserify@1.0.1: {} path-case@3.0.4: @@ -17210,6 +18071,8 @@ snapshots: dot-case: 3.0.4 tslib: 2.6.2 + path-dirname@1.0.2: {} + path-exists-cli@2.0.0: dependencies: meow: 10.1.5 @@ -17246,6 +18109,10 @@ snapshots: pathval@1.1.1: {} + pause-stream@0.0.11: + dependencies: + through: 2.3.8 + pbkdf2@3.1.2: dependencies: create-hash: 1.2.0 @@ -17339,6 +18206,8 @@ snapshots: transitivePeerDependencies: - supports-color + posix-character-classes@0.1.1: {} + possible-typed-array-names@1.0.0: {} postcss@8.4.31: @@ -17389,9 +18258,9 @@ snapshots: pretty-hrtime@1.0.3: {} - prismarine-auth@2.4.2(encoding@0.1.13): + prismarine-auth@2.4.1(encoding@0.1.13): dependencies: - '@azure/msal-node': 2.7.0 + '@azure/msal-node': 2.6.3 '@xboxreplay/xboxlive-auth': 3.3.3(debug@4.3.4) debug: 4.3.4(supports-color@8.1.1) jose: 4.15.5 @@ -17658,6 +18527,8 @@ snapshots: proxy-from-env@1.1.0: {} + proxy-middleware@0.15.0: {} + psl@1.9.0: optional: true @@ -17999,6 +18870,14 @@ snapshots: process: 0.11.10 string_decoder: 1.3.0 + readdirp@2.2.1: + dependencies: + graceful-fs: 4.2.11 + micromatch: 3.1.10 + readable-stream: 2.3.8 + transitivePeerDependencies: + - supports-color + readdirp@3.6.0: dependencies: picomatch: 2.3.1 @@ -18036,7 +18915,7 @@ snapshots: es-abstract: 1.23.3 es-errors: 1.3.0 get-intrinsic: 1.2.4 - globalthis: 1.0.4 + globalthis: 1.0.3 which-builtin-type: 1.1.3 regenerate-unicode-properties@10.1.0: @@ -18054,6 +18933,11 @@ snapshots: dependencies: '@babel/runtime': 7.22.11 + regex-not@1.0.2: + dependencies: + extend-shallow: 3.0.2 + safe-regex: 1.1.0 + regexp-tree@0.1.27: {} regexp.prototype.flags@1.5.1: @@ -18067,7 +18951,7 @@ snapshots: call-bind: 1.0.7 define-properties: 1.2.1 es-errors: 1.3.0 - set-function-name: 2.0.2 + set-function-name: 2.0.1 regexpp@3.2.0: {} @@ -18126,6 +19010,12 @@ snapshots: transitivePeerDependencies: - supports-color + remove-trailing-separator@1.1.0: {} + + repeat-element@1.1.4: {} + + repeat-string@1.6.1: {} + request-progress@3.0.0: dependencies: throttleit: 1.0.0 @@ -18145,6 +19035,8 @@ snapshots: resolve-pkg-maps@1.0.0: {} + resolve-url@0.2.1: {} + resolve@1.22.4: dependencies: is-core-module: 2.13.0 @@ -18253,6 +19145,10 @@ snapshots: es-errors: 1.3.0 is-regex: 1.1.4 + safe-regex@1.1.0: + dependencies: + ret: 0.1.15 + safer-buffer@2.1.2: {} sanitize-filename@1.6.3: @@ -18324,6 +19220,18 @@ snapshots: dependencies: randombytes: 2.1.0 + serve-index@1.9.1: + dependencies: + accepts: 1.3.8 + batch: 0.6.1 + debug: 2.6.9 + escape-html: 1.0.3 + http-errors: 1.6.3 + mime-types: 2.1.35 + parseurl: 1.3.3 + transitivePeerDependencies: + - supports-color + serve-static@1.15.0: dependencies: encodeurl: 1.0.2 @@ -18351,17 +19259,19 @@ snapshots: functions-have-names: 1.2.3 has-property-descriptors: 1.0.0 - set-function-name@2.0.2: - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - functions-have-names: 1.2.3 - has-property-descriptors: 1.0.2 - set-harmonic-interval@1.0.1: {} + set-value@2.0.1: + dependencies: + extend-shallow: 2.0.1 + is-extendable: 0.1.1 + is-plain-object: 2.0.4 + split-string: 3.1.0 + setimmediate@1.0.5: {} + setprototypeof@1.1.0: {} + setprototypeof@1.2.0: {} sha.js@2.4.11: @@ -18379,7 +19289,7 @@ snapshots: detect-libc: 2.0.2 node-addon-api: 5.1.0 prebuild-install: 7.1.1 - semver: 7.6.0 + semver: 7.5.4 simple-get: 4.0.1 tar-fs: 2.1.1 tunnel-agent: 0.6.0 @@ -18410,14 +19320,6 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.2.4 object-inspect: 1.13.1 - optional: true - - side-channel@1.0.6: - dependencies: - call-bind: 1.0.7 - es-errors: 1.3.0 - get-intrinsic: 1.2.4 - object-inspect: 1.13.1 siginfo@2.0.0: {} @@ -18481,6 +19383,29 @@ snapshots: dot-case: 3.0.4 tslib: 2.6.2 + snapdragon-node@2.1.1: + dependencies: + define-property: 1.0.0 + isobject: 3.0.1 + snapdragon-util: 3.0.1 + + snapdragon-util@3.0.1: + dependencies: + kind-of: 3.2.2 + + snapdragon@0.8.2: + dependencies: + base: 0.11.2 + debug: 2.6.9 + define-property: 0.2.5 + extend-shallow: 2.0.1 + map-cache: 0.2.2 + source-map: 0.5.7 + source-map-resolve: 0.5.3 + use: 3.1.1 + transitivePeerDependencies: + - supports-color + socket.io-adapter@1.1.2: optional: true @@ -18593,11 +19518,21 @@ snapshots: source-map-js@1.2.0: {} + source-map-resolve@0.5.3: + dependencies: + atob: 2.1.2 + decode-uri-component: 0.2.2 + resolve-url: 0.2.1 + source-map-url: 0.4.1 + urix: 0.1.0 + source-map-support@0.5.21: dependencies: buffer-from: 1.1.2 source-map: 0.6.1 + source-map-url@0.4.1: {} + source-map@0.5.6: {} source-map@0.5.7: {} @@ -18626,6 +19561,14 @@ snapshots: spdx-license-ids@3.0.13: {} + split-string@3.1.0: + dependencies: + extend-shallow: 3.0.2 + + split@0.3.3: + dependencies: + through: 2.3.8 + sprintf-js@1.0.3: {} sshpk@1.17.0: @@ -18665,10 +19608,17 @@ snapshots: stack-generator: 2.0.10 stacktrace-gps: 3.1.2 + static-extend@0.1.2: + dependencies: + define-property: 0.2.5 + object-copy: 0.1.0 + stats-gl@1.0.5: {} stats.js@0.17.0: {} + statuses@1.5.0: {} + statuses@2.0.1: {} std-env@3.4.3: {} @@ -18689,6 +19639,10 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 + stream-combiner@0.0.4: + dependencies: + duplexer: 0.1.2 + stream-http@3.2.0: dependencies: builtin-status-codes: 3.0.0 @@ -18724,21 +19678,6 @@ snapshots: set-function-name: 2.0.1 side-channel: 1.0.4 - string.prototype.matchall@4.0.11: - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.23.3 - es-errors: 1.3.0 - es-object-atoms: 1.0.0 - get-intrinsic: 1.2.4 - gopd: 1.0.1 - has-symbols: 1.0.3 - internal-slot: 1.0.7 - regexp.prototype.flags: 1.5.2 - set-function-name: 2.0.2 - side-channel: 1.0.6 - string.prototype.padend@3.1.4: dependencies: call-bind: 1.0.2 @@ -18847,7 +19786,7 @@ snapshots: synchronous-promise@2.0.17: {} - systeminformation@5.22.7: + systeminformation@5.21.24: optional: true tabbable@6.2.0: {} @@ -18974,8 +19913,7 @@ snapshots: readable-stream: 2.3.8 xtend: 4.0.2 - through@2.3.8: - optional: true + through@2.3.8: {} timers-browserify@2.0.12: dependencies: @@ -19011,10 +19949,26 @@ snapshots: to-fast-properties@2.0.0: {} + to-object-path@0.3.0: + dependencies: + kind-of: 3.2.2 + + to-regex-range@2.1.1: + dependencies: + is-number: 3.0.0 + repeat-string: 1.6.1 + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 + to-regex@3.0.2: + dependencies: + define-property: 2.0.2 + extend-shallow: 3.0.2 + regex-not: 1.0.2 + safe-regex: 1.1.0 + tocbot@4.21.2: {} toggle-selection@1.0.6: {} @@ -19078,6 +20032,8 @@ snapshots: tweetnacl@0.14.5: optional: true + twgl.js@5.5.4: {} + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 @@ -19223,6 +20179,13 @@ snapshots: trough: 2.2.0 vfile: 6.0.1 + union-value@1.0.1: + dependencies: + arr-union: 3.1.0 + get-value: 2.0.6 + is-extendable: 0.1.1 + set-value: 2.0.1 + union@0.5.0: dependencies: qs: 6.11.2 @@ -19281,6 +20244,8 @@ snapshots: universalify@2.0.0: {} + unix-crypt-td-js@1.1.4: {} + unpipe@1.0.0: {} unplugin@1.5.0: @@ -19290,6 +20255,11 @@ snapshots: webpack-sources: 3.2.3 webpack-virtual-modules: 0.5.0 + unset-value@1.0.0: + dependencies: + has-value: 0.3.1 + isobject: 3.0.1 + untildify@4.0.0: {} upath@1.2.0: {} @@ -19318,6 +20288,8 @@ snapshots: dependencies: punycode: 2.3.0 + urix@0.1.0: {} + url-join@4.0.1: {} url-parse@1.5.10: @@ -19369,6 +20341,8 @@ snapshots: optionalDependencies: typescript: 5.5.4 + use@3.1.1: {} + utf8-byte-length@1.0.4: {} utif@2.0.1: @@ -19392,6 +20366,8 @@ snapshots: dependencies: macaddress: 0.5.3 + uuid@3.4.0: {} + uuid@8.3.2: {} uuid@9.0.1: {} @@ -19599,6 +20575,14 @@ snapshots: dependencies: sdp: 3.2.0 + websocket-driver@0.7.4: + dependencies: + http-parser-js: 0.5.8 + safe-buffer: 5.2.1 + websocket-extensions: 0.1.4 + + websocket-extensions@0.1.4: {} + whatwg-encoding@2.0.0: dependencies: iconv-lite: 0.6.3 @@ -19637,15 +20621,15 @@ snapshots: is-weakref: 1.0.2 isarray: 2.0.5 which-boxed-primitive: 1.0.2 - which-collection: 1.0.2 + which-collection: 1.0.1 which-typed-array: 1.1.15 - which-collection@1.0.2: + which-collection@1.0.1: dependencies: - is-map: 2.0.3 - is-set: 2.0.3 - is-weakmap: 2.0.2 - is-weakset: 2.0.3 + is-map: 2.0.2 + is-set: 2.0.2 + is-weakmap: 2.0.1 + is-weakset: 2.0.2 which-typed-array@1.1.11: dependencies: diff --git a/prismarine-viewer/buildMesherWorker.mjs b/prismarine-viewer/buildMesherWorker.mjs index f70b8128..f6b50033 100644 --- a/prismarine-viewer/buildMesherWorker.mjs +++ b/prismarine-viewer/buildMesherWorker.mjs @@ -38,7 +38,7 @@ const buildOptions = { ...mesherSharedPlugins, { name: 'external-json', - setup (build) { + setup(build) { build.onResolve({ filter: /\.json$/ }, args => { const fileName = args.path.split('/').pop().replace('.json', '') if (args.resolveDir.includes('minecraft-data')) { diff --git a/prismarine-viewer/esbuild.mjs b/prismarine-viewer/esbuild.mjs index 90741ee1..78e0e83d 100644 --- a/prismarine-viewer/esbuild.mjs +++ b/prismarine-viewer/esbuild.mjs @@ -46,18 +46,20 @@ const buildOptions = { http: 'http-browserify', stream: 'stream-browserify', net: 'net-browserify', - // 'mc-assets': '/Users/vitaly/Documents/mc-assets', + 'stats.js': 'stats.js/src/Stats.js', }, inject: [], metafile: true, loader: { '.png': 'dataurl', + '.vert': 'text', + '.frag': 'text', '.obj': 'text', }, plugins: [ { name: 'minecraft-data', - setup(build) { + setup (build) { build.onLoad({ filter: /minecraft-data[\/\\]data.js$/, }, () => { diff --git a/prismarine-viewer/examples/Cube.comp.wgsl b/prismarine-viewer/examples/Cube.comp.wgsl new file mode 100644 index 00000000..3a7672a7 --- /dev/null +++ b/prismarine-viewer/examples/Cube.comp.wgsl @@ -0,0 +1,45 @@ +struct Cube { + position: vec3f, + textureIndex: f32, + colorBlend: vec3f, + //tt: f32 +} + +struct Uniforms { + ViewProjectionMatrix: mat4x4, +} + +struct IndirectDrawParams { + vertexCount: u32, + instanceCount: atomic, + firstVertex: u32, + firstInstance: u32, +} + +@group(0) @binding(0) var uniforms: Uniforms; +@group(0) @binding(1) var cubes: array; +@group(0) @binding(2) var visibleCubes: array; // Changed to @binding(4) +@group(0) @binding(3) var drawParams: IndirectDrawParams; + +@compute @workgroup_size(256) +fn main(@builtin(global_invocation_id) global_id: vec3) { + let index = global_id.x; + if (index >= arrayLength(&cubes)) { + return; + } + + let cube = cubes[index]; + + // Transform cube position to clip space + let clipPos = uniforms.ViewProjectionMatrix * (vec4(cube.position, 1.0) + vec4(0.5, 0.0, 0.5, 0.0)); + let clipDepth = clipPos.z / clipPos.w; // Obtain depth in clip space + let clipX = clipPos.x / clipPos.w; + let clipY = clipPos.y / clipPos.w; + + // Check if cube is within the view frustum z-range (depth within near and far planes) + let Oversize = 1.2; + if (clipDepth >= 0.0 && clipDepth <= 1.0 && clipX > -1.0 * Oversize && clipX < 1.0 * Oversize && clipY > -1.0 * Oversize && clipY < 1.0 * Oversize) { //Small Oversize because binding size + let visibleIndex = atomicAdd(&drawParams.instanceCount, 1); + visibleCubes[visibleIndex] = cube; + } +} diff --git a/prismarine-viewer/examples/Cube.frag.wgsl b/prismarine-viewer/examples/Cube.frag.wgsl new file mode 100644 index 00000000..c7f04082 --- /dev/null +++ b/prismarine-viewer/examples/Cube.frag.wgsl @@ -0,0 +1,14 @@ +@group(0) @binding(1) var mySampler: sampler; +@group(0) @binding(2) var myTexture: texture_2d; + +@fragment +fn main( + @location(0) fragUV: vec2f, + @location(1) @interpolate(flat) TextureIndex: f32, + @location(2) @interpolate(flat) ColorBlend: vec3f +) -> @location(0) vec4f { + let textureSize: vec2 = vec2(textureDimensions(myTexture)); + let tileSize: vec2 = vec2(16.0f,16.0f); + let tilesPerTexture: vec2 = vec2(textureSize)/tileSize; + return textureSample(myTexture, mySampler, fragUV/tilesPerTexture + vec2f(trunc(TextureIndex%tilesPerTexture.y),trunc(TextureIndex/tilesPerTexture.x) )/tilesPerTexture) * vec4f(ColorBlend,1.0); +} diff --git a/prismarine-viewer/examples/Cube.vert.wgsl b/prismarine-viewer/examples/Cube.vert.wgsl new file mode 100644 index 00000000..ab65fa0a --- /dev/null +++ b/prismarine-viewer/examples/Cube.vert.wgsl @@ -0,0 +1,36 @@ +struct Uniforms { + ViewProjectionMatrix: mat4x4, +} + +struct Cube { + position: vec3f, + textureIndex: f32, + colorBlend: vec3f, + //tt: f32 +} + +struct VertexOutput { + @builtin(position) Position: vec4f, + @location(0) fragUV: vec2f, + @location(1) @interpolate(flat) TextureIndex: f32, + @location(2) @interpolate(flat) ColorBlend: vec3f +} + +@group(0) @binding(0) var uniforms: Uniforms; +@group(0) @binding(3) var visibleCubes: array; + +@vertex +fn main( + @builtin(instance_index) instanceIndex: u32, + @location(0) position: vec4, + @location(1) uv: vec2 +) -> VertexOutput { + let cube = visibleCubes[instanceIndex]; + //cube.position.x = instance_index * 2; + var output: VertexOutput; + output.Position = uniforms.ViewProjectionMatrix * (position + vec4(cube.position, 0.0) + vec4(0.5, 0.0, 0.5, 0.0)); + output.fragUV = uv; + output.TextureIndex = cube.textureIndex; + output.ColorBlend = cube.colorBlend; + return output; +} diff --git a/prismarine-viewer/examples/CubeDef.ts b/prismarine-viewer/examples/CubeDef.ts new file mode 100644 index 00000000..d41f9251 --- /dev/null +++ b/prismarine-viewer/examples/CubeDef.ts @@ -0,0 +1,95 @@ +export const cubeVertexSize = 4 * 5 // Byte size of one cube vertex. +export const cubePositionOffset = 0 +//export const cubeColorOffset = 4 * 3 // Byte offset of cube vertex color attribute. +export const cubeUVOffset = 4 * 3 +export const cubeVertexCount = 36 + +//@ts-format-ignore-region +export const cubeVertexArray = new Float32Array([ + -0.5, -0.5, -0.5, 0.0, 0.0, // Bottom-let + 0.5, -0.5, -0.5, 1.0, 0.0, // bottom-right + 0.5, 0.5, -0.5, 1.0, 1.0, // top-right + 0.5, 0.5, -0.5, 1.0, 1.0, // top-right + -0.5, 0.5, -0.5, 0.0, 1.0, // top-let + -0.5, -0.5, -0.5, 0.0, 0.0, // bottom-let + // ront ace + -0.5, -0.5, 0.5, 0.0, 0.0, // bottom-let + 0.5, 0.5, 0.5, 1.0, 1.0, // top-right + 0.5, -0.5, 0.5, 1.0, 0.0, // bottom-right + 0.5, 0.5, 0.5, 1.0, 1.0, // top-right + -0.5, -0.5, 0.5, 0.0, 0.0, // bottom-let + -0.5, 0.5, 0.5, 0.0, 1.0, // top-let + // Let ace + -0.5, 0.5, 0.5, 1.0, 0.0, // top-right + -0.5, -0.5, -0.5, 0.0, 1.0, // bottom-let + -0.5, 0.5, -0.5, 1.0, 1.0, // top-let + -0.5, -0.5, -0.5, 0.0, 1.0, // bottom-let + -0.5, 0.5, 0.5, 1.0, 0.0, // top-right + -0.5, -0.5, 0.5, 0.0, 0.0, // bottom-right + // Right ace + 0.5, 0.5, 0.5, 1.0, 0.0, // top-let + 0.5, 0.5, -0.5, 1.0, 1.0, // top-right + 0.5, -0.5, -0.5, 0.0, 1.0, // bottom-right + 0.5, -0.5, -0.5, 0.0, 1.0, // bottom-right + 0.5, -0.5, 0.5, 0.0, 0.0, // bottom-let + 0.5, 0.5, 0.5, 1.0, 0.0, // top-let + // Bottom ace + -0.5, -0.5, -0.5, 0.0, 1.0, // top-right + 0.5, -0.5, 0.5, 1.0, 0.0, // bottom-let + 0.5, -0.5, -0.5, 1.0, 1.0, // top-let + 0.5, -0.5, 0.5, 1.0, 0.0, // bottom-let + -0.5, -0.5, -0.5, 0.0, 1.0, // top-right + -0.5, -0.5, 0.5, 0.0, 0.0, // bottom-right + // Top ace + -0.5, 0.5, -0.5, 0.0, 1.0, // top-let + 0.5, 0.5, -0.5, 1.0, 1.0, // top-right + 0.5, 0.5, 0.5, 1.0, 0.0, // bottom-right + 0.5, 0.5, 0.5, 1.0, 0.0, // bottom-right + -0.5, 0.5, 0.5, 0.0, 0.0, // bottom-let + -0.5, 0.5, -0.5, 0.0, 1.0// top-letËš +]); + + +export const cubeVertexArraySub = new Float32Array([ + -0.5, -0.5, -0.5, 0.0, 0.0, // Bottom-let + 0.5, -0.5, -0.5, 1.0, 0.0, // bottom-right + 0.5, 0.5, -0.5, 1.0, 1.0, // top-right + 0.5, 0.5, -0.5, 1.0, 1.0, // top-right + -0.5, 0.5, -0.5, 0.0, 1.0, // top-let + -0.5, -0.5, -0.5, 0.0, 0.0, // bottom-let + // ront ace + -0.5, -0.5, 0.5, 0.0, 0.0, // bottom-let + 0.5, 0.5, 0.5, 1.0, 1.0, // top-right + 0.5, -0.5, 0.5, 1.0, 0.0, // bottom-right + 0.5, 0.5, 0.5, 1.0, 1.0, // top-right + -0.5, -0.5, 0.5, 0.0, 0.0, // bottom-let + -0.5, 0.5, 0.5, 0.0, 1.0, // top-let + // Let ace + -0.5, 0.5, 0.5, 1.0, 0.0, // top-right + -0.5, -0.5, -0.5, 0.0, 1.0, // bottom-let + -0.5, 0.5, -0.5, 1.0, 1.0, // top-let + -0.5, -0.5, -0.5, 0.0, 1.0, // bottom-let + -0.5, 0.5, 0.5, 1.0, 0.0, // top-right + -0.5, -0.5, 0.5, 0.0, 0.0, // bottom-right + // Right ace + 0.5, 0.5, 0.5, 1.0, 0.0, // top-let + 0.5, 0.5, -0.5, 1.0, 1.0, // top-right + 0.5, -0.5, -0.5, 0.0, 1.0, // bottom-right + 0.5, -0.5, -0.5, 0.0, 1.0, // bottom-right + 0.5, -0.5, 0.5, 0.0, 0.0, // bottom-let + 0.5, 0.5, 0.5, 1.0, 0.0, // top-let + // Bottom ace + -0.5, -0.5, -0.5, 0.0, 1.0, // top-right + 0.5, -0.5, 0.5, 1.0, 0.0, // bottom-let + 0.5, -0.5, -0.5, 1.0, 1.0, // top-let + 0.5, -0.5, 0.5, 1.0, 0.0, // bottom-let + -0.5, -0.5, -0.5, 0.0, 1.0, // top-right + -0.5, -0.5, 0.5, 0.0, 0.0, // bottom-right + // Top ace + -0.5, 0.5, -0.5, 0.0, 1.0, // top-let + 0.5, 0.5, -0.5, 1.0, 1.0, // top-right + 0.5, 0.5, 0.5, 1.0, 0.0, // bottom-right + 0.5, 0.5, 0.5, 1.0, 0.0, // bottom-right + -0.5, 0.5, 0.5, 0.0, 0.0, // bottom-let + -0.5, 0.5, -0.5, 0.0, 1.0, 5.0// top-letËš +]); diff --git a/prismarine-viewer/examples/TextureAnimation.ts b/prismarine-viewer/examples/TextureAnimation.ts new file mode 100644 index 00000000..dfa00462 --- /dev/null +++ b/prismarine-viewer/examples/TextureAnimation.ts @@ -0,0 +1,69 @@ +export type AnimationControlSwitches = { + tick: number + interpolationTick: number // next one +} + +type Data = { + interpolate: boolean; + frametime: number; + frames: ({ + index: number; + time: number; + } | number)[] | undefined; +}; + +export class TextureAnimation { + data: Data; + frameImages: number; + frameDelta: number; + frameTime: number; + framesToSwitch: number; + frameIndex: number; + + constructor(public animationControl: AnimationControlSwitches, data: Data, public framesImages: number) { + this.data = { + interpolate: false, + frametime: 1, + ...data + }; + this.frameImages = 1; + this.frameDelta = 0; + this.frameTime = this.data.frametime * 50; + this.frameIndex = 0; + + this.framesToSwitch = this.frameImages; + if (this.data.frames) { + this.framesToSwitch = this.data.frames.length; + } + } + + step (deltaMs: number) { + this.frameDelta += deltaMs; + + if (this.frameDelta > this.frameTime) { + this.frameDelta -= this.frameTime; + this.frameDelta %= this.frameTime; + + this.frameIndex++; + this.frameIndex %= this.framesToSwitch; + + const frames = this.data.frames.map(frame => typeof frame === 'number' ? { index: frame, time: this.data.frametime } : frame); + if (frames) { + let frame = frames[this.frameIndex] + let nextFrame = frames[(this.frameIndex + 1) % this.framesToSwitch]; + + this.animationControl.tick = frame.index; + this.animationControl.interpolationTick = nextFrame.index; + this.frameTime = frame.time * 50; + } else { + this.animationControl.tick = this.frameIndex; + this.animationControl.interpolationTick = (this.frameIndex + 1) % this.framesToSwitch; + } + } + + if (this.data.interpolate) { + this.animationControl.interpolationTick = this.frameDelta / this.frameTime; + } + } + +} diff --git a/prismarine-viewer/examples/TouchControls2.tsx b/prismarine-viewer/examples/TouchControls2.tsx new file mode 100644 index 00000000..5d1b4459 --- /dev/null +++ b/prismarine-viewer/examples/TouchControls2.tsx @@ -0,0 +1,63 @@ +import React, { useEffect } from 'react' +import { LeftTouchArea, RightTouchArea, useInterfaceState } from '@dimaka/interface' +import { css } from '@emotion/css' +import { Viewer } from '../viewer/lib/viewer' +import { renderToDom } from '@zardoy/react-util' +import { Vec3 } from 'vec3' +import * as THREE from 'three' + +declare const viewer: Viewer +const Controls = () => { + // todo setting + const usingTouch = navigator.maxTouchPoints > 0 + + useEffect(() => { + let vec3 = new Vec3(0, 0, 0) + + setInterval(() => { + viewer.camera.position.add(new THREE.Vector3(vec3.x, vec3.y, vec3.z)) + }, 1000 / 30) + + useInterfaceState.setState({ + isFlying: false, + uiCustomization: { + touchButtonSize: 40, + }, + updateCoord ([coord, state]) { + vec3 = new Vec3(0, 0, 0) + vec3[coord] = state + } + }) + }, []) + + if (!usingTouch) return null + return ( +
div { + pointer-events: auto; + } + `} + > + +
+ +
+ ) +} + +export const renderPlayground = () => { + renderToDom(, { + // selector: 'body', + }) +} diff --git a/prismarine-viewer/examples/newStats.ts b/prismarine-viewer/examples/newStats.ts new file mode 100644 index 00000000..fb363484 --- /dev/null +++ b/prismarine-viewer/examples/newStats.ts @@ -0,0 +1,35 @@ +let rightOffset = 0 + +const stats = {} + +export const addNewStat = (id: string, width = 80, x = rightOffset, y = 0) => { + const pane = document.createElement('div') + pane.id = 'fps-counter' + pane.style.position = 'fixed' + pane.style.top = `${y}px` + pane.style.right = `${x}px` + // gray bg + pane.style.backgroundColor = 'rgba(0, 0, 0, 0.5)' + pane.style.color = 'white' + pane.style.padding = '2px' + pane.style.fontFamily = 'monospace' + pane.style.fontSize = '12px' + pane.style.zIndex = '10000' + pane.style.pointerEvents = 'none' + document.body.appendChild(pane) + stats[id] = pane + if (y === 0) { // otherwise it's a custom position + rightOffset += width + } + + return { + updateText: (text: string) => { + pane.innerText = text + } + } +} + +export const updateStatText = (id, text) => { + if (!stats[id]) return + stats[id].innerText = text +} diff --git a/prismarine-viewer/examples/playground.ts b/prismarine-viewer/examples/playground.ts index d881f920..1bdd8aa5 100644 --- a/prismarine-viewer/examples/playground.ts +++ b/prismarine-viewer/examples/playground.ts @@ -11,13 +11,22 @@ import JSZip from 'jszip' import { TWEEN_DURATION } from '../viewer/lib/entities' import { EntityMesh } from '../viewer/lib/entity/EntityMesh' import blockstatesModels from 'mc-assets/dist/blockStatesModels.json' +// import * as Mathgl from 'math.gl' +import { initWebgpuRenderer, loadFixtureSides, setAnimationTick, webgpuChannel } from './webgpuRendererMain' +import { renderToDom } from '@zardoy/react-util' globalThis.THREE = THREE //@ts-ignore import { OrbitControls } from 'three/addons/controls/OrbitControls.js' import { toMajorVersion } from '../../src/utils' +import { renderPlayground } from './TouchControls2' +import { WorldRendererWebgpu } from '../viewer/lib/worldrendererWebgpu' +import { TextureAnimation } from './TextureAnimation' +import { BlockType } from './shared' +import { addNewStat } from './newStats' const gui = new GUI() +const { updateText: updateTextEvent } = addNewStat('events', 90, 0, 40) // initial values const params = { @@ -40,7 +49,8 @@ const params = { camera: '', playSound () { }, blockIsomorphicRenderBundle () { }, - modelVariant: 0 + modelVariant: 0, + animationTick: 0 } const qs = new URLSearchParams(window.location.search) @@ -60,10 +70,20 @@ const setQs = () => { let ignoreResize = false +const enableControls = new URLSearchParams(window.location.search).get('controls') === 'true' + async function main () { let continuousRender = false - const { version } = params + // const { version } = params + let fixtureUrl = qs.get('fixture') + let fixture: undefined | Record + if (fixtureUrl) { + console.log('Loading fixture') + fixture = await fetch(fixtureUrl).then(r => r.json()) + console.log('Loaded fixture') + } + const version = fixture?.version ?? '1.20.2' // temporary solution until web worker is here, cache data for faster reloads const globalMcData = window['mcData'] if (!globalMcData['version']) { @@ -94,6 +114,7 @@ async function main () { gui.add(params, 'skipQs') gui.add(params, 'playSound') gui.add(params, 'blockIsomorphicRenderBundle') + const animationController = gui.add(params, 'animationTick', -1, 20, 1).listen() gui.open(false) let metadataFolder = gui.addFolder('metadata') // let entityRotationFolder = gui.addFolder('entity metadata') @@ -125,25 +146,133 @@ async function main () { return chunk }) + let stopUpdate = false + // let stopUpdate = true + // await schem.paste(world, new Vec3(0, 60, 0)) const worldView = new WorldDataEmitter(world, viewDistance, targetPos) - - // Create three.js context, add to page - const renderer = new THREE.WebGLRenderer({ alpha: true, ...localStorage['renderer'] }) - renderer.setPixelRatio(window.devicePixelRatio || 1) - renderer.setSize(window.innerWidth, window.innerHeight) - document.body.appendChild(renderer.domElement) - - // Create viewer - const viewer = new Viewer(renderer, { numWorkers: 1, showChunkBorders: false, }) + const nullRenderer = new THREE.WebGLRenderer({ antialias: true }) + const viewer = new Viewer(nullRenderer, { numWorkers: 1, showChunkBorders: false }) viewer.world.blockstatesModels = blockstatesModels viewer.entities.setDebugMode('basic') + viewer.world.stopBlockUpdate = stopUpdate viewer.setVersion(version) - viewer.entities.onSkinUpdate = () => { - viewer.render() + globalThis.viewer = viewer + + await initWebgpuRenderer(() => { }, !enableControls && !fixture, true) + const simpleControls = () => { + let pressedKeys = new Set() + const loop = () => { + // Create a vector that points in the direction the camera is looking + let direction = new THREE.Vector3(0, 0, 0) + if (pressedKeys.has('KeyW')) { + direction.z = -0.5 + } + if (pressedKeys.has('KeyS')) { + direction.z += 0.5 + } + if (pressedKeys.has('KeyA')) { + direction.x -= 0.5 + } + if (pressedKeys.has('KeyD')) { + direction.x += 0.5 + } + + + if (pressedKeys.has('ShiftLeft')) { + viewer.camera.position.y -= 0.5 + } + if (pressedKeys.has('Space')) { + viewer.camera.position.y += 0.5 + } + direction.applyQuaternion(viewer.camera.quaternion) + direction.y = 0 + + if (pressedKeys.has('ShiftLeft')) { + direction.y *= 2 + direction.x *= 2 + direction.z *= 2 + } + // Add the vector to the camera's position to move the camera + viewer.camera.position.add(direction) + } + setInterval(loop, 1000 / 30) + const keys = (e) => { + const code = e.code + const pressed = e.type === 'keydown' + if (pressed) { + pressedKeys.add(code) + } else { + pressedKeys.delete(code) + } + } + window.addEventListener('keydown', keys) + window.addEventListener('keyup', keys) + window.addEventListener('blur', (e) => { + for (const key of pressedKeys) { + keys(new KeyboardEvent('keyup', { code: key })) + } + }) + + // mouse + const mouse = { x: 0, y: 0 } + let mouseMoveCounter = 0 + const mouseMove = (e: PointerEvent) => { + if ((e.target as HTMLElement).closest('.lil-gui')) return + if (e.buttons === 1 || e.pointerType === 'touch') { + mouseMoveCounter++ + viewer.camera.rotation.x -= e.movementY / 100 + //viewer.camera. + viewer.camera.rotation.y -= e.movementX / 100 + if (viewer.camera.rotation.x < -Math.PI / 2) viewer.camera.rotation.x = -Math.PI / 2 + if (viewer.camera.rotation.x > Math.PI / 2) viewer.camera.rotation.x = Math.PI / 2 + + // yaw += e.movementY / 20; + // pitch += e.movementX / 20; + } + if (e.buttons === 2) { + viewer.camera.position.set(0, 0, 0) + } + } + setInterval(() => { + updateTextEvent(`Mouse Events: ${mouseMoveCounter}`) + mouseMoveCounter = 0 + }, 1000) + window.addEventListener('pointermove', mouseMove) } - viewer.world.mesherConfig.enableLighting = false + viewer.camera.position.set(0, 0, 8) + simpleControls() + renderPlayground() + + const writeToIndexedDb = async (name, data) => { + const db = await window.indexedDB.open(name, 1) + db.onupgradeneeded = (e) => { + const db = (e.target as any).result + db.createObjectStore(name) + } + db.onsuccess = (e) => { + const db = (e.target as any).result + const tx = db.transaction(name, 'readwrite') + const store = tx.objectStore(name) + store.add(data, name) + } + } + + if (fixture) { + loadFixtureSides(fixture.sides) + const pos = fixture.camera[0] + viewer.camera.position.set(pos[0], pos[1], pos[2]) + } + + let blocks: Record = {} + let i = 0 + console.log('generating random data') + webgpuChannel.generateRandom(490_000) + + return + + // Create viewer viewer.listen(worldView) // Load chunks @@ -151,127 +280,17 @@ async function main () { window['worldView'] = worldView window['viewer'] = viewer - params.blockIsomorphicRenderBundle = () => { - const canvas = renderer.domElement - const onlyCurrent = !confirm('Ok - render all blocks, Cancel - render only current one') - const sizeRaw = prompt('Size', '512') - if (!sizeRaw) return - const size = parseInt(sizeRaw) - // const size = 512 - - ignoreResize = true - canvas.width = size - canvas.height = size - renderer.setSize(size, size) - - //@ts-ignore - viewer.camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 10) - viewer.scene.background = null - - const rad = THREE.MathUtils.degToRad(-120) - viewer.directionalLight.position.set( - Math.cos(rad), - Math.sin(rad), - 0.2 - ).normalize() - viewer.directionalLight.intensity = 1 - - const cameraPos = targetPos.offset(2, 2, 2) - const pitch = THREE.MathUtils.degToRad(-30) - const yaw = THREE.MathUtils.degToRad(45) - viewer.camera.rotation.set(pitch, yaw, 0, 'ZYX') - // viewer.camera.lookAt(center.x + 0.5, center.y + 0.5, center.z + 0.5) - viewer.camera.position.set(cameraPos.x + 1, cameraPos.y + 0.5, cameraPos.z + 1) - - const allBlocks = mcData.blocksArray.map(b => b.name) - // const allBlocks = ['stone', 'warped_slab'] - - let blockCount = 1 - let blockName = allBlocks[0] - - const updateBlock = () => { - - //@ts-ignore - // viewer.setBlockStateId(targetPos, mcData.blocksByName[blockName].minStateId) - params.block = blockName - // todo cleanup (introduce getDefaultState) - onUpdate.block() - applyChanges(false, true) - } - viewer.waitForChunksToRender().then(async () => { - // wait for next macro task - await new Promise(resolve => { - setTimeout(resolve, 0) - }) - if (onlyCurrent) { - viewer.render() - onWorldUpdate() - } else { - // will be called on every render update - viewer.world.renderUpdateEmitter.addListener('update', onWorldUpdate) - updateBlock() - } - }) - - const zip = new JSZip() - zip.file('description.txt', 'Generated with prismarine-viewer') - - const end = async () => { - // download zip file - - const a = document.createElement('a') - const blob = await zip.generateAsync({ type: 'blob' }) - const dataUrlZip = URL.createObjectURL(blob) - a.href = dataUrlZip - a.download = 'blocks_render.zip' - a.click() - URL.revokeObjectURL(dataUrlZip) - console.log('end') - - viewer.world.renderUpdateEmitter.removeListener('update', onWorldUpdate) - } - - async function onWorldUpdate () { - // await new Promise(resolve => { - // setTimeout(resolve, 50) - // }) - const dataUrl = canvas.toDataURL('image/png') - - zip.file(`${blockName}.png`, dataUrl.split(',')[1], { base64: true }) - - if (onlyCurrent) { - end() - } else { - nextBlock() - } - } - const nextBlock = async () => { - blockName = allBlocks[blockCount++] - console.log(allBlocks.length, '/', blockCount, blockName) - if (blockCount % 5 === 0) { - await new Promise(resolve => { - setTimeout(resolve, 100) - }) - } - if (blockName) { - updateBlock() - } else { - end() - } - } - } - //@ts-ignore - const controls = new OrbitControls(viewer.camera, renderer.domElement) - controls.target.set(targetPos.x + 0.5, targetPos.y + 0.5, targetPos.z + 0.5) + // const controls = new OrbitControls(viewer.camera, nullRenderer.domElement) + // controls.target.set(targetPos.x + 0.5, targetPos.y + 0.5, targetPos.z + 0.5) const cameraPos = targetPos.offset(2, 2, 2) const pitch = THREE.MathUtils.degToRad(-45) const yaw = THREE.MathUtils.degToRad(45) viewer.camera.rotation.set(pitch, yaw, 0, 'ZYX') - viewer.camera.lookAt(targetPos.x + 0.5, targetPos.y + 0.5, targetPos.z + 0.5) - viewer.camera.position.set(cameraPos.x + 0.5, cameraPos.y + 0.5, cameraPos.z + 0.5) - controls.update() + // viewer.camera.lookAt(targetPos.x + 0.5, targetPos.y + 0.5, targetPos.z + 0.5) + viewer.camera.position.set(cameraPos.x, cameraPos.y, cameraPos.z) + // controls.update() let blockProps = {} let entityOverrides = {} @@ -302,6 +321,9 @@ async function main () { }, TWEEN_DURATION) } + params.block ||= 'stone' + + let textureAnimation: TextureAnimation | undefined const onUpdate = { version (initialUpdate) { if (initialUpdate) return @@ -381,6 +403,27 @@ async function main () { }, modelVariant () { viewer.world.mesherConfig.debugModelVariant = params.modelVariant === 0 ? undefined : [params.modelVariant] + }, + animationTick () { + // TODO + const webgl = (viewer.world as WorldRendererWebgpu).playgroundGetWebglData() as unknown as { animation: any } + if (!webgl?.animation) { + setAnimationTick(0) + return + } + if (params.animationTick === -1) { + textureAnimation = new TextureAnimation(new Proxy({} as any, { + set (t, p, v) { + if (p === 'tick') { + setAnimationTick(v) + } + return true + } + }), webgl.animation, webgl.animation.framesCount) + } else { + setAnimationTick(params.animationTick) + textureAnimation = undefined + } } } @@ -418,7 +461,9 @@ async function main () { if (object === params) { if (property === 'camera') return onUpdate[property]?.() - applyChanges(property === 'metadata') + if (property !== 'animationTick') { + applyChanges(property === 'metadata') + } } else { applyChanges() } @@ -432,25 +477,35 @@ async function main () { update(true) } applyChanges() - gui.openAnimated() + // gui.openAnimated() }) - const animate = () => { + const animate = () => { } + const animate2 = () => { // if (controls) controls.update() // worldView.updatePosition(controls.target) viewer.render() - // window.requestAnimationFrame(animate) + window.requestAnimationFrame(animate2) } viewer.world.renderUpdateEmitter.addListener('update', () => { - animate() + // const frames = viewer.world.hasWithFrames ? viewer.world.hasWithFrames - 1 : 0; + const webgl = (viewer.world as WorldRendererWebgpu).playgroundGetWebglData() + // if (webgl?.animation) { + // params.animationTick = -1 + // animationController.show() + // animationController.max(webgl.animation.framesCount) + // } else { + // animationController.hide() + // } + onUpdate.animationTick() }) - animate() + animate2() // #region camera rotation param if (params.camera) { const [x, y] = params.camera.split(',') viewer.camera.rotation.set(parseFloat(x), parseFloat(y), 0, 'ZYX') - controls.update() + // controls.update() console.log(viewer.camera.rotation.x, parseFloat(x)) } const throttledCamQsUpdate = _.throttle(() => { @@ -458,16 +513,16 @@ async function main () { // params.camera = `${camera.rotation.x.toFixed(2)},${camera.rotation.y.toFixed(2)}` setQs() }, 200) - controls.addEventListener('change', () => { - throttledCamQsUpdate() - animate() - }) + // controls.addEventListener('change', () => { + // throttledCamQsUpdate() + // animate() + // }) // #endregion + let time = performance.now() const continuousUpdate = () => { - if (continuousRender) { - animate() - } + textureAnimation?.step(performance.now() - time) + time = performance.now() requestAnimationFrame(continuousUpdate) } continuousUpdate() @@ -482,7 +537,7 @@ async function main () { const { camera } = viewer viewer.camera.aspect = window.innerWidth / window.innerHeight viewer.camera.updateProjectionMatrix() - renderer.setSize(window.innerWidth, window.innerHeight) + nullRenderer.setSize(window.innerWidth, window.innerHeight) animate() } diff --git a/prismarine-viewer/examples/shared.ts b/prismarine-viewer/examples/shared.ts new file mode 100644 index 00000000..4ef9b417 --- /dev/null +++ b/prismarine-viewer/examples/shared.ts @@ -0,0 +1,11 @@ +export type BlockFaceType = { + side: number + textureIndex: number + textureName?: string + tint?: [number, number, number] + isTransparent?: boolean +} + +export type BlockType = { + faces: BlockFaceType[] +} diff --git a/prismarine-viewer/examples/webgpuRenderer.ts b/prismarine-viewer/examples/webgpuRenderer.ts new file mode 100644 index 00000000..189ac02d --- /dev/null +++ b/prismarine-viewer/examples/webgpuRenderer.ts @@ -0,0 +1,511 @@ +import * as THREE from 'three'; +import { BlockFaceType } from './shared'; +import * as tweenJs from '@tweenjs/tween.js'; +import { cubePositionOffset, cubeUVOffset, cubeVertexArray, cubeVertexCount, cubeVertexSize } from './CubeDef'; +import VertShader from './Cube.vert.wgsl'; +import FragShader from './Cube.frag.wgsl'; +import ComputeShader from './Cube.comp.wgsl'; +import { updateSize, allSides } from './webgpuRendererWorker'; + +export class WebgpuRenderer { + rendering = true + NUMBER_OF_CUBES = 490_000; + renderedFrames = 0 + localStorage: any = {} + + ready = false; + + device: GPUDevice; + renderPassDescriptor: GPURenderPassDescriptor; + uniformBindGroup: GPUBindGroup; + UniformBuffer: GPUBuffer; + ViewUniformBuffer: GPUBuffer; + ProjectionUniformBuffer: GPUBuffer; + ctx: GPUCanvasContext; + verticesBuffer: GPUBuffer; + InstancedModelBuffer: GPUBuffer; + pipeline: GPURenderPipeline; + InstancedTextureIndexBuffer: GPUBuffer; + InstancedColorBuffer: GPUBuffer; + notRenderedAdditions = 0; + + // Add these properties to the WebgpuRenderer class + computePipeline: GPUComputePipeline; + indirectDrawBuffer: GPUBuffer; + cubesBuffer: GPUBuffer; + visibleCubesBuffer: GPUBuffer; + computeBindGroup: GPUBindGroup; + computeBindGroupLayout: GPUBindGroupLayout; + indirectDrawParams: Uint32Array; + maxBufferSize: number + + constructor(public canvas: HTMLCanvasElement, public imageBlob: ImageBitmapSource, public isPlayground: boolean, public camera: THREE.PerspectiveCamera) { + this.init(); + } + + async init () { + const { canvas, imageBlob, isPlayground, localStorage } = this; + + updateSize(canvas.width, canvas.height); + const textureBitmap = await createImageBitmap(imageBlob); + const textureWidth = textureBitmap.width; + const textureHeight = textureBitmap.height; + + const adapter = await navigator.gpu.requestAdapter(); + if (!adapter) throw new Error('WebGPU not supported'); + this.device = await adapter.requestDevice(); + const { device } = this; + this.maxBufferSize = device.limits.maxStorageBufferBindingSize; + this.renderedFrames = device.limits.maxComputeWorkgroupSizeX; + console.log('max buffer size', this.maxBufferSize / 1024 / 1024, 'MB') + + const ctx = this.ctx = canvas.getContext('webgpu')!; + + const presentationFormat = navigator.gpu.getPreferredCanvasFormat(); + + ctx.configure({ + device, + format: presentationFormat, + alphaMode: 'premultiplied', + }); + + const verticesBuffer = device.createBuffer({ + size: cubeVertexArray.byteLength, + usage: GPUBufferUsage.VERTEX, + mappedAtCreation: true, + }); + this.verticesBuffer = verticesBuffer; + new Float32Array(verticesBuffer.getMappedRange()).set(cubeVertexArray); + verticesBuffer.unmap(); + + const pipeline = device.createRenderPipeline({ + label: 'mainPipeline', + layout: 'auto', + vertex: { + module: device.createShaderModule({ + code: localStorage.vertShader || VertShader, + }), + buffers: [ + { + arrayStride: cubeVertexSize, + attributes: [ + { + shaderLocation: 0, + offset: cubePositionOffset, + format: 'float32x3', + }, + { + shaderLocation: 1, + offset: cubeUVOffset, + format: 'float32x2', + }, + ], + }, + // { + // arrayStride: 3 * 4, + // attributes: [ + // { + // shaderLocation: 2, + // offset: 0, + // format: 'float32x3', + // }, + // ], + // stepMode: 'instance', + // }, + // { + // arrayStride: 1 * 4, + // attributes: [ + // { + // shaderLocation: 3, + // offset: 0, + // format: 'float32', + // }, + // ], + // stepMode: 'instance', + // }, + // { + // arrayStride: 3 * 4, + // attributes: [ + // { + // shaderLocation: 4, + // offset: 0, + // format: 'float32x3', + // }, + // ], + // stepMode: 'instance', + // }, + ], + }, + fragment: { + module: device.createShaderModule({ + code: localStorage.fragShader || FragShader, + }), + targets: [ + { + format: presentationFormat, + blend: { + color: { + srcFactor: 'src-alpha', + dstFactor: 'one-minus-src-alpha', + operation: 'add', + }, + alpha: { + srcFactor: 'src-alpha', + dstFactor: 'one-minus-src-alpha', + operation: 'add', + }, + }, + }, + ], + }, + + primitive: { + topology: 'triangle-list', + cullMode: 'front', + }, + depthStencil: { + depthWriteEnabled: true, + depthCompare: 'less', + format: 'depth24plus', + }, + }); + this.pipeline = pipeline; + + const depthTexture = device.createTexture({ + size: [canvas.width, canvas.height], + format: 'depth24plus', + usage: GPUTextureUsage.RENDER_ATTACHMENT, + }); + + const uniformBufferSize = 4 * (4 * 4); // 4x4 matrix + this.UniformBuffer = device.createBuffer({ + size: uniformBufferSize, + usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, + }); + + // Fetch the image and upload it into a GPUTexture. + let cubeTexture: GPUTexture; + { + cubeTexture = device.createTexture({ + size: [textureBitmap.width, textureBitmap.height, 1], + format: 'rgb10a2unorm', + usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT, + }); + device.queue.copyExternalImageToTexture( + { source: textureBitmap }, + { texture: cubeTexture }, + [textureBitmap.width, textureBitmap.height] + ); + } + + const sampler = device.createSampler({ + magFilter: 'nearest', + minFilter: 'nearest', + }); + + this.renderPassDescriptor = { + label: 'MainRenderPassDescriptor', + colorAttachments: [ + { + view: undefined as any, // Assigned later + clearValue: [0.6784313725490196, 0.8470588235294118, 0.9019607843137255, 1], + loadOp: 'clear', + storeOp: 'store', + }, + ], + depthStencilAttachment: { + view: depthTexture.createView(), + depthClearValue: 1, + depthLoadOp: 'clear', + depthStoreOp: 'store', + }, + }; + + // Create compute pipeline + const computeShaderModule = device.createShaderModule({ + code: localStorage.computeShader || ComputeShader, + label: 'Culled Instance', + }); + + const computeBindGroupLayout = device.createBindGroupLayout({ + label: 'computeBindGroupLayout', + entries: [ + { binding: 0, visibility: GPUShaderStage.COMPUTE, buffer: { type: 'uniform' } }, + { binding: 1, visibility: GPUShaderStage.COMPUTE, buffer: { type: 'read-only-storage' } }, + { binding: 2, visibility: GPUShaderStage.COMPUTE, buffer: { type: 'storage' } }, + { binding: 3, visibility: GPUShaderStage.COMPUTE, buffer: { type: 'storage' } }, + ], + }); + + const computePipelineLayout = device.createPipelineLayout({ + label: 'computePipelineLayout', + bindGroupLayouts: [computeBindGroupLayout], + + }) + + this.computePipeline = device.createComputePipeline({ + label: 'Culled Instance', + layout: computePipelineLayout, + // layout: 'auto', + compute: { + module: computeShaderModule, + entryPoint: 'main', + }, + }); + + // Create buffers for compute shader and indirect drawing + this.cubesBuffer = device.createBuffer({ + label: 'cubesBuffer', + size: this.NUMBER_OF_CUBES * 32, // 8 floats per cube - minimum buffer size + usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST, + }); + + this.visibleCubesBuffer = device.createBuffer({ + label: 'visibleCubesBuffer', + size: this.NUMBER_OF_CUBES * 32, + usage: GPUBufferUsage.STORAGE | GPUBufferUsage.VERTEX, + }); + + this.indirectDrawBuffer = device.createBuffer({ + label: 'indirectDrawBuffer', + size: 16, // 4 uint32 values + usage: GPUBufferUsage.INDIRECT | GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST, + }); + + // Initialize indirect draw parameters + const indirectDrawParams = new Uint32Array([cubeVertexCount, 0, 0, 0]); + device.queue.writeBuffer(this.indirectDrawBuffer, 0, indirectDrawParams); + + // const vertexBindGroupLayout = device.createBindGroupLayout({ + // label: 'vertexBindGroupLayout', + // entries: [ + // { binding: 0, visibility: GPUShaderStage.VERTEX, buffer: { type: 'uniform' } }, + // { binding: 2, visibility: GPUShaderStage.VERTEX, buffer: { type: 'read-only-storage' } } // Read-only storage + // ] + // }); + + + // Create bind group for render pass + this.uniformBindGroup = device.createBindGroup({ + label: 'uniformBindGroups', + //layout: vertexBindGroupLayout, + layout: pipeline.getBindGroupLayout(0), + entries: [ + { + binding: 0, + resource: { + buffer: this.UniformBuffer, + }, + }, + { + binding: 1, + resource: sampler, + }, + { + binding: 2, + resource: cubeTexture.createView(), + }, + { + binding: 3, + resource: { + buffer: this.visibleCubesBuffer + } + + } + ], + }); + + // // Create bind group for compute shader + // this.computeBindGroupLayout = device.createBindGroupLayout({ + // label: 'computeBindGroupLayout', + // entries: [ + // { + // binding: 0, + // visibility: GPUShaderStage.COMPUTE, + // buffer: { + // type: 'uniform', + // }, + // }, + // { + // binding: 1, + // visibility: GPUShaderStage.COMPUTE, + // buffer: { + // type: 'storage', + // }, + // }, + // { + // binding: 2, + // visibility: GPUShaderStage.COMPUTE, + // buffer: { + // type: '', + // }, + // }, + // { + // binding: 3, + // visibility: GPUShaderStage.COMPUTE, + // buffer: { + // type: 'storage', + // }, + // }, + // ], + // }); + + this.computeBindGroup = device.createBindGroup({ + //layout: this.computeBindGroupLayout, + layout: this.computePipeline.getBindGroupLayout(0), + label: 'computeBindGroup', + entries: [ + { + binding: 0, + resource: { buffer: this.UniformBuffer }, + }, + { + binding: 1, + resource: { buffer: this.cubesBuffer }, + }, + { + binding: 2, + resource: { buffer: this.visibleCubesBuffer }, + }, + { + binding: 3, + resource: { buffer: this.indirectDrawBuffer }, + }, + ], + }) + + this.indirectDrawParams = new Uint32Array([cubeVertexCount, 0, 0, 0]); + + // always last! + this.rendering = false; + console.log('init finish') + this.updateSides() + this.loop(); + this.ready = true; + return canvas; + } + + removeOne () { } + + realNumberOfCubes = 0; + + updateSides (startOffset = 0) { + console.time('updateSides') + this.rendering = true; + const positions = [] as number[]; + let textureIndexes = [] as number[]; + let colors = [] as number[]; + const blocksPerFace = {} as Record; + for (const side of allSides.slice(startOffset)) { + if (!side) continue; + const [x, y, z] = side.slice(0, 3); + const key = `${x},${y},${z}`; + if (blocksPerFace[key]) continue; + blocksPerFace[key] = side[3]; + } + for (const key in blocksPerFace) { + const side = key.split(',').map(Number); + positions.push(...[side[0], side[1], side[2]]); + const face = blocksPerFace[key]; + textureIndexes.push(face.textureIndex); + colors.push(1, 1, 1); + } + + const NUMBER_OF_CUBES_NEEDED = Math.ceil(positions.length / 3); + this.realNumberOfCubes = NUMBER_OF_CUBES_NEEDED; + if (NUMBER_OF_CUBES_NEEDED > this.NUMBER_OF_CUBES) { + console.warn('extending number of cubes', NUMBER_OF_CUBES_NEEDED, this.NUMBER_OF_CUBES) + this.NUMBER_OF_CUBES = NUMBER_OF_CUBES_NEEDED + 5000; + } + + const BYTES_PER_ELEMENT = 8; + const cubeData = new Float32Array(this.NUMBER_OF_CUBES * BYTES_PER_ELEMENT); + for (let i = 0; i < this.NUMBER_OF_CUBES; i++) { + const offset = i * BYTES_PER_ELEMENT; + cubeData[offset] = positions[i * 3]; + cubeData[offset + 1] = positions[i * 3 + 1]; + cubeData[offset + 2] = positions[i * 3 + 2]; + cubeData[offset + 3] = textureIndexes[i]; + cubeData[offset + 4] = colors[i * 3]; + cubeData[offset + 5] = colors[i * 3 + 1]; + cubeData[offset + 6] = colors[i * 3 + 2]; + //cubeData[offset + 7] = 0.5; // Sphere radius + } + + console.time('writeCubes buffer') + this.device.queue.writeBuffer(this.cubesBuffer, 0, cubeData); + console.timeEnd('writeCubes buffer') + + // Reset indirect draw parameters + // this.indirectDrawParams = new Uint32Array([cubeVertexCount, 0, 0, 0]); + //this.device.queue.writeBuffer(this.indirectDrawBuffer, 0, this.indirectDrawParams); + + this.notRenderedAdditions++; + console.timeEnd('updateSides') + } + + lastCall = performance.now(); + logged = false; + loop () { + if (!this.rendering) { + requestAnimationFrame(() => this.loop()); + return; + } + + const { device, UniformBuffer: uniformBuffer, renderPassDescriptor, uniformBindGroup, pipeline, ctx, verticesBuffer } = this; + + const now = Date.now(); + tweenJs.update(); + + const ViewProjectionMat4 = new THREE.Matrix4(); + this.camera.updateMatrix(); + const projectionMatrix = this.camera.projectionMatrix; + ViewProjectionMat4.multiplyMatrices(projectionMatrix, this.camera.matrix.invert()); + const ViewProjection = new Float32Array(ViewProjectionMat4.elements); + device.queue.writeBuffer( + uniformBuffer, + 0, + ViewProjection + ); + + // const EmptyVisibleCubes = new Float32Array([36, 0, 0, 0]) ; + + device.queue.writeBuffer( + this.indirectDrawBuffer, 0, this.indirectDrawParams); + + renderPassDescriptor.colorAttachments[0].view = ctx + .getCurrentTexture() + .createView(); + + let commandEncoder = device.createCommandEncoder(); + // Compute pass for occlusion culling + commandEncoder.label = "Main Comand Encoder" + const computePass = commandEncoder.beginComputePass(); + computePass.label = "ComputePass" + computePass.setPipeline(this.computePipeline); + //computePass.setBindGroup(0, this.uniformBindGroup); + computePass.setBindGroup(0, this.computeBindGroup); + computePass.dispatchWorkgroups(Math.ceil(this.NUMBER_OF_CUBES / 256)); + computePass.end(); + device.queue.submit([commandEncoder.finish()]); + commandEncoder = device.createCommandEncoder(); + //device.queue.submit([commandEncoder.finish()]); + // Render pass + //console.log(this.indirectDrawBuffer.getMappedRange()); + const renderPass = commandEncoder.beginRenderPass(this.renderPassDescriptor); + renderPass.label = "RenderPass" + renderPass.setPipeline(pipeline); + renderPass.setBindGroup(0, this.uniformBindGroup); + renderPass.setVertexBuffer(0, verticesBuffer); + + // Use indirect drawing + renderPass.drawIndirect(this.indirectDrawBuffer, 0); + + renderPass.end(); + device.queue.submit([commandEncoder.finish()]); + + this.renderedFrames++; + requestAnimationFrame(() => this.loop()); + this.notRenderedAdditions = 0; + } +} diff --git a/prismarine-viewer/examples/webgpuRendererMain.ts b/prismarine-viewer/examples/webgpuRendererMain.ts new file mode 100644 index 00000000..22f057b4 --- /dev/null +++ b/prismarine-viewer/examples/webgpuRendererMain.ts @@ -0,0 +1,204 @@ +import { generateSpiralMatrix } from 'flying-squid/dist/utils' +import { Viewer } from '../viewer/lib/viewer' +import { addNewStat } from './newStats' +import type { workerProxyType } from './webgpuRendererWorker' +import { useWorkerProxy } from './workerProxy' +import { MesherGeometryOutput } from '../viewer/lib/mesher/shared' +import { pickObj } from '@zardoy/utils' + +let worker: Worker + +export let webgpuChannel: typeof workerProxyType['__workerProxy'] = new Proxy({}, { + get: () => () => { } +}) as any // placeholder to avoid crashes + +declare const viewer: Viewer + +let allReceived = false +declare const customEvents +declare const bot +if (typeof customEvents !== 'undefined') { + customEvents.on('gameLoaded', () => { + const chunksExpected = generateSpiralMatrix(globalThis.options.renderDistance) + let received = 0 + bot.on('chunkColumnLoad', (data) => { + received++ + if (received === chunksExpected.length) { + allReceived = true + // addBlocksSection('all', viewer.world.newChunks) + } + }) + }) +} + + +let isWaitingToUpload = false +globalThis.tiles = {} +export const addBlocksSection = (key, data: MesherGeometryOutput) => { + if (globalThis.tiles[key]) return + globalThis.tiles[key] = data.tiles + webgpuChannel.addBlocksSection(data.tiles, key, false) + if (playground && !isWaitingToUpload) { + isWaitingToUpload = true + // viewer.waitForChunksToRender().then(() => { + // isWaitingToUpload = false + // sendWorkerMessage({ + // type: 'addBlocksSectionDone' + // }) + // }) + } +} + +export const loadFixtureSides = (json) => { + webgpuChannel.loadFixture(json) +} + +export const sendCameraToWorker = () => { + const cameraVectors = ['rotation', 'position'].reduce((acc, key) => { + acc[key] = ['x', 'y', 'z'].reduce((acc2, key2) => { + acc2[key2] = viewer.camera[key][key2] + return acc2 + }, {}) + return acc + }, {}) as any + webgpuChannel.camera({ + ...cameraVectors, + fov: viewer.camera.fov + }) +} + +export const removeBlocksSection = (key) => { + webgpuChannel.removeBlocksSection(key) +} + +let playground = false +export const initWebgpuRenderer = async (postRender = () => { }, playgroundModeInWorker = false, actuallyPlayground = false) => { + playground = actuallyPlayground + await new Promise(resolve => { + // console.log('viewer.world.material.map!.image', viewer.world.material.map!.image) + // viewer.world.material.map!.image.onload = () => { + // console.log(this.material.map!.image) + // resolve() + // } + viewer.world.renderUpdateEmitter.once('textureDownloaded', resolve) + }) + const image = viewer.world.material.map!.image + const imageBlob = await fetch(image.src).then((res) => res.blob()) + const canvas = document.createElement('canvas') + canvas.width = window.innerWidth * window.devicePixelRatio + canvas.height = window.innerHeight * window.devicePixelRatio + document.body.appendChild(canvas) + canvas.id = 'viewer-canvas' + console.log('starting offscreen') + + const offscreen = canvas.transferControlToOffscreen() + + // replacable by initWebglRenderer + worker = new Worker('./webgpuRendererWorker.js') + addFpsCounters() + webgpuChannel = useWorkerProxy(worker, true) + webgpuChannel.canvas(offscreen, imageBlob, playgroundModeInWorker, pickObj(localStorage, 'vertShader', 'fragShader', 'computeShader')) + + let oldWidth = window.innerWidth + let oldHeight = window.innerHeight + let oldCamera = { + position: { x: 0, y: 0, z: 0 }, + rotation: { x: 0, y: 0, z: 0 } + } + let focused = true + window.addEventListener('focus', () => { + focused = true + webgpuChannel.startRender() + }) + window.addEventListener('blur', () => { + focused = false + webgpuChannel.stopRender() + }) + const mainLoop = () => { + requestAnimationFrame(mainLoop) + //@ts-ignore + if (!focused || window.stopRender) return + + if (oldWidth !== window.innerWidth || oldHeight !== window.innerHeight) { + oldWidth = window.innerWidth + oldHeight = window.innerHeight + webgpuChannel.resize(window.innerWidth * window.devicePixelRatio, window.innerHeight * window.devicePixelRatio) + } + postRender() + // TODO! do it in viewer to avoid possible delays + if (actuallyPlayground && ['rotation', 'position'].some((key) => oldCamera[key] !== viewer.camera[key])) { + // TODO fix + for (const [key, val] of Object.entries(oldCamera)) { + for (const key2 of Object.keys(val)) { + oldCamera[key][key2] = viewer.camera[key][key2] + } + } + sendCameraToWorker() + } + } + + requestAnimationFrame(mainLoop) +} + +export const setAnimationTick = (tick: number, frames?: number) => { + webgpuChannel.animationTick(tick, frames) +} + +export const exportLoadedTiles = () => { + webgpuChannel.exportData() + const controller = new AbortController() + worker.addEventListener('message', async (e) => { + const receivedData = e.data.data + console.log('received fixture') + // await new Promise(resolve => { + // setTimeout(resolve, 0) + // }) + try { + const a = document.createElement('a') + type Vec3 = [number, number, number] + type PlayTimeline = [pos: Vec3, rot: Vec3, time: number] + const vec3ToArr = (vec3: { x, y, z }) => [vec3.x, vec3.y, vec3.z] as Vec3 + // const dataObj = { + // ...receivedData, + // version: viewer.version, + // camera: [vec3ToArr(viewer.camera.position), vec3ToArr(viewer.camera.rotation)], + // playTimeline: [] as PlayTimeline[] + // } + // split into two chunks + const objectURL = URL.createObjectURL(new Blob([receivedData.sides.buffer], { type: 'application/octet-stream' })) + a.href = objectURL + a.download = 'dumped-chunks-tiles.bin' + a.click() + URL.revokeObjectURL(objectURL) + } finally { + controller.abort() + } + }, { signal: controller.signal }) +} + + +const addFpsCounters = () => { + const { updateText } = addNewStat('fps') + let prevTimeout + worker.addEventListener('message', (e) => { + if (e.data.type === 'fps') { + updateText(`FPS: ${e.data.fps}`) + if (prevTimeout) clearTimeout(prevTimeout) + prevTimeout = setTimeout(() => { + updateText('') + }, 1002) + } + }) + + const { updateText: updateText2 } = addNewStat('fps-main', 90, 0, 20) + let updates = 0 + const mainLoop = () => { + requestAnimationFrame(mainLoop) + updates++ + } + mainLoop() + setInterval(() => { + updateText2(`Main Loop: ${updates}`) + updates = 0 + }, 1000) +} diff --git a/prismarine-viewer/examples/webgpuRendererWorker.ts b/prismarine-viewer/examples/webgpuRendererWorker.ts new file mode 100644 index 00000000..af5bd6d3 --- /dev/null +++ b/prismarine-viewer/examples/webgpuRendererWorker.ts @@ -0,0 +1,241 @@ +/// +import * as THREE from 'three' +import { BlockFaceType, BlockType } from './shared' +import * as tweenJs from '@tweenjs/tween.js' +//@ts-ignore +//@ts-ignore +import { createWorkerProxy } from './workerProxy' +import { WebgpuRenderer } from './webgpuRenderer' + +export let allSides = [] as ([number, number, number, BlockFaceType] | undefined)[] +globalThis.allSides = allSides +let allSidesAdded = 0 +let needsSidesUpdate = false + +let chunksArrIndexes = {} +let freeArrayIndexes = [] as [number, number][] +let sidePositions +let lastNotUpdatedIndex +let lastNotUpdatedArrSize +let animationTick = 0 + +const camera = new THREE.PerspectiveCamera(75, 1 / 1, 0.1, 10_000) +globalThis.camera = camera + +let webgpuRenderer: WebgpuRenderer | undefined + +setInterval(() => { + if (!webgpuRenderer) return + // console.log('FPS:', renderedFrames) + postMessage({ type: 'fps', fps: webgpuRenderer.renderedFrames }) + webgpuRenderer.renderedFrames = 0 +}, 1000) + +export const updateSize = (width, height) => { + camera.aspect = width / height + camera.updateProjectionMatrix() +} + + +let fullReset + +const updateCubesWhenAvailable = (pos) => { + if (webgpuRenderer?.ready) { + webgpuRenderer.updateSides(pos) + } else { + setTimeout(updateCubesWhenAvailable, 100) + } +} + +let started = false +let newWidth: number | undefined +let newHeight: number | undefined +let autoTickUpdate = undefined as number | undefined +export const workerProxyType = createWorkerProxy({ + canvas (canvas, imageBlob, isPlayground, localStorage) { + started = true + webgpuRenderer = new WebgpuRenderer(canvas, imageBlob, isPlayground, camera) + webgpuRenderer.localStorage + globalThis.webgpuRenderer = webgpuRenderer + }, + startRender () { + if (!webgpuRenderer) return + webgpuRenderer.rendering = true + }, + stopRender () { + if (!webgpuRenderer) return + webgpuRenderer.rendering = false + }, + resize (newWidth, newHeight) { + newWidth = newWidth + newHeight = newHeight + updateSize(newWidth, newHeight) + }, + generateRandom (count: number) { + const square = Math.sqrt(count) + if (square % 1 !== 0) throw new Error('square must be a whole number') + const blocks = {} + const getFace = (face: number) => { + return { + side: face, + textureIndex: Math.floor(Math.random() * 512) + } + } + for (let x = 0; x < square; x++) { + for (let z = 0; z < square; z++) { + blocks[`${x},${0},${z}`] = { + faces: [ + getFace(0), + getFace(1), + getFace(2), + getFace(3), + getFace(4), + getFace(5) + ], + } + } + } + console.log('data ready') + this.addBlocksSection(blocks, `0,0,0`) + }, + addBlocksSection (tiles: Record, key: string, update = true) { + const currentLength = allSides.length + // in: object - name, out: [x, y, z, name] + const newData = Object.entries(tiles).flatMap(([key, value]) => { + const [x, y, z] = key.split(',').map(Number) + const block = value as BlockType + return block.faces.map((side) => { + return [x, y, z, side] as [number, number, number, BlockFaceType] + }) + }) + // find freeIndexes if possible + const freeArea = freeArrayIndexes.find(([startIndex, endIndex]) => endIndex - startIndex >= newData.length) + if (freeArea) { + const [startIndex, endIndex] = freeArea + allSides.splice(startIndex, newData.length, ...newData) + lastNotUpdatedIndex ??= startIndex + const freeAreaIndex = freeArrayIndexes.indexOf(freeArea) + freeArrayIndexes[freeAreaIndex] = [startIndex + newData.length, endIndex] + if (freeArrayIndexes[freeAreaIndex][0] >= freeArrayIndexes[freeAreaIndex][1]) { + freeArrayIndexes.splice(freeAreaIndex, 1) + // todo merge + } + lastNotUpdatedArrSize = newData.length + console.log('using free area', freeArea) + } + + chunksArrIndexes[key] = [currentLength, currentLength + newData.length] + let i = 0; + while (i < newData.length) { + allSides.splice(currentLength + i, 0, ...newData.slice(i, i + 1024)); + i += 1024; + } + lastNotUpdatedIndex ??= currentLength + // if (webglRendererWorker && webglRendererWorker.notRenderedAdditions < 5) { + if (update) { + updateCubesWhenAvailable(currentLength) + } + }, + addBlocksSectionDone () { + updateCubesWhenAvailable(lastNotUpdatedIndex) + lastNotUpdatedIndex = undefined + lastNotUpdatedArrSize = undefined + }, + removeBlocksSection (key) { + return + // fill data with 0 + const [startIndex, endIndex] = chunksArrIndexes[key] + for (let i = startIndex; i < endIndex; i++) { + allSides[i] = undefined + } + lastNotUpdatedArrSize = endIndex - startIndex + updateCubesWhenAvailable(startIndex) + + // freeArrayIndexes.push([startIndex, endIndex]) + + // // merge freeArrayIndexes TODO + // if (freeArrayIndexes.at(-1)[0] === freeArrayIndexes.at(-2)?.[1]) { + // const [startIndex, endIndex] = freeArrayIndexes.pop()! + // const [startIndex2, endIndex2] = freeArrayIndexes.pop()! + // freeArrayIndexes.push([startIndex2, endIndex]) + // } + }, + camera (newCam: { rotation: { x: number, y: number, z: number }, position: { x: number, y: number, z: number }, fov: number }) { + // if (webgpuRenderer?.isPlayground) { + // camera.rotation.order = 'ZYX' + // new tweenJs.Tween(camera.rotation).to({ x: newCam.rotation.x, y: newCam.rotation.y, z: newCam.rotation.z }, 50).start() + // } else { + camera.rotation.set(newCam.rotation.x, newCam.rotation.y, newCam.rotation.z, 'ZYX') + // } + if (newCam.position.x === 0 && newCam.position.y === 0 && newCam.position.z === 0) { + // initial camera position + camera.position.set(newCam.position.x, newCam.position.y, newCam.position.z) + } else { + new tweenJs.Tween(camera.position).to({ x: newCam.position.x, y: newCam.position.y, z: newCam.position.z }, 50).start() + } + + if (newCam.fov !== camera.fov) { + camera.fov = newCam.fov + camera.updateProjectionMatrix() + } + }, + animationTick (frames, tick) { + if (frames <= 0) { + autoTickUpdate = undefined + animationTick = 0 + return + } + if (tick === -1) { + autoTickUpdate = frames + } else { + autoTickUpdate = undefined + animationTick = tick % 20 // todo update automatically in worker + } + }, + fullReset () { + fullReset() + }, + exportData () { + const exported = exportData() + postMessage({ type: 'exportData', data: exported }, undefined as any, [exported.sides.buffer]) + }, + loadFixture (json) { + // allSides = json.map(([x, y, z, face, textureIndex]) => { + // return [x, y, z, { face, textureIndex }] as [number, number, number, BlockFaceType] + // }) + const dataSize = json.length / 5 + for (let i = 0; i < json.length; i += 5) { + allSides.push([json[i], json[i + 1], json[i + 2], { side: json[i + 3], textureIndex: json[i + 4] }]) + } + updateCubesWhenAvailable(0) + }, +}) + +globalThis.testDuplicates = () => { + const duplicates = allSides.filter((value, index, self) => self.indexOf(value) !== index) + console.log('duplicates', duplicates) +} + +const exportData = () => { + // Calculate the total length of the final array + const totalLength = allSides.length * 5 + + // Create a new Int16Array with the total length + const flatData = new Int16Array(totalLength) + + // Fill the flatData array + for (let i = 0; i < allSides.length; i++) { + const sideData = allSides[i] + if (!sideData) continue + const [x, y, z, side] = sideData + flatData.set([x, y, z, side.side, side.textureIndex], i * 5) + } + + return { sides: flatData } +} + +setInterval(() => { + if (autoTickUpdate) { + animationTick = (animationTick + 1) % autoTickUpdate + } +}, 1000 / 20) diff --git a/prismarine-viewer/examples/workerProxy.ts b/prismarine-viewer/examples/workerProxy.ts new file mode 100644 index 00000000..80a8cdb4 --- /dev/null +++ b/prismarine-viewer/examples/workerProxy.ts @@ -0,0 +1,58 @@ +export function createWorkerProxy void>> (handlers: T): { __workerProxy: T } { + addEventListener('message', (event) => { + const { type, args } = event.data + if (handlers[type]) { + handlers[type](...args) + } + }) + return null as any +} + +/** + * in main thread + * ```ts + * // either: + * import type { importedTypeWorkerProxy } from './worker' + * // or: + * type importedTypeWorkerProxy = import('./worker').importedTypeWorkerProxy + * + * const workerChannel = useWorkerProxy(worker) + * ``` + */ +export const useWorkerProxy = void> }> (worker: Worker, autoTransfer = true): T['__workerProxy'] & { + transfer: (...args: Transferable[]) => T['__workerProxy'] +} => { + // in main thread + return new Proxy({} as any, { + get: (target, prop) => { + if (prop === 'transfer') return (...transferable: Transferable[]) => { + return new Proxy({}, { + get: (target, prop) => { + return (...args: any[]) => { + worker.postMessage({ + type: prop, + args, + }, transferable) + } + } + }) + } + return (...args: any[]) => { + const transfer = autoTransfer ? args.filter(arg => arg instanceof ArrayBuffer || arg instanceof MessagePort || arg instanceof ImageBitmap || arg instanceof OffscreenCanvas || arg instanceof ImageData) : [] + worker.postMessage({ + type: prop, + args, + }, transfer) + } + } + }) +} + +// const workerProxy = createWorkerProxy({ +// startRender (canvas: HTMLCanvasElement) { +// }, +// }) + +// const worker = useWorkerProxy(null, workerProxy) + +// worker. diff --git a/prismarine-viewer/globals.d.ts b/prismarine-viewer/globals.d.ts new file mode 100644 index 00000000..c2cb5532 --- /dev/null +++ b/prismarine-viewer/globals.d.ts @@ -0,0 +1,9 @@ +type StringKeys = Extract + +interface ObjectConstructor { + keys (obj: T): Array> + entries (obj: T): Array<[StringKeys, T[keyof T]]> + // todo review https://stackoverflow.com/questions/57390305/trying-to-get-fromentries-type-right + fromEntries> (obj: T): Record + assign, K extends Record> (target: T, source: K): asserts target is T & K +} diff --git a/prismarine-viewer/package.json b/prismarine-viewer/package.json index d0ea3826..38245aa0 100644 --- a/prismarine-viewer/package.json +++ b/prismarine-viewer/package.json @@ -16,6 +16,7 @@ }, "dependencies": { "@tweenjs/tween.js": "^20.0.3", + "live-server": "^1.2.2", "assert": "^2.0.0", "buffer": "^6.0.3", "filesize": "^10.0.12", diff --git a/prismarine-viewer/playground.html b/prismarine-viewer/playground.html index fd92009a..20317781 100644 --- a/prismarine-viewer/playground.html +++ b/prismarine-viewer/playground.html @@ -7,6 +7,8 @@ html { overflow: hidden; background: black; + user-select: none; + touch-action: none; } html, body { @@ -31,6 +33,7 @@ +
diff --git a/prismarine-viewer/sharedBuildOptions.mjs b/prismarine-viewer/sharedBuildOptions.mjs new file mode 100644 index 00000000..52b2fb8f --- /dev/null +++ b/prismarine-viewer/sharedBuildOptions.mjs @@ -0,0 +1,3 @@ +export const sharedPlaygroundMainOptions = { + alias: {} +} \ No newline at end of file diff --git a/prismarine-viewer/viewer/lib/mesher/mesher.ts b/prismarine-viewer/viewer/lib/mesher/mesher.ts index b13b8ae0..fbefd1a9 100644 --- a/prismarine-viewer/viewer/lib/mesher/mesher.ts +++ b/prismarine-viewer/viewer/lib/mesher/mesher.ts @@ -84,7 +84,7 @@ const handleMessage = data => { } if (data.type === 'mesherData') { - setMesherData(data.blockstatesModels, data.blocksAtlas) + setMesherData(data.blockstatesModels, data.blocksAtlas, data.config.outputFormat === 'webgpu') allDataReady = true } else if (data.type === 'dirty') { const loc = new Vec3(data.x, data.y, data.z) @@ -128,7 +128,7 @@ setInterval(() => { const chunk = world.getColumn(x, z) if (chunk?.getSection(new Vec3(x, y, z))) { const geometry = getSectionGeometry(x, y, z, world) - const transferable = [geometry.positions.buffer, geometry.normals.buffer, geometry.colors.buffer, geometry.uvs.buffer] + const transferable = [geometry.positions?.buffer, geometry.normals?.buffer, geometry.colors?.buffer, geometry.uvs?.buffer].filter(Boolean) //@ts-ignore postMessage({ type: 'geometry', key, geometry }, transferable) } else { diff --git a/prismarine-viewer/viewer/lib/mesher/models.ts b/prismarine-viewer/viewer/lib/mesher/models.ts index 1e3aae77..afbb7e7a 100644 --- a/prismarine-viewer/viewer/lib/mesher/models.ts +++ b/prismarine-viewer/viewer/lib/mesher/models.ts @@ -6,6 +6,8 @@ import worldBlockProvider, { WorldBlockProvider } from 'mc-assets/dist/worldBloc import { BlockElement, buildRotationMatrix, elemFaces, matmul3, matmulmat3, vecadd3, vecsub3 } from './modelsGeometryCommon' let blockProvider: WorldBlockProvider +import { BlockType } from '../../../examples/shared' +import { MesherGeometryOutput } from './shared' const tints: any = {} let needTiles = false @@ -20,6 +22,19 @@ for (const key of Object.keys(tintsData)) { tints[key] = prepareTints(tintsData[key]) } +type TestTileData = { + block: string + faces: { + face: string + neighbor: string + light?: number + }[] +} + +type Tiles = { + [blockPos: string]: BlockType & TestTileData +} + function prepareTints (tints) { const map = new Map() const defaultValue = tintToGl(tints.default) @@ -104,18 +119,23 @@ function getLiquidRenderHeight (world, block, type, pos) { return ((block.metadata >= 8 ? 8 : 7 - block.metadata) + 1) / 9 } +const everyArray = (array, callback) => { + if (!array?.length) return false + return array.every(callback) +} -const isCube = (block: Block) => { +const isCube = (block) => { if (!block || block.transparent) return false if (block.isCube) return true - if (!block.models?.length || block.models.length !== 1) return false - // all variants - return block.models[0].every(v => v.elements!.every(e => { + // TODO! + // if (!block.variant) block.variant = getModelVariants(block) + if (!block.variant?.length) return false + return block.variant.every(v => everyArray(v?.model?.elements, e => { return e.from[0] === 0 && e.from[1] === 0 && e.from[2] === 0 && e.to[0] === 16 && e.to[1] === 16 && e.to[2] === 16 })) } -function renderLiquid (world: World, cursor: Vec3, texture: any | undefined, type: number, biome: string, water: boolean, attr: Record) { +function renderLiquid (world, cursor, texture, type, biome, water, attr) { const heights: number[] = [] for (let z = -1; z <= 1; z++) { for (let x = -1; x <= 1; x++) { @@ -134,12 +154,12 @@ function renderLiquid (world: World, cursor: Vec3, texture: any | undefined, typ const { dir, corners } = elemFaces[face] const isUp = dir[1] === 1 - const neighborPos = cursor.offset(...dir as [number, number, number]) + const neighborPos = cursor.offset(...dir) const neighbor = world.getBlock(neighborPos) if (!neighbor) continue if (neighbor.type === type) continue const isGlass = neighbor.name.includes('glass') - if ((isCube(neighbor) && !isUp) || neighbor.getProperties().waterlogged) continue + if ((isCube(neighbor) && !isUp) || neighbor.material === 'plant' || neighbor.getProperties().waterlogged) continue let tint = [1, 1, 1] if (water) { @@ -151,11 +171,12 @@ function renderLiquid (world: World, cursor: Vec3, texture: any | undefined, typ } if (needTiles) { - attr.tiles[`${cursor.x},${cursor.y},${cursor.z}`] ??= { + const tiles = attr.tiles as Tiles + tiles[`${cursor.x},${cursor.y},${cursor.z}`] ??= { block: 'water', faces: [], } - attr.tiles[`${cursor.x},${cursor.y},${cursor.z}`].faces.push({ + tiles[`${cursor.x},${cursor.y},${cursor.z}`].faces.push({ face, neighbor: `${neighborPos.x},${neighborPos.y},${neighborPos.z}`, // texture: eFace.texture.name, @@ -182,7 +203,7 @@ function renderLiquid (world: World, cursor: Vec3, texture: any | undefined, typ let needRecompute = false -function renderElement (world: World, cursor: Vec3, element: BlockElement, doAO: boolean, attr: Record, globalMatrix: any, globalShift: any, block: Block, biome: string) { +function renderElement (world: World, cursor: Vec3, element: BlockElement, doAO: boolean, attr: MesherGeometryOutput, globalMatrix: any, globalShift: any, block: Block, biome: string) { const position = cursor // const key = `${position.x},${position.y},${position.z}` // if (!globalThis.allowedBlocks.includes(key)) return @@ -190,7 +211,7 @@ function renderElement (world: World, cursor: Vec3, element: BlockElement, doAO: for (const face in element.faces) { const eFace = element.faces[face] - const { corners, mask1, mask2 } = elemFaces[face] + const { corners, mask1, mask2, side } = elemFaces[face] const dir = matmul3(globalMatrix, elemFaces[face].dir) if (eFace.cullface) { @@ -322,17 +343,24 @@ function renderElement (world: World, cursor: Vec3, element: BlockElement, doAO: attr.colors.push(baseLight * tint[0] * light, baseLight * tint[1] * light, baseLight * tint[2] * light) } + const lightWithColor = [baseLight * tint[0], baseLight * tint[1], baseLight * tint[2]] + if (needTiles) { - attr.tiles[`${cursor.x},${cursor.y},${cursor.z}`] ??= { + const tiles = attr.tiles as Tiles + tiles[`${cursor.x},${cursor.y},${cursor.z}`] ??= { block: block.name, faces: [], } - attr.tiles[`${cursor.x},${cursor.y},${cursor.z}`].faces.push({ + tiles[`${cursor.x},${cursor.y},${cursor.z}`].faces.push({ face, + side, + textureIndex: eFace.texture.tileIndex, neighbor: `${neighborPos.x},${neighborPos.y},${neighborPos.z}`, - light: baseLight - // texture: eFace.texture.name, - }) + light: baseLight, + // color: lightWithColor, + //@ts-ignore debug prop + texture: eFace.texture.debugName || block.name, + } satisfies BlockType['faces'][number] & TestTileData['faces'][number] as any) } if (doAO && aos[0] + aos[3] >= aos[1] + aos[2]) { @@ -357,7 +385,7 @@ let unknownBlockModel: BlockModelPartsResolved export function getSectionGeometry (sx, sy, sz, world: World) { let delayedRender = [] as (() => void)[] - const attr = { + const attr: MesherGeometryOutput = { sx: sx + 8, sy: sy + 8, sz: sz + 8, @@ -373,7 +401,7 @@ export function getSectionGeometry (sx, sy, sz, world: World) { tiles: {}, // todo this can be removed here signs: {} - } as Record + } const cursor = new Vec3(0, 0, 0) for (cursor.y = sy; cursor.y < sy + 16; cursor.y++) { @@ -492,7 +520,7 @@ export function getSectionGeometry (sx, sy, sz, world: World) { delayedRender = [] let ndx = attr.positions.length / 3 - for (let i = 0; i < attr.t_positions.length / 12; i++) { + for (let i = 0; i < attr.t_positions!.length / 12; i++) { attr.indices.push( ndx, ndx + 1, ndx + 2, ndx + 2, ndx + 1, ndx + 3, @@ -503,10 +531,10 @@ export function getSectionGeometry (sx, sy, sz, world: World) { ndx += 4 } - attr.positions.push(...attr.t_positions) - attr.normals.push(...attr.t_normals) - attr.colors.push(...attr.t_colors) - attr.uvs.push(...attr.t_uvs) + attr.positions.push(...attr.t_positions!) + attr.normals.push(...attr.t_normals!) + attr.colors.push(...attr.t_colors!) + attr.uvs.push(...attr.t_uvs!) delete attr.t_positions delete attr.t_normals @@ -518,6 +546,13 @@ export function getSectionGeometry (sx, sy, sz, world: World) { attr.colors = new Float32Array(attr.colors) as any attr.uvs = new Float32Array(attr.uvs) as any + if (needTiles) { + delete attr.positions + delete attr.normals + delete attr.colors + delete attr.uvs + } + return attr } diff --git a/prismarine-viewer/viewer/lib/mesher/modelsGeometryCommon.ts b/prismarine-viewer/viewer/lib/mesher/modelsGeometryCommon.ts index 1d83c818..fa8d029c 100644 --- a/prismarine-viewer/viewer/lib/mesher/modelsGeometryCommon.ts +++ b/prismarine-viewer/viewer/lib/mesher/modelsGeometryCommon.ts @@ -74,6 +74,7 @@ export function matmulmat3 (a, b) { export const elemFaces = { up: { + side: 0, dir: [0, 1, 0], mask1: [1, 1, 0], mask2: [0, 1, 1], @@ -85,6 +86,7 @@ export const elemFaces = { ] }, down: { + side: 1, dir: [0, -1, 0], mask1: [1, 1, 0], mask2: [0, 1, 1], @@ -96,6 +98,7 @@ export const elemFaces = { ] }, east: { + side: 2, dir: [1, 0, 0], mask1: [1, 1, 0], mask2: [1, 0, 1], @@ -107,6 +110,7 @@ export const elemFaces = { ] }, west: { + side: 3, dir: [-1, 0, 0], mask1: [1, 1, 0], mask2: [1, 0, 1], @@ -118,6 +122,7 @@ export const elemFaces = { ] }, north: { + side: 4, dir: [0, 0, -1], mask1: [1, 0, 1], mask2: [0, 1, 1], @@ -129,6 +134,7 @@ export const elemFaces = { ] }, south: { + side: 5, dir: [0, 0, 1], mask1: [1, 0, 1], mask2: [0, 1, 1], diff --git a/prismarine-viewer/viewer/lib/mesher/shared.ts b/prismarine-viewer/viewer/lib/mesher/shared.ts index 782a3141..a7a017de 100644 --- a/prismarine-viewer/viewer/lib/mesher/shared.ts +++ b/prismarine-viewer/viewer/lib/mesher/shared.ts @@ -1,11 +1,32 @@ +import { BlockType } from '../../../examples/shared' + export const defaultMesherConfig = { version: '', enableLighting: true, skyLight: 15, smoothLighting: true, - outputFormat: 'threeJs' as 'threeJs' | 'webgl', + outputFormat: 'threeJs' as 'threeJs' | 'webgpu', textureSize: 1024, // for testing debugModelVariant: undefined as undefined | number[] } export type MesherConfig = typeof defaultMesherConfig + +export type MesherGeometryOutput = { + sx: number, + sy: number, + sz: number, + // resulting: float32array + positions: any, + normals: any, + colors: any, + uvs: any, + t_positions?: number[], + t_normals?: number[], + t_colors?: number[], + t_uvs?: number[], + + indices: number[], + tiles: Record, + signs: Record, +} diff --git a/prismarine-viewer/viewer/lib/utils.web.js b/prismarine-viewer/viewer/lib/utils.web.js index ffa22808..4e34ac68 100644 --- a/prismarine-viewer/viewer/lib/utils.web.js +++ b/prismarine-viewer/viewer/lib/utils.web.js @@ -2,7 +2,7 @@ const THREE = require('three') const textureCache = {} -function loadTexture (texture, cb, onLoad) { +function loadTexture(texture, cb, onLoad) { const cached = textureCache[texture] if (!cached) { textureCache[texture] = new THREE.TextureLoader().load(texture, onLoad) @@ -11,7 +11,7 @@ function loadTexture (texture, cb, onLoad) { if (cached) onLoad?.() } -function loadJSON (url, callback) { +function loadJSON(url, callback) { const xhr = new XMLHttpRequest() xhr.open('GET', url, true) xhr.responseType = 'json' diff --git a/prismarine-viewer/viewer/lib/viewer.ts b/prismarine-viewer/viewer/lib/viewer.ts index f281c525..d709115f 100644 --- a/prismarine-viewer/viewer/lib/viewer.ts +++ b/prismarine-viewer/viewer/lib/viewer.ts @@ -1,11 +1,13 @@ import * as THREE from 'three' import { Vec3 } from 'vec3' +import { WorldRendererWebgpu } from './worldrendererWebgpu' import { Entities } from './entities' import { Primitives } from './primitives' import EventEmitter from 'events' -import { WorldRendererThree } from './worldrendererThree' import { generateSpiralMatrix } from 'flying-squid/dist/utils' -import { WorldRendererCommon, WorldRendererConfig, defaultWorldRendererConfig } from './worldrendererCommon' +import { defaultWorldRendererConfig } from './worldrendererCommon' +import { sendCameraToWorker } from '../../examples/webgpuRendererMain' +import { WorldRendererThree } from './worldrendererThree' import { versionToNumber } from '../prepare/utils' import worldBlockProvider from 'mc-assets/dist/worldBlockProvider' import { renderBlockThree } from './mesher/standaloneRenderer' @@ -14,33 +16,36 @@ export class Viewer { scene: THREE.Scene ambientLight: THREE.AmbientLight directionalLight: THREE.DirectionalLight - world: WorldRendererCommon + camera: THREE.PerspectiveCamera + world: WorldRendererWebgpu/* | WorldRendererThree */ entities: Entities // primitives: Primitives domElement: HTMLCanvasElement playerHeight = 1.62 isSneaking = false - threeJsWorld: WorldRendererThree + // threeJsWorld: WorldRendererThree cameraObjectOverride?: THREE.Object3D // for xr audioListener: THREE.AudioListener renderingUntilNoUpdates = false processEntityOverrides = (e, overrides) => overrides + webgpuWorld: WorldRendererWebgpu - get camera () { - return this.world.camera - } - set camera (camera) { - this.world.camera = camera - } + // get camera () { + // return this.world.camera + // } + // set camera (camera) { + // this.world.camera = camera + // } - constructor (public renderer: THREE.WebGLRenderer, worldConfig = defaultWorldRendererConfig) { + constructor(public renderer: THREE.WebGLRenderer, worldConfig = defaultWorldRendererConfig) { // https://discourse.threejs.org/t/updates-to-color-management-in-three-js-r152/50791 THREE.ColorManagement.enabled = false renderer.outputColorSpace = THREE.LinearSRGBColorSpace this.scene = new THREE.Scene() this.scene.matrixAutoUpdate = false // for perf - this.threeJsWorld = new WorldRendererThree(this.scene, this.renderer, worldConfig) + // this.threeJsWorld = new WorldRendererThree(this.scene, this.renderer, worldConfig) + this.webgpuWorld = new WorldRendererWebgpu(worldConfig) this.setWorld() this.resetScene() this.entities = new Entities(this.scene) @@ -50,7 +55,7 @@ export class Viewer { } setWorld () { - this.world = this.threeJsWorld + this.world = this.webgpuWorld } resetScene () { @@ -132,11 +137,14 @@ export class Viewer { setFirstPersonCamera (pos: Vec3 | null, yaw: number, pitch: number, roll = 0) { const cam = this.cameraObjectOverride || this.camera - let yOffset = this.playerHeight - if (this.isSneaking) yOffset -= 0.3 - - if (this.world instanceof WorldRendererThree) this.world.camera = cam as THREE.PerspectiveCamera - this.world.updateCamera(pos?.offset(0, yOffset, 0) ?? null, yaw, pitch) + if (pos) { + let y = pos.y + this.playerHeight + if (this.isSneaking) y -= 0.3 + // new tweenJs.Tween(cam.position).to({ x: pos.x, y, z: pos.z }, 50).start() + cam.position.set(pos.x, y, pos.z) + } + cam.rotation.set(pitch, yaw, roll, 'ZYX') + sendCameraToWorker() } playSound (position: Vec3, path: string, volume = 1, pitch = 1) { @@ -184,7 +192,7 @@ export class Viewer { }) // todo remove and use other architecture instead so data flow is clear emitter.on('blockEntities', (blockEntities) => { - if (this.world instanceof WorldRendererThree) this.world.blockEntities = blockEntities + if (this.world instanceof WorldRendererThree) (this.world as WorldRendererThree).blockEntities = blockEntities }) emitter.on('unloadChunk', ({ x, z }) => { @@ -199,6 +207,16 @@ export class Viewer { this.world.updateViewerPosition(pos) }) + emitter.on('renderDistance', (d) => { + this.world.viewDistance = d + this.world.chunksLength = d === 0 ? 1 : generateSpiralMatrix(d).length + }) + + emitter.on('renderDistance', (d) => { + this.world.viewDistance = d + this.world.chunksLength = d === 0 ? 1 : generateSpiralMatrix(d).length + }) + emitter.on('renderDistance', (d) => { this.world.viewDistance = d this.world.chunksLength = d === 0 ? 1 : generateSpiralMatrix(d).length @@ -206,7 +224,7 @@ export class Viewer { }) emitter.on('updateLight', ({ pos }) => { - if (this.world instanceof WorldRendererThree) this.world.updateLight(pos.x, pos.z) + if (this.world instanceof WorldRendererThree) (this.world as WorldRendererThree).updateLight(pos.x, pos.z) }) emitter.on('time', (timeOfDay) => { @@ -227,15 +245,24 @@ export class Viewer { if (this.world.mesherConfig.skyLight === skyLight) return this.world.mesherConfig.skyLight = skyLight - ; (this.world as WorldRendererThree).rerenderAllChunks?.() + if (this.world instanceof WorldRendererThree) { + (this.world as WorldRendererThree).rerenderAllChunks?.() + } }) emitter.emit('listening') } + loadChunksFixture () { } + render () { - this.world.render() - this.entities.render() + // if (this.composer) { + // this.renderPass.camera = this.camera + // this.composer.render() + // } else { + // this.renderer.render(this.scene, this.camera) + // } + // this.entities.render() } async waitForChunksToRender () { diff --git a/prismarine-viewer/viewer/lib/worldrendererCommon.ts b/prismarine-viewer/viewer/lib/worldrendererCommon.ts index b381a7a5..1a2a56d1 100644 --- a/prismarine-viewer/viewer/lib/worldrendererCommon.ts +++ b/prismarine-viewer/viewer/lib/worldrendererCommon.ts @@ -80,7 +80,7 @@ export abstract class WorldRendererCommon blocks?: CustomTexturesData } = {} - abstract outputFormat: 'threeJs' | 'webgl' + abstract outputFormat: 'threeJs' | 'webgpu' constructor (public config: WorldRendererConfig) { // this.initWorkers(1) // preload script on page load diff --git a/prismarine-viewer/viewer/lib/worldrendererThree.ts b/prismarine-viewer/viewer/lib/worldrendererThree.ts index cc89a823..6f8e1b3a 100644 --- a/prismarine-viewer/viewer/lib/worldrendererThree.ts +++ b/prismarine-viewer/viewer/lib/worldrendererThree.ts @@ -4,6 +4,10 @@ import nbt from 'prismarine-nbt' import PrismarineChatLoader from 'prismarine-chat' import { renderSign } from '../sign-renderer/' import { chunkPos, sectionPos } from './simpleUtils' + +function mod (x, n) { + return ((x % n) + n) % n +} import { WorldRendererCommon, WorldRendererConfig } from './worldrendererCommon' import * as tweenJs from '@tweenjs/tween.js' import { BloomPass, RenderPass, UnrealBloomPass, EffectComposer, WaterPass, GlitchPass } from 'three-stdlib' diff --git a/prismarine-viewer/viewer/lib/worldrendererWebgpu.ts b/prismarine-viewer/viewer/lib/worldrendererWebgpu.ts new file mode 100644 index 00000000..915dc7c9 --- /dev/null +++ b/prismarine-viewer/viewer/lib/worldrendererWebgpu.ts @@ -0,0 +1,103 @@ +import { Vec3 } from 'vec3' +import { updateStatText } from '../../examples/newStats' +import { addBlocksSection, removeBlocksSection, webgpuChannel } from '../../examples/webgpuRendererMain' +import type { WebglData } from '../prepare/webglData' +import { loadJSON } from './utils.web' +import { WorldRendererCommon } from './worldrendererCommon' +import { MesherGeometryOutput } from './mesher/shared' + +export class WorldRendererWebgpu extends WorldRendererCommon { + outputFormat = 'webgpu' as const + newChunks = {} as Record + // webglData: WebglData + stopBlockUpdate = false + lastChunkDistance = 0 + + constructor(config) { + super(config) + + this.renderUpdateEmitter.on('update', () => { + const loadedChunks = Object.keys(this.finishedChunks).length + updateStatText('loaded-chunks', `${loadedChunks}/${this.chunksLength} chunks (${this.lastChunkDistance})`) + }) + } + + playgroundGetWebglData () { + const playgroundChunk = Object.values(this.newChunks).filter((x: any) => Object.keys(x?.blocks ?? {}).length > 0)?.[0] as any + if (!playgroundChunk) return + const block = Object.values(playgroundChunk.blocks)?.[0] as any + if (!block) return + const { textureName } = block + if (!textureName) return + // return this.webglData[textureName] + } + + setBlockStateId (pos: any, stateId: any): void { + if (this.stopBlockUpdate) return + super.setBlockStateId(pos, stateId) + } + + isWaitingForChunksToRender = false + + allChunksLoaded (): void { + console.log('allChunksLoaded') + webgpuChannel.addBlocksSectionDone() + } + + handleWorkerMessage (data: { geometry: MesherGeometryOutput, type, key }): void { + if (data.type === 'geometry' && Object.keys(data.geometry.tiles).length) { + + const chunkCoords = data.key.split(',').map(Number) as [number, number, number] + if (/* !this.loadedChunks[chunkCoords[0] + ',' + chunkCoords[2]] || */ !this.active) return + + addBlocksSection(data.key, data.geometry) + this.lastChunkDistance = Math.max(...this.getDistance(new Vec3(chunkCoords[0], 0, chunkCoords[2]))) + + // todo + this.newChunks[data.key] = data.geometry + } + } + + updateCamera (pos: Vec3 | null, yaw: number, pitch: number): void { } + render (): void { } + + chunksReset () { + webgpuChannel.fullReset() + } + + updatePosDataChunk (key: string) { + } + + async updateTexturesData (): Promise { + await super.updateTexturesData() + } + + updateShowChunksBorder (value: boolean) { + // todo + } + + + removeColumn (x, z) { + console.log('removeColumn', x, z) + super.removeColumn(x, z) + for (const key of Object.keys(this.newChunks)) { + const [xSec, _ySec, zSec] = key.split(',').map(Number) + // if (Math.floor(x / 16) === x && Math.floor(z / 16) === z) { + if (x === xSec && z === zSec) { + // foundSections.push(key) + removeBlocksSection(key) + } + } + // for (let y = this.worldConfig.minY; y < this.worldConfig.worldHeight; y += 16) { + // this.setSectionDirty(new Vec3(x, y, z), false) + // const key = `${x},${y},${z}` + // const mesh = this.sectionObjects[key] + // if (mesh) { + // this.scene.remove(mesh) + // dispose3(mesh) + // } + // delete this.sectionObjects[key] + // } + } + +} diff --git a/prismarine-viewer/viewer/prepare/webglData.ts b/prismarine-viewer/viewer/prepare/webglData.ts new file mode 100644 index 00000000..937637e3 --- /dev/null +++ b/prismarine-viewer/viewer/prepare/webglData.ts @@ -0,0 +1,28 @@ +import { JsonAtlas } from './atlas'; +import { join } from 'path' +import fs from 'fs' + +export type WebglData = ReturnType + +export const prepareWebglData = (blockTexturesDir: string, atlas: JsonAtlas) => { + // todo + return Object.fromEntries(Object.entries(atlas.textures).map(([texture, { animatedFrames }]) => { + if (!animatedFrames) return null! + const mcMeta = JSON.parse(fs.readFileSync(join(blockTexturesDir, texture + '.png.mcmeta'), 'utf8')) as { + animation: { + interpolate: boolean, + frametime: number, + frames: ({ + index: number, + time: number + } | number)[] + } + } + return [texture, { + animation: { + ...mcMeta.animation, + framesCount: animatedFrames + } + }] as const + }).filter(Boolean)) +} diff --git a/rsbuild.config.ts b/rsbuild.config.ts index 28a16ec3..e17a194c 100644 --- a/rsbuild.config.ts +++ b/rsbuild.config.ts @@ -121,6 +121,12 @@ export default defineConfig({ } else { await execAsync('pnpm run build-mesher') } + if (fs.existsSync('./prismarine-viewer/public/webgpuRendererWorker.js')) { + // copy worker + fs.copyFileSync('./prismarine-viewer/public/webgpuRendererWorker.js', './dist/webgpuRendererWorker.js') + } else { + await execAsync('pnpm run build-other-workers') + } fs.writeFileSync('./dist/version.txt', buildingVersion, 'utf-8') console.timeEnd('total-prep') } @@ -166,6 +172,10 @@ export default defineConfig({ test: /\.obj$/, type: 'asset/source', }, + { + test: /\.wgsl$/, + type: 'asset/source', + }, { test: /\.mp3$/, type: 'asset/source', diff --git a/src/controls.ts b/src/controls.ts index 86a01151..bf8239ac 100644 --- a/src/controls.ts +++ b/src/controls.ts @@ -438,6 +438,10 @@ export const f3Keybinds = [ console.warn('forcefully removed chunk from scene') } } + + viewer.world.chunksReset() // todo + viewer.world.newChunks = {} + if (localServer) { //@ts-expect-error not sure why it is private... maybe revisit api? localServer.players[0].world.columns = {} diff --git a/src/globals.d.ts b/src/globals.d.ts index 98bf19ca..1e6f1baa 100644 --- a/src/globals.d.ts +++ b/src/globals.d.ts @@ -32,4 +32,17 @@ declare interface Document { exitPointerLock?(): void } +declare module '*.frag' { + const png: string + export default png +} +declare module '*.vert' { + const png: string + export default png +} +declare module '*.wgsl' { + const png: string + export default png +} + declare interface Window extends Record { } diff --git a/src/index.ts b/src/index.ts index 3f964a9f..abef5aa9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -99,6 +99,9 @@ import { signInMessageState } from './react/SignInMessageProvider' import { updateAuthenticatedAccountData, updateLoadedServerData } from './react/ServersListProvider' import { versionToNumber } from 'prismarine-viewer/viewer/prepare/utils' import packetsPatcher from './packetsPatcher' +import { initWebgpuRenderer } from 'prismarine-viewer/examples/webgpuRendererMain' +import { addNewStat } from 'prismarine-viewer/examples/newStats' +// import { ViewerBase } from 'prismarine-viewer/viewer/lib/viewerWrapper' import blockstatesModels from 'mc-assets/dist/blockStatesModels.json' import { mainMenuState } from './react/MainMenuRenderApp' import { ItemsRenderer } from 'mc-assets/dist/itemsRenderer' @@ -414,10 +417,15 @@ async function connect (connectOptions: ConnectOptions) { viewer.setVersion(version, options.useVersionsTextures === 'latest' ? version : options.useVersionsTextures) } + // serverOptions.version = '1.18.1' const downloadVersion = connectOptions.botVersion || (singleplayer ? serverOptions.version : undefined) if (downloadVersion) { await downloadMcData(downloadVersion) } + await initWebgpuRenderer(() => { + renderWrapper.postRender() + }) + addNewStat('loaded-chunks') if (singleplayer) { // SINGLEPLAYER EXPLAINER: diff --git a/src/react/PauseScreen.tsx b/src/react/PauseScreen.tsx index adb91ac3..704c827f 100644 --- a/src/react/PauseScreen.tsx +++ b/src/react/PauseScreen.tsx @@ -3,6 +3,7 @@ import { useEffect } from 'react' import { useSnapshot } from 'valtio' import { usedServerPathsV1 } from 'flying-squid/dist/lib/modules/world' import { openURL } from 'prismarine-viewer/viewer/lib/simpleUtils' +import { exportLoadedTiles } from 'prismarine-viewer/examples/webgpuRendererMain' import { activeModalStack, showModal, @@ -98,10 +99,16 @@ export default () => { if (fsStateSnap.inMemorySave || !singleplayer) { return showOptionsModal('World actions...', []) } - const action = await showOptionsModal('World actions...', ['Save to browser memory']) + const action = await showOptionsModal('World actions...', [ + ...!fsStateSnap.inMemorySave && singleplayer ? ['Save to browser memory'] : [], + 'Dump loaded chunks' + ]) if (action === 'Save to browser memory') { await saveToBrowserMemory() } + if (action === 'Dump loaded chunks') { + exportLoadedTiles() + } } if (!isModalActive) return null diff --git a/src/topRightStats.ts b/src/topRightStats.ts index 71303e81..78dcd9c8 100644 --- a/src/topRightStats.ts +++ b/src/topRightStats.ts @@ -39,7 +39,7 @@ if (hasRamPanel) { addStat(stats2.dom) } -const hideStats = localStorage.hideStats || isCypress() +const hideStats = localStorage.hideStats || isCypress() || true if (hideStats) { stats.dom.style.display = 'none' stats2.dom.style.display = 'none' diff --git a/src/worldSaveWorker.ts b/src/worldSaveWorker.ts new file mode 100644 index 00000000..b49c0200 --- /dev/null +++ b/src/worldSaveWorker.ts @@ -0,0 +1,2 @@ +import './workerWorkaround' +import './browserfs' diff --git a/tsconfig.json b/tsconfig.json index 8ecff3bd..683ab52b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,8 +15,8 @@ "forceConsistentCasingInFileNames": true, "useUnknownInCatchVariables": false, "skipLibCheck": true, - "experimentalDecorators": true, "strictBindCallApply": true, + "experimentalDecorators": true, // this the only options that allows smooth transition from js to ts (by not dropping types from js files) // however might need to consider includeing *only needed libraries* instead of using this "maxNodeModuleJsDepth": 1,