├── .gitattributes
├── .gitignore
├── .husky
    └── pre-commit
├── .prettierignore
├── .prettierrc.json
├── .run
    ├── build.run.xml
    ├── dev.run.xml
    └── preview.run.xml
├── .yarn
    ├── plugins
    │   └── @yarnpkg
    │   │   └── plugin-interactive-tools.cjs
    └── releases
    │   └── yarn-3.2.1.cjs
├── .yarnrc.yml
├── LICENSE
├── README.md
├── assets
    ├── github.png
    └── twitter.png
├── favicon.ico
├── index.html
├── package-lock.json
├── package.json
├── public
    └── models
    │   └── tentacle.glb
├── scripts
    └── cleanup.js
├── src
    ├── engine
    │   ├── Camera.ts
    │   ├── Engine.ts
    │   ├── Experience.ts
    │   ├── GameEntity.ts
    │   ├── RenderEngine.ts
    │   ├── RenderLoop.ts
    │   ├── Resources.ts
    │   ├── Sizes.ts
    │   ├── interface
    │   │   ├── DebugUI.ts
    │   │   ├── InfoUI.ts
    │   │   ├── Loader.ts
    │   │   ├── info.scss
    │   │   └── loader.scss
    │   └── utilities
    │   │   └── EventEmitter.ts
    ├── main.ts
    ├── style.scss
    ├── toon-shader
    │   ├── Floor.ts
    │   ├── MainScene.ts
    │   ├── ToonShaderMaterial.ts
    │   ├── geometries
    │   │   ├── Cylinder.ts
    │   │   ├── Knot.ts
    │   │   ├── Sphere.ts
    │   │   └── Tentacle.ts
    │   └── shaders
    │   │   ├── toon.frag
    │   │   └── toon.vert
    ├── types
    │   └── glsl.d.ts
    └── vite-env.d.ts
├── tsconfig.json
├── vite.config.js
└── yarn.lock
/.gitattributes:
--------------------------------------------------------------------------------
1 | /.yarn/releases/** binary
2 | /.yarn/plugins/** binary
3 | 
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
 1 | # Logs
 2 | logs
 3 | *.log
 4 | npm-debug.log*
 5 | yarn-debug.log*
 6 | yarn-error.log*
 7 | pnpm-debug.log*
 8 | lerna-debug.log*
 9 | 
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 | 
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 | 
26 | .pnp.*
27 | .yarn/*
28 | !.yarn/patches
29 | !.yarn/plugins
30 | !.yarn/releases
31 | !.yarn/sdks
32 | !.yarn/versions
33 | 
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | . "$(dirname -- "$0")/_/husky.sh"
3 | 
4 | npx lint-staged
5 | 
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | dist
2 | assets
3 | public
4 | 
5 | .yarn
6 | .husky
7 | package-lock.json
8 | .yarnrc.yml
9 | 
--------------------------------------------------------------------------------
/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 |   "semi": false,
3 |   "singleQuote": true
4 | }
5 | 
--------------------------------------------------------------------------------
/.run/build.run.xml:
--------------------------------------------------------------------------------
 1 | 
 2 |   
 3 |     
 4 |     
 5 |     
 6 |       
 7 |     
 8 |     
 9 |     
10 |     
11 |   
12 | 
--------------------------------------------------------------------------------
/.run/dev.run.xml:
--------------------------------------------------------------------------------
 1 | 
 2 |   
 3 |     
 4 |     
 5 |     
 6 |       
 7 |     
 8 |     
 9 |     
10 |     
11 |   
12 | 
--------------------------------------------------------------------------------
/.run/preview.run.xml:
--------------------------------------------------------------------------------
 1 | 
 2 |   
 3 |     
 4 |     
 5 |     
 6 |       
 7 |     
 8 |     
 9 |     
10 |     
11 |   
12 | 
--------------------------------------------------------------------------------
/.yarnrc.yml:
--------------------------------------------------------------------------------
1 | nodeLinker: node-modules
2 | 
3 | plugins:
4 |   - path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
5 |     spec: "@yarnpkg/plugin-interactive-tools"
6 | 
7 | yarnPath: .yarn/releases/yarn-3.2.1.cjs
8 | 
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
 1 | MIT License
 2 | 
 3 | Copyright (c) 2022 Maya Nedeljkovich Batić
 4 | 
 5 | Permission is hereby granted, free of charge, to any person obtaining a copy
 6 | of this software and associated documentation files (the "Software"), to deal
 7 | in the Software without restriction, including without limitation the rights
 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 | 
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 | 
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 | 
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
 1 | # Three.js Toon Shader
 2 | 
 3 | Inspired by [Toon Shader](https://roystan.net/articles/toon-shader.html) in Unity by Roystan and [Cel Shading](https://halisavakis.com/my-take-on-shaders-cel-shading/) by Harry Alisavakis.
 4 |   
 5 | Local development:
 6 | ```bash
 7 | yarn
 8 | yarn dev
 9 | ```
10 | 
--------------------------------------------------------------------------------
/assets/github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mayacoda/toon-shader/760b0f338bcf8d01743690aeb23580c07a3afd86/assets/github.png
--------------------------------------------------------------------------------
/assets/twitter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mayacoda/toon-shader/760b0f338bcf8d01743690aeb23580c07a3afd86/assets/twitter.png
--------------------------------------------------------------------------------
/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mayacoda/toon-shader/760b0f338bcf8d01743690aeb23580c07a3afd86/favicon.ico
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 |   
 4 |     
 5 |     
 6 |     
 7 |     Simple Three.js + TypeScript Starter
 8 |   
 9 |   
10 |     
11 |     
12 |   
13 | 
14 | 
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
   1 | {
   2 |   "name": "simple-threejs-typescript-starter",
   3 |   "version": "0.1.0",
   4 |   "lockfileVersion": 2,
   5 |   "requires": true,
   6 |   "packages": {
   7 |     "": {
   8 |       "name": "simple-threejs-typescript-starter",
   9 |       "version": "0.1.0",
  10 |       "license": "MIT",
  11 |       "dependencies": {
  12 |         "lil-gui": "^0.16.1",
  13 |         "three": "^0.141.0"
  14 |       },
  15 |       "devDependencies": {
  16 |         "@types/three": "^0.141.0",
  17 |         "sass": "^1.52.3",
  18 |         "typescript": "^4.7.4",
  19 |         "vite": "^2.9.12",
  20 |         "vite-plugin-glsl": "^0.1.5"
  21 |       }
  22 |     },
  23 |     "node_modules/@rollup/pluginutils": {
  24 |       "version": "4.2.1",
  25 |       "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz",
  26 |       "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==",
  27 |       "dev": true,
  28 |       "dependencies": {
  29 |         "estree-walker": "^2.0.1",
  30 |         "picomatch": "^2.2.2"
  31 |       },
  32 |       "engines": {
  33 |         "node": ">= 8.0.0"
  34 |       }
  35 |     },
  36 |     "node_modules/@types/three": {
  37 |       "version": "0.141.0",
  38 |       "resolved": "https://registry.npmjs.org/@types/three/-/three-0.141.0.tgz",
  39 |       "integrity": "sha512-OJdKDgTPVBUgc+s74DYoy4aLznbFFC38Xm4ElmU1YwGNgR7GGFVvFCX7lpVgOsT6S1zSJtGdajTsOYE8/xY9nA==",
  40 |       "dev": true,
  41 |       "dependencies": {
  42 |         "@types/webxr": "*"
  43 |       }
  44 |     },
  45 |     "node_modules/@types/webxr": {
  46 |       "version": "0.4.0",
  47 |       "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.4.0.tgz",
  48 |       "integrity": "sha512-LQvrACV3Pj17GpkwHwXuTd733gfY+D7b9mKdrTmLdO7vo7P/o6209Qqtk63y/FCv/lspdmi0pWz6Qe/ull9kQg==",
  49 |       "dev": true
  50 |     },
  51 |     "node_modules/anymatch": {
  52 |       "version": "3.1.2",
  53 |       "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
  54 |       "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
  55 |       "dev": true,
  56 |       "dependencies": {
  57 |         "normalize-path": "^3.0.0",
  58 |         "picomatch": "^2.0.4"
  59 |       },
  60 |       "engines": {
  61 |         "node": ">= 8"
  62 |       }
  63 |     },
  64 |     "node_modules/binary-extensions": {
  65 |       "version": "2.2.0",
  66 |       "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
  67 |       "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
  68 |       "dev": true,
  69 |       "engines": {
  70 |         "node": ">=8"
  71 |       }
  72 |     },
  73 |     "node_modules/braces": {
  74 |       "version": "3.0.2",
  75 |       "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
  76 |       "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
  77 |       "dev": true,
  78 |       "dependencies": {
  79 |         "fill-range": "^7.0.1"
  80 |       },
  81 |       "engines": {
  82 |         "node": ">=8"
  83 |       }
  84 |     },
  85 |     "node_modules/chokidar": {
  86 |       "version": "3.5.3",
  87 |       "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
  88 |       "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
  89 |       "dev": true,
  90 |       "funding": [
  91 |         {
  92 |           "type": "individual",
  93 |           "url": "https://paulmillr.com/funding/"
  94 |         }
  95 |       ],
  96 |       "dependencies": {
  97 |         "anymatch": "~3.1.2",
  98 |         "braces": "~3.0.2",
  99 |         "glob-parent": "~5.1.2",
 100 |         "is-binary-path": "~2.1.0",
 101 |         "is-glob": "~4.0.1",
 102 |         "normalize-path": "~3.0.0",
 103 |         "readdirp": "~3.6.0"
 104 |       },
 105 |       "engines": {
 106 |         "node": ">= 8.10.0"
 107 |       },
 108 |       "optionalDependencies": {
 109 |         "fsevents": "~2.3.2"
 110 |       }
 111 |     },
 112 |     "node_modules/esbuild": {
 113 |       "version": "0.14.45",
 114 |       "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.45.tgz",
 115 |       "integrity": "sha512-JOxGUD8jcs8xE8DjyGWC8by/vLMCXTJ/wuauWipL5kJRZx1dhpqIntb31QHjA45GZJWaXv7SjC/Zwu1bCkXWtQ==",
 116 |       "dev": true,
 117 |       "hasInstallScript": true,
 118 |       "bin": {
 119 |         "esbuild": "bin/esbuild"
 120 |       },
 121 |       "engines": {
 122 |         "node": ">=12"
 123 |       },
 124 |       "optionalDependencies": {
 125 |         "esbuild-android-64": "0.14.45",
 126 |         "esbuild-android-arm64": "0.14.45",
 127 |         "esbuild-darwin-64": "0.14.45",
 128 |         "esbuild-darwin-arm64": "0.14.45",
 129 |         "esbuild-freebsd-64": "0.14.45",
 130 |         "esbuild-freebsd-arm64": "0.14.45",
 131 |         "esbuild-linux-32": "0.14.45",
 132 |         "esbuild-linux-64": "0.14.45",
 133 |         "esbuild-linux-arm": "0.14.45",
 134 |         "esbuild-linux-arm64": "0.14.45",
 135 |         "esbuild-linux-mips64le": "0.14.45",
 136 |         "esbuild-linux-ppc64le": "0.14.45",
 137 |         "esbuild-linux-riscv64": "0.14.45",
 138 |         "esbuild-linux-s390x": "0.14.45",
 139 |         "esbuild-netbsd-64": "0.14.45",
 140 |         "esbuild-openbsd-64": "0.14.45",
 141 |         "esbuild-sunos-64": "0.14.45",
 142 |         "esbuild-windows-32": "0.14.45",
 143 |         "esbuild-windows-64": "0.14.45",
 144 |         "esbuild-windows-arm64": "0.14.45"
 145 |       }
 146 |     },
 147 |     "node_modules/esbuild-android-64": {
 148 |       "version": "0.14.45",
 149 |       "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.45.tgz",
 150 |       "integrity": "sha512-krVmwL2uXQN1A+Ci4u2MR+Y0IAvQK0u3no5TsgguHVhTy138szjuohScCGjkpvLCpGLk7P4kFP1LKuntvJ0d4A==",
 151 |       "cpu": [
 152 |         "x64"
 153 |       ],
 154 |       "dev": true,
 155 |       "optional": true,
 156 |       "os": [
 157 |         "android"
 158 |       ],
 159 |       "engines": {
 160 |         "node": ">=12"
 161 |       }
 162 |     },
 163 |     "node_modules/esbuild-android-arm64": {
 164 |       "version": "0.14.45",
 165 |       "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.45.tgz",
 166 |       "integrity": "sha512-62POGdzAjM+XOXEM5MmFW6k9Pjdjg1hTrXKKBbPE700LFF36B+1Jv9QkskT5UadbTk4cdH9BQ7bGiRPYY0p/Dw==",
 167 |       "cpu": [
 168 |         "arm64"
 169 |       ],
 170 |       "dev": true,
 171 |       "optional": true,
 172 |       "os": [
 173 |         "android"
 174 |       ],
 175 |       "engines": {
 176 |         "node": ">=12"
 177 |       }
 178 |     },
 179 |     "node_modules/esbuild-darwin-64": {
 180 |       "version": "0.14.45",
 181 |       "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.45.tgz",
 182 |       "integrity": "sha512-dbkVUAnGx5IeZesWnIhnvxy7dSvgUQvfy0TVLzd9XVP3oI/VsKs8UNsfPrxI5HiN4SINv7oPAbxWceMpB7IqNA==",
 183 |       "cpu": [
 184 |         "x64"
 185 |       ],
 186 |       "dev": true,
 187 |       "optional": true,
 188 |       "os": [
 189 |         "darwin"
 190 |       ],
 191 |       "engines": {
 192 |         "node": ">=12"
 193 |       }
 194 |     },
 195 |     "node_modules/esbuild-darwin-arm64": {
 196 |       "version": "0.14.45",
 197 |       "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.45.tgz",
 198 |       "integrity": "sha512-O6Bz7nnOae5rvbh2Ueo8ibSr7+/eLjsbPdgeMsAZri+LkOa7nsVPnhmocpO3Hy/LWfagTtHy1O9HRPIaArPmTg==",
 199 |       "cpu": [
 200 |         "arm64"
 201 |       ],
 202 |       "dev": true,
 203 |       "optional": true,
 204 |       "os": [
 205 |         "darwin"
 206 |       ],
 207 |       "engines": {
 208 |         "node": ">=12"
 209 |       }
 210 |     },
 211 |     "node_modules/esbuild-freebsd-64": {
 212 |       "version": "0.14.45",
 213 |       "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.45.tgz",
 214 |       "integrity": "sha512-y1X2nr3XSWnDC7MRcy21EVAT0TiCtdefOntJ+SQcZnPBTURzX77f99S8lDF2KswukChkiacpd2Wd4VZieo7w7Q==",
 215 |       "cpu": [
 216 |         "x64"
 217 |       ],
 218 |       "dev": true,
 219 |       "optional": true,
 220 |       "os": [
 221 |         "freebsd"
 222 |       ],
 223 |       "engines": {
 224 |         "node": ">=12"
 225 |       }
 226 |     },
 227 |     "node_modules/esbuild-freebsd-arm64": {
 228 |       "version": "0.14.45",
 229 |       "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.45.tgz",
 230 |       "integrity": "sha512-r3ZNejkx1BKXQ6sYOP6C5rTwgiUajyAh03wygLWZtl+SLyygvAnu+OouqtveesufjBDgujp4wZXP/n8PVqXkqg==",
 231 |       "cpu": [
 232 |         "arm64"
 233 |       ],
 234 |       "dev": true,
 235 |       "optional": true,
 236 |       "os": [
 237 |         "freebsd"
 238 |       ],
 239 |       "engines": {
 240 |         "node": ">=12"
 241 |       }
 242 |     },
 243 |     "node_modules/esbuild-linux-32": {
 244 |       "version": "0.14.45",
 245 |       "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.45.tgz",
 246 |       "integrity": "sha512-Qk9cCO3PJig/Y+SdslN/Th4pbAjgaH9oUjVH28eMsLTPf6QDUuK6EED91jepJdR3vxhcnVjyl6JqtOWmP+uxCg==",
 247 |       "cpu": [
 248 |         "ia32"
 249 |       ],
 250 |       "dev": true,
 251 |       "optional": true,
 252 |       "os": [
 253 |         "linux"
 254 |       ],
 255 |       "engines": {
 256 |         "node": ">=12"
 257 |       }
 258 |     },
 259 |     "node_modules/esbuild-linux-64": {
 260 |       "version": "0.14.45",
 261 |       "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.45.tgz",
 262 |       "integrity": "sha512-IybO2ugqvc/Zzn1Kih3x0FVjYAy3GTCwhtcp91dbdqk3wPqxYCzObYspa8ca0s+OovI0Cnb+rhXrUtq8gBqlqw==",
 263 |       "cpu": [
 264 |         "x64"
 265 |       ],
 266 |       "dev": true,
 267 |       "optional": true,
 268 |       "os": [
 269 |         "linux"
 270 |       ],
 271 |       "engines": {
 272 |         "node": ">=12"
 273 |       }
 274 |     },
 275 |     "node_modules/esbuild-linux-arm": {
 276 |       "version": "0.14.45",
 277 |       "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.45.tgz",
 278 |       "integrity": "sha512-qKWJ4A4TAcxXV2TBLPw3Av5X2SYNfyNnBHNJTQJ5VuevK6Aq5i6XEMvUgdlcVuZ9MYPfS5aJZWglzDzJMf1Lpw==",
 279 |       "cpu": [
 280 |         "arm"
 281 |       ],
 282 |       "dev": true,
 283 |       "optional": true,
 284 |       "os": [
 285 |         "linux"
 286 |       ],
 287 |       "engines": {
 288 |         "node": ">=12"
 289 |       }
 290 |     },
 291 |     "node_modules/esbuild-linux-arm64": {
 292 |       "version": "0.14.45",
 293 |       "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.45.tgz",
 294 |       "integrity": "sha512-UNEyuHTwztrkEU/+mWIxGzKrYBo2cEtjYAZQVZB1kliANKgRITktg2miaO/b/VtNe84ob1aXSvW8XOPEn5RTGQ==",
 295 |       "cpu": [
 296 |         "arm64"
 297 |       ],
 298 |       "dev": true,
 299 |       "optional": true,
 300 |       "os": [
 301 |         "linux"
 302 |       ],
 303 |       "engines": {
 304 |         "node": ">=12"
 305 |       }
 306 |     },
 307 |     "node_modules/esbuild-linux-mips64le": {
 308 |       "version": "0.14.45",
 309 |       "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.45.tgz",
 310 |       "integrity": "sha512-s/jcfw3Vpku5dIVSFVY7idJsGdIpIJ88IrkyprVgCG2yBeXatb67B7yIt0E1tL+OHrJJdNBw6GikCiMPAAu1VA==",
 311 |       "cpu": [
 312 |         "mips64el"
 313 |       ],
 314 |       "dev": true,
 315 |       "optional": true,
 316 |       "os": [
 317 |         "linux"
 318 |       ],
 319 |       "engines": {
 320 |         "node": ">=12"
 321 |       }
 322 |     },
 323 |     "node_modules/esbuild-linux-ppc64le": {
 324 |       "version": "0.14.45",
 325 |       "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.45.tgz",
 326 |       "integrity": "sha512-lJItl6ESZnhSx951U9R7MTBopgwIELHlQzC6SBR023V5JC1rPRFDZ/UEBsV+7BFcCAfqlyb+odGEAmcBSf4XCA==",
 327 |       "cpu": [
 328 |         "ppc64"
 329 |       ],
 330 |       "dev": true,
 331 |       "optional": true,
 332 |       "os": [
 333 |         "linux"
 334 |       ],
 335 |       "engines": {
 336 |         "node": ">=12"
 337 |       }
 338 |     },
 339 |     "node_modules/esbuild-linux-riscv64": {
 340 |       "version": "0.14.45",
 341 |       "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.45.tgz",
 342 |       "integrity": "sha512-8anMu+QLl9MununVCGJN2I/JvUWPm1EVsBBLq/J+Nz4hr8t6QOCuEp0HRaeMohyl2XiMFBchVu0mwa05rF7GFQ==",
 343 |       "cpu": [
 344 |         "riscv64"
 345 |       ],
 346 |       "dev": true,
 347 |       "optional": true,
 348 |       "os": [
 349 |         "linux"
 350 |       ],
 351 |       "engines": {
 352 |         "node": ">=12"
 353 |       }
 354 |     },
 355 |     "node_modules/esbuild-linux-s390x": {
 356 |       "version": "0.14.45",
 357 |       "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.45.tgz",
 358 |       "integrity": "sha512-1TPeNvNCoahMw745KNTA6POKaFfSqQrBb3fdOL82GXZqyKU/6rHNwGP0NgHe88bAUMp3QZfjGfCGKxfBHL77RQ==",
 359 |       "cpu": [
 360 |         "s390x"
 361 |       ],
 362 |       "dev": true,
 363 |       "optional": true,
 364 |       "os": [
 365 |         "linux"
 366 |       ],
 367 |       "engines": {
 368 |         "node": ">=12"
 369 |       }
 370 |     },
 371 |     "node_modules/esbuild-netbsd-64": {
 372 |       "version": "0.14.45",
 373 |       "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.45.tgz",
 374 |       "integrity": "sha512-55f2eZ8EQhhOZosqX0mApgRoI9PrVyXlHd9Uivk+B0B4WTKUgzkoHaVk4EkIUtNRQTpDWPciTlpb/C2tUYVejA==",
 375 |       "cpu": [
 376 |         "x64"
 377 |       ],
 378 |       "dev": true,
 379 |       "optional": true,
 380 |       "os": [
 381 |         "netbsd"
 382 |       ],
 383 |       "engines": {
 384 |         "node": ">=12"
 385 |       }
 386 |     },
 387 |     "node_modules/esbuild-openbsd-64": {
 388 |       "version": "0.14.45",
 389 |       "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.45.tgz",
 390 |       "integrity": "sha512-Z5sNcT3oN9eryMW3mGn5HAgg7XCxiUS4isqH1tZXpsdOdOESbgbTEP0mBEJU0WU7Vt2gIN5XMbAp7Oigm0k71g==",
 391 |       "cpu": [
 392 |         "x64"
 393 |       ],
 394 |       "dev": true,
 395 |       "optional": true,
 396 |       "os": [
 397 |         "openbsd"
 398 |       ],
 399 |       "engines": {
 400 |         "node": ">=12"
 401 |       }
 402 |     },
 403 |     "node_modules/esbuild-sunos-64": {
 404 |       "version": "0.14.45",
 405 |       "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.45.tgz",
 406 |       "integrity": "sha512-WmWu4wAm8mIxxK9aWFCj5VHunY3BHQDT3dAPexMLLszPyMF7RDtUYf+Dash9tjyitvnoxPAvR7DpWpirDLQIlQ==",
 407 |       "cpu": [
 408 |         "x64"
 409 |       ],
 410 |       "dev": true,
 411 |       "optional": true,
 412 |       "os": [
 413 |         "sunos"
 414 |       ],
 415 |       "engines": {
 416 |         "node": ">=12"
 417 |       }
 418 |     },
 419 |     "node_modules/esbuild-windows-32": {
 420 |       "version": "0.14.45",
 421 |       "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.45.tgz",
 422 |       "integrity": "sha512-DPPehKwPJFBoSG+jILc/vcJNN8pTwz1m6FWojxqtqPhgw8OabTgN4vL7gNMqL/FSeDxF+zyvZeeMrZFYF1d81Q==",
 423 |       "cpu": [
 424 |         "ia32"
 425 |       ],
 426 |       "dev": true,
 427 |       "optional": true,
 428 |       "os": [
 429 |         "win32"
 430 |       ],
 431 |       "engines": {
 432 |         "node": ">=12"
 433 |       }
 434 |     },
 435 |     "node_modules/esbuild-windows-64": {
 436 |       "version": "0.14.45",
 437 |       "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.45.tgz",
 438 |       "integrity": "sha512-t6bxFZcp9bLmSs+1pCNL/BW2bq3QEQHxU4HoiMEyWfF8QBU8iNXFI1iLGdyCzB1Ue2739h55tpOvojFrfyNPWA==",
 439 |       "cpu": [
 440 |         "x64"
 441 |       ],
 442 |       "dev": true,
 443 |       "optional": true,
 444 |       "os": [
 445 |         "win32"
 446 |       ],
 447 |       "engines": {
 448 |         "node": ">=12"
 449 |       }
 450 |     },
 451 |     "node_modules/esbuild-windows-arm64": {
 452 |       "version": "0.14.45",
 453 |       "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.45.tgz",
 454 |       "integrity": "sha512-DnhrvjECBJ2L0owoznPb4RqQKZ498SM8J+YHqmqzi0Gf/enkUwwTjB8vPCK6dDuFnNU/NE8f94FhKdkBHYruDQ==",
 455 |       "cpu": [
 456 |         "arm64"
 457 |       ],
 458 |       "dev": true,
 459 |       "optional": true,
 460 |       "os": [
 461 |         "win32"
 462 |       ],
 463 |       "engines": {
 464 |         "node": ">=12"
 465 |       }
 466 |     },
 467 |     "node_modules/estree-walker": {
 468 |       "version": "2.0.2",
 469 |       "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
 470 |       "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
 471 |       "dev": true
 472 |     },
 473 |     "node_modules/fill-range": {
 474 |       "version": "7.0.1",
 475 |       "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
 476 |       "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
 477 |       "dev": true,
 478 |       "dependencies": {
 479 |         "to-regex-range": "^5.0.1"
 480 |       },
 481 |       "engines": {
 482 |         "node": ">=8"
 483 |       }
 484 |     },
 485 |     "node_modules/fsevents": {
 486 |       "version": "2.3.2",
 487 |       "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
 488 |       "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
 489 |       "dev": true,
 490 |       "hasInstallScript": true,
 491 |       "optional": true,
 492 |       "os": [
 493 |         "darwin"
 494 |       ],
 495 |       "engines": {
 496 |         "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
 497 |       }
 498 |     },
 499 |     "node_modules/function-bind": {
 500 |       "version": "1.1.1",
 501 |       "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
 502 |       "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
 503 |       "dev": true
 504 |     },
 505 |     "node_modules/glob-parent": {
 506 |       "version": "5.1.2",
 507 |       "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
 508 |       "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
 509 |       "dev": true,
 510 |       "dependencies": {
 511 |         "is-glob": "^4.0.1"
 512 |       },
 513 |       "engines": {
 514 |         "node": ">= 6"
 515 |       }
 516 |     },
 517 |     "node_modules/has": {
 518 |       "version": "1.0.3",
 519 |       "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
 520 |       "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
 521 |       "dev": true,
 522 |       "dependencies": {
 523 |         "function-bind": "^1.1.1"
 524 |       },
 525 |       "engines": {
 526 |         "node": ">= 0.4.0"
 527 |       }
 528 |     },
 529 |     "node_modules/immutable": {
 530 |       "version": "4.1.0",
 531 |       "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz",
 532 |       "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==",
 533 |       "dev": true
 534 |     },
 535 |     "node_modules/is-binary-path": {
 536 |       "version": "2.1.0",
 537 |       "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
 538 |       "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
 539 |       "dev": true,
 540 |       "dependencies": {
 541 |         "binary-extensions": "^2.0.0"
 542 |       },
 543 |       "engines": {
 544 |         "node": ">=8"
 545 |       }
 546 |     },
 547 |     "node_modules/is-core-module": {
 548 |       "version": "2.9.0",
 549 |       "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz",
 550 |       "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==",
 551 |       "dev": true,
 552 |       "dependencies": {
 553 |         "has": "^1.0.3"
 554 |       },
 555 |       "funding": {
 556 |         "url": "https://github.com/sponsors/ljharb"
 557 |       }
 558 |     },
 559 |     "node_modules/is-extglob": {
 560 |       "version": "2.1.1",
 561 |       "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
 562 |       "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
 563 |       "dev": true,
 564 |       "engines": {
 565 |         "node": ">=0.10.0"
 566 |       }
 567 |     },
 568 |     "node_modules/is-glob": {
 569 |       "version": "4.0.3",
 570 |       "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
 571 |       "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
 572 |       "dev": true,
 573 |       "dependencies": {
 574 |         "is-extglob": "^2.1.1"
 575 |       },
 576 |       "engines": {
 577 |         "node": ">=0.10.0"
 578 |       }
 579 |     },
 580 |     "node_modules/is-number": {
 581 |       "version": "7.0.0",
 582 |       "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
 583 |       "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
 584 |       "dev": true,
 585 |       "engines": {
 586 |         "node": ">=0.12.0"
 587 |       }
 588 |     },
 589 |     "node_modules/lil-gui": {
 590 |       "version": "0.16.1",
 591 |       "resolved": "https://registry.npmjs.org/lil-gui/-/lil-gui-0.16.1.tgz",
 592 |       "integrity": "sha512-6wnnfBvQxJYRhdLyIA+w5b8utwbuVxNmtpTXElm36OSgHa8lyKp00Xz/4AEx3kvodT0AJYgbfadCFWAM0Q8DgQ=="
 593 |     },
 594 |     "node_modules/nanoid": {
 595 |       "version": "3.3.4",
 596 |       "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
 597 |       "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
 598 |       "dev": true,
 599 |       "bin": {
 600 |         "nanoid": "bin/nanoid.cjs"
 601 |       },
 602 |       "engines": {
 603 |         "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
 604 |       }
 605 |     },
 606 |     "node_modules/normalize-path": {
 607 |       "version": "3.0.0",
 608 |       "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
 609 |       "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
 610 |       "dev": true,
 611 |       "engines": {
 612 |         "node": ">=0.10.0"
 613 |       }
 614 |     },
 615 |     "node_modules/path-parse": {
 616 |       "version": "1.0.7",
 617 |       "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
 618 |       "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
 619 |       "dev": true
 620 |     },
 621 |     "node_modules/picocolors": {
 622 |       "version": "1.0.0",
 623 |       "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
 624 |       "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
 625 |       "dev": true
 626 |     },
 627 |     "node_modules/picomatch": {
 628 |       "version": "2.3.1",
 629 |       "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
 630 |       "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
 631 |       "dev": true,
 632 |       "engines": {
 633 |         "node": ">=8.6"
 634 |       },
 635 |       "funding": {
 636 |         "url": "https://github.com/sponsors/jonschlinkert"
 637 |       }
 638 |     },
 639 |     "node_modules/postcss": {
 640 |       "version": "8.4.14",
 641 |       "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz",
 642 |       "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==",
 643 |       "dev": true,
 644 |       "funding": [
 645 |         {
 646 |           "type": "opencollective",
 647 |           "url": "https://opencollective.com/postcss/"
 648 |         },
 649 |         {
 650 |           "type": "tidelift",
 651 |           "url": "https://tidelift.com/funding/github/npm/postcss"
 652 |         }
 653 |       ],
 654 |       "dependencies": {
 655 |         "nanoid": "^3.3.4",
 656 |         "picocolors": "^1.0.0",
 657 |         "source-map-js": "^1.0.2"
 658 |       },
 659 |       "engines": {
 660 |         "node": "^10 || ^12 || >=14"
 661 |       }
 662 |     },
 663 |     "node_modules/readdirp": {
 664 |       "version": "3.6.0",
 665 |       "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
 666 |       "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
 667 |       "dev": true,
 668 |       "dependencies": {
 669 |         "picomatch": "^2.2.1"
 670 |       },
 671 |       "engines": {
 672 |         "node": ">=8.10.0"
 673 |       }
 674 |     },
 675 |     "node_modules/resolve": {
 676 |       "version": "1.22.1",
 677 |       "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
 678 |       "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
 679 |       "dev": true,
 680 |       "dependencies": {
 681 |         "is-core-module": "^2.9.0",
 682 |         "path-parse": "^1.0.7",
 683 |         "supports-preserve-symlinks-flag": "^1.0.0"
 684 |       },
 685 |       "bin": {
 686 |         "resolve": "bin/resolve"
 687 |       },
 688 |       "funding": {
 689 |         "url": "https://github.com/sponsors/ljharb"
 690 |       }
 691 |     },
 692 |     "node_modules/rollup": {
 693 |       "version": "2.75.6",
 694 |       "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.75.6.tgz",
 695 |       "integrity": "sha512-OEf0TgpC9vU6WGROJIk1JA3LR5vk/yvqlzxqdrE2CzzXnqKXNzbAwlWUXis8RS3ZPe7LAq+YUxsRa0l3r27MLA==",
 696 |       "dev": true,
 697 |       "bin": {
 698 |         "rollup": "dist/bin/rollup"
 699 |       },
 700 |       "engines": {
 701 |         "node": ">=10.0.0"
 702 |       },
 703 |       "optionalDependencies": {
 704 |         "fsevents": "~2.3.2"
 705 |       }
 706 |     },
 707 |     "node_modules/sass": {
 708 |       "version": "1.52.3",
 709 |       "resolved": "https://registry.npmjs.org/sass/-/sass-1.52.3.tgz",
 710 |       "integrity": "sha512-LNNPJ9lafx+j1ArtA7GyEJm9eawXN8KlA1+5dF6IZyoONg1Tyo/g+muOsENWJH/2Q1FHbbV4UwliU0cXMa/VIA==",
 711 |       "dev": true,
 712 |       "dependencies": {
 713 |         "chokidar": ">=3.0.0 <4.0.0",
 714 |         "immutable": "^4.0.0",
 715 |         "source-map-js": ">=0.6.2 <2.0.0"
 716 |       },
 717 |       "bin": {
 718 |         "sass": "sass.js"
 719 |       },
 720 |       "engines": {
 721 |         "node": ">=12.0.0"
 722 |       }
 723 |     },
 724 |     "node_modules/source-map-js": {
 725 |       "version": "1.0.2",
 726 |       "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
 727 |       "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
 728 |       "dev": true,
 729 |       "engines": {
 730 |         "node": ">=0.10.0"
 731 |       }
 732 |     },
 733 |     "node_modules/supports-preserve-symlinks-flag": {
 734 |       "version": "1.0.0",
 735 |       "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
 736 |       "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
 737 |       "dev": true,
 738 |       "engines": {
 739 |         "node": ">= 0.4"
 740 |       },
 741 |       "funding": {
 742 |         "url": "https://github.com/sponsors/ljharb"
 743 |       }
 744 |     },
 745 |     "node_modules/three": {
 746 |       "version": "0.141.0",
 747 |       "resolved": "https://registry.npmjs.org/three/-/three-0.141.0.tgz",
 748 |       "integrity": "sha512-JaSDAPWuk4RTzG5BYRQm8YZbERUxTfTDVouWgHMisS2to4E5fotMS9F2zPFNOIJyEFTTQDDKPpsgZVThKU3pXA=="
 749 |     },
 750 |     "node_modules/to-regex-range": {
 751 |       "version": "5.0.1",
 752 |       "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
 753 |       "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
 754 |       "dev": true,
 755 |       "dependencies": {
 756 |         "is-number": "^7.0.0"
 757 |       },
 758 |       "engines": {
 759 |         "node": ">=8.0"
 760 |       }
 761 |     },
 762 |     "node_modules/tslib": {
 763 |       "version": "2.4.0",
 764 |       "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
 765 |       "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
 766 |       "dev": true
 767 |     },
 768 |     "node_modules/typescript": {
 769 |       "version": "4.7.4",
 770 |       "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
 771 |       "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
 772 |       "dev": true,
 773 |       "bin": {
 774 |         "tsc": "bin/tsc",
 775 |         "tsserver": "bin/tsserver"
 776 |       },
 777 |       "engines": {
 778 |         "node": ">=4.2.0"
 779 |       }
 780 |     },
 781 |     "node_modules/vite": {
 782 |       "version": "2.9.12",
 783 |       "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.12.tgz",
 784 |       "integrity": "sha512-suxC36dQo9Rq1qMB2qiRorNJtJAdxguu5TMvBHOc/F370KvqAe9t48vYp+/TbPKRNrMh/J55tOUmkuIqstZaew==",
 785 |       "dev": true,
 786 |       "dependencies": {
 787 |         "esbuild": "^0.14.27",
 788 |         "postcss": "^8.4.13",
 789 |         "resolve": "^1.22.0",
 790 |         "rollup": "^2.59.0"
 791 |       },
 792 |       "bin": {
 793 |         "vite": "bin/vite.js"
 794 |       },
 795 |       "engines": {
 796 |         "node": ">=12.2.0"
 797 |       },
 798 |       "optionalDependencies": {
 799 |         "fsevents": "~2.3.2"
 800 |       },
 801 |       "peerDependencies": {
 802 |         "less": "*",
 803 |         "sass": "*",
 804 |         "stylus": "*"
 805 |       },
 806 |       "peerDependenciesMeta": {
 807 |         "less": {
 808 |           "optional": true
 809 |         },
 810 |         "sass": {
 811 |           "optional": true
 812 |         },
 813 |         "stylus": {
 814 |           "optional": true
 815 |         }
 816 |       }
 817 |     },
 818 |     "node_modules/vite-plugin-glsl": {
 819 |       "version": "0.1.5",
 820 |       "resolved": "https://registry.npmjs.org/vite-plugin-glsl/-/vite-plugin-glsl-0.1.5.tgz",
 821 |       "integrity": "sha512-BsY0ndZthCXYipF/rc/Vri0s6N/JNwMyCDRJx7qiJNNY8+MiDgzhT2iOIHL7O7v3CvjOG9yOM2+WVTNvnHGT1w==",
 822 |       "dev": true,
 823 |       "dependencies": {
 824 |         "@rollup/pluginutils": "^4.2.1",
 825 |         "tslib": "^2.4.0"
 826 |       },
 827 |       "engines": {
 828 |         "node": ">= 14.17.0",
 829 |         "npm": ">= 6.14.13"
 830 |       }
 831 |     }
 832 |   },
 833 |   "dependencies": {
 834 |     "@rollup/pluginutils": {
 835 |       "version": "4.2.1",
 836 |       "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz",
 837 |       "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==",
 838 |       "dev": true,
 839 |       "requires": {
 840 |         "estree-walker": "^2.0.1",
 841 |         "picomatch": "^2.2.2"
 842 |       }
 843 |     },
 844 |     "@types/three": {
 845 |       "version": "0.141.0",
 846 |       "resolved": "https://registry.npmjs.org/@types/three/-/three-0.141.0.tgz",
 847 |       "integrity": "sha512-OJdKDgTPVBUgc+s74DYoy4aLznbFFC38Xm4ElmU1YwGNgR7GGFVvFCX7lpVgOsT6S1zSJtGdajTsOYE8/xY9nA==",
 848 |       "dev": true,
 849 |       "requires": {
 850 |         "@types/webxr": "*"
 851 |       }
 852 |     },
 853 |     "@types/webxr": {
 854 |       "version": "0.4.0",
 855 |       "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.4.0.tgz",
 856 |       "integrity": "sha512-LQvrACV3Pj17GpkwHwXuTd733gfY+D7b9mKdrTmLdO7vo7P/o6209Qqtk63y/FCv/lspdmi0pWz6Qe/ull9kQg==",
 857 |       "dev": true
 858 |     },
 859 |     "anymatch": {
 860 |       "version": "3.1.2",
 861 |       "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
 862 |       "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
 863 |       "dev": true,
 864 |       "requires": {
 865 |         "normalize-path": "^3.0.0",
 866 |         "picomatch": "^2.0.4"
 867 |       }
 868 |     },
 869 |     "binary-extensions": {
 870 |       "version": "2.2.0",
 871 |       "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
 872 |       "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
 873 |       "dev": true
 874 |     },
 875 |     "braces": {
 876 |       "version": "3.0.2",
 877 |       "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
 878 |       "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
 879 |       "dev": true,
 880 |       "requires": {
 881 |         "fill-range": "^7.0.1"
 882 |       }
 883 |     },
 884 |     "chokidar": {
 885 |       "version": "3.5.3",
 886 |       "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
 887 |       "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
 888 |       "dev": true,
 889 |       "requires": {
 890 |         "anymatch": "~3.1.2",
 891 |         "braces": "~3.0.2",
 892 |         "fsevents": "~2.3.2",
 893 |         "glob-parent": "~5.1.2",
 894 |         "is-binary-path": "~2.1.0",
 895 |         "is-glob": "~4.0.1",
 896 |         "normalize-path": "~3.0.0",
 897 |         "readdirp": "~3.6.0"
 898 |       }
 899 |     },
 900 |     "esbuild": {
 901 |       "version": "0.14.45",
 902 |       "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.45.tgz",
 903 |       "integrity": "sha512-JOxGUD8jcs8xE8DjyGWC8by/vLMCXTJ/wuauWipL5kJRZx1dhpqIntb31QHjA45GZJWaXv7SjC/Zwu1bCkXWtQ==",
 904 |       "dev": true,
 905 |       "requires": {
 906 |         "esbuild-android-64": "0.14.45",
 907 |         "esbuild-android-arm64": "0.14.45",
 908 |         "esbuild-darwin-64": "0.14.45",
 909 |         "esbuild-darwin-arm64": "0.14.45",
 910 |         "esbuild-freebsd-64": "0.14.45",
 911 |         "esbuild-freebsd-arm64": "0.14.45",
 912 |         "esbuild-linux-32": "0.14.45",
 913 |         "esbuild-linux-64": "0.14.45",
 914 |         "esbuild-linux-arm": "0.14.45",
 915 |         "esbuild-linux-arm64": "0.14.45",
 916 |         "esbuild-linux-mips64le": "0.14.45",
 917 |         "esbuild-linux-ppc64le": "0.14.45",
 918 |         "esbuild-linux-riscv64": "0.14.45",
 919 |         "esbuild-linux-s390x": "0.14.45",
 920 |         "esbuild-netbsd-64": "0.14.45",
 921 |         "esbuild-openbsd-64": "0.14.45",
 922 |         "esbuild-sunos-64": "0.14.45",
 923 |         "esbuild-windows-32": "0.14.45",
 924 |         "esbuild-windows-64": "0.14.45",
 925 |         "esbuild-windows-arm64": "0.14.45"
 926 |       }
 927 |     },
 928 |     "esbuild-android-64": {
 929 |       "version": "0.14.45",
 930 |       "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.45.tgz",
 931 |       "integrity": "sha512-krVmwL2uXQN1A+Ci4u2MR+Y0IAvQK0u3no5TsgguHVhTy138szjuohScCGjkpvLCpGLk7P4kFP1LKuntvJ0d4A==",
 932 |       "dev": true,
 933 |       "optional": true
 934 |     },
 935 |     "esbuild-android-arm64": {
 936 |       "version": "0.14.45",
 937 |       "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.45.tgz",
 938 |       "integrity": "sha512-62POGdzAjM+XOXEM5MmFW6k9Pjdjg1hTrXKKBbPE700LFF36B+1Jv9QkskT5UadbTk4cdH9BQ7bGiRPYY0p/Dw==",
 939 |       "dev": true,
 940 |       "optional": true
 941 |     },
 942 |     "esbuild-darwin-64": {
 943 |       "version": "0.14.45",
 944 |       "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.45.tgz",
 945 |       "integrity": "sha512-dbkVUAnGx5IeZesWnIhnvxy7dSvgUQvfy0TVLzd9XVP3oI/VsKs8UNsfPrxI5HiN4SINv7oPAbxWceMpB7IqNA==",
 946 |       "dev": true,
 947 |       "optional": true
 948 |     },
 949 |     "esbuild-darwin-arm64": {
 950 |       "version": "0.14.45",
 951 |       "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.45.tgz",
 952 |       "integrity": "sha512-O6Bz7nnOae5rvbh2Ueo8ibSr7+/eLjsbPdgeMsAZri+LkOa7nsVPnhmocpO3Hy/LWfagTtHy1O9HRPIaArPmTg==",
 953 |       "dev": true,
 954 |       "optional": true
 955 |     },
 956 |     "esbuild-freebsd-64": {
 957 |       "version": "0.14.45",
 958 |       "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.45.tgz",
 959 |       "integrity": "sha512-y1X2nr3XSWnDC7MRcy21EVAT0TiCtdefOntJ+SQcZnPBTURzX77f99S8lDF2KswukChkiacpd2Wd4VZieo7w7Q==",
 960 |       "dev": true,
 961 |       "optional": true
 962 |     },
 963 |     "esbuild-freebsd-arm64": {
 964 |       "version": "0.14.45",
 965 |       "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.45.tgz",
 966 |       "integrity": "sha512-r3ZNejkx1BKXQ6sYOP6C5rTwgiUajyAh03wygLWZtl+SLyygvAnu+OouqtveesufjBDgujp4wZXP/n8PVqXkqg==",
 967 |       "dev": true,
 968 |       "optional": true
 969 |     },
 970 |     "esbuild-linux-32": {
 971 |       "version": "0.14.45",
 972 |       "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.45.tgz",
 973 |       "integrity": "sha512-Qk9cCO3PJig/Y+SdslN/Th4pbAjgaH9oUjVH28eMsLTPf6QDUuK6EED91jepJdR3vxhcnVjyl6JqtOWmP+uxCg==",
 974 |       "dev": true,
 975 |       "optional": true
 976 |     },
 977 |     "esbuild-linux-64": {
 978 |       "version": "0.14.45",
 979 |       "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.45.tgz",
 980 |       "integrity": "sha512-IybO2ugqvc/Zzn1Kih3x0FVjYAy3GTCwhtcp91dbdqk3wPqxYCzObYspa8ca0s+OovI0Cnb+rhXrUtq8gBqlqw==",
 981 |       "dev": true,
 982 |       "optional": true
 983 |     },
 984 |     "esbuild-linux-arm": {
 985 |       "version": "0.14.45",
 986 |       "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.45.tgz",
 987 |       "integrity": "sha512-qKWJ4A4TAcxXV2TBLPw3Av5X2SYNfyNnBHNJTQJ5VuevK6Aq5i6XEMvUgdlcVuZ9MYPfS5aJZWglzDzJMf1Lpw==",
 988 |       "dev": true,
 989 |       "optional": true
 990 |     },
 991 |     "esbuild-linux-arm64": {
 992 |       "version": "0.14.45",
 993 |       "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.45.tgz",
 994 |       "integrity": "sha512-UNEyuHTwztrkEU/+mWIxGzKrYBo2cEtjYAZQVZB1kliANKgRITktg2miaO/b/VtNe84ob1aXSvW8XOPEn5RTGQ==",
 995 |       "dev": true,
 996 |       "optional": true
 997 |     },
 998 |     "esbuild-linux-mips64le": {
 999 |       "version": "0.14.45",
1000 |       "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.45.tgz",
1001 |       "integrity": "sha512-s/jcfw3Vpku5dIVSFVY7idJsGdIpIJ88IrkyprVgCG2yBeXatb67B7yIt0E1tL+OHrJJdNBw6GikCiMPAAu1VA==",
1002 |       "dev": true,
1003 |       "optional": true
1004 |     },
1005 |     "esbuild-linux-ppc64le": {
1006 |       "version": "0.14.45",
1007 |       "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.45.tgz",
1008 |       "integrity": "sha512-lJItl6ESZnhSx951U9R7MTBopgwIELHlQzC6SBR023V5JC1rPRFDZ/UEBsV+7BFcCAfqlyb+odGEAmcBSf4XCA==",
1009 |       "dev": true,
1010 |       "optional": true
1011 |     },
1012 |     "esbuild-linux-riscv64": {
1013 |       "version": "0.14.45",
1014 |       "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.45.tgz",
1015 |       "integrity": "sha512-8anMu+QLl9MununVCGJN2I/JvUWPm1EVsBBLq/J+Nz4hr8t6QOCuEp0HRaeMohyl2XiMFBchVu0mwa05rF7GFQ==",
1016 |       "dev": true,
1017 |       "optional": true
1018 |     },
1019 |     "esbuild-linux-s390x": {
1020 |       "version": "0.14.45",
1021 |       "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.45.tgz",
1022 |       "integrity": "sha512-1TPeNvNCoahMw745KNTA6POKaFfSqQrBb3fdOL82GXZqyKU/6rHNwGP0NgHe88bAUMp3QZfjGfCGKxfBHL77RQ==",
1023 |       "dev": true,
1024 |       "optional": true
1025 |     },
1026 |     "esbuild-netbsd-64": {
1027 |       "version": "0.14.45",
1028 |       "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.45.tgz",
1029 |       "integrity": "sha512-55f2eZ8EQhhOZosqX0mApgRoI9PrVyXlHd9Uivk+B0B4WTKUgzkoHaVk4EkIUtNRQTpDWPciTlpb/C2tUYVejA==",
1030 |       "dev": true,
1031 |       "optional": true
1032 |     },
1033 |     "esbuild-openbsd-64": {
1034 |       "version": "0.14.45",
1035 |       "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.45.tgz",
1036 |       "integrity": "sha512-Z5sNcT3oN9eryMW3mGn5HAgg7XCxiUS4isqH1tZXpsdOdOESbgbTEP0mBEJU0WU7Vt2gIN5XMbAp7Oigm0k71g==",
1037 |       "dev": true,
1038 |       "optional": true
1039 |     },
1040 |     "esbuild-sunos-64": {
1041 |       "version": "0.14.45",
1042 |       "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.45.tgz",
1043 |       "integrity": "sha512-WmWu4wAm8mIxxK9aWFCj5VHunY3BHQDT3dAPexMLLszPyMF7RDtUYf+Dash9tjyitvnoxPAvR7DpWpirDLQIlQ==",
1044 |       "dev": true,
1045 |       "optional": true
1046 |     },
1047 |     "esbuild-windows-32": {
1048 |       "version": "0.14.45",
1049 |       "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.45.tgz",
1050 |       "integrity": "sha512-DPPehKwPJFBoSG+jILc/vcJNN8pTwz1m6FWojxqtqPhgw8OabTgN4vL7gNMqL/FSeDxF+zyvZeeMrZFYF1d81Q==",
1051 |       "dev": true,
1052 |       "optional": true
1053 |     },
1054 |     "esbuild-windows-64": {
1055 |       "version": "0.14.45",
1056 |       "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.45.tgz",
1057 |       "integrity": "sha512-t6bxFZcp9bLmSs+1pCNL/BW2bq3QEQHxU4HoiMEyWfF8QBU8iNXFI1iLGdyCzB1Ue2739h55tpOvojFrfyNPWA==",
1058 |       "dev": true,
1059 |       "optional": true
1060 |     },
1061 |     "esbuild-windows-arm64": {
1062 |       "version": "0.14.45",
1063 |       "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.45.tgz",
1064 |       "integrity": "sha512-DnhrvjECBJ2L0owoznPb4RqQKZ498SM8J+YHqmqzi0Gf/enkUwwTjB8vPCK6dDuFnNU/NE8f94FhKdkBHYruDQ==",
1065 |       "dev": true,
1066 |       "optional": true
1067 |     },
1068 |     "estree-walker": {
1069 |       "version": "2.0.2",
1070 |       "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
1071 |       "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
1072 |       "dev": true
1073 |     },
1074 |     "fill-range": {
1075 |       "version": "7.0.1",
1076 |       "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
1077 |       "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
1078 |       "dev": true,
1079 |       "requires": {
1080 |         "to-regex-range": "^5.0.1"
1081 |       }
1082 |     },
1083 |     "fsevents": {
1084 |       "version": "2.3.2",
1085 |       "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
1086 |       "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
1087 |       "dev": true,
1088 |       "optional": true
1089 |     },
1090 |     "function-bind": {
1091 |       "version": "1.1.1",
1092 |       "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
1093 |       "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
1094 |       "dev": true
1095 |     },
1096 |     "glob-parent": {
1097 |       "version": "5.1.2",
1098 |       "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
1099 |       "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
1100 |       "dev": true,
1101 |       "requires": {
1102 |         "is-glob": "^4.0.1"
1103 |       }
1104 |     },
1105 |     "has": {
1106 |       "version": "1.0.3",
1107 |       "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
1108 |       "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
1109 |       "dev": true,
1110 |       "requires": {
1111 |         "function-bind": "^1.1.1"
1112 |       }
1113 |     },
1114 |     "immutable": {
1115 |       "version": "4.1.0",
1116 |       "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz",
1117 |       "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==",
1118 |       "dev": true
1119 |     },
1120 |     "is-binary-path": {
1121 |       "version": "2.1.0",
1122 |       "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
1123 |       "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
1124 |       "dev": true,
1125 |       "requires": {
1126 |         "binary-extensions": "^2.0.0"
1127 |       }
1128 |     },
1129 |     "is-core-module": {
1130 |       "version": "2.9.0",
1131 |       "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz",
1132 |       "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==",
1133 |       "dev": true,
1134 |       "requires": {
1135 |         "has": "^1.0.3"
1136 |       }
1137 |     },
1138 |     "is-extglob": {
1139 |       "version": "2.1.1",
1140 |       "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
1141 |       "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
1142 |       "dev": true
1143 |     },
1144 |     "is-glob": {
1145 |       "version": "4.0.3",
1146 |       "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
1147 |       "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
1148 |       "dev": true,
1149 |       "requires": {
1150 |         "is-extglob": "^2.1.1"
1151 |       }
1152 |     },
1153 |     "is-number": {
1154 |       "version": "7.0.0",
1155 |       "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
1156 |       "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
1157 |       "dev": true
1158 |     },
1159 |     "lil-gui": {
1160 |       "version": "0.16.1",
1161 |       "resolved": "https://registry.npmjs.org/lil-gui/-/lil-gui-0.16.1.tgz",
1162 |       "integrity": "sha512-6wnnfBvQxJYRhdLyIA+w5b8utwbuVxNmtpTXElm36OSgHa8lyKp00Xz/4AEx3kvodT0AJYgbfadCFWAM0Q8DgQ=="
1163 |     },
1164 |     "nanoid": {
1165 |       "version": "3.3.4",
1166 |       "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
1167 |       "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
1168 |       "dev": true
1169 |     },
1170 |     "normalize-path": {
1171 |       "version": "3.0.0",
1172 |       "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
1173 |       "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
1174 |       "dev": true
1175 |     },
1176 |     "path-parse": {
1177 |       "version": "1.0.7",
1178 |       "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
1179 |       "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
1180 |       "dev": true
1181 |     },
1182 |     "picocolors": {
1183 |       "version": "1.0.0",
1184 |       "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
1185 |       "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
1186 |       "dev": true
1187 |     },
1188 |     "picomatch": {
1189 |       "version": "2.3.1",
1190 |       "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
1191 |       "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
1192 |       "dev": true
1193 |     },
1194 |     "postcss": {
1195 |       "version": "8.4.14",
1196 |       "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz",
1197 |       "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==",
1198 |       "dev": true,
1199 |       "requires": {
1200 |         "nanoid": "^3.3.4",
1201 |         "picocolors": "^1.0.0",
1202 |         "source-map-js": "^1.0.2"
1203 |       }
1204 |     },
1205 |     "readdirp": {
1206 |       "version": "3.6.0",
1207 |       "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
1208 |       "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
1209 |       "dev": true,
1210 |       "requires": {
1211 |         "picomatch": "^2.2.1"
1212 |       }
1213 |     },
1214 |     "resolve": {
1215 |       "version": "1.22.1",
1216 |       "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
1217 |       "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
1218 |       "dev": true,
1219 |       "requires": {
1220 |         "is-core-module": "^2.9.0",
1221 |         "path-parse": "^1.0.7",
1222 |         "supports-preserve-symlinks-flag": "^1.0.0"
1223 |       }
1224 |     },
1225 |     "rollup": {
1226 |       "version": "2.75.6",
1227 |       "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.75.6.tgz",
1228 |       "integrity": "sha512-OEf0TgpC9vU6WGROJIk1JA3LR5vk/yvqlzxqdrE2CzzXnqKXNzbAwlWUXis8RS3ZPe7LAq+YUxsRa0l3r27MLA==",
1229 |       "dev": true,
1230 |       "requires": {
1231 |         "fsevents": "~2.3.2"
1232 |       }
1233 |     },
1234 |     "sass": {
1235 |       "version": "1.52.3",
1236 |       "resolved": "https://registry.npmjs.org/sass/-/sass-1.52.3.tgz",
1237 |       "integrity": "sha512-LNNPJ9lafx+j1ArtA7GyEJm9eawXN8KlA1+5dF6IZyoONg1Tyo/g+muOsENWJH/2Q1FHbbV4UwliU0cXMa/VIA==",
1238 |       "dev": true,
1239 |       "requires": {
1240 |         "chokidar": ">=3.0.0 <4.0.0",
1241 |         "immutable": "^4.0.0",
1242 |         "source-map-js": ">=0.6.2 <2.0.0"
1243 |       }
1244 |     },
1245 |     "source-map-js": {
1246 |       "version": "1.0.2",
1247 |       "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
1248 |       "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
1249 |       "dev": true
1250 |     },
1251 |     "supports-preserve-symlinks-flag": {
1252 |       "version": "1.0.0",
1253 |       "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
1254 |       "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
1255 |       "dev": true
1256 |     },
1257 |     "three": {
1258 |       "version": "0.141.0",
1259 |       "resolved": "https://registry.npmjs.org/three/-/three-0.141.0.tgz",
1260 |       "integrity": "sha512-JaSDAPWuk4RTzG5BYRQm8YZbERUxTfTDVouWgHMisS2to4E5fotMS9F2zPFNOIJyEFTTQDDKPpsgZVThKU3pXA=="
1261 |     },
1262 |     "to-regex-range": {
1263 |       "version": "5.0.1",
1264 |       "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
1265 |       "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
1266 |       "dev": true,
1267 |       "requires": {
1268 |         "is-number": "^7.0.0"
1269 |       }
1270 |     },
1271 |     "tslib": {
1272 |       "version": "2.4.0",
1273 |       "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
1274 |       "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
1275 |       "dev": true
1276 |     },
1277 |     "typescript": {
1278 |       "version": "4.7.4",
1279 |       "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
1280 |       "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
1281 |       "dev": true
1282 |     },
1283 |     "vite": {
1284 |       "version": "2.9.12",
1285 |       "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.12.tgz",
1286 |       "integrity": "sha512-suxC36dQo9Rq1qMB2qiRorNJtJAdxguu5TMvBHOc/F370KvqAe9t48vYp+/TbPKRNrMh/J55tOUmkuIqstZaew==",
1287 |       "dev": true,
1288 |       "requires": {
1289 |         "esbuild": "^0.14.27",
1290 |         "fsevents": "~2.3.2",
1291 |         "postcss": "^8.4.13",
1292 |         "resolve": "^1.22.0",
1293 |         "rollup": "^2.59.0"
1294 |       }
1295 |     },
1296 |     "vite-plugin-glsl": {
1297 |       "version": "0.1.5",
1298 |       "resolved": "https://registry.npmjs.org/vite-plugin-glsl/-/vite-plugin-glsl-0.1.5.tgz",
1299 |       "integrity": "sha512-BsY0ndZthCXYipF/rc/Vri0s6N/JNwMyCDRJx7qiJNNY8+MiDgzhT2iOIHL7O7v3CvjOG9yOM2+WVTNvnHGT1w==",
1300 |       "dev": true,
1301 |       "requires": {
1302 |         "@rollup/pluginutils": "^4.2.1",
1303 |         "tslib": "^2.4.0"
1304 |       }
1305 |     }
1306 |   }
1307 | }
1308 | 
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "name": "simple-threejs-typescript-starter",
 3 |   "version": "0.1.0",
 4 |   "description": "Simple starter for Three.js projects with TypeScript",
 5 |   "main": "index.html",
 6 |   "repository": "https://github.com/mayacoda/simple-threejs-typescript-starter",
 7 |   "author": "Maya Nedeljković Batić",
 8 |   "license": "MIT",
 9 |   "scripts": {
10 |     "dev": "vite",
11 |     "build": "tsc && vite build",
12 |     "preview": "vite preview",
13 |     "cleanup": "node ./scripts/cleanup.js",
14 |     "prepare": "husky install"
15 |   },
16 |   "type": "module",
17 |   "dependencies": {
18 |     "lil-gui": "^0.18.1",
19 |     "three": "^0.151.3"
20 |   },
21 |   "devDependencies": {
22 |     "@types/three": "^0.150.2",
23 |     "husky": "^8.0.3",
24 |     "lint-staged": "^13.2.1",
25 |     "prettier": "2.8.7",
26 |     "sass": "^1.62.0",
27 |     "typescript": "^5.0.4",
28 |     "vite": "^4.2.2",
29 |     "vite-plugin-glsl": "^1.1.2"
30 |   },
31 |   "packageManager": "yarn@3.2.1",
32 |   "lint-staged": {
33 |     "**/*": "prettier --write --ignore-unknown"
34 |   }
35 | }
36 | 
--------------------------------------------------------------------------------
/public/models/tentacle.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mayacoda/toon-shader/760b0f338bcf8d01743690aeb23580c07a3afd86/public/models/tentacle.glb
--------------------------------------------------------------------------------
/scripts/cleanup.js:
--------------------------------------------------------------------------------
 1 | import * as fs from 'fs'
 2 | 
 3 | // remove src/demo directory
 4 | fs.rm('./src/demo', { recursive: true }, () => {})
 5 | 
 6 | // remove public/space_dog directory
 7 | fs.rm('./public/space_dog', { recursive: true }, () => {})
 8 | 
 9 | fs.rm('./assets/docs', { recursive: true }, () => {})
10 | 
11 | // rewrite src/main.ts to only include the style import
12 | fs.writeFileSync(
13 |   './src/main.ts',
14 |   `import './style.scss'
15 | import { Engine } from './engine/Engine'
16 | import { Experience } from './engine/Experience'
17 | 
18 | new Engine({
19 |   canvas: document.querySelector('#canvas') as HTMLCanvasElement,
20 |   experience: class implements Experience {
21 |     resources = []
22 |     init() {}
23 |     update() {}
24 |     resize() {}
25 |   }
26 | })`
27 | )
28 | 
29 | fs.writeFileSync(
30 |   './README.md',
31 |   `# Simple Three.js + TypeScript + Vite Starter
32 |   
33 | Local development:
34 | \`\`\`bash
35 | yarn
36 | yarn dev
37 | \`\`\`
38 | `
39 | )
40 | 
41 | console.log('🧹 Repo cleaned up')
42 | 
--------------------------------------------------------------------------------
/src/engine/Camera.ts:
--------------------------------------------------------------------------------
 1 | import { Engine } from './Engine'
 2 | import * as THREE from 'three'
 3 | import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
 4 | import { GameEntity } from './GameEntity'
 5 | 
 6 | export class Camera implements GameEntity {
 7 |   public instance!: THREE.PerspectiveCamera
 8 |   private controls!: OrbitControls
 9 | 
10 |   constructor(private engine: Engine) {
11 |     this.initCamera()
12 |     this.initControls()
13 |   }
14 | 
15 |   private initCamera() {
16 |     this.instance = new THREE.PerspectiveCamera(
17 |       75,
18 |       window.innerWidth / window.innerHeight,
19 |       0.1,
20 |       1000
21 |     )
22 |     this.instance.position.z = 3
23 |     this.instance.position.y = 1
24 |     this.engine.scene.add(this.instance)
25 |   }
26 | 
27 |   private initControls() {
28 |     this.controls = new OrbitControls(this.instance, this.engine.canvas)
29 |     this.controls.update()
30 |   }
31 | 
32 |   resize() {
33 |     this.instance.aspect = this.engine.sizes.aspectRatio
34 |     this.instance.updateProjectionMatrix()
35 |   }
36 | 
37 |   update() {
38 |     this.controls.update()
39 |   }
40 | }
41 | 
--------------------------------------------------------------------------------
/src/engine/Engine.ts:
--------------------------------------------------------------------------------
 1 | import * as THREE from 'three'
 2 | import { RenderEngine } from './RenderEngine'
 3 | import { RenderLoop } from './RenderLoop'
 4 | import { DebugUI } from './interface/DebugUI'
 5 | import { Sizes } from './Sizes'
 6 | import { Camera } from './Camera'
 7 | import { Resources } from './Resources'
 8 | import { InfoConfig, InfoUI } from './interface/InfoUI'
 9 | import { Experience, ExperienceConstructor } from './Experience'
10 | import { Loader } from './interface/Loader'
11 | 
12 | export class Engine {
13 |   public readonly camera!: Camera
14 |   public readonly scene!: THREE.Scene
15 |   public readonly renderEngine!: RenderEngine
16 |   public readonly time!: RenderLoop
17 |   public readonly debug!: DebugUI
18 |   public readonly infoUI!: InfoUI
19 |   public readonly sizes!: Sizes
20 |   public readonly canvas!: HTMLCanvasElement
21 |   public readonly resources!: Resources
22 |   public readonly experience!: Experience
23 |   private readonly loader!: Loader
24 | 
25 |   constructor({
26 |     canvas,
27 |     experience,
28 |     info,
29 |   }: {
30 |     canvas: HTMLCanvasElement
31 |     experience: ExperienceConstructor
32 |     info?: InfoConfig
33 |   }) {
34 |     if (!canvas) {
35 |       throw new Error('No canvas provided')
36 |     }
37 | 
38 |     this.canvas = canvas
39 |     this.sizes = new Sizes(this)
40 |     this.debug = new DebugUI()
41 |     this.time = new RenderLoop(this)
42 |     this.scene = new THREE.Scene()
43 |     this.camera = new Camera(this)
44 |     this.infoUI = new InfoUI(info)
45 |     this.renderEngine = new RenderEngine(this)
46 |     this.experience = new experience(this)
47 |     this.resources = new Resources(this.experience.resources)
48 |     this.loader = new Loader()
49 | 
50 |     this.resources.on('loaded', () => {
51 |       this.experience.init()
52 |       this.loader.complete()
53 |     })
54 | 
55 |     this.resources.on('progress', (progress: number) => {
56 |       this.loader.setProgress(progress)
57 |     })
58 |   }
59 | 
60 |   update(delta: number) {
61 |     this.camera.update()
62 |     this.renderEngine.update()
63 |     this.experience.update(delta)
64 |     this.debug.update()
65 |   }
66 | 
67 |   resize() {
68 |     this.camera.resize()
69 |     this.renderEngine.resize()
70 |     this.experience.resize()
71 |   }
72 | }
73 | 
--------------------------------------------------------------------------------
/src/engine/Experience.ts:
--------------------------------------------------------------------------------
 1 | import { GameEntity } from './GameEntity'
 2 | import { Engine } from './Engine'
 3 | import { Resource } from './Resources'
 4 | 
 5 | export type ExperienceConstructor = new (engine: Engine) => Experience
 6 | export interface Experience extends GameEntity {
 7 |   init(): void
 8 |   resources: Resource[]
 9 | }
10 | 
--------------------------------------------------------------------------------
/src/engine/GameEntity.ts:
--------------------------------------------------------------------------------
1 | export interface GameEntity {
2 |   update(delta: number): void
3 |   resize(): void
4 | }
5 | 
--------------------------------------------------------------------------------
/src/engine/RenderEngine.ts:
--------------------------------------------------------------------------------
 1 | import { WebGLRenderer } from 'three'
 2 | import { Engine } from './Engine'
 3 | import * as THREE from 'three'
 4 | import { GameEntity } from './GameEntity'
 5 | 
 6 | export class RenderEngine implements GameEntity {
 7 |   private readonly renderer: WebGLRenderer
 8 | 
 9 |   constructor(private engine: Engine) {
10 |     this.renderer = new WebGLRenderer({
11 |       canvas: this.engine.canvas,
12 |       antialias: true,
13 |     })
14 | 
15 |     this.renderer.physicallyCorrectLights = true
16 |     this.renderer.outputEncoding = THREE.sRGBEncoding
17 |     this.renderer.toneMapping = THREE.CineonToneMapping
18 |     this.renderer.toneMappingExposure = 1.75
19 |     this.renderer.shadowMap.enabled = true
20 |     this.renderer.shadowMap.type = THREE.PCFSoftShadowMap
21 |     this.renderer.setClearColor('#000000')
22 |     this.renderer.setSize(this.engine.sizes.width, this.engine.sizes.height)
23 |     this.renderer.setPixelRatio(Math.min(this.engine.sizes.pixelRatio, 2))
24 |   }
25 | 
26 |   update() {
27 |     this.renderer.render(this.engine.scene, this.engine.camera.instance)
28 |   }
29 | 
30 |   resize() {
31 |     this.renderer.setSize(this.engine.sizes.width, this.engine.sizes.height)
32 |   }
33 | }
34 | 
--------------------------------------------------------------------------------
/src/engine/RenderLoop.ts:
--------------------------------------------------------------------------------
 1 | import { Engine } from './Engine'
 2 | import * as THREE from 'three'
 3 | 
 4 | export class RenderLoop {
 5 |   private clock: THREE.Clock
 6 |   public deltaTime: number = 16
 7 |   public currentTime: number = 0
 8 | 
 9 |   constructor(private engine: Engine) {
10 |     this.clock = new THREE.Clock()
11 |     window.requestAnimationFrame(() => this.update())
12 |   }
13 | 
14 |   update() {
15 |     const step = () => {
16 |       requestAnimationFrame(step)
17 |       const elapsedTime = this.clock.getElapsedTime()
18 | 
19 |       this.deltaTime = elapsedTime - this.currentTime
20 | 
21 |       this.currentTime = elapsedTime
22 | 
23 |       this.engine.update(this.deltaTime)
24 |     }
25 |     step()
26 |   }
27 | }
28 | 
--------------------------------------------------------------------------------
/src/engine/Resources.ts:
--------------------------------------------------------------------------------
 1 | import * as THREE from 'three'
 2 | import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
 3 | import { EventEmitter } from './utilities/EventEmitter'
 4 | 
 5 | export type Resource =
 6 |   | {
 7 |       name: string
 8 |       type: Exclude
 9 |       path: string
10 |     }
11 |   | {
12 |       name: string
13 |       type: 'cubeTexture'
14 |       path: string[]
15 |     }
16 | 
17 | type AssetType = 'gltf' | 'texture' | 'cubeTexture'
18 | 
19 | type Loaders = {
20 |   gltf: GLTFLoader
21 |   texture: THREE.TextureLoader
22 |   cubeTexture: THREE.CubeTextureLoader
23 | }
24 | 
25 | export class Resources extends EventEmitter {
26 |   private loadingManager = new THREE.LoadingManager(
27 |     () => {
28 |       this.emit('loaded')
29 |     },
30 |     // @ts-ignore
31 |     (url: string, item: number, total: number) => {
32 |       this.emit('progress', item / total)
33 |     },
34 |     (url: string) => {
35 |       console.error(`Failed to load ${url}`)
36 |     }
37 |   )
38 |   private loaders!: Loaders
39 |   public items: Record = {}
40 | 
41 |   constructor(private readonly resources: Resource[]) {
42 |     super()
43 |     this.initLoaders()
44 |     this.load()
45 |   }
46 | 
47 |   private initLoaders() {
48 |     this.loaders = {
49 |       gltf: new GLTFLoader(this.loadingManager),
50 |       texture: new THREE.TextureLoader(this.loadingManager),
51 |       cubeTexture: new THREE.CubeTextureLoader(this.loadingManager),
52 |     }
53 |   }
54 | 
55 |   getItem(name: string) {
56 |     let item = this.items[name]
57 |     if (!item) {
58 |       throw new Error(`Resource ${name} not found`)
59 |     }
60 |     return item
61 |   }
62 | 
63 |   load() {
64 |     if (this.resources.length === 0) {
65 |       setTimeout(() => {
66 |         this.emit('loaded')
67 |       })
68 |     }
69 | 
70 |     for (const resource of this.resources) {
71 |       switch (resource.type) {
72 |         case 'gltf':
73 |           this.loaders.gltf.load(
74 |             resource.path,
75 |             (file) => (this.items[resource.name] = file)
76 |           )
77 |           break
78 |         case 'texture':
79 |           this.loaders.texture.load(
80 |             resource.path,
81 |             (file) => (this.items[resource.name] = file)
82 |           )
83 |           break
84 |         case 'cubeTexture':
85 |           this.loaders.cubeTexture.load(
86 |             resource.path,
87 |             (file) => (this.items[resource.name] = file)
88 |           )
89 |           break
90 |       }
91 |     }
92 |   }
93 | }
94 | 
--------------------------------------------------------------------------------
/src/engine/Sizes.ts:
--------------------------------------------------------------------------------
 1 | import { Engine } from './Engine'
 2 | import { EventEmitter } from './utilities/EventEmitter'
 3 | 
 4 | type Sizing = 'cover' | 'contain'
 5 | 
 6 | export class Sizes extends EventEmitter {
 7 |   public width!: number
 8 |   public height!: number
 9 |   public pixelRatio: number = Math.min(window.devicePixelRatio, 2)
10 |   public aspectRatio!: number
11 | 
12 |   public sizing: Sizing = 'contain'
13 | 
14 |   constructor(private engine: Engine) {
15 |     super()
16 |     this.setContainsSizing()
17 | 
18 |     window.addEventListener('resize', () => {
19 |       this.resize()
20 |       this.engine.resize()
21 |       this.emit('resize')
22 |     })
23 |   }
24 | 
25 |   public setContainsSizing() {
26 |     this.width = window.innerWidth
27 |     this.height = window.innerHeight
28 | 
29 |     this.aspectRatio = this.width / this.height
30 |   }
31 | 
32 |   public setCoverSizing() {
33 |     const maxWidth = window.innerWidth
34 |     const maxHeight = window.innerHeight
35 | 
36 |     if (maxWidth / maxHeight < this.aspectRatio) {
37 |       this.width = maxWidth
38 |       this.height = maxWidth / this.aspectRatio
39 |     } else {
40 |       this.width = maxHeight * this.aspectRatio
41 |       this.height = maxHeight
42 |     }
43 |   }
44 | 
45 |   setAspectRatio(aspectRatio: number) {
46 |     this.aspectRatio = aspectRatio
47 |   }
48 | 
49 |   setSizing(sizing: Sizing) {
50 |     this.sizing = sizing
51 | 
52 |     this.resize()
53 |   }
54 | 
55 |   resize() {
56 |     if (this.sizing === 'contain') {
57 |       this.setContainsSizing()
58 |     } else {
59 |       this.setCoverSizing()
60 |     }
61 |   }
62 | }
63 | 
--------------------------------------------------------------------------------
/src/engine/interface/DebugUI.ts:
--------------------------------------------------------------------------------
 1 | import * as lilGui from 'lil-gui'
 2 | import Stats from 'three/examples/jsm/libs/stats.module'
 3 | 
 4 | let instance: DebugUI | null = null
 5 | 
 6 | export class DebugUI {
 7 |   gui!: lilGui.GUI
 8 |   stats!: Stats
 9 | 
10 |   constructor() {
11 |     if (instance) {
12 |       return this
13 |     }
14 | 
15 |     instance = this
16 | 
17 |     this.stats = Stats()
18 |     document.body.appendChild(this.stats.dom)
19 | 
20 |     this.gui = new lilGui.GUI()
21 | 
22 |     if (!window.location.search.includes('debug')) {
23 |       this.gui.hide()
24 |       this.stats.dom.style.display = 'none'
25 |     }
26 | 
27 |     window.addEventListener('keydown', (event) => {
28 |       if (event.key === 'h') {
29 |         if (this.gui._hidden) {
30 |           this.gui.show()
31 |           this.stats.dom.style.display = 'block'
32 |         } else {
33 |           this.gui.hide()
34 |           this.stats.dom.style.display = 'none'
35 |         }
36 |       }
37 |     })
38 |   }
39 | 
40 |   update() {
41 |     this.stats.update()
42 |   }
43 | }
44 | 
--------------------------------------------------------------------------------
/src/engine/interface/InfoUI.ts:
--------------------------------------------------------------------------------
 1 | import './info.scss'
 2 | 
 3 | export type InfoConfig = {
 4 |   twitter?: string
 5 |   github?: string
 6 |   description?: string
 7 |   title?: string
 8 |   documentTitle?: string
 9 | }
10 | 
11 | export class InfoUI {
12 |   constructor(config: InfoConfig = {}) {
13 |     if (config.documentTitle) {
14 |       document.title = config.documentTitle
15 |     }
16 | 
17 |     const container = document.createElement('div')
18 |     container.classList.add('info-container')
19 |     container.insertAdjacentHTML(
20 |       'beforeend',
21 |       `
22 | ${config.title ? `${config.title}
` : ''}
23 | ${
24 |   config.description
25 |     ? `
26 |   
${config.description}
27 |  
 `
28 |     : ``
29 | }
30 | 
31 | ${
32 |   config.twitter
33 |     ? `
 
34 |     
35 |   `
36 |     : ``
37 | }
38 | ${
39 |   config.github
40 |     ? `
41 |     
42 |   `
43 |     : ``
44 | }
45 | 
 
46 |     `
47 |     )
48 |     document.body.prepend(container)
49 |   }
50 | }
51 | 
--------------------------------------------------------------------------------
/src/engine/interface/Loader.ts:
--------------------------------------------------------------------------------
 1 | import './loader.scss'
 2 | 
 3 | export class Loader {
 4 |   element: HTMLDivElement
 5 | 
 6 |   constructor() {
 7 |     this.element = document.createElement('div')
 8 |     this.element.classList.add('loader')
 9 |     this.element.insertAdjacentHTML(
10 |       'beforeend',
11 |       `
12 |         
16 |         `
17 |     )
18 | 
19 |     this.start()
20 |   }
21 | 
22 |   start() {
23 |     document.body.prepend(this.element)
24 |   }
25 | 
26 |   setProgress(progress: number) {
27 |     const progressNumber = this.element.querySelector(
28 |       '.progress-number'
29 |     ) as HTMLHeadingElement
30 | 
31 |     progressNumber!.innerText = `${Math.floor(progress * 100)}%`
32 | 
33 |     const progressBar = this.element.querySelector(
34 |       '.progress-bar'
35 |     ) as HTMLDivElement
36 | 
37 |     progressBar.style.width = `${progress * 100}%`
38 |   }
39 | 
40 |   complete() {
41 |     this.element.remove()
42 |   }
43 | }
44 | 
--------------------------------------------------------------------------------
/src/engine/interface/info.scss:
--------------------------------------------------------------------------------
 1 | .info-container {
 2 |   position: absolute;
 3 |   bottom: 0;
 4 |   left: 0;
 5 |   padding: 16px 20px;
 6 | 
 7 |   display: flex;
 8 |   flex-direction: column;
 9 | 
10 |   user-select: none;
11 |   opacity: 40%;
12 |   transition: opacity 0.3s ease-in-out;
13 | 
14 |   color: #fff;
15 |   font-family: 'Helvetica', 'Arial', sans-serif;
16 |   text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.8);
17 | 
18 |   &:hover {
19 |     opacity: 100%;
20 |   }
21 | 
22 |   h1 {
23 |     margin-bottom: 0;
24 |     font-weight: normal;
25 |   }
26 | 
27 |   .description {
28 |     width: 250px;
29 |     max-width: 100%;
30 |     margin-bottom: 4px;
31 |   }
32 | 
33 |   .social-container {
34 |     display: flex;
35 |     flex-direction: row;
36 |     justify-content: flex-start;
37 |     align-items: center;
38 |   }
39 | 
40 |   .social-button {
41 |     display: flex;
42 |     width: 24px;
43 |     height: 24px;
44 |     padding: 8px;
45 |     margin-right: 8px;
46 |     border-radius: 50px;
47 |     align-items: center;
48 | 
49 |     background: #fff;
50 |     transition: box-shadow 0.3s ease-in-out;
51 | 
52 |     &:hover {
53 |       box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
54 |     }
55 | 
56 |     img {
57 |       max-width: 100%;
58 |     }
59 |   }
60 | }
61 | 
--------------------------------------------------------------------------------
/src/engine/interface/loader.scss:
--------------------------------------------------------------------------------
 1 | .loader {
 2 |   width: 100%;
 3 |   height: 100%;
 4 |   display: flex;
 5 |   justify-content: center;
 6 |   align-items: center;
 7 | 
 8 |   color: #fff;
 9 |   font-family: 'Helvetica', 'Arial', sans-serif;
10 |   font-weight: normal;
11 | 
12 |   .loader-inner {
13 |     width: 500px;
14 |     max-width: 95%;
15 |   }
16 | 
17 |   .progress-number {
18 |     text-align: center;
19 |   }
20 | 
21 |   .progress-bar {
22 |     background-color: #fff;
23 |     transition: width 0.3s ease-in-out;
24 | 
25 |     height: 5px;
26 |   }
27 | }
28 | 
--------------------------------------------------------------------------------
/src/engine/utilities/EventEmitter.ts:
--------------------------------------------------------------------------------
 1 | export class EventEmitter {
 2 |   private listeners: { [key: string]: Function[] } = {}
 3 | 
 4 |   public on(event: string, listener: Function) {
 5 |     if (!this.listeners[event]) {
 6 |       this.listeners[event] = []
 7 |     }
 8 | 
 9 |     this.listeners[event].push(listener)
10 | 
11 |     return () => this.off(event, listener)
12 |   }
13 | 
14 |   public off(event: string, listener: Function) {
15 |     if (!this.listeners[event]) {
16 |       return
17 |     }
18 | 
19 |     const index = this.listeners[event].indexOf(listener)
20 | 
21 |     if (index === -1) {
22 |       return
23 |     }
24 | 
25 |     this.listeners[event].splice(index, 1)
26 |   }
27 | 
28 |   public emit(event: string, ...args: any[]) {
29 |     if (!this.listeners[event]) {
30 |       return
31 |     }
32 | 
33 |     this.listeners[event].forEach((listener) => listener(...args))
34 |   }
35 | }
36 | 
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
 1 | import './style.scss'
 2 | import { Engine } from './engine/Engine'
 3 | import { MainScene } from './toon-shader/MainScene'
 4 | 
 5 | new Engine({
 6 |   canvas: document.querySelector('#canvas') as HTMLCanvasElement,
 7 |   experience: MainScene,
 8 |   info: {
 9 |     title: 'Three.js Toon Shader',
10 |     documentTitle: 'Three.js Toon Shader',
11 |     description: 'GLSL Toon Shader with Three.js',
12 |     twitter: 'https://twitter.com/maya_ndljk',
13 |     github: 'https://github.com/mayacoda/toon-shader'
14 |   }
15 | })
16 | 
--------------------------------------------------------------------------------
/src/style.scss:
--------------------------------------------------------------------------------
 1 | html,
 2 | body,
 3 | #canvas {
 4 |   height: 100%;
 5 |   width: 100%;
 6 |   margin: 0;
 7 |   padding: 0;
 8 |   overflow: hidden;
 9 |   background: #000;
10 | }
11 | 
12 | #canvas {
13 |   outline: none;
14 | }
15 | 
--------------------------------------------------------------------------------
/src/toon-shader/Floor.ts:
--------------------------------------------------------------------------------
 1 | import * as THREE from 'three'
 2 | 
 3 | export class Floor extends THREE.Mesh {
 4 |   constructor() {
 5 |     super()
 6 |     this.geometry = new THREE.PlaneBufferGeometry(10, 10, 2)
 7 |     this.material = new THREE.MeshStandardMaterial({ color: '#7a7775' })
 8 |     this.receiveShadow = true
 9 | 
10 |     this.rotation.x = -Math.PI / 2
11 |   }
12 | }
13 | 
--------------------------------------------------------------------------------
/src/toon-shader/MainScene.ts:
--------------------------------------------------------------------------------
 1 | import { Experience } from '../engine/Experience'
 2 | import { Engine } from '../engine/Engine'
 3 | import { Floor } from './Floor'
 4 | import { Sphere } from './geometries/Sphere'
 5 | import * as THREE from 'three'
 6 | import { Knot } from './geometries/Knot'
 7 | import { Cylinder } from './geometries/Cylinder'
 8 | import { Tentacle } from './geometries/Tentacle'
 9 | 
10 | export class MainScene implements Experience {
11 |   constructor(private engine: Engine) {}
12 | 
13 |   resources = [Tentacle.resource]
14 | 
15 |   init() {
16 |     const floor = new Floor()
17 |     this.engine.scene.add(floor)
18 | 
19 |     const sphere = new Sphere()
20 |     this.engine.scene.add(sphere)
21 | 
22 |     const knot = new Knot()
23 |     knot.position.x = -1.25
24 |     this.engine.scene.add(knot)
25 | 
26 |     const cylinder = new Cylinder()
27 |     cylinder.position.x = 1.25
28 |     this.engine.scene.add(cylinder)
29 | 
30 |     const tentacle = new Tentacle(this.engine)
31 |     tentacle.position.z = -2.5
32 |     this.engine.scene.add(tentacle)
33 | 
34 |     const ambientLight = new THREE.AmbientLight('#ffffff', 1)
35 |     this.engine.scene.add(ambientLight)
36 | 
37 |     const directionalLight = new THREE.DirectionalLight('#f8f1e6', 0.5)
38 |     directionalLight.position.set(1, 1, 1)
39 |     directionalLight.castShadow = true
40 |     directionalLight.shadow.mapSize.width = 4096
41 |     directionalLight.shadow.mapSize.height = 4096
42 |     this.engine.scene.add(directionalLight)
43 |   }
44 | 
45 |   update() {}
46 | 
47 |   resize() {}
48 | }
49 | 
--------------------------------------------------------------------------------
/src/toon-shader/ToonShaderMaterial.ts:
--------------------------------------------------------------------------------
 1 | import * as THREE from 'three'
 2 | import toonVertexShader from './shaders/toon.vert'
 3 | import toonFragmentShader from './shaders/toon.frag'
 4 | 
 5 | export class ToonShaderMaterial extends THREE.ShaderMaterial {
 6 |   constructor({ color = '#fff' }: { color: string }) {
 7 |     super({
 8 |       lights: true,
 9 |       uniforms: {
10 |         ...THREE.UniformsLib.lights,
11 |         uGlossiness: {
12 |           value: 20,
13 |         },
14 |         uColor: {
15 |           value: new THREE.Color(color),
16 |         },
17 |       },
18 |     })
19 | 
20 |     this.vertexShader = toonVertexShader
21 |     this.fragmentShader = toonFragmentShader
22 |   }
23 | }
24 | 
--------------------------------------------------------------------------------
/src/toon-shader/geometries/Cylinder.ts:
--------------------------------------------------------------------------------
 1 | import * as THREE from 'three'
 2 | import { ToonShaderMaterial } from '../ToonShaderMaterial'
 3 | 
 4 | export class Cylinder extends THREE.Mesh {
 5 |   material: ToonShaderMaterial
 6 | 
 7 |   constructor() {
 8 |     super()
 9 | 
10 |     this.geometry = new THREE.CylinderBufferGeometry(0, 0.5, 1, 32, 8)
11 |     this.material = new ToonShaderMaterial({ color: '#6b8847' })
12 | 
13 |     this.castShadow = true
14 | 
15 |     this.position.y = 0.5
16 |   }
17 | }
18 | 
--------------------------------------------------------------------------------
/src/toon-shader/geometries/Knot.ts:
--------------------------------------------------------------------------------
 1 | import * as THREE from 'three'
 2 | import { ToonShaderMaterial } from '../ToonShaderMaterial'
 3 | 
 4 | export class Knot extends THREE.Mesh {
 5 |   material: ToonShaderMaterial
 6 | 
 7 |   constructor() {
 8 |     super()
 9 | 
10 |     this.geometry = new THREE.TorusKnotBufferGeometry(1, 0.4, 128, 64)
11 |     this.material = new ToonShaderMaterial({ color: '#a15218' })
12 | 
13 |     this.scale.setScalar(0.3)
14 | 
15 |     this.castShadow = true
16 | 
17 |     this.position.y = 0.5
18 |   }
19 | }
20 | 
--------------------------------------------------------------------------------
/src/toon-shader/geometries/Sphere.ts:
--------------------------------------------------------------------------------
 1 | import * as THREE from 'three'
 2 | import { ToonShaderMaterial } from '../ToonShaderMaterial'
 3 | 
 4 | export class Sphere extends THREE.Mesh {
 5 |   material: ToonShaderMaterial
 6 | 
 7 |   constructor() {
 8 |     super()
 9 | 
10 |     this.geometry = new THREE.SphereBufferGeometry(0.5, 64, 64)
11 |     this.material = new ToonShaderMaterial({ color: '#33d9c5' })
12 | 
13 |     this.castShadow = true
14 | 
15 |     this.position.y = 0.5
16 |   }
17 | }
18 | 
--------------------------------------------------------------------------------
/src/toon-shader/geometries/Tentacle.ts:
--------------------------------------------------------------------------------
 1 | import * as THREE from 'three'
 2 | import { Engine } from '../../engine/Engine'
 3 | import { Resource } from '../../engine/Resources'
 4 | import { ToonShaderMaterial } from '../ToonShaderMaterial'
 5 | 
 6 | export class Tentacle extends THREE.Group {
 7 |   public static resource: Resource = {
 8 |     name: 'tentacle',
 9 |     path: 'models/tentacle.glb',
10 |     type: 'gltf',
11 |   }
12 | 
13 |   constructor(engine: Engine) {
14 |     super()
15 | 
16 |     const gltfScene = engine.resources.getItem(Tentacle.resource.name)
17 |     this.add(...gltfScene.scene.children)
18 | 
19 |     this.traverse((child: THREE.Object3D) => {
20 |       if (child instanceof THREE.Mesh) {
21 |         child.castShadow = true
22 |         child.receiveShadow = true
23 |       }
24 |     })
25 | 
26 |     const outside = this.getObjectByName('Tentacle_1') as THREE.Mesh
27 |     const inside = this.getObjectByName('Tentacle_2') as THREE.Mesh
28 |     const sucker = this.getObjectByName('Tentacle_3') as THREE.Mesh
29 | 
30 |     outside.material = new ToonShaderMaterial({ color: '#231312' })
31 |     inside.material = new ToonShaderMaterial({ color: '#e57a7a' })
32 |     sucker.material = new ToonShaderMaterial({ color: '#b25c73' })
33 |   }
34 | }
35 | 
--------------------------------------------------------------------------------
/src/toon-shader/shaders/toon.frag:
--------------------------------------------------------------------------------
 1 | #include 
 2 | #include 
 3 | #include 
 4 | #include 
 5 | #include 
 6 | 
 7 | uniform vec3 uColor;
 8 | uniform float uGlossiness;
 9 | 
10 | varying vec3 vNormal;
11 | varying vec3 vViewDir;
12 | 
13 | void main() {
14 |     // shadow map
15 |     DirectionalLightShadow directionalLight = directionalLightShadows[0];
16 | 
17 |     float shadow = getShadow(
18 |         directionalShadowMap[0],
19 |         directionalLight.shadowMapSize,
20 |         directionalLight.shadowBias,
21 |         directionalLight.shadowRadius,
22 |         vDirectionalShadowCoord[0]
23 |     );
24 | 
25 |     // directional light
26 |     float NdotL = dot(vNormal, directionalLights[0].direction);
27 |     float lightIntensity = smoothstep(0.0, 0.01, NdotL * shadow);
28 |     vec3 light = directionalLights[0].color * lightIntensity;
29 | 
30 |     // specular light
31 |     vec3 halfVector = normalize(directionalLights[0].direction + vViewDir);
32 |     float NdotH = dot(vNormal, halfVector);
33 | 
34 |     float specularIntensity = pow(NdotH * lightIntensity, uGlossiness * uGlossiness);
35 |     float specularIntensitySmooth = smoothstep(0.05, 0.1, specularIntensity);
36 | 
37 |     vec3 specular = specularIntensitySmooth * directionalLights[0].color;
38 | 
39 |     // rim lighting
40 |     float rimDot = 1.0 - dot(vViewDir, vNormal);
41 |     float rimAmount = 0.6;
42 | 
43 |     float rimThreshold = 0.2;
44 |     float rimIntensity = rimDot * pow(NdotL, rimThreshold);
45 |     rimIntensity = smoothstep(rimAmount - 0.01, rimAmount + 0.01, rimIntensity);
46 | 
47 |     vec3 rim = rimIntensity * directionalLights[0].color;
48 | 
49 |     gl_FragColor = vec4(uColor * (ambientLightColor + light + specular + rim), 1.0);
50 | }
51 | 
--------------------------------------------------------------------------------
/src/toon-shader/shaders/toon.vert:
--------------------------------------------------------------------------------
 1 | #include 
 2 | #include 
 3 | 
 4 | varying vec3 vNormal;
 5 | varying vec3 vViewDir;
 6 | 
 7 | void main() {
 8 |     #include 
 9 |     #include 
10 | 
11 |     #include 
12 | 
13 |     #include 
14 |     #include 
15 | 
16 |     vec4 modelPosition = modelMatrix * vec4(position, 1.0);
17 |     vec4 viewPosition = viewMatrix * modelPosition;
18 |     vec4 clipPosition = projectionMatrix * viewPosition;
19 | 
20 |     vNormal = normalize(normalMatrix * normal);
21 |     vViewDir = normalize(-viewPosition.xyz);
22 | 
23 |     gl_Position = clipPosition;
24 | 
25 | }
26 | 
--------------------------------------------------------------------------------
/src/types/glsl.d.ts:
--------------------------------------------------------------------------------
 1 | declare module '*.glsl' {
 2 |   const value: string
 3 |   export default value
 4 | }
 5 | 
 6 | declare module '*.frag' {
 7 |   const value: string
 8 |   export default value
 9 | }
10 | 
11 | declare module '*.vert' {
12 |   const value: string
13 |   export default value
14 | }
15 | 
--------------------------------------------------------------------------------
/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | /// 
2 | 
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "compilerOptions": {
 3 |     "target": "ESNext",
 4 |     "useDefineForClassFields": true,
 5 |     "module": "ESNext",
 6 |     "lib": ["ESNext", "DOM"],
 7 |     "moduleResolution": "Node",
 8 |     "strict": true,
 9 |     "sourceMap": true,
10 |     "resolveJsonModule": true,
11 |     "isolatedModules": true,
12 |     "esModuleInterop": true,
13 |     "noEmit": true,
14 |     "noUnusedLocals": true,
15 |     "noUnusedParameters": true,
16 |     "noImplicitReturns": true,
17 |     "skipLibCheck": true
18 |   },
19 |   "include": ["src"]
20 | }
21 | 
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | import glsl from 'vite-plugin-glsl'
2 | import { defineConfig } from 'vite'
3 | 
4 | export default defineConfig({
5 |   plugins: [glsl()],
6 | })
7 | 
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
   1 | # This file is generated by running "yarn install" inside your project.
   2 | # Manual changes might be lost - proceed with caution!
   3 | 
   4 | __metadata:
   5 |   version: 6
   6 |   cacheKey: 8
   7 | 
   8 | "@esbuild/android-arm64@npm:0.17.17":
   9 |   version: 0.17.17
  10 |   resolution: "@esbuild/android-arm64@npm:0.17.17"
  11 |   conditions: os=android & cpu=arm64
  12 |   languageName: node
  13 |   linkType: hard
  14 | 
  15 | "@esbuild/android-arm@npm:0.17.17":
  16 |   version: 0.17.17
  17 |   resolution: "@esbuild/android-arm@npm:0.17.17"
  18 |   conditions: os=android & cpu=arm
  19 |   languageName: node
  20 |   linkType: hard
  21 | 
  22 | "@esbuild/android-x64@npm:0.17.17":
  23 |   version: 0.17.17
  24 |   resolution: "@esbuild/android-x64@npm:0.17.17"
  25 |   conditions: os=android & cpu=x64
  26 |   languageName: node
  27 |   linkType: hard
  28 | 
  29 | "@esbuild/darwin-arm64@npm:0.17.17":
  30 |   version: 0.17.17
  31 |   resolution: "@esbuild/darwin-arm64@npm:0.17.17"
  32 |   conditions: os=darwin & cpu=arm64
  33 |   languageName: node
  34 |   linkType: hard
  35 | 
  36 | "@esbuild/darwin-x64@npm:0.17.17":
  37 |   version: 0.17.17
  38 |   resolution: "@esbuild/darwin-x64@npm:0.17.17"
  39 |   conditions: os=darwin & cpu=x64
  40 |   languageName: node
  41 |   linkType: hard
  42 | 
  43 | "@esbuild/freebsd-arm64@npm:0.17.17":
  44 |   version: 0.17.17
  45 |   resolution: "@esbuild/freebsd-arm64@npm:0.17.17"
  46 |   conditions: os=freebsd & cpu=arm64
  47 |   languageName: node
  48 |   linkType: hard
  49 | 
  50 | "@esbuild/freebsd-x64@npm:0.17.17":
  51 |   version: 0.17.17
  52 |   resolution: "@esbuild/freebsd-x64@npm:0.17.17"
  53 |   conditions: os=freebsd & cpu=x64
  54 |   languageName: node
  55 |   linkType: hard
  56 | 
  57 | "@esbuild/linux-arm64@npm:0.17.17":
  58 |   version: 0.17.17
  59 |   resolution: "@esbuild/linux-arm64@npm:0.17.17"
  60 |   conditions: os=linux & cpu=arm64
  61 |   languageName: node
  62 |   linkType: hard
  63 | 
  64 | "@esbuild/linux-arm@npm:0.17.17":
  65 |   version: 0.17.17
  66 |   resolution: "@esbuild/linux-arm@npm:0.17.17"
  67 |   conditions: os=linux & cpu=arm
  68 |   languageName: node
  69 |   linkType: hard
  70 | 
  71 | "@esbuild/linux-ia32@npm:0.17.17":
  72 |   version: 0.17.17
  73 |   resolution: "@esbuild/linux-ia32@npm:0.17.17"
  74 |   conditions: os=linux & cpu=ia32
  75 |   languageName: node
  76 |   linkType: hard
  77 | 
  78 | "@esbuild/linux-loong64@npm:0.17.17":
  79 |   version: 0.17.17
  80 |   resolution: "@esbuild/linux-loong64@npm:0.17.17"
  81 |   conditions: os=linux & cpu=loong64
  82 |   languageName: node
  83 |   linkType: hard
  84 | 
  85 | "@esbuild/linux-mips64el@npm:0.17.17":
  86 |   version: 0.17.17
  87 |   resolution: "@esbuild/linux-mips64el@npm:0.17.17"
  88 |   conditions: os=linux & cpu=mips64el
  89 |   languageName: node
  90 |   linkType: hard
  91 | 
  92 | "@esbuild/linux-ppc64@npm:0.17.17":
  93 |   version: 0.17.17
  94 |   resolution: "@esbuild/linux-ppc64@npm:0.17.17"
  95 |   conditions: os=linux & cpu=ppc64
  96 |   languageName: node
  97 |   linkType: hard
  98 | 
  99 | "@esbuild/linux-riscv64@npm:0.17.17":
 100 |   version: 0.17.17
 101 |   resolution: "@esbuild/linux-riscv64@npm:0.17.17"
 102 |   conditions: os=linux & cpu=riscv64
 103 |   languageName: node
 104 |   linkType: hard
 105 | 
 106 | "@esbuild/linux-s390x@npm:0.17.17":
 107 |   version: 0.17.17
 108 |   resolution: "@esbuild/linux-s390x@npm:0.17.17"
 109 |   conditions: os=linux & cpu=s390x
 110 |   languageName: node
 111 |   linkType: hard
 112 | 
 113 | "@esbuild/linux-x64@npm:0.17.17":
 114 |   version: 0.17.17
 115 |   resolution: "@esbuild/linux-x64@npm:0.17.17"
 116 |   conditions: os=linux & cpu=x64
 117 |   languageName: node
 118 |   linkType: hard
 119 | 
 120 | "@esbuild/netbsd-x64@npm:0.17.17":
 121 |   version: 0.17.17
 122 |   resolution: "@esbuild/netbsd-x64@npm:0.17.17"
 123 |   conditions: os=netbsd & cpu=x64
 124 |   languageName: node
 125 |   linkType: hard
 126 | 
 127 | "@esbuild/openbsd-x64@npm:0.17.17":
 128 |   version: 0.17.17
 129 |   resolution: "@esbuild/openbsd-x64@npm:0.17.17"
 130 |   conditions: os=openbsd & cpu=x64
 131 |   languageName: node
 132 |   linkType: hard
 133 | 
 134 | "@esbuild/sunos-x64@npm:0.17.17":
 135 |   version: 0.17.17
 136 |   resolution: "@esbuild/sunos-x64@npm:0.17.17"
 137 |   conditions: os=sunos & cpu=x64
 138 |   languageName: node
 139 |   linkType: hard
 140 | 
 141 | "@esbuild/win32-arm64@npm:0.17.17":
 142 |   version: 0.17.17
 143 |   resolution: "@esbuild/win32-arm64@npm:0.17.17"
 144 |   conditions: os=win32 & cpu=arm64
 145 |   languageName: node
 146 |   linkType: hard
 147 | 
 148 | "@esbuild/win32-ia32@npm:0.17.17":
 149 |   version: 0.17.17
 150 |   resolution: "@esbuild/win32-ia32@npm:0.17.17"
 151 |   conditions: os=win32 & cpu=ia32
 152 |   languageName: node
 153 |   linkType: hard
 154 | 
 155 | "@esbuild/win32-x64@npm:0.17.17":
 156 |   version: 0.17.17
 157 |   resolution: "@esbuild/win32-x64@npm:0.17.17"
 158 |   conditions: os=win32 & cpu=x64
 159 |   languageName: node
 160 |   linkType: hard
 161 | 
 162 | "@gar/promisify@npm:^1.1.3":
 163 |   version: 1.1.3
 164 |   resolution: "@gar/promisify@npm:1.1.3"
 165 |   checksum: 4059f790e2d07bf3c3ff3e0fec0daa8144fe35c1f6e0111c9921bd32106adaa97a4ab096ad7dab1e28ee6a9060083c4d1a4ada42a7f5f3f7a96b8812e2b757c1
 166 |   languageName: node
 167 |   linkType: hard
 168 | 
 169 | "@npmcli/fs@npm:^2.1.0":
 170 |   version: 2.1.1
 171 |   resolution: "@npmcli/fs@npm:2.1.1"
 172 |   dependencies:
 173 |     "@gar/promisify": ^1.1.3
 174 |     semver: ^7.3.5
 175 |   checksum: 4944a0545d38d3e6e29780eeb3cd4be6059c1e9627509d2c9ced635c53b852d28b37cdc615a2adf815b51ab8673adb6507e370401a20a7e90c8a6dc4fac02389
 176 |   languageName: node
 177 |   linkType: hard
 178 | 
 179 | "@npmcli/move-file@npm:^2.0.0":
 180 |   version: 2.0.0
 181 |   resolution: "@npmcli/move-file@npm:2.0.0"
 182 |   dependencies:
 183 |     mkdirp: ^1.0.4
 184 |     rimraf: ^3.0.2
 185 |   checksum: 1388777b507b0c592d53f41b9d182e1a8de7763bc625fc07999b8edbc22325f074e5b3ec90af79c89d6987fdb2325bc66d59f483258543c14a43661621f841b0
 186 |   languageName: node
 187 |   linkType: hard
 188 | 
 189 | "@rollup/pluginutils@npm:^5.0.2":
 190 |   version: 5.0.2
 191 |   resolution: "@rollup/pluginutils@npm:5.0.2"
 192 |   dependencies:
 193 |     "@types/estree": ^1.0.0
 194 |     estree-walker: ^2.0.2
 195 |     picomatch: ^2.3.1
 196 |   peerDependencies:
 197 |     rollup: ^1.20.0||^2.0.0||^3.0.0
 198 |   peerDependenciesMeta:
 199 |     rollup:
 200 |       optional: true
 201 |   checksum: edea15e543bebc7dcac3b0ac8bc7b8e8e6dbd46e2864dbe5dd28072de1fbd5b0e10d545a610c0edaa178e8a7ac432e2a2a52e547ece1308471412caba47db8ce
 202 |   languageName: node
 203 |   linkType: hard
 204 | 
 205 | "@tootallnate/once@npm:2":
 206 |   version: 2.0.0
 207 |   resolution: "@tootallnate/once@npm:2.0.0"
 208 |   checksum: ad87447820dd3f24825d2d947ebc03072b20a42bfc96cbafec16bff8bbda6c1a81fcb0be56d5b21968560c5359a0af4038a68ba150c3e1694fe4c109a063bed8
 209 |   languageName: node
 210 |   linkType: hard
 211 | 
 212 | "@types/estree@npm:^1.0.0":
 213 |   version: 1.0.1
 214 |   resolution: "@types/estree@npm:1.0.1"
 215 |   checksum: e9aa175eacb797216fafce4d41e8202c7a75555bc55232dee0f9903d7171f8f19f0ae7d5191bb1a88cb90e65468be508c0df850a9fb81b4433b293a5a749899d
 216 |   languageName: node
 217 |   linkType: hard
 218 | 
 219 | "@types/stats.js@npm:*":
 220 |   version: 0.17.0
 221 |   resolution: "@types/stats.js@npm:0.17.0"
 222 |   checksum: ac8dc5e622fa3b7cc37b9e21663193a2f171a4f5896285e4dfc04f2874acbb75edc958f077bffbd85b0ae358daa5bf4ecbc71210386a4300bff05d09435e35f9
 223 |   languageName: node
 224 |   linkType: hard
 225 | 
 226 | "@types/three@npm:^0.150.2":
 227 |   version: 0.150.2
 228 |   resolution: "@types/three@npm:0.150.2"
 229 |   dependencies:
 230 |     "@types/stats.js": "*"
 231 |     "@types/webxr": "*"
 232 |     fflate: ~0.6.9
 233 |     lil-gui: ~0.17.0
 234 |   checksum: 6252abd77cb3336116361d262cc9b4c809c1184953ed847ca6969e7e10e01be01a253c5dea03e010821dae8e06cf3ea7f56d424bb0aa5660599408387d5b46da
 235 |   languageName: node
 236 |   linkType: hard
 237 | 
 238 | "@types/webxr@npm:*":
 239 |   version: 0.4.0
 240 |   resolution: "@types/webxr@npm:0.4.0"
 241 |   checksum: 4388c18a5b08ef4aa97f2177d3d80d384c5557c4b06278215d46472585923128fb316353e5fb799d22ffe99be149af90d0c27c41cb3681e82228088e48b24184
 242 |   languageName: node
 243 |   linkType: hard
 244 | 
 245 | "abbrev@npm:1":
 246 |   version: 1.1.1
 247 |   resolution: "abbrev@npm:1.1.1"
 248 |   checksum: a4a97ec07d7ea112c517036882b2ac22f3109b7b19077dc656316d07d308438aac28e4d9746dc4d84bf6b1e75b4a7b0a5f3cb30592419f128ca9a8cee3bcfa17
 249 |   languageName: node
 250 |   linkType: hard
 251 | 
 252 | "agent-base@npm:6, agent-base@npm:^6.0.2":
 253 |   version: 6.0.2
 254 |   resolution: "agent-base@npm:6.0.2"
 255 |   dependencies:
 256 |     debug: 4
 257 |   checksum: f52b6872cc96fd5f622071b71ef200e01c7c4c454ee68bc9accca90c98cfb39f2810e3e9aa330435835eedc8c23f4f8a15267f67c6e245d2b33757575bdac49d
 258 |   languageName: node
 259 |   linkType: hard
 260 | 
 261 | "agentkeepalive@npm:^4.2.1":
 262 |   version: 4.2.1
 263 |   resolution: "agentkeepalive@npm:4.2.1"
 264 |   dependencies:
 265 |     debug: ^4.1.0
 266 |     depd: ^1.1.2
 267 |     humanize-ms: ^1.2.1
 268 |   checksum: 39cb49ed8cf217fd6da058a92828a0a84e0b74c35550f82ee0a10e1ee403c4b78ade7948be2279b188b7a7303f5d396ea2738b134731e464bf28de00a4f72a18
 269 |   languageName: node
 270 |   linkType: hard
 271 | 
 272 | "aggregate-error@npm:^3.0.0":
 273 |   version: 3.1.0
 274 |   resolution: "aggregate-error@npm:3.1.0"
 275 |   dependencies:
 276 |     clean-stack: ^2.0.0
 277 |     indent-string: ^4.0.0
 278 |   checksum: 1101a33f21baa27a2fa8e04b698271e64616b886795fd43c31068c07533c7b3facfcaf4e9e0cab3624bd88f729a592f1c901a1a229c9e490eafce411a8644b79
 279 |   languageName: node
 280 |   linkType: hard
 281 | 
 282 | "ansi-escapes@npm:^4.3.0":
 283 |   version: 4.3.2
 284 |   resolution: "ansi-escapes@npm:4.3.2"
 285 |   dependencies:
 286 |     type-fest: ^0.21.3
 287 |   checksum: 93111c42189c0a6bed9cdb4d7f2829548e943827ee8479c74d6e0b22ee127b2a21d3f8b5ca57723b8ef78ce011fbfc2784350eb2bde3ccfccf2f575fa8489815
 288 |   languageName: node
 289 |   linkType: hard
 290 | 
 291 | "ansi-regex@npm:^5.0.1":
 292 |   version: 5.0.1
 293 |   resolution: "ansi-regex@npm:5.0.1"
 294 |   checksum: 2aa4bb54caf2d622f1afdad09441695af2a83aa3fe8b8afa581d205e57ed4261c183c4d3877cee25794443fde5876417d859c108078ab788d6af7e4fe52eb66b
 295 |   languageName: node
 296 |   linkType: hard
 297 | 
 298 | "ansi-regex@npm:^6.0.1":
 299 |   version: 6.0.1
 300 |   resolution: "ansi-regex@npm:6.0.1"
 301 |   checksum: 1ff8b7667cded1de4fa2c9ae283e979fc87036864317da86a2e546725f96406746411d0d85e87a2d12fa5abd715d90006de7fa4fa0477c92321ad3b4c7d4e169
 302 |   languageName: node
 303 |   linkType: hard
 304 | 
 305 | "ansi-styles@npm:^4.0.0":
 306 |   version: 4.3.0
 307 |   resolution: "ansi-styles@npm:4.3.0"
 308 |   dependencies:
 309 |     color-convert: ^2.0.1
 310 |   checksum: 513b44c3b2105dd14cc42a19271e80f386466c4be574bccf60b627432f9198571ebf4ab1e4c3ba17347658f4ee1711c163d574248c0c1cdc2d5917a0ad582ec4
 311 |   languageName: node
 312 |   linkType: hard
 313 | 
 314 | "ansi-styles@npm:^6.0.0":
 315 |   version: 6.1.0
 316 |   resolution: "ansi-styles@npm:6.1.0"
 317 |   checksum: 7a7f8528c07a9d20c3a92bccd2b6bc3bb4d26e5cb775c02826921477377bd495d615d61f710d56216344b6238d1d11ef2b0348e146c5b128715578bfb3217229
 318 |   languageName: node
 319 |   linkType: hard
 320 | 
 321 | "anymatch@npm:~3.1.2":
 322 |   version: 3.1.2
 323 |   resolution: "anymatch@npm:3.1.2"
 324 |   dependencies:
 325 |     normalize-path: ^3.0.0
 326 |     picomatch: ^2.0.4
 327 |   checksum: 985163db2292fac9e5a1e072bf99f1b5baccf196e4de25a0b0b81865ebddeb3b3eb4480734ef0a2ac8c002845396b91aa89121f5b84f93981a4658164a9ec6e9
 328 |   languageName: node
 329 |   linkType: hard
 330 | 
 331 | "aproba@npm:^1.0.3 || ^2.0.0":
 332 |   version: 2.0.0
 333 |   resolution: "aproba@npm:2.0.0"
 334 |   checksum: 5615cadcfb45289eea63f8afd064ab656006361020e1735112e346593856f87435e02d8dcc7ff0d11928bc7d425f27bc7c2a84f6c0b35ab0ff659c814c138a24
 335 |   languageName: node
 336 |   linkType: hard
 337 | 
 338 | "are-we-there-yet@npm:^3.0.0":
 339 |   version: 3.0.0
 340 |   resolution: "are-we-there-yet@npm:3.0.0"
 341 |   dependencies:
 342 |     delegates: ^1.0.0
 343 |     readable-stream: ^3.6.0
 344 |   checksum: 348edfdd931b0b50868b55402c01c3f64df1d4c229ab6f063539a5025fd6c5f5bb8a0cab409bbed8d75d34762d22aa91b7c20b4204eb8177063158d9ba792981
 345 |   languageName: node
 346 |   linkType: hard
 347 | 
 348 | "astral-regex@npm:^2.0.0":
 349 |   version: 2.0.0
 350 |   resolution: "astral-regex@npm:2.0.0"
 351 |   checksum: 876231688c66400473ba505731df37ea436e574dd524520294cc3bbc54ea40334865e01fa0d074d74d036ee874ee7e62f486ea38bc421ee8e6a871c06f011766
 352 |   languageName: node
 353 |   linkType: hard
 354 | 
 355 | "balanced-match@npm:^1.0.0":
 356 |   version: 1.0.2
 357 |   resolution: "balanced-match@npm:1.0.2"
 358 |   checksum: 9706c088a283058a8a99e0bf91b0a2f75497f185980d9ffa8b304de1d9e58ebda7c72c07ebf01dadedaac5b2907b2c6f566f660d62bd336c3468e960403b9d65
 359 |   languageName: node
 360 |   linkType: hard
 361 | 
 362 | "binary-extensions@npm:^2.0.0":
 363 |   version: 2.2.0
 364 |   resolution: "binary-extensions@npm:2.2.0"
 365 |   checksum: ccd267956c58d2315f5d3ea6757cf09863c5fc703e50fbeb13a7dc849b812ef76e3cf9ca8f35a0c48498776a7478d7b4a0418e1e2b8cb9cb9731f2922aaad7f8
 366 |   languageName: node
 367 |   linkType: hard
 368 | 
 369 | "brace-expansion@npm:^1.1.7":
 370 |   version: 1.1.11
 371 |   resolution: "brace-expansion@npm:1.1.11"
 372 |   dependencies:
 373 |     balanced-match: ^1.0.0
 374 |     concat-map: 0.0.1
 375 |   checksum: faf34a7bb0c3fcf4b59c7808bc5d2a96a40988addf2e7e09dfbb67a2251800e0d14cd2bfc1aa79174f2f5095c54ff27f46fb1289fe2d77dac755b5eb3434cc07
 376 |   languageName: node
 377 |   linkType: hard
 378 | 
 379 | "brace-expansion@npm:^2.0.1":
 380 |   version: 2.0.1
 381 |   resolution: "brace-expansion@npm:2.0.1"
 382 |   dependencies:
 383 |     balanced-match: ^1.0.0
 384 |   checksum: a61e7cd2e8a8505e9f0036b3b6108ba5e926b4b55089eeb5550cd04a471fe216c96d4fe7e4c7f995c728c554ae20ddfc4244cad10aef255e72b62930afd233d1
 385 |   languageName: node
 386 |   linkType: hard
 387 | 
 388 | "braces@npm:^3.0.2, braces@npm:~3.0.2":
 389 |   version: 3.0.2
 390 |   resolution: "braces@npm:3.0.2"
 391 |   dependencies:
 392 |     fill-range: ^7.0.1
 393 |   checksum: e2a8e769a863f3d4ee887b5fe21f63193a891c68b612ddb4b68d82d1b5f3ff9073af066c343e9867a393fe4c2555dcb33e89b937195feb9c1613d259edfcd459
 394 |   languageName: node
 395 |   linkType: hard
 396 | 
 397 | "cacache@npm:^16.1.0":
 398 |   version: 16.1.1
 399 |   resolution: "cacache@npm:16.1.1"
 400 |   dependencies:
 401 |     "@npmcli/fs": ^2.1.0
 402 |     "@npmcli/move-file": ^2.0.0
 403 |     chownr: ^2.0.0
 404 |     fs-minipass: ^2.1.0
 405 |     glob: ^8.0.1
 406 |     infer-owner: ^1.0.4
 407 |     lru-cache: ^7.7.1
 408 |     minipass: ^3.1.6
 409 |     minipass-collect: ^1.0.2
 410 |     minipass-flush: ^1.0.5
 411 |     minipass-pipeline: ^1.2.4
 412 |     mkdirp: ^1.0.4
 413 |     p-map: ^4.0.0
 414 |     promise-inflight: ^1.0.1
 415 |     rimraf: ^3.0.2
 416 |     ssri: ^9.0.0
 417 |     tar: ^6.1.11
 418 |     unique-filename: ^1.1.1
 419 |   checksum: 488524617008b793f0249b0c4ea2c330c710ca997921376e15650cc2415a8054491ae2dee9f01382c2015602c0641f3f977faf2fa7361aa33d2637dcfb03907a
 420 |   languageName: node
 421 |   linkType: hard
 422 | 
 423 | "chalk@npm:5.2.0":
 424 |   version: 5.2.0
 425 |   resolution: "chalk@npm:5.2.0"
 426 |   checksum: 03d8060277de6cf2fd567dc25fcf770593eb5bb85f460ce443e49255a30ff1242edd0c90a06a03803b0466ff0687a939b41db1757bec987113e83de89a003caa
 427 |   languageName: node
 428 |   linkType: hard
 429 | 
 430 | "chokidar@npm:>=3.0.0 <4.0.0":
 431 |   version: 3.5.3
 432 |   resolution: "chokidar@npm:3.5.3"
 433 |   dependencies:
 434 |     anymatch: ~3.1.2
 435 |     braces: ~3.0.2
 436 |     fsevents: ~2.3.2
 437 |     glob-parent: ~5.1.2
 438 |     is-binary-path: ~2.1.0
 439 |     is-glob: ~4.0.1
 440 |     normalize-path: ~3.0.0
 441 |     readdirp: ~3.6.0
 442 |   dependenciesMeta:
 443 |     fsevents:
 444 |       optional: true
 445 |   checksum: b49fcde40176ba007ff361b198a2d35df60d9bb2a5aab228279eb810feae9294a6b4649ab15981304447afe1e6ffbf4788ad5db77235dc770ab777c6e771980c
 446 |   languageName: node
 447 |   linkType: hard
 448 | 
 449 | "chownr@npm:^2.0.0":
 450 |   version: 2.0.0
 451 |   resolution: "chownr@npm:2.0.0"
 452 |   checksum: c57cf9dd0791e2f18a5ee9c1a299ae6e801ff58fee96dc8bfd0dcb4738a6ce58dd252a3605b1c93c6418fe4f9d5093b28ffbf4d66648cb2a9c67eaef9679be2f
 453 |   languageName: node
 454 |   linkType: hard
 455 | 
 456 | "clean-stack@npm:^2.0.0":
 457 |   version: 2.2.0
 458 |   resolution: "clean-stack@npm:2.2.0"
 459 |   checksum: 2ac8cd2b2f5ec986a3c743935ec85b07bc174d5421a5efc8017e1f146a1cf5f781ae962618f416352103b32c9cd7e203276e8c28241bbe946160cab16149fb68
 460 |   languageName: node
 461 |   linkType: hard
 462 | 
 463 | "cli-cursor@npm:^3.1.0":
 464 |   version: 3.1.0
 465 |   resolution: "cli-cursor@npm:3.1.0"
 466 |   dependencies:
 467 |     restore-cursor: ^3.1.0
 468 |   checksum: 2692784c6cd2fd85cfdbd11f53aea73a463a6d64a77c3e098b2b4697a20443f430c220629e1ca3b195ea5ac4a97a74c2ee411f3807abf6df2b66211fec0c0a29
 469 |   languageName: node
 470 |   linkType: hard
 471 | 
 472 | "cli-truncate@npm:^2.1.0":
 473 |   version: 2.1.0
 474 |   resolution: "cli-truncate@npm:2.1.0"
 475 |   dependencies:
 476 |     slice-ansi: ^3.0.0
 477 |     string-width: ^4.2.0
 478 |   checksum: bf1e4e6195392dc718bf9cd71f317b6300dc4a9191d052f31046b8773230ece4fa09458813bf0e3455a5e68c0690d2ea2c197d14a8b85a7b5e01c97f4b5feb5d
 479 |   languageName: node
 480 |   linkType: hard
 481 | 
 482 | "cli-truncate@npm:^3.1.0":
 483 |   version: 3.1.0
 484 |   resolution: "cli-truncate@npm:3.1.0"
 485 |   dependencies:
 486 |     slice-ansi: ^5.0.0
 487 |     string-width: ^5.0.0
 488 |   checksum: c3243e41974445691c63f8b405df1d5a24049dc33d324fe448dc572e561a7b772ae982692900b1a5960901cc4fc7def25a629b9c69a4208ee89d12ab3332617a
 489 |   languageName: node
 490 |   linkType: hard
 491 | 
 492 | "color-convert@npm:^2.0.1":
 493 |   version: 2.0.1
 494 |   resolution: "color-convert@npm:2.0.1"
 495 |   dependencies:
 496 |     color-name: ~1.1.4
 497 |   checksum: 79e6bdb9fd479a205c71d89574fccfb22bd9053bd98c6c4d870d65c132e5e904e6034978e55b43d69fcaa7433af2016ee203ce76eeba9cfa554b373e7f7db336
 498 |   languageName: node
 499 |   linkType: hard
 500 | 
 501 | "color-name@npm:~1.1.4":
 502 |   version: 1.1.4
 503 |   resolution: "color-name@npm:1.1.4"
 504 |   checksum: b0445859521eb4021cd0fb0cc1a75cecf67fceecae89b63f62b201cca8d345baf8b952c966862a9d9a2632987d4f6581f0ec8d957dfacece86f0a7919316f610
 505 |   languageName: node
 506 |   linkType: hard
 507 | 
 508 | "color-support@npm:^1.1.3":
 509 |   version: 1.1.3
 510 |   resolution: "color-support@npm:1.1.3"
 511 |   bin:
 512 |     color-support: bin.js
 513 |   checksum: 9b7356817670b9a13a26ca5af1c21615463b500783b739b7634a0c2047c16cef4b2865d7576875c31c3cddf9dd621fa19285e628f20198b233a5cfdda6d0793b
 514 |   languageName: node
 515 |   linkType: hard
 516 | 
 517 | "colorette@npm:^2.0.19":
 518 |   version: 2.0.20
 519 |   resolution: "colorette@npm:2.0.20"
 520 |   checksum: 0c016fea2b91b733eb9f4bcdb580018f52c0bc0979443dad930e5037a968237ac53d9beb98e218d2e9235834f8eebce7f8e080422d6194e957454255bde71d3d
 521 |   languageName: node
 522 |   linkType: hard
 523 | 
 524 | "commander@npm:^10.0.0":
 525 |   version: 10.0.1
 526 |   resolution: "commander@npm:10.0.1"
 527 |   checksum: 436901d64a818295803c1996cd856621a74f30b9f9e28a588e726b2b1670665bccd7c1a77007ebf328729f0139838a88a19265858a0fa7a8728c4656796db948
 528 |   languageName: node
 529 |   linkType: hard
 530 | 
 531 | "concat-map@npm:0.0.1":
 532 |   version: 0.0.1
 533 |   resolution: "concat-map@npm:0.0.1"
 534 |   checksum: 902a9f5d8967a3e2faf138d5cb784b9979bad2e6db5357c5b21c568df4ebe62bcb15108af1b2253744844eb964fc023fbd9afbbbb6ddd0bcc204c6fb5b7bf3af
 535 |   languageName: node
 536 |   linkType: hard
 537 | 
 538 | "console-control-strings@npm:^1.1.0":
 539 |   version: 1.1.0
 540 |   resolution: "console-control-strings@npm:1.1.0"
 541 |   checksum: 8755d76787f94e6cf79ce4666f0c5519906d7f5b02d4b884cf41e11dcd759ed69c57da0670afd9236d229a46e0f9cf519db0cd829c6dca820bb5a5c3def584ed
 542 |   languageName: node
 543 |   linkType: hard
 544 | 
 545 | "cross-spawn@npm:^7.0.3":
 546 |   version: 7.0.3
 547 |   resolution: "cross-spawn@npm:7.0.3"
 548 |   dependencies:
 549 |     path-key: ^3.1.0
 550 |     shebang-command: ^2.0.0
 551 |     which: ^2.0.1
 552 |   checksum: 671cc7c7288c3a8406f3c69a3ae2fc85555c04169e9d611def9a675635472614f1c0ed0ef80955d5b6d4e724f6ced67f0ad1bb006c2ea643488fcfef994d7f52
 553 |   languageName: node
 554 |   linkType: hard
 555 | 
 556 | "debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.3.3, debug@npm:^4.3.4":
 557 |   version: 4.3.4
 558 |   resolution: "debug@npm:4.3.4"
 559 |   dependencies:
 560 |     ms: 2.1.2
 561 |   peerDependenciesMeta:
 562 |     supports-color:
 563 |       optional: true
 564 |   checksum: 3dbad3f94ea64f34431a9cbf0bafb61853eda57bff2880036153438f50fb5a84f27683ba0d8e5426bf41a8c6ff03879488120cf5b3a761e77953169c0600a708
 565 |   languageName: node
 566 |   linkType: hard
 567 | 
 568 | "delegates@npm:^1.0.0":
 569 |   version: 1.0.0
 570 |   resolution: "delegates@npm:1.0.0"
 571 |   checksum: a51744d9b53c164ba9c0492471a1a2ffa0b6727451bdc89e31627fdf4adda9d51277cfcbfb20f0a6f08ccb3c436f341df3e92631a3440226d93a8971724771fd
 572 |   languageName: node
 573 |   linkType: hard
 574 | 
 575 | "depd@npm:^1.1.2":
 576 |   version: 1.1.2
 577 |   resolution: "depd@npm:1.1.2"
 578 |   checksum: 6b406620d269619852885ce15965272b829df6f409724415e0002c8632ab6a8c0a08ec1f0bd2add05dc7bd7507606f7e2cc034fa24224ab829580040b835ecd9
 579 |   languageName: node
 580 |   linkType: hard
 581 | 
 582 | "eastasianwidth@npm:^0.2.0":
 583 |   version: 0.2.0
 584 |   resolution: "eastasianwidth@npm:0.2.0"
 585 |   checksum: 7d00d7cd8e49b9afa762a813faac332dee781932d6f2c848dc348939c4253f1d4564341b7af1d041853bc3f32c2ef141b58e0a4d9862c17a7f08f68df1e0f1ed
 586 |   languageName: node
 587 |   linkType: hard
 588 | 
 589 | "emoji-regex@npm:^8.0.0":
 590 |   version: 8.0.0
 591 |   resolution: "emoji-regex@npm:8.0.0"
 592 |   checksum: d4c5c39d5a9868b5fa152f00cada8a936868fd3367f33f71be515ecee4c803132d11b31a6222b2571b1e5f7e13890156a94880345594d0ce7e3c9895f560f192
 593 |   languageName: node
 594 |   linkType: hard
 595 | 
 596 | "emoji-regex@npm:^9.2.2":
 597 |   version: 9.2.2
 598 |   resolution: "emoji-regex@npm:9.2.2"
 599 |   checksum: 8487182da74aabd810ac6d6f1994111dfc0e331b01271ae01ec1eb0ad7b5ecc2bbbbd2f053c05cb55a1ac30449527d819bbfbf0e3de1023db308cbcb47f86601
 600 |   languageName: node
 601 |   linkType: hard
 602 | 
 603 | "encoding@npm:^0.1.13":
 604 |   version: 0.1.13
 605 |   resolution: "encoding@npm:0.1.13"
 606 |   dependencies:
 607 |     iconv-lite: ^0.6.2
 608 |   checksum: bb98632f8ffa823996e508ce6a58ffcf5856330fde839ae42c9e1f436cc3b5cc651d4aeae72222916545428e54fd0f6aa8862fd8d25bdbcc4589f1e3f3715e7f
 609 |   languageName: node
 610 |   linkType: hard
 611 | 
 612 | "env-paths@npm:^2.2.0":
 613 |   version: 2.2.1
 614 |   resolution: "env-paths@npm:2.2.1"
 615 |   checksum: 65b5df55a8bab92229ab2b40dad3b387fad24613263d103a97f91c9fe43ceb21965cd3392b1ccb5d77088021e525c4e0481adb309625d0cb94ade1d1fb8dc17e
 616 |   languageName: node
 617 |   linkType: hard
 618 | 
 619 | "err-code@npm:^2.0.2":
 620 |   version: 2.0.3
 621 |   resolution: "err-code@npm:2.0.3"
 622 |   checksum: 8b7b1be20d2de12d2255c0bc2ca638b7af5171142693299416e6a9339bd7d88fc8d7707d913d78e0993176005405a236b066b45666b27b797252c771156ace54
 623 |   languageName: node
 624 |   linkType: hard
 625 | 
 626 | "esbuild@npm:^0.17.5":
 627 |   version: 0.17.17
 628 |   resolution: "esbuild@npm:0.17.17"
 629 |   dependencies:
 630 |     "@esbuild/android-arm": 0.17.17
 631 |     "@esbuild/android-arm64": 0.17.17
 632 |     "@esbuild/android-x64": 0.17.17
 633 |     "@esbuild/darwin-arm64": 0.17.17
 634 |     "@esbuild/darwin-x64": 0.17.17
 635 |     "@esbuild/freebsd-arm64": 0.17.17
 636 |     "@esbuild/freebsd-x64": 0.17.17
 637 |     "@esbuild/linux-arm": 0.17.17
 638 |     "@esbuild/linux-arm64": 0.17.17
 639 |     "@esbuild/linux-ia32": 0.17.17
 640 |     "@esbuild/linux-loong64": 0.17.17
 641 |     "@esbuild/linux-mips64el": 0.17.17
 642 |     "@esbuild/linux-ppc64": 0.17.17
 643 |     "@esbuild/linux-riscv64": 0.17.17
 644 |     "@esbuild/linux-s390x": 0.17.17
 645 |     "@esbuild/linux-x64": 0.17.17
 646 |     "@esbuild/netbsd-x64": 0.17.17
 647 |     "@esbuild/openbsd-x64": 0.17.17
 648 |     "@esbuild/sunos-x64": 0.17.17
 649 |     "@esbuild/win32-arm64": 0.17.17
 650 |     "@esbuild/win32-ia32": 0.17.17
 651 |     "@esbuild/win32-x64": 0.17.17
 652 |   dependenciesMeta:
 653 |     "@esbuild/android-arm":
 654 |       optional: true
 655 |     "@esbuild/android-arm64":
 656 |       optional: true
 657 |     "@esbuild/android-x64":
 658 |       optional: true
 659 |     "@esbuild/darwin-arm64":
 660 |       optional: true
 661 |     "@esbuild/darwin-x64":
 662 |       optional: true
 663 |     "@esbuild/freebsd-arm64":
 664 |       optional: true
 665 |     "@esbuild/freebsd-x64":
 666 |       optional: true
 667 |     "@esbuild/linux-arm":
 668 |       optional: true
 669 |     "@esbuild/linux-arm64":
 670 |       optional: true
 671 |     "@esbuild/linux-ia32":
 672 |       optional: true
 673 |     "@esbuild/linux-loong64":
 674 |       optional: true
 675 |     "@esbuild/linux-mips64el":
 676 |       optional: true
 677 |     "@esbuild/linux-ppc64":
 678 |       optional: true
 679 |     "@esbuild/linux-riscv64":
 680 |       optional: true
 681 |     "@esbuild/linux-s390x":
 682 |       optional: true
 683 |     "@esbuild/linux-x64":
 684 |       optional: true
 685 |     "@esbuild/netbsd-x64":
 686 |       optional: true
 687 |     "@esbuild/openbsd-x64":
 688 |       optional: true
 689 |     "@esbuild/sunos-x64":
 690 |       optional: true
 691 |     "@esbuild/win32-arm64":
 692 |       optional: true
 693 |     "@esbuild/win32-ia32":
 694 |       optional: true
 695 |     "@esbuild/win32-x64":
 696 |       optional: true
 697 |   bin:
 698 |     esbuild: bin/esbuild
 699 |   checksum: dbb803a7fc798755ffcc347fd4e83f33bdffb91b62ff14c41d858acacd60b2b74a9fbcfb54da2be7cc385bd99fc00f5a0cc1e80c7e5d501236f4fd39cf8c03d1
 700 |   languageName: node
 701 |   linkType: hard
 702 | 
 703 | "estree-walker@npm:^2.0.2":
 704 |   version: 2.0.2
 705 |   resolution: "estree-walker@npm:2.0.2"
 706 |   checksum: 6151e6f9828abe2259e57f5fd3761335bb0d2ebd76dc1a01048ccee22fabcfef3c0859300f6d83ff0d1927849368775ec5a6d265dde2f6de5a1be1721cd94efc
 707 |   languageName: node
 708 |   linkType: hard
 709 | 
 710 | "execa@npm:^7.0.0":
 711 |   version: 7.1.1
 712 |   resolution: "execa@npm:7.1.1"
 713 |   dependencies:
 714 |     cross-spawn: ^7.0.3
 715 |     get-stream: ^6.0.1
 716 |     human-signals: ^4.3.0
 717 |     is-stream: ^3.0.0
 718 |     merge-stream: ^2.0.0
 719 |     npm-run-path: ^5.1.0
 720 |     onetime: ^6.0.0
 721 |     signal-exit: ^3.0.7
 722 |     strip-final-newline: ^3.0.0
 723 |   checksum: 21fa46fc69314ace4068cf820142bdde5b643a5d89831c2c9349479c1555bff137a291b8e749e7efca36535e4e0a8c772c11008ca2e84d2cbd6ca141a3c8f937
 724 |   languageName: node
 725 |   linkType: hard
 726 | 
 727 | "fflate@npm:~0.6.9":
 728 |   version: 0.6.10
 729 |   resolution: "fflate@npm:0.6.10"
 730 |   checksum: 96384bc4090987fe565c0de8204e3830f538144ec950576fea50aee1b42adbe9fc3ed5e7905dfa7979faaa20979def330dbebce548f3dcafc3e118cc9838526d
 731 |   languageName: node
 732 |   linkType: hard
 733 | 
 734 | "fill-range@npm:^7.0.1":
 735 |   version: 7.0.1
 736 |   resolution: "fill-range@npm:7.0.1"
 737 |   dependencies:
 738 |     to-regex-range: ^5.0.1
 739 |   checksum: cc283f4e65b504259e64fd969bcf4def4eb08d85565e906b7d36516e87819db52029a76b6363d0f02d0d532f0033c9603b9e2d943d56ee3b0d4f7ad3328ff917
 740 |   languageName: node
 741 |   linkType: hard
 742 | 
 743 | "fs-minipass@npm:^2.0.0, fs-minipass@npm:^2.1.0":
 744 |   version: 2.1.0
 745 |   resolution: "fs-minipass@npm:2.1.0"
 746 |   dependencies:
 747 |     minipass: ^3.0.0
 748 |   checksum: 1b8d128dae2ac6cc94230cc5ead341ba3e0efaef82dab46a33d171c044caaa6ca001364178d42069b2809c35a1c3c35079a32107c770e9ffab3901b59af8c8b1
 749 |   languageName: node
 750 |   linkType: hard
 751 | 
 752 | "fs.realpath@npm:^1.0.0":
 753 |   version: 1.0.0
 754 |   resolution: "fs.realpath@npm:1.0.0"
 755 |   checksum: 99ddea01a7e75aa276c250a04eedeffe5662bce66c65c07164ad6264f9de18fb21be9433ead460e54cff20e31721c811f4fb5d70591799df5f85dce6d6746fd0
 756 |   languageName: node
 757 |   linkType: hard
 758 | 
 759 | "fsevents@npm:~2.3.2":
 760 |   version: 2.3.2
 761 |   resolution: "fsevents@npm:2.3.2"
 762 |   dependencies:
 763 |     node-gyp: latest
 764 |   checksum: 97ade64e75091afee5265e6956cb72ba34db7819b4c3e94c431d4be2b19b8bb7a2d4116da417950c3425f17c8fe693d25e20212cac583ac1521ad066b77ae31f
 765 |   conditions: os=darwin
 766 |   languageName: node
 767 |   linkType: hard
 768 | 
 769 | "fsevents@patch:fsevents@~2.3.2#~builtin":
 770 |   version: 2.3.2
 771 |   resolution: "fsevents@patch:fsevents@npm%3A2.3.2#~builtin::version=2.3.2&hash=18f3a7"
 772 |   dependencies:
 773 |     node-gyp: latest
 774 |   conditions: os=darwin
 775 |   languageName: node
 776 |   linkType: hard
 777 | 
 778 | "function-bind@npm:^1.1.1":
 779 |   version: 1.1.1
 780 |   resolution: "function-bind@npm:1.1.1"
 781 |   checksum: b32fbaebb3f8ec4969f033073b43f5c8befbb58f1a79e12f1d7490358150359ebd92f49e72ff0144f65f2c48ea2a605bff2d07965f548f6474fd8efd95bf361a
 782 |   languageName: node
 783 |   linkType: hard
 784 | 
 785 | "gauge@npm:^4.0.3":
 786 |   version: 4.0.4
 787 |   resolution: "gauge@npm:4.0.4"
 788 |   dependencies:
 789 |     aproba: ^1.0.3 || ^2.0.0
 790 |     color-support: ^1.1.3
 791 |     console-control-strings: ^1.1.0
 792 |     has-unicode: ^2.0.1
 793 |     signal-exit: ^3.0.7
 794 |     string-width: ^4.2.3
 795 |     strip-ansi: ^6.0.1
 796 |     wide-align: ^1.1.5
 797 |   checksum: 788b6bfe52f1dd8e263cda800c26ac0ca2ff6de0b6eee2fe0d9e3abf15e149b651bd27bf5226be10e6e3edb5c4e5d5985a5a1a98137e7a892f75eff76467ad2d
 798 |   languageName: node
 799 |   linkType: hard
 800 | 
 801 | "get-stream@npm:^6.0.1":
 802 |   version: 6.0.1
 803 |   resolution: "get-stream@npm:6.0.1"
 804 |   checksum: e04ecece32c92eebf5b8c940f51468cd53554dcbb0ea725b2748be583c9523d00128137966afce410b9b051eb2ef16d657cd2b120ca8edafcf5a65e81af63cad
 805 |   languageName: node
 806 |   linkType: hard
 807 | 
 808 | "glob-parent@npm:~5.1.2":
 809 |   version: 5.1.2
 810 |   resolution: "glob-parent@npm:5.1.2"
 811 |   dependencies:
 812 |     is-glob: ^4.0.1
 813 |   checksum: f4f2bfe2425296e8a47e36864e4f42be38a996db40420fe434565e4480e3322f18eb37589617a98640c5dc8fdec1a387007ee18dbb1f3f5553409c34d17f425e
 814 |   languageName: node
 815 |   linkType: hard
 816 | 
 817 | "glob@npm:^7.1.3, glob@npm:^7.1.4":
 818 |   version: 7.2.3
 819 |   resolution: "glob@npm:7.2.3"
 820 |   dependencies:
 821 |     fs.realpath: ^1.0.0
 822 |     inflight: ^1.0.4
 823 |     inherits: 2
 824 |     minimatch: ^3.1.1
 825 |     once: ^1.3.0
 826 |     path-is-absolute: ^1.0.0
 827 |   checksum: 29452e97b38fa704dabb1d1045350fb2467cf0277e155aa9ff7077e90ad81d1ea9d53d3ee63bd37c05b09a065e90f16aec4a65f5b8de401d1dac40bc5605d133
 828 |   languageName: node
 829 |   linkType: hard
 830 | 
 831 | "glob@npm:^8.0.1":
 832 |   version: 8.0.3
 833 |   resolution: "glob@npm:8.0.3"
 834 |   dependencies:
 835 |     fs.realpath: ^1.0.0
 836 |     inflight: ^1.0.4
 837 |     inherits: 2
 838 |     minimatch: ^5.0.1
 839 |     once: ^1.3.0
 840 |   checksum: 50bcdea19d8e79d8de5f460b1939ffc2b3299eac28deb502093fdca22a78efebc03e66bf54f0abc3d3d07d8134d19a32850288b7440d77e072aa55f9d33b18c5
 841 |   languageName: node
 842 |   linkType: hard
 843 | 
 844 | "graceful-fs@npm:^4.2.6":
 845 |   version: 4.2.10
 846 |   resolution: "graceful-fs@npm:4.2.10"
 847 |   checksum: 3f109d70ae123951905d85032ebeae3c2a5a7a997430df00ea30df0e3a6c60cf6689b109654d6fdacd28810a053348c4d14642da1d075049e6be1ba5216218da
 848 |   languageName: node
 849 |   linkType: hard
 850 | 
 851 | "has-unicode@npm:^2.0.1":
 852 |   version: 2.0.1
 853 |   resolution: "has-unicode@npm:2.0.1"
 854 |   checksum: 1eab07a7436512db0be40a710b29b5dc21fa04880b7f63c9980b706683127e3c1b57cb80ea96d47991bdae2dfe479604f6a1ba410106ee1046a41d1bd0814400
 855 |   languageName: node
 856 |   linkType: hard
 857 | 
 858 | "has@npm:^1.0.3":
 859 |   version: 1.0.3
 860 |   resolution: "has@npm:1.0.3"
 861 |   dependencies:
 862 |     function-bind: ^1.1.1
 863 |   checksum: b9ad53d53be4af90ce5d1c38331e712522417d017d5ef1ebd0507e07c2fbad8686fffb8e12ddecd4c39ca9b9b47431afbb975b8abf7f3c3b82c98e9aad052792
 864 |   languageName: node
 865 |   linkType: hard
 866 | 
 867 | "http-cache-semantics@npm:^4.1.0":
 868 |   version: 4.1.0
 869 |   resolution: "http-cache-semantics@npm:4.1.0"
 870 |   checksum: 974de94a81c5474be07f269f9fd8383e92ebb5a448208223bfb39e172a9dbc26feff250192ecc23b9593b3f92098e010406b0f24bd4d588d631f80214648ed42
 871 |   languageName: node
 872 |   linkType: hard
 873 | 
 874 | "http-proxy-agent@npm:^5.0.0":
 875 |   version: 5.0.0
 876 |   resolution: "http-proxy-agent@npm:5.0.0"
 877 |   dependencies:
 878 |     "@tootallnate/once": 2
 879 |     agent-base: 6
 880 |     debug: 4
 881 |   checksum: e2ee1ff1656a131953839b2a19cd1f3a52d97c25ba87bd2559af6ae87114abf60971e498021f9b73f9fd78aea8876d1fb0d4656aac8a03c6caa9fc175f22b786
 882 |   languageName: node
 883 |   linkType: hard
 884 | 
 885 | "https-proxy-agent@npm:^5.0.0":
 886 |   version: 5.0.1
 887 |   resolution: "https-proxy-agent@npm:5.0.1"
 888 |   dependencies:
 889 |     agent-base: 6
 890 |     debug: 4
 891 |   checksum: 571fccdf38184f05943e12d37d6ce38197becdd69e58d03f43637f7fa1269cf303a7d228aa27e5b27bbd3af8f09fd938e1c91dcfefff2df7ba77c20ed8dfc765
 892 |   languageName: node
 893 |   linkType: hard
 894 | 
 895 | "human-signals@npm:^4.3.0":
 896 |   version: 4.3.1
 897 |   resolution: "human-signals@npm:4.3.1"
 898 |   checksum: 6f12958df3f21b6fdaf02d90896c271df00636a31e2bbea05bddf817a35c66b38a6fdac5863e2df85bd52f34958997f1f50350ff97249e1dff8452865d5235d1
 899 |   languageName: node
 900 |   linkType: hard
 901 | 
 902 | "humanize-ms@npm:^1.2.1":
 903 |   version: 1.2.1
 904 |   resolution: "humanize-ms@npm:1.2.1"
 905 |   dependencies:
 906 |     ms: ^2.0.0
 907 |   checksum: 9c7a74a2827f9294c009266c82031030eae811ca87b0da3dceb8d6071b9bde22c9f3daef0469c3c533cc67a97d8a167cd9fc0389350e5f415f61a79b171ded16
 908 |   languageName: node
 909 |   linkType: hard
 910 | 
 911 | "husky@npm:^8.0.3":
 912 |   version: 8.0.3
 913 |   resolution: "husky@npm:8.0.3"
 914 |   bin:
 915 |     husky: lib/bin.js
 916 |   checksum: 837bc7e4413e58c1f2946d38fb050f5d7324c6f16b0fd66411ffce5703b294bd21429e8ba58711cd331951ee86ed529c5be4f76805959ff668a337dbfa82a1b0
 917 |   languageName: node
 918 |   linkType: hard
 919 | 
 920 | "iconv-lite@npm:^0.6.2":
 921 |   version: 0.6.3
 922 |   resolution: "iconv-lite@npm:0.6.3"
 923 |   dependencies:
 924 |     safer-buffer: ">= 2.1.2 < 3.0.0"
 925 |   checksum: 3f60d47a5c8fc3313317edfd29a00a692cc87a19cac0159e2ce711d0ebc9019064108323b5e493625e25594f11c6236647d8e256fbe7a58f4a3b33b89e6d30bf
 926 |   languageName: node
 927 |   linkType: hard
 928 | 
 929 | "immutable@npm:^4.0.0":
 930 |   version: 4.1.0
 931 |   resolution: "immutable@npm:4.1.0"
 932 |   checksum: b9bc1f14fb18eb382d48339c064b24a1f97ae4cf43102e0906c0a6e186a27afcd18b55ca4a0b63c98eefb58143e2b5ebc7755a5fb4da4a7ad84b7a6096ac5b13
 933 |   languageName: node
 934 |   linkType: hard
 935 | 
 936 | "imurmurhash@npm:^0.1.4":
 937 |   version: 0.1.4
 938 |   resolution: "imurmurhash@npm:0.1.4"
 939 |   checksum: 7cae75c8cd9a50f57dadd77482359f659eaebac0319dd9368bcd1714f55e65badd6929ca58569da2b6494ef13fdd5598cd700b1eba23f8b79c5f19d195a3ecf7
 940 |   languageName: node
 941 |   linkType: hard
 942 | 
 943 | "indent-string@npm:^4.0.0":
 944 |   version: 4.0.0
 945 |   resolution: "indent-string@npm:4.0.0"
 946 |   checksum: 824cfb9929d031dabf059bebfe08cf3137365e112019086ed3dcff6a0a7b698cb80cf67ccccde0e25b9e2d7527aa6cc1fed1ac490c752162496caba3e6699612
 947 |   languageName: node
 948 |   linkType: hard
 949 | 
 950 | "infer-owner@npm:^1.0.4":
 951 |   version: 1.0.4
 952 |   resolution: "infer-owner@npm:1.0.4"
 953 |   checksum: 181e732764e4a0611576466b4b87dac338972b839920b2a8cde43642e4ed6bd54dc1fb0b40874728f2a2df9a1b097b8ff83b56d5f8f8e3927f837fdcb47d8a89
 954 |   languageName: node
 955 |   linkType: hard
 956 | 
 957 | "inflight@npm:^1.0.4":
 958 |   version: 1.0.6
 959 |   resolution: "inflight@npm:1.0.6"
 960 |   dependencies:
 961 |     once: ^1.3.0
 962 |     wrappy: 1
 963 |   checksum: f4f76aa072ce19fae87ce1ef7d221e709afb59d445e05d47fba710e85470923a75de35bfae47da6de1b18afc3ce83d70facf44cfb0aff89f0a3f45c0a0244dfd
 964 |   languageName: node
 965 |   linkType: hard
 966 | 
 967 | "inherits@npm:2, inherits@npm:^2.0.3":
 968 |   version: 2.0.4
 969 |   resolution: "inherits@npm:2.0.4"
 970 |   checksum: 4a48a733847879d6cf6691860a6b1e3f0f4754176e4d71494c41f3475553768b10f84b5ce1d40fbd0e34e6bfbb864ee35858ad4dd2cf31e02fc4a154b724d7f1
 971 |   languageName: node
 972 |   linkType: hard
 973 | 
 974 | "ip@npm:^2.0.0":
 975 |   version: 2.0.0
 976 |   resolution: "ip@npm:2.0.0"
 977 |   checksum: cfcfac6b873b701996d71ec82a7dd27ba92450afdb421e356f44044ed688df04567344c36cbacea7d01b1c39a4c732dc012570ebe9bebfb06f27314bca625349
 978 |   languageName: node
 979 |   linkType: hard
 980 | 
 981 | "is-binary-path@npm:~2.1.0":
 982 |   version: 2.1.0
 983 |   resolution: "is-binary-path@npm:2.1.0"
 984 |   dependencies:
 985 |     binary-extensions: ^2.0.0
 986 |   checksum: 84192eb88cff70d320426f35ecd63c3d6d495da9d805b19bc65b518984b7c0760280e57dbf119b7e9be6b161784a5a673ab2c6abe83abb5198a432232ad5b35c
 987 |   languageName: node
 988 |   linkType: hard
 989 | 
 990 | "is-core-module@npm:^2.12.0":
 991 |   version: 2.12.0
 992 |   resolution: "is-core-module@npm:2.12.0"
 993 |   dependencies:
 994 |     has: ^1.0.3
 995 |   checksum: f7f7eb2ab71fd769ee9fb2385c095d503aa4b5ce0028c04557de03f1e67a87c85e5bac1f215945fc3c955867a139a415a3ec4c4234a0bffdf715232660f440a6
 996 |   languageName: node
 997 |   linkType: hard
 998 | 
 999 | "is-extglob@npm:^2.1.1":
1000 |   version: 2.1.1
1001 |   resolution: "is-extglob@npm:2.1.1"
1002 |   checksum: df033653d06d0eb567461e58a7a8c9f940bd8c22274b94bf7671ab36df5719791aae15eef6d83bbb5e23283967f2f984b8914559d4449efda578c775c4be6f85
1003 |   languageName: node
1004 |   linkType: hard
1005 | 
1006 | "is-fullwidth-code-point@npm:^3.0.0":
1007 |   version: 3.0.0
1008 |   resolution: "is-fullwidth-code-point@npm:3.0.0"
1009 |   checksum: 44a30c29457c7fb8f00297bce733f0a64cd22eca270f83e58c105e0d015e45c019491a4ab2faef91ab51d4738c670daff901c799f6a700e27f7314029e99e348
1010 |   languageName: node
1011 |   linkType: hard
1012 | 
1013 | "is-fullwidth-code-point@npm:^4.0.0":
1014 |   version: 4.0.0
1015 |   resolution: "is-fullwidth-code-point@npm:4.0.0"
1016 |   checksum: 8ae89bf5057bdf4f57b346fb6c55e9c3dd2549983d54191d722d5c739397a903012cc41a04ee3403fd872e811243ef91a7c5196da7b5841dc6b6aae31a264a8d
1017 |   languageName: node
1018 |   linkType: hard
1019 | 
1020 | "is-glob@npm:^4.0.1, is-glob@npm:~4.0.1":
1021 |   version: 4.0.3
1022 |   resolution: "is-glob@npm:4.0.3"
1023 |   dependencies:
1024 |     is-extglob: ^2.1.1
1025 |   checksum: d381c1319fcb69d341cc6e6c7cd588e17cd94722d9a32dbd60660b993c4fb7d0f19438674e68dfec686d09b7c73139c9166b47597f846af387450224a8101ab4
1026 |   languageName: node
1027 |   linkType: hard
1028 | 
1029 | "is-lambda@npm:^1.0.1":
1030 |   version: 1.0.1
1031 |   resolution: "is-lambda@npm:1.0.1"
1032 |   checksum: 93a32f01940220532e5948538699ad610d5924ac86093fcee83022252b363eb0cc99ba53ab084a04e4fb62bf7b5731f55496257a4c38adf87af9c4d352c71c35
1033 |   languageName: node
1034 |   linkType: hard
1035 | 
1036 | "is-number@npm:^7.0.0":
1037 |   version: 7.0.0
1038 |   resolution: "is-number@npm:7.0.0"
1039 |   checksum: 456ac6f8e0f3111ed34668a624e45315201dff921e5ac181f8ec24923b99e9f32ca1a194912dc79d539c97d33dba17dc635202ff0b2cf98326f608323276d27a
1040 |   languageName: node
1041 |   linkType: hard
1042 | 
1043 | "is-stream@npm:^3.0.0":
1044 |   version: 3.0.0
1045 |   resolution: "is-stream@npm:3.0.0"
1046 |   checksum: 172093fe99119ffd07611ab6d1bcccfe8bc4aa80d864b15f43e63e54b7abc71e779acd69afdb854c4e2a67fdc16ae710e370eda40088d1cfc956a50ed82d8f16
1047 |   languageName: node
1048 |   linkType: hard
1049 | 
1050 | "isexe@npm:^2.0.0":
1051 |   version: 2.0.0
1052 |   resolution: "isexe@npm:2.0.0"
1053 |   checksum: 26bf6c5480dda5161c820c5b5c751ae1e766c587b1f951ea3fcfc973bafb7831ae5b54a31a69bd670220e42e99ec154475025a468eae58ea262f813fdc8d1c62
1054 |   languageName: node
1055 |   linkType: hard
1056 | 
1057 | "lil-gui@npm:^0.18.1":
1058 |   version: 0.18.1
1059 |   resolution: "lil-gui@npm:0.18.1"
1060 |   checksum: b2e54eb23542d2620dce606603390697127da6c4ad3ed275bc47b3c6692d2b6a17c73e7d14389c1121cfe061d108d7f136e43f22bfad16a17a5caede8b7653fa
1061 |   languageName: node
1062 |   linkType: hard
1063 | 
1064 | "lil-gui@npm:~0.17.0":
1065 |   version: 0.17.0
1066 |   resolution: "lil-gui@npm:0.17.0"
1067 |   checksum: a6f33e90748ea98477f1f7af6d6cbdc4a1b38ce9da86d674d73f7b0bbdc7f3e947d81edee04c32f33fb28c69a108ba04c24270a8398064ffcc56ffeabc0a916e
1068 |   languageName: node
1069 |   linkType: hard
1070 | 
1071 | "lilconfig@npm:2.1.0":
1072 |   version: 2.1.0
1073 |   resolution: "lilconfig@npm:2.1.0"
1074 |   checksum: 8549bb352b8192375fed4a74694cd61ad293904eee33f9d4866c2192865c44c4eb35d10782966242634e0cbc1e91fe62b1247f148dc5514918e3a966da7ea117
1075 |   languageName: node
1076 |   linkType: hard
1077 | 
1078 | "lint-staged@npm:^13.2.1":
1079 |   version: 13.2.1
1080 |   resolution: "lint-staged@npm:13.2.1"
1081 |   dependencies:
1082 |     chalk: 5.2.0
1083 |     cli-truncate: ^3.1.0
1084 |     commander: ^10.0.0
1085 |     debug: ^4.3.4
1086 |     execa: ^7.0.0
1087 |     lilconfig: 2.1.0
1088 |     listr2: ^5.0.7
1089 |     micromatch: ^4.0.5
1090 |     normalize-path: ^3.0.0
1091 |     object-inspect: ^1.12.3
1092 |     pidtree: ^0.6.0
1093 |     string-argv: ^0.3.1
1094 |     yaml: ^2.2.1
1095 |   bin:
1096 |     lint-staged: bin/lint-staged.js
1097 |   checksum: 5788d3fe38e69b7f7b7f700284d4e10738978a0916bc77d3f6253c43a030fc4f01f89c09da349fb658f929f3393d8b1e3eaabaac5b604416ebc33476640b51ce
1098 |   languageName: node
1099 |   linkType: hard
1100 | 
1101 | "listr2@npm:^5.0.7":
1102 |   version: 5.0.8
1103 |   resolution: "listr2@npm:5.0.8"
1104 |   dependencies:
1105 |     cli-truncate: ^2.1.0
1106 |     colorette: ^2.0.19
1107 |     log-update: ^4.0.0
1108 |     p-map: ^4.0.0
1109 |     rfdc: ^1.3.0
1110 |     rxjs: ^7.8.0
1111 |     through: ^2.3.8
1112 |     wrap-ansi: ^7.0.0
1113 |   peerDependencies:
1114 |     enquirer: ">= 2.3.0 < 3"
1115 |   peerDependenciesMeta:
1116 |     enquirer:
1117 |       optional: true
1118 |   checksum: 8be9f5632627c4df0dc33f452c98d415a49e5f1614650d3cab1b103c33e95f2a7a0e9f3e1e5de00d51bf0b4179acd8ff11b25be77dbe097cf3773c05e728d46c
1119 |   languageName: node
1120 |   linkType: hard
1121 | 
1122 | "log-update@npm:^4.0.0":
1123 |   version: 4.0.0
1124 |   resolution: "log-update@npm:4.0.0"
1125 |   dependencies:
1126 |     ansi-escapes: ^4.3.0
1127 |     cli-cursor: ^3.1.0
1128 |     slice-ansi: ^4.0.0
1129 |     wrap-ansi: ^6.2.0
1130 |   checksum: ae2f85bbabc1906034154fb7d4c4477c79b3e703d22d78adee8b3862fa913942772e7fa11713e3d96fb46de4e3cabefbf5d0a544344f03b58d3c4bff52aa9eb2
1131 |   languageName: node
1132 |   linkType: hard
1133 | 
1134 | "lru-cache@npm:^6.0.0":
1135 |   version: 6.0.0
1136 |   resolution: "lru-cache@npm:6.0.0"
1137 |   dependencies:
1138 |     yallist: ^4.0.0
1139 |   checksum: f97f499f898f23e4585742138a22f22526254fdba6d75d41a1c2526b3b6cc5747ef59c5612ba7375f42aca4f8461950e925ba08c991ead0651b4918b7c978297
1140 |   languageName: node
1141 |   linkType: hard
1142 | 
1143 | "lru-cache@npm:^7.7.1":
1144 |   version: 7.13.1
1145 |   resolution: "lru-cache@npm:7.13.1"
1146 |   checksum: f53c7dd098a7afd6342b23f7182629edff206c7665de79445a7f5455440e768a4d1c6ec52e1a16175580c71535c9437dfb6f6bc22ca1a0e4a7454a97cde87329
1147 |   languageName: node
1148 |   linkType: hard
1149 | 
1150 | "make-fetch-happen@npm:^10.0.3":
1151 |   version: 10.2.0
1152 |   resolution: "make-fetch-happen@npm:10.2.0"
1153 |   dependencies:
1154 |     agentkeepalive: ^4.2.1
1155 |     cacache: ^16.1.0
1156 |     http-cache-semantics: ^4.1.0
1157 |     http-proxy-agent: ^5.0.0
1158 |     https-proxy-agent: ^5.0.0
1159 |     is-lambda: ^1.0.1
1160 |     lru-cache: ^7.7.1
1161 |     minipass: ^3.1.6
1162 |     minipass-collect: ^1.0.2
1163 |     minipass-fetch: ^2.0.3
1164 |     minipass-flush: ^1.0.5
1165 |     minipass-pipeline: ^1.2.4
1166 |     negotiator: ^0.6.3
1167 |     promise-retry: ^2.0.1
1168 |     socks-proxy-agent: ^7.0.0
1169 |     ssri: ^9.0.0
1170 |   checksum: 2f6c294179972f56fab40fd8618f07841e06550692bb78f6da16e7afaa9dca78c345b08cf44a77a8907ef3948e4dc77e93eb7492b8381f1217d7ac057a7522f8
1171 |   languageName: node
1172 |   linkType: hard
1173 | 
1174 | "merge-stream@npm:^2.0.0":
1175 |   version: 2.0.0
1176 |   resolution: "merge-stream@npm:2.0.0"
1177 |   checksum: 6fa4dcc8d86629705cea944a4b88ef4cb0e07656ebf223fa287443256414283dd25d91c1cd84c77987f2aec5927af1a9db6085757cb43d90eb170ebf4b47f4f4
1178 |   languageName: node
1179 |   linkType: hard
1180 | 
1181 | "micromatch@npm:^4.0.5":
1182 |   version: 4.0.5
1183 |   resolution: "micromatch@npm:4.0.5"
1184 |   dependencies:
1185 |     braces: ^3.0.2
1186 |     picomatch: ^2.3.1
1187 |   checksum: 02a17b671c06e8fefeeb6ef996119c1e597c942e632a21ef589154f23898c9c6a9858526246abb14f8bca6e77734aa9dcf65476fca47cedfb80d9577d52843fc
1188 |   languageName: node
1189 |   linkType: hard
1190 | 
1191 | "mimic-fn@npm:^2.1.0":
1192 |   version: 2.1.0
1193 |   resolution: "mimic-fn@npm:2.1.0"
1194 |   checksum: d2421a3444848ce7f84bd49115ddacff29c15745db73f54041edc906c14b131a38d05298dae3081667627a59b2eb1ca4b436ff2e1b80f69679522410418b478a
1195 |   languageName: node
1196 |   linkType: hard
1197 | 
1198 | "mimic-fn@npm:^4.0.0":
1199 |   version: 4.0.0
1200 |   resolution: "mimic-fn@npm:4.0.0"
1201 |   checksum: 995dcece15ee29aa16e188de6633d43a3db4611bcf93620e7e62109ec41c79c0f34277165b8ce5e361205049766e371851264c21ac64ca35499acb5421c2ba56
1202 |   languageName: node
1203 |   linkType: hard
1204 | 
1205 | "minimatch@npm:^3.1.1":
1206 |   version: 3.1.2
1207 |   resolution: "minimatch@npm:3.1.2"
1208 |   dependencies:
1209 |     brace-expansion: ^1.1.7
1210 |   checksum: c154e566406683e7bcb746e000b84d74465b3a832c45d59912b9b55cd50dee66e5c4b1e5566dba26154040e51672f9aa450a9aef0c97cfc7336b78b7afb9540a
1211 |   languageName: node
1212 |   linkType: hard
1213 | 
1214 | "minimatch@npm:^5.0.1":
1215 |   version: 5.1.0
1216 |   resolution: "minimatch@npm:5.1.0"
1217 |   dependencies:
1218 |     brace-expansion: ^2.0.1
1219 |   checksum: 15ce53d31a06361e8b7a629501b5c75491bc2b59712d53e802b1987121d91b433d73fcc5be92974fde66b2b51d8fb28d75a9ae900d249feb792bb1ba2a4f0a90
1220 |   languageName: node
1221 |   linkType: hard
1222 | 
1223 | "minipass-collect@npm:^1.0.2":
1224 |   version: 1.0.2
1225 |   resolution: "minipass-collect@npm:1.0.2"
1226 |   dependencies:
1227 |     minipass: ^3.0.0
1228 |   checksum: 14df761028f3e47293aee72888f2657695ec66bd7d09cae7ad558da30415fdc4752bbfee66287dcc6fd5e6a2fa3466d6c484dc1cbd986525d9393b9523d97f10
1229 |   languageName: node
1230 |   linkType: hard
1231 | 
1232 | "minipass-fetch@npm:^2.0.3":
1233 |   version: 2.1.0
1234 |   resolution: "minipass-fetch@npm:2.1.0"
1235 |   dependencies:
1236 |     encoding: ^0.1.13
1237 |     minipass: ^3.1.6
1238 |     minipass-sized: ^1.0.3
1239 |     minizlib: ^2.1.2
1240 |   dependenciesMeta:
1241 |     encoding:
1242 |       optional: true
1243 |   checksum: 1334732859a3f7959ed22589bafd9c40384b885aebb5932328071c33f86b3eb181d54c86919675d1825ab5f1c8e4f328878c863873258d113c29d79a4b0c9c9f
1244 |   languageName: node
1245 |   linkType: hard
1246 | 
1247 | "minipass-flush@npm:^1.0.5":
1248 |   version: 1.0.5
1249 |   resolution: "minipass-flush@npm:1.0.5"
1250 |   dependencies:
1251 |     minipass: ^3.0.0
1252 |   checksum: 56269a0b22bad756a08a94b1ffc36b7c9c5de0735a4dd1ab2b06c066d795cfd1f0ac44a0fcae13eece5589b908ecddc867f04c745c7009be0b566421ea0944cf
1253 |   languageName: node
1254 |   linkType: hard
1255 | 
1256 | "minipass-pipeline@npm:^1.2.4":
1257 |   version: 1.2.4
1258 |   resolution: "minipass-pipeline@npm:1.2.4"
1259 |   dependencies:
1260 |     minipass: ^3.0.0
1261 |   checksum: b14240dac0d29823c3d5911c286069e36d0b81173d7bdf07a7e4a91ecdef92cdff4baaf31ea3746f1c61e0957f652e641223970870e2353593f382112257971b
1262 |   languageName: node
1263 |   linkType: hard
1264 | 
1265 | "minipass-sized@npm:^1.0.3":
1266 |   version: 1.0.3
1267 |   resolution: "minipass-sized@npm:1.0.3"
1268 |   dependencies:
1269 |     minipass: ^3.0.0
1270 |   checksum: 79076749fcacf21b5d16dd596d32c3b6bf4d6e62abb43868fac21674078505c8b15eaca4e47ed844985a4514854f917d78f588fcd029693709417d8f98b2bd60
1271 |   languageName: node
1272 |   linkType: hard
1273 | 
1274 | "minipass@npm:^3.0.0, minipass@npm:^3.1.1, minipass@npm:^3.1.6":
1275 |   version: 3.3.4
1276 |   resolution: "minipass@npm:3.3.4"
1277 |   dependencies:
1278 |     yallist: ^4.0.0
1279 |   checksum: 5d95a7738c54852ba78d484141e850c792e062666a2d0c681a5ac1021275beb7e1acb077e59f9523ff1defb80901aea4e30fac10ded9a20a25d819a42916ef1b
1280 |   languageName: node
1281 |   linkType: hard
1282 | 
1283 | "minizlib@npm:^2.1.1, minizlib@npm:^2.1.2":
1284 |   version: 2.1.2
1285 |   resolution: "minizlib@npm:2.1.2"
1286 |   dependencies:
1287 |     minipass: ^3.0.0
1288 |     yallist: ^4.0.0
1289 |   checksum: f1fdeac0b07cf8f30fcf12f4b586795b97be856edea22b5e9072707be51fc95d41487faec3f265b42973a304fe3a64acd91a44a3826a963e37b37bafde0212c3
1290 |   languageName: node
1291 |   linkType: hard
1292 | 
1293 | "mkdirp@npm:^1.0.3, mkdirp@npm:^1.0.4":
1294 |   version: 1.0.4
1295 |   resolution: "mkdirp@npm:1.0.4"
1296 |   bin:
1297 |     mkdirp: bin/cmd.js
1298 |   checksum: a96865108c6c3b1b8e1d5e9f11843de1e077e57737602de1b82030815f311be11f96f09cce59bd5b903d0b29834733e5313f9301e3ed6d6f6fba2eae0df4298f
1299 |   languageName: node
1300 |   linkType: hard
1301 | 
1302 | "ms@npm:2.1.2":
1303 |   version: 2.1.2
1304 |   resolution: "ms@npm:2.1.2"
1305 |   checksum: 673cdb2c3133eb050c745908d8ce632ed2c02d85640e2edb3ace856a2266a813b30c613569bf3354fdf4ea7d1a1494add3bfa95e2713baa27d0c2c71fc44f58f
1306 |   languageName: node
1307 |   linkType: hard
1308 | 
1309 | "ms@npm:^2.0.0":
1310 |   version: 2.1.3
1311 |   resolution: "ms@npm:2.1.3"
1312 |   checksum: aa92de608021b242401676e35cfa5aa42dd70cbdc082b916da7fb925c542173e36bce97ea3e804923fe92c0ad991434e4a38327e15a1b5b5f945d66df615ae6d
1313 |   languageName: node
1314 |   linkType: hard
1315 | 
1316 | "nanoid@npm:^3.3.6":
1317 |   version: 3.3.6
1318 |   resolution: "nanoid@npm:3.3.6"
1319 |   bin:
1320 |     nanoid: bin/nanoid.cjs
1321 |   checksum: 7d0eda657002738aa5206107bd0580aead6c95c460ef1bdd0b1a87a9c7ae6277ac2e9b945306aaa5b32c6dcb7feaf462d0f552e7f8b5718abfc6ead5c94a71b3
1322 |   languageName: node
1323 |   linkType: hard
1324 | 
1325 | "negotiator@npm:^0.6.3":
1326 |   version: 0.6.3
1327 |   resolution: "negotiator@npm:0.6.3"
1328 |   checksum: b8ffeb1e262eff7968fc90a2b6767b04cfd9842582a9d0ece0af7049537266e7b2506dfb1d107a32f06dd849ab2aea834d5830f7f4d0e5cb7d36e1ae55d021d9
1329 |   languageName: node
1330 |   linkType: hard
1331 | 
1332 | "node-gyp@npm:latest":
1333 |   version: 9.1.0
1334 |   resolution: "node-gyp@npm:9.1.0"
1335 |   dependencies:
1336 |     env-paths: ^2.2.0
1337 |     glob: ^7.1.4
1338 |     graceful-fs: ^4.2.6
1339 |     make-fetch-happen: ^10.0.3
1340 |     nopt: ^5.0.0
1341 |     npmlog: ^6.0.0
1342 |     rimraf: ^3.0.2
1343 |     semver: ^7.3.5
1344 |     tar: ^6.1.2
1345 |     which: ^2.0.2
1346 |   bin:
1347 |     node-gyp: bin/node-gyp.js
1348 |   checksum: 1437fa4a879b5b9010604128e8da8609b57c66034262087539ee04a8b764b8436af2be01bab66f8fc729a3adba2dcc21b10a32b9f552696c3fa8cd657d134fc4
1349 |   languageName: node
1350 |   linkType: hard
1351 | 
1352 | "nopt@npm:^5.0.0":
1353 |   version: 5.0.0
1354 |   resolution: "nopt@npm:5.0.0"
1355 |   dependencies:
1356 |     abbrev: 1
1357 |   bin:
1358 |     nopt: bin/nopt.js
1359 |   checksum: d35fdec187269503843924e0114c0c6533fb54bbf1620d0f28b4b60ba01712d6687f62565c55cc20a504eff0fbe5c63e22340c3fad549ad40469ffb611b04f2f
1360 |   languageName: node
1361 |   linkType: hard
1362 | 
1363 | "normalize-path@npm:^3.0.0, normalize-path@npm:~3.0.0":
1364 |   version: 3.0.0
1365 |   resolution: "normalize-path@npm:3.0.0"
1366 |   checksum: 88eeb4da891e10b1318c4b2476b6e2ecbeb5ff97d946815ffea7794c31a89017c70d7f34b3c2ebf23ef4e9fc9fb99f7dffe36da22011b5b5c6ffa34f4873ec20
1367 |   languageName: node
1368 |   linkType: hard
1369 | 
1370 | "npm-run-path@npm:^5.1.0":
1371 |   version: 5.1.0
1372 |   resolution: "npm-run-path@npm:5.1.0"
1373 |   dependencies:
1374 |     path-key: ^4.0.0
1375 |   checksum: dc184eb5ec239d6a2b990b43236845332ef12f4e0beaa9701de724aa797fe40b6bbd0157fb7639d24d3ab13f5d5cf22d223a19c6300846b8126f335f788bee66
1376 |   languageName: node
1377 |   linkType: hard
1378 | 
1379 | "npmlog@npm:^6.0.0":
1380 |   version: 6.0.2
1381 |   resolution: "npmlog@npm:6.0.2"
1382 |   dependencies:
1383 |     are-we-there-yet: ^3.0.0
1384 |     console-control-strings: ^1.1.0
1385 |     gauge: ^4.0.3
1386 |     set-blocking: ^2.0.0
1387 |   checksum: ae238cd264a1c3f22091cdd9e2b106f684297d3c184f1146984ecbe18aaa86343953f26b9520dedd1b1372bc0316905b736c1932d778dbeb1fcf5a1001390e2a
1388 |   languageName: node
1389 |   linkType: hard
1390 | 
1391 | "object-inspect@npm:^1.12.3":
1392 |   version: 1.12.3
1393 |   resolution: "object-inspect@npm:1.12.3"
1394 |   checksum: dabfd824d97a5f407e6d5d24810d888859f6be394d8b733a77442b277e0808860555176719c5905e765e3743a7cada6b8b0a3b85e5331c530fd418cc8ae991db
1395 |   languageName: node
1396 |   linkType: hard
1397 | 
1398 | "once@npm:^1.3.0":
1399 |   version: 1.4.0
1400 |   resolution: "once@npm:1.4.0"
1401 |   dependencies:
1402 |     wrappy: 1
1403 |   checksum: cd0a88501333edd640d95f0d2700fbde6bff20b3d4d9bdc521bdd31af0656b5706570d6c6afe532045a20bb8dc0849f8332d6f2a416e0ba6d3d3b98806c7db68
1404 |   languageName: node
1405 |   linkType: hard
1406 | 
1407 | "onetime@npm:^5.1.0":
1408 |   version: 5.1.2
1409 |   resolution: "onetime@npm:5.1.2"
1410 |   dependencies:
1411 |     mimic-fn: ^2.1.0
1412 |   checksum: 2478859ef817fc5d4e9c2f9e5728512ddd1dbc9fb7829ad263765bb6d3b91ce699d6e2332eef6b7dff183c2f490bd3349f1666427eaba4469fba0ac38dfd0d34
1413 |   languageName: node
1414 |   linkType: hard
1415 | 
1416 | "onetime@npm:^6.0.0":
1417 |   version: 6.0.0
1418 |   resolution: "onetime@npm:6.0.0"
1419 |   dependencies:
1420 |     mimic-fn: ^4.0.0
1421 |   checksum: 0846ce78e440841335d4e9182ef69d5762e9f38aa7499b19f42ea1c4cd40f0b4446094c455c713f9adac3f4ae86f613bb5e30c99e52652764d06a89f709b3788
1422 |   languageName: node
1423 |   linkType: hard
1424 | 
1425 | "p-map@npm:^4.0.0":
1426 |   version: 4.0.0
1427 |   resolution: "p-map@npm:4.0.0"
1428 |   dependencies:
1429 |     aggregate-error: ^3.0.0
1430 |   checksum: cb0ab21ec0f32ddffd31dfc250e3afa61e103ef43d957cc45497afe37513634589316de4eb88abdfd969fe6410c22c0b93ab24328833b8eb1ccc087fc0442a1c
1431 |   languageName: node
1432 |   linkType: hard
1433 | 
1434 | "path-is-absolute@npm:^1.0.0":
1435 |   version: 1.0.1
1436 |   resolution: "path-is-absolute@npm:1.0.1"
1437 |   checksum: 060840f92cf8effa293bcc1bea81281bd7d363731d214cbe5c227df207c34cd727430f70c6037b5159c8a870b9157cba65e775446b0ab06fd5ecc7e54615a3b8
1438 |   languageName: node
1439 |   linkType: hard
1440 | 
1441 | "path-key@npm:^3.1.0":
1442 |   version: 3.1.1
1443 |   resolution: "path-key@npm:3.1.1"
1444 |   checksum: 55cd7a9dd4b343412a8386a743f9c746ef196e57c823d90ca3ab917f90ab9f13dd0ded27252ba49dbdfcab2b091d998bc446f6220cd3cea65db407502a740020
1445 |   languageName: node
1446 |   linkType: hard
1447 | 
1448 | "path-key@npm:^4.0.0":
1449 |   version: 4.0.0
1450 |   resolution: "path-key@npm:4.0.0"
1451 |   checksum: 8e6c314ae6d16b83e93032c61020129f6f4484590a777eed709c4a01b50e498822b00f76ceaf94bc64dbd90b327df56ceadce27da3d83393790f1219e07721d7
1452 |   languageName: node
1453 |   linkType: hard
1454 | 
1455 | "path-parse@npm:^1.0.7":
1456 |   version: 1.0.7
1457 |   resolution: "path-parse@npm:1.0.7"
1458 |   checksum: 49abf3d81115642938a8700ec580da6e830dde670be21893c62f4e10bd7dd4c3742ddc603fe24f898cba7eb0c6bc1777f8d9ac14185d34540c6d4d80cd9cae8a
1459 |   languageName: node
1460 |   linkType: hard
1461 | 
1462 | "picocolors@npm:^1.0.0":
1463 |   version: 1.0.0
1464 |   resolution: "picocolors@npm:1.0.0"
1465 |   checksum: a2e8092dd86c8396bdba9f2b5481032848525b3dc295ce9b57896f931e63fc16f79805144321f72976383fc249584672a75cc18d6777c6b757603f372f745981
1466 |   languageName: node
1467 |   linkType: hard
1468 | 
1469 | "picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.3.1":
1470 |   version: 2.3.1
1471 |   resolution: "picomatch@npm:2.3.1"
1472 |   checksum: 050c865ce81119c4822c45d3c84f1ced46f93a0126febae20737bd05ca20589c564d6e9226977df859ed5e03dc73f02584a2b0faad36e896936238238b0446cf
1473 |   languageName: node
1474 |   linkType: hard
1475 | 
1476 | "pidtree@npm:^0.6.0":
1477 |   version: 0.6.0
1478 |   resolution: "pidtree@npm:0.6.0"
1479 |   bin:
1480 |     pidtree: bin/pidtree.js
1481 |   checksum: 8fbc073ede9209dd15e80d616e65eb674986c93be49f42d9ddde8dbbd141bb53d628a7ca4e58ab5c370bb00383f67d75df59a9a226dede8fa801267a7030c27a
1482 |   languageName: node
1483 |   linkType: hard
1484 | 
1485 | "postcss@npm:^8.4.21":
1486 |   version: 8.4.23
1487 |   resolution: "postcss@npm:8.4.23"
1488 |   dependencies:
1489 |     nanoid: ^3.3.6
1490 |     picocolors: ^1.0.0
1491 |     source-map-js: ^1.0.2
1492 |   checksum: 8bb9d1b2ea6e694f8987d4f18c94617971b2b8d141602725fedcc2222fdc413b776a6e1b969a25d627d7b2681ca5aabb56f59e727ef94072e1b6ac8412105a2f
1493 |   languageName: node
1494 |   linkType: hard
1495 | 
1496 | "prettier@npm:2.8.7":
1497 |   version: 2.8.7
1498 |   resolution: "prettier@npm:2.8.7"
1499 |   bin:
1500 |     prettier: bin-prettier.js
1501 |   checksum: fdc8f2616f099f5f0d685907f4449a70595a0fc1d081a88919604375989e0d5e9168d6121d8cc6861f21990b31665828e00472544d785d5940ea08a17660c3a6
1502 |   languageName: node
1503 |   linkType: hard
1504 | 
1505 | "promise-inflight@npm:^1.0.1":
1506 |   version: 1.0.1
1507 |   resolution: "promise-inflight@npm:1.0.1"
1508 |   checksum: 22749483091d2c594261517f4f80e05226d4d5ecc1fc917e1886929da56e22b5718b7f2a75f3807e7a7d471bc3be2907fe92e6e8f373ddf5c64bae35b5af3981
1509 |   languageName: node
1510 |   linkType: hard
1511 | 
1512 | "promise-retry@npm:^2.0.1":
1513 |   version: 2.0.1
1514 |   resolution: "promise-retry@npm:2.0.1"
1515 |   dependencies:
1516 |     err-code: ^2.0.2
1517 |     retry: ^0.12.0
1518 |   checksum: f96a3f6d90b92b568a26f71e966cbbc0f63ab85ea6ff6c81284dc869b41510e6cdef99b6b65f9030f0db422bf7c96652a3fff9f2e8fb4a0f069d8f4430359429
1519 |   languageName: node
1520 |   linkType: hard
1521 | 
1522 | "readable-stream@npm:^3.6.0":
1523 |   version: 3.6.0
1524 |   resolution: "readable-stream@npm:3.6.0"
1525 |   dependencies:
1526 |     inherits: ^2.0.3
1527 |     string_decoder: ^1.1.1
1528 |     util-deprecate: ^1.0.1
1529 |   checksum: d4ea81502d3799439bb955a3a5d1d808592cf3133350ed352aeaa499647858b27b1c4013984900238b0873ec8d0d8defce72469fb7a83e61d53f5ad61cb80dc8
1530 |   languageName: node
1531 |   linkType: hard
1532 | 
1533 | "readdirp@npm:~3.6.0":
1534 |   version: 3.6.0
1535 |   resolution: "readdirp@npm:3.6.0"
1536 |   dependencies:
1537 |     picomatch: ^2.2.1
1538 |   checksum: 1ced032e6e45670b6d7352d71d21ce7edf7b9b928494dcaba6f11fba63180d9da6cd7061ebc34175ffda6ff529f481818c962952004d273178acd70f7059b320
1539 |   languageName: node
1540 |   linkType: hard
1541 | 
1542 | "resolve@npm:^1.22.1":
1543 |   version: 1.22.3
1544 |   resolution: "resolve@npm:1.22.3"
1545 |   dependencies:
1546 |     is-core-module: ^2.12.0
1547 |     path-parse: ^1.0.7
1548 |     supports-preserve-symlinks-flag: ^1.0.0
1549 |   bin:
1550 |     resolve: bin/resolve
1551 |   checksum: fb834b81348428cb545ff1b828a72ea28feb5a97c026a1cf40aa1008352c72811ff4d4e71f2035273dc536dcfcae20c13604ba6283c612d70fa0b6e44519c374
1552 |   languageName: node
1553 |   linkType: hard
1554 | 
1555 | "resolve@patch:resolve@^1.22.1#~builtin":
1556 |   version: 1.22.3
1557 |   resolution: "resolve@patch:resolve@npm%3A1.22.3#~builtin::version=1.22.3&hash=07638b"
1558 |   dependencies:
1559 |     is-core-module: ^2.12.0
1560 |     path-parse: ^1.0.7
1561 |     supports-preserve-symlinks-flag: ^1.0.0
1562 |   bin:
1563 |     resolve: bin/resolve
1564 |   checksum: ad59734723b596d0891321c951592ed9015a77ce84907f89c9d9307dd0c06e11a67906a3e628c4cae143d3e44898603478af0ddeb2bba3f229a9373efe342665
1565 |   languageName: node
1566 |   linkType: hard
1567 | 
1568 | "restore-cursor@npm:^3.1.0":
1569 |   version: 3.1.0
1570 |   resolution: "restore-cursor@npm:3.1.0"
1571 |   dependencies:
1572 |     onetime: ^5.1.0
1573 |     signal-exit: ^3.0.2
1574 |   checksum: f877dd8741796b909f2a82454ec111afb84eb45890eb49ac947d87991379406b3b83ff9673a46012fca0d7844bb989f45cc5b788254cf1a39b6b5a9659de0630
1575 |   languageName: node
1576 |   linkType: hard
1577 | 
1578 | "retry@npm:^0.12.0":
1579 |   version: 0.12.0
1580 |   resolution: "retry@npm:0.12.0"
1581 |   checksum: 623bd7d2e5119467ba66202d733ec3c2e2e26568074923bc0585b6b99db14f357e79bdedb63cab56cec47491c4a0da7e6021a7465ca6dc4f481d3898fdd3158c
1582 |   languageName: node
1583 |   linkType: hard
1584 | 
1585 | "rfdc@npm:^1.3.0":
1586 |   version: 1.3.0
1587 |   resolution: "rfdc@npm:1.3.0"
1588 |   checksum: fb2ba8512e43519983b4c61bd3fa77c0f410eff6bae68b08614437bc3f35f91362215f7b4a73cbda6f67330b5746ce07db5dd9850ad3edc91271ad6deea0df32
1589 |   languageName: node
1590 |   linkType: hard
1591 | 
1592 | "rimraf@npm:^3.0.2":
1593 |   version: 3.0.2
1594 |   resolution: "rimraf@npm:3.0.2"
1595 |   dependencies:
1596 |     glob: ^7.1.3
1597 |   bin:
1598 |     rimraf: bin.js
1599 |   checksum: 87f4164e396f0171b0a3386cc1877a817f572148ee13a7e113b238e48e8a9f2f31d009a92ec38a591ff1567d9662c6b67fd8818a2dbbaed74bc26a87a2a4a9a0
1600 |   languageName: node
1601 |   linkType: hard
1602 | 
1603 | "rollup@npm:^3.18.0":
1604 |   version: 3.20.6
1605 |   resolution: "rollup@npm:3.20.6"
1606 |   dependencies:
1607 |     fsevents: ~2.3.2
1608 |   dependenciesMeta:
1609 |     fsevents:
1610 |       optional: true
1611 |   bin:
1612 |     rollup: dist/bin/rollup
1613 |   checksum: fa30f1e1d214b8c62e631d3c181a75d61bc9c20fca38220d6f938bb3bf734a874e407cd641c90f550dc2b127df5029dfb3108be08934a654f1f40b50f368b0c2
1614 |   languageName: node
1615 |   linkType: hard
1616 | 
1617 | "rxjs@npm:^7.8.0":
1618 |   version: 7.8.0
1619 |   resolution: "rxjs@npm:7.8.0"
1620 |   dependencies:
1621 |     tslib: ^2.1.0
1622 |   checksum: 61b4d4fd323c1043d8d6ceb91f24183b28bcf5def4f01ca111511d5c6b66755bc5578587fe714ef5d67cf4c9f2e26f4490d4e1d8cabf9bd5967687835e9866a2
1623 |   languageName: node
1624 |   linkType: hard
1625 | 
1626 | "safe-buffer@npm:~5.2.0":
1627 |   version: 5.2.1
1628 |   resolution: "safe-buffer@npm:5.2.1"
1629 |   checksum: b99c4b41fdd67a6aaf280fcd05e9ffb0813654894223afb78a31f14a19ad220bba8aba1cb14eddce1fcfb037155fe6de4e861784eb434f7d11ed58d1e70dd491
1630 |   languageName: node
1631 |   linkType: hard
1632 | 
1633 | "safer-buffer@npm:>= 2.1.2 < 3.0.0":
1634 |   version: 2.1.2
1635 |   resolution: "safer-buffer@npm:2.1.2"
1636 |   checksum: cab8f25ae6f1434abee8d80023d7e72b598cf1327164ddab31003c51215526801e40b66c5e65d658a0af1e9d6478cadcb4c745f4bd6751f97d8644786c0978b0
1637 |   languageName: node
1638 |   linkType: hard
1639 | 
1640 | "sass@npm:^1.62.0":
1641 |   version: 1.62.0
1642 |   resolution: "sass@npm:1.62.0"
1643 |   dependencies:
1644 |     chokidar: ">=3.0.0 <4.0.0"
1645 |     immutable: ^4.0.0
1646 |     source-map-js: ">=0.6.2 <2.0.0"
1647 |   bin:
1648 |     sass: sass.js
1649 |   checksum: d5f606aa25afdf3ed9f316602811a40cf3b29f64cb70ea02f4198ae4288f9687de6fcef9f4fd2d58e06c28282d859aa249bdbf7d7d97a3a6a582eeaa8e5607fa
1650 |   languageName: node
1651 |   linkType: hard
1652 | 
1653 | "semver@npm:^7.3.5":
1654 |   version: 7.3.7
1655 |   resolution: "semver@npm:7.3.7"
1656 |   dependencies:
1657 |     lru-cache: ^6.0.0
1658 |   bin:
1659 |     semver: bin/semver.js
1660 |   checksum: 2fa3e877568cd6ce769c75c211beaed1f9fce80b28338cadd9d0b6c40f2e2862bafd62c19a6cff42f3d54292b7c623277bcab8816a2b5521cf15210d43e75232
1661 |   languageName: node
1662 |   linkType: hard
1663 | 
1664 | "set-blocking@npm:^2.0.0":
1665 |   version: 2.0.0
1666 |   resolution: "set-blocking@npm:2.0.0"
1667 |   checksum: 6e65a05f7cf7ebdf8b7c75b101e18c0b7e3dff4940d480efed8aad3a36a4005140b660fa1d804cb8bce911cac290441dc728084a30504d3516ac2ff7ad607b02
1668 |   languageName: node
1669 |   linkType: hard
1670 | 
1671 | "shebang-command@npm:^2.0.0":
1672 |   version: 2.0.0
1673 |   resolution: "shebang-command@npm:2.0.0"
1674 |   dependencies:
1675 |     shebang-regex: ^3.0.0
1676 |   checksum: 6b52fe87271c12968f6a054e60f6bde5f0f3d2db483a1e5c3e12d657c488a15474121a1d55cd958f6df026a54374ec38a4a963988c213b7570e1d51575cea7fa
1677 |   languageName: node
1678 |   linkType: hard
1679 | 
1680 | "shebang-regex@npm:^3.0.0":
1681 |   version: 3.0.0
1682 |   resolution: "shebang-regex@npm:3.0.0"
1683 |   checksum: 1a2bcae50de99034fcd92ad4212d8e01eedf52c7ec7830eedcf886622804fe36884278f2be8be0ea5fde3fd1c23911643a4e0f726c8685b61871c8908af01222
1684 |   languageName: node
1685 |   linkType: hard
1686 | 
1687 | "signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.7":
1688 |   version: 3.0.7
1689 |   resolution: "signal-exit@npm:3.0.7"
1690 |   checksum: a2f098f247adc367dffc27845853e9959b9e88b01cb301658cfe4194352d8d2bb32e18467c786a7fe15f1d44b233ea35633d076d5e737870b7139949d1ab6318
1691 |   languageName: node
1692 |   linkType: hard
1693 | 
1694 | "simple-threejs-typescript-starter@workspace:.":
1695 |   version: 0.0.0-use.local
1696 |   resolution: "simple-threejs-typescript-starter@workspace:."
1697 |   dependencies:
1698 |     "@types/three": ^0.150.2
1699 |     husky: ^8.0.3
1700 |     lil-gui: ^0.18.1
1701 |     lint-staged: ^13.2.1
1702 |     prettier: 2.8.7
1703 |     sass: ^1.62.0
1704 |     three: ^0.151.3
1705 |     typescript: ^5.0.4
1706 |     vite: ^4.2.2
1707 |     vite-plugin-glsl: ^1.1.2
1708 |   languageName: unknown
1709 |   linkType: soft
1710 | 
1711 | "slice-ansi@npm:^3.0.0":
1712 |   version: 3.0.0
1713 |   resolution: "slice-ansi@npm:3.0.0"
1714 |   dependencies:
1715 |     ansi-styles: ^4.0.0
1716 |     astral-regex: ^2.0.0
1717 |     is-fullwidth-code-point: ^3.0.0
1718 |   checksum: 5ec6d022d12e016347e9e3e98a7eb2a592213a43a65f1b61b74d2c78288da0aded781f665807a9f3876b9daa9ad94f64f77d7633a0458876c3a4fdc4eb223f24
1719 |   languageName: node
1720 |   linkType: hard
1721 | 
1722 | "slice-ansi@npm:^4.0.0":
1723 |   version: 4.0.0
1724 |   resolution: "slice-ansi@npm:4.0.0"
1725 |   dependencies:
1726 |     ansi-styles: ^4.0.0
1727 |     astral-regex: ^2.0.0
1728 |     is-fullwidth-code-point: ^3.0.0
1729 |   checksum: 4a82d7f085b0e1b070e004941ada3c40d3818563ac44766cca4ceadd2080427d337554f9f99a13aaeb3b4a94d9964d9466c807b3d7b7541d1ec37ee32d308756
1730 |   languageName: node
1731 |   linkType: hard
1732 | 
1733 | "slice-ansi@npm:^5.0.0":
1734 |   version: 5.0.0
1735 |   resolution: "slice-ansi@npm:5.0.0"
1736 |   dependencies:
1737 |     ansi-styles: ^6.0.0
1738 |     is-fullwidth-code-point: ^4.0.0
1739 |   checksum: 7e600a2a55e333a21ef5214b987c8358fe28bfb03c2867ff2cbf919d62143d1812ac27b4297a077fdaf27a03da3678e49551c93e35f9498a3d90221908a1180e
1740 |   languageName: node
1741 |   linkType: hard
1742 | 
1743 | "smart-buffer@npm:^4.2.0":
1744 |   version: 4.2.0
1745 |   resolution: "smart-buffer@npm:4.2.0"
1746 |   checksum: b5167a7142c1da704c0e3af85c402002b597081dd9575031a90b4f229ca5678e9a36e8a374f1814c8156a725d17008ae3bde63b92f9cfd132526379e580bec8b
1747 |   languageName: node
1748 |   linkType: hard
1749 | 
1750 | "socks-proxy-agent@npm:^7.0.0":
1751 |   version: 7.0.0
1752 |   resolution: "socks-proxy-agent@npm:7.0.0"
1753 |   dependencies:
1754 |     agent-base: ^6.0.2
1755 |     debug: ^4.3.3
1756 |     socks: ^2.6.2
1757 |   checksum: 720554370154cbc979e2e9ce6a6ec6ced205d02757d8f5d93fe95adae454fc187a5cbfc6b022afab850a5ce9b4c7d73e0f98e381879cf45f66317a4895953846
1758 |   languageName: node
1759 |   linkType: hard
1760 | 
1761 | "socks@npm:^2.6.2":
1762 |   version: 2.7.0
1763 |   resolution: "socks@npm:2.7.0"
1764 |   dependencies:
1765 |     ip: ^2.0.0
1766 |     smart-buffer: ^4.2.0
1767 |   checksum: 0b5d94e2b3c11e7937b40fc5dac1e80d8b92a330e68c51f1d271ce6980c70adca42a3f8cd47c4a5769956bada074823b53374f2dc5f2ea5c2121b222dec6eadf
1768 |   languageName: node
1769 |   linkType: hard
1770 | 
1771 | "source-map-js@npm:>=0.6.2 <2.0.0, source-map-js@npm:^1.0.2":
1772 |   version: 1.0.2
1773 |   resolution: "source-map-js@npm:1.0.2"
1774 |   checksum: c049a7fc4deb9a7e9b481ae3d424cc793cb4845daa690bc5a05d428bf41bf231ced49b4cf0c9e77f9d42fdb3d20d6187619fc586605f5eabe995a316da8d377c
1775 |   languageName: node
1776 |   linkType: hard
1777 | 
1778 | "ssri@npm:^9.0.0":
1779 |   version: 9.0.1
1780 |   resolution: "ssri@npm:9.0.1"
1781 |   dependencies:
1782 |     minipass: ^3.1.1
1783 |   checksum: fb58f5e46b6923ae67b87ad5ef1c5ab6d427a17db0bead84570c2df3cd50b4ceb880ebdba2d60726588272890bae842a744e1ecce5bd2a2a582fccd5068309eb
1784 |   languageName: node
1785 |   linkType: hard
1786 | 
1787 | "string-argv@npm:^0.3.1":
1788 |   version: 0.3.1
1789 |   resolution: "string-argv@npm:0.3.1"
1790 |   checksum: efbd0289b599bee808ce80820dfe49c9635610715429c6b7cc50750f0437e3c2f697c81e5c390208c13b5d5d12d904a1546172a88579f6ee5cbaaaa4dc9ec5cf
1791 |   languageName: node
1792 |   linkType: hard
1793 | 
1794 | "string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3":
1795 |   version: 4.2.3
1796 |   resolution: "string-width@npm:4.2.3"
1797 |   dependencies:
1798 |     emoji-regex: ^8.0.0
1799 |     is-fullwidth-code-point: ^3.0.0
1800 |     strip-ansi: ^6.0.1
1801 |   checksum: e52c10dc3fbfcd6c3a15f159f54a90024241d0f149cf8aed2982a2d801d2e64df0bf1dc351cf8e95c3319323f9f220c16e740b06faecd53e2462df1d2b5443fb
1802 |   languageName: node
1803 |   linkType: hard
1804 | 
1805 | "string-width@npm:^5.0.0":
1806 |   version: 5.1.2
1807 |   resolution: "string-width@npm:5.1.2"
1808 |   dependencies:
1809 |     eastasianwidth: ^0.2.0
1810 |     emoji-regex: ^9.2.2
1811 |     strip-ansi: ^7.0.1
1812 |   checksum: 7369deaa29f21dda9a438686154b62c2c5f661f8dda60449088f9f980196f7908fc39fdd1803e3e01541970287cf5deae336798337e9319a7055af89dafa7193
1813 |   languageName: node
1814 |   linkType: hard
1815 | 
1816 | "string_decoder@npm:^1.1.1":
1817 |   version: 1.3.0
1818 |   resolution: "string_decoder@npm:1.3.0"
1819 |   dependencies:
1820 |     safe-buffer: ~5.2.0
1821 |   checksum: 8417646695a66e73aefc4420eb3b84cc9ffd89572861fe004e6aeb13c7bc00e2f616247505d2dbbef24247c372f70268f594af7126f43548565c68c117bdeb56
1822 |   languageName: node
1823 |   linkType: hard
1824 | 
1825 | "strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1":
1826 |   version: 6.0.1
1827 |   resolution: "strip-ansi@npm:6.0.1"
1828 |   dependencies:
1829 |     ansi-regex: ^5.0.1
1830 |   checksum: f3cd25890aef3ba6e1a74e20896c21a46f482e93df4a06567cebf2b57edabb15133f1f94e57434e0a958d61186087b1008e89c94875d019910a213181a14fc8c
1831 |   languageName: node
1832 |   linkType: hard
1833 | 
1834 | "strip-ansi@npm:^7.0.1":
1835 |   version: 7.0.1
1836 |   resolution: "strip-ansi@npm:7.0.1"
1837 |   dependencies:
1838 |     ansi-regex: ^6.0.1
1839 |   checksum: 257f78fa433520e7f9897722731d78599cb3fce29ff26a20a5e12ba4957463b50a01136f37c43707f4951817a75e90820174853d6ccc240997adc5df8f966039
1840 |   languageName: node
1841 |   linkType: hard
1842 | 
1843 | "strip-final-newline@npm:^3.0.0":
1844 |   version: 3.0.0
1845 |   resolution: "strip-final-newline@npm:3.0.0"
1846 |   checksum: 23ee263adfa2070cd0f23d1ac14e2ed2f000c9b44229aec9c799f1367ec001478469560abefd00c5c99ee6f0b31c137d53ec6029c53e9f32a93804e18c201050
1847 |   languageName: node
1848 |   linkType: hard
1849 | 
1850 | "supports-preserve-symlinks-flag@npm:^1.0.0":
1851 |   version: 1.0.0
1852 |   resolution: "supports-preserve-symlinks-flag@npm:1.0.0"
1853 |   checksum: 53b1e247e68e05db7b3808b99b892bd36fb096e6fba213a06da7fab22045e97597db425c724f2bbd6c99a3c295e1e73f3e4de78592289f38431049e1277ca0ae
1854 |   languageName: node
1855 |   linkType: hard
1856 | 
1857 | "tar@npm:^6.1.11, tar@npm:^6.1.2":
1858 |   version: 6.1.11
1859 |   resolution: "tar@npm:6.1.11"
1860 |   dependencies:
1861 |     chownr: ^2.0.0
1862 |     fs-minipass: ^2.0.0
1863 |     minipass: ^3.0.0
1864 |     minizlib: ^2.1.1
1865 |     mkdirp: ^1.0.3
1866 |     yallist: ^4.0.0
1867 |   checksum: a04c07bb9e2d8f46776517d4618f2406fb977a74d914ad98b264fc3db0fe8224da5bec11e5f8902c5b9bcb8ace22d95fbe3c7b36b8593b7dfc8391a25898f32f
1868 |   languageName: node
1869 |   linkType: hard
1870 | 
1871 | "three@npm:^0.151.3":
1872 |   version: 0.151.3
1873 |   resolution: "three@npm:0.151.3"
1874 |   checksum: cb6f10e4e409bbc4677d2128470c4e0bdb29f7879a77bc800180e30bda3527816c45b47ac10228f346cfc7501234457f63a87c1bdd5c3b6e2841d523e5d6eb79
1875 |   languageName: node
1876 |   linkType: hard
1877 | 
1878 | "through@npm:^2.3.8":
1879 |   version: 2.3.8
1880 |   resolution: "through@npm:2.3.8"
1881 |   checksum: a38c3e059853c494af95d50c072b83f8b676a9ba2818dcc5b108ef252230735c54e0185437618596c790bbba8fcdaef5b290405981ffa09dce67b1f1bf190cbd
1882 |   languageName: node
1883 |   linkType: hard
1884 | 
1885 | "to-regex-range@npm:^5.0.1":
1886 |   version: 5.0.1
1887 |   resolution: "to-regex-range@npm:5.0.1"
1888 |   dependencies:
1889 |     is-number: ^7.0.0
1890 |   checksum: f76fa01b3d5be85db6a2a143e24df9f60dd047d151062d0ba3df62953f2f697b16fe5dad9b0ac6191c7efc7b1d9dcaa4b768174b7b29da89d4428e64bc0a20ed
1891 |   languageName: node
1892 |   linkType: hard
1893 | 
1894 | "tslib@npm:^2.1.0":
1895 |   version: 2.4.0
1896 |   resolution: "tslib@npm:2.4.0"
1897 |   checksum: 8c4aa6a3c5a754bf76aefc38026134180c053b7bd2f81338cb5e5ebf96fefa0f417bff221592bf801077f5bf990562f6264fecbc42cd3309b33872cb6fc3b113
1898 |   languageName: node
1899 |   linkType: hard
1900 | 
1901 | "type-fest@npm:^0.21.3":
1902 |   version: 0.21.3
1903 |   resolution: "type-fest@npm:0.21.3"
1904 |   checksum: e6b32a3b3877f04339bae01c193b273c62ba7bfc9e325b8703c4ee1b32dc8fe4ef5dfa54bf78265e069f7667d058e360ae0f37be5af9f153b22382cd55a9afe0
1905 |   languageName: node
1906 |   linkType: hard
1907 | 
1908 | "typescript@npm:^5.0.4":
1909 |   version: 5.0.4
1910 |   resolution: "typescript@npm:5.0.4"
1911 |   bin:
1912 |     tsc: bin/tsc
1913 |     tsserver: bin/tsserver
1914 |   checksum: 82b94da3f4604a8946da585f7d6c3025fff8410779e5bde2855ab130d05e4fd08938b9e593b6ebed165bda6ad9292b230984f10952cf82f0a0ca07bbeaa08172
1915 |   languageName: node
1916 |   linkType: hard
1917 | 
1918 | "typescript@patch:typescript@^5.0.4#~builtin":
1919 |   version: 5.0.4
1920 |   resolution: "typescript@patch:typescript@npm%3A5.0.4#~builtin::version=5.0.4&hash=7ad353"
1921 |   bin:
1922 |     tsc: bin/tsc
1923 |     tsserver: bin/tsserver
1924 |   checksum: 6a1fe9a77bb9c5176ead919cc4a1499ee63e46b4e05bf667079f11bf3a8f7887f135aa72460a4c3b016e6e6bb65a822cb8689a6d86cbfe92d22cc9f501f09213
1925 |   languageName: node
1926 |   linkType: hard
1927 | 
1928 | "unique-filename@npm:^1.1.1":
1929 |   version: 1.1.1
1930 |   resolution: "unique-filename@npm:1.1.1"
1931 |   dependencies:
1932 |     unique-slug: ^2.0.0
1933 |   checksum: cf4998c9228cc7647ba7814e255dec51be43673903897b1786eff2ac2d670f54d4d733357eb08dea969aa5e6875d0e1bd391d668fbdb5a179744e7c7551a6f80
1934 |   languageName: node
1935 |   linkType: hard
1936 | 
1937 | "unique-slug@npm:^2.0.0":
1938 |   version: 2.0.2
1939 |   resolution: "unique-slug@npm:2.0.2"
1940 |   dependencies:
1941 |     imurmurhash: ^0.1.4
1942 |   checksum: 5b6876a645da08d505dedb970d1571f6cebdf87044cb6b740c8dbb24f0d6e1dc8bdbf46825fd09f994d7cf50760e6f6e063cfa197d51c5902c00a861702eb75a
1943 |   languageName: node
1944 |   linkType: hard
1945 | 
1946 | "util-deprecate@npm:^1.0.1":
1947 |   version: 1.0.2
1948 |   resolution: "util-deprecate@npm:1.0.2"
1949 |   checksum: 474acf1146cb2701fe3b074892217553dfcf9a031280919ba1b8d651a068c9b15d863b7303cb15bd00a862b498e6cf4ad7b4a08fb134edd5a6f7641681cb54a2
1950 |   languageName: node
1951 |   linkType: hard
1952 | 
1953 | "vite-plugin-glsl@npm:^1.1.2":
1954 |   version: 1.1.2
1955 |   resolution: "vite-plugin-glsl@npm:1.1.2"
1956 |   dependencies:
1957 |     "@rollup/pluginutils": ^5.0.2
1958 |   peerDependencies:
1959 |     vite: ^3.0.0 || ^4.0.0
1960 |   checksum: 8b77944ce9529c52a83f39770bd4e9512e52e4db2d5ee3be270a7c0251d05ea713206a07e03e57c4cb0567bbaeee69c1845f3bc76e49fc4de01f4d2b6dc76578
1961 |   languageName: node
1962 |   linkType: hard
1963 | 
1964 | "vite@npm:^4.2.2":
1965 |   version: 4.2.2
1966 |   resolution: "vite@npm:4.2.2"
1967 |   dependencies:
1968 |     esbuild: ^0.17.5
1969 |     fsevents: ~2.3.2
1970 |     postcss: ^8.4.21
1971 |     resolve: ^1.22.1
1972 |     rollup: ^3.18.0
1973 |   peerDependencies:
1974 |     "@types/node": ">= 14"
1975 |     less: "*"
1976 |     sass: "*"
1977 |     stylus: "*"
1978 |     sugarss: "*"
1979 |     terser: ^5.4.0
1980 |   dependenciesMeta:
1981 |     fsevents:
1982 |       optional: true
1983 |   peerDependenciesMeta:
1984 |     "@types/node":
1985 |       optional: true
1986 |     less:
1987 |       optional: true
1988 |     sass:
1989 |       optional: true
1990 |     stylus:
1991 |       optional: true
1992 |     sugarss:
1993 |       optional: true
1994 |     terser:
1995 |       optional: true
1996 |   bin:
1997 |     vite: bin/vite.js
1998 |   checksum: 7fff9d046f6091c02e030aa5f45e68939b9bec1dd15d4e2c3c084d82ec185300295f3db26f537daf2e19f9ad191be260bf70e5fe0e2d9054f174a7ad457623f8
1999 |   languageName: node
2000 |   linkType: hard
2001 | 
2002 | "which@npm:^2.0.1, which@npm:^2.0.2":
2003 |   version: 2.0.2
2004 |   resolution: "which@npm:2.0.2"
2005 |   dependencies:
2006 |     isexe: ^2.0.0
2007 |   bin:
2008 |     node-which: ./bin/node-which
2009 |   checksum: 1a5c563d3c1b52d5f893c8b61afe11abc3bab4afac492e8da5bde69d550de701cf9806235f20a47b5c8fa8a1d6a9135841de2596535e998027a54589000e66d1
2010 |   languageName: node
2011 |   linkType: hard
2012 | 
2013 | "wide-align@npm:^1.1.5":
2014 |   version: 1.1.5
2015 |   resolution: "wide-align@npm:1.1.5"
2016 |   dependencies:
2017 |     string-width: ^1.0.2 || 2 || 3 || 4
2018 |   checksum: d5fc37cd561f9daee3c80e03b92ed3e84d80dde3365a8767263d03dacfc8fa06b065ffe1df00d8c2a09f731482fcacae745abfbb478d4af36d0a891fad4834d3
2019 |   languageName: node
2020 |   linkType: hard
2021 | 
2022 | "wrap-ansi@npm:^6.2.0":
2023 |   version: 6.2.0
2024 |   resolution: "wrap-ansi@npm:6.2.0"
2025 |   dependencies:
2026 |     ansi-styles: ^4.0.0
2027 |     string-width: ^4.1.0
2028 |     strip-ansi: ^6.0.0
2029 |   checksum: 6cd96a410161ff617b63581a08376f0cb9162375adeb7956e10c8cd397821f7eb2a6de24eb22a0b28401300bf228c86e50617cd568209b5f6775b93c97d2fe3a
2030 |   languageName: node
2031 |   linkType: hard
2032 | 
2033 | "wrap-ansi@npm:^7.0.0":
2034 |   version: 7.0.0
2035 |   resolution: "wrap-ansi@npm:7.0.0"
2036 |   dependencies:
2037 |     ansi-styles: ^4.0.0
2038 |     string-width: ^4.1.0
2039 |     strip-ansi: ^6.0.0
2040 |   checksum: a790b846fd4505de962ba728a21aaeda189b8ee1c7568ca5e817d85930e06ef8d1689d49dbf0e881e8ef84436af3a88bc49115c2e2788d841ff1b8b5b51a608b
2041 |   languageName: node
2042 |   linkType: hard
2043 | 
2044 | "wrappy@npm:1":
2045 |   version: 1.0.2
2046 |   resolution: "wrappy@npm:1.0.2"
2047 |   checksum: 159da4805f7e84a3d003d8841557196034155008f817172d4e986bd591f74aa82aa7db55929a54222309e01079a65a92a9e6414da5a6aa4b01ee44a511ac3ee5
2048 |   languageName: node
2049 |   linkType: hard
2050 | 
2051 | "yallist@npm:^4.0.0":
2052 |   version: 4.0.0
2053 |   resolution: "yallist@npm:4.0.0"
2054 |   checksum: 343617202af32df2a15a3be36a5a8c0c8545208f3d3dfbc6bb7c3e3b7e8c6f8e7485432e4f3b88da3031a6e20afa7c711eded32ddfb122896ac5d914e75848d5
2055 |   languageName: node
2056 |   linkType: hard
2057 | 
2058 | "yaml@npm:^2.2.1":
2059 |   version: 2.2.1
2060 |   resolution: "yaml@npm:2.2.1"
2061 |   checksum: 84f68cbe462d5da4e7ded4a8bded949ffa912bc264472e5a684c3d45b22d8f73a3019963a32164023bdf3d83cfb6f5b58ff7b2b10ef5b717c630f40bd6369a23
2062 |   languageName: node
2063 |   linkType: hard
2064 | 
--------------------------------------------------------------------------------