From b88ec0161b9aca30ecda21613c61867b87a1714a Mon Sep 17 00:00:00 2001 From: Sceat Date: Tue, 5 Mar 2024 00:42:11 +0200 Subject: [PATCH] refactor: enforce standard format & move config to root along with prettier & eslint --- .eslintignore | 2 + .eslintrc | 25 + .github/workflows/CI.yml | 16 +- .prettierrc | 5 + README.md | 2 - index.html | 4 +- package-lock.json | 2404 ++++++++++++++++- package.json | 25 +- src/lib/config/.eslintrc.json | 50 - src/lib/config/tsconfig.json | 52 - src/lib/exports.ts | 4 +- src/lib/index.ts | 3 +- src/lib/terrain/i-voxel-map.ts | 83 +- src/lib/terrain/patch/material.ts | 49 +- src/lib/terrain/patch/patch-factory/cube.ts | 279 +- .../patch/patch-factory/patch-factory-base.ts | 384 +-- .../split/patch-factory-split.ts | 326 ++- .../split/vertex-data-encoder.ts | 46 +- .../patch/patch-factory/uint-packing.ts | 97 +- src/lib/terrain/patch/patch.ts | 141 +- src/lib/terrain/terrain.ts | 333 +-- src/lib/three-usage.ts | 28 +- src/test/config/tsconfig.json | 14 +- src/test/config/webpack.config.js | 99 +- src/test/main.ts | 66 +- src/test/voxel-map.ts | 201 +- test/index.html | 20 +- tsconfig.json | 47 + 28 files changed, 3708 insertions(+), 1097 deletions(-) create mode 100644 .eslintignore create mode 100644 .eslintrc create mode 100644 .prettierrc delete mode 100644 src/lib/config/.eslintrc.json delete mode 100644 src/lib/config/tsconfig.json create mode 100644 tsconfig.json diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..be3f0c7 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,2 @@ +dist +test \ No newline at end of file diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..a9430a7 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,25 @@ +{ + "extends": ["standard", "prettier"], + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"], + "parserOptions": { + "requireConfigFile": false, + "sourceType": "module", + "ecmaVersion": 12 + }, + "rules": { + "camelcase": "off", + "no-var": "error", + "object-shorthand": "error", + "prefer-const": ["error", { "destructuring": "any" }], + "prefer-rest-params": "error", + "prefer-spread": "error", + "prefer-object-spread": "error", + "prefer-destructuring": "error", + "prefer-numeric-literals": "error", + "import/order": ["error", { "newlines-between": "always" }], + "no-throw-literal": 0, + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": ["error"] + } +} diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 5e349ec..9e987f1 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -2,10 +2,23 @@ name: CI on: push: + branches: + - master tags: - v* + pull_request: jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 21 + cache: 'npm' + - run: npm ci + - run: npm run lint publish-npm: runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/') @@ -14,10 +27,11 @@ jobs: - uses: actions/setup-node@v4 with: node-version: 21 + cache: 'npm' registry-url: https://registry.npmjs.org/ - run: npm ci - run: npm run lint - run: npm run build - run: npm publish env: - NODE_AUTH_TOKEN: ${{secrets.npm_token}} \ No newline at end of file + NODE_AUTH_TOKEN: ${{secrets.npm_token}} diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..759232e --- /dev/null +++ b/.prettierrc @@ -0,0 +1,5 @@ +{ + "semi": false, + "singleQuote": true, + "arrowParens": "avoid" +} diff --git a/README.md b/README.md index 936d491..0d0592f 100644 --- a/README.md +++ b/README.md @@ -14,5 +14,3 @@ ![](https://i.imgur.com/ozCF28L.png) TODO: documentation - - diff --git a/index.html b/index.html index 196a947..95a27a9 100644 --- a/index.html +++ b/index.html @@ -1,4 +1,4 @@ - + @@ -26,7 +26,7 @@ ]) // Define indices for the square using TRIANGLE_STRIP - const indices = new Uint16Array([0, 1, 2, 0, 2, 3]); + const indices = new Uint16Array([0, 1, 2, 0, 2, 3]) diff --git a/package-lock.json b/package-lock.json index a378a68..4f8c946 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "aresrpg-engine", + "name": "@aresrpg/aresrpg-engine", "version": "0.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "aresrpg-engine", + "name": "@aresrpg/aresrpg-engine", "version": "0.2.0", "dependencies": { "three": "^0.162.0" @@ -15,7 +15,13 @@ "@typescript-eslint/eslint-plugin": "^7.1.0", "@typescript-eslint/parser": "^7.1.0", "eslint": "^8.57.0", + "eslint-config-prettier": "9.1.0", + "eslint-config-standard": "17.1.0", + "eslint-plugin-import": "2.29.1", "http-server": "^14.1.1", + "husky": "^4.3.8", + "lint-staged": "13.2.3", + "prettier": "3.1.1", "shx": "^0.3.4", "simplex-noise": "^4.0.1", "ts-loader": "^9.5.1", @@ -33,6 +39,184 @@ "node": ">=0.10.0" } }, + "node_modules/@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", @@ -302,6 +486,12 @@ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, "node_modules/@types/node": { "version": "20.11.24", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.24.tgz", @@ -311,6 +501,12 @@ "undici-types": "~5.26.4" } }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "dev": true + }, "node_modules/@types/semver": { "version": "7.5.8", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", @@ -885,6 +1081,19 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -910,6 +1119,33 @@ "ajv": "^6.9.1" } }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -940,6 +1176,41 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", + "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", @@ -949,6 +1220,111 @@ "node": ">=8" } }, + "node_modules/array.prototype.filter": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array.prototype.filter/-/array.prototype.filter-1.0.3.tgz", + "integrity": "sha512-VizNcj/RGJiUyQBgzwxzE5oHdeuXY5hSbbmKMlphj1cy1Vl7Pn2asCGbSrru6hSQjmCzqTBPVWAF/whmEOVHbw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.4.tgz", + "integrity": "sha512-hzvSHUshSpCflDR1QMUBLHGHP1VIEBegT4pix9H/Z92Xw3ySoy6c2qh7lJWTJnRJ8JCZ9bJNCgTyYaJGcJu6xQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/async": { "version": "2.6.4", "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", @@ -958,6 +1334,21 @@ "lodash": "^4.17.14" } }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -1036,6 +1427,29 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/builtins": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", + "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", + "dev": true, + "peer": true, + "dependencies": { + "semver": "^7.0.0" + } + }, "node_modules/call-bind": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", @@ -1109,6 +1523,49 @@ "node": ">=6.0" } }, + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-truncate": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", + "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", + "dev": true, + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/clone-deep": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", @@ -1153,6 +1610,12 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "node_modules/compare-versions": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", + "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==", + "dev": true + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1168,6 +1631,22 @@ "node": ">= 0.4.0" } }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dev": true, + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -1214,6 +1693,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -1238,12 +1734,24 @@ "node": ">=6.0.0" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, "node_modules/electron-to-chromium": { "version": "1.4.687", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.687.tgz", "integrity": "sha512-Ic85cOuXSP6h7KM0AIJ2hpJ98Bo4hyTUjc4yjMbkvD+8yTxEhfK9+8exT2KKYsSjnCn2tGsKVSZwE7ZgTORQCw==", "dev": true }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, "node_modules/enhanced-resolve": { "version": "5.15.1", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.1.tgz", @@ -1269,6 +1777,76 @@ "node": ">=4" } }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.22.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.5.tgz", + "integrity": "sha512-oW69R+4q2wG+Hc3KZePPZxOiisRIqfKBVo/HLx94QcJeWGU/8sZhCvc829rd1kS366vlJbzBfXf9yWwf0+Ko7w==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.1", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.0", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.5", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", + "dev": true + }, "node_modules/es-define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", @@ -1296,6 +1874,46 @@ "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==", "dev": true }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/escalade": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", @@ -1372,6 +1990,203 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-compat-utils": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.1.2.tgz", + "integrity": "sha512-Jia4JDldWnFNIru1Ehx1H5s9/yxiRHY/TimCuUc0jNexew3cF1gI6CYZil1ociakfWO3rRqFjl1mskBblB3RYg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-config-standard": { + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz", + "integrity": "sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "eslint": "^8.0.1", + "eslint-plugin-import": "^2.25.2", + "eslint-plugin-n": "^15.0.0 || ^16.0.0 ", + "eslint-plugin-promise": "^6.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", + "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "dev": true, + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-es-x": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.5.0.tgz", + "integrity": "sha512-ODswlDSO0HJDzXU0XvgZ3lF3lS3XAZEossh15Q2UHjwrJggWeBoKqqEsLTZLXl+dh5eOAozG0zRcYtuE35oTuQ==", + "dev": true, + "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.1.2", + "@eslint-community/regexpp": "^4.6.0", + "eslint-compat-utils": "^0.1.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "eslint": ">=8" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-n": { + "version": "16.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz", + "integrity": "sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==", + "dev": true, + "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "builtins": "^5.0.1", + "eslint-plugin-es-x": "^7.5.0", + "get-tsconfig": "^4.7.0", + "globals": "^13.24.0", + "ignore": "^5.2.4", + "is-builtin-module": "^3.2.1", + "is-core-module": "^2.12.1", + "minimatch": "^3.1.2", + "resolve": "^1.22.2", + "semver": "^7.5.3" + }, + "engines": { + "node": ">=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-promise": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", + "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==", + "dev": true, + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, "node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -1598,6 +2413,29 @@ "node": ">=0.8.x" } }, + "node_modules/execa": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", + "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.1", + "human-signals": "^4.3.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^3.0.7", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": "^14.18.0 || ^16.14.0 || >=18.0.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -1705,6 +2543,21 @@ "node": ">=8" } }, + "node_modules/find-versions": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-4.0.0.tgz", + "integrity": "sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ==", + "dev": true, + "dependencies": { + "semver-regex": "^3.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", @@ -1754,6 +2607,15 @@ } } }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1769,6 +2631,33 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/get-intrinsic": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", @@ -1788,6 +2677,48 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", + "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", + "dev": true, + "peer": true, + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -1841,10 +2772,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "dependencies": { "array-union": "^2.1.0", @@ -1885,6 +2831,15 @@ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -1930,6 +2885,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/hasown": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", @@ -2004,6 +2974,118 @@ "node": ">=12" } }, + "node_modules/human-signals": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", + "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", + "dev": true, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/husky": { + "version": "4.3.8", + "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.8.tgz", + "integrity": "sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "chalk": "^4.0.0", + "ci-info": "^2.0.0", + "compare-versions": "^3.6.0", + "cosmiconfig": "^7.0.0", + "find-versions": "^4.0.0", + "opencollective-postinstall": "^2.0.2", + "pkg-dir": "^5.0.0", + "please-upgrade-node": "^3.2.0", + "slash": "^3.0.0", + "which-pm-runs": "^1.0.0" + }, + "bin": { + "husky-run": "bin/run.js", + "husky-upgrade": "lib/upgrader/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/husky" + } + }, + "node_modules/husky/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/husky/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/husky/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/husky/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/husky/node_modules/pkg-dir": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", + "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", + "dev": true, + "dependencies": { + "find-up": "^5.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -2078,6 +3160,15 @@ "node": ">=0.8.19" } }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -2094,6 +3185,20 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/interpret": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", @@ -2103,6 +3208,84 @@ "node": ">= 0.10" } }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "peer": true, + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-core-module": { "version": "2.13.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", @@ -2115,6 +3298,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -2124,6 +3322,18 @@ "node": ">=0.10.0" } }, + "node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -2136,6 +3346,18 @@ "node": ">=0.10.0" } }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -2145,6 +3367,21 @@ "node": ">=0.12.0" } }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", @@ -2166,6 +3403,112 @@ "node": ">=0.10.0" } }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -2210,6 +3553,12 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -2246,35 +3595,234 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, - "dependencies": { - "json-buffer": "3.0.1" + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/lint-staged": { + "version": "13.2.3", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-13.2.3.tgz", + "integrity": "sha512-zVVEXLuQIhr1Y7R7YAWx4TZLdvuzk7DnmrsTNL0fax6Z3jrpFcas+vKbzxhhvp6TA55m1SQuWkpzI1qbfDZbAg==", + "dev": true, + "dependencies": { + "chalk": "5.2.0", + "cli-truncate": "^3.1.0", + "commander": "^10.0.0", + "debug": "^4.3.4", + "execa": "^7.0.0", + "lilconfig": "2.1.0", + "listr2": "^5.0.7", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-inspect": "^1.12.3", + "pidtree": "^0.6.0", + "string-argv": "^0.3.1", + "yaml": "^2.2.2" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" + }, + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/lint-staged" + } + }, + "node_modules/lint-staged/node_modules/chalk": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz", + "integrity": "sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/lint-staged/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/lint-staged/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/lint-staged/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/lint-staged/node_modules/yaml": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.0.tgz", + "integrity": "sha512-j9iR8g+/t0lArF4V6NE/QCfT+CO7iLqrXAHZbJdo+LfjqP1vR8Fg5bSiaq6Q2lOD1AUEVrEVIgABvBFYojJVYQ==", + "dev": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/listr2": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-5.0.8.tgz", + "integrity": "sha512-mC73LitKHj9w6v30nLNGPetZIlfpUniNSsxxrbaPcWOjDb92SHPzJPi/t+v1YC/lxKz/AJ9egOjww0qUuFxBpA==", + "dev": true, + "dependencies": { + "cli-truncate": "^2.1.0", + "colorette": "^2.0.19", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.8.0", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "enquirer": ">= 2.3.0 < 3" + }, + "peerDependenciesMeta": { + "enquirer": { + "optional": true + } + } + }, + "node_modules/listr2/node_modules/cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/listr2/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" } }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "node_modules/listr2/node_modules/slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "node_modules/listr2/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">= 0.8.0" + "node": ">=8" } }, "node_modules/loader-runner": { @@ -2310,6 +3858,84 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -2389,6 +4015,18 @@ "node": ">= 0.6" } }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -2446,6 +4084,42 @@ "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", "dev": true }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", @@ -2455,6 +4129,80 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", + "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.2.tgz", + "integrity": "sha512-bzBq58S+x+uo0VjurFT0UktpKHOZmv4/xePiOA1nbB9pMqpGK7rUPNgf+1YC+7mE+0HzhTMqNUuCqvKhj6FnBw==", + "dev": true, + "dependencies": { + "array.prototype.filter": "^1.0.3", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.0.0" + } + }, + "node_modules/object.values": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", + "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -2464,6 +4212,30 @@ "wrappy": "1" } }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/opencollective-postinstall": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", + "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==", + "dev": true, + "bin": { + "opencollective-postinstall": "index.js" + } + }, "node_modules/opener": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", @@ -2517,6 +4289,21 @@ "node": ">=8" } }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -2538,6 +4325,24 @@ "node": ">=6" } }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -2598,6 +4403,18 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pidtree": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "dev": true, + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -2610,6 +4427,15 @@ "node": ">=8" } }, + "node_modules/please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "dev": true, + "dependencies": { + "semver-compare": "^1.0.0" + } + }, "node_modules/portfinder": { "version": "1.0.32", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", @@ -2624,6 +4450,15 @@ "node": ">= 0.12.0" } }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -2633,6 +4468,21 @@ "node": ">= 0.8.0" } }, + "node_modules/prettier": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.1.tgz", + "integrity": "sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -2698,6 +4548,24 @@ "node": ">= 0.10" } }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -2742,6 +4610,53 @@ "node": ">=8" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "peer": true, + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/restore-cursor/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/restore-cursor/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -2752,6 +4667,12 @@ "node": ">=0.10.0" } }, + "node_modules/rfdc": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz", + "integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==", + "dev": true + }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -2787,7 +4708,34 @@ } ], "dependencies": { - "queue-microtask": "^1.2.2" + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.0.tgz", + "integrity": "sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "get-intrinsic": "^1.2.2", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/safe-buffer": { @@ -2796,6 +4744,23 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -2841,6 +4806,24 @@ "node": ">=10" } }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "dev": true + }, + "node_modules/semver-regex": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.4.tgz", + "integrity": "sha512-6IiqeZNgq01qGf0TId0t3NvKzSvUsjcpdEO3AQNeIjR6A2+ckTnQlDpl4qu1bjRv0RzN3FP9hzFmws3lKqRWkA==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/serialize-javascript": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", @@ -2867,6 +4850,21 @@ "node": ">= 0.4" } }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/shallow-clone": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", @@ -2951,6 +4949,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, "node_modules/simplex-noise": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/simplex-noise/-/simplex-noise-4.0.1.tgz", @@ -2966,6 +4970,34 @@ "node": ">=8" } }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/source-map": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", @@ -2994,6 +5026,104 @@ "node": ">=0.10.0" } }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -3006,6 +5136,27 @@ "node": ">=8" } }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -3114,6 +5265,12 @@ "resolved": "https://registry.npmjs.org/three/-/three-0.162.0.tgz", "integrity": "sha512-xfCYj4RnlozReCmUd+XQzj6/5OjDNHBy5nT6rVwrOKGENAvpXe2z1jL+DZYaMu4/9pNsjH/4Os/VvS9IrH7IOQ==" }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -3158,6 +5315,24 @@ "webpack": "^5.0.0" } }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -3182,6 +5357,79 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz", + "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/typescript": { "version": "5.3.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", @@ -3195,6 +5443,21 @@ "node": ">=14.17" } }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -3443,12 +5706,102 @@ "node": ">= 8" } }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-pm-runs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz", + "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz", + "integrity": "sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.6", + "call-bind": "^1.0.5", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/wildcard": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", "dev": true }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -3461,6 +5814,15 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 52a972a..5804aa7 100644 --- a/package.json +++ b/package.json @@ -7,9 +7,10 @@ ], "scripts": { "publish": "npm run build && npm run lint", - "build": "tsc -p src/lib/config/tsconfig.json", + "build": "tsc -p tsconfig.json", "clean": "shx rm -rf dist test/**/*.js*", - "lint": "eslint src/lib -c src/lib/config/.eslintrc.json --ext .ts --fix", + "lint": "eslint . --ext .ts && prettier . --check", + "format": "prettier . --write && eslint . --fix --ext .ts", "test:http-server": "http-server ./test -p 8086 -c-1", "test:build": "webpack --config src/test/config/webpack.config.js" }, @@ -24,12 +25,32 @@ "@typescript-eslint/eslint-plugin": "^7.1.0", "@typescript-eslint/parser": "^7.1.0", "eslint": "^8.57.0", + "eslint-config-prettier": "9.1.0", + "eslint-config-standard": "17.1.0", + "eslint-plugin-import": "2.29.1", "http-server": "^14.1.1", "shx": "^0.3.4", "simplex-noise": "^4.0.1", "ts-loader": "^9.5.1", "typescript": "^5.3.3", + "husky": "^4.3.8", + "lint-staged": "13.2.3", + "prettier": "3.1.1", "webpack": "^5.90.3", "webpack-cli": "^5.1.4" + }, + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "*.js": [ + "prettier --write", + "eslint --fix" + ], + "*.json": "prettier --write", + "*.md": "prettier --write", + "*.yml": "prettier --write" } } diff --git a/src/lib/config/.eslintrc.json b/src/lib/config/.eslintrc.json deleted file mode 100644 index c6ac68d..0000000 --- a/src/lib/config/.eslintrc.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "root": true, - "parser": "@typescript-eslint/parser", - "ignorePatterns": [ - "*.d.ts", - "*.js" - ], - "plugins": [ - "@typescript-eslint" - ], - "env": { - "browser": true - }, - "parserOptions": { - "project": "./src/lib/config/tsconfig.json" - }, - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended" - ], - "rules": { - "@typescript-eslint/explicit-function-return-type": [ - "error", - { - "allowExpressions": true - } - ], - "@typescript-eslint/no-inferrable-types": [ - "error", - { - "ignoreParameters": true, - "ignoreProperties": true - } - ], - "@typescript-eslint/no-shadow": [ - "error" - ], - "@typescript-eslint/no-unused-vars": "off", // enforced by TS - "indent": [ - "warn", - 4, - { - "SwitchCase": 1 - } - ], - "semi": [ - "error" - ] - } -} \ No newline at end of file diff --git a/src/lib/config/tsconfig.json b/src/lib/config/tsconfig.json deleted file mode 100644 index 6606598..0000000 --- a/src/lib/config/tsconfig.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "files": [ - "../index.ts" - ], - "compilerOptions": { - /* Type Checking */ - "allowUnreachableCode": false, - "allowUnusedLabels": false, - "alwaysStrict": true, - "exactOptionalPropertyTypes": true, - "noFallthroughCasesInSwitch": true, - "noImplicitAny": true, - "noImplicitOverride": true, - "noImplicitReturns": true, - "noImplicitThis": true, - "noPropertyAccessFromIndexSignature": true, - "noUncheckedIndexedAccess": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "strict": true, - "strictBindCallApply": true, - "strictFunctionTypes": true, - "strictNullChecks": true, - "strictPropertyInitialization": true, - "useUnknownInCatchVariables": true, - - /* Modules */ - "module": "ES6", - "moduleResolution": "Bundler", - "typeRoots": [ - "../@types", - "../../node_modules/@types" - ], - - /* Emit */ - "declaration": true, - "declarationMap": false, - "outDir": "../../../dist", - "sourceMap": false, - - /* JavaScript Support */ - "allowJs": false, - - /* Interop Constraints */ - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "isolatedModules": true, - - /* Language and Environment */ - "target": "ES2018" - } -} diff --git a/src/lib/exports.ts b/src/lib/exports.ts index 2d88e1f..86ba9e4 100644 --- a/src/lib/exports.ts +++ b/src/lib/exports.ts @@ -1,2 +1,2 @@ -export { Terrain } from "./terrain/terrain"; -export type { IVoxelMap, IVoxel, IVoxelMaterial } from "./terrain/i-voxel-map"; +export { Terrain } from './terrain/terrain' +export type { IVoxelMap, IVoxel, IVoxelMaterial } from './terrain/i-voxel-map' diff --git a/src/lib/index.ts b/src/lib/index.ts index a8cdb07..4b3bb4f 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -1,2 +1 @@ -export * as AresRpgEngine from "./exports"; - +export * as AresRpgEngine from './exports' diff --git a/src/lib/terrain/i-voxel-map.ts b/src/lib/terrain/i-voxel-map.ts index 0b114fb..87c2dd8 100644 --- a/src/lib/terrain/i-voxel-map.ts +++ b/src/lib/terrain/i-voxel-map.ts @@ -1,28 +1,28 @@ type Uint3 = { - readonly x: number; - readonly y: number; - readonly z: number; -}; + readonly x: number + readonly y: number + readonly z: number +} /** * A color stored in RGB format. Each component should be normalized. */ type Color = { - readonly r: number; - readonly g: number; - readonly b: number; -}; + readonly r: number + readonly g: number + readonly b: number +} interface IVoxelMaterial { - readonly color: Color; + readonly color: Color } /** * A representation of a voxel. */ interface IVoxel { - readonly position: Uint3; - readonly materialId: number; + readonly position: Uint3 + readonly materialId: number } /** @@ -31,41 +31,38 @@ interface IVoxel { * The map starts at coordinates { x: 0, y: 0, z: 0 }. */ interface IVoxelMap { - /** - * Size of the map. Should be integers. - * - * Since the coordinates start at { x: 0, y: 0, z: 0 }, this means that - * the higher coordinates are { x: size.x - 1, y: size.y - 1, z: size.z - 1 }. - */ - readonly size: Uint3; + /** + * Size of the map. Should be integers. + * + * Since the coordinates start at { x: 0, y: 0, z: 0 }, this means that + * the higher coordinates are { x: size.x - 1, y: size.y - 1, z: size.z - 1 }. + */ + readonly size: Uint3 - /** - * @returns an array of all the possible voxel materials contained in the map. - * Each material is then identified by its index in the array. - */ - readonly voxelMaterialsList: ReadonlyArray; + /** + * @returns an array of all the possible voxel materials contained in the map. + * Each material is then identified by its index in the array. + */ + readonly voxelMaterialsList: ReadonlyArray - /** - * @param from Start of the subsection - * @param to End of the subsection (exclusive) - * @returns An upper bound of the count of voxels withing the given sub-section of the map. - */ - getMaxVoxelsCount(from: Uint3, to: Uint3): number; + /** + * @param from Start of the subsection + * @param to End of the subsection (exclusive) + * @returns An upper bound of the count of voxels withing the given sub-section of the map. + */ + getMaxVoxelsCount(from: Uint3, to: Uint3): number - /** - * Iterates on all for voxels within a given sub-section of the map. - * @param from Start of the subsection - * @param to End of the subsection (exclusive) - */ - iterateOnVoxels(from: Uint3, to: Uint3): Generator; + /** + * Iterates on all for voxels within a given sub-section of the map. + * @param from Start of the subsection + * @param to End of the subsection (exclusive) + */ + iterateOnVoxels(from: Uint3, to: Uint3): Generator - /** - * @returns whether or not a voxel exists at these coordinates. - */ - voxelExists(x: number, y: number, z: number): boolean; + /** + * @returns whether or not a voxel exists at these coordinates. + */ + voxelExists(x: number, y: number, z: number): boolean } -export type { - IVoxel, IVoxelMap, IVoxelMaterial -}; - +export type { IVoxel, IVoxelMap, IVoxelMaterial } diff --git a/src/lib/terrain/patch/material.ts b/src/lib/terrain/patch/material.ts index 6045e72..8905d4c 100644 --- a/src/lib/terrain/patch/material.ts +++ b/src/lib/terrain/patch/material.ts @@ -1,35 +1,36 @@ +import * as THREE from '../../three-usage' + enum EMaterial { - ROCK = 0, - GRASS = 1, + ROCK = 0, + GRASS = 1, } enum EDisplayMode { - TEXTURES, - NORMALS, - GREY, + TEXTURES, + NORMALS, + GREY, } type PatchMaterialUniforms = { - readonly uDisplayMode: { value: EDisplayMode }; - readonly uTexture: { value: THREE.Texture }; - readonly uNoiseTexture: { value: THREE.Texture }; - readonly uNoiseStrength: { value: number }; - readonly uAoStrength: { value: number }; - readonly uAoSpread: { value: number }; - readonly uSmoothEdgeRadius: { value: number }; - readonly uSmoothEdgeMethod: { value: number }; - readonly uAmbient: { value: number }; - readonly uDiffuse: { value: number }; -}; + readonly uDisplayMode: { value: EDisplayMode } + readonly uTexture: { value: THREE.Texture } + readonly uNoiseTexture: { value: THREE.Texture } + readonly uNoiseStrength: { value: number } + readonly uAoStrength: { value: number } + readonly uAoSpread: { value: number } + readonly uSmoothEdgeRadius: { value: number } + readonly uSmoothEdgeMethod: { value: number } + readonly uAmbient: { value: number } + readonly uDiffuse: { value: number } +} type PatchMaterial = THREE.Material & { - readonly uniforms: PatchMaterialUniforms; -}; + readonly uniforms: PatchMaterialUniforms +} export { - EDisplayMode, - EMaterial, - type PatchMaterial, - type PatchMaterialUniforms -}; - + EDisplayMode, + EMaterial, + type PatchMaterial, + type PatchMaterialUniforms, +} diff --git a/src/lib/terrain/patch/patch-factory/cube.ts b/src/lib/terrain/patch/patch-factory/cube.ts index b71e80d..67292d1 100644 --- a/src/lib/terrain/patch/patch-factory/cube.ts +++ b/src/lib/terrain/patch/patch-factory/cube.ts @@ -1,147 +1,166 @@ -import * as THREE from "../../../three-usage"; +import * as THREE from '../../../three-usage' const vertices = { - ppp: new THREE.Vector3(1, 1, 1), - mpp: new THREE.Vector3(0, 1, 1), - pmp: new THREE.Vector3(1, 0, 1), - mmp: new THREE.Vector3(0, 0, 1), - ppm: new THREE.Vector3(1, 1, 0), - mpm: new THREE.Vector3(0, 1, 0), - pmm: new THREE.Vector3(1, 0, 0), - mmm: new THREE.Vector3(0, 0, 0), -}; + ppp: new THREE.Vector3(1, 1, 1), + mpp: new THREE.Vector3(0, 1, 1), + pmp: new THREE.Vector3(1, 0, 1), + mmp: new THREE.Vector3(0, 0, 1), + ppm: new THREE.Vector3(1, 1, 0), + mpm: new THREE.Vector3(0, 1, 0), + pmm: new THREE.Vector3(1, 0, 0), + mmm: new THREE.Vector3(0, 0, 0), +} type FaceVertex = { - readonly vertex: THREE.Vector3; - readonly shadowingNeighbourVoxels: [THREE.Vector3, THREE.Vector3, THREE.Vector3]; - readonly edgeNeighbourVoxels: { - readonly x: [THREE.Vector3, THREE.Vector3]; - readonly y: [THREE.Vector3, THREE.Vector3]; - }; -}; + readonly vertex: THREE.Vector3 + readonly shadowingNeighbourVoxels: [ + THREE.Vector3, + THREE.Vector3, + THREE.Vector3, + ] + readonly edgeNeighbourVoxels: { + readonly x: [THREE.Vector3, THREE.Vector3] + readonly y: [THREE.Vector3, THREE.Vector3] + } +} -type FaceType = "up" | "down" | "left" | "right" | "front" | "back"; +type FaceType = 'up' | 'down' | 'left' | 'right' | 'front' | 'back' const normals: Record = { - up: new THREE.Vector3(0, +1, 0), - down: new THREE.Vector3(0, -1, 0), - left: new THREE.Vector3(-1, 0, 0), - right: new THREE.Vector3(+1, 0, 0), - front: new THREE.Vector3(0, 0, +1), - back: new THREE.Vector3(0, 0, -1), -}; + up: new THREE.Vector3(0, +1, 0), + down: new THREE.Vector3(0, -1, 0), + left: new THREE.Vector3(-1, 0, 0), + right: new THREE.Vector3(+1, 0, 0), + front: new THREE.Vector3(0, 0, +1), + back: new THREE.Vector3(0, 0, -1), +} type Face = { - readonly id: number; - readonly type: FaceType; - readonly vertices: [FaceVertex, FaceVertex, FaceVertex, FaceVertex]; - readonly normal: THREE.Vector3; - readonly uvUp: THREE.Vector3; - readonly uvRight: THREE.Vector3; -}; + readonly id: number + readonly type: FaceType + readonly vertices: [FaceVertex, FaceVertex, FaceVertex, FaceVertex] + readonly normal: THREE.Vector3 + readonly uvUp: THREE.Vector3 + readonly uvRight: THREE.Vector3 +} -const faceIndices: [number, number, number, number, number, number] = [0, 2, 1, 1, 2, 3]; +const faceIndices: [number, number, number, number, number, number] = [ + 0, 2, 1, 1, 2, 3, +] -let iF = 0; +let iF = 0 -function buildFace(type: FaceType, v00: THREE.Vector3, v01: THREE.Vector3, v10: THREE.Vector3, v11: THREE.Vector3): Face { - const normal = normals[type]; - const uvUp = new THREE.Vector3().subVectors(v01, v00); - const uvRight = new THREE.Vector3().subVectors(v10, v00); - const uvLeft = uvRight.clone().multiplyScalar(-1); - const uvDown = uvUp.clone().multiplyScalar(-1); +function buildFace( + type: FaceType, + v00: THREE.Vector3, + v01: THREE.Vector3, + v10: THREE.Vector3, + v11: THREE.Vector3, +): Face { + const normal = normals[type] + const uvUp = new THREE.Vector3().subVectors(v01, v00) + const uvRight = new THREE.Vector3().subVectors(v10, v00) + const uvLeft = uvRight.clone().multiplyScalar(-1) + const uvDown = uvUp.clone().multiplyScalar(-1) - return { - id: iF++, - type, - vertices: [ - { - vertex: v00, - shadowingNeighbourVoxels: [ - new THREE.Vector3().subVectors(normal, uvRight), - new THREE.Vector3().subVectors(normal, uvUp), - new THREE.Vector3().subVectors(normal, uvRight).sub(uvUp), - ], - edgeNeighbourVoxels: { - x: [ - uvLeft, - new THREE.Vector3().addVectors(uvLeft, normal), - ], - y: [ - uvDown, - new THREE.Vector3().addVectors(uvDown, normal), - ] - }, - }, - { - vertex: v01, - shadowingNeighbourVoxels: [ - new THREE.Vector3().subVectors(normal, uvRight), - new THREE.Vector3().addVectors(normal, uvUp), - new THREE.Vector3().subVectors(normal, uvRight).add(uvUp), - ], - edgeNeighbourVoxels: { - x: [ - uvLeft, - new THREE.Vector3().addVectors(uvLeft, normal), - ], - y: [ - uvUp, - new THREE.Vector3().addVectors(uvUp, normal), - ] - }, - }, - { - vertex: v10, - shadowingNeighbourVoxels: [ - new THREE.Vector3().addVectors(normal, uvRight), - new THREE.Vector3().subVectors(normal, uvUp), - new THREE.Vector3().addVectors(normal, uvRight).sub(uvUp), - ], - edgeNeighbourVoxels: { - x: [ - uvRight, - new THREE.Vector3().addVectors(uvRight, normal), - ], - y: [ - uvDown, - new THREE.Vector3().addVectors(uvDown, normal), - ] - }, - }, - { - vertex: v11, - shadowingNeighbourVoxels: [ - new THREE.Vector3().addVectors(normal, uvRight), - new THREE.Vector3().addVectors(normal, uvUp), - new THREE.Vector3().addVectors(normal, uvRight).add(uvUp), - ], - edgeNeighbourVoxels: { - x: [ - uvRight, - new THREE.Vector3().addVectors(uvRight, normal), - ], - y: [ - uvUp, - new THREE.Vector3().addVectors(uvUp, normal), - ] - }, - }, + return { + id: iF++, + type, + vertices: [ + { + vertex: v00, + shadowingNeighbourVoxels: [ + new THREE.Vector3().subVectors(normal, uvRight), + new THREE.Vector3().subVectors(normal, uvUp), + new THREE.Vector3().subVectors(normal, uvRight).sub(uvUp), + ], + edgeNeighbourVoxels: { + x: [uvLeft, new THREE.Vector3().addVectors(uvLeft, normal)], + y: [uvDown, new THREE.Vector3().addVectors(uvDown, normal)], + }, + }, + { + vertex: v01, + shadowingNeighbourVoxels: [ + new THREE.Vector3().subVectors(normal, uvRight), + new THREE.Vector3().addVectors(normal, uvUp), + new THREE.Vector3().subVectors(normal, uvRight).add(uvUp), ], - normal, - uvUp, - uvRight, - }; + edgeNeighbourVoxels: { + x: [uvLeft, new THREE.Vector3().addVectors(uvLeft, normal)], + y: [uvUp, new THREE.Vector3().addVectors(uvUp, normal)], + }, + }, + { + vertex: v10, + shadowingNeighbourVoxels: [ + new THREE.Vector3().addVectors(normal, uvRight), + new THREE.Vector3().subVectors(normal, uvUp), + new THREE.Vector3().addVectors(normal, uvRight).sub(uvUp), + ], + edgeNeighbourVoxels: { + x: [uvRight, new THREE.Vector3().addVectors(uvRight, normal)], + y: [uvDown, new THREE.Vector3().addVectors(uvDown, normal)], + }, + }, + { + vertex: v11, + shadowingNeighbourVoxels: [ + new THREE.Vector3().addVectors(normal, uvRight), + new THREE.Vector3().addVectors(normal, uvUp), + new THREE.Vector3().addVectors(normal, uvRight).add(uvUp), + ], + edgeNeighbourVoxels: { + x: [uvRight, new THREE.Vector3().addVectors(uvRight, normal)], + y: [uvUp, new THREE.Vector3().addVectors(uvUp, normal)], + }, + }, + ], + normal, + uvUp, + uvRight, + } } const faces: Record = { - up: buildFace("up", vertices.mpp, vertices.mpm, vertices.ppp, vertices.ppm), - down: buildFace("down", vertices.mmm, vertices.mmp, vertices.pmm, vertices.pmp), - left: buildFace("left", vertices.mmm, vertices.mpm, vertices.mmp, vertices.mpp), - right: buildFace("right", vertices.pmp, vertices.ppp, vertices.pmm, vertices.ppm), - front: buildFace("front", vertices.mmp, vertices.mpp, vertices.pmp, vertices.ppp), - back: buildFace("back", vertices.pmm, vertices.ppm, vertices.mmm, vertices.mpm), -}; -const facesById = Object.values(faces).sort((face1: Face, face2: Face) => face1.id - face2.id); - -export { faceIndices, faces, facesById, type FaceType, type FaceVertex }; + up: buildFace('up', vertices.mpp, vertices.mpm, vertices.ppp, vertices.ppm), + down: buildFace( + 'down', + vertices.mmm, + vertices.mmp, + vertices.pmm, + vertices.pmp, + ), + left: buildFace( + 'left', + vertices.mmm, + vertices.mpm, + vertices.mmp, + vertices.mpp, + ), + right: buildFace( + 'right', + vertices.pmp, + vertices.ppp, + vertices.pmm, + vertices.ppm, + ), + front: buildFace( + 'front', + vertices.mmp, + vertices.mpp, + vertices.pmp, + vertices.ppp, + ), + back: buildFace( + 'back', + vertices.pmm, + vertices.ppm, + vertices.mmm, + vertices.mpm, + ), +} +const facesById = Object.values(faces).sort( + (face1: Face, face2: Face) => face1.id - face2.id, +) +export { faceIndices, faces, facesById, type FaceType, type FaceVertex } diff --git a/src/lib/terrain/patch/patch-factory/patch-factory-base.ts b/src/lib/terrain/patch/patch-factory/patch-factory-base.ts index 6de2293..8b49394 100644 --- a/src/lib/terrain/patch/patch-factory/patch-factory-base.ts +++ b/src/lib/terrain/patch/patch-factory/patch-factory-base.ts @@ -1,189 +1,261 @@ -import * as THREE from "../../../three-usage"; -import type { IVoxelMap, IVoxelMaterial } from "../../i-voxel-map"; -import type { PatchMaterial, PatchMaterialUniforms } from "../material"; -import { Patch } from "../patch"; -import * as Cube from "./cube"; -import type { PackedUintFragment } from "./uint-packing"; +import * as THREE from '../../../three-usage' +import type { IVoxelMap, IVoxelMaterial } from '../../i-voxel-map' +import type { PatchMaterial, PatchMaterialUniforms } from '../material' +import { Patch } from '../patch' -type GeometryAndMaterial = { - readonly geometry: THREE.BufferGeometry; - readonly material: PatchMaterial; -}; +import * as Cube from './cube' +import type { PackedUintFragment } from './uint-packing' -type FaceData = { - readonly voxelWorldPosition: THREE.Vector3; - readonly voxelLocalPosition: THREE.Vector3; - readonly voxelMaterialId: number; - readonly faceType: Cube.FaceType; - readonly faceId: number; - readonly verticesData: [VertexData, VertexData, VertexData, VertexData]; -}; +type GeometryAndMaterial = { + readonly geometry: THREE.BufferGeometry + readonly material: PatchMaterial +} type VertexData = { - readonly localPosition: THREE.Vector3; - readonly ao: number; - readonly roundnessX: boolean; - readonly roundnessY: boolean; -}; + readonly localPosition: THREE.Vector3 + readonly ao: number + readonly roundnessX: boolean + readonly roundnessY: boolean +} + +type FaceData = { + readonly voxelWorldPosition: THREE.Vector3 + readonly voxelLocalPosition: THREE.Vector3 + readonly voxelMaterialId: number + readonly faceType: Cube.FaceType + readonly faceId: number + readonly verticesData: [VertexData, VertexData, VertexData, VertexData] +} abstract class PatchFactoryBase { - public static readonly maxSmoothEdgeRadius = 0.3; + public static readonly maxSmoothEdgeRadius = 0.3 - public abstract readonly maxPatchSize: THREE.Vector3; + public abstract readonly maxPatchSize: THREE.Vector3 - protected readonly map: IVoxelMap; + protected readonly map: IVoxelMap - private readonly texture: THREE.Texture; - private readonly noiseTexture: THREE.Texture; + private readonly texture: THREE.Texture + private readonly noiseTexture: THREE.Texture - protected readonly noiseResolution = 5; - protected readonly noiseTypes = 16; + protected readonly noiseResolution = 5 + protected readonly noiseTypes = 16 - protected readonly uniformsTemplate: PatchMaterialUniforms; + protected readonly uniformsTemplate: PatchMaterialUniforms - protected constructor(map: IVoxelMap, voxelTypeEncoder: PackedUintFragment) { - this.map = map; + protected constructor(map: IVoxelMap, voxelTypeEncoder: PackedUintFragment) { + this.map = map - this.texture = PatchFactoryBase.buildMaterialsTexture(map.voxelMaterialsList, voxelTypeEncoder); - this.noiseTexture = PatchFactoryBase.buildNoiseTexture(this.noiseResolution, this.noiseTypes); + this.texture = PatchFactoryBase.buildMaterialsTexture( + map.voxelMaterialsList, + voxelTypeEncoder, + ) + this.noiseTexture = PatchFactoryBase.buildNoiseTexture( + this.noiseResolution, + this.noiseTypes, + ) - this.uniformsTemplate = { - uDisplayMode: { value: 0 }, - uTexture: { value: this.texture }, - uNoiseTexture: { value: this.noiseTexture }, - uNoiseStrength: { value: 0 }, - uAoStrength: { value: 0 }, - uAoSpread: { value: 0 }, - uSmoothEdgeRadius: { value: 0 }, - uSmoothEdgeMethod: { value: 0 }, - uAmbient: { value: 0 }, - uDiffuse: { value: 0 }, - }; - this.uniformsTemplate.uTexture.value = this.texture; + this.uniformsTemplate = { + uDisplayMode: { value: 0 }, + uTexture: { value: this.texture }, + uNoiseTexture: { value: this.noiseTexture }, + uNoiseStrength: { value: 0 }, + uAoStrength: { value: 0 }, + uAoSpread: { value: 0 }, + uSmoothEdgeRadius: { value: 0 }, + uSmoothEdgeMethod: { value: 0 }, + uAmbient: { value: 0 }, + uDiffuse: { value: 0 }, } + this.uniformsTemplate.uTexture.value = this.texture + } - public buildPatch(patchStart: THREE.Vector3, patchEnd: THREE.Vector3): Patch | null { - const patchSize = new THREE.Vector3().subVectors(patchEnd, patchStart); - if (patchSize.x > this.maxPatchSize.x || patchSize.y > this.maxPatchSize.y || patchSize.z > this.maxPatchSize.z) { - throw new Error(`Patch is too big ${patchSize.x}x${patchSize.y}x${patchSize.z} (max is ${this.maxPatchSize.x}x${this.maxPatchSize.y}x${this.maxPatchSize.z})`); - } - - const patchData = this.computePatchData(patchStart, patchEnd); - if (patchData.length === 0) { - return null; - } - - const boundingBox = new THREE.Box3(patchStart, patchEnd); - const boundingSphere = new THREE.Sphere(); - boundingBox.getBoundingSphere(boundingSphere); - - return new Patch(patchStart, patchSize, patchData.map(geometryAndMaterial => { - const geometry = geometryAndMaterial.geometry; - geometry.boundingBox = boundingBox.clone(); - geometry.boundingSphere = boundingSphere.clone(); - - const material = geometryAndMaterial.material.clone(); - const mesh = new THREE.Mesh(geometryAndMaterial.geometry, material); - mesh.frustumCulled = false; - mesh.translateX(patchStart.x); - mesh.translateY(patchStart.y); - mesh.translateZ(patchStart.z); - return { mesh, material }; - })); + public buildPatch( + patchStart: THREE.Vector3, + patchEnd: THREE.Vector3, + ): Patch | null { + const patchSize = new THREE.Vector3().subVectors(patchEnd, patchStart) + if ( + patchSize.x > this.maxPatchSize.x || + patchSize.y > this.maxPatchSize.y || + patchSize.z > this.maxPatchSize.z + ) { + throw new Error( + `Patch is too big ${patchSize.x}x${patchSize.y}x${patchSize.z} (max is ${this.maxPatchSize.x}x${this.maxPatchSize.y}x${this.maxPatchSize.z})`, + ) } - public dispose(): void { - this.disposeInternal(); - this.texture.dispose(); - this.noiseTexture.dispose(); + const patchData = this.computePatchData(patchStart, patchEnd) + if (patchData.length === 0) { + return null } - protected *iterateOnVisibleFaces(patchStart: THREE.Vector3, patchEnd: THREE.Vector3): Generator { - for (const voxel of this.map.iterateOnVoxels(patchStart, patchEnd)) { - const voxelWorldPosition = new THREE.Vector3(voxel.position.x, voxel.position.y, voxel.position.z); - const voxelLocalPosition = new THREE.Vector3().subVectors(voxelWorldPosition, patchStart); + const boundingBox = new THREE.Box3(patchStart, patchEnd) + const boundingSphere = new THREE.Sphere() + boundingBox.getBoundingSphere(boundingSphere) - for (const face of Object.values(Cube.faces)) { - if (this.map.voxelExists(voxelWorldPosition.x + face.normal.x, voxelWorldPosition.y + face.normal.y, voxelWorldPosition.z + face.normal.z)) { - // this face will be hidden -> skip it - continue; - } + return new Patch( + patchStart, + patchSize, + patchData.map(geometryAndMaterial => { + const { geometry } = geometryAndMaterial + geometry.boundingBox = boundingBox.clone() + geometry.boundingSphere = boundingSphere.clone() - yield { - voxelWorldPosition, - voxelLocalPosition, - voxelMaterialId: voxel.materialId, - faceType: face.type, - faceId: face.id, - verticesData: face.vertices.map((faceVertex: Cube.FaceVertex): VertexData => { - let ao = 0; - const [a, b, c] = faceVertex.shadowingNeighbourVoxels.map(neighbourVoxel => this.map.voxelExists(voxelWorldPosition.x + neighbourVoxel.x, voxelWorldPosition.y + neighbourVoxel.y, voxelWorldPosition.z + neighbourVoxel.z)) as [boolean, boolean, boolean]; - if (a && b) { - ao = 3; - } else { - ao = +a + +b + +c; - } - - let roundnessX = true; - let roundnessY = true; - if (faceVertex.edgeNeighbourVoxels) { - for (const neighbourVoxel of faceVertex.edgeNeighbourVoxels.x) { - roundnessX &&= !this.map.voxelExists(voxelWorldPosition.x + neighbourVoxel.x, voxelWorldPosition.y + neighbourVoxel.y, voxelWorldPosition.z + neighbourVoxel.z); - } - for (const neighbourVoxel of faceVertex.edgeNeighbourVoxels.y) { - roundnessY &&= !this.map.voxelExists(voxelWorldPosition.x + neighbourVoxel.x, voxelWorldPosition.y + neighbourVoxel.y, voxelWorldPosition.z + neighbourVoxel.z); - } - } - return { localPosition: faceVertex.vertex, ao, roundnessX, roundnessY }; - }) as [VertexData, VertexData, VertexData, VertexData], - }; - } - } - } + const material = geometryAndMaterial.material.clone() + const mesh = new THREE.Mesh(geometryAndMaterial.geometry, material) + mesh.frustumCulled = false + mesh.translateX(patchStart.x) + mesh.translateY(patchStart.y) + mesh.translateZ(patchStart.z) + return { mesh, material } + }), + ) + } - protected abstract computePatchData(patchStart: THREE.Vector3, patchEnd: THREE.Vector3): GeometryAndMaterial[]; + public dispose(): void { + this.disposeInternal() + this.texture.dispose() + this.noiseTexture.dispose() + } - protected abstract disposeInternal(): void; + protected *iterateOnVisibleFaces( + patchStart: THREE.Vector3, + patchEnd: THREE.Vector3, + ): Generator { + for (const voxel of this.map.iterateOnVoxels(patchStart, patchEnd)) { + const voxelWorldPosition = new THREE.Vector3( + voxel.position.x, + voxel.position.y, + voxel.position.z, + ) + const voxelLocalPosition = new THREE.Vector3().subVectors( + voxelWorldPosition, + patchStart, + ) - private static buildMaterialsTexture(voxelMaterials: ReadonlyArray, voxelTypeEncoder: PackedUintFragment): THREE.Texture { - const voxelTypesCount = voxelMaterials.length; - const maxVoxelTypesSupported = voxelTypeEncoder.maxValue + 1; - if (voxelTypesCount > maxVoxelTypesSupported) { - throw new Error(`A map cannot have more than ${maxVoxelTypesSupported} voxel types (received ${voxelTypesCount}).`); + for (const face of Object.values(Cube.faces)) { + if ( + this.map.voxelExists( + voxelWorldPosition.x + face.normal.x, + voxelWorldPosition.y + face.normal.y, + voxelWorldPosition.z + face.normal.z, + ) + ) { + // this face will be hidden -> skip it + continue } - const textureWidth = voxelTypesCount; - const textureHeight = 1; - const textureData = new Uint8Array(4 * textureWidth * textureHeight); - - voxelMaterials.forEach((material: IVoxelMaterial, materialId: number) => { - textureData[4 * materialId + 0] = 255 * material.color.r; - textureData[4 * materialId + 1] = 255 * material.color.g; - textureData[4 * materialId + 2] = 255 * material.color.b; - textureData[4 * materialId + 3] = 255; - }); - const texture = new THREE.DataTexture(textureData, textureWidth, textureHeight); - texture.needsUpdate = true; - return texture; + yield { + voxelWorldPosition, + voxelLocalPosition, + voxelMaterialId: voxel.materialId, + faceType: face.type, + faceId: face.id, + verticesData: face.vertices.map( + (faceVertex: Cube.FaceVertex): VertexData => { + let ao = 0 + const [a, b, c] = faceVertex.shadowingNeighbourVoxels.map( + neighbourVoxel => + this.map.voxelExists( + voxelWorldPosition.x + neighbourVoxel.x, + voxelWorldPosition.y + neighbourVoxel.y, + voxelWorldPosition.z + neighbourVoxel.z, + ), + ) as [boolean, boolean, boolean] + if (a && b) { + ao = 3 + } else { + ao = +a + +b + +c + } + + let roundnessX = true + let roundnessY = true + if (faceVertex.edgeNeighbourVoxels) { + for (const neighbourVoxel of faceVertex.edgeNeighbourVoxels.x) { + roundnessX &&= !this.map.voxelExists( + voxelWorldPosition.x + neighbourVoxel.x, + voxelWorldPosition.y + neighbourVoxel.y, + voxelWorldPosition.z + neighbourVoxel.z, + ) + } + for (const neighbourVoxel of faceVertex.edgeNeighbourVoxels.y) { + roundnessY &&= !this.map.voxelExists( + voxelWorldPosition.x + neighbourVoxel.x, + voxelWorldPosition.y + neighbourVoxel.y, + voxelWorldPosition.z + neighbourVoxel.z, + ) + } + } + return { + localPosition: faceVertex.vertex, + ao, + roundnessX, + roundnessY, + } + }, + ) as [VertexData, VertexData, VertexData, VertexData], + } + } } + } - private static buildNoiseTexture(resolution: number, typesCount: number): THREE.Texture { - const textureWidth = resolution * typesCount; - const textureHeight = resolution; - const textureData = new Uint8Array(4 * textureWidth * textureHeight); + protected abstract computePatchData( + patchStart: THREE.Vector3, + patchEnd: THREE.Vector3, + ): GeometryAndMaterial[] - for (let i = 0; i < textureData.length; i++) { - textureData[i] = 256 * Math.random(); - } - const texture = new THREE.DataTexture(textureData, textureWidth, textureHeight); - texture.needsUpdate = true; - return texture; + protected abstract disposeInternal(): void + + private static buildMaterialsTexture( + voxelMaterials: ReadonlyArray, + voxelTypeEncoder: PackedUintFragment, + ): THREE.Texture { + const voxelTypesCount = voxelMaterials.length + const maxVoxelTypesSupported = voxelTypeEncoder.maxValue + 1 + if (voxelTypesCount > maxVoxelTypesSupported) { + throw new Error( + `A map cannot have more than ${maxVoxelTypesSupported} voxel types (received ${voxelTypesCount}).`, + ) } -} -export { - PatchFactoryBase, - type GeometryAndMaterial, - type VertexData -}; + const textureWidth = voxelTypesCount + const textureHeight = 1 + const textureData = new Uint8Array(4 * textureWidth * textureHeight) + + voxelMaterials.forEach((material: IVoxelMaterial, materialId: number) => { + textureData[4 * materialId + 0] = 255 * material.color.r + textureData[4 * materialId + 1] = 255 * material.color.g + textureData[4 * materialId + 2] = 255 * material.color.b + textureData[4 * materialId + 3] = 255 + }) + const texture = new THREE.DataTexture( + textureData, + textureWidth, + textureHeight, + ) + texture.needsUpdate = true + return texture + } + + private static buildNoiseTexture( + resolution: number, + typesCount: number, + ): THREE.Texture { + const textureWidth = resolution * typesCount + const textureHeight = resolution + const textureData = new Uint8Array(4 * textureWidth * textureHeight) + + for (let i = 0; i < textureData.length; i++) { + textureData[i] = 256 * Math.random() + } + const texture = new THREE.DataTexture( + textureData, + textureWidth, + textureHeight, + ) + texture.needsUpdate = true + return texture + } +} +export { PatchFactoryBase, type GeometryAndMaterial, type VertexData } diff --git a/src/lib/terrain/patch/patch-factory/split/patch-factory-split.ts b/src/lib/terrain/patch/patch-factory/split/patch-factory-split.ts index 0cd642a..025f185 100644 --- a/src/lib/terrain/patch/patch-factory/split/patch-factory-split.ts +++ b/src/lib/terrain/patch/patch-factory/split/patch-factory-split.ts @@ -1,35 +1,40 @@ -import * as THREE from "../../../../three-usage"; -import { IVoxelMap } from "../../../i-voxel-map"; -import { EDisplayMode, PatchMaterial } from "../../material"; -import * as Cube from "../cube"; -import { GeometryAndMaterial, PatchFactoryBase, VertexData } from "../patch-factory-base"; -import { VertexDataEncoder } from "./vertex-data-encoder"; +import * as THREE from '../../../../three-usage' +import { IVoxelMap } from '../../../i-voxel-map' +import { EDisplayMode, PatchMaterial } from '../../material' +import * as Cube from '../cube' +import { + GeometryAndMaterial, + PatchFactoryBase, + VertexData, +} from '../patch-factory-base' + +import { VertexDataEncoder } from './vertex-data-encoder' class PatchFactorySplit extends PatchFactoryBase { - private static readonly dataAttributeName = "aData"; - - private static readonly vertexDataEncoder = new VertexDataEncoder(); - - public readonly maxPatchSize = new THREE.Vector3( - PatchFactorySplit.vertexDataEncoder.voxelX.maxValue + 1, - PatchFactorySplit.vertexDataEncoder.voxelY.maxValue + 1, - PatchFactorySplit.vertexDataEncoder.voxelZ.maxValue + 1, - ); - - private readonly materialsTemplates: Record = { - up: this.buildPatchMaterial("up"), - down: this.buildPatchMaterial("down"), - left: this.buildPatchMaterial("left"), - right: this.buildPatchMaterial("right"), - front: this.buildPatchMaterial("front"), - back: this.buildPatchMaterial("back"), - }; - - private buildPatchMaterial(faceType: Cube.FaceType): PatchMaterial { - return new THREE.ShaderMaterial({ - glslVersion: "300 es", - uniforms: this.uniformsTemplate, - vertexShader: ` + private static readonly dataAttributeName = 'aData' + + private static readonly vertexDataEncoder = new VertexDataEncoder() + + public readonly maxPatchSize = new THREE.Vector3( + PatchFactorySplit.vertexDataEncoder.voxelX.maxValue + 1, + PatchFactorySplit.vertexDataEncoder.voxelY.maxValue + 1, + PatchFactorySplit.vertexDataEncoder.voxelZ.maxValue + 1, + ) + + private readonly materialsTemplates: Record = { + up: this.buildPatchMaterial('up'), + down: this.buildPatchMaterial('down'), + left: this.buildPatchMaterial('left'), + right: this.buildPatchMaterial('right'), + front: this.buildPatchMaterial('front'), + back: this.buildPatchMaterial('back'), + } + + private buildPatchMaterial(faceType: Cube.FaceType): PatchMaterial { + return new THREE.ShaderMaterial({ + glslVersion: '300 es', + uniforms: this.uniformsTemplate, + vertexShader: ` in uint ${PatchFactorySplit.dataAttributeName}; out vec2 vUv; @@ -39,17 +44,30 @@ class PatchFactorySplit extends PatchFactoryBase { out float vAo; void main(void) { - const uint vertexIds[] = uint[](${Cube.faceIndices.map(indice => `${indice}u`).join(", ")}); + const uint vertexIds[] = uint[](${Cube.faceIndices + .map(indice => `${indice}u`) + .join(', ')}); uint vertexId = vertexIds[gl_VertexID % 6]; uvec3 worldVoxelPosition = uvec3( - ${PatchFactorySplit.vertexDataEncoder.voxelX.glslDecode(PatchFactorySplit.dataAttributeName)}, - ${PatchFactorySplit.vertexDataEncoder.voxelY.glslDecode(PatchFactorySplit.dataAttributeName)}, - ${PatchFactorySplit.vertexDataEncoder.voxelZ.glslDecode(PatchFactorySplit.dataAttributeName)} + ${PatchFactorySplit.vertexDataEncoder.voxelX.glslDecode( + PatchFactorySplit.dataAttributeName, + )}, + ${PatchFactorySplit.vertexDataEncoder.voxelY.glslDecode( + PatchFactorySplit.dataAttributeName, + )}, + ${PatchFactorySplit.vertexDataEncoder.voxelZ.glslDecode( + PatchFactorySplit.dataAttributeName, + )} ); const uvec3 localVertexPositions[] = uvec3[]( - ${Cube.faces[faceType].vertices.map(vertex => `uvec3(${vertex.vertex.x}, ${vertex.vertex.y}, ${vertex.vertex.z})`).join(",\n")} + ${Cube.faces[faceType].vertices + .map( + vertex => + `uvec3(${vertex.vertex.x}, ${vertex.vertex.y}, ${vertex.vertex.z})`, + ) + .join(',\n')} ); uvec3 localVertexPosition = localVertexPositions[vertexId]; vec3 worldPosition = vec3(worldVoxelPosition + localVertexPosition); @@ -69,15 +87,23 @@ class PatchFactorySplit extends PatchFactoryBase { vec2(0,1), vec2(1,1) ); - uint edgeRoundnessId = ${PatchFactorySplit.vertexDataEncoder.edgeRoundness.glslDecode(PatchFactorySplit.dataAttributeName)}; + uint edgeRoundnessId = ${PatchFactorySplit.vertexDataEncoder.edgeRoundness.glslDecode( + PatchFactorySplit.dataAttributeName, + )}; vEdgeRoundness = edgeRoundness[edgeRoundnessId]; - vAo = float(${PatchFactorySplit.vertexDataEncoder.ao.glslDecode(PatchFactorySplit.dataAttributeName)}) / ${PatchFactorySplit.vertexDataEncoder.ao.maxValue.toFixed(1)}; + vAo = float(${PatchFactorySplit.vertexDataEncoder.ao.glslDecode( + PatchFactorySplit.dataAttributeName, + )}) / ${PatchFactorySplit.vertexDataEncoder.ao.maxValue.toFixed(1)}; - vMaterial = int(${PatchFactorySplit.vertexDataEncoder.voxelMaterialId.glslDecode(PatchFactorySplit.dataAttributeName)}); - vNoise = int(worldVoxelPosition.x + worldVoxelPosition.y * 3u + worldVoxelPosition.z * 2u) % ${this.noiseTypes}; + vMaterial = int(${PatchFactorySplit.vertexDataEncoder.voxelMaterialId.glslDecode( + PatchFactorySplit.dataAttributeName, + )}); + vNoise = int(worldVoxelPosition.x + worldVoxelPosition.y * 3u + worldVoxelPosition.z * 2u) % ${ + this.noiseTypes + }; }`, - fragmentShader: `precision mediump float; + fragmentShader: `precision mediump float; uniform sampler2D uTexture; uniform sampler2D uNoiseTexture; @@ -99,14 +125,20 @@ class PatchFactorySplit extends PatchFactoryBase { out vec4 fragColor; vec3 computeModelNormal() { - const vec3 worldFaceNormal = vec3(${Cube.faces[faceType].normal.x.toFixed(1)}, ${Cube.faces[faceType].normal.y.toFixed(1)}, ${Cube.faces[faceType].normal.z.toFixed(1)}); + const vec3 worldFaceNormal = vec3(${Cube.faces[ + faceType + ].normal.x.toFixed(1)}, ${Cube.faces[faceType].normal.y.toFixed( + 1, + )}, ${Cube.faces[faceType].normal.z.toFixed(1)}); if (uSmoothEdgeRadius <= 0.0) { return worldFaceNormal; } vec3 localNormal; - vec2 edgeRoundness = step(${PatchFactoryBase.maxSmoothEdgeRadius.toFixed(2)}, vEdgeRoundness); + vec2 edgeRoundness = step(${PatchFactoryBase.maxSmoothEdgeRadius.toFixed( + 2, + )}, vEdgeRoundness); if (uSmoothEdgeMethod == 0u) { vec2 margin = mix(vec2(0), vec2(uSmoothEdgeRadius), edgeRoundness); vec3 roundnessCenter = vec3(clamp(vUv, margin, 1.0 - margin), -uSmoothEdgeRadius); @@ -122,13 +154,23 @@ class PatchFactorySplit extends PatchFactoryBase { localNormal = normalize(vec3(distanceFromMargin, 1)); } - const vec3 uvUp = vec3(${Cube.faces[faceType].uvUp.x.toFixed(1)}, ${Cube.faces[faceType].uvUp.y.toFixed(1)}, ${Cube.faces[faceType].uvUp.z.toFixed(1)}); - const vec3 uvRight = vec3(${Cube.faces[faceType].uvRight.x.toFixed(1)}, ${Cube.faces[faceType].uvRight.y.toFixed(1)}, ${Cube.faces[faceType].uvRight.z.toFixed(1)}); + const vec3 uvUp = vec3(${Cube.faces[faceType].uvUp.x.toFixed( + 1, + )}, ${Cube.faces[faceType].uvUp.y.toFixed(1)}, ${Cube.faces[ + faceType + ].uvUp.z.toFixed(1)}); + const vec3 uvRight = vec3(${Cube.faces[faceType].uvRight.x.toFixed( + 1, + )}, ${Cube.faces[faceType].uvRight.y.toFixed(1)}, ${Cube.faces[ + faceType + ].uvRight.z.toFixed(1)}); return localNormal.x * uvRight + localNormal.y * uvUp + localNormal.z * worldFaceNormal; } float computeNoise() { - ivec2 texelCoords = clamp(ivec2(vUv * ${this.noiseResolution.toFixed(1)}), ivec2(0), ivec2(${this.noiseResolution - 1})); + ivec2 texelCoords = clamp(ivec2(vUv * ${this.noiseResolution.toFixed( + 1, + )}), ivec2(0), ivec2(${this.noiseResolution - 1})); texelCoords.x += vNoise * ${this.noiseResolution}; float noise = texelFetch(uNoiseTexture, texelCoords, 0).r - 0.5; return uNoiseStrength * noise; @@ -158,88 +200,134 @@ class PatchFactorySplit extends PatchFactoryBase { fragColor = vec4(color, 1); } `, - }) as unknown as PatchMaterial; - } + }) as unknown as PatchMaterial + } + + public constructor(map: IVoxelMap) { + super(map, PatchFactorySplit.vertexDataEncoder.voxelMaterialId) + } - public constructor(map: IVoxelMap) { - super(map, PatchFactorySplit.vertexDataEncoder.voxelMaterialId); + protected disposeInternal(): void { + for (const material of Object.values(this.materialsTemplates)) { + material.dispose() + } + } + + protected computePatchData( + patchStart: THREE.Vector3, + patchEnd: THREE.Vector3, + ): GeometryAndMaterial[] { + const voxelsCountPerPatch = this.map.getMaxVoxelsCount(patchStart, patchEnd) + if (voxelsCountPerPatch <= 0) { + return [] } - protected disposeInternal(): void { - for (const material of Object.values(this.materialsTemplates)) { - material.dispose(); - } + const verticesPerFace = 6 + const uint32PerVertex = 1 + + const verticesData: Record = { + up: new Uint32Array( + voxelsCountPerPatch * verticesPerFace * uint32PerVertex, + ), + down: new Uint32Array( + voxelsCountPerPatch * verticesPerFace * uint32PerVertex, + ), + left: new Uint32Array( + voxelsCountPerPatch * verticesPerFace * uint32PerVertex, + ), + right: new Uint32Array( + voxelsCountPerPatch * verticesPerFace * uint32PerVertex, + ), + front: new Uint32Array( + voxelsCountPerPatch * verticesPerFace * uint32PerVertex, + ), + back: new Uint32Array( + voxelsCountPerPatch * verticesPerFace * uint32PerVertex, + ), } - protected computePatchData(patchStart: THREE.Vector3, patchEnd: THREE.Vector3): GeometryAndMaterial[] { - const voxelsCountPerPatch = this.map.getMaxVoxelsCount(patchStart, patchEnd); - if (voxelsCountPerPatch <= 0) { - return []; - } + const iVertice: Record = { + up: 0, + down: 0, + left: 0, + right: 0, + front: 0, + back: 0, + } - const verticesPerFace = 6; - const uint32PerVertex = 1; - - const verticesData: Record = { - up: new Uint32Array(voxelsCountPerPatch * verticesPerFace * uint32PerVertex), - down: new Uint32Array(voxelsCountPerPatch * verticesPerFace * uint32PerVertex), - left: new Uint32Array(voxelsCountPerPatch * verticesPerFace * uint32PerVertex), - right: new Uint32Array(voxelsCountPerPatch * verticesPerFace * uint32PerVertex), - front: new Uint32Array(voxelsCountPerPatch * verticesPerFace * uint32PerVertex), - back: new Uint32Array(voxelsCountPerPatch * verticesPerFace * uint32PerVertex), - }; - - const iVertice: Record = { - up: 0, - down: 0, - left: 0, - right: 0, - front: 0, - back: 0, - }; - - const faceVerticesData = new Uint32Array(4 * uint32PerVertex); - for (const faceData of this.iterateOnVisibleFaces(patchStart, patchEnd)) { - faceData.verticesData.forEach((faceVertexData: VertexData, faceVertexIndex: number) => { - faceVerticesData[faceVertexIndex] = PatchFactorySplit.vertexDataEncoder.encode( - faceData.voxelLocalPosition.x, faceData.voxelLocalPosition.y, faceData.voxelLocalPosition.z, - faceData.voxelMaterialId, - faceVertexData.ao, - [faceVertexData.roundnessX, faceVertexData.roundnessY], - ); - }); - - for (const index of Cube.faceIndices) { - verticesData[faceData.faceType][iVertice[faceData.faceType]++] = faceVerticesData[index]!; - } - } + const faceVerticesData = new Uint32Array(4 * uint32PerVertex) + for (const faceData of this.iterateOnVisibleFaces(patchStart, patchEnd)) { + faceData.verticesData.forEach( + (faceVertexData: VertexData, faceVertexIndex: number) => { + faceVerticesData[faceVertexIndex] = + PatchFactorySplit.vertexDataEncoder.encode( + faceData.voxelLocalPosition.x, + faceData.voxelLocalPosition.y, + faceData.voxelLocalPosition.z, + faceData.voxelMaterialId, + faceVertexData.ao, + [faceVertexData.roundnessX, faceVertexData.roundnessY], + ) + }, + ) + + for (const index of Cube.faceIndices) { + verticesData[faceData.faceType][iVertice[faceData.faceType]++] = + faceVerticesData[index]! + } + } - const geometriesAndMaterials: Record = { - up: { geometry: new THREE.BufferGeometry(), material: this.materialsTemplates.up }, - down: { geometry: new THREE.BufferGeometry(), material: this.materialsTemplates.down }, - left: { geometry: new THREE.BufferGeometry(), material: this.materialsTemplates.left }, - right: { geometry: new THREE.BufferGeometry(), material: this.materialsTemplates.right }, - front: { geometry: new THREE.BufferGeometry(), material: this.materialsTemplates.front }, - back: { geometry: new THREE.BufferGeometry(), material: this.materialsTemplates.back }, - }; - - for (const [faceType, geometryAndMaterial] of Object.entries(geometriesAndMaterials) as [Cube.FaceType, GeometryAndMaterial][]) { - const faceTypeVerticesData = verticesData[faceType]; - const faceTypeIVertice = iVertice[faceType]; - const faceTypeVerticesDataBuffer = new THREE.Uint32BufferAttribute(faceTypeVerticesData.subarray(0, faceTypeIVertice), 1, false); - faceTypeVerticesDataBuffer.onUpload(() => { (faceTypeVerticesDataBuffer.array as THREE.TypedArray | null) = null; }); - - const geometry = geometryAndMaterial.geometry; - geometry.setAttribute(PatchFactorySplit.dataAttributeName, faceTypeVerticesDataBuffer); - geometry.setDrawRange(0, faceTypeIVertice); - } + const geometriesAndMaterials: Record = { + up: { + geometry: new THREE.BufferGeometry(), + material: this.materialsTemplates.up, + }, + down: { + geometry: new THREE.BufferGeometry(), + material: this.materialsTemplates.down, + }, + left: { + geometry: new THREE.BufferGeometry(), + material: this.materialsTemplates.left, + }, + right: { + geometry: new THREE.BufferGeometry(), + material: this.materialsTemplates.right, + }, + front: { + geometry: new THREE.BufferGeometry(), + material: this.materialsTemplates.front, + }, + back: { + geometry: new THREE.BufferGeometry(), + material: this.materialsTemplates.back, + }, + } - return Object.values(geometriesAndMaterials); + for (const [faceType, geometryAndMaterial] of Object.entries( + geometriesAndMaterials, + ) as [Cube.FaceType, GeometryAndMaterial][]) { + const faceTypeVerticesData = verticesData[faceType] + const faceTypeIVertice = iVertice[faceType] + const faceTypeVerticesDataBuffer = new THREE.Uint32BufferAttribute( + faceTypeVerticesData.subarray(0, faceTypeIVertice), + 1, + false, + ) + faceTypeVerticesDataBuffer.onUpload(() => { + ;(faceTypeVerticesDataBuffer.array as THREE.TypedArray | null) = null + }) + + const { geometry } = geometryAndMaterial + geometry.setAttribute( + PatchFactorySplit.dataAttributeName, + faceTypeVerticesDataBuffer, + ) + geometry.setDrawRange(0, faceTypeIVertice) } -} -export { - PatchFactorySplit, - type PatchMaterial -}; + return Object.values(geometriesAndMaterials) + } +} +export { PatchFactorySplit, type PatchMaterial } diff --git a/src/lib/terrain/patch/patch-factory/split/vertex-data-encoder.ts b/src/lib/terrain/patch/patch-factory/split/vertex-data-encoder.ts index 6902a8a..025e9b4 100644 --- a/src/lib/terrain/patch/patch-factory/split/vertex-data-encoder.ts +++ b/src/lib/terrain/patch/patch-factory/split/vertex-data-encoder.ts @@ -1,23 +1,33 @@ -import { PackedUintFactory } from "../uint-packing"; +import { PackedUintFactory } from '../uint-packing' class VertexDataEncoder { - private readonly packedUintFactory = new PackedUintFactory(32); - public readonly voxelX = this.packedUintFactory.encodePart(128); - public readonly voxelY = this.packedUintFactory.encodePart(64); - public readonly voxelZ = this.packedUintFactory.encodePart(128); - public readonly ao = this.packedUintFactory.encodePart(4); - public readonly edgeRoundness = this.packedUintFactory.encodePart(4); - public readonly voxelMaterialId = this.packedUintFactory.encodePart(1 << (32 - this.packedUintFactory.getNextAvailableBit())); + private readonly packedUintFactory = new PackedUintFactory(32) + public readonly voxelX = this.packedUintFactory.encodePart(128) + public readonly voxelY = this.packedUintFactory.encodePart(64) + public readonly voxelZ = this.packedUintFactory.encodePart(128) + public readonly ao = this.packedUintFactory.encodePart(4) + public readonly edgeRoundness = this.packedUintFactory.encodePart(4) + public readonly voxelMaterialId = this.packedUintFactory.encodePart( + 1 << (32 - this.packedUintFactory.getNextAvailableBit()), + ) - public encode(posX: number, posY: number, posZ: number, voxelMaterialId: number, ao: number, edgeRoundness: [boolean, boolean]): number { - return this.voxelX.encode(posX) + this.voxelY.encode(posY) + this.voxelZ.encode(posZ) - + this.voxelMaterialId.encode(voxelMaterialId) - + this.ao.encode(ao) - + this.edgeRoundness.encode(+edgeRoundness[0] + (+edgeRoundness[1] << 1)); - } + public encode( + posX: number, + posY: number, + posZ: number, + voxelMaterialId: number, + ao: number, + edgeRoundness: [boolean, boolean], + ): number { + return ( + this.voxelX.encode(posX) + + this.voxelY.encode(posY) + + this.voxelZ.encode(posZ) + + this.voxelMaterialId.encode(voxelMaterialId) + + this.ao.encode(ao) + + this.edgeRoundness.encode(+edgeRoundness[0] + (+edgeRoundness[1] << 1)) + ) + } } -export { - VertexDataEncoder -}; - +export { VertexDataEncoder } diff --git a/src/lib/terrain/patch/patch-factory/uint-packing.ts b/src/lib/terrain/patch/patch-factory/uint-packing.ts index 5bc7a78..c6528a4 100644 --- a/src/lib/terrain/patch/patch-factory/uint-packing.ts +++ b/src/lib/terrain/patch/patch-factory/uint-packing.ts @@ -1,60 +1,61 @@ type PackedUintFragment = { - readonly maxValue: number; - encode(value: number): number; - glslDecode(varname: string): string; - glslDecodeWithShift(varname: string, shiftAsString: string): string; -}; + readonly maxValue: number + encode(value: number): number + glslDecode(varname: string): string + glslDecodeWithShift(varname: string, shiftAsString: string): string +} class PackedUintFactory { - private readonly totalAllowedBits: number; - private nextAvailableBit: number = 0; - - public constructor(totalAllowedBits: number) { - this.totalAllowedBits = totalAllowedBits; + private readonly totalAllowedBits: number + private nextAvailableBit: number = 0 + + public constructor(totalAllowedBits: number) { + this.totalAllowedBits = totalAllowedBits + } + + public encodePart(nbValues: number): PackedUintFragment { + const shift = this.nextAvailableBit + const bitsCount = this.computeBitsNeeeded(nbValues) + this.nextAvailableBit += bitsCount + if (this.nextAvailableBit > this.totalAllowedBits) { + throw new Error('Does not fit') } + const maxValue = (1 << bitsCount) - 1 - public encodePart(nbValues: number): PackedUintFragment { - const shift = this.nextAvailableBit; - const bitsCount = this.computeBitsNeeeded(nbValues); - this.nextAvailableBit += bitsCount; - if (this.nextAvailableBit > this.totalAllowedBits) { - throw new Error("Does not fit"); + return { + maxValue, + encode: (value: number) => { + if (value < 0 || value > maxValue) { + throw new Error('Out of range') } - const maxValue = (1 << bitsCount) - 1; - - return { - maxValue, - encode: (value: number) => { - if (value < 0 || value > maxValue) { - throw new Error("Out of range"); - } - return value << shift; - }, - glslDecode: (varname: string) => { - return `((${varname} >> ${shift}u) & ${maxValue}u)`; - }, - glslDecodeWithShift: (varname: string, additionalShiftAsString: string) => { - return `((${varname} >> (${shift}u + ${additionalShiftAsString})) & ${maxValue}u)`; - }, - }; + return value << shift + }, + glslDecode: (varname: string) => { + return `((${varname} >> ${shift}u) & ${maxValue}u)` + }, + glslDecodeWithShift: ( + varname: string, + additionalShiftAsString: string, + ) => { + return `((${varname} >> (${shift}u + ${additionalShiftAsString})) & ${maxValue}u)` + }, } + } - public getNextAvailableBit(): number { - return this.nextAvailableBit; - } + public getNextAvailableBit(): number { + return this.nextAvailableBit + } - private computeBitsNeeeded(nbValues: number): number { - for (let i = 1; i < this.totalAllowedBits; i++) { - if (1 << i >= nbValues) { - return i; - } - } - throw new Error(`${this.totalAllowedBits} bits is not enough to store ${nbValues} values`); + private computeBitsNeeeded(nbValues: number): number { + for (let i = 1; i < this.totalAllowedBits; i++) { + if (1 << i >= nbValues) { + return i + } } + throw new Error( + `${this.totalAllowedBits} bits is not enough to store ${nbValues} values`, + ) + } } -export { - PackedUintFactory, - type PackedUintFragment -}; - +export { PackedUintFactory, type PackedUintFragment } diff --git a/src/lib/terrain/patch/patch.ts b/src/lib/terrain/patch/patch.ts index a17a2b5..df7323d 100644 --- a/src/lib/terrain/patch/patch.ts +++ b/src/lib/terrain/patch/patch.ts @@ -1,83 +1,92 @@ -import * as THREE from "../../three-usage"; -import { EDisplayMode, PatchMaterial } from "./material"; +import * as THREE from '../../three-usage' + +import { EDisplayMode, PatchMaterial } from './material' type PatchMesh = { - readonly mesh: THREE.Mesh; - readonly material: PatchMaterial; -}; + readonly mesh: THREE.Mesh + readonly material: PatchMaterial +} class Patch { - public readonly container: THREE.Object3D; + public readonly container: THREE.Object3D - public readonly parameters = { - voxels: { - displayMode: EDisplayMode.TEXTURES, - noiseStrength: 0.05, - }, - lighting: { - ambient: 0.7, - diffuse: 0.8, - }, - smoothEdges: { - enabled: true, - radius: 0.1, - quality: 2, - }, - ao: { - enabled: true, - strength: 0.4, - spread: 0.85, - }, - }; + public readonly parameters = { + voxels: { + displayMode: EDisplayMode.TEXTURES, + noiseStrength: 0.05, + }, + lighting: { + ambient: 0.7, + diffuse: 0.8, + }, + smoothEdges: { + enabled: true, + radius: 0.1, + quality: 2, + }, + ao: { + enabled: true, + strength: 0.4, + spread: 0.85, + }, + } - public readonly patchStart: THREE.Vector3; - public readonly patchSize: THREE.Vector3; + public readonly patchStart: THREE.Vector3 + public readonly patchSize: THREE.Vector3 - private gpuResources: { - readonly patchMeshes: ReadonlyArray; - } | null = null; + private gpuResources: { + readonly patchMeshes: ReadonlyArray + } | null = null - public constructor(patchStart: THREE.Vector3, patchSize: THREE.Vector3, patchMeshes: PatchMesh[]) { - this.patchStart = patchStart; - this.patchSize = patchSize; - this.gpuResources = { patchMeshes }; + public constructor( + patchStart: THREE.Vector3, + patchSize: THREE.Vector3, + patchMeshes: PatchMesh[], + ) { + this.patchStart = patchStart + this.patchSize = patchSize + this.gpuResources = { patchMeshes } - this.container = new THREE.Object3D(); - for (const patchMesh of patchMeshes) { - this.container.add(patchMesh.mesh); - } + this.container = new THREE.Object3D() + for (const patchMesh of patchMeshes) { + this.container.add(patchMesh.mesh) } + } - public updateUniforms(): void { - if (this.gpuResources) { - for (const patchMesh of this.gpuResources.patchMeshes) { - patchMesh.material.uniforms.uAoStrength.value = +this.parameters.ao.enabled * this.parameters.ao.strength; - patchMesh.material.uniforms.uAoSpread.value = this.parameters.ao.spread; - patchMesh.material.uniforms.uSmoothEdgeRadius.value = +this.parameters.smoothEdges.enabled * this.parameters.smoothEdges.radius; - patchMesh.material.uniforms.uSmoothEdgeMethod.value = this.parameters.smoothEdges.quality; - patchMesh.material.uniforms.uDisplayMode.value = this.parameters.voxels.displayMode; - patchMesh.material.uniforms.uAmbient.value = this.parameters.lighting.ambient; - patchMesh.material.uniforms.uDiffuse.value = this.parameters.lighting.diffuse; - patchMesh.material.uniforms.uNoiseStrength.value = this.parameters.voxels.noiseStrength; - } - } + public updateUniforms(): void { + if (this.gpuResources) { + for (const patchMesh of this.gpuResources.patchMeshes) { + patchMesh.material.uniforms.uAoStrength.value = + +this.parameters.ao.enabled * this.parameters.ao.strength + patchMesh.material.uniforms.uAoSpread.value = this.parameters.ao.spread + patchMesh.material.uniforms.uSmoothEdgeRadius.value = + +this.parameters.smoothEdges.enabled * + this.parameters.smoothEdges.radius + patchMesh.material.uniforms.uSmoothEdgeMethod.value = + this.parameters.smoothEdges.quality + patchMesh.material.uniforms.uDisplayMode.value = + this.parameters.voxels.displayMode + patchMesh.material.uniforms.uAmbient.value = + this.parameters.lighting.ambient + patchMesh.material.uniforms.uDiffuse.value = + this.parameters.lighting.diffuse + patchMesh.material.uniforms.uNoiseStrength.value = + this.parameters.voxels.noiseStrength + } } + } - public dispose(): void { - if (this.gpuResources) { - for (const patchMesh of this.gpuResources.patchMeshes) { - this.container.remove(patchMesh.mesh); - patchMesh.mesh.geometry.dispose(); - patchMesh.material.dispose(); - } + public dispose(): void { + if (this.gpuResources) { + for (const patchMesh of this.gpuResources.patchMeshes) { + this.container.remove(patchMesh.mesh) + patchMesh.mesh.geometry.dispose() + patchMesh.material.dispose() + } - this.gpuResources = null; - } + this.gpuResources = null } + } } -export { - EDisplayMode, - Patch -}; - +export { EDisplayMode, Patch } diff --git a/src/lib/terrain/terrain.ts b/src/lib/terrain/terrain.ts index 89a79e9..28c9137 100644 --- a/src/lib/terrain/terrain.ts +++ b/src/lib/terrain/terrain.ts @@ -1,170 +1,195 @@ -import * as THREE from "../three-usage"; -import { IVoxelMap } from "./i-voxel-map"; -import { EDisplayMode, Patch } from "./patch/patch"; -import { PatchFactoryBase } from "./patch/patch-factory/patch-factory-base"; -import { PatchFactorySplit } from "./patch/patch-factory/split/patch-factory-split"; +import * as THREE from '../three-usage' + +import { IVoxelMap } from './i-voxel-map' +import { EDisplayMode, Patch } from './patch/patch' +import { PatchFactoryBase } from './patch/patch-factory/patch-factory-base' +import { PatchFactorySplit } from './patch/patch-factory/split/patch-factory-split' /** * Class that takes an IVoxelMap and makes a renderable three.js object of it. */ class Terrain { - /** - * The three.js object containing the renderable map. - */ - public readonly container: THREE.Object3D; - - public readonly parameters = { - voxels: { - displayMode: EDisplayMode.TEXTURES, - noiseStrength: 0.025, - }, - lighting: { - ambient: 0.7, - diffuse: 0.8, - }, - smoothEdges: { - enabled: true, - radius: 0.1, - quality: 2, - }, - ao: { - enabled: true, - strength: 0.4, - spread: 0.85, - }, - }; - - private readonly map: IVoxelMap; - private readonly patchFactory: PatchFactoryBase; - private readonly patchSize: THREE.Vector3; - - private readonly patches: Record = {}; - - /** - * - * @param map The map that will be rendered. - */ - public constructor(map: IVoxelMap) { - this.map = map; - this.patchFactory = new PatchFactorySplit(map); - - this.patchSize = this.patchFactory.maxPatchSize.clone(); - console.log(`Using max patch size ${this.patchSize.x}x${this.patchSize.y}x${this.patchSize.z}.`); - - this.container = new THREE.Group(); - } - - /** - * Makes the whole make visible. - */ - public showEntireMap(): void { - const patchStart = new THREE.Vector3(); - for (patchStart.x = 0; patchStart.x < this.map.size.x; patchStart.x += this.patchSize.x) { - for (patchStart.y = 0; patchStart.y < this.map.size.y; patchStart.y += this.patchSize.y) { - for (patchStart.z = 0; patchStart.z < this.map.size.z; patchStart.z += this.patchSize.z) { - const patch = this.getPatch(patchStart); - if (patch) { - patch.container.visible = true; - } - } - } + /** + * The three.js object containing the renderable map. + */ + public readonly container: THREE.Object3D + + public readonly parameters = { + voxels: { + displayMode: EDisplayMode.TEXTURES, + noiseStrength: 0.025, + }, + lighting: { + ambient: 0.7, + diffuse: 0.8, + }, + smoothEdges: { + enabled: true, + radius: 0.1, + quality: 2, + }, + ao: { + enabled: true, + strength: 0.4, + spread: 0.85, + }, + } + + private readonly map: IVoxelMap + private readonly patchFactory: PatchFactoryBase + private readonly patchSize: THREE.Vector3 + + private readonly patches: Record = {} + + /** + * + * @param map The map that will be rendered. + */ + public constructor(map: IVoxelMap) { + this.map = map + this.patchFactory = new PatchFactorySplit(map) + + this.patchSize = this.patchFactory.maxPatchSize.clone() + console.log( + `Using max patch size ${this.patchSize.x}x${this.patchSize.y}x${this.patchSize.z}.`, + ) + + this.container = new THREE.Group() + } + + /** + * Makes the whole make visible. + */ + public showEntireMap(): void { + const patchStart = new THREE.Vector3() + for ( + patchStart.x = 0; + patchStart.x < this.map.size.x; + patchStart.x += this.patchSize.x + ) { + for ( + patchStart.y = 0; + patchStart.y < this.map.size.y; + patchStart.y += this.patchSize.y + ) { + for ( + patchStart.z = 0; + patchStart.z < this.map.size.z; + patchStart.z += this.patchSize.z + ) { + const patch = this.getPatch(patchStart) + if (patch) { + patch.container.visible = true + } } + } } - - /** - * Only makes visible the portion of the map that is around a given position. - * @param position The position around which the map will be made visible. - * @param radius The visibility radius, in voxels. - */ - public showMapAroundPosition(position: THREE.Vector3, radius: number): void { - const voxelFrom = new THREE.Vector3().copy(position).subScalar(radius); - const voxelTo = new THREE.Vector3().copy(position).addScalar(radius); - const patchIdFrom = voxelFrom.divide(this.patchSize).floor(); - const patchIdTo = voxelTo.divide(this.patchSize).ceil(); - - for (const patch of Object.values(this.patches)) { - if (patch) { - patch.container.visible = false; - } - } - - const patchId = new THREE.Vector3(); - for (patchId.x = patchIdFrom.x; patchId.x < patchIdTo.x; patchId.x++) { - for (patchId.y = patchIdFrom.y; patchId.y < patchIdTo.y; patchId.y++) { - for (patchId.z = patchIdFrom.z; patchId.z < patchIdTo.z; patchId.z++) { - const patchStart = new THREE.Vector3().multiplyVectors(patchId, this.patchSize); - const patch = this.getPatch(patchStart); - if (patch) { - patch.container.visible = true; - } - } - } - } + } + + /** + * Only makes visible the portion of the map that is around a given position. + * @param position The position around which the map will be made visible. + * @param radius The visibility radius, in voxels. + */ + public showMapAroundPosition(position: THREE.Vector3, radius: number): void { + const voxelFrom = new THREE.Vector3().copy(position).subScalar(radius) + const voxelTo = new THREE.Vector3().copy(position).addScalar(radius) + const patchIdFrom = voxelFrom.divide(this.patchSize).floor() + const patchIdTo = voxelTo.divide(this.patchSize).ceil() + + for (const patch of Object.values(this.patches)) { + if (patch) { + patch.container.visible = false + } } - /** Call this method before rendering. */ - public updateUniforms(): void { - for (const patch of Object.values(this.patches)) { - if (patch) { - patch.parameters.voxels.displayMode = this.parameters.voxels.displayMode; - patch.parameters.voxels.noiseStrength = this.parameters.voxels.noiseStrength; - - patch.parameters.lighting.ambient = this.parameters.lighting.ambient; - patch.parameters.lighting.diffuse = this.parameters.lighting.diffuse; - - patch.parameters.smoothEdges.enabled = this.parameters.smoothEdges.enabled; - patch.parameters.smoothEdges.radius = this.parameters.smoothEdges.radius; - patch.parameters.smoothEdges.quality = this.parameters.smoothEdges.quality; - - patch.parameters.ao.enabled = this.parameters.ao.enabled; - patch.parameters.ao.strength = this.parameters.ao.strength; - patch.parameters.ao.spread = this.parameters.ao.spread; - patch.updateUniforms(); - } + const patchId = new THREE.Vector3() + for (patchId.x = patchIdFrom.x; patchId.x < patchIdTo.x; patchId.x++) { + for (patchId.y = patchIdFrom.y; patchId.y < patchIdTo.y; patchId.y++) { + for (patchId.z = patchIdFrom.z; patchId.z < patchIdTo.z; patchId.z++) { + const patchStart = new THREE.Vector3().multiplyVectors( + patchId, + this.patchSize, + ) + const patch = this.getPatch(patchStart) + if (patch) { + patch.container.visible = true + } } + } } - - /** - * Deletes all the geometry data stored on the GPU. - * It will be recomputed if needed again. - */ - public clear(): void { - for (const [patchId, patch] of Object.entries(this.patches)) { - patch?.dispose(); - this.container.clear(); - delete this.patches[patchId]; - } + } + + /** Call this method before rendering. */ + public updateUniforms(): void { + for (const patch of Object.values(this.patches)) { + if (patch) { + patch.parameters.voxels.displayMode = this.parameters.voxels.displayMode + patch.parameters.voxels.noiseStrength = + this.parameters.voxels.noiseStrength + + patch.parameters.lighting.ambient = this.parameters.lighting.ambient + patch.parameters.lighting.diffuse = this.parameters.lighting.diffuse + + patch.parameters.smoothEdges.enabled = + this.parameters.smoothEdges.enabled + patch.parameters.smoothEdges.radius = this.parameters.smoothEdges.radius + patch.parameters.smoothEdges.quality = + this.parameters.smoothEdges.quality + + patch.parameters.ao.enabled = this.parameters.ao.enabled + patch.parameters.ao.strength = this.parameters.ao.strength + patch.parameters.ao.spread = this.parameters.ao.spread + patch.updateUniforms() + } } - - /** - * Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app. - */ - public dispose(): void { - this.clear(); - this.patchFactory.dispose(); - } - - private getPatch(patchStart: THREE.Vector3): Patch | null { - const patchId = this.computePatchId(patchStart); - - let patch = this.patches[patchId]; - if (typeof patch === "undefined") { - const patchEnd = new THREE.Vector3().addVectors(patchStart, this.patchSize); - - patch = this.patchFactory.buildPatch(patchStart, patchEnd); - if (patch) { - patch.container.visible = false; - this.container.add(patch.container); - } - this.patches[patchId] = patch; - } - return patch; + } + + /** + * Deletes all the geometry data stored on the GPU. + * It will be recomputed if needed again. + */ + public clear(): void { + for (const [patchId, patch] of Object.entries(this.patches)) { + patch?.dispose() + this.container.clear() + delete this.patches[patchId] } - - private computePatchId(patchStart: THREE.Vector3): string { - return `${patchStart.x / this.patchSize.x}_${patchStart.y / this.patchSize.y}_${patchStart.z / this.patchSize.z}`; + } + + /** + * Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app. + */ + public dispose(): void { + this.clear() + this.patchFactory.dispose() + } + + private getPatch(patchStart: THREE.Vector3): Patch | null { + const patchId = this.computePatchId(patchStart) + + let patch = this.patches[patchId] + if (typeof patch === 'undefined') { + const patchEnd = new THREE.Vector3().addVectors( + patchStart, + this.patchSize, + ) + + patch = this.patchFactory.buildPatch(patchStart, patchEnd) + if (patch) { + patch.container.visible = false + this.container.add(patch.container) + } + this.patches[patchId] = patch } + return patch + } + + private computePatchId(patchStart: THREE.Vector3): string { + return `${patchStart.x / this.patchSize.x}_${ + patchStart.y / this.patchSize.y + }_${patchStart.z / this.patchSize.z}` + } } -export { Terrain, type IVoxelMap }; - +export { Terrain, type IVoxelMap } diff --git a/src/lib/three-usage.ts b/src/lib/three-usage.ts index 6cd2d78..746f926 100644 --- a/src/lib/three-usage.ts +++ b/src/lib/three-usage.ts @@ -1,15 +1,15 @@ export { - Box3, - BufferGeometry, - DataTexture, - Group, - Mesh, - Object3D, - ShaderMaterial, - Sphere, - Texture, - type TypedArray, - Uint32BufferAttribute, - Vector3 -} from "three"; - + Box3, + BufferGeometry, + DataTexture, + Group, + Mesh, + Object3D, + ShaderMaterial, + Sphere, + Texture, + type TypedArray, + type Material, + Uint32BufferAttribute, + Vector3, +} from 'three' diff --git a/src/test/config/tsconfig.json b/src/test/config/tsconfig.json index aae8d00..74ee163 100644 --- a/src/test/config/tsconfig.json +++ b/src/test/config/tsconfig.json @@ -1,9 +1,7 @@ { - "extends": "../../lib/config/tsconfig.json", - "files": [ - "../main.ts" - ], - "compilerOptions": { - "declaration": false, - } -} \ No newline at end of file + "extends": "../../../tsconfig.json", + "files": ["../main.ts"], + "compilerOptions": { + "declaration": false + } +} diff --git a/src/test/config/webpack.config.js b/src/test/config/webpack.config.js index 648ad2c..8ad11aa 100644 --- a/src/test/config/webpack.config.js +++ b/src/test/config/webpack.config.js @@ -1,53 +1,64 @@ -const path = require("path"); +const path = require('path') -const PROJECT_DIR = path.resolve(__dirname, "..", "..", ".."); +const PROJECT_DIR = path.resolve(__dirname, '..', '..', '..') -function makeExport(sourceFilepath /* string */, outFolder /* string */, mode /* string */, library /* optional string */) /* void */ { - let name = library ? library.toLowerCase() : "[name]"; - const filename = `${name}${mode === "production" ? ".min" : ""}.js`; +function makeExport( + sourceFilepath /* string */, + outFolder /* string */, + mode /* string */, + library /* optional string */, +) /* void */ { + let name = library ? library.toLowerCase() : '[name]' + const filename = `${name}${mode === 'production' ? '.min' : ''}.js` - return { - devtool: "source-map", - mode, - entry: sourceFilepath, - output: { - path: outFolder, - filename: filename, - library, - }, - target: ["web", "es5"], - resolve: { - extensions: [".ts"], - alias: { - three: path.resolve('./node_modules/three') + return { + devtool: 'source-map', + mode, + entry: sourceFilepath, + output: { + path: outFolder, + filename: filename, + library, + }, + target: ['web', 'es5'], + resolve: { + extensions: ['.ts'], + alias: { + three: path.resolve('./node_modules/three'), + }, + }, + module: { + rules: [ + { + test: /\.ts?$/, + // exclude: /node_modules/, + use: [ + { + loader: 'ts-loader', + options: { + // transpileOnly: true, + compilerOptions: { + rootDir: path.join(PROJECT_DIR, 'src'), + }, + configFile: path.join( + PROJECT_DIR, + 'src', + 'test', + 'config', + 'tsconfig.json', + ), + }, }, + ], }, - module: { - rules: [ - { - test: /\.ts?$/, - // exclude: /node_modules/, - use: [ - { - loader: "ts-loader", - options: { - // transpileOnly: true, - compilerOptions: { - rootDir: path.join(PROJECT_DIR, "src") - }, - configFile: path.join(PROJECT_DIR, "src", "test", "config", 'tsconfig.json') - } - } - ], - }, - ] - } - }; + ], + }, + } } -const srcDir = path.join(PROJECT_DIR, "src", "test"); -const targetDir = path.join(PROJECT_DIR, "test", "script"); +const srcDir = path.join(PROJECT_DIR, 'src', 'test') +const targetDir = path.join(PROJECT_DIR, 'test', 'script') module.exports = [ - makeExport(path.join(srcDir, "main.ts"), targetDir, "development"), -]; + makeExport(path.join(srcDir, 'main.ts'), targetDir, 'development'), +] diff --git a/src/test/main.ts b/src/test/main.ts index d5dd54c..600eab1 100644 --- a/src/test/main.ts +++ b/src/test/main.ts @@ -1,41 +1,47 @@ +import * as THREE from 'three' +import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js' -import * as THREE from "three"; -import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js"; -import { AresRpgEngine } from "../lib/index"; -import { VoxelMap } from "./voxel-map"; +import { AresRpgEngine } from '../lib/index' -const renderer = new THREE.WebGLRenderer(); -document.body.appendChild(renderer.domElement); -renderer.setClearColor(0x880000); +import { VoxelMap } from './voxel-map' -const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); +const renderer = new THREE.WebGLRenderer() +document.body.appendChild(renderer.domElement) +renderer.setClearColor(0x880000) + +const camera = new THREE.PerspectiveCamera( + 75, + window.innerWidth / window.innerHeight, + 0.1, + 1000, +) const udpateRendererSize = () => { - const width = window.innerWidth; - const height = window.innerHeight; - renderer.setSize(width, height); - camera.aspect = width / height; - camera.updateProjectionMatrix(); -}; -window.addEventListener("resize", udpateRendererSize); -udpateRendererSize(); + const width = window.innerWidth + const height = window.innerHeight + renderer.setSize(width, height) + camera.aspect = width / height + camera.updateProjectionMatrix() +} +window.addEventListener('resize', udpateRendererSize) +udpateRendererSize() -const scene = new THREE.Scene(); +const scene = new THREE.Scene() -const voxelMap = new VoxelMap(256, 256, 16); -const terrain = new AresRpgEngine.Terrain(voxelMap); -scene.add(terrain.container); +const voxelMap = new VoxelMap(256, 256, 16) +const terrain = new AresRpgEngine.Terrain(voxelMap) +scene.add(terrain.container) -scene.add(new THREE.AxesHelper(500)); +scene.add(new THREE.AxesHelper(500)) -camera.position.set(-50, 100, -50); -const cameraControl = new OrbitControls(camera, renderer.domElement); -cameraControl.target.set(voxelMap.size.x / 2, 0, voxelMap.size.z / 2); +camera.position.set(-50, 100, -50) +const cameraControl = new OrbitControls(camera, renderer.domElement) +cameraControl.target.set(voxelMap.size.x / 2, 0, voxelMap.size.z / 2) -terrain.showEntireMap(); +terrain.showEntireMap() function render(): void { - cameraControl.update(); - terrain.updateUniforms(); - renderer.render(scene, camera); - requestAnimationFrame(render); + cameraControl.update() + terrain.updateUniforms() + renderer.render(scene, camera) + requestAnimationFrame(render) } -requestAnimationFrame(render); +requestAnimationFrame(render) diff --git a/src/test/voxel-map.ts b/src/test/voxel-map.ts index a8f55b3..beb803b 100644 --- a/src/test/voxel-map.ts +++ b/src/test/voxel-map.ts @@ -1,120 +1,125 @@ -import { createNoise2D } from 'simplex-noise'; -import * as THREE from "three"; -import { AresRpgEngine } from '../lib/index'; +import { createNoise2D } from 'simplex-noise' +import * as THREE from 'three' + +import { AresRpgEngine } from '../lib/index' enum EVoxelType { - ROCK, - GRASS, - SNOW, - WATER, - SAND, + ROCK, + GRASS, + SNOW, + WATER, + SAND, } const voxelMaterials: Record = [ - { color: new THREE.Color("#ABABAB") }, - { color: new THREE.Color("#00B920") }, - { color: new THREE.Color("#E5E5E5") }, - { color: new THREE.Color("#0055E2") }, - { color: new THREE.Color("#DCBE28") }, -]; + { color: new THREE.Color('#ABABAB') }, + { color: new THREE.Color('#00B920') }, + { color: new THREE.Color('#E5E5E5') }, + { color: new THREE.Color('#0055E2') }, + { color: new THREE.Color('#DCBE28') }, +] type StoredVoxel = { - readonly y: number; - readonly type: EVoxelType; -}; + readonly y: number + readonly type: EVoxelType +} class VoxelMap implements AresRpgEngine.IVoxelMap { - public readonly size: THREE.Vector3; - public readonly voxelMaterialsList = Object.values(voxelMaterials); - - private readonly voxels: ReadonlyArray; - - public constructor(width: number, height: number, altitude: number) { - this.size = new THREE.Vector3(width, altitude, height); - - const noise2D = createNoise2D(); - - const voxels: StoredVoxel[] = []; - for (let iX = 0; iX < this.size.x; iX++) { - for (let iZ = 0; iZ < this.size.z; iZ++) { - const yNoise = 0.5 + 0.5 * noise2D(iX / 50, iZ / 50); - const iY = Math.floor(yNoise * this.size.y); - const id = this.buildId(iX, iZ); - - let type: EVoxelType; - if (iY < 0.10 * altitude) { - type = EVoxelType.WATER; - } else if (iY < 0.3 * altitude) { - type = EVoxelType.SAND; - } else if (iY < 0.75 * altitude) { - type = EVoxelType.GRASS; - } else if (iY < 0.85 * altitude) { - type = EVoxelType.ROCK; - } else { - type = EVoxelType.SNOW; - } - voxels[id] = { - y: iY, - type, - }; - } + public readonly size: THREE.Vector3 + public readonly voxelMaterialsList = Object.values(voxelMaterials) + + private readonly voxels: ReadonlyArray + + public constructor(width: number, height: number, altitude: number) { + this.size = new THREE.Vector3(width, altitude, height) + + const noise2D = createNoise2D() + + const voxels: StoredVoxel[] = [] + for (let iX = 0; iX < this.size.x; iX++) { + for (let iZ = 0; iZ < this.size.z; iZ++) { + const yNoise = 0.5 + 0.5 * noise2D(iX / 50, iZ / 50) + const iY = Math.floor(yNoise * this.size.y) + const id = this.buildId(iX, iZ) + + let type: EVoxelType + if (iY < 0.1 * altitude) { + type = EVoxelType.WATER + } else if (iY < 0.3 * altitude) { + type = EVoxelType.SAND + } else if (iY < 0.75 * altitude) { + type = EVoxelType.GRASS + } else if (iY < 0.85 * altitude) { + type = EVoxelType.ROCK + } else { + type = EVoxelType.SNOW } - this.voxels = voxels; - - console.log(`Generated map of size ${this.size.x}x${this.size.y}x${this.size.z} (${this.voxels.length.toLocaleString()} voxels)`); + voxels[id] = { + y: iY, + type, + } + } } - - public getMaxVoxelsCount(from: THREE.Vector3, to: THREE.Vector3): number { - const fromX = Math.max(from.x, 0); - const fromZ = Math.max(from.z, 0); - - const toX = Math.min(to.x, this.size.x); - const toZ = Math.min(to.z, this.size.z); - - return (toX - fromX) * (toZ - fromZ); + this.voxels = voxels + + console.log( + `Generated map of size ${this.size.x}x${this.size.y}x${ + this.size.z + } (${this.voxels.length.toLocaleString()} voxels)`, + ) + } + + public getMaxVoxelsCount(from: THREE.Vector3, to: THREE.Vector3): number { + const fromX = Math.max(from.x, 0) + const fromZ = Math.max(from.z, 0) + + const toX = Math.min(to.x, this.size.x) + const toZ = Math.min(to.z, this.size.z) + + return (toX - fromX) * (toZ - fromZ) + } + + public *iterateOnVoxels( + from: THREE.Vector3, + to: THREE.Vector3, + ): Generator { + if (to.x < from.x || to.y < from.y || to.z < from.z) { + throw new Error() } - public *iterateOnVoxels(from: THREE.Vector3, to: THREE.Vector3): Generator { - if (to.x < from.x || to.y < from.y || to.z < from.z) { - throw new Error(); - } - - const position = new THREE.Vector3(); - for (position.x = from.x; position.x < to.x; position.x++) { - for (position.z = from.z; position.z < to.z; position.z++) { - const voxel = this.getVoxel(position.x, position.z); - if (voxel) { - position.y = voxel.y; - if (from.y <= position.y && position.y < to.y) { - yield { - position, - materialId: voxel.type - }; - } - } + const position = new THREE.Vector3() + for (position.x = from.x; position.x < to.x; position.x++) { + for (position.z = from.z; position.z < to.z; position.z++) { + const voxel = this.getVoxel(position.x, position.z) + if (voxel) { + position.y = voxel.y + if (from.y <= position.y && position.y < to.y) { + yield { + position, + materialId: voxel.type, } + } } + } } + } - public voxelExists(x: number, y: number, z: number): boolean { - const voxel = this.getVoxel(x, z); - return voxel?.y === y; - } + public voxelExists(x: number, y: number, z: number): boolean { + const voxel = this.getVoxel(x, z) + return voxel?.y === y + } - private getVoxel(x: number, z: number): StoredVoxel | null { - if (x >= 0 && x < this.size.x && z >= 0 && z < this.size.z) { - const index = this.buildId(x, z); - return this.voxels[index] || null; - } - return null; + private getVoxel(x: number, z: number): StoredVoxel | null { + if (x >= 0 && x < this.size.x && z >= 0 && z < this.size.z) { + const index = this.buildId(x, z) + return this.voxels[index] || null } + return null + } - private buildId(x: number, z: number): number { - return x * this.size.z + z; - } + private buildId(x: number, z: number): number { + return x * this.size.z + z + } } -export { - VoxelMap -}; - +export { VoxelMap } diff --git a/test/index.html b/test/index.html index a91c9d3..c18523f 100644 --- a/test/index.html +++ b/test/index.html @@ -1,13 +1,11 @@ - + + + + Voxel World + - - - Voxel World - - - - - - - \ No newline at end of file + + + + diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..742f6b0 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,47 @@ +{ + "files": ["src/lib/index.ts"], + "compilerOptions": { + /* Type Checking */ + "allowUnreachableCode": false, + "allowUnusedLabels": false, + "alwaysStrict": true, + "exactOptionalPropertyTypes": true, + "noFallthroughCasesInSwitch": true, + "noImplicitAny": true, + "noImplicitOverride": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noPropertyAccessFromIndexSignature": true, + "noUncheckedIndexedAccess": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "strict": true, + "strictBindCallApply": true, + "strictFunctionTypes": true, + "strictNullChecks": true, + "strictPropertyInitialization": true, + "useUnknownInCatchVariables": true, + + /* Modules */ + "module": "ES6", + "moduleResolution": "Bundler", + "typeRoots": ["src/lib/@types", "./node_modules/@types"], + + /* Emit */ + "declaration": true, + "declarationMap": false, + "outDir": "dist", + "sourceMap": false, + + /* JavaScript Support */ + "allowJs": false, + + /* Interop Constraints */ + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "isolatedModules": true, + + /* Language and Environment */ + "target": "ES2018" + } +}