├── .gitignore ├── LICENSE ├── assets └── demo.mp4 ├── example ├── .gitignore ├── .vite │ └── deps │ │ ├── _metadata.json │ │ └── package.json ├── index.html ├── package-lock.json ├── package.json ├── public │ ├── uv.png │ └── vite.svg ├── src │ ├── experience.ts │ ├── main.ts │ ├── style.css │ └── vite-env.d.ts ├── tsconfig.json └── vite.config.ts ├── package ├── .gitignore ├── UIController.ts ├── index.ts ├── package-lock.json ├── package.json ├── readme.md ├── tsconfig.json └── vite.config.ts └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | *.vite 5 | npm-debug.log* 6 | yarn-debug.log* 7 | yarn-error.log* 8 | lerna-debug.log* 9 | .pnpm-debug.log* 10 | 11 | # Diagnostic reports (https://nodejs.org/api/report.html) 12 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 13 | 14 | # Runtime data 15 | pids 16 | *.pid 17 | *.seed 18 | *.pid.lock 19 | 20 | # Directory for instrumented libs generated by jscoverage/JSCover 21 | lib-cov 22 | 23 | # Coverage directory used by tools like istanbul 24 | coverage 25 | *.lcov 26 | 27 | # nyc test coverage 28 | .nyc_output 29 | 30 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 31 | .grunt 32 | 33 | # Bower dependency directory (https://bower.io/) 34 | bower_components 35 | 36 | # node-waf configuration 37 | .lock-wscript 38 | 39 | # Compiled binary addons (https://nodejs.org/api/addons.html) 40 | build/Release 41 | 42 | # Dependency directories 43 | node_modules/ 44 | jspm_packages/ 45 | 46 | # Snowpack dependency directory (https://snowpack.dev/) 47 | web_modules/ 48 | 49 | # TypeScript cache 50 | *.tsbuildinfo 51 | 52 | # Optional npm cache directory 53 | .npm 54 | 55 | # Optional eslint cache 56 | .eslintcache 57 | 58 | # Optional stylelint cache 59 | .stylelintcache 60 | 61 | # Microbundle cache 62 | .rpt2_cache/ 63 | .rts2_cache_cjs/ 64 | .rts2_cache_es/ 65 | .rts2_cache_umd/ 66 | 67 | # Optional REPL history 68 | .node_repl_history 69 | 70 | # Output of 'npm pack' 71 | *.tgz 72 | 73 | # Yarn Integrity file 74 | .yarn-integrity 75 | 76 | # dotenv environment variable files 77 | .env 78 | .env.development.local 79 | .env.test.local 80 | .env.production.local 81 | .env.local 82 | 83 | # parcel-bundler cache (https://parceljs.org/) 84 | .cache 85 | .parcel-cache 86 | 87 | # Next.js build output 88 | .next 89 | out 90 | 91 | # Nuxt.js build / generate output 92 | .nuxt 93 | dist 94 | 95 | # Gatsby files 96 | .cache/ 97 | # Comment in the public line in if your project uses Gatsby and not Next.js 98 | # https://nextjs.org/blog/next-9-1#public-directory-support 99 | # public 100 | 101 | # vuepress build output 102 | .vuepress/dist 103 | 104 | # vuepress v2.x temp and cache directory 105 | .temp 106 | .cache 107 | 108 | # Docusaurus cache and generated files 109 | .docusaurus 110 | 111 | # Serverless directories 112 | .serverless/ 113 | 114 | # FuseBox cache 115 | .fusebox/ 116 | 117 | # DynamoDB Local files 118 | .dynamodb/ 119 | 120 | # TernJS port file 121 | .tern-port 122 | 123 | # Stores VSCode versions used for testing VSCode extensions 124 | .vscode-test 125 | 126 | # yarn v2 127 | .yarn/cache 128 | .yarn/unplugged 129 | .yarn/build-state.yml 130 | .yarn/install-state.gz 131 | .pnp.* 132 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Bhushan Wagh 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 | -------------------------------------------------------------------------------- /assets/demo.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhushan6/tsl-Uniform-UI-Vite-Plugin/eaa81750da585eff842def13912f2124c28a99ad/assets/demo.mp4 -------------------------------------------------------------------------------- /example/.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 | -------------------------------------------------------------------------------- /example/.vite/deps/_metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "hash": "9ae66b2e", 3 | "configHash": "cd9c5a8f", 4 | "lockfileHash": "d024ea5c", 5 | "browserHash": "a1d77677", 6 | "optimized": {}, 7 | "chunks": {} 8 | } -------------------------------------------------------------------------------- /example/.vite/deps/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module" 3 | } 4 | -------------------------------------------------------------------------------- /example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + TS 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /example/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "three-tsl-boilerplate", 3 | "version": "0.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "three-tsl-boilerplate", 9 | "version": "0.0.0", 10 | "dependencies": { 11 | "@tweakpane/core": "^2.0.5", 12 | "@tweakpane/plugin-essentials": "^0.2.1", 13 | "@types/three": "^0.173.0", 14 | "three": "^0.173.0", 15 | "tsl-uniform-ui-vite-plugin": "^0.7.2", 16 | "tweakpane": "^4.0.5", 17 | "tweakpane-plugin-file-import": "^1.1.1" 18 | }, 19 | "devDependencies": { 20 | "typescript": "~5.7.2", 21 | "vite": "^6.1.0" 22 | } 23 | }, 24 | "node_modules/@babel/code-frame": { 25 | "version": "7.26.2", 26 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", 27 | "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", 28 | "license": "MIT", 29 | "dependencies": { 30 | "@babel/helper-validator-identifier": "^7.25.9", 31 | "js-tokens": "^4.0.0", 32 | "picocolors": "^1.0.0" 33 | }, 34 | "engines": { 35 | "node": ">=6.9.0" 36 | } 37 | }, 38 | "node_modules/@babel/generator": { 39 | "version": "7.26.9", 40 | "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.9.tgz", 41 | "integrity": "sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==", 42 | "license": "MIT", 43 | "dependencies": { 44 | "@babel/parser": "^7.26.9", 45 | "@babel/types": "^7.26.9", 46 | "@jridgewell/gen-mapping": "^0.3.5", 47 | "@jridgewell/trace-mapping": "^0.3.25", 48 | "jsesc": "^3.0.2" 49 | }, 50 | "engines": { 51 | "node": ">=6.9.0" 52 | } 53 | }, 54 | "node_modules/@babel/helper-string-parser": { 55 | "version": "7.25.9", 56 | "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", 57 | "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", 58 | "license": "MIT", 59 | "engines": { 60 | "node": ">=6.9.0" 61 | } 62 | }, 63 | "node_modules/@babel/helper-validator-identifier": { 64 | "version": "7.25.9", 65 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", 66 | "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", 67 | "license": "MIT", 68 | "engines": { 69 | "node": ">=6.9.0" 70 | } 71 | }, 72 | "node_modules/@babel/parser": { 73 | "version": "7.26.9", 74 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.9.tgz", 75 | "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==", 76 | "license": "MIT", 77 | "dependencies": { 78 | "@babel/types": "^7.26.9" 79 | }, 80 | "bin": { 81 | "parser": "bin/babel-parser.js" 82 | }, 83 | "engines": { 84 | "node": ">=6.0.0" 85 | } 86 | }, 87 | "node_modules/@babel/template": { 88 | "version": "7.26.9", 89 | "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz", 90 | "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==", 91 | "license": "MIT", 92 | "dependencies": { 93 | "@babel/code-frame": "^7.26.2", 94 | "@babel/parser": "^7.26.9", 95 | "@babel/types": "^7.26.9" 96 | }, 97 | "engines": { 98 | "node": ">=6.9.0" 99 | } 100 | }, 101 | "node_modules/@babel/traverse": { 102 | "version": "7.26.9", 103 | "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.9.tgz", 104 | "integrity": "sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==", 105 | "license": "MIT", 106 | "dependencies": { 107 | "@babel/code-frame": "^7.26.2", 108 | "@babel/generator": "^7.26.9", 109 | "@babel/parser": "^7.26.9", 110 | "@babel/template": "^7.26.9", 111 | "@babel/types": "^7.26.9", 112 | "debug": "^4.3.1", 113 | "globals": "^11.1.0" 114 | }, 115 | "engines": { 116 | "node": ">=6.9.0" 117 | } 118 | }, 119 | "node_modules/@babel/types": { 120 | "version": "7.26.9", 121 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz", 122 | "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==", 123 | "license": "MIT", 124 | "dependencies": { 125 | "@babel/helper-string-parser": "^7.25.9", 126 | "@babel/helper-validator-identifier": "^7.25.9" 127 | }, 128 | "engines": { 129 | "node": ">=6.9.0" 130 | } 131 | }, 132 | "node_modules/@esbuild/aix-ppc64": { 133 | "version": "0.24.2", 134 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", 135 | "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==", 136 | "cpu": [ 137 | "ppc64" 138 | ], 139 | "dev": true, 140 | "license": "MIT", 141 | "optional": true, 142 | "os": [ 143 | "aix" 144 | ], 145 | "engines": { 146 | "node": ">=18" 147 | } 148 | }, 149 | "node_modules/@esbuild/android-arm": { 150 | "version": "0.24.2", 151 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz", 152 | "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==", 153 | "cpu": [ 154 | "arm" 155 | ], 156 | "dev": true, 157 | "license": "MIT", 158 | "optional": true, 159 | "os": [ 160 | "android" 161 | ], 162 | "engines": { 163 | "node": ">=18" 164 | } 165 | }, 166 | "node_modules/@esbuild/android-arm64": { 167 | "version": "0.24.2", 168 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz", 169 | "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==", 170 | "cpu": [ 171 | "arm64" 172 | ], 173 | "dev": true, 174 | "license": "MIT", 175 | "optional": true, 176 | "os": [ 177 | "android" 178 | ], 179 | "engines": { 180 | "node": ">=18" 181 | } 182 | }, 183 | "node_modules/@esbuild/android-x64": { 184 | "version": "0.24.2", 185 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz", 186 | "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==", 187 | "cpu": [ 188 | "x64" 189 | ], 190 | "dev": true, 191 | "license": "MIT", 192 | "optional": true, 193 | "os": [ 194 | "android" 195 | ], 196 | "engines": { 197 | "node": ">=18" 198 | } 199 | }, 200 | "node_modules/@esbuild/darwin-arm64": { 201 | "version": "0.24.2", 202 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz", 203 | "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==", 204 | "cpu": [ 205 | "arm64" 206 | ], 207 | "dev": true, 208 | "license": "MIT", 209 | "optional": true, 210 | "os": [ 211 | "darwin" 212 | ], 213 | "engines": { 214 | "node": ">=18" 215 | } 216 | }, 217 | "node_modules/@esbuild/darwin-x64": { 218 | "version": "0.24.2", 219 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz", 220 | "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==", 221 | "cpu": [ 222 | "x64" 223 | ], 224 | "dev": true, 225 | "license": "MIT", 226 | "optional": true, 227 | "os": [ 228 | "darwin" 229 | ], 230 | "engines": { 231 | "node": ">=18" 232 | } 233 | }, 234 | "node_modules/@esbuild/freebsd-arm64": { 235 | "version": "0.24.2", 236 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz", 237 | "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==", 238 | "cpu": [ 239 | "arm64" 240 | ], 241 | "dev": true, 242 | "license": "MIT", 243 | "optional": true, 244 | "os": [ 245 | "freebsd" 246 | ], 247 | "engines": { 248 | "node": ">=18" 249 | } 250 | }, 251 | "node_modules/@esbuild/freebsd-x64": { 252 | "version": "0.24.2", 253 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz", 254 | "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==", 255 | "cpu": [ 256 | "x64" 257 | ], 258 | "dev": true, 259 | "license": "MIT", 260 | "optional": true, 261 | "os": [ 262 | "freebsd" 263 | ], 264 | "engines": { 265 | "node": ">=18" 266 | } 267 | }, 268 | "node_modules/@esbuild/linux-arm": { 269 | "version": "0.24.2", 270 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz", 271 | "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==", 272 | "cpu": [ 273 | "arm" 274 | ], 275 | "dev": true, 276 | "license": "MIT", 277 | "optional": true, 278 | "os": [ 279 | "linux" 280 | ], 281 | "engines": { 282 | "node": ">=18" 283 | } 284 | }, 285 | "node_modules/@esbuild/linux-arm64": { 286 | "version": "0.24.2", 287 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz", 288 | "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==", 289 | "cpu": [ 290 | "arm64" 291 | ], 292 | "dev": true, 293 | "license": "MIT", 294 | "optional": true, 295 | "os": [ 296 | "linux" 297 | ], 298 | "engines": { 299 | "node": ">=18" 300 | } 301 | }, 302 | "node_modules/@esbuild/linux-ia32": { 303 | "version": "0.24.2", 304 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz", 305 | "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==", 306 | "cpu": [ 307 | "ia32" 308 | ], 309 | "dev": true, 310 | "license": "MIT", 311 | "optional": true, 312 | "os": [ 313 | "linux" 314 | ], 315 | "engines": { 316 | "node": ">=18" 317 | } 318 | }, 319 | "node_modules/@esbuild/linux-loong64": { 320 | "version": "0.24.2", 321 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz", 322 | "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==", 323 | "cpu": [ 324 | "loong64" 325 | ], 326 | "dev": true, 327 | "license": "MIT", 328 | "optional": true, 329 | "os": [ 330 | "linux" 331 | ], 332 | "engines": { 333 | "node": ">=18" 334 | } 335 | }, 336 | "node_modules/@esbuild/linux-mips64el": { 337 | "version": "0.24.2", 338 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz", 339 | "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==", 340 | "cpu": [ 341 | "mips64el" 342 | ], 343 | "dev": true, 344 | "license": "MIT", 345 | "optional": true, 346 | "os": [ 347 | "linux" 348 | ], 349 | "engines": { 350 | "node": ">=18" 351 | } 352 | }, 353 | "node_modules/@esbuild/linux-ppc64": { 354 | "version": "0.24.2", 355 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz", 356 | "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==", 357 | "cpu": [ 358 | "ppc64" 359 | ], 360 | "dev": true, 361 | "license": "MIT", 362 | "optional": true, 363 | "os": [ 364 | "linux" 365 | ], 366 | "engines": { 367 | "node": ">=18" 368 | } 369 | }, 370 | "node_modules/@esbuild/linux-riscv64": { 371 | "version": "0.24.2", 372 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz", 373 | "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==", 374 | "cpu": [ 375 | "riscv64" 376 | ], 377 | "dev": true, 378 | "license": "MIT", 379 | "optional": true, 380 | "os": [ 381 | "linux" 382 | ], 383 | "engines": { 384 | "node": ">=18" 385 | } 386 | }, 387 | "node_modules/@esbuild/linux-s390x": { 388 | "version": "0.24.2", 389 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz", 390 | "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==", 391 | "cpu": [ 392 | "s390x" 393 | ], 394 | "dev": true, 395 | "license": "MIT", 396 | "optional": true, 397 | "os": [ 398 | "linux" 399 | ], 400 | "engines": { 401 | "node": ">=18" 402 | } 403 | }, 404 | "node_modules/@esbuild/linux-x64": { 405 | "version": "0.24.2", 406 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz", 407 | "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==", 408 | "cpu": [ 409 | "x64" 410 | ], 411 | "dev": true, 412 | "license": "MIT", 413 | "optional": true, 414 | "os": [ 415 | "linux" 416 | ], 417 | "engines": { 418 | "node": ">=18" 419 | } 420 | }, 421 | "node_modules/@esbuild/netbsd-arm64": { 422 | "version": "0.24.2", 423 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz", 424 | "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==", 425 | "cpu": [ 426 | "arm64" 427 | ], 428 | "dev": true, 429 | "license": "MIT", 430 | "optional": true, 431 | "os": [ 432 | "netbsd" 433 | ], 434 | "engines": { 435 | "node": ">=18" 436 | } 437 | }, 438 | "node_modules/@esbuild/netbsd-x64": { 439 | "version": "0.24.2", 440 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz", 441 | "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==", 442 | "cpu": [ 443 | "x64" 444 | ], 445 | "dev": true, 446 | "license": "MIT", 447 | "optional": true, 448 | "os": [ 449 | "netbsd" 450 | ], 451 | "engines": { 452 | "node": ">=18" 453 | } 454 | }, 455 | "node_modules/@esbuild/openbsd-arm64": { 456 | "version": "0.24.2", 457 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz", 458 | "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==", 459 | "cpu": [ 460 | "arm64" 461 | ], 462 | "dev": true, 463 | "license": "MIT", 464 | "optional": true, 465 | "os": [ 466 | "openbsd" 467 | ], 468 | "engines": { 469 | "node": ">=18" 470 | } 471 | }, 472 | "node_modules/@esbuild/openbsd-x64": { 473 | "version": "0.24.2", 474 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz", 475 | "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==", 476 | "cpu": [ 477 | "x64" 478 | ], 479 | "dev": true, 480 | "license": "MIT", 481 | "optional": true, 482 | "os": [ 483 | "openbsd" 484 | ], 485 | "engines": { 486 | "node": ">=18" 487 | } 488 | }, 489 | "node_modules/@esbuild/sunos-x64": { 490 | "version": "0.24.2", 491 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz", 492 | "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==", 493 | "cpu": [ 494 | "x64" 495 | ], 496 | "dev": true, 497 | "license": "MIT", 498 | "optional": true, 499 | "os": [ 500 | "sunos" 501 | ], 502 | "engines": { 503 | "node": ">=18" 504 | } 505 | }, 506 | "node_modules/@esbuild/win32-arm64": { 507 | "version": "0.24.2", 508 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz", 509 | "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==", 510 | "cpu": [ 511 | "arm64" 512 | ], 513 | "dev": true, 514 | "license": "MIT", 515 | "optional": true, 516 | "os": [ 517 | "win32" 518 | ], 519 | "engines": { 520 | "node": ">=18" 521 | } 522 | }, 523 | "node_modules/@esbuild/win32-ia32": { 524 | "version": "0.24.2", 525 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz", 526 | "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==", 527 | "cpu": [ 528 | "ia32" 529 | ], 530 | "dev": true, 531 | "license": "MIT", 532 | "optional": true, 533 | "os": [ 534 | "win32" 535 | ], 536 | "engines": { 537 | "node": ">=18" 538 | } 539 | }, 540 | "node_modules/@esbuild/win32-x64": { 541 | "version": "0.24.2", 542 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz", 543 | "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==", 544 | "cpu": [ 545 | "x64" 546 | ], 547 | "dev": true, 548 | "license": "MIT", 549 | "optional": true, 550 | "os": [ 551 | "win32" 552 | ], 553 | "engines": { 554 | "node": ">=18" 555 | } 556 | }, 557 | "node_modules/@jridgewell/gen-mapping": { 558 | "version": "0.3.8", 559 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", 560 | "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", 561 | "license": "MIT", 562 | "dependencies": { 563 | "@jridgewell/set-array": "^1.2.1", 564 | "@jridgewell/sourcemap-codec": "^1.4.10", 565 | "@jridgewell/trace-mapping": "^0.3.24" 566 | }, 567 | "engines": { 568 | "node": ">=6.0.0" 569 | } 570 | }, 571 | "node_modules/@jridgewell/resolve-uri": { 572 | "version": "3.1.2", 573 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", 574 | "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", 575 | "license": "MIT", 576 | "engines": { 577 | "node": ">=6.0.0" 578 | } 579 | }, 580 | "node_modules/@jridgewell/set-array": { 581 | "version": "1.2.1", 582 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", 583 | "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", 584 | "license": "MIT", 585 | "engines": { 586 | "node": ">=6.0.0" 587 | } 588 | }, 589 | "node_modules/@jridgewell/sourcemap-codec": { 590 | "version": "1.5.0", 591 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", 592 | "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", 593 | "license": "MIT" 594 | }, 595 | "node_modules/@jridgewell/trace-mapping": { 596 | "version": "0.3.25", 597 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", 598 | "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", 599 | "license": "MIT", 600 | "dependencies": { 601 | "@jridgewell/resolve-uri": "^3.1.0", 602 | "@jridgewell/sourcemap-codec": "^1.4.14" 603 | } 604 | }, 605 | "node_modules/@rollup/rollup-android-arm-eabi": { 606 | "version": "4.34.8", 607 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz", 608 | "integrity": "sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==", 609 | "cpu": [ 610 | "arm" 611 | ], 612 | "dev": true, 613 | "license": "MIT", 614 | "optional": true, 615 | "os": [ 616 | "android" 617 | ] 618 | }, 619 | "node_modules/@rollup/rollup-android-arm64": { 620 | "version": "4.34.8", 621 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.8.tgz", 622 | "integrity": "sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==", 623 | "cpu": [ 624 | "arm64" 625 | ], 626 | "dev": true, 627 | "license": "MIT", 628 | "optional": true, 629 | "os": [ 630 | "android" 631 | ] 632 | }, 633 | "node_modules/@rollup/rollup-darwin-arm64": { 634 | "version": "4.34.8", 635 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.8.tgz", 636 | "integrity": "sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==", 637 | "cpu": [ 638 | "arm64" 639 | ], 640 | "dev": true, 641 | "license": "MIT", 642 | "optional": true, 643 | "os": [ 644 | "darwin" 645 | ] 646 | }, 647 | "node_modules/@rollup/rollup-darwin-x64": { 648 | "version": "4.34.8", 649 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.8.tgz", 650 | "integrity": "sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==", 651 | "cpu": [ 652 | "x64" 653 | ], 654 | "dev": true, 655 | "license": "MIT", 656 | "optional": true, 657 | "os": [ 658 | "darwin" 659 | ] 660 | }, 661 | "node_modules/@rollup/rollup-freebsd-arm64": { 662 | "version": "4.34.8", 663 | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.8.tgz", 664 | "integrity": "sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==", 665 | "cpu": [ 666 | "arm64" 667 | ], 668 | "dev": true, 669 | "license": "MIT", 670 | "optional": true, 671 | "os": [ 672 | "freebsd" 673 | ] 674 | }, 675 | "node_modules/@rollup/rollup-freebsd-x64": { 676 | "version": "4.34.8", 677 | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.8.tgz", 678 | "integrity": "sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==", 679 | "cpu": [ 680 | "x64" 681 | ], 682 | "dev": true, 683 | "license": "MIT", 684 | "optional": true, 685 | "os": [ 686 | "freebsd" 687 | ] 688 | }, 689 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": { 690 | "version": "4.34.8", 691 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.8.tgz", 692 | "integrity": "sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==", 693 | "cpu": [ 694 | "arm" 695 | ], 696 | "dev": true, 697 | "license": "MIT", 698 | "optional": true, 699 | "os": [ 700 | "linux" 701 | ] 702 | }, 703 | "node_modules/@rollup/rollup-linux-arm-musleabihf": { 704 | "version": "4.34.8", 705 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.8.tgz", 706 | "integrity": "sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==", 707 | "cpu": [ 708 | "arm" 709 | ], 710 | "dev": true, 711 | "license": "MIT", 712 | "optional": true, 713 | "os": [ 714 | "linux" 715 | ] 716 | }, 717 | "node_modules/@rollup/rollup-linux-arm64-gnu": { 718 | "version": "4.34.8", 719 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.8.tgz", 720 | "integrity": "sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==", 721 | "cpu": [ 722 | "arm64" 723 | ], 724 | "dev": true, 725 | "license": "MIT", 726 | "optional": true, 727 | "os": [ 728 | "linux" 729 | ] 730 | }, 731 | "node_modules/@rollup/rollup-linux-arm64-musl": { 732 | "version": "4.34.8", 733 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.8.tgz", 734 | "integrity": "sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==", 735 | "cpu": [ 736 | "arm64" 737 | ], 738 | "dev": true, 739 | "license": "MIT", 740 | "optional": true, 741 | "os": [ 742 | "linux" 743 | ] 744 | }, 745 | "node_modules/@rollup/rollup-linux-loongarch64-gnu": { 746 | "version": "4.34.8", 747 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.8.tgz", 748 | "integrity": "sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==", 749 | "cpu": [ 750 | "loong64" 751 | ], 752 | "dev": true, 753 | "license": "MIT", 754 | "optional": true, 755 | "os": [ 756 | "linux" 757 | ] 758 | }, 759 | "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { 760 | "version": "4.34.8", 761 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.8.tgz", 762 | "integrity": "sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==", 763 | "cpu": [ 764 | "ppc64" 765 | ], 766 | "dev": true, 767 | "license": "MIT", 768 | "optional": true, 769 | "os": [ 770 | "linux" 771 | ] 772 | }, 773 | "node_modules/@rollup/rollup-linux-riscv64-gnu": { 774 | "version": "4.34.8", 775 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.8.tgz", 776 | "integrity": "sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==", 777 | "cpu": [ 778 | "riscv64" 779 | ], 780 | "dev": true, 781 | "license": "MIT", 782 | "optional": true, 783 | "os": [ 784 | "linux" 785 | ] 786 | }, 787 | "node_modules/@rollup/rollup-linux-s390x-gnu": { 788 | "version": "4.34.8", 789 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.8.tgz", 790 | "integrity": "sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==", 791 | "cpu": [ 792 | "s390x" 793 | ], 794 | "dev": true, 795 | "license": "MIT", 796 | "optional": true, 797 | "os": [ 798 | "linux" 799 | ] 800 | }, 801 | "node_modules/@rollup/rollup-linux-x64-gnu": { 802 | "version": "4.34.8", 803 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.8.tgz", 804 | "integrity": "sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==", 805 | "cpu": [ 806 | "x64" 807 | ], 808 | "dev": true, 809 | "license": "MIT", 810 | "optional": true, 811 | "os": [ 812 | "linux" 813 | ] 814 | }, 815 | "node_modules/@rollup/rollup-linux-x64-musl": { 816 | "version": "4.34.8", 817 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.8.tgz", 818 | "integrity": "sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==", 819 | "cpu": [ 820 | "x64" 821 | ], 822 | "dev": true, 823 | "license": "MIT", 824 | "optional": true, 825 | "os": [ 826 | "linux" 827 | ] 828 | }, 829 | "node_modules/@rollup/rollup-win32-arm64-msvc": { 830 | "version": "4.34.8", 831 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.8.tgz", 832 | "integrity": "sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==", 833 | "cpu": [ 834 | "arm64" 835 | ], 836 | "dev": true, 837 | "license": "MIT", 838 | "optional": true, 839 | "os": [ 840 | "win32" 841 | ] 842 | }, 843 | "node_modules/@rollup/rollup-win32-ia32-msvc": { 844 | "version": "4.34.8", 845 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.8.tgz", 846 | "integrity": "sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==", 847 | "cpu": [ 848 | "ia32" 849 | ], 850 | "dev": true, 851 | "license": "MIT", 852 | "optional": true, 853 | "os": [ 854 | "win32" 855 | ] 856 | }, 857 | "node_modules/@rollup/rollup-win32-x64-msvc": { 858 | "version": "4.34.8", 859 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.8.tgz", 860 | "integrity": "sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==", 861 | "cpu": [ 862 | "x64" 863 | ], 864 | "dev": true, 865 | "license": "MIT", 866 | "optional": true, 867 | "os": [ 868 | "win32" 869 | ] 870 | }, 871 | "node_modules/@tweakpane/core": { 872 | "version": "2.0.5", 873 | "resolved": "https://registry.npmjs.org/@tweakpane/core/-/core-2.0.5.tgz", 874 | "integrity": "sha512-punBgD5rKCF5vcNo6BsSOXiDR/NSs9VM7SG65QSLJIxfRaGgj54ree9zQW6bO3pNFf3AogiGgaNODUVQRk9YqQ==", 875 | "license": "MIT" 876 | }, 877 | "node_modules/@tweakpane/plugin-essentials": { 878 | "version": "0.2.1", 879 | "resolved": "https://registry.npmjs.org/@tweakpane/plugin-essentials/-/plugin-essentials-0.2.1.tgz", 880 | "integrity": "sha512-VbFU1/uD+CJNFQdfLXUOLjeG5HyUZH97Ox9CxmyVetg1hqjVun3C83HAGFULyhKzl8tSgii8jr304r8QpdHwzQ==", 881 | "license": "MIT", 882 | "peerDependencies": { 883 | "tweakpane": "^4.0.0" 884 | } 885 | }, 886 | "node_modules/@tweenjs/tween.js": { 887 | "version": "23.1.3", 888 | "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-23.1.3.tgz", 889 | "integrity": "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==", 890 | "license": "MIT" 891 | }, 892 | "node_modules/@types/estree": { 893 | "version": "1.0.6", 894 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", 895 | "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", 896 | "dev": true, 897 | "license": "MIT" 898 | }, 899 | "node_modules/@types/stats.js": { 900 | "version": "0.17.3", 901 | "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.3.tgz", 902 | "integrity": "sha512-pXNfAD3KHOdif9EQXZ9deK82HVNaXP5ZIF5RP2QG6OQFNTaY2YIetfrE9t528vEreGQvEPRDDc8muaoYeK0SxQ==", 903 | "license": "MIT" 904 | }, 905 | "node_modules/@types/three": { 906 | "version": "0.173.0", 907 | "resolved": "https://registry.npmjs.org/@types/three/-/three-0.173.0.tgz", 908 | "integrity": "sha512-KtNjfI/CRB6JVKIVeZM1R3GYDX2wkoV2itNcQu2j4d7qkhjGOuB+s2oF6jl9mztycDLGMtrAnJQYxInC8Bb20A==", 909 | "license": "MIT", 910 | "dependencies": { 911 | "@tweenjs/tween.js": "~23.1.3", 912 | "@types/stats.js": "*", 913 | "@types/webxr": "*", 914 | "@webgpu/types": "*", 915 | "fflate": "~0.8.2", 916 | "meshoptimizer": "~0.18.1" 917 | } 918 | }, 919 | "node_modules/@types/webxr": { 920 | "version": "0.5.21", 921 | "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.21.tgz", 922 | "integrity": "sha512-geZIAtLzjGmgY2JUi6VxXdCrTb99A7yP49lxLr2Nm/uIK0PkkxcEi4OGhoGDO4pxCf3JwGz2GiJL2Ej4K2bKaA==", 923 | "license": "MIT" 924 | }, 925 | "node_modules/@webgpu/types": { 926 | "version": "0.1.54", 927 | "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.54.tgz", 928 | "integrity": "sha512-81oaalC8LFrXjhsczomEQ0u3jG+TqE6V9QHLA8GNZq/Rnot0KDugu3LhSYSlie8tSdooAN1Hov05asrUUp9qgg==", 929 | "license": "BSD-3-Clause" 930 | }, 931 | "node_modules/debug": { 932 | "version": "4.4.0", 933 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", 934 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", 935 | "license": "MIT", 936 | "dependencies": { 937 | "ms": "^2.1.3" 938 | }, 939 | "engines": { 940 | "node": ">=6.0" 941 | }, 942 | "peerDependenciesMeta": { 943 | "supports-color": { 944 | "optional": true 945 | } 946 | } 947 | }, 948 | "node_modules/esbuild": { 949 | "version": "0.24.2", 950 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz", 951 | "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==", 952 | "dev": true, 953 | "hasInstallScript": true, 954 | "license": "MIT", 955 | "bin": { 956 | "esbuild": "bin/esbuild" 957 | }, 958 | "engines": { 959 | "node": ">=18" 960 | }, 961 | "optionalDependencies": { 962 | "@esbuild/aix-ppc64": "0.24.2", 963 | "@esbuild/android-arm": "0.24.2", 964 | "@esbuild/android-arm64": "0.24.2", 965 | "@esbuild/android-x64": "0.24.2", 966 | "@esbuild/darwin-arm64": "0.24.2", 967 | "@esbuild/darwin-x64": "0.24.2", 968 | "@esbuild/freebsd-arm64": "0.24.2", 969 | "@esbuild/freebsd-x64": "0.24.2", 970 | "@esbuild/linux-arm": "0.24.2", 971 | "@esbuild/linux-arm64": "0.24.2", 972 | "@esbuild/linux-ia32": "0.24.2", 973 | "@esbuild/linux-loong64": "0.24.2", 974 | "@esbuild/linux-mips64el": "0.24.2", 975 | "@esbuild/linux-ppc64": "0.24.2", 976 | "@esbuild/linux-riscv64": "0.24.2", 977 | "@esbuild/linux-s390x": "0.24.2", 978 | "@esbuild/linux-x64": "0.24.2", 979 | "@esbuild/netbsd-arm64": "0.24.2", 980 | "@esbuild/netbsd-x64": "0.24.2", 981 | "@esbuild/openbsd-arm64": "0.24.2", 982 | "@esbuild/openbsd-x64": "0.24.2", 983 | "@esbuild/sunos-x64": "0.24.2", 984 | "@esbuild/win32-arm64": "0.24.2", 985 | "@esbuild/win32-ia32": "0.24.2", 986 | "@esbuild/win32-x64": "0.24.2" 987 | } 988 | }, 989 | "node_modules/fflate": { 990 | "version": "0.8.2", 991 | "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", 992 | "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", 993 | "license": "MIT" 994 | }, 995 | "node_modules/fsevents": { 996 | "version": "2.3.3", 997 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 998 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 999 | "dev": true, 1000 | "hasInstallScript": true, 1001 | "license": "MIT", 1002 | "optional": true, 1003 | "os": [ 1004 | "darwin" 1005 | ], 1006 | "engines": { 1007 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 1008 | } 1009 | }, 1010 | "node_modules/globals": { 1011 | "version": "11.12.0", 1012 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", 1013 | "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", 1014 | "license": "MIT", 1015 | "engines": { 1016 | "node": ">=4" 1017 | } 1018 | }, 1019 | "node_modules/js-tokens": { 1020 | "version": "4.0.0", 1021 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 1022 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", 1023 | "license": "MIT" 1024 | }, 1025 | "node_modules/jsesc": { 1026 | "version": "3.1.0", 1027 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", 1028 | "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", 1029 | "license": "MIT", 1030 | "bin": { 1031 | "jsesc": "bin/jsesc" 1032 | }, 1033 | "engines": { 1034 | "node": ">=6" 1035 | } 1036 | }, 1037 | "node_modules/meshoptimizer": { 1038 | "version": "0.18.1", 1039 | "resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-0.18.1.tgz", 1040 | "integrity": "sha512-ZhoIoL7TNV4s5B6+rx5mC//fw8/POGyNxS/DZyCJeiZ12ScLfVwRE/GfsxwiTkMYYD5DmK2/JXnEVXqL4rF+Sw==", 1041 | "license": "MIT" 1042 | }, 1043 | "node_modules/ms": { 1044 | "version": "2.1.3", 1045 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1046 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 1047 | "license": "MIT" 1048 | }, 1049 | "node_modules/nanoid": { 1050 | "version": "3.3.8", 1051 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", 1052 | "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", 1053 | "dev": true, 1054 | "funding": [ 1055 | { 1056 | "type": "github", 1057 | "url": "https://github.com/sponsors/ai" 1058 | } 1059 | ], 1060 | "license": "MIT", 1061 | "bin": { 1062 | "nanoid": "bin/nanoid.cjs" 1063 | }, 1064 | "engines": { 1065 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 1066 | } 1067 | }, 1068 | "node_modules/picocolors": { 1069 | "version": "1.1.1", 1070 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", 1071 | "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", 1072 | "license": "ISC" 1073 | }, 1074 | "node_modules/postcss": { 1075 | "version": "8.5.3", 1076 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", 1077 | "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", 1078 | "dev": true, 1079 | "funding": [ 1080 | { 1081 | "type": "opencollective", 1082 | "url": "https://opencollective.com/postcss/" 1083 | }, 1084 | { 1085 | "type": "tidelift", 1086 | "url": "https://tidelift.com/funding/github/npm/postcss" 1087 | }, 1088 | { 1089 | "type": "github", 1090 | "url": "https://github.com/sponsors/ai" 1091 | } 1092 | ], 1093 | "license": "MIT", 1094 | "dependencies": { 1095 | "nanoid": "^3.3.8", 1096 | "picocolors": "^1.1.1", 1097 | "source-map-js": "^1.2.1" 1098 | }, 1099 | "engines": { 1100 | "node": "^10 || ^12 || >=14" 1101 | } 1102 | }, 1103 | "node_modules/rollup": { 1104 | "version": "4.34.8", 1105 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.8.tgz", 1106 | "integrity": "sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==", 1107 | "dev": true, 1108 | "license": "MIT", 1109 | "dependencies": { 1110 | "@types/estree": "1.0.6" 1111 | }, 1112 | "bin": { 1113 | "rollup": "dist/bin/rollup" 1114 | }, 1115 | "engines": { 1116 | "node": ">=18.0.0", 1117 | "npm": ">=8.0.0" 1118 | }, 1119 | "optionalDependencies": { 1120 | "@rollup/rollup-android-arm-eabi": "4.34.8", 1121 | "@rollup/rollup-android-arm64": "4.34.8", 1122 | "@rollup/rollup-darwin-arm64": "4.34.8", 1123 | "@rollup/rollup-darwin-x64": "4.34.8", 1124 | "@rollup/rollup-freebsd-arm64": "4.34.8", 1125 | "@rollup/rollup-freebsd-x64": "4.34.8", 1126 | "@rollup/rollup-linux-arm-gnueabihf": "4.34.8", 1127 | "@rollup/rollup-linux-arm-musleabihf": "4.34.8", 1128 | "@rollup/rollup-linux-arm64-gnu": "4.34.8", 1129 | "@rollup/rollup-linux-arm64-musl": "4.34.8", 1130 | "@rollup/rollup-linux-loongarch64-gnu": "4.34.8", 1131 | "@rollup/rollup-linux-powerpc64le-gnu": "4.34.8", 1132 | "@rollup/rollup-linux-riscv64-gnu": "4.34.8", 1133 | "@rollup/rollup-linux-s390x-gnu": "4.34.8", 1134 | "@rollup/rollup-linux-x64-gnu": "4.34.8", 1135 | "@rollup/rollup-linux-x64-musl": "4.34.8", 1136 | "@rollup/rollup-win32-arm64-msvc": "4.34.8", 1137 | "@rollup/rollup-win32-ia32-msvc": "4.34.8", 1138 | "@rollup/rollup-win32-x64-msvc": "4.34.8", 1139 | "fsevents": "~2.3.2" 1140 | } 1141 | }, 1142 | "node_modules/source-map-js": { 1143 | "version": "1.2.1", 1144 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", 1145 | "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", 1146 | "dev": true, 1147 | "license": "BSD-3-Clause", 1148 | "engines": { 1149 | "node": ">=0.10.0" 1150 | } 1151 | }, 1152 | "node_modules/three": { 1153 | "version": "0.173.0", 1154 | "resolved": "https://registry.npmjs.org/three/-/three-0.173.0.tgz", 1155 | "integrity": "sha512-AUwVmViIEUgBwxJJ7stnF0NkPpZxx1aZ6WiAbQ/Qq61h6I9UR4grXtZDmO8mnlaNORhHnIBlXJ1uBxILEKuVyw==", 1156 | "license": "MIT" 1157 | }, 1158 | "node_modules/tsl-uniform-ui-vite-plugin": { 1159 | "version": "0.7.2", 1160 | "resolved": "https://registry.npmjs.org/tsl-uniform-ui-vite-plugin/-/tsl-uniform-ui-vite-plugin-0.7.2.tgz", 1161 | "integrity": "sha512-/AZ/foiWUT9MpRbKi7KEMJNvZlh4QqYrR6pIYnpncCB17EuCNfS70wW8BkKlcobQJ30yXOjpQdTCCJr6oNyp5A==", 1162 | "license": "MIT", 1163 | "dependencies": { 1164 | "@babel/parser": "^7.26.9", 1165 | "@babel/traverse": "^7.26.9", 1166 | "@babel/types": "^7.26.9" 1167 | } 1168 | }, 1169 | "node_modules/tweakpane": { 1170 | "version": "4.0.5", 1171 | "resolved": "https://registry.npmjs.org/tweakpane/-/tweakpane-4.0.5.tgz", 1172 | "integrity": "sha512-rxEXdSI+ArlG1RyO6FghC4ZUX8JkEfz8F3v1JuteXSV0pEtHJzyo07fcDG+NsJfN5L39kSbCYbB9cBGHyuI/tQ==", 1173 | "license": "MIT", 1174 | "funding": { 1175 | "url": "https://github.com/sponsors/cocopon" 1176 | } 1177 | }, 1178 | "node_modules/tweakpane-plugin-file-import": { 1179 | "version": "1.1.1", 1180 | "resolved": "https://registry.npmjs.org/tweakpane-plugin-file-import/-/tweakpane-plugin-file-import-1.1.1.tgz", 1181 | "integrity": "sha512-7QbLToRTPYprzrZWJ1BWefIDJOyxj/9IHzVE/wZwK1+z1oUFtZ+ptzMxKm6apeZNoQTG7zS6opEaJi5tJ0igaQ==", 1182 | "license": "MIT", 1183 | "peerDependencies": { 1184 | "tweakpane": "^4.0.0" 1185 | } 1186 | }, 1187 | "node_modules/typescript": { 1188 | "version": "5.7.3", 1189 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", 1190 | "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", 1191 | "dev": true, 1192 | "license": "Apache-2.0", 1193 | "bin": { 1194 | "tsc": "bin/tsc", 1195 | "tsserver": "bin/tsserver" 1196 | }, 1197 | "engines": { 1198 | "node": ">=14.17" 1199 | } 1200 | }, 1201 | "node_modules/vite": { 1202 | "version": "6.1.1", 1203 | "resolved": "https://registry.npmjs.org/vite/-/vite-6.1.1.tgz", 1204 | "integrity": "sha512-4GgM54XrwRfrOp297aIYspIti66k56v16ZnqHvrIM7mG+HjDlAwS7p+Srr7J6fGvEdOJ5JcQ/D9T7HhtdXDTzA==", 1205 | "dev": true, 1206 | "license": "MIT", 1207 | "dependencies": { 1208 | "esbuild": "^0.24.2", 1209 | "postcss": "^8.5.2", 1210 | "rollup": "^4.30.1" 1211 | }, 1212 | "bin": { 1213 | "vite": "bin/vite.js" 1214 | }, 1215 | "engines": { 1216 | "node": "^18.0.0 || ^20.0.0 || >=22.0.0" 1217 | }, 1218 | "funding": { 1219 | "url": "https://github.com/vitejs/vite?sponsor=1" 1220 | }, 1221 | "optionalDependencies": { 1222 | "fsevents": "~2.3.3" 1223 | }, 1224 | "peerDependencies": { 1225 | "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", 1226 | "jiti": ">=1.21.0", 1227 | "less": "*", 1228 | "lightningcss": "^1.21.0", 1229 | "sass": "*", 1230 | "sass-embedded": "*", 1231 | "stylus": "*", 1232 | "sugarss": "*", 1233 | "terser": "^5.16.0", 1234 | "tsx": "^4.8.1", 1235 | "yaml": "^2.4.2" 1236 | }, 1237 | "peerDependenciesMeta": { 1238 | "@types/node": { 1239 | "optional": true 1240 | }, 1241 | "jiti": { 1242 | "optional": true 1243 | }, 1244 | "less": { 1245 | "optional": true 1246 | }, 1247 | "lightningcss": { 1248 | "optional": true 1249 | }, 1250 | "sass": { 1251 | "optional": true 1252 | }, 1253 | "sass-embedded": { 1254 | "optional": true 1255 | }, 1256 | "stylus": { 1257 | "optional": true 1258 | }, 1259 | "sugarss": { 1260 | "optional": true 1261 | }, 1262 | "terser": { 1263 | "optional": true 1264 | }, 1265 | "tsx": { 1266 | "optional": true 1267 | }, 1268 | "yaml": { 1269 | "optional": true 1270 | } 1271 | } 1272 | } 1273 | } 1274 | } 1275 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "three-tsl-boilerplate", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc && vite build", 9 | "preview": "vite preview" 10 | }, 11 | "devDependencies": { 12 | "typescript": "~5.7.2", 13 | "vite": "^6.1.0" 14 | }, 15 | "dependencies": { 16 | "@types/three": "^0.173.0", 17 | "three": "^0.173.0", 18 | "@tweakpane/core": "^2.0.5", 19 | "@tweakpane/plugin-essentials": "^0.2.1", 20 | "tsl-uniform-ui-vite-plugin": "^0.7.2", 21 | "tweakpane": "^4.0.5", 22 | "tweakpane-plugin-file-import": "^1.1.1" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /example/public/uv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhushan6/tsl-Uniform-UI-Vite-Plugin/eaa81750da585eff842def13912f2124c28a99ad/example/public/uv.png -------------------------------------------------------------------------------- /example/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/src/experience.ts: -------------------------------------------------------------------------------- 1 | import { OrbitControls } from "three/examples/jsm/Addons.js"; 2 | import { 3 | Fn, 4 | mix, 5 | positionGeometry, 6 | remap, 7 | uniform, 8 | } from "three/tsl"; 9 | import * as THREE from "three/webgpu"; 10 | 11 | export class Experience { 12 | private _canvas: HTMLCanvasElement; 13 | 14 | private _scene: THREE.Scene; 15 | private _camera: THREE.PerspectiveCamera; 16 | private _renderer: THREE.WebGPURenderer; 17 | private _controls: OrbitControls; 18 | private _size: { width: number; height: number } | null = null; 19 | 20 | private _parent = new THREE.Object3D(); 21 | 22 | constructor( 23 | canvas: HTMLCanvasElement, 24 | size?: { width: number; height: number } 25 | ) { 26 | this._canvas = canvas; 27 | if (size) { 28 | this._size = size; 29 | } 30 | this._camera = new THREE.PerspectiveCamera( 31 | 25, 32 | this._size 33 | ? this._size.width / this._size.height 34 | : window.innerWidth / window.innerHeight, 35 | 0.1, 36 | 100 37 | ); 38 | this._camera.position.set(0, 0, 10); 39 | 40 | this._scene = new THREE.Scene(); 41 | 42 | this._renderer = new THREE.WebGPURenderer({ 43 | antialias: true, 44 | canvas: this._canvas, 45 | }); 46 | this._renderer.setPixelRatio(window.devicePixelRatio); 47 | 48 | if (this._size) { 49 | this._renderer.setSize(this._size.width, this._size.height); 50 | } else { 51 | this._renderer.setSize(window.innerWidth, window.innerHeight); 52 | } 53 | 54 | this._controls = new OrbitControls(this._camera, this._renderer.domElement); 55 | this._controls.enableDamping = true; 56 | this._controls.minDistance = 0.1; 57 | this._controls.maxDistance = 50; 58 | this._controls.target.y = 0; 59 | this._controls.target.z = 0; 60 | this._controls.target.x = 0; 61 | this._controls.addEventListener("change", () => { 62 | if (!this._currentAnimationFrame) 63 | this._renderer.render(this._scene, this._camera); 64 | }); 65 | this._controls.domElement?.addEventListener("wheel", (e) => { 66 | e.stopImmediatePropagation(); 67 | }); 68 | 69 | window.addEventListener("resize", this.onWindowResize); 70 | 71 | const directionalLight = new THREE.DirectionalLight(0xffffff, 1); 72 | directionalLight.position.set(0, 5, 5); 73 | this._scene.add(directionalLight); 74 | 75 | const directionalLight2 = new THREE.DirectionalLight(0xffffff, 1); 76 | directionalLight2.position.set(-5, 5, 0); 77 | this._scene.add(directionalLight2); 78 | 79 | const directionalLight3 = new THREE.DirectionalLight(0xffffff, 1); 80 | directionalLight3.position.set(5, 5, 0); 81 | this._scene.add(directionalLight3); 82 | 83 | const directionalLight4 = new THREE.DirectionalLight(0xffffff, 1); 84 | directionalLight4.position.set(0, 5, -5); 85 | this._scene.add(directionalLight4); 86 | 87 | const boxGeometry = new THREE.BoxGeometry(2, 2, 2, 1, 1, 1); 88 | 89 | const boxMaterial = new THREE.MeshStandardNodeMaterial({ 90 | transparent: false, 91 | side: THREE.FrontSide, 92 | }); 93 | 94 | const box = new THREE.Mesh(boxGeometry, boxMaterial); 95 | this._scene.add(this._parent); 96 | 97 | this._parent.add(box); 98 | 99 | const color1 = uniform(new THREE.Color(0xff0000), "color"); 100 | const color2 = uniform(new THREE.Color(0x00ff00)); 101 | // const progress = uniform(0); 102 | 103 | const scale = uniform(1, "float"); 104 | const position = uniform(new THREE.Vector3(0, 0, 0), "vec3"); 105 | 106 | // const tex = new THREE.TextureLoader().load("/uv.png"); 107 | 108 | // const textureUniform = texture(tex); 109 | 110 | boxMaterial.colorNode = Fn(() => { 111 | return mix(color1, color2, remap(positionGeometry.y, -1, 1, 0, 1)); 112 | })(); 113 | boxMaterial.positionNode = Fn(() => { 114 | return positionGeometry.add(position).mul(scale); 115 | })(); 116 | } 117 | 118 | private onWindowResize = () => { 119 | if (this._size) { 120 | this._camera.aspect = this._size.width / this._size.height; 121 | } else { 122 | this._camera.aspect = window.innerWidth / window.innerHeight; 123 | } 124 | this._camera.updateProjectionMatrix(); 125 | if (this._size) { 126 | this._renderer.setSize(this._size.width, this._size.height); 127 | } else { 128 | this._renderer.setSize(window.innerWidth, window.innerHeight); 129 | } 130 | }; 131 | 132 | private _currentAnimationFrame: number | null = null; 133 | 134 | public render = () => this._renderer.render(this._scene, this._camera); 135 | 136 | private animate = () => { 137 | this._controls.update(); 138 | this.render(); 139 | this._currentAnimationFrame = requestAnimationFrame(this.animate); 140 | }; 141 | 142 | public startRendering() { 143 | if (this._currentAnimationFrame) { 144 | this.stopRendering; 145 | } 146 | this.animate(); 147 | } 148 | 149 | public stopRendering() { 150 | if (this._currentAnimationFrame !== null) { 151 | cancelAnimationFrame(this._currentAnimationFrame); 152 | this._currentAnimationFrame = null; 153 | } 154 | } 155 | 156 | public dispose() { 157 | this.stopRendering(); 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /example/src/main.ts: -------------------------------------------------------------------------------- 1 | import { Experience } from './experience'; 2 | import './style.css' 3 | 4 | const canvas = document.getElementById("canvas") as HTMLCanvasElement; 5 | 6 | if(!canvas) { 7 | throw new Error("Canvas not found"); 8 | } 9 | 10 | 11 | 12 | new Experience(canvas).startRendering(); -------------------------------------------------------------------------------- /example/src/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | } 6 | 7 | 8 | canvas{ 9 | display: block; 10 | width: 100vw; 11 | height: 100vh; 12 | background-color: black; 13 | } -------------------------------------------------------------------------------- /example/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "isolatedModules": true, 13 | "moduleDetection": "force", 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true, 21 | "noUncheckedSideEffectImports": true 22 | }, 23 | "include": ["src"] 24 | } 25 | -------------------------------------------------------------------------------- /example/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import threeUniformGui from "tsl-uniform-ui-vite-plugin"; 3 | 4 | export default defineConfig({ 5 | plugins: [threeUniformGui({devOnly: false, persistent: true})], 6 | }); 7 | 8 | -------------------------------------------------------------------------------- /package/.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 | -------------------------------------------------------------------------------- /package/UIController.ts: -------------------------------------------------------------------------------- 1 | export const uniformPaneClass = ` 2 | class UniformUIController { 3 | pane = new Pane({ title: "Shader Uniforms" }); 4 | 5 | constructor(persistent) { 6 | this.persistent = persistent; 7 | 8 | if (this.persistent) { 9 | const savedState = localStorage.getItem("threeUniformGuiPluginState"); 10 | if (savedState) { 11 | try { 12 | const parsedState = JSON.parse(savedState); 13 | this.initialUniformState = parsedState; 14 | this.currentState = this.initialUniformState 15 | } catch (err) { 16 | console.error(err); 17 | } 18 | } 19 | } 20 | 21 | const presets = localStorage.getItem("threeUniformGuiPluginPresets"); 22 | if(presets) { 23 | this.presets = JSON.parse(presets) 24 | } 25 | 26 | 27 | } 28 | 29 | setupUI(){ 30 | this.setupCopyConfigButton(); 31 | this.setupUndoRedoButtons() 32 | this.setupPresets(); 33 | } 34 | 35 | presets = {} 36 | 37 | setupPresets() { 38 | const presetFolder = this.pane.addFolder({ 39 | title: 'Presets', 40 | expanded: false 41 | }) 42 | 43 | const PRESETPARAMS = { 44 | newPresetName: "", 45 | currentPreset: "", 46 | } 47 | 48 | presetFolder.addBinding(PRESETPARAMS, "newPresetName", { 49 | label: "Name" 50 | }) 51 | 52 | const btn = presetFolder.addButton({ 53 | title: 'Create Preset', 54 | }); 55 | 56 | const createPresetDropDown = () => { 57 | const options = Object.keys(this.presets).reduce((acc, value) => { 58 | acc[value] = value 59 | return acc 60 | }, {none: ""}) 61 | 62 | const presetDropDown = presetFolder.addBinding(PRESETPARAMS, "currentPreset", { 63 | options: options 64 | }).on("change", (e) => { 65 | if(e.value.trim() === ""){ 66 | this.undoRedoInProgress = true; 67 | this.currentState && this.applyConfigs(this.currentState) 68 | this.undoRedoInProgress = false; 69 | return; 70 | } 71 | const configs = this.presets[e.value] 72 | this.undoRedoInProgress = true; 73 | configs && this.applyConfigs(configs) 74 | this.undoRedoInProgress = false; 75 | }) 76 | return presetDropDown 77 | } 78 | 79 | let presetOptions = createPresetDropDown() 80 | 81 | 82 | btn.on('click', () => { 83 | const newPresetName = PRESETPARAMS.newPresetName; 84 | if(newPresetName.trim() === "") return; 85 | const newPreset = this.uniformStateSerializer(); 86 | delete newPreset.Presets 87 | this.presets[newPresetName] = newPreset; 88 | presetOptions.dispose() 89 | presetOptions = createPresetDropDown() 90 | localStorage.setItem("threeUniformGuiPluginPresets", JSON.stringify(this.presets)); 91 | PRESETPARAMS.newPresetName = "" 92 | this.pane.refresh() 93 | }); 94 | } 95 | 96 | setupCopyConfigButton() { 97 | const btn = this.pane.addButton({ 98 | title: "Copy configs", 99 | }); 100 | 101 | let t; 102 | 103 | btn.on("click", () => { 104 | if (t) clearTimeout(t); 105 | btn.title = "Coping..."; 106 | this.pane.refresh(); 107 | 108 | const uniformState = this.uniformStateSerializer(); 109 | navigator.clipboard.writeText(JSON.stringify(uniformState)); 110 | btn.title = "Copied!!"; 111 | this.pane.refresh(); 112 | 113 | t = setTimeout(() => { 114 | btn.title = "Copy configs"; 115 | this.pane.refresh(); 116 | }, 1000); 117 | }); 118 | } 119 | 120 | uniformStateSerializer = () => { 121 | const paneState = this.pane.exportState(); 122 | 123 | const extractValues = (children, accumulator) => { 124 | return children.reduce((acc, value) => { 125 | if (value.label) { 126 | if (value.binding.value?.isColor) { 127 | const color = { 128 | r: value.binding.value.r, 129 | g: value.binding.value.g, 130 | b: value.binding.value.b, 131 | }; 132 | acc[value.label] = JSON.stringify(color); 133 | } else { 134 | acc[value.label] = value.binding.value; 135 | } 136 | } 137 | if (value.children) { 138 | acc[value.title] = extractValues(value.children, {}); 139 | } 140 | return acc; 141 | }, accumulator); 142 | }; 143 | const state = extractValues(paneState.children, {}) 144 | delete state.Presets 145 | return state; 146 | }; 147 | 148 | applyConfigs = (configs) => { 149 | const paneState = this.pane.exportState(); 150 | 151 | const applyValues = (children, params) => { 152 | children.forEach(child => { 153 | if(child.title !== 'Presets'){ 154 | if(child.binding){ 155 | const value = params[child.label] 156 | if(child.binding.value?.isColor){ 157 | const colorValue = JSON.parse(value) 158 | child.binding.value.r = colorValue.r 159 | child.binding.value.g = colorValue.g 160 | child.binding.value.b = colorValue.b 161 | }else{ 162 | child.binding.value = value 163 | } 164 | }else if(child.children){ 165 | applyValues(child.children, params[child.title] || {}) 166 | } 167 | } 168 | }) 169 | } 170 | applyValues(paneState.children, configs) 171 | this.pane.importState(paneState); 172 | } 173 | 174 | saveTimerId = null; 175 | 176 | undoStack = []; 177 | redoStack = []; 178 | 179 | undoRedoController = null 180 | 181 | refreshUndoRedoController = () => { 182 | let i = 0 183 | this.undoRedoController.cellToApiMap_.forEach((api) => { 184 | if(i === 0){ 185 | api.disabled = this.undoStack.length < 1 186 | }else{ 187 | api.disabled = this.redoStack.length < 1 188 | } 189 | i += 1; 190 | }) 191 | } 192 | 193 | undoRedoInProgress = false 194 | 195 | undo = () => { 196 | this.undoRedoInProgress = true 197 | const last = this.undoStack.pop(); 198 | const uniformState = this.uniformStateSerializer(); 199 | this.applyConfigs(last) 200 | this.redoStack.push(uniformState); 201 | this.refreshUndoRedoController() 202 | this.undoRedoInProgress = false 203 | }; 204 | 205 | redo = () => { 206 | this.undoRedoInProgress = true 207 | const last = this.redoStack.pop(); 208 | const uniformState = this.uniformStateSerializer(); 209 | this.applyConfigs(last) 210 | this.undoStack.push(uniformState); 211 | this.refreshUndoRedoController() 212 | this.undoRedoInProgress = false 213 | }; 214 | 215 | 216 | setupUndoRedoButtons = () => { 217 | this.undoRedoController = this.pane.addBlade({ 218 | view: 'buttongrid', 219 | size: [2, 1], 220 | cells: (x, y) => ({ 221 | title: [ 222 | ['Undo', 'Redo'], 223 | ][y][x], 224 | }) 225 | }).on('click', (ev) => { 226 | if(ev.index[0] === 0){ 227 | this.undo(); 228 | }else{ 229 | this.redo() 230 | } 231 | }); 232 | 233 | this.refreshUndoRedoController() 234 | } 235 | 236 | uniformSaveDebounced = () => { 237 | this.saveTimerId && clearTimeout(this.saveTimerId); 238 | console.log(this.undoRedoInProgress) 239 | if(this.undoRedoInProgress){ 240 | const uniformState = this.uniformStateSerializer(); 241 | this.persistent && 242 | localStorage.setItem( 243 | "threeUniformGuiPluginState", 244 | JSON.stringify(uniformState) 245 | ); 246 | return; 247 | } 248 | this.saveTimerId = setTimeout(() => { 249 | const uniformState = this.uniformStateSerializer(); 250 | if(this.currentState){ 251 | this.undoStack.push({...this.currentState}); 252 | } 253 | this.currentState = uniformState 254 | console.log(this.undoStack) 255 | this.refreshUndoRedoController() 256 | this.persistent && 257 | localStorage.setItem( 258 | "threeUniformGuiPluginState", 259 | JSON.stringify(uniformState) 260 | ); 261 | }, 500); 262 | }; 263 | 264 | dispose = () => {}; 265 | } 266 | 267 | `; 268 | -------------------------------------------------------------------------------- /package/index.ts: -------------------------------------------------------------------------------- 1 | import { Plugin } from "vite"; 2 | import * as parser from "@babel/parser"; 3 | import traverseDefault from "@babel/traverse"; 4 | import type { NodePath } from "@babel/traverse"; 5 | import * as t from "@babel/types"; 6 | import { uniformPaneClass } from "./UIController"; 7 | 8 | // Plugin configuration interface 9 | interface ThreeUniformGuiOptions { 10 | persistent?: boolean; 11 | devOnly?: boolean; // New option to control if the plugin only works in dev mode 12 | } 13 | 14 | // Default options 15 | const defaultOptions: ThreeUniformGuiOptions = { 16 | persistent: false, 17 | devOnly: true, // Default to only work in dev mode 18 | }; 19 | 20 | // Rest of the utility functions... 21 | const pathUtils = { 22 | basename: (filePath: string, ext?: string): string => { 23 | // Extract file name from path 24 | const parts = filePath.split(/[/\\]/); 25 | let fileName = parts[parts.length - 1]; 26 | 27 | // Remove extension if provided 28 | if (ext && fileName.endsWith(ext)) { 29 | fileName = fileName.slice(0, -ext.length); 30 | } 31 | 32 | return fileName; 33 | }, 34 | 35 | extname: (filePath: string): string => { 36 | // Extract extension from filename 37 | const lastDotIndex = filePath.lastIndexOf("."); 38 | return lastDotIndex !== -1 ? filePath.slice(lastDotIndex) : ""; 39 | }, 40 | }; 41 | 42 | // @ts-ignore 43 | const traverse = (traverseDefault.default || 44 | // @ts-ignore 45 | traverseDefault) as typeof traverseDefault.default; 46 | 47 | interface UniformInfo { 48 | name: string; 49 | type: 50 | | "boolean" 51 | | "number" 52 | | "color" 53 | | "vector2" 54 | | "vector3" 55 | | "vector4" 56 | | "matrix3" 57 | | "matrix4" 58 | | "texture"; 59 | position: number; 60 | } 61 | 62 | const debug = { 63 | log: (...args: any[]) => 64 | console.log("\x1b[36m%s\x1b[0m", "[three-uniform-gui]", ...args), 65 | warn: (...args: any[]) => 66 | console.log("\x1b[33m%s\x1b[0m", "[three-uniform-gui][warn]", ...args), 67 | error: (...args: any[]) => 68 | console.log("\x1b[31m%s\x1b[0m", "[three-uniform-gui][error]", ...args), 69 | }; 70 | 71 | // All the existing type detection and control generation functions... 72 | function getUniformType( 73 | valueNode: t.Node, 74 | typeNode?: t.Node | null 75 | ): UniformInfo["type"] | null { 76 | // Existing implementation... 77 | if (typeNode && t.isStringLiteral(typeNode)) { 78 | const explicitType = typeNode.value.toLowerCase(); 79 | switch (explicitType) { 80 | case "float": 81 | return "number"; 82 | case "bool": 83 | return "boolean"; 84 | case "color": 85 | return "color"; 86 | case "vec2": 87 | return "vector2"; 88 | case "vec3": 89 | return "vector3"; 90 | case "vec4": 91 | return "vector4"; 92 | default: 93 | return null; 94 | } 95 | } 96 | 97 | if (t.isNewExpression(valueNode)) { 98 | const className = t.isMemberExpression(valueNode.callee) 99 | ? (valueNode.callee.property as t.Identifier).name 100 | : t.isIdentifier(valueNode.callee) 101 | ? valueNode.callee.name 102 | : null; 103 | 104 | switch (className) { 105 | case "Color": 106 | return "color"; 107 | case "Vector2": 108 | return "vector2"; 109 | case "Vector3": 110 | return "vector3"; 111 | case "Vector4": 112 | return "vector4"; 113 | case "Matrix3": 114 | return "matrix3"; 115 | case "Matrix4": 116 | return "matrix4"; 117 | default: 118 | return null; 119 | } 120 | } 121 | 122 | if (t.isNumericLiteral(valueNode)) return "number"; 123 | if (t.isBooleanLiteral(valueNode)) return "boolean"; 124 | if (t.isMemberExpression(valueNode)) return "number"; 125 | 126 | return null; 127 | } 128 | 129 | const addSubfolder = (folderName: string, subfolderInit: string) => { 130 | return `{ 131 | let folder = window.uniformPane.pane.children.find(child => child.title === '${folderName}'); 132 | if(folder){ 133 | ${subfolderInit} 134 | }else{ 135 | 136 | } 137 | } 138 | `; 139 | }; 140 | 141 | function generateControl( 142 | uniform: UniformInfo, 143 | folderName: string, 144 | persistent?: boolean 145 | ): string { 146 | // Existing implementation... 147 | // [All the existing control generation code here] 148 | switch (uniform.type) { 149 | case "boolean": 150 | return addSubfolder( 151 | folderName, 152 | ` 153 | if(window.uniformPane.initialUniformState){ 154 | if(window.uniformPane.initialUniformState.${folderName}?.${uniform.name}){ 155 | ${uniform.name}.value = window.uniformPane.initialUniformState.${folderName}.${uniform.name} 156 | } 157 | }else{ 158 | const uniformState = window.uniformPane.uniformStateSerializer(); 159 | window.uniformPane.currentState = uniformState 160 | } 161 | folder.addBinding(${uniform.name}, 'value', { 162 | label: '${uniform.name}' 163 | }).on("change", () => { 164 | ${persistent} && window.uniformPane.uniformSaveDebounced() 165 | }); 166 | ` 167 | ); 168 | 169 | // [All other cases] 170 | case "number": 171 | return addSubfolder( 172 | folderName, 173 | ` 174 | if(window.uniformPane.initialUniformState){ 175 | if(window.uniformPane.initialUniformState.${folderName}?.${uniform.name}){ 176 | ${uniform.name}.value = window.uniformPane.initialUniformState.${folderName}.${uniform.name} 177 | } 178 | }else{ 179 | const uniformState = window.uniformPane.uniformStateSerializer(); 180 | window.uniformPane.currentState = uniformState 181 | } 182 | folder.addBinding(${uniform.name}, 'value', { 183 | label: '${uniform.name}', 184 | step: 0.01 185 | }).on("change", () => { 186 | ${persistent} && window.uniformPane.uniformSaveDebounced() 187 | }); 188 | ` 189 | ); 190 | case "color": 191 | return addSubfolder( 192 | folderName, 193 | ` 194 | if(window.uniformPane.initialUniformState){ 195 | if(window.uniformPane.initialUniformState.${folderName}?.${uniform.name}){ 196 | const color = JSON.parse(window.uniformPane.initialUniformState.${folderName}.${uniform.name} ) 197 | ${uniform.name}.value.setRGB(color.r, color.g, color.b) 198 | } 199 | }else{ 200 | const uniformState = window.uniformPane.uniformStateSerializer(); 201 | window.uniformPane.currentState = uniformState 202 | } 203 | folder.addBinding(${uniform.name}, 'value', { 204 | label: '${uniform.name}', 205 | view: 'color', 206 | picker: 'inline', 207 | color: {type: 'float'}, 208 | }).on("change", () => { 209 | ${persistent} && window.uniformPane.uniformSaveDebounced() 210 | }); 211 | ` 212 | ); 213 | 214 | case "vector2": 215 | case "vector3": 216 | case "vector4": 217 | const axes = 218 | uniform.type === "vector2" 219 | ? ["x", "y"] 220 | : uniform.type === "vector3" 221 | ? ["x", "y", "z"] 222 | : ["x", "y", "z", "w"]; 223 | 224 | return addSubfolder( 225 | folderName, 226 | ` 227 | const ${uniform.name}Folder = folder.addFolder({ 228 | title: '${uniform.name}' 229 | }) 230 | 231 | ${axes 232 | .map((axis) => { 233 | return ` 234 | if(window.uniformPane.initialUniformState){ 235 | if(window.uniformPane.initialUniformState.${folderName}?.${uniform.name}){ 236 | const value = window.uniformPane.initialUniformState.${folderName}.${uniform.name} 237 | ${uniform.name}.value.${axis} = value.${axis} 238 | } 239 | }else{ 240 | const uniformState = window.uniformPane.uniformStateSerializer(); 241 | window.uniformPane.currentState = uniformState 242 | } 243 | ${uniform.name}Folder.addBinding(${uniform.name}.value, '${axis}', { 244 | label: '${axis}', 245 | step: 0.01 246 | }).on("change", () => { 247 | ${persistent} && window.uniformPane.uniformSaveDebounced() 248 | }); 249 | `; 250 | }) 251 | .join("\n")} 252 | ` 253 | ); 254 | case "texture": 255 | return addSubfolder( 256 | folderName, 257 | ` const ${uniform.name}Params = { 258 | file: "", 259 | } 260 | const ${uniform.name}Folder = folder.addFolder({ 261 | title: '${uniform.name}' 262 | }); 263 | ${uniform.name}Folder.addBinding(${uniform.name}Params, "file", { 264 | view: "file-input", 265 | lineCount: 3, 266 | filetypes: [".png", ".jpg"], 267 | invalidFiletypeMessage: "We can't accept those filetypes!", 268 | }) 269 | .on("change", (ev) => { 270 | if (!ev.value) { 271 | return; 272 | } 273 | const imageFile = ev.value; 274 | const blobUrl = URL.createObjectURL(imageFile); 275 | const texture = new THREE.TextureLoader().load(blobUrl); 276 | ${uniform.name}.value = texture; 277 | ${persistent} && window.uniformPane.uniformSaveDebounced() 278 | });` 279 | ); 280 | default: 281 | return ""; 282 | } 283 | } 284 | 285 | // Updated plugin function to accept options 286 | export default function threeUniformGuiPlugin(options?: ThreeUniformGuiOptions | boolean): Plugin { 287 | // Handle backward compatibility - if a boolean is passed, treat it as the persistent option 288 | const opts = typeof options === 'boolean' 289 | ? { ...defaultOptions, persistent: options } 290 | : { ...defaultOptions, ...options }; 291 | 292 | debug.log("Options:", opts); 293 | 294 | return { 295 | name: "three-uniform-gui", 296 | apply: (config, { command }) => { 297 | // Only apply in development mode if devOnly is true 298 | if (opts.devOnly && command !== 'serve') { 299 | return false; 300 | } 301 | return true; 302 | }, 303 | transform(code, id) { 304 | if (!id.match(/\.[jt]sx?$/)) return; 305 | 306 | debug.log("Processing file:", id); 307 | 308 | try { 309 | const ast = parser.parse(code, { 310 | sourceType: "module", 311 | plugins: ["typescript", "jsx"], 312 | }); 313 | 314 | const uniforms: UniformInfo[] = []; 315 | let paneExists = false; 316 | 317 | traverse(ast, { 318 | VariableDeclarator(path: NodePath) { 319 | // Existing implementation... 320 | if ( 321 | t.isCallExpression(path.node.init) && 322 | t.isIdentifier(path.node.init.callee) && 323 | path.node.init.callee.name === "uniform" && 324 | t.isIdentifier(path.node.id) 325 | ) { 326 | const [valueArg, typeArg] = path.node.init.arguments; 327 | 328 | let type = getUniformType(valueArg, typeArg); 329 | 330 | if (!type && t.isIdentifier(valueArg)) { 331 | const binding = path.scope.getBinding(valueArg.name); 332 | if ( 333 | binding && 334 | binding.kind !== "module" && 335 | binding.path.node.init 336 | ) { 337 | const initNode = binding.path.node.init; 338 | type = getUniformType(initNode); 339 | } 340 | } 341 | 342 | if (type && path.node.end) { 343 | uniforms.push({ 344 | name: path.node.id.name, 345 | type, 346 | position: path.node.end, 347 | }); 348 | } 349 | } 350 | // Check for texture uniform patterns 351 | if ( 352 | t.isIdentifier(path.node.id) && 353 | t.isCallExpression(path.node.init) && 354 | t.isIdentifier(path.node.init.callee) && 355 | path.node.init.callee.name === "texture" && 356 | path.node.end 357 | ) { 358 | uniforms.push({ 359 | name: path.node.id.name, 360 | type: "texture", 361 | position: path.node.end, 362 | }); 363 | } 364 | }, 365 | //@ts-ignore 366 | ImportDeclaration(path) { 367 | if ( 368 | path.node.source.value === "tweakpane" && 369 | path.node.specifiers.some( 370 | //@ts-ignore 371 | (spec) => 372 | //@ts-ignore 373 | t.isImportSpecifier(spec) && spec.imported.name === "Pane" 374 | ) 375 | ) { 376 | paneExists = true; 377 | } 378 | }, 379 | }); 380 | 381 | if (uniforms.length === 0) { 382 | debug.log("No uniforms found in file"); 383 | return; 384 | } 385 | 386 | const ext = pathUtils.extname(id); 387 | const fileName = pathUtils.basename(id, ext); 388 | 389 | debug.log("Found uniforms:", uniforms); 390 | 391 | uniforms.sort((a, b) => b.position - a.position); 392 | 393 | let modifiedCode = code; 394 | 395 | let lastImportIndex = 0; 396 | traverse(ast, { 397 | //@ts-ignore 398 | ImportDeclaration(path) { 399 | const endIndex = path.node.end || 0; 400 | lastImportIndex = Math.max(lastImportIndex, endIndex); 401 | }, 402 | }); 403 | 404 | uniforms.forEach((uniform) => { 405 | const control = generateControl( 406 | uniform, 407 | `uniform_${fileName}`, 408 | opts.persistent 409 | ); 410 | modifiedCode = 411 | modifiedCode.slice(0, uniform.position) + 412 | ";\n" + 413 | control + 414 | modifiedCode.slice(uniform.position); 415 | }); 416 | 417 | modifiedCode = 418 | modifiedCode.slice(0, lastImportIndex) + 419 | ` 420 | if (!window.uniformPane) { 421 | ${uniformPaneClass} 422 | window.uniformPane = new UniformUIController(${opts.persistent}); 423 | window.uniformPane.pane.registerPlugin(TweakpaneEssentialsPlugin); 424 | window.uniformPane.pane.registerPlugin(TweakpaneFileImportPlugin); 425 | window.uniformPane.setupUI() 426 | } 427 | 428 | let folder = window.uniformPane.pane.children.find(child => child.title === 'uniform_${fileName}'); 429 | if (folder) { 430 | folder.dispose(); 431 | } 432 | 433 | window.uniformPane.pane.addFolder({ title: 'uniform_${fileName}'}) 434 | 435 | ` + 436 | modifiedCode.slice(lastImportIndex); 437 | 438 | if (!paneExists) { 439 | modifiedCode = 440 | ` 441 | import { Pane } from 'tweakpane'; 442 | import * as TweakpaneEssentialsPlugin from '@tweakpane/plugin-essentials'; 443 | import * as TweakpaneFileImportPlugin from 'tweakpane-plugin-file-import'; 444 | ` + modifiedCode; 445 | } 446 | 447 | debug.log("Successfully transformed file"); 448 | return { 449 | code: modifiedCode, 450 | map: null, 451 | }; 452 | } catch (error) { 453 | debug.error("Error processing file:", error); 454 | return null; 455 | } 456 | }, 457 | }; 458 | } -------------------------------------------------------------------------------- /package/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tsl-uniform-ui-vite-plugin", 3 | "version": "0.7.2", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "tsl-uniform-ui-vite-plugin", 9 | "version": "0.7.2", 10 | "license": "MIT", 11 | "dependencies": { 12 | "@babel/parser": "^7.26.9", 13 | "@babel/traverse": "^7.26.9", 14 | "@babel/types": "^7.26.9", 15 | "@tweakpane/core": "^2.0.5", 16 | "tweakpane": "^4.0.5", 17 | "tweakpane-plugin-file-import": "^1.1.1" 18 | }, 19 | "devDependencies": { 20 | "@types/babel__traverse": "^7.20.6", 21 | "typescript": "~5.7.2", 22 | "vite": "^6.1.0", 23 | "vite-plugin-dts": "^4.5.0" 24 | } 25 | }, 26 | "node_modules/@babel/code-frame": { 27 | "version": "7.26.2", 28 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", 29 | "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", 30 | "license": "MIT", 31 | "dependencies": { 32 | "@babel/helper-validator-identifier": "^7.25.9", 33 | "js-tokens": "^4.0.0", 34 | "picocolors": "^1.0.0" 35 | }, 36 | "engines": { 37 | "node": ">=6.9.0" 38 | } 39 | }, 40 | "node_modules/@babel/generator": { 41 | "version": "7.26.9", 42 | "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.9.tgz", 43 | "integrity": "sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==", 44 | "license": "MIT", 45 | "dependencies": { 46 | "@babel/parser": "^7.26.9", 47 | "@babel/types": "^7.26.9", 48 | "@jridgewell/gen-mapping": "^0.3.5", 49 | "@jridgewell/trace-mapping": "^0.3.25", 50 | "jsesc": "^3.0.2" 51 | }, 52 | "engines": { 53 | "node": ">=6.9.0" 54 | } 55 | }, 56 | "node_modules/@babel/helper-string-parser": { 57 | "version": "7.25.9", 58 | "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", 59 | "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", 60 | "license": "MIT", 61 | "engines": { 62 | "node": ">=6.9.0" 63 | } 64 | }, 65 | "node_modules/@babel/helper-validator-identifier": { 66 | "version": "7.25.9", 67 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", 68 | "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", 69 | "license": "MIT", 70 | "engines": { 71 | "node": ">=6.9.0" 72 | } 73 | }, 74 | "node_modules/@babel/parser": { 75 | "version": "7.26.9", 76 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.9.tgz", 77 | "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==", 78 | "license": "MIT", 79 | "dependencies": { 80 | "@babel/types": "^7.26.9" 81 | }, 82 | "bin": { 83 | "parser": "bin/babel-parser.js" 84 | }, 85 | "engines": { 86 | "node": ">=6.0.0" 87 | } 88 | }, 89 | "node_modules/@babel/template": { 90 | "version": "7.26.9", 91 | "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz", 92 | "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==", 93 | "license": "MIT", 94 | "dependencies": { 95 | "@babel/code-frame": "^7.26.2", 96 | "@babel/parser": "^7.26.9", 97 | "@babel/types": "^7.26.9" 98 | }, 99 | "engines": { 100 | "node": ">=6.9.0" 101 | } 102 | }, 103 | "node_modules/@babel/traverse": { 104 | "version": "7.26.9", 105 | "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.9.tgz", 106 | "integrity": "sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==", 107 | "license": "MIT", 108 | "dependencies": { 109 | "@babel/code-frame": "^7.26.2", 110 | "@babel/generator": "^7.26.9", 111 | "@babel/parser": "^7.26.9", 112 | "@babel/template": "^7.26.9", 113 | "@babel/types": "^7.26.9", 114 | "debug": "^4.3.1", 115 | "globals": "^11.1.0" 116 | }, 117 | "engines": { 118 | "node": ">=6.9.0" 119 | } 120 | }, 121 | "node_modules/@babel/types": { 122 | "version": "7.26.9", 123 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz", 124 | "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==", 125 | "license": "MIT", 126 | "dependencies": { 127 | "@babel/helper-string-parser": "^7.25.9", 128 | "@babel/helper-validator-identifier": "^7.25.9" 129 | }, 130 | "engines": { 131 | "node": ">=6.9.0" 132 | } 133 | }, 134 | "node_modules/@esbuild/aix-ppc64": { 135 | "version": "0.24.2", 136 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", 137 | "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==", 138 | "cpu": [ 139 | "ppc64" 140 | ], 141 | "dev": true, 142 | "license": "MIT", 143 | "optional": true, 144 | "os": [ 145 | "aix" 146 | ], 147 | "engines": { 148 | "node": ">=18" 149 | } 150 | }, 151 | "node_modules/@esbuild/android-arm": { 152 | "version": "0.24.2", 153 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz", 154 | "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==", 155 | "cpu": [ 156 | "arm" 157 | ], 158 | "dev": true, 159 | "license": "MIT", 160 | "optional": true, 161 | "os": [ 162 | "android" 163 | ], 164 | "engines": { 165 | "node": ">=18" 166 | } 167 | }, 168 | "node_modules/@esbuild/android-arm64": { 169 | "version": "0.24.2", 170 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz", 171 | "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==", 172 | "cpu": [ 173 | "arm64" 174 | ], 175 | "dev": true, 176 | "license": "MIT", 177 | "optional": true, 178 | "os": [ 179 | "android" 180 | ], 181 | "engines": { 182 | "node": ">=18" 183 | } 184 | }, 185 | "node_modules/@esbuild/android-x64": { 186 | "version": "0.24.2", 187 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz", 188 | "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==", 189 | "cpu": [ 190 | "x64" 191 | ], 192 | "dev": true, 193 | "license": "MIT", 194 | "optional": true, 195 | "os": [ 196 | "android" 197 | ], 198 | "engines": { 199 | "node": ">=18" 200 | } 201 | }, 202 | "node_modules/@esbuild/darwin-arm64": { 203 | "version": "0.24.2", 204 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz", 205 | "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==", 206 | "cpu": [ 207 | "arm64" 208 | ], 209 | "dev": true, 210 | "license": "MIT", 211 | "optional": true, 212 | "os": [ 213 | "darwin" 214 | ], 215 | "engines": { 216 | "node": ">=18" 217 | } 218 | }, 219 | "node_modules/@esbuild/darwin-x64": { 220 | "version": "0.24.2", 221 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz", 222 | "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==", 223 | "cpu": [ 224 | "x64" 225 | ], 226 | "dev": true, 227 | "license": "MIT", 228 | "optional": true, 229 | "os": [ 230 | "darwin" 231 | ], 232 | "engines": { 233 | "node": ">=18" 234 | } 235 | }, 236 | "node_modules/@esbuild/freebsd-arm64": { 237 | "version": "0.24.2", 238 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz", 239 | "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==", 240 | "cpu": [ 241 | "arm64" 242 | ], 243 | "dev": true, 244 | "license": "MIT", 245 | "optional": true, 246 | "os": [ 247 | "freebsd" 248 | ], 249 | "engines": { 250 | "node": ">=18" 251 | } 252 | }, 253 | "node_modules/@esbuild/freebsd-x64": { 254 | "version": "0.24.2", 255 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz", 256 | "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==", 257 | "cpu": [ 258 | "x64" 259 | ], 260 | "dev": true, 261 | "license": "MIT", 262 | "optional": true, 263 | "os": [ 264 | "freebsd" 265 | ], 266 | "engines": { 267 | "node": ">=18" 268 | } 269 | }, 270 | "node_modules/@esbuild/linux-arm": { 271 | "version": "0.24.2", 272 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz", 273 | "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==", 274 | "cpu": [ 275 | "arm" 276 | ], 277 | "dev": true, 278 | "license": "MIT", 279 | "optional": true, 280 | "os": [ 281 | "linux" 282 | ], 283 | "engines": { 284 | "node": ">=18" 285 | } 286 | }, 287 | "node_modules/@esbuild/linux-arm64": { 288 | "version": "0.24.2", 289 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz", 290 | "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==", 291 | "cpu": [ 292 | "arm64" 293 | ], 294 | "dev": true, 295 | "license": "MIT", 296 | "optional": true, 297 | "os": [ 298 | "linux" 299 | ], 300 | "engines": { 301 | "node": ">=18" 302 | } 303 | }, 304 | "node_modules/@esbuild/linux-ia32": { 305 | "version": "0.24.2", 306 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz", 307 | "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==", 308 | "cpu": [ 309 | "ia32" 310 | ], 311 | "dev": true, 312 | "license": "MIT", 313 | "optional": true, 314 | "os": [ 315 | "linux" 316 | ], 317 | "engines": { 318 | "node": ">=18" 319 | } 320 | }, 321 | "node_modules/@esbuild/linux-loong64": { 322 | "version": "0.24.2", 323 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz", 324 | "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==", 325 | "cpu": [ 326 | "loong64" 327 | ], 328 | "dev": true, 329 | "license": "MIT", 330 | "optional": true, 331 | "os": [ 332 | "linux" 333 | ], 334 | "engines": { 335 | "node": ">=18" 336 | } 337 | }, 338 | "node_modules/@esbuild/linux-mips64el": { 339 | "version": "0.24.2", 340 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz", 341 | "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==", 342 | "cpu": [ 343 | "mips64el" 344 | ], 345 | "dev": true, 346 | "license": "MIT", 347 | "optional": true, 348 | "os": [ 349 | "linux" 350 | ], 351 | "engines": { 352 | "node": ">=18" 353 | } 354 | }, 355 | "node_modules/@esbuild/linux-ppc64": { 356 | "version": "0.24.2", 357 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz", 358 | "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==", 359 | "cpu": [ 360 | "ppc64" 361 | ], 362 | "dev": true, 363 | "license": "MIT", 364 | "optional": true, 365 | "os": [ 366 | "linux" 367 | ], 368 | "engines": { 369 | "node": ">=18" 370 | } 371 | }, 372 | "node_modules/@esbuild/linux-riscv64": { 373 | "version": "0.24.2", 374 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz", 375 | "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==", 376 | "cpu": [ 377 | "riscv64" 378 | ], 379 | "dev": true, 380 | "license": "MIT", 381 | "optional": true, 382 | "os": [ 383 | "linux" 384 | ], 385 | "engines": { 386 | "node": ">=18" 387 | } 388 | }, 389 | "node_modules/@esbuild/linux-s390x": { 390 | "version": "0.24.2", 391 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz", 392 | "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==", 393 | "cpu": [ 394 | "s390x" 395 | ], 396 | "dev": true, 397 | "license": "MIT", 398 | "optional": true, 399 | "os": [ 400 | "linux" 401 | ], 402 | "engines": { 403 | "node": ">=18" 404 | } 405 | }, 406 | "node_modules/@esbuild/linux-x64": { 407 | "version": "0.24.2", 408 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz", 409 | "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==", 410 | "cpu": [ 411 | "x64" 412 | ], 413 | "dev": true, 414 | "license": "MIT", 415 | "optional": true, 416 | "os": [ 417 | "linux" 418 | ], 419 | "engines": { 420 | "node": ">=18" 421 | } 422 | }, 423 | "node_modules/@esbuild/netbsd-arm64": { 424 | "version": "0.24.2", 425 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz", 426 | "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==", 427 | "cpu": [ 428 | "arm64" 429 | ], 430 | "dev": true, 431 | "license": "MIT", 432 | "optional": true, 433 | "os": [ 434 | "netbsd" 435 | ], 436 | "engines": { 437 | "node": ">=18" 438 | } 439 | }, 440 | "node_modules/@esbuild/netbsd-x64": { 441 | "version": "0.24.2", 442 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz", 443 | "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==", 444 | "cpu": [ 445 | "x64" 446 | ], 447 | "dev": true, 448 | "license": "MIT", 449 | "optional": true, 450 | "os": [ 451 | "netbsd" 452 | ], 453 | "engines": { 454 | "node": ">=18" 455 | } 456 | }, 457 | "node_modules/@esbuild/openbsd-arm64": { 458 | "version": "0.24.2", 459 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz", 460 | "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==", 461 | "cpu": [ 462 | "arm64" 463 | ], 464 | "dev": true, 465 | "license": "MIT", 466 | "optional": true, 467 | "os": [ 468 | "openbsd" 469 | ], 470 | "engines": { 471 | "node": ">=18" 472 | } 473 | }, 474 | "node_modules/@esbuild/openbsd-x64": { 475 | "version": "0.24.2", 476 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz", 477 | "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==", 478 | "cpu": [ 479 | "x64" 480 | ], 481 | "dev": true, 482 | "license": "MIT", 483 | "optional": true, 484 | "os": [ 485 | "openbsd" 486 | ], 487 | "engines": { 488 | "node": ">=18" 489 | } 490 | }, 491 | "node_modules/@esbuild/sunos-x64": { 492 | "version": "0.24.2", 493 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz", 494 | "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==", 495 | "cpu": [ 496 | "x64" 497 | ], 498 | "dev": true, 499 | "license": "MIT", 500 | "optional": true, 501 | "os": [ 502 | "sunos" 503 | ], 504 | "engines": { 505 | "node": ">=18" 506 | } 507 | }, 508 | "node_modules/@esbuild/win32-arm64": { 509 | "version": "0.24.2", 510 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz", 511 | "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==", 512 | "cpu": [ 513 | "arm64" 514 | ], 515 | "dev": true, 516 | "license": "MIT", 517 | "optional": true, 518 | "os": [ 519 | "win32" 520 | ], 521 | "engines": { 522 | "node": ">=18" 523 | } 524 | }, 525 | "node_modules/@esbuild/win32-ia32": { 526 | "version": "0.24.2", 527 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz", 528 | "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==", 529 | "cpu": [ 530 | "ia32" 531 | ], 532 | "dev": true, 533 | "license": "MIT", 534 | "optional": true, 535 | "os": [ 536 | "win32" 537 | ], 538 | "engines": { 539 | "node": ">=18" 540 | } 541 | }, 542 | "node_modules/@esbuild/win32-x64": { 543 | "version": "0.24.2", 544 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz", 545 | "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==", 546 | "cpu": [ 547 | "x64" 548 | ], 549 | "dev": true, 550 | "license": "MIT", 551 | "optional": true, 552 | "os": [ 553 | "win32" 554 | ], 555 | "engines": { 556 | "node": ">=18" 557 | } 558 | }, 559 | "node_modules/@jridgewell/gen-mapping": { 560 | "version": "0.3.8", 561 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", 562 | "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", 563 | "license": "MIT", 564 | "dependencies": { 565 | "@jridgewell/set-array": "^1.2.1", 566 | "@jridgewell/sourcemap-codec": "^1.4.10", 567 | "@jridgewell/trace-mapping": "^0.3.24" 568 | }, 569 | "engines": { 570 | "node": ">=6.0.0" 571 | } 572 | }, 573 | "node_modules/@jridgewell/resolve-uri": { 574 | "version": "3.1.2", 575 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", 576 | "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", 577 | "license": "MIT", 578 | "engines": { 579 | "node": ">=6.0.0" 580 | } 581 | }, 582 | "node_modules/@jridgewell/set-array": { 583 | "version": "1.2.1", 584 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", 585 | "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", 586 | "license": "MIT", 587 | "engines": { 588 | "node": ">=6.0.0" 589 | } 590 | }, 591 | "node_modules/@jridgewell/sourcemap-codec": { 592 | "version": "1.5.0", 593 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", 594 | "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", 595 | "license": "MIT" 596 | }, 597 | "node_modules/@jridgewell/trace-mapping": { 598 | "version": "0.3.25", 599 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", 600 | "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", 601 | "license": "MIT", 602 | "dependencies": { 603 | "@jridgewell/resolve-uri": "^3.1.0", 604 | "@jridgewell/sourcemap-codec": "^1.4.14" 605 | } 606 | }, 607 | "node_modules/@microsoft/api-extractor": { 608 | "version": "7.50.0", 609 | "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.50.0.tgz", 610 | "integrity": "sha512-Ds/PHTiVzuENQsmXrJKkSdfgNkr/SDG/2rDef0AWl3BchAnXdO7gXaYsAkNx4gWiC4OngNA3fQfd3+BcQxP1DQ==", 611 | "dev": true, 612 | "license": "MIT", 613 | "dependencies": { 614 | "@microsoft/api-extractor-model": "7.30.3", 615 | "@microsoft/tsdoc": "~0.15.1", 616 | "@microsoft/tsdoc-config": "~0.17.1", 617 | "@rushstack/node-core-library": "5.11.0", 618 | "@rushstack/rig-package": "0.5.3", 619 | "@rushstack/terminal": "0.15.0", 620 | "@rushstack/ts-command-line": "4.23.5", 621 | "lodash": "~4.17.15", 622 | "minimatch": "~3.0.3", 623 | "resolve": "~1.22.1", 624 | "semver": "~7.5.4", 625 | "source-map": "~0.6.1", 626 | "typescript": "5.7.2" 627 | }, 628 | "bin": { 629 | "api-extractor": "bin/api-extractor" 630 | } 631 | }, 632 | "node_modules/@microsoft/api-extractor-model": { 633 | "version": "7.30.3", 634 | "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.30.3.tgz", 635 | "integrity": "sha512-yEAvq0F78MmStXdqz9TTT4PZ05Xu5R8nqgwI5xmUmQjWBQ9E6R2n8HB/iZMRciG4rf9iwI2mtuQwIzDXBvHn1w==", 636 | "dev": true, 637 | "license": "MIT", 638 | "dependencies": { 639 | "@microsoft/tsdoc": "~0.15.1", 640 | "@microsoft/tsdoc-config": "~0.17.1", 641 | "@rushstack/node-core-library": "5.11.0" 642 | } 643 | }, 644 | "node_modules/@microsoft/api-extractor/node_modules/typescript": { 645 | "version": "5.7.2", 646 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", 647 | "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", 648 | "dev": true, 649 | "license": "Apache-2.0", 650 | "bin": { 651 | "tsc": "bin/tsc", 652 | "tsserver": "bin/tsserver" 653 | }, 654 | "engines": { 655 | "node": ">=14.17" 656 | } 657 | }, 658 | "node_modules/@microsoft/tsdoc": { 659 | "version": "0.15.1", 660 | "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz", 661 | "integrity": "sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==", 662 | "dev": true, 663 | "license": "MIT" 664 | }, 665 | "node_modules/@microsoft/tsdoc-config": { 666 | "version": "0.17.1", 667 | "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.17.1.tgz", 668 | "integrity": "sha512-UtjIFe0C6oYgTnad4q1QP4qXwLhe6tIpNTRStJ2RZEPIkqQPREAwE5spzVxsdn9UaEMUqhh0AqSx3X4nWAKXWw==", 669 | "dev": true, 670 | "license": "MIT", 671 | "dependencies": { 672 | "@microsoft/tsdoc": "0.15.1", 673 | "ajv": "~8.12.0", 674 | "jju": "~1.4.0", 675 | "resolve": "~1.22.2" 676 | } 677 | }, 678 | "node_modules/@rollup/pluginutils": { 679 | "version": "5.1.4", 680 | "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz", 681 | "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==", 682 | "dev": true, 683 | "license": "MIT", 684 | "dependencies": { 685 | "@types/estree": "^1.0.0", 686 | "estree-walker": "^2.0.2", 687 | "picomatch": "^4.0.2" 688 | }, 689 | "engines": { 690 | "node": ">=14.0.0" 691 | }, 692 | "peerDependencies": { 693 | "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" 694 | }, 695 | "peerDependenciesMeta": { 696 | "rollup": { 697 | "optional": true 698 | } 699 | } 700 | }, 701 | "node_modules/@rollup/rollup-android-arm-eabi": { 702 | "version": "4.34.8", 703 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz", 704 | "integrity": "sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==", 705 | "cpu": [ 706 | "arm" 707 | ], 708 | "dev": true, 709 | "license": "MIT", 710 | "optional": true, 711 | "os": [ 712 | "android" 713 | ] 714 | }, 715 | "node_modules/@rollup/rollup-android-arm64": { 716 | "version": "4.34.8", 717 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.8.tgz", 718 | "integrity": "sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==", 719 | "cpu": [ 720 | "arm64" 721 | ], 722 | "dev": true, 723 | "license": "MIT", 724 | "optional": true, 725 | "os": [ 726 | "android" 727 | ] 728 | }, 729 | "node_modules/@rollup/rollup-darwin-arm64": { 730 | "version": "4.34.8", 731 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.8.tgz", 732 | "integrity": "sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==", 733 | "cpu": [ 734 | "arm64" 735 | ], 736 | "dev": true, 737 | "license": "MIT", 738 | "optional": true, 739 | "os": [ 740 | "darwin" 741 | ] 742 | }, 743 | "node_modules/@rollup/rollup-darwin-x64": { 744 | "version": "4.34.8", 745 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.8.tgz", 746 | "integrity": "sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==", 747 | "cpu": [ 748 | "x64" 749 | ], 750 | "dev": true, 751 | "license": "MIT", 752 | "optional": true, 753 | "os": [ 754 | "darwin" 755 | ] 756 | }, 757 | "node_modules/@rollup/rollup-freebsd-arm64": { 758 | "version": "4.34.8", 759 | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.8.tgz", 760 | "integrity": "sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==", 761 | "cpu": [ 762 | "arm64" 763 | ], 764 | "dev": true, 765 | "license": "MIT", 766 | "optional": true, 767 | "os": [ 768 | "freebsd" 769 | ] 770 | }, 771 | "node_modules/@rollup/rollup-freebsd-x64": { 772 | "version": "4.34.8", 773 | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.8.tgz", 774 | "integrity": "sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==", 775 | "cpu": [ 776 | "x64" 777 | ], 778 | "dev": true, 779 | "license": "MIT", 780 | "optional": true, 781 | "os": [ 782 | "freebsd" 783 | ] 784 | }, 785 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": { 786 | "version": "4.34.8", 787 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.8.tgz", 788 | "integrity": "sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==", 789 | "cpu": [ 790 | "arm" 791 | ], 792 | "dev": true, 793 | "license": "MIT", 794 | "optional": true, 795 | "os": [ 796 | "linux" 797 | ] 798 | }, 799 | "node_modules/@rollup/rollup-linux-arm-musleabihf": { 800 | "version": "4.34.8", 801 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.8.tgz", 802 | "integrity": "sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==", 803 | "cpu": [ 804 | "arm" 805 | ], 806 | "dev": true, 807 | "license": "MIT", 808 | "optional": true, 809 | "os": [ 810 | "linux" 811 | ] 812 | }, 813 | "node_modules/@rollup/rollup-linux-arm64-gnu": { 814 | "version": "4.34.8", 815 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.8.tgz", 816 | "integrity": "sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==", 817 | "cpu": [ 818 | "arm64" 819 | ], 820 | "dev": true, 821 | "license": "MIT", 822 | "optional": true, 823 | "os": [ 824 | "linux" 825 | ] 826 | }, 827 | "node_modules/@rollup/rollup-linux-arm64-musl": { 828 | "version": "4.34.8", 829 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.8.tgz", 830 | "integrity": "sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==", 831 | "cpu": [ 832 | "arm64" 833 | ], 834 | "dev": true, 835 | "license": "MIT", 836 | "optional": true, 837 | "os": [ 838 | "linux" 839 | ] 840 | }, 841 | "node_modules/@rollup/rollup-linux-loongarch64-gnu": { 842 | "version": "4.34.8", 843 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.8.tgz", 844 | "integrity": "sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==", 845 | "cpu": [ 846 | "loong64" 847 | ], 848 | "dev": true, 849 | "license": "MIT", 850 | "optional": true, 851 | "os": [ 852 | "linux" 853 | ] 854 | }, 855 | "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { 856 | "version": "4.34.8", 857 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.8.tgz", 858 | "integrity": "sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==", 859 | "cpu": [ 860 | "ppc64" 861 | ], 862 | "dev": true, 863 | "license": "MIT", 864 | "optional": true, 865 | "os": [ 866 | "linux" 867 | ] 868 | }, 869 | "node_modules/@rollup/rollup-linux-riscv64-gnu": { 870 | "version": "4.34.8", 871 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.8.tgz", 872 | "integrity": "sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==", 873 | "cpu": [ 874 | "riscv64" 875 | ], 876 | "dev": true, 877 | "license": "MIT", 878 | "optional": true, 879 | "os": [ 880 | "linux" 881 | ] 882 | }, 883 | "node_modules/@rollup/rollup-linux-s390x-gnu": { 884 | "version": "4.34.8", 885 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.8.tgz", 886 | "integrity": "sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==", 887 | "cpu": [ 888 | "s390x" 889 | ], 890 | "dev": true, 891 | "license": "MIT", 892 | "optional": true, 893 | "os": [ 894 | "linux" 895 | ] 896 | }, 897 | "node_modules/@rollup/rollup-linux-x64-gnu": { 898 | "version": "4.34.8", 899 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.8.tgz", 900 | "integrity": "sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==", 901 | "cpu": [ 902 | "x64" 903 | ], 904 | "dev": true, 905 | "license": "MIT", 906 | "optional": true, 907 | "os": [ 908 | "linux" 909 | ] 910 | }, 911 | "node_modules/@rollup/rollup-linux-x64-musl": { 912 | "version": "4.34.8", 913 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.8.tgz", 914 | "integrity": "sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==", 915 | "cpu": [ 916 | "x64" 917 | ], 918 | "dev": true, 919 | "license": "MIT", 920 | "optional": true, 921 | "os": [ 922 | "linux" 923 | ] 924 | }, 925 | "node_modules/@rollup/rollup-win32-arm64-msvc": { 926 | "version": "4.34.8", 927 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.8.tgz", 928 | "integrity": "sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==", 929 | "cpu": [ 930 | "arm64" 931 | ], 932 | "dev": true, 933 | "license": "MIT", 934 | "optional": true, 935 | "os": [ 936 | "win32" 937 | ] 938 | }, 939 | "node_modules/@rollup/rollup-win32-ia32-msvc": { 940 | "version": "4.34.8", 941 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.8.tgz", 942 | "integrity": "sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==", 943 | "cpu": [ 944 | "ia32" 945 | ], 946 | "dev": true, 947 | "license": "MIT", 948 | "optional": true, 949 | "os": [ 950 | "win32" 951 | ] 952 | }, 953 | "node_modules/@rollup/rollup-win32-x64-msvc": { 954 | "version": "4.34.8", 955 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.8.tgz", 956 | "integrity": "sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==", 957 | "cpu": [ 958 | "x64" 959 | ], 960 | "dev": true, 961 | "license": "MIT", 962 | "optional": true, 963 | "os": [ 964 | "win32" 965 | ] 966 | }, 967 | "node_modules/@rushstack/node-core-library": { 968 | "version": "5.11.0", 969 | "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.11.0.tgz", 970 | "integrity": "sha512-I8+VzG9A0F3nH2rLpPd7hF8F7l5Xb7D+ldrWVZYegXM6CsKkvWc670RlgK3WX8/AseZfXA/vVrh0bpXe2Y2UDQ==", 971 | "dev": true, 972 | "license": "MIT", 973 | "dependencies": { 974 | "ajv": "~8.13.0", 975 | "ajv-draft-04": "~1.0.0", 976 | "ajv-formats": "~3.0.1", 977 | "fs-extra": "~11.3.0", 978 | "import-lazy": "~4.0.0", 979 | "jju": "~1.4.0", 980 | "resolve": "~1.22.1", 981 | "semver": "~7.5.4" 982 | }, 983 | "peerDependencies": { 984 | "@types/node": "*" 985 | }, 986 | "peerDependenciesMeta": { 987 | "@types/node": { 988 | "optional": true 989 | } 990 | } 991 | }, 992 | "node_modules/@rushstack/node-core-library/node_modules/ajv": { 993 | "version": "8.13.0", 994 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", 995 | "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", 996 | "dev": true, 997 | "license": "MIT", 998 | "dependencies": { 999 | "fast-deep-equal": "^3.1.3", 1000 | "json-schema-traverse": "^1.0.0", 1001 | "require-from-string": "^2.0.2", 1002 | "uri-js": "^4.4.1" 1003 | }, 1004 | "funding": { 1005 | "type": "github", 1006 | "url": "https://github.com/sponsors/epoberezkin" 1007 | } 1008 | }, 1009 | "node_modules/@rushstack/rig-package": { 1010 | "version": "0.5.3", 1011 | "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.3.tgz", 1012 | "integrity": "sha512-olzSSjYrvCNxUFZowevC3uz8gvKr3WTpHQ7BkpjtRpA3wK+T0ybep/SRUMfr195gBzJm5gaXw0ZMgjIyHqJUow==", 1013 | "dev": true, 1014 | "license": "MIT", 1015 | "dependencies": { 1016 | "resolve": "~1.22.1", 1017 | "strip-json-comments": "~3.1.1" 1018 | } 1019 | }, 1020 | "node_modules/@rushstack/terminal": { 1021 | "version": "0.15.0", 1022 | "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.15.0.tgz", 1023 | "integrity": "sha512-vXQPRQ+vJJn4GVqxkwRe+UGgzNxdV8xuJZY2zem46Y0p3tlahucH9/hPmLGj2i9dQnUBFiRnoM9/KW7PYw8F4Q==", 1024 | "dev": true, 1025 | "license": "MIT", 1026 | "dependencies": { 1027 | "@rushstack/node-core-library": "5.11.0", 1028 | "supports-color": "~8.1.1" 1029 | }, 1030 | "peerDependencies": { 1031 | "@types/node": "*" 1032 | }, 1033 | "peerDependenciesMeta": { 1034 | "@types/node": { 1035 | "optional": true 1036 | } 1037 | } 1038 | }, 1039 | "node_modules/@rushstack/ts-command-line": { 1040 | "version": "4.23.5", 1041 | "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.23.5.tgz", 1042 | "integrity": "sha512-jg70HfoK44KfSP3MTiL5rxsZH7X1ktX3cZs9Sl8eDu1/LxJSbPsh0MOFRC710lIuYYSgxWjI5AjbCBAl7u3RxA==", 1043 | "dev": true, 1044 | "license": "MIT", 1045 | "dependencies": { 1046 | "@rushstack/terminal": "0.15.0", 1047 | "@types/argparse": "1.0.38", 1048 | "argparse": "~1.0.9", 1049 | "string-argv": "~0.3.1" 1050 | } 1051 | }, 1052 | "node_modules/@tweakpane/core": { 1053 | "version": "2.0.5", 1054 | "resolved": "https://registry.npmjs.org/@tweakpane/core/-/core-2.0.5.tgz", 1055 | "integrity": "sha512-punBgD5rKCF5vcNo6BsSOXiDR/NSs9VM7SG65QSLJIxfRaGgj54ree9zQW6bO3pNFf3AogiGgaNODUVQRk9YqQ==", 1056 | "license": "MIT" 1057 | }, 1058 | "node_modules/@types/argparse": { 1059 | "version": "1.0.38", 1060 | "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz", 1061 | "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==", 1062 | "dev": true, 1063 | "license": "MIT" 1064 | }, 1065 | "node_modules/@types/babel__traverse": { 1066 | "version": "7.20.6", 1067 | "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", 1068 | "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", 1069 | "dev": true, 1070 | "license": "MIT", 1071 | "dependencies": { 1072 | "@babel/types": "^7.20.7" 1073 | } 1074 | }, 1075 | "node_modules/@types/estree": { 1076 | "version": "1.0.6", 1077 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", 1078 | "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", 1079 | "dev": true, 1080 | "license": "MIT" 1081 | }, 1082 | "node_modules/@volar/language-core": { 1083 | "version": "2.4.11", 1084 | "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.11.tgz", 1085 | "integrity": "sha512-lN2C1+ByfW9/JRPpqScuZt/4OrUUse57GLI6TbLgTIqBVemdl1wNcZ1qYGEo2+Gw8coYLgCy7SuKqn6IrQcQgg==", 1086 | "dev": true, 1087 | "license": "MIT", 1088 | "dependencies": { 1089 | "@volar/source-map": "2.4.11" 1090 | } 1091 | }, 1092 | "node_modules/@volar/source-map": { 1093 | "version": "2.4.11", 1094 | "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.11.tgz", 1095 | "integrity": "sha512-ZQpmafIGvaZMn/8iuvCFGrW3smeqkq/IIh9F1SdSx9aUl0J4Iurzd6/FhmjNO5g2ejF3rT45dKskgXWiofqlZQ==", 1096 | "dev": true, 1097 | "license": "MIT" 1098 | }, 1099 | "node_modules/@volar/typescript": { 1100 | "version": "2.4.11", 1101 | "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.11.tgz", 1102 | "integrity": "sha512-2DT+Tdh88Spp5PyPbqhyoYavYCPDsqbHLFwcUI9K1NlY1YgUJvujGdrqUp0zWxnW7KWNTr3xSpMuv2WnaTKDAw==", 1103 | "dev": true, 1104 | "license": "MIT", 1105 | "dependencies": { 1106 | "@volar/language-core": "2.4.11", 1107 | "path-browserify": "^1.0.1", 1108 | "vscode-uri": "^3.0.8" 1109 | } 1110 | }, 1111 | "node_modules/@vue/compiler-core": { 1112 | "version": "3.5.13", 1113 | "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.13.tgz", 1114 | "integrity": "sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==", 1115 | "dev": true, 1116 | "license": "MIT", 1117 | "dependencies": { 1118 | "@babel/parser": "^7.25.3", 1119 | "@vue/shared": "3.5.13", 1120 | "entities": "^4.5.0", 1121 | "estree-walker": "^2.0.2", 1122 | "source-map-js": "^1.2.0" 1123 | } 1124 | }, 1125 | "node_modules/@vue/compiler-dom": { 1126 | "version": "3.5.13", 1127 | "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz", 1128 | "integrity": "sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==", 1129 | "dev": true, 1130 | "license": "MIT", 1131 | "dependencies": { 1132 | "@vue/compiler-core": "3.5.13", 1133 | "@vue/shared": "3.5.13" 1134 | } 1135 | }, 1136 | "node_modules/@vue/compiler-vue2": { 1137 | "version": "2.7.16", 1138 | "resolved": "https://registry.npmjs.org/@vue/compiler-vue2/-/compiler-vue2-2.7.16.tgz", 1139 | "integrity": "sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==", 1140 | "dev": true, 1141 | "license": "MIT", 1142 | "dependencies": { 1143 | "de-indent": "^1.0.2", 1144 | "he": "^1.2.0" 1145 | } 1146 | }, 1147 | "node_modules/@vue/language-core": { 1148 | "version": "2.2.0", 1149 | "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-2.2.0.tgz", 1150 | "integrity": "sha512-O1ZZFaaBGkKbsRfnVH1ifOK1/1BUkyK+3SQsfnh6PmMmD4qJcTU8godCeA96jjDRTL6zgnK7YzCHfaUlH2r0Mw==", 1151 | "dev": true, 1152 | "license": "MIT", 1153 | "dependencies": { 1154 | "@volar/language-core": "~2.4.11", 1155 | "@vue/compiler-dom": "^3.5.0", 1156 | "@vue/compiler-vue2": "^2.7.16", 1157 | "@vue/shared": "^3.5.0", 1158 | "alien-signals": "^0.4.9", 1159 | "minimatch": "^9.0.3", 1160 | "muggle-string": "^0.4.1", 1161 | "path-browserify": "^1.0.1" 1162 | }, 1163 | "peerDependencies": { 1164 | "typescript": "*" 1165 | }, 1166 | "peerDependenciesMeta": { 1167 | "typescript": { 1168 | "optional": true 1169 | } 1170 | } 1171 | }, 1172 | "node_modules/@vue/language-core/node_modules/brace-expansion": { 1173 | "version": "2.0.1", 1174 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", 1175 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", 1176 | "dev": true, 1177 | "license": "MIT", 1178 | "dependencies": { 1179 | "balanced-match": "^1.0.0" 1180 | } 1181 | }, 1182 | "node_modules/@vue/language-core/node_modules/minimatch": { 1183 | "version": "9.0.5", 1184 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", 1185 | "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", 1186 | "dev": true, 1187 | "license": "ISC", 1188 | "dependencies": { 1189 | "brace-expansion": "^2.0.1" 1190 | }, 1191 | "engines": { 1192 | "node": ">=16 || 14 >=14.17" 1193 | }, 1194 | "funding": { 1195 | "url": "https://github.com/sponsors/isaacs" 1196 | } 1197 | }, 1198 | "node_modules/@vue/shared": { 1199 | "version": "3.5.13", 1200 | "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.13.tgz", 1201 | "integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==", 1202 | "dev": true, 1203 | "license": "MIT" 1204 | }, 1205 | "node_modules/acorn": { 1206 | "version": "8.14.0", 1207 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", 1208 | "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", 1209 | "dev": true, 1210 | "license": "MIT", 1211 | "bin": { 1212 | "acorn": "bin/acorn" 1213 | }, 1214 | "engines": { 1215 | "node": ">=0.4.0" 1216 | } 1217 | }, 1218 | "node_modules/ajv": { 1219 | "version": "8.12.0", 1220 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", 1221 | "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", 1222 | "dev": true, 1223 | "license": "MIT", 1224 | "dependencies": { 1225 | "fast-deep-equal": "^3.1.1", 1226 | "json-schema-traverse": "^1.0.0", 1227 | "require-from-string": "^2.0.2", 1228 | "uri-js": "^4.2.2" 1229 | }, 1230 | "funding": { 1231 | "type": "github", 1232 | "url": "https://github.com/sponsors/epoberezkin" 1233 | } 1234 | }, 1235 | "node_modules/ajv-draft-04": { 1236 | "version": "1.0.0", 1237 | "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", 1238 | "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", 1239 | "dev": true, 1240 | "license": "MIT", 1241 | "peerDependencies": { 1242 | "ajv": "^8.5.0" 1243 | }, 1244 | "peerDependenciesMeta": { 1245 | "ajv": { 1246 | "optional": true 1247 | } 1248 | } 1249 | }, 1250 | "node_modules/ajv-formats": { 1251 | "version": "3.0.1", 1252 | "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", 1253 | "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", 1254 | "dev": true, 1255 | "license": "MIT", 1256 | "dependencies": { 1257 | "ajv": "^8.0.0" 1258 | }, 1259 | "peerDependencies": { 1260 | "ajv": "^8.0.0" 1261 | }, 1262 | "peerDependenciesMeta": { 1263 | "ajv": { 1264 | "optional": true 1265 | } 1266 | } 1267 | }, 1268 | "node_modules/alien-signals": { 1269 | "version": "0.4.14", 1270 | "resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-0.4.14.tgz", 1271 | "integrity": "sha512-itUAVzhczTmP2U5yX67xVpsbbOiquusbWVyA9N+sy6+r6YVbFkahXvNCeEPWEOMhwDYwbVbGHFkVL03N9I5g+Q==", 1272 | "dev": true, 1273 | "license": "MIT" 1274 | }, 1275 | "node_modules/argparse": { 1276 | "version": "1.0.10", 1277 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 1278 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 1279 | "dev": true, 1280 | "license": "MIT", 1281 | "dependencies": { 1282 | "sprintf-js": "~1.0.2" 1283 | } 1284 | }, 1285 | "node_modules/balanced-match": { 1286 | "version": "1.0.2", 1287 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 1288 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 1289 | "dev": true, 1290 | "license": "MIT" 1291 | }, 1292 | "node_modules/brace-expansion": { 1293 | "version": "1.1.11", 1294 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 1295 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 1296 | "dev": true, 1297 | "license": "MIT", 1298 | "dependencies": { 1299 | "balanced-match": "^1.0.0", 1300 | "concat-map": "0.0.1" 1301 | } 1302 | }, 1303 | "node_modules/compare-versions": { 1304 | "version": "6.1.1", 1305 | "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz", 1306 | "integrity": "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==", 1307 | "dev": true, 1308 | "license": "MIT" 1309 | }, 1310 | "node_modules/concat-map": { 1311 | "version": "0.0.1", 1312 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 1313 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 1314 | "dev": true, 1315 | "license": "MIT" 1316 | }, 1317 | "node_modules/confbox": { 1318 | "version": "0.1.8", 1319 | "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", 1320 | "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", 1321 | "dev": true, 1322 | "license": "MIT" 1323 | }, 1324 | "node_modules/de-indent": { 1325 | "version": "1.0.2", 1326 | "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", 1327 | "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", 1328 | "dev": true, 1329 | "license": "MIT" 1330 | }, 1331 | "node_modules/debug": { 1332 | "version": "4.4.0", 1333 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", 1334 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", 1335 | "license": "MIT", 1336 | "dependencies": { 1337 | "ms": "^2.1.3" 1338 | }, 1339 | "engines": { 1340 | "node": ">=6.0" 1341 | }, 1342 | "peerDependenciesMeta": { 1343 | "supports-color": { 1344 | "optional": true 1345 | } 1346 | } 1347 | }, 1348 | "node_modules/entities": { 1349 | "version": "4.5.0", 1350 | "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", 1351 | "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", 1352 | "dev": true, 1353 | "license": "BSD-2-Clause", 1354 | "engines": { 1355 | "node": ">=0.12" 1356 | }, 1357 | "funding": { 1358 | "url": "https://github.com/fb55/entities?sponsor=1" 1359 | } 1360 | }, 1361 | "node_modules/esbuild": { 1362 | "version": "0.24.2", 1363 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz", 1364 | "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==", 1365 | "dev": true, 1366 | "hasInstallScript": true, 1367 | "license": "MIT", 1368 | "bin": { 1369 | "esbuild": "bin/esbuild" 1370 | }, 1371 | "engines": { 1372 | "node": ">=18" 1373 | }, 1374 | "optionalDependencies": { 1375 | "@esbuild/aix-ppc64": "0.24.2", 1376 | "@esbuild/android-arm": "0.24.2", 1377 | "@esbuild/android-arm64": "0.24.2", 1378 | "@esbuild/android-x64": "0.24.2", 1379 | "@esbuild/darwin-arm64": "0.24.2", 1380 | "@esbuild/darwin-x64": "0.24.2", 1381 | "@esbuild/freebsd-arm64": "0.24.2", 1382 | "@esbuild/freebsd-x64": "0.24.2", 1383 | "@esbuild/linux-arm": "0.24.2", 1384 | "@esbuild/linux-arm64": "0.24.2", 1385 | "@esbuild/linux-ia32": "0.24.2", 1386 | "@esbuild/linux-loong64": "0.24.2", 1387 | "@esbuild/linux-mips64el": "0.24.2", 1388 | "@esbuild/linux-ppc64": "0.24.2", 1389 | "@esbuild/linux-riscv64": "0.24.2", 1390 | "@esbuild/linux-s390x": "0.24.2", 1391 | "@esbuild/linux-x64": "0.24.2", 1392 | "@esbuild/netbsd-arm64": "0.24.2", 1393 | "@esbuild/netbsd-x64": "0.24.2", 1394 | "@esbuild/openbsd-arm64": "0.24.2", 1395 | "@esbuild/openbsd-x64": "0.24.2", 1396 | "@esbuild/sunos-x64": "0.24.2", 1397 | "@esbuild/win32-arm64": "0.24.2", 1398 | "@esbuild/win32-ia32": "0.24.2", 1399 | "@esbuild/win32-x64": "0.24.2" 1400 | } 1401 | }, 1402 | "node_modules/estree-walker": { 1403 | "version": "2.0.2", 1404 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", 1405 | "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", 1406 | "dev": true, 1407 | "license": "MIT" 1408 | }, 1409 | "node_modules/fast-deep-equal": { 1410 | "version": "3.1.3", 1411 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 1412 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 1413 | "dev": true, 1414 | "license": "MIT" 1415 | }, 1416 | "node_modules/fs-extra": { 1417 | "version": "11.3.0", 1418 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", 1419 | "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", 1420 | "dev": true, 1421 | "license": "MIT", 1422 | "dependencies": { 1423 | "graceful-fs": "^4.2.0", 1424 | "jsonfile": "^6.0.1", 1425 | "universalify": "^2.0.0" 1426 | }, 1427 | "engines": { 1428 | "node": ">=14.14" 1429 | } 1430 | }, 1431 | "node_modules/fsevents": { 1432 | "version": "2.3.3", 1433 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 1434 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 1435 | "dev": true, 1436 | "hasInstallScript": true, 1437 | "license": "MIT", 1438 | "optional": true, 1439 | "os": [ 1440 | "darwin" 1441 | ], 1442 | "engines": { 1443 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 1444 | } 1445 | }, 1446 | "node_modules/function-bind": { 1447 | "version": "1.1.2", 1448 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 1449 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 1450 | "dev": true, 1451 | "license": "MIT", 1452 | "funding": { 1453 | "url": "https://github.com/sponsors/ljharb" 1454 | } 1455 | }, 1456 | "node_modules/globals": { 1457 | "version": "11.12.0", 1458 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", 1459 | "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", 1460 | "license": "MIT", 1461 | "engines": { 1462 | "node": ">=4" 1463 | } 1464 | }, 1465 | "node_modules/graceful-fs": { 1466 | "version": "4.2.11", 1467 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", 1468 | "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", 1469 | "dev": true, 1470 | "license": "ISC" 1471 | }, 1472 | "node_modules/has-flag": { 1473 | "version": "4.0.0", 1474 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 1475 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 1476 | "dev": true, 1477 | "license": "MIT", 1478 | "engines": { 1479 | "node": ">=8" 1480 | } 1481 | }, 1482 | "node_modules/hasown": { 1483 | "version": "2.0.2", 1484 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 1485 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 1486 | "dev": true, 1487 | "license": "MIT", 1488 | "dependencies": { 1489 | "function-bind": "^1.1.2" 1490 | }, 1491 | "engines": { 1492 | "node": ">= 0.4" 1493 | } 1494 | }, 1495 | "node_modules/he": { 1496 | "version": "1.2.0", 1497 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 1498 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 1499 | "dev": true, 1500 | "license": "MIT", 1501 | "bin": { 1502 | "he": "bin/he" 1503 | } 1504 | }, 1505 | "node_modules/import-lazy": { 1506 | "version": "4.0.0", 1507 | "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", 1508 | "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", 1509 | "dev": true, 1510 | "license": "MIT", 1511 | "engines": { 1512 | "node": ">=8" 1513 | } 1514 | }, 1515 | "node_modules/is-core-module": { 1516 | "version": "2.16.1", 1517 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", 1518 | "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", 1519 | "dev": true, 1520 | "license": "MIT", 1521 | "dependencies": { 1522 | "hasown": "^2.0.2" 1523 | }, 1524 | "engines": { 1525 | "node": ">= 0.4" 1526 | }, 1527 | "funding": { 1528 | "url": "https://github.com/sponsors/ljharb" 1529 | } 1530 | }, 1531 | "node_modules/jju": { 1532 | "version": "1.4.0", 1533 | "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", 1534 | "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==", 1535 | "dev": true, 1536 | "license": "MIT" 1537 | }, 1538 | "node_modules/js-tokens": { 1539 | "version": "4.0.0", 1540 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 1541 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", 1542 | "license": "MIT" 1543 | }, 1544 | "node_modules/jsesc": { 1545 | "version": "3.1.0", 1546 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", 1547 | "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", 1548 | "license": "MIT", 1549 | "bin": { 1550 | "jsesc": "bin/jsesc" 1551 | }, 1552 | "engines": { 1553 | "node": ">=6" 1554 | } 1555 | }, 1556 | "node_modules/json-schema-traverse": { 1557 | "version": "1.0.0", 1558 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", 1559 | "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", 1560 | "dev": true, 1561 | "license": "MIT" 1562 | }, 1563 | "node_modules/jsonfile": { 1564 | "version": "6.1.0", 1565 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", 1566 | "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", 1567 | "dev": true, 1568 | "license": "MIT", 1569 | "dependencies": { 1570 | "universalify": "^2.0.0" 1571 | }, 1572 | "optionalDependencies": { 1573 | "graceful-fs": "^4.1.6" 1574 | } 1575 | }, 1576 | "node_modules/kolorist": { 1577 | "version": "1.8.0", 1578 | "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", 1579 | "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", 1580 | "dev": true, 1581 | "license": "MIT" 1582 | }, 1583 | "node_modules/local-pkg": { 1584 | "version": "0.5.1", 1585 | "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.1.tgz", 1586 | "integrity": "sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==", 1587 | "dev": true, 1588 | "license": "MIT", 1589 | "dependencies": { 1590 | "mlly": "^1.7.3", 1591 | "pkg-types": "^1.2.1" 1592 | }, 1593 | "engines": { 1594 | "node": ">=14" 1595 | }, 1596 | "funding": { 1597 | "url": "https://github.com/sponsors/antfu" 1598 | } 1599 | }, 1600 | "node_modules/lodash": { 1601 | "version": "4.17.21", 1602 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 1603 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", 1604 | "dev": true, 1605 | "license": "MIT" 1606 | }, 1607 | "node_modules/lru-cache": { 1608 | "version": "6.0.0", 1609 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 1610 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 1611 | "dev": true, 1612 | "license": "ISC", 1613 | "dependencies": { 1614 | "yallist": "^4.0.0" 1615 | }, 1616 | "engines": { 1617 | "node": ">=10" 1618 | } 1619 | }, 1620 | "node_modules/magic-string": { 1621 | "version": "0.30.17", 1622 | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", 1623 | "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", 1624 | "dev": true, 1625 | "license": "MIT", 1626 | "dependencies": { 1627 | "@jridgewell/sourcemap-codec": "^1.5.0" 1628 | } 1629 | }, 1630 | "node_modules/minimatch": { 1631 | "version": "3.0.8", 1632 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", 1633 | "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", 1634 | "dev": true, 1635 | "license": "ISC", 1636 | "dependencies": { 1637 | "brace-expansion": "^1.1.7" 1638 | }, 1639 | "engines": { 1640 | "node": "*" 1641 | } 1642 | }, 1643 | "node_modules/mlly": { 1644 | "version": "1.7.4", 1645 | "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz", 1646 | "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==", 1647 | "dev": true, 1648 | "license": "MIT", 1649 | "dependencies": { 1650 | "acorn": "^8.14.0", 1651 | "pathe": "^2.0.1", 1652 | "pkg-types": "^1.3.0", 1653 | "ufo": "^1.5.4" 1654 | } 1655 | }, 1656 | "node_modules/ms": { 1657 | "version": "2.1.3", 1658 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1659 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 1660 | "license": "MIT" 1661 | }, 1662 | "node_modules/muggle-string": { 1663 | "version": "0.4.1", 1664 | "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz", 1665 | "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==", 1666 | "dev": true, 1667 | "license": "MIT" 1668 | }, 1669 | "node_modules/nanoid": { 1670 | "version": "3.3.8", 1671 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", 1672 | "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", 1673 | "dev": true, 1674 | "funding": [ 1675 | { 1676 | "type": "github", 1677 | "url": "https://github.com/sponsors/ai" 1678 | } 1679 | ], 1680 | "license": "MIT", 1681 | "bin": { 1682 | "nanoid": "bin/nanoid.cjs" 1683 | }, 1684 | "engines": { 1685 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 1686 | } 1687 | }, 1688 | "node_modules/path-browserify": { 1689 | "version": "1.0.1", 1690 | "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", 1691 | "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", 1692 | "dev": true, 1693 | "license": "MIT" 1694 | }, 1695 | "node_modules/path-parse": { 1696 | "version": "1.0.7", 1697 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 1698 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", 1699 | "dev": true, 1700 | "license": "MIT" 1701 | }, 1702 | "node_modules/pathe": { 1703 | "version": "2.0.3", 1704 | "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", 1705 | "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", 1706 | "dev": true, 1707 | "license": "MIT" 1708 | }, 1709 | "node_modules/picocolors": { 1710 | "version": "1.1.1", 1711 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", 1712 | "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", 1713 | "license": "ISC" 1714 | }, 1715 | "node_modules/picomatch": { 1716 | "version": "4.0.2", 1717 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", 1718 | "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", 1719 | "dev": true, 1720 | "license": "MIT", 1721 | "engines": { 1722 | "node": ">=12" 1723 | }, 1724 | "funding": { 1725 | "url": "https://github.com/sponsors/jonschlinkert" 1726 | } 1727 | }, 1728 | "node_modules/pkg-types": { 1729 | "version": "1.3.1", 1730 | "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", 1731 | "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", 1732 | "dev": true, 1733 | "license": "MIT", 1734 | "dependencies": { 1735 | "confbox": "^0.1.8", 1736 | "mlly": "^1.7.4", 1737 | "pathe": "^2.0.1" 1738 | } 1739 | }, 1740 | "node_modules/postcss": { 1741 | "version": "8.5.3", 1742 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", 1743 | "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", 1744 | "dev": true, 1745 | "funding": [ 1746 | { 1747 | "type": "opencollective", 1748 | "url": "https://opencollective.com/postcss/" 1749 | }, 1750 | { 1751 | "type": "tidelift", 1752 | "url": "https://tidelift.com/funding/github/npm/postcss" 1753 | }, 1754 | { 1755 | "type": "github", 1756 | "url": "https://github.com/sponsors/ai" 1757 | } 1758 | ], 1759 | "license": "MIT", 1760 | "dependencies": { 1761 | "nanoid": "^3.3.8", 1762 | "picocolors": "^1.1.1", 1763 | "source-map-js": "^1.2.1" 1764 | }, 1765 | "engines": { 1766 | "node": "^10 || ^12 || >=14" 1767 | } 1768 | }, 1769 | "node_modules/punycode": { 1770 | "version": "2.3.1", 1771 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 1772 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 1773 | "dev": true, 1774 | "license": "MIT", 1775 | "engines": { 1776 | "node": ">=6" 1777 | } 1778 | }, 1779 | "node_modules/require-from-string": { 1780 | "version": "2.0.2", 1781 | "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", 1782 | "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", 1783 | "dev": true, 1784 | "license": "MIT", 1785 | "engines": { 1786 | "node": ">=0.10.0" 1787 | } 1788 | }, 1789 | "node_modules/resolve": { 1790 | "version": "1.22.10", 1791 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", 1792 | "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", 1793 | "dev": true, 1794 | "license": "MIT", 1795 | "dependencies": { 1796 | "is-core-module": "^2.16.0", 1797 | "path-parse": "^1.0.7", 1798 | "supports-preserve-symlinks-flag": "^1.0.0" 1799 | }, 1800 | "bin": { 1801 | "resolve": "bin/resolve" 1802 | }, 1803 | "engines": { 1804 | "node": ">= 0.4" 1805 | }, 1806 | "funding": { 1807 | "url": "https://github.com/sponsors/ljharb" 1808 | } 1809 | }, 1810 | "node_modules/rollup": { 1811 | "version": "4.34.8", 1812 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.8.tgz", 1813 | "integrity": "sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==", 1814 | "dev": true, 1815 | "license": "MIT", 1816 | "dependencies": { 1817 | "@types/estree": "1.0.6" 1818 | }, 1819 | "bin": { 1820 | "rollup": "dist/bin/rollup" 1821 | }, 1822 | "engines": { 1823 | "node": ">=18.0.0", 1824 | "npm": ">=8.0.0" 1825 | }, 1826 | "optionalDependencies": { 1827 | "@rollup/rollup-android-arm-eabi": "4.34.8", 1828 | "@rollup/rollup-android-arm64": "4.34.8", 1829 | "@rollup/rollup-darwin-arm64": "4.34.8", 1830 | "@rollup/rollup-darwin-x64": "4.34.8", 1831 | "@rollup/rollup-freebsd-arm64": "4.34.8", 1832 | "@rollup/rollup-freebsd-x64": "4.34.8", 1833 | "@rollup/rollup-linux-arm-gnueabihf": "4.34.8", 1834 | "@rollup/rollup-linux-arm-musleabihf": "4.34.8", 1835 | "@rollup/rollup-linux-arm64-gnu": "4.34.8", 1836 | "@rollup/rollup-linux-arm64-musl": "4.34.8", 1837 | "@rollup/rollup-linux-loongarch64-gnu": "4.34.8", 1838 | "@rollup/rollup-linux-powerpc64le-gnu": "4.34.8", 1839 | "@rollup/rollup-linux-riscv64-gnu": "4.34.8", 1840 | "@rollup/rollup-linux-s390x-gnu": "4.34.8", 1841 | "@rollup/rollup-linux-x64-gnu": "4.34.8", 1842 | "@rollup/rollup-linux-x64-musl": "4.34.8", 1843 | "@rollup/rollup-win32-arm64-msvc": "4.34.8", 1844 | "@rollup/rollup-win32-ia32-msvc": "4.34.8", 1845 | "@rollup/rollup-win32-x64-msvc": "4.34.8", 1846 | "fsevents": "~2.3.2" 1847 | } 1848 | }, 1849 | "node_modules/semver": { 1850 | "version": "7.5.4", 1851 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", 1852 | "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", 1853 | "dev": true, 1854 | "license": "ISC", 1855 | "dependencies": { 1856 | "lru-cache": "^6.0.0" 1857 | }, 1858 | "bin": { 1859 | "semver": "bin/semver.js" 1860 | }, 1861 | "engines": { 1862 | "node": ">=10" 1863 | } 1864 | }, 1865 | "node_modules/source-map": { 1866 | "version": "0.6.1", 1867 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 1868 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 1869 | "dev": true, 1870 | "license": "BSD-3-Clause", 1871 | "engines": { 1872 | "node": ">=0.10.0" 1873 | } 1874 | }, 1875 | "node_modules/source-map-js": { 1876 | "version": "1.2.1", 1877 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", 1878 | "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", 1879 | "dev": true, 1880 | "license": "BSD-3-Clause", 1881 | "engines": { 1882 | "node": ">=0.10.0" 1883 | } 1884 | }, 1885 | "node_modules/sprintf-js": { 1886 | "version": "1.0.3", 1887 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 1888 | "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", 1889 | "dev": true, 1890 | "license": "BSD-3-Clause" 1891 | }, 1892 | "node_modules/string-argv": { 1893 | "version": "0.3.2", 1894 | "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", 1895 | "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", 1896 | "dev": true, 1897 | "license": "MIT", 1898 | "engines": { 1899 | "node": ">=0.6.19" 1900 | } 1901 | }, 1902 | "node_modules/strip-json-comments": { 1903 | "version": "3.1.1", 1904 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 1905 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 1906 | "dev": true, 1907 | "license": "MIT", 1908 | "engines": { 1909 | "node": ">=8" 1910 | }, 1911 | "funding": { 1912 | "url": "https://github.com/sponsors/sindresorhus" 1913 | } 1914 | }, 1915 | "node_modules/supports-color": { 1916 | "version": "8.1.1", 1917 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", 1918 | "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", 1919 | "dev": true, 1920 | "license": "MIT", 1921 | "dependencies": { 1922 | "has-flag": "^4.0.0" 1923 | }, 1924 | "engines": { 1925 | "node": ">=10" 1926 | }, 1927 | "funding": { 1928 | "url": "https://github.com/chalk/supports-color?sponsor=1" 1929 | } 1930 | }, 1931 | "node_modules/supports-preserve-symlinks-flag": { 1932 | "version": "1.0.0", 1933 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 1934 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", 1935 | "dev": true, 1936 | "license": "MIT", 1937 | "engines": { 1938 | "node": ">= 0.4" 1939 | }, 1940 | "funding": { 1941 | "url": "https://github.com/sponsors/ljharb" 1942 | } 1943 | }, 1944 | "node_modules/tweakpane": { 1945 | "version": "4.0.5", 1946 | "resolved": "https://registry.npmjs.org/tweakpane/-/tweakpane-4.0.5.tgz", 1947 | "integrity": "sha512-rxEXdSI+ArlG1RyO6FghC4ZUX8JkEfz8F3v1JuteXSV0pEtHJzyo07fcDG+NsJfN5L39kSbCYbB9cBGHyuI/tQ==", 1948 | "license": "MIT", 1949 | "funding": { 1950 | "url": "https://github.com/sponsors/cocopon" 1951 | } 1952 | }, 1953 | "node_modules/tweakpane-plugin-file-import": { 1954 | "version": "1.1.1", 1955 | "resolved": "https://registry.npmjs.org/tweakpane-plugin-file-import/-/tweakpane-plugin-file-import-1.1.1.tgz", 1956 | "integrity": "sha512-7QbLToRTPYprzrZWJ1BWefIDJOyxj/9IHzVE/wZwK1+z1oUFtZ+ptzMxKm6apeZNoQTG7zS6opEaJi5tJ0igaQ==", 1957 | "license": "MIT", 1958 | "peerDependencies": { 1959 | "tweakpane": "^4.0.0" 1960 | } 1961 | }, 1962 | "node_modules/typescript": { 1963 | "version": "5.7.3", 1964 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", 1965 | "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", 1966 | "dev": true, 1967 | "license": "Apache-2.0", 1968 | "bin": { 1969 | "tsc": "bin/tsc", 1970 | "tsserver": "bin/tsserver" 1971 | }, 1972 | "engines": { 1973 | "node": ">=14.17" 1974 | } 1975 | }, 1976 | "node_modules/ufo": { 1977 | "version": "1.5.4", 1978 | "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz", 1979 | "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==", 1980 | "dev": true, 1981 | "license": "MIT" 1982 | }, 1983 | "node_modules/universalify": { 1984 | "version": "2.0.1", 1985 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", 1986 | "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", 1987 | "dev": true, 1988 | "license": "MIT", 1989 | "engines": { 1990 | "node": ">= 10.0.0" 1991 | } 1992 | }, 1993 | "node_modules/uri-js": { 1994 | "version": "4.4.1", 1995 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 1996 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 1997 | "dev": true, 1998 | "license": "BSD-2-Clause", 1999 | "dependencies": { 2000 | "punycode": "^2.1.0" 2001 | } 2002 | }, 2003 | "node_modules/vite": { 2004 | "version": "6.1.1", 2005 | "resolved": "https://registry.npmjs.org/vite/-/vite-6.1.1.tgz", 2006 | "integrity": "sha512-4GgM54XrwRfrOp297aIYspIti66k56v16ZnqHvrIM7mG+HjDlAwS7p+Srr7J6fGvEdOJ5JcQ/D9T7HhtdXDTzA==", 2007 | "dev": true, 2008 | "license": "MIT", 2009 | "dependencies": { 2010 | "esbuild": "^0.24.2", 2011 | "postcss": "^8.5.2", 2012 | "rollup": "^4.30.1" 2013 | }, 2014 | "bin": { 2015 | "vite": "bin/vite.js" 2016 | }, 2017 | "engines": { 2018 | "node": "^18.0.0 || ^20.0.0 || >=22.0.0" 2019 | }, 2020 | "funding": { 2021 | "url": "https://github.com/vitejs/vite?sponsor=1" 2022 | }, 2023 | "optionalDependencies": { 2024 | "fsevents": "~2.3.3" 2025 | }, 2026 | "peerDependencies": { 2027 | "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", 2028 | "jiti": ">=1.21.0", 2029 | "less": "*", 2030 | "lightningcss": "^1.21.0", 2031 | "sass": "*", 2032 | "sass-embedded": "*", 2033 | "stylus": "*", 2034 | "sugarss": "*", 2035 | "terser": "^5.16.0", 2036 | "tsx": "^4.8.1", 2037 | "yaml": "^2.4.2" 2038 | }, 2039 | "peerDependenciesMeta": { 2040 | "@types/node": { 2041 | "optional": true 2042 | }, 2043 | "jiti": { 2044 | "optional": true 2045 | }, 2046 | "less": { 2047 | "optional": true 2048 | }, 2049 | "lightningcss": { 2050 | "optional": true 2051 | }, 2052 | "sass": { 2053 | "optional": true 2054 | }, 2055 | "sass-embedded": { 2056 | "optional": true 2057 | }, 2058 | "stylus": { 2059 | "optional": true 2060 | }, 2061 | "sugarss": { 2062 | "optional": true 2063 | }, 2064 | "terser": { 2065 | "optional": true 2066 | }, 2067 | "tsx": { 2068 | "optional": true 2069 | }, 2070 | "yaml": { 2071 | "optional": true 2072 | } 2073 | } 2074 | }, 2075 | "node_modules/vite-plugin-dts": { 2076 | "version": "4.5.0", 2077 | "resolved": "https://registry.npmjs.org/vite-plugin-dts/-/vite-plugin-dts-4.5.0.tgz", 2078 | "integrity": "sha512-M1lrPTdi7gilLYRZoLmGYnl4fbPryVYsehPN9JgaxjJKTs8/f7tuAlvCCvOLB5gRDQTTKnptBcB0ACsaw2wNLw==", 2079 | "dev": true, 2080 | "license": "MIT", 2081 | "dependencies": { 2082 | "@microsoft/api-extractor": "^7.49.1", 2083 | "@rollup/pluginutils": "^5.1.4", 2084 | "@volar/typescript": "^2.4.11", 2085 | "@vue/language-core": "2.2.0", 2086 | "compare-versions": "^6.1.1", 2087 | "debug": "^4.4.0", 2088 | "kolorist": "^1.8.0", 2089 | "local-pkg": "^0.5.1", 2090 | "magic-string": "^0.30.17" 2091 | }, 2092 | "peerDependencies": { 2093 | "typescript": "*", 2094 | "vite": "*" 2095 | }, 2096 | "peerDependenciesMeta": { 2097 | "vite": { 2098 | "optional": true 2099 | } 2100 | } 2101 | }, 2102 | "node_modules/vscode-uri": { 2103 | "version": "3.1.0", 2104 | "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz", 2105 | "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==", 2106 | "dev": true, 2107 | "license": "MIT" 2108 | }, 2109 | "node_modules/yallist": { 2110 | "version": "4.0.0", 2111 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 2112 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", 2113 | "dev": true, 2114 | "license": "ISC" 2115 | } 2116 | } 2117 | } 2118 | -------------------------------------------------------------------------------- /package/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tsl-uniform-ui-vite-plugin", 3 | "version": "0.7.2", 4 | "type": "module", 5 | "keywords": [ 6 | "tsl", 7 | "threejs", 8 | "vite", 9 | "plugin", 10 | "tweakpane" 11 | ], 12 | "author": "Bhushan Wagh (https://github.com/bhushan6)", 13 | "bugs": { 14 | "url": "https://github.com/bhushan6/tsl-uniform-ui-vite-plugin/issues" 15 | }, 16 | "homepage": "https://github.com/bhushan6/tsl-uniform-ui-vite-plugin#readme", 17 | "scripts": { 18 | "dev": "vite", 19 | "build": "vite build", 20 | "publish:patch": "npm version patch && npm run build && npm publish && sleep 10 && cd ../example && npm install tsl-uniform-ui-vite-plugin@latest", 21 | "publish:minor": "npm version minor && npm run build && npm publish && sleep 10 && cd ../example && npm install tsl-uniform-ui-vite-plugin@latest", 22 | "publish:major": "npm version major && npm run build && npm publish && sleep 10 && cd ../example && npm install tsl-uniform-ui-vite-plugin@latest", 23 | "preview": "vite preview" 24 | }, 25 | "license": "MIT", 26 | "files": [ 27 | "dist" 28 | ], 29 | "module": "./dist/index.es.js", 30 | "exports": { 31 | ".": { 32 | "import": "./dist/index.es.js" 33 | } 34 | }, 35 | "dependencies": { 36 | "@babel/parser": "^7.26.9", 37 | "@babel/traverse": "^7.26.9", 38 | "@babel/types": "^7.26.9" 39 | }, 40 | "devDependencies": { 41 | "@types/babel__traverse": "^7.20.6", 42 | "typescript": "~5.7.2", 43 | "vite": "^6.1.0", 44 | "vite-plugin-dts": "^4.5.0" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /package/readme.md: -------------------------------------------------------------------------------- 1 | # tsl-uniform-ui-vite-plugin 2 | A Vite plugin that automatically generates GUI controls for Three.js shader uniforms using Tweakpane. This plugin simplifies shader development by providing real-time controls for uniform values without manual GUI setup. 3 | 4 | ## Features 5 | - Automatic GUI generation for shader uniforms 6 | - Supports multiple uniform types: 7 | - Boolean 8 | - Number 9 | - Color 10 | - Vector2/3/4 11 | - Texture 12 | - Export Configs 13 | - Persistent configs 14 | - Undo/redo 15 | - Presets 16 | - Development-only mode (disabled in production by default) 17 | 18 | ## Installation 19 | ```bash 20 | npm install tsl-uniform-ui-vite-plugin @tweakpane/core tweakpane @tweakpane/plugin-essentials tweakpane-plugin-file-import 21 | ``` 22 | 23 | ## Usage 24 | 1. Add the plugin to your Vite config: 25 | ```javascript 26 | // vite.config.js 27 | import threeUniformGui from 'tsl-uniform-ui-vite-plugin'; 28 | 29 | export default { 30 | plugins: [threeUniformGui()] 31 | } 32 | ``` 33 | 34 | 2. Define your uniforms using the `uniform()` function: 35 | ```javascript 36 | import { uniform } from 'three/tsl'; 37 | const brightness = uniform(1.0); // number 38 | const color = uniform(new THREE.Color(1, 0, 0)); // color 39 | const position = uniform(new THREE.Vector3(0, 1, 0)); // vector3 40 | ``` 41 | The plugin will automatically generate appropriate Tweakpane controls for each uniform based on its type. 42 | 43 | ## Configuration Options 44 | 45 | You can configure the plugin with the following options: 46 | 47 | ```javascript 48 | // vite.config.js 49 | import threeUniformGui from 'tsl-uniform-ui-vite-plugin'; 50 | 51 | export default { 52 | plugins: [ 53 | threeUniformGui({ 54 | persistent: true, // Save configurations in localStorage 55 | devOnly: true // Only active in development mode (default) 56 | }) 57 | ] 58 | } 59 | ``` 60 | 61 | | Option | Type | Default | Description | 62 | |--------|------|---------|-------------| 63 | | `persistent` | boolean | `false` | Save UI state in localStorage | 64 | | `devOnly` | boolean | `true` | Only enable the plugin in development mode | 65 | 66 | For backward compatibility, you can still use the old configuration style: 67 | 68 | ```javascript 69 | // vite.config.js - Legacy style 70 | import threeUniformGui from 'tsl-uniform-ui-vite-plugin'; 71 | 72 | export default { 73 | plugins: [threeUniformGui(true)] // Persistent mode, dev only 74 | } 75 | ``` 76 | 77 | ## Supported Types 78 | | Type | Example | GUI Control | 79 | |------|---------|------------| 80 | | Boolean | `uniform(false)` | Checkbox | 81 | | Number | `uniform(1.0)` | Slider | 82 | | Color | `uniform(new THREE.Color())` | Color Picker | 83 | | Vector2 | `uniform(new THREE.Vector2())` | X/Y Sliders | 84 | | Vector3 | `uniform(new THREE.Vector3())` | X/Y/Z Sliders | 85 | | Vector4 | `uniform(new THREE.Vector4())` | X/Y/Z/W Sliders | 86 | | Texture | `texture(new THREE.TextureLoader().load("/uv.png"))` | File Picker | 87 | 88 | ## Caveat 89 | ### Passing Types to the uniform Function 90 | When using the uniform() function, the plugin can sometimes automatically infer the type of the uniform based on the value you pass. However, there are specific cases where you must provide the type explicitly as a second argument to ensure the plugin generates the correct GUI controls. 91 | 92 | ### When Type Inference Works 93 | The plugin can automatically determine the type in these situations: 94 | - **Literals**: When you pass a direct value like a number, boolean, or a Three.js object. 95 | - Example: `uniform(1.0)` is inferred as "number". 96 | - Example: `uniform(new THREE.Vector3(0, 1, 0))` is inferred as "vector3". 97 | - **Variables with Obvious Types**: When you pass a variable that has a clear type from its declaration. 98 | - Example: 99 | ```javascript 100 | const vec = new THREE.Vector3(0, 1, 0); 101 | const position = uniform(vec); // Inferred as "vector3" 102 | ``` 103 | 104 | In these cases, you don't need to pass the type explicitly—the plugin will handle it for you. 105 | 106 | ### When You Must Pass the Type Explicitly 107 | You must provide the type as a second argument in these situations: 108 | - **Function Calls**: When the value is the result of a function call, as the plugin cannot inspect the return value at compile time. 109 | - Example: 110 | ```javascript 111 | const position = uniform(randomVector3(), "vec3"); // Type must be specified 112 | ``` 113 | - **Complex Expressions**: When the value comes from an expression whose type cannot be determined statically. 114 | - Example: 115 | ```javascript 116 | const value = uniform(Math.random() > 0.5 ? 1 : 0, "float"); // Type should be specified 117 | ``` 118 | 119 | If you don't pass the type in these cases, the plugin won't be able to determine the type and will not generate any GUI controls for that uniform. 120 | 121 | ## License 122 | MIT 123 | 124 | ## Contributing 125 | Contributions are welcome! Please feel free to submit a Pull Request. -------------------------------------------------------------------------------- /package/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "isolatedModules": true, 13 | "moduleDetection": "force", 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true, 21 | "noUncheckedSideEffectImports": true 22 | }, 23 | "include": ["index.ts"] 24 | } 25 | -------------------------------------------------------------------------------- /package/vite.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-undef */ 2 | import path from "node:path"; 3 | import { defineConfig } from "vite"; 4 | import dts from "vite-plugin-dts"; 5 | 6 | export default defineConfig({ 7 | plugins: [ 8 | dts({ 9 | insertTypesEntry: true, 10 | }), 11 | ], 12 | build: { 13 | lib: { 14 | entry: path.resolve(__dirname, "index.ts"), 15 | name: "index", 16 | formats: ["es"], 17 | fileName: (format) => `index.${format}.js`, 18 | }, 19 | rollupOptions: { 20 | external: ["fsevents", "vite", "fs"], 21 | }, 22 | }, 23 | }); -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # tsl-uniform-ui-vite-plugin 2 | A Vite plugin that automatically generates GUI controls for Three.js shader uniforms using Tweakpane. This plugin simplifies shader development by providing real-time controls for uniform values without manual GUI setup. 3 | 4 | ## Features 5 | - Automatic GUI generation for shader uniforms 6 | - Supports multiple uniform types: 7 | - Boolean 8 | - Number 9 | - Color 10 | - Vector2/3/4 11 | - Texture 12 | - Export Configs 13 | - Persistent configs 14 | - Undo/redo 15 | - Presets 16 | - Development-only mode (disabled in production by default) 17 | 18 | ## Installation 19 | ```bash 20 | npm install tsl-uniform-ui-vite-plugin @tweakpane/core tweakpane @tweakpane/plugin-essentials tweakpane-plugin-file-import 21 | ``` 22 | 23 | ## Usage 24 | 1. Add the plugin to your Vite config: 25 | ```javascript 26 | // vite.config.js 27 | import threeUniformGui from 'tsl-uniform-ui-vite-plugin'; 28 | 29 | export default { 30 | plugins: [threeUniformGui()] 31 | } 32 | ``` 33 | 34 | 2. Define your uniforms using the `uniform()` function: 35 | ```javascript 36 | import { uniform } from 'three/tsl'; 37 | const brightness = uniform(1.0); // number 38 | const color = uniform(new THREE.Color(1, 0, 0)); // color 39 | const position = uniform(new THREE.Vector3(0, 1, 0)); // vector3 40 | ``` 41 | The plugin will automatically generate appropriate Tweakpane controls for each uniform based on its type. 42 | 43 | ## Configuration Options 44 | 45 | You can configure the plugin with the following options: 46 | 47 | ```javascript 48 | // vite.config.js 49 | import threeUniformGui from 'tsl-uniform-ui-vite-plugin'; 50 | 51 | export default { 52 | plugins: [ 53 | threeUniformGui({ 54 | persistent: true, // Save configurations in localStorage 55 | devOnly: true // Only active in development mode (default) 56 | }) 57 | ] 58 | } 59 | ``` 60 | 61 | | Option | Type | Default | Description | 62 | |--------|------|---------|-------------| 63 | | `persistent` | boolean | `false` | Save UI state in localStorage | 64 | | `devOnly` | boolean | `true` | Only enable the plugin in development mode | 65 | 66 | For backward compatibility, you can still use the old configuration style: 67 | 68 | ```javascript 69 | // vite.config.js - Legacy style 70 | import threeUniformGui from 'tsl-uniform-ui-vite-plugin'; 71 | 72 | export default { 73 | plugins: [threeUniformGui(true)] // Persistent mode, dev only 74 | } 75 | ``` 76 | 77 | ## Supported Types 78 | | Type | Example | GUI Control | 79 | |------|---------|------------| 80 | | Boolean | `uniform(false)` | Checkbox | 81 | | Number | `uniform(1.0)` | Slider | 82 | | Color | `uniform(new THREE.Color())` | Color Picker | 83 | | Vector2 | `uniform(new THREE.Vector2())` | X/Y Sliders | 84 | | Vector3 | `uniform(new THREE.Vector3())` | X/Y/Z Sliders | 85 | | Vector4 | `uniform(new THREE.Vector4())` | X/Y/Z/W Sliders | 86 | | Texture | `texture(new THREE.TextureLoader().load("/uv.png"))` | File Picker | 87 | 88 | ## Caveat 89 | ### Passing Types to the uniform Function 90 | When using the uniform() function, the plugin can sometimes automatically infer the type of the uniform based on the value you pass. However, there are specific cases where you must provide the type explicitly as a second argument to ensure the plugin generates the correct GUI controls. 91 | 92 | ### When Type Inference Works 93 | The plugin can automatically determine the type in these situations: 94 | - **Literals**: When you pass a direct value like a number, boolean, or a Three.js object. 95 | - Example: `uniform(1.0)` is inferred as "number". 96 | - Example: `uniform(new THREE.Vector3(0, 1, 0))` is inferred as "vector3". 97 | - **Variables with Obvious Types**: When you pass a variable that has a clear type from its declaration. 98 | - Example: 99 | ```javascript 100 | const vec = new THREE.Vector3(0, 1, 0); 101 | const position = uniform(vec); // Inferred as "vector3" 102 | ``` 103 | 104 | In these cases, you don't need to pass the type explicitly—the plugin will handle it for you. 105 | 106 | ### When You Must Pass the Type Explicitly 107 | You must provide the type as a second argument in these situations: 108 | - **Function Calls**: When the value is the result of a function call, as the plugin cannot inspect the return value at compile time. 109 | - Example: 110 | ```javascript 111 | const position = uniform(randomVector3(), "vec3"); // Type must be specified 112 | ``` 113 | - **Complex Expressions**: When the value comes from an expression whose type cannot be determined statically. 114 | - Example: 115 | ```javascript 116 | const value = uniform(Math.random() > 0.5 ? 1 : 0, "float"); // Type should be specified 117 | ``` 118 | 119 | If you don't pass the type in these cases, the plugin won't be able to determine the type and will not generate any GUI controls for that uniform. 120 | 121 | ## License 122 | MIT 123 | 124 | ## Contributing 125 | Contributions are welcome! Please feel free to submit a Pull Request. --------------------------------------------------------------------------------