├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public ├── assets │ └── images │ │ ├── wlop01.jpg │ │ ├── wlop02.jpg │ │ ├── wlop03.jpg │ │ └── wlop04.jpg └── meta │ └── favicon.svg ├── src ├── home │ ├── Canvas.ts │ ├── Home.ts │ ├── home.scss │ ├── shader │ │ ├── planeFrag.glsl │ │ └── planeVert.glsl │ └── store.ts ├── index.html ├── modules │ ├── scripts │ │ ├── DomSyncPlane.ts │ │ ├── Mouse2d.ts │ │ ├── MouseWheel.ts │ │ ├── extends │ │ │ └── TCanvas.ts │ │ ├── flowmap │ │ │ ├── Flowmap.ts │ │ │ ├── Simulator.ts │ │ │ ├── flowmapFrag.glsl │ │ │ ├── flowmapVert.glsl │ │ │ └── simulatorFrag.glsl │ │ ├── glsl │ │ │ ├── cnoise21.glsl │ │ │ └── random.glsl │ │ ├── math.ts │ │ └── utils.ts │ └── styles │ │ ├── common.scss │ │ └── mixin │ │ └── media.scss └── types │ ├── glsl.d.ts │ └── vite-env.d.ts ├── tsconfig.json └── vite.config.ts /.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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # About 2 | In this application, the 'threejs plane' is overlaid on the 'dom element' to apply a special effect. 3 | 4 | https://nemutas.github.io/ghost-veil/ 5 | 6 | ![output(video-cutter-js com)](https://user-images.githubusercontent.com/46724121/175795833-79784279-ba17-47a8-b253-c1fdc6650bee.gif) 7 | 8 | # Making 9 | This application is made up of three layers. 10 | 11 | ### 1. dom layer 12 | In this layer, the image is displayed and animated in response to scrolling using the GSAP Scroll Trigger. 13 | 14 | ### 2. plane layer (threejs canvas) 15 | In this layer, the image source is obtained from the image element of the dom layer, and a grayscale texture is pasted onto the Plane.
16 | In addition, depending on the degree to which the image is displayed, it was expressed as if it were coming down like a dark curtain. 17 | 18 | ### 3. postprocessing layer (threejs canvas) 19 | In this layer, the UVs of the screen are distorted and also made transparent in response to mouse movements. 20 | 21 | # Technology 22 | 23 | - Three.js 24 | - TypeScript 25 | - GLSL 26 | - GSAP 27 | 28 | # Reference 29 | - [Yudouhu Portfolio](https://yudouhu.org/) - created by [itoh](https://twitter.com/FrontArtGraph) 30 | - [Alien.js - flowmap](https://github.com/pschroen/alien.js/) - created by [Patrick Schroen](https://twitter.com/pschroen) 31 | - [WLOP's excellent works](https://twitter.com/wlopwangling) 32 | 33 | # License 34 | 35 | This source code is not MIT License. 36 | 37 | ❌ Commercial use is prohibited.
38 | ❌ Redistribution is prohibited.
39 | ❌ Diversion is prohibited.(Incorporate all of the code into the project, etc.)
40 | ✅ You can look at the application and reproduce the representation.
41 | ✅ You can use parts of the code. 42 | 43 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ghost-veil", 3 | "version": "0.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "ghost-veil", 9 | "version": "0.0.0", 10 | "dependencies": { 11 | "gsap": "^3.10.4", 12 | "lil-gui": "^0.16.1", 13 | "ress": "^5.0.2", 14 | "three": "^0.141.0" 15 | }, 16 | "devDependencies": { 17 | "@types/three": "^0.141.0", 18 | "gh-pages": "^4.0.0", 19 | "sass": "^1.53.0", 20 | "typescript": "^4.5.4", 21 | "vite": "^2.9.9", 22 | "vite-plugin-glsl": "^0.1.2" 23 | } 24 | }, 25 | "node_modules/@rollup/pluginutils": { 26 | "version": "4.2.1", 27 | "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", 28 | "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", 29 | "dev": true, 30 | "dependencies": { 31 | "estree-walker": "^2.0.1", 32 | "picomatch": "^2.2.2" 33 | }, 34 | "engines": { 35 | "node": ">= 8.0.0" 36 | } 37 | }, 38 | "node_modules/@types/three": { 39 | "version": "0.141.0", 40 | "resolved": "https://registry.npmjs.org/@types/three/-/three-0.141.0.tgz", 41 | "integrity": "sha512-OJdKDgTPVBUgc+s74DYoy4aLznbFFC38Xm4ElmU1YwGNgR7GGFVvFCX7lpVgOsT6S1zSJtGdajTsOYE8/xY9nA==", 42 | "dev": true, 43 | "dependencies": { 44 | "@types/webxr": "*" 45 | } 46 | }, 47 | "node_modules/@types/webxr": { 48 | "version": "0.4.0", 49 | "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.4.0.tgz", 50 | "integrity": "sha512-LQvrACV3Pj17GpkwHwXuTd733gfY+D7b9mKdrTmLdO7vo7P/o6209Qqtk63y/FCv/lspdmi0pWz6Qe/ull9kQg==", 51 | "dev": true 52 | }, 53 | "node_modules/anymatch": { 54 | "version": "3.1.2", 55 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", 56 | "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", 57 | "dev": true, 58 | "dependencies": { 59 | "normalize-path": "^3.0.0", 60 | "picomatch": "^2.0.4" 61 | }, 62 | "engines": { 63 | "node": ">= 8" 64 | } 65 | }, 66 | "node_modules/array-union": { 67 | "version": "1.0.2", 68 | "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", 69 | "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", 70 | "dev": true, 71 | "dependencies": { 72 | "array-uniq": "^1.0.1" 73 | }, 74 | "engines": { 75 | "node": ">=0.10.0" 76 | } 77 | }, 78 | "node_modules/array-uniq": { 79 | "version": "1.0.3", 80 | "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", 81 | "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", 82 | "dev": true, 83 | "engines": { 84 | "node": ">=0.10.0" 85 | } 86 | }, 87 | "node_modules/async": { 88 | "version": "2.6.4", 89 | "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", 90 | "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", 91 | "dev": true, 92 | "dependencies": { 93 | "lodash": "^4.17.14" 94 | } 95 | }, 96 | "node_modules/balanced-match": { 97 | "version": "1.0.2", 98 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 99 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 100 | "dev": true 101 | }, 102 | "node_modules/binary-extensions": { 103 | "version": "2.2.0", 104 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", 105 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", 106 | "dev": true, 107 | "engines": { 108 | "node": ">=8" 109 | } 110 | }, 111 | "node_modules/brace-expansion": { 112 | "version": "1.1.11", 113 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 114 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 115 | "dev": true, 116 | "dependencies": { 117 | "balanced-match": "^1.0.0", 118 | "concat-map": "0.0.1" 119 | } 120 | }, 121 | "node_modules/braces": { 122 | "version": "3.0.2", 123 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 124 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 125 | "dev": true, 126 | "dependencies": { 127 | "fill-range": "^7.0.1" 128 | }, 129 | "engines": { 130 | "node": ">=8" 131 | } 132 | }, 133 | "node_modules/chokidar": { 134 | "version": "3.5.3", 135 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", 136 | "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", 137 | "dev": true, 138 | "funding": [ 139 | { 140 | "type": "individual", 141 | "url": "https://paulmillr.com/funding/" 142 | } 143 | ], 144 | "dependencies": { 145 | "anymatch": "~3.1.2", 146 | "braces": "~3.0.2", 147 | "glob-parent": "~5.1.2", 148 | "is-binary-path": "~2.1.0", 149 | "is-glob": "~4.0.1", 150 | "normalize-path": "~3.0.0", 151 | "readdirp": "~3.6.0" 152 | }, 153 | "engines": { 154 | "node": ">= 8.10.0" 155 | }, 156 | "optionalDependencies": { 157 | "fsevents": "~2.3.2" 158 | } 159 | }, 160 | "node_modules/commander": { 161 | "version": "2.20.3", 162 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", 163 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", 164 | "dev": true 165 | }, 166 | "node_modules/commondir": { 167 | "version": "1.0.1", 168 | "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", 169 | "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", 170 | "dev": true 171 | }, 172 | "node_modules/concat-map": { 173 | "version": "0.0.1", 174 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 175 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 176 | "dev": true 177 | }, 178 | "node_modules/email-addresses": { 179 | "version": "3.1.0", 180 | "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-3.1.0.tgz", 181 | "integrity": "sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg==", 182 | "dev": true 183 | }, 184 | "node_modules/esbuild": { 185 | "version": "0.14.47", 186 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.47.tgz", 187 | "integrity": "sha512-wI4ZiIfFxpkuxB8ju4MHrGwGLyp1+awEHAHVpx6w7a+1pmYIq8T9FGEVVwFo0iFierDoMj++Xq69GXWYn2EiwA==", 188 | "dev": true, 189 | "hasInstallScript": true, 190 | "bin": { 191 | "esbuild": "bin/esbuild" 192 | }, 193 | "engines": { 194 | "node": ">=12" 195 | }, 196 | "optionalDependencies": { 197 | "esbuild-android-64": "0.14.47", 198 | "esbuild-android-arm64": "0.14.47", 199 | "esbuild-darwin-64": "0.14.47", 200 | "esbuild-darwin-arm64": "0.14.47", 201 | "esbuild-freebsd-64": "0.14.47", 202 | "esbuild-freebsd-arm64": "0.14.47", 203 | "esbuild-linux-32": "0.14.47", 204 | "esbuild-linux-64": "0.14.47", 205 | "esbuild-linux-arm": "0.14.47", 206 | "esbuild-linux-arm64": "0.14.47", 207 | "esbuild-linux-mips64le": "0.14.47", 208 | "esbuild-linux-ppc64le": "0.14.47", 209 | "esbuild-linux-riscv64": "0.14.47", 210 | "esbuild-linux-s390x": "0.14.47", 211 | "esbuild-netbsd-64": "0.14.47", 212 | "esbuild-openbsd-64": "0.14.47", 213 | "esbuild-sunos-64": "0.14.47", 214 | "esbuild-windows-32": "0.14.47", 215 | "esbuild-windows-64": "0.14.47", 216 | "esbuild-windows-arm64": "0.14.47" 217 | } 218 | }, 219 | "node_modules/esbuild-android-64": { 220 | "version": "0.14.47", 221 | "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.47.tgz", 222 | "integrity": "sha512-R13Bd9+tqLVFndncMHssZrPWe6/0Kpv2/dt4aA69soX4PRxlzsVpCvoJeFE8sOEoeVEiBkI0myjlkDodXlHa0g==", 223 | "cpu": [ 224 | "x64" 225 | ], 226 | "dev": true, 227 | "optional": true, 228 | "os": [ 229 | "android" 230 | ], 231 | "engines": { 232 | "node": ">=12" 233 | } 234 | }, 235 | "node_modules/esbuild-android-arm64": { 236 | "version": "0.14.47", 237 | "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.47.tgz", 238 | "integrity": "sha512-OkwOjj7ts4lBp/TL6hdd8HftIzOy/pdtbrNA4+0oVWgGG64HrdVzAF5gxtJufAPOsEjkyh1oIYvKAUinKKQRSQ==", 239 | "cpu": [ 240 | "arm64" 241 | ], 242 | "dev": true, 243 | "optional": true, 244 | "os": [ 245 | "android" 246 | ], 247 | "engines": { 248 | "node": ">=12" 249 | } 250 | }, 251 | "node_modules/esbuild-darwin-64": { 252 | "version": "0.14.47", 253 | "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.47.tgz", 254 | "integrity": "sha512-R6oaW0y5/u6Eccti/TS6c/2c1xYTb1izwK3gajJwi4vIfNs1s8B1dQzI1UiC9T61YovOQVuePDcfqHLT3mUZJA==", 255 | "cpu": [ 256 | "x64" 257 | ], 258 | "dev": true, 259 | "optional": true, 260 | "os": [ 261 | "darwin" 262 | ], 263 | "engines": { 264 | "node": ">=12" 265 | } 266 | }, 267 | "node_modules/esbuild-darwin-arm64": { 268 | "version": "0.14.47", 269 | "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.47.tgz", 270 | "integrity": "sha512-seCmearlQyvdvM/noz1L9+qblC5vcBrhUaOoLEDDoLInF/VQ9IkobGiLlyTPYP5dW1YD4LXhtBgOyevoIHGGnw==", 271 | "cpu": [ 272 | "arm64" 273 | ], 274 | "dev": true, 275 | "optional": true, 276 | "os": [ 277 | "darwin" 278 | ], 279 | "engines": { 280 | "node": ">=12" 281 | } 282 | }, 283 | "node_modules/esbuild-freebsd-64": { 284 | "version": "0.14.47", 285 | "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.47.tgz", 286 | "integrity": "sha512-ZH8K2Q8/Ux5kXXvQMDsJcxvkIwut69KVrYQhza/ptkW50DC089bCVrJZZ3sKzIoOx+YPTrmsZvqeZERjyYrlvQ==", 287 | "cpu": [ 288 | "x64" 289 | ], 290 | "dev": true, 291 | "optional": true, 292 | "os": [ 293 | "freebsd" 294 | ], 295 | "engines": { 296 | "node": ">=12" 297 | } 298 | }, 299 | "node_modules/esbuild-freebsd-arm64": { 300 | "version": "0.14.47", 301 | "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.47.tgz", 302 | "integrity": "sha512-ZJMQAJQsIOhn3XTm7MPQfCzEu5b9STNC+s90zMWe2afy9EwnHV7Ov7ohEMv2lyWlc2pjqLW8QJnz2r0KZmeAEQ==", 303 | "cpu": [ 304 | "arm64" 305 | ], 306 | "dev": true, 307 | "optional": true, 308 | "os": [ 309 | "freebsd" 310 | ], 311 | "engines": { 312 | "node": ">=12" 313 | } 314 | }, 315 | "node_modules/esbuild-linux-32": { 316 | "version": "0.14.47", 317 | "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.47.tgz", 318 | "integrity": "sha512-FxZOCKoEDPRYvq300lsWCTv1kcHgiiZfNrPtEhFAiqD7QZaXrad8LxyJ8fXGcWzIFzRiYZVtB3ttvITBvAFhKw==", 319 | "cpu": [ 320 | "ia32" 321 | ], 322 | "dev": true, 323 | "optional": true, 324 | "os": [ 325 | "linux" 326 | ], 327 | "engines": { 328 | "node": ">=12" 329 | } 330 | }, 331 | "node_modules/esbuild-linux-64": { 332 | "version": "0.14.47", 333 | "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.47.tgz", 334 | "integrity": "sha512-nFNOk9vWVfvWYF9YNYksZptgQAdstnDCMtR6m42l5Wfugbzu11VpMCY9XrD4yFxvPo9zmzcoUL/88y0lfJZJJw==", 335 | "cpu": [ 336 | "x64" 337 | ], 338 | "dev": true, 339 | "optional": true, 340 | "os": [ 341 | "linux" 342 | ], 343 | "engines": { 344 | "node": ">=12" 345 | } 346 | }, 347 | "node_modules/esbuild-linux-arm": { 348 | "version": "0.14.47", 349 | "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.47.tgz", 350 | "integrity": "sha512-ZGE1Bqg/gPRXrBpgpvH81tQHpiaGxa8c9Rx/XOylkIl2ypLuOcawXEAo8ls+5DFCcRGt/o3sV+PzpAFZobOsmA==", 351 | "cpu": [ 352 | "arm" 353 | ], 354 | "dev": true, 355 | "optional": true, 356 | "os": [ 357 | "linux" 358 | ], 359 | "engines": { 360 | "node": ">=12" 361 | } 362 | }, 363 | "node_modules/esbuild-linux-arm64": { 364 | "version": "0.14.47", 365 | "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.47.tgz", 366 | "integrity": "sha512-ywfme6HVrhWcevzmsufjd4iT3PxTfCX9HOdxA7Hd+/ZM23Y9nXeb+vG6AyA6jgq/JovkcqRHcL9XwRNpWG6XRw==", 367 | "cpu": [ 368 | "arm64" 369 | ], 370 | "dev": true, 371 | "optional": true, 372 | "os": [ 373 | "linux" 374 | ], 375 | "engines": { 376 | "node": ">=12" 377 | } 378 | }, 379 | "node_modules/esbuild-linux-mips64le": { 380 | "version": "0.14.47", 381 | "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.47.tgz", 382 | "integrity": "sha512-mg3D8YndZ1LvUiEdDYR3OsmeyAew4MA/dvaEJxvyygahWmpv1SlEEnhEZlhPokjsUMfRagzsEF/d/2XF+kTQGg==", 383 | "cpu": [ 384 | "mips64el" 385 | ], 386 | "dev": true, 387 | "optional": true, 388 | "os": [ 389 | "linux" 390 | ], 391 | "engines": { 392 | "node": ">=12" 393 | } 394 | }, 395 | "node_modules/esbuild-linux-ppc64le": { 396 | "version": "0.14.47", 397 | "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.47.tgz", 398 | "integrity": "sha512-WER+f3+szmnZiWoK6AsrTKGoJoErG2LlauSmk73LEZFQ/iWC+KhhDsOkn1xBUpzXWsxN9THmQFltLoaFEH8F8w==", 399 | "cpu": [ 400 | "ppc64" 401 | ], 402 | "dev": true, 403 | "optional": true, 404 | "os": [ 405 | "linux" 406 | ], 407 | "engines": { 408 | "node": ">=12" 409 | } 410 | }, 411 | "node_modules/esbuild-linux-riscv64": { 412 | "version": "0.14.47", 413 | "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.47.tgz", 414 | "integrity": "sha512-1fI6bP3A3rvI9BsaaXbMoaOjLE3lVkJtLxsgLHqlBhLlBVY7UqffWBvkrX/9zfPhhVMd9ZRFiaqXnB1T7BsL2g==", 415 | "cpu": [ 416 | "riscv64" 417 | ], 418 | "dev": true, 419 | "optional": true, 420 | "os": [ 421 | "linux" 422 | ], 423 | "engines": { 424 | "node": ">=12" 425 | } 426 | }, 427 | "node_modules/esbuild-linux-s390x": { 428 | "version": "0.14.47", 429 | "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.47.tgz", 430 | "integrity": "sha512-eZrWzy0xFAhki1CWRGnhsHVz7IlSKX6yT2tj2Eg8lhAwlRE5E96Hsb0M1mPSE1dHGpt1QVwwVivXIAacF/G6mw==", 431 | "cpu": [ 432 | "s390x" 433 | ], 434 | "dev": true, 435 | "optional": true, 436 | "os": [ 437 | "linux" 438 | ], 439 | "engines": { 440 | "node": ">=12" 441 | } 442 | }, 443 | "node_modules/esbuild-netbsd-64": { 444 | "version": "0.14.47", 445 | "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.47.tgz", 446 | "integrity": "sha512-Qjdjr+KQQVH5Q2Q1r6HBYswFTToPpss3gqCiSw2Fpq/ua8+eXSQyAMG+UvULPqXceOwpnPo4smyZyHdlkcPppQ==", 447 | "cpu": [ 448 | "x64" 449 | ], 450 | "dev": true, 451 | "optional": true, 452 | "os": [ 453 | "netbsd" 454 | ], 455 | "engines": { 456 | "node": ">=12" 457 | } 458 | }, 459 | "node_modules/esbuild-openbsd-64": { 460 | "version": "0.14.47", 461 | "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.47.tgz", 462 | "integrity": "sha512-QpgN8ofL7B9z8g5zZqJE+eFvD1LehRlxr25PBkjyyasakm4599iroUpaj96rdqRlO2ShuyqwJdr+oNqWwTUmQw==", 463 | "cpu": [ 464 | "x64" 465 | ], 466 | "dev": true, 467 | "optional": true, 468 | "os": [ 469 | "openbsd" 470 | ], 471 | "engines": { 472 | "node": ">=12" 473 | } 474 | }, 475 | "node_modules/esbuild-sunos-64": { 476 | "version": "0.14.47", 477 | "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.47.tgz", 478 | "integrity": "sha512-uOeSgLUwukLioAJOiGYm3kNl+1wJjgJA8R671GYgcPgCx7QR73zfvYqXFFcIO93/nBdIbt5hd8RItqbbf3HtAQ==", 479 | "cpu": [ 480 | "x64" 481 | ], 482 | "dev": true, 483 | "optional": true, 484 | "os": [ 485 | "sunos" 486 | ], 487 | "engines": { 488 | "node": ">=12" 489 | } 490 | }, 491 | "node_modules/esbuild-windows-32": { 492 | "version": "0.14.47", 493 | "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.47.tgz", 494 | "integrity": "sha512-H0fWsLTp2WBfKLBgwYT4OTfFly4Im/8B5f3ojDv1Kx//kiubVY0IQunP2Koc/fr/0wI7hj3IiBDbSrmKlrNgLQ==", 495 | "cpu": [ 496 | "ia32" 497 | ], 498 | "dev": true, 499 | "optional": true, 500 | "os": [ 501 | "win32" 502 | ], 503 | "engines": { 504 | "node": ">=12" 505 | } 506 | }, 507 | "node_modules/esbuild-windows-64": { 508 | "version": "0.14.47", 509 | "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.47.tgz", 510 | "integrity": "sha512-/Pk5jIEH34T68r8PweKRi77W49KwanZ8X6lr3vDAtOlH5EumPE4pBHqkCUdELanvsT14yMXLQ/C/8XPi1pAtkQ==", 511 | "cpu": [ 512 | "x64" 513 | ], 514 | "dev": true, 515 | "optional": true, 516 | "os": [ 517 | "win32" 518 | ], 519 | "engines": { 520 | "node": ">=12" 521 | } 522 | }, 523 | "node_modules/esbuild-windows-arm64": { 524 | "version": "0.14.47", 525 | "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.47.tgz", 526 | "integrity": "sha512-HFSW2lnp62fl86/qPQlqw6asIwCnEsEoNIL1h2uVMgakddf+vUuMcCbtUY1i8sst7KkgHrVKCJQB33YhhOweCQ==", 527 | "cpu": [ 528 | "arm64" 529 | ], 530 | "dev": true, 531 | "optional": true, 532 | "os": [ 533 | "win32" 534 | ], 535 | "engines": { 536 | "node": ">=12" 537 | } 538 | }, 539 | "node_modules/escape-string-regexp": { 540 | "version": "1.0.5", 541 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 542 | "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", 543 | "dev": true, 544 | "engines": { 545 | "node": ">=0.8.0" 546 | } 547 | }, 548 | "node_modules/estree-walker": { 549 | "version": "2.0.2", 550 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", 551 | "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", 552 | "dev": true 553 | }, 554 | "node_modules/filename-reserved-regex": { 555 | "version": "2.0.0", 556 | "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", 557 | "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", 558 | "dev": true, 559 | "engines": { 560 | "node": ">=4" 561 | } 562 | }, 563 | "node_modules/filenamify": { 564 | "version": "4.3.0", 565 | "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", 566 | "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", 567 | "dev": true, 568 | "dependencies": { 569 | "filename-reserved-regex": "^2.0.0", 570 | "strip-outer": "^1.0.1", 571 | "trim-repeated": "^1.0.0" 572 | }, 573 | "engines": { 574 | "node": ">=8" 575 | }, 576 | "funding": { 577 | "url": "https://github.com/sponsors/sindresorhus" 578 | } 579 | }, 580 | "node_modules/fill-range": { 581 | "version": "7.0.1", 582 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 583 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 584 | "dev": true, 585 | "dependencies": { 586 | "to-regex-range": "^5.0.1" 587 | }, 588 | "engines": { 589 | "node": ">=8" 590 | } 591 | }, 592 | "node_modules/find-cache-dir": { 593 | "version": "3.3.2", 594 | "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", 595 | "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", 596 | "dev": true, 597 | "dependencies": { 598 | "commondir": "^1.0.1", 599 | "make-dir": "^3.0.2", 600 | "pkg-dir": "^4.1.0" 601 | }, 602 | "engines": { 603 | "node": ">=8" 604 | }, 605 | "funding": { 606 | "url": "https://github.com/avajs/find-cache-dir?sponsor=1" 607 | } 608 | }, 609 | "node_modules/find-up": { 610 | "version": "4.1.0", 611 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", 612 | "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", 613 | "dev": true, 614 | "dependencies": { 615 | "locate-path": "^5.0.0", 616 | "path-exists": "^4.0.0" 617 | }, 618 | "engines": { 619 | "node": ">=8" 620 | } 621 | }, 622 | "node_modules/fs-extra": { 623 | "version": "8.1.0", 624 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", 625 | "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", 626 | "dev": true, 627 | "dependencies": { 628 | "graceful-fs": "^4.2.0", 629 | "jsonfile": "^4.0.0", 630 | "universalify": "^0.1.0" 631 | }, 632 | "engines": { 633 | "node": ">=6 <7 || >=8" 634 | } 635 | }, 636 | "node_modules/fs.realpath": { 637 | "version": "1.0.0", 638 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 639 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", 640 | "dev": true 641 | }, 642 | "node_modules/fsevents": { 643 | "version": "2.3.2", 644 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 645 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 646 | "dev": true, 647 | "hasInstallScript": true, 648 | "optional": true, 649 | "os": [ 650 | "darwin" 651 | ], 652 | "engines": { 653 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 654 | } 655 | }, 656 | "node_modules/function-bind": { 657 | "version": "1.1.1", 658 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 659 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 660 | "dev": true 661 | }, 662 | "node_modules/gh-pages": { 663 | "version": "4.0.0", 664 | "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-4.0.0.tgz", 665 | "integrity": "sha512-p8S0T3aGJc68MtwOcZusul5qPSNZCalap3NWbhRUZYu1YOdp+EjZ+4kPmRM8h3NNRdqw00yuevRjlkuSzCn7iQ==", 666 | "dev": true, 667 | "dependencies": { 668 | "async": "^2.6.1", 669 | "commander": "^2.18.0", 670 | "email-addresses": "^3.0.1", 671 | "filenamify": "^4.3.0", 672 | "find-cache-dir": "^3.3.1", 673 | "fs-extra": "^8.1.0", 674 | "globby": "^6.1.0" 675 | }, 676 | "bin": { 677 | "gh-pages": "bin/gh-pages.js", 678 | "gh-pages-clean": "bin/gh-pages-clean.js" 679 | }, 680 | "engines": { 681 | "node": ">=10" 682 | } 683 | }, 684 | "node_modules/glob": { 685 | "version": "7.2.3", 686 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", 687 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", 688 | "dev": true, 689 | "dependencies": { 690 | "fs.realpath": "^1.0.0", 691 | "inflight": "^1.0.4", 692 | "inherits": "2", 693 | "minimatch": "^3.1.1", 694 | "once": "^1.3.0", 695 | "path-is-absolute": "^1.0.0" 696 | }, 697 | "engines": { 698 | "node": "*" 699 | }, 700 | "funding": { 701 | "url": "https://github.com/sponsors/isaacs" 702 | } 703 | }, 704 | "node_modules/glob-parent": { 705 | "version": "5.1.2", 706 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 707 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 708 | "dev": true, 709 | "dependencies": { 710 | "is-glob": "^4.0.1" 711 | }, 712 | "engines": { 713 | "node": ">= 6" 714 | } 715 | }, 716 | "node_modules/globby": { 717 | "version": "6.1.0", 718 | "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", 719 | "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", 720 | "dev": true, 721 | "dependencies": { 722 | "array-union": "^1.0.1", 723 | "glob": "^7.0.3", 724 | "object-assign": "^4.0.1", 725 | "pify": "^2.0.0", 726 | "pinkie-promise": "^2.0.0" 727 | }, 728 | "engines": { 729 | "node": ">=0.10.0" 730 | } 731 | }, 732 | "node_modules/graceful-fs": { 733 | "version": "4.2.10", 734 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", 735 | "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", 736 | "dev": true 737 | }, 738 | "node_modules/gsap": { 739 | "version": "3.10.4", 740 | "resolved": "https://registry.npmjs.org/gsap/-/gsap-3.10.4.tgz", 741 | "integrity": "sha512-6QatdkKxXCMfvCW4rM++0RqyLQAzFX5nwl3yHS0XPgkZBkiSEY3VZVbMltrdtsbER/xZonLtyHt684wRp4erlQ==" 742 | }, 743 | "node_modules/has": { 744 | "version": "1.0.3", 745 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 746 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 747 | "dev": true, 748 | "dependencies": { 749 | "function-bind": "^1.1.1" 750 | }, 751 | "engines": { 752 | "node": ">= 0.4.0" 753 | } 754 | }, 755 | "node_modules/immutable": { 756 | "version": "4.1.0", 757 | "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", 758 | "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", 759 | "dev": true 760 | }, 761 | "node_modules/inflight": { 762 | "version": "1.0.6", 763 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 764 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 765 | "dev": true, 766 | "dependencies": { 767 | "once": "^1.3.0", 768 | "wrappy": "1" 769 | } 770 | }, 771 | "node_modules/inherits": { 772 | "version": "2.0.4", 773 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 774 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 775 | "dev": true 776 | }, 777 | "node_modules/is-binary-path": { 778 | "version": "2.1.0", 779 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 780 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 781 | "dev": true, 782 | "dependencies": { 783 | "binary-extensions": "^2.0.0" 784 | }, 785 | "engines": { 786 | "node": ">=8" 787 | } 788 | }, 789 | "node_modules/is-core-module": { 790 | "version": "2.9.0", 791 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", 792 | "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", 793 | "dev": true, 794 | "dependencies": { 795 | "has": "^1.0.3" 796 | }, 797 | "funding": { 798 | "url": "https://github.com/sponsors/ljharb" 799 | } 800 | }, 801 | "node_modules/is-extglob": { 802 | "version": "2.1.1", 803 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 804 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 805 | "dev": true, 806 | "engines": { 807 | "node": ">=0.10.0" 808 | } 809 | }, 810 | "node_modules/is-glob": { 811 | "version": "4.0.3", 812 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 813 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 814 | "dev": true, 815 | "dependencies": { 816 | "is-extglob": "^2.1.1" 817 | }, 818 | "engines": { 819 | "node": ">=0.10.0" 820 | } 821 | }, 822 | "node_modules/is-number": { 823 | "version": "7.0.0", 824 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 825 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 826 | "dev": true, 827 | "engines": { 828 | "node": ">=0.12.0" 829 | } 830 | }, 831 | "node_modules/jsonfile": { 832 | "version": "4.0.0", 833 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", 834 | "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", 835 | "dev": true, 836 | "optionalDependencies": { 837 | "graceful-fs": "^4.1.6" 838 | } 839 | }, 840 | "node_modules/lil-gui": { 841 | "version": "0.16.1", 842 | "resolved": "https://registry.npmjs.org/lil-gui/-/lil-gui-0.16.1.tgz", 843 | "integrity": "sha512-6wnnfBvQxJYRhdLyIA+w5b8utwbuVxNmtpTXElm36OSgHa8lyKp00Xz/4AEx3kvodT0AJYgbfadCFWAM0Q8DgQ==" 844 | }, 845 | "node_modules/locate-path": { 846 | "version": "5.0.0", 847 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", 848 | "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", 849 | "dev": true, 850 | "dependencies": { 851 | "p-locate": "^4.1.0" 852 | }, 853 | "engines": { 854 | "node": ">=8" 855 | } 856 | }, 857 | "node_modules/lodash": { 858 | "version": "4.17.21", 859 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 860 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", 861 | "dev": true 862 | }, 863 | "node_modules/make-dir": { 864 | "version": "3.1.0", 865 | "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", 866 | "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", 867 | "dev": true, 868 | "dependencies": { 869 | "semver": "^6.0.0" 870 | }, 871 | "engines": { 872 | "node": ">=8" 873 | }, 874 | "funding": { 875 | "url": "https://github.com/sponsors/sindresorhus" 876 | } 877 | }, 878 | "node_modules/minimatch": { 879 | "version": "3.1.2", 880 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 881 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 882 | "dev": true, 883 | "dependencies": { 884 | "brace-expansion": "^1.1.7" 885 | }, 886 | "engines": { 887 | "node": "*" 888 | } 889 | }, 890 | "node_modules/nanoid": { 891 | "version": "3.3.4", 892 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", 893 | "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", 894 | "dev": true, 895 | "bin": { 896 | "nanoid": "bin/nanoid.cjs" 897 | }, 898 | "engines": { 899 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 900 | } 901 | }, 902 | "node_modules/normalize-path": { 903 | "version": "3.0.0", 904 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 905 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 906 | "dev": true, 907 | "engines": { 908 | "node": ">=0.10.0" 909 | } 910 | }, 911 | "node_modules/object-assign": { 912 | "version": "4.1.1", 913 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 914 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", 915 | "dev": true, 916 | "engines": { 917 | "node": ">=0.10.0" 918 | } 919 | }, 920 | "node_modules/once": { 921 | "version": "1.4.0", 922 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 923 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 924 | "dev": true, 925 | "dependencies": { 926 | "wrappy": "1" 927 | } 928 | }, 929 | "node_modules/p-limit": { 930 | "version": "2.3.0", 931 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", 932 | "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", 933 | "dev": true, 934 | "dependencies": { 935 | "p-try": "^2.0.0" 936 | }, 937 | "engines": { 938 | "node": ">=6" 939 | }, 940 | "funding": { 941 | "url": "https://github.com/sponsors/sindresorhus" 942 | } 943 | }, 944 | "node_modules/p-locate": { 945 | "version": "4.1.0", 946 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", 947 | "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", 948 | "dev": true, 949 | "dependencies": { 950 | "p-limit": "^2.2.0" 951 | }, 952 | "engines": { 953 | "node": ">=8" 954 | } 955 | }, 956 | "node_modules/p-try": { 957 | "version": "2.2.0", 958 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", 959 | "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", 960 | "dev": true, 961 | "engines": { 962 | "node": ">=6" 963 | } 964 | }, 965 | "node_modules/path-exists": { 966 | "version": "4.0.0", 967 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 968 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 969 | "dev": true, 970 | "engines": { 971 | "node": ">=8" 972 | } 973 | }, 974 | "node_modules/path-is-absolute": { 975 | "version": "1.0.1", 976 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 977 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 978 | "dev": true, 979 | "engines": { 980 | "node": ">=0.10.0" 981 | } 982 | }, 983 | "node_modules/path-parse": { 984 | "version": "1.0.7", 985 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 986 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", 987 | "dev": true 988 | }, 989 | "node_modules/picocolors": { 990 | "version": "1.0.0", 991 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", 992 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", 993 | "dev": true 994 | }, 995 | "node_modules/picomatch": { 996 | "version": "2.3.1", 997 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 998 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 999 | "dev": true, 1000 | "engines": { 1001 | "node": ">=8.6" 1002 | }, 1003 | "funding": { 1004 | "url": "https://github.com/sponsors/jonschlinkert" 1005 | } 1006 | }, 1007 | "node_modules/pify": { 1008 | "version": "2.3.0", 1009 | "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", 1010 | "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", 1011 | "dev": true, 1012 | "engines": { 1013 | "node": ">=0.10.0" 1014 | } 1015 | }, 1016 | "node_modules/pinkie": { 1017 | "version": "2.0.4", 1018 | "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", 1019 | "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", 1020 | "dev": true, 1021 | "engines": { 1022 | "node": ">=0.10.0" 1023 | } 1024 | }, 1025 | "node_modules/pinkie-promise": { 1026 | "version": "2.0.1", 1027 | "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", 1028 | "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", 1029 | "dev": true, 1030 | "dependencies": { 1031 | "pinkie": "^2.0.0" 1032 | }, 1033 | "engines": { 1034 | "node": ">=0.10.0" 1035 | } 1036 | }, 1037 | "node_modules/pkg-dir": { 1038 | "version": "4.2.0", 1039 | "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", 1040 | "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", 1041 | "dev": true, 1042 | "dependencies": { 1043 | "find-up": "^4.0.0" 1044 | }, 1045 | "engines": { 1046 | "node": ">=8" 1047 | } 1048 | }, 1049 | "node_modules/postcss": { 1050 | "version": "8.4.14", 1051 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", 1052 | "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", 1053 | "dev": true, 1054 | "funding": [ 1055 | { 1056 | "type": "opencollective", 1057 | "url": "https://opencollective.com/postcss/" 1058 | }, 1059 | { 1060 | "type": "tidelift", 1061 | "url": "https://tidelift.com/funding/github/npm/postcss" 1062 | } 1063 | ], 1064 | "dependencies": { 1065 | "nanoid": "^3.3.4", 1066 | "picocolors": "^1.0.0", 1067 | "source-map-js": "^1.0.2" 1068 | }, 1069 | "engines": { 1070 | "node": "^10 || ^12 || >=14" 1071 | } 1072 | }, 1073 | "node_modules/readdirp": { 1074 | "version": "3.6.0", 1075 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", 1076 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", 1077 | "dev": true, 1078 | "dependencies": { 1079 | "picomatch": "^2.2.1" 1080 | }, 1081 | "engines": { 1082 | "node": ">=8.10.0" 1083 | } 1084 | }, 1085 | "node_modules/resolve": { 1086 | "version": "1.22.1", 1087 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", 1088 | "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", 1089 | "dev": true, 1090 | "dependencies": { 1091 | "is-core-module": "^2.9.0", 1092 | "path-parse": "^1.0.7", 1093 | "supports-preserve-symlinks-flag": "^1.0.0" 1094 | }, 1095 | "bin": { 1096 | "resolve": "bin/resolve" 1097 | }, 1098 | "funding": { 1099 | "url": "https://github.com/sponsors/ljharb" 1100 | } 1101 | }, 1102 | "node_modules/ress": { 1103 | "version": "5.0.2", 1104 | "resolved": "https://registry.npmjs.org/ress/-/ress-5.0.2.tgz", 1105 | "integrity": "sha512-oHBtOWo/Uc8SzQMbQNIKTcgi8wKmAs7IlNlRywmXudbOtF+c27FlOIq7tnwLDVcTywe6JXYo1pDXHO6kABwNYA==" 1106 | }, 1107 | "node_modules/rollup": { 1108 | "version": "2.75.7", 1109 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.75.7.tgz", 1110 | "integrity": "sha512-VSE1iy0eaAYNCxEXaleThdFXqZJ42qDBatAwrfnPlENEZ8erQ+0LYX4JXOLPceWfZpV1VtZwZ3dFCuOZiSyFtQ==", 1111 | "dev": true, 1112 | "bin": { 1113 | "rollup": "dist/bin/rollup" 1114 | }, 1115 | "engines": { 1116 | "node": ">=10.0.0" 1117 | }, 1118 | "optionalDependencies": { 1119 | "fsevents": "~2.3.2" 1120 | } 1121 | }, 1122 | "node_modules/sass": { 1123 | "version": "1.53.0", 1124 | "resolved": "https://registry.npmjs.org/sass/-/sass-1.53.0.tgz", 1125 | "integrity": "sha512-zb/oMirbKhUgRQ0/GFz8TSAwRq2IlR29vOUJZOx0l8sV+CkHUfHa4u5nqrG+1VceZp7Jfj59SVW9ogdhTvJDcQ==", 1126 | "dev": true, 1127 | "dependencies": { 1128 | "chokidar": ">=3.0.0 <4.0.0", 1129 | "immutable": "^4.0.0", 1130 | "source-map-js": ">=0.6.2 <2.0.0" 1131 | }, 1132 | "bin": { 1133 | "sass": "sass.js" 1134 | }, 1135 | "engines": { 1136 | "node": ">=12.0.0" 1137 | } 1138 | }, 1139 | "node_modules/semver": { 1140 | "version": "6.3.0", 1141 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", 1142 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", 1143 | "dev": true, 1144 | "bin": { 1145 | "semver": "bin/semver.js" 1146 | } 1147 | }, 1148 | "node_modules/source-map-js": { 1149 | "version": "1.0.2", 1150 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", 1151 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", 1152 | "dev": true, 1153 | "engines": { 1154 | "node": ">=0.10.0" 1155 | } 1156 | }, 1157 | "node_modules/strip-outer": { 1158 | "version": "1.0.1", 1159 | "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", 1160 | "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", 1161 | "dev": true, 1162 | "dependencies": { 1163 | "escape-string-regexp": "^1.0.2" 1164 | }, 1165 | "engines": { 1166 | "node": ">=0.10.0" 1167 | } 1168 | }, 1169 | "node_modules/supports-preserve-symlinks-flag": { 1170 | "version": "1.0.0", 1171 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 1172 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", 1173 | "dev": true, 1174 | "engines": { 1175 | "node": ">= 0.4" 1176 | }, 1177 | "funding": { 1178 | "url": "https://github.com/sponsors/ljharb" 1179 | } 1180 | }, 1181 | "node_modules/three": { 1182 | "version": "0.141.0", 1183 | "resolved": "https://registry.npmjs.org/three/-/three-0.141.0.tgz", 1184 | "integrity": "sha512-JaSDAPWuk4RTzG5BYRQm8YZbERUxTfTDVouWgHMisS2to4E5fotMS9F2zPFNOIJyEFTTQDDKPpsgZVThKU3pXA==" 1185 | }, 1186 | "node_modules/to-regex-range": { 1187 | "version": "5.0.1", 1188 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 1189 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 1190 | "dev": true, 1191 | "dependencies": { 1192 | "is-number": "^7.0.0" 1193 | }, 1194 | "engines": { 1195 | "node": ">=8.0" 1196 | } 1197 | }, 1198 | "node_modules/trim-repeated": { 1199 | "version": "1.0.0", 1200 | "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", 1201 | "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", 1202 | "dev": true, 1203 | "dependencies": { 1204 | "escape-string-regexp": "^1.0.2" 1205 | }, 1206 | "engines": { 1207 | "node": ">=0.10.0" 1208 | } 1209 | }, 1210 | "node_modules/tslib": { 1211 | "version": "2.4.0", 1212 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", 1213 | "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", 1214 | "dev": true 1215 | }, 1216 | "node_modules/typescript": { 1217 | "version": "4.7.4", 1218 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", 1219 | "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", 1220 | "dev": true, 1221 | "bin": { 1222 | "tsc": "bin/tsc", 1223 | "tsserver": "bin/tsserver" 1224 | }, 1225 | "engines": { 1226 | "node": ">=4.2.0" 1227 | } 1228 | }, 1229 | "node_modules/universalify": { 1230 | "version": "0.1.2", 1231 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", 1232 | "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", 1233 | "dev": true, 1234 | "engines": { 1235 | "node": ">= 4.0.0" 1236 | } 1237 | }, 1238 | "node_modules/vite": { 1239 | "version": "2.9.12", 1240 | "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.12.tgz", 1241 | "integrity": "sha512-suxC36dQo9Rq1qMB2qiRorNJtJAdxguu5TMvBHOc/F370KvqAe9t48vYp+/TbPKRNrMh/J55tOUmkuIqstZaew==", 1242 | "dev": true, 1243 | "dependencies": { 1244 | "esbuild": "^0.14.27", 1245 | "postcss": "^8.4.13", 1246 | "resolve": "^1.22.0", 1247 | "rollup": "^2.59.0" 1248 | }, 1249 | "bin": { 1250 | "vite": "bin/vite.js" 1251 | }, 1252 | "engines": { 1253 | "node": ">=12.2.0" 1254 | }, 1255 | "optionalDependencies": { 1256 | "fsevents": "~2.3.2" 1257 | }, 1258 | "peerDependencies": { 1259 | "less": "*", 1260 | "sass": "*", 1261 | "stylus": "*" 1262 | }, 1263 | "peerDependenciesMeta": { 1264 | "less": { 1265 | "optional": true 1266 | }, 1267 | "sass": { 1268 | "optional": true 1269 | }, 1270 | "stylus": { 1271 | "optional": true 1272 | } 1273 | } 1274 | }, 1275 | "node_modules/vite-plugin-glsl": { 1276 | "version": "0.1.2", 1277 | "resolved": "https://registry.npmjs.org/vite-plugin-glsl/-/vite-plugin-glsl-0.1.2.tgz", 1278 | "integrity": "sha512-RFwoYn8EQFXp4YygIyt8Ex3bQE5/v5927AF0MAgrNfX4NRPlDAX12ciWlpVs4ObKLYro49fctnou4+fajO0FOg==", 1279 | "dev": true, 1280 | "dependencies": { 1281 | "@rollup/pluginutils": "^4.1.2", 1282 | "tslib": "^2.3.1" 1283 | }, 1284 | "engines": { 1285 | "node": ">= 14.17.0", 1286 | "npm": ">= 6.14.13" 1287 | } 1288 | }, 1289 | "node_modules/wrappy": { 1290 | "version": "1.0.2", 1291 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1292 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 1293 | "dev": true 1294 | } 1295 | }, 1296 | "dependencies": { 1297 | "@rollup/pluginutils": { 1298 | "version": "4.2.1", 1299 | "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", 1300 | "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", 1301 | "dev": true, 1302 | "requires": { 1303 | "estree-walker": "^2.0.1", 1304 | "picomatch": "^2.2.2" 1305 | } 1306 | }, 1307 | "@types/three": { 1308 | "version": "0.141.0", 1309 | "resolved": "https://registry.npmjs.org/@types/three/-/three-0.141.0.tgz", 1310 | "integrity": "sha512-OJdKDgTPVBUgc+s74DYoy4aLznbFFC38Xm4ElmU1YwGNgR7GGFVvFCX7lpVgOsT6S1zSJtGdajTsOYE8/xY9nA==", 1311 | "dev": true, 1312 | "requires": { 1313 | "@types/webxr": "*" 1314 | } 1315 | }, 1316 | "@types/webxr": { 1317 | "version": "0.4.0", 1318 | "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.4.0.tgz", 1319 | "integrity": "sha512-LQvrACV3Pj17GpkwHwXuTd733gfY+D7b9mKdrTmLdO7vo7P/o6209Qqtk63y/FCv/lspdmi0pWz6Qe/ull9kQg==", 1320 | "dev": true 1321 | }, 1322 | "anymatch": { 1323 | "version": "3.1.2", 1324 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", 1325 | "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", 1326 | "dev": true, 1327 | "requires": { 1328 | "normalize-path": "^3.0.0", 1329 | "picomatch": "^2.0.4" 1330 | } 1331 | }, 1332 | "array-union": { 1333 | "version": "1.0.2", 1334 | "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", 1335 | "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", 1336 | "dev": true, 1337 | "requires": { 1338 | "array-uniq": "^1.0.1" 1339 | } 1340 | }, 1341 | "array-uniq": { 1342 | "version": "1.0.3", 1343 | "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", 1344 | "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", 1345 | "dev": true 1346 | }, 1347 | "async": { 1348 | "version": "2.6.4", 1349 | "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", 1350 | "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", 1351 | "dev": true, 1352 | "requires": { 1353 | "lodash": "^4.17.14" 1354 | } 1355 | }, 1356 | "balanced-match": { 1357 | "version": "1.0.2", 1358 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 1359 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 1360 | "dev": true 1361 | }, 1362 | "binary-extensions": { 1363 | "version": "2.2.0", 1364 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", 1365 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", 1366 | "dev": true 1367 | }, 1368 | "brace-expansion": { 1369 | "version": "1.1.11", 1370 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 1371 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 1372 | "dev": true, 1373 | "requires": { 1374 | "balanced-match": "^1.0.0", 1375 | "concat-map": "0.0.1" 1376 | } 1377 | }, 1378 | "braces": { 1379 | "version": "3.0.2", 1380 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 1381 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 1382 | "dev": true, 1383 | "requires": { 1384 | "fill-range": "^7.0.1" 1385 | } 1386 | }, 1387 | "chokidar": { 1388 | "version": "3.5.3", 1389 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", 1390 | "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", 1391 | "dev": true, 1392 | "requires": { 1393 | "anymatch": "~3.1.2", 1394 | "braces": "~3.0.2", 1395 | "fsevents": "~2.3.2", 1396 | "glob-parent": "~5.1.2", 1397 | "is-binary-path": "~2.1.0", 1398 | "is-glob": "~4.0.1", 1399 | "normalize-path": "~3.0.0", 1400 | "readdirp": "~3.6.0" 1401 | } 1402 | }, 1403 | "commander": { 1404 | "version": "2.20.3", 1405 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", 1406 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", 1407 | "dev": true 1408 | }, 1409 | "commondir": { 1410 | "version": "1.0.1", 1411 | "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", 1412 | "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", 1413 | "dev": true 1414 | }, 1415 | "concat-map": { 1416 | "version": "0.0.1", 1417 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 1418 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 1419 | "dev": true 1420 | }, 1421 | "email-addresses": { 1422 | "version": "3.1.0", 1423 | "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-3.1.0.tgz", 1424 | "integrity": "sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg==", 1425 | "dev": true 1426 | }, 1427 | "esbuild": { 1428 | "version": "0.14.47", 1429 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.47.tgz", 1430 | "integrity": "sha512-wI4ZiIfFxpkuxB8ju4MHrGwGLyp1+awEHAHVpx6w7a+1pmYIq8T9FGEVVwFo0iFierDoMj++Xq69GXWYn2EiwA==", 1431 | "dev": true, 1432 | "requires": { 1433 | "esbuild-android-64": "0.14.47", 1434 | "esbuild-android-arm64": "0.14.47", 1435 | "esbuild-darwin-64": "0.14.47", 1436 | "esbuild-darwin-arm64": "0.14.47", 1437 | "esbuild-freebsd-64": "0.14.47", 1438 | "esbuild-freebsd-arm64": "0.14.47", 1439 | "esbuild-linux-32": "0.14.47", 1440 | "esbuild-linux-64": "0.14.47", 1441 | "esbuild-linux-arm": "0.14.47", 1442 | "esbuild-linux-arm64": "0.14.47", 1443 | "esbuild-linux-mips64le": "0.14.47", 1444 | "esbuild-linux-ppc64le": "0.14.47", 1445 | "esbuild-linux-riscv64": "0.14.47", 1446 | "esbuild-linux-s390x": "0.14.47", 1447 | "esbuild-netbsd-64": "0.14.47", 1448 | "esbuild-openbsd-64": "0.14.47", 1449 | "esbuild-sunos-64": "0.14.47", 1450 | "esbuild-windows-32": "0.14.47", 1451 | "esbuild-windows-64": "0.14.47", 1452 | "esbuild-windows-arm64": "0.14.47" 1453 | } 1454 | }, 1455 | "esbuild-android-64": { 1456 | "version": "0.14.47", 1457 | "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.47.tgz", 1458 | "integrity": "sha512-R13Bd9+tqLVFndncMHssZrPWe6/0Kpv2/dt4aA69soX4PRxlzsVpCvoJeFE8sOEoeVEiBkI0myjlkDodXlHa0g==", 1459 | "dev": true, 1460 | "optional": true 1461 | }, 1462 | "esbuild-android-arm64": { 1463 | "version": "0.14.47", 1464 | "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.47.tgz", 1465 | "integrity": "sha512-OkwOjj7ts4lBp/TL6hdd8HftIzOy/pdtbrNA4+0oVWgGG64HrdVzAF5gxtJufAPOsEjkyh1oIYvKAUinKKQRSQ==", 1466 | "dev": true, 1467 | "optional": true 1468 | }, 1469 | "esbuild-darwin-64": { 1470 | "version": "0.14.47", 1471 | "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.47.tgz", 1472 | "integrity": "sha512-R6oaW0y5/u6Eccti/TS6c/2c1xYTb1izwK3gajJwi4vIfNs1s8B1dQzI1UiC9T61YovOQVuePDcfqHLT3mUZJA==", 1473 | "dev": true, 1474 | "optional": true 1475 | }, 1476 | "esbuild-darwin-arm64": { 1477 | "version": "0.14.47", 1478 | "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.47.tgz", 1479 | "integrity": "sha512-seCmearlQyvdvM/noz1L9+qblC5vcBrhUaOoLEDDoLInF/VQ9IkobGiLlyTPYP5dW1YD4LXhtBgOyevoIHGGnw==", 1480 | "dev": true, 1481 | "optional": true 1482 | }, 1483 | "esbuild-freebsd-64": { 1484 | "version": "0.14.47", 1485 | "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.47.tgz", 1486 | "integrity": "sha512-ZH8K2Q8/Ux5kXXvQMDsJcxvkIwut69KVrYQhza/ptkW50DC089bCVrJZZ3sKzIoOx+YPTrmsZvqeZERjyYrlvQ==", 1487 | "dev": true, 1488 | "optional": true 1489 | }, 1490 | "esbuild-freebsd-arm64": { 1491 | "version": "0.14.47", 1492 | "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.47.tgz", 1493 | "integrity": "sha512-ZJMQAJQsIOhn3XTm7MPQfCzEu5b9STNC+s90zMWe2afy9EwnHV7Ov7ohEMv2lyWlc2pjqLW8QJnz2r0KZmeAEQ==", 1494 | "dev": true, 1495 | "optional": true 1496 | }, 1497 | "esbuild-linux-32": { 1498 | "version": "0.14.47", 1499 | "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.47.tgz", 1500 | "integrity": "sha512-FxZOCKoEDPRYvq300lsWCTv1kcHgiiZfNrPtEhFAiqD7QZaXrad8LxyJ8fXGcWzIFzRiYZVtB3ttvITBvAFhKw==", 1501 | "dev": true, 1502 | "optional": true 1503 | }, 1504 | "esbuild-linux-64": { 1505 | "version": "0.14.47", 1506 | "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.47.tgz", 1507 | "integrity": "sha512-nFNOk9vWVfvWYF9YNYksZptgQAdstnDCMtR6m42l5Wfugbzu11VpMCY9XrD4yFxvPo9zmzcoUL/88y0lfJZJJw==", 1508 | "dev": true, 1509 | "optional": true 1510 | }, 1511 | "esbuild-linux-arm": { 1512 | "version": "0.14.47", 1513 | "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.47.tgz", 1514 | "integrity": "sha512-ZGE1Bqg/gPRXrBpgpvH81tQHpiaGxa8c9Rx/XOylkIl2ypLuOcawXEAo8ls+5DFCcRGt/o3sV+PzpAFZobOsmA==", 1515 | "dev": true, 1516 | "optional": true 1517 | }, 1518 | "esbuild-linux-arm64": { 1519 | "version": "0.14.47", 1520 | "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.47.tgz", 1521 | "integrity": "sha512-ywfme6HVrhWcevzmsufjd4iT3PxTfCX9HOdxA7Hd+/ZM23Y9nXeb+vG6AyA6jgq/JovkcqRHcL9XwRNpWG6XRw==", 1522 | "dev": true, 1523 | "optional": true 1524 | }, 1525 | "esbuild-linux-mips64le": { 1526 | "version": "0.14.47", 1527 | "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.47.tgz", 1528 | "integrity": "sha512-mg3D8YndZ1LvUiEdDYR3OsmeyAew4MA/dvaEJxvyygahWmpv1SlEEnhEZlhPokjsUMfRagzsEF/d/2XF+kTQGg==", 1529 | "dev": true, 1530 | "optional": true 1531 | }, 1532 | "esbuild-linux-ppc64le": { 1533 | "version": "0.14.47", 1534 | "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.47.tgz", 1535 | "integrity": "sha512-WER+f3+szmnZiWoK6AsrTKGoJoErG2LlauSmk73LEZFQ/iWC+KhhDsOkn1xBUpzXWsxN9THmQFltLoaFEH8F8w==", 1536 | "dev": true, 1537 | "optional": true 1538 | }, 1539 | "esbuild-linux-riscv64": { 1540 | "version": "0.14.47", 1541 | "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.47.tgz", 1542 | "integrity": "sha512-1fI6bP3A3rvI9BsaaXbMoaOjLE3lVkJtLxsgLHqlBhLlBVY7UqffWBvkrX/9zfPhhVMd9ZRFiaqXnB1T7BsL2g==", 1543 | "dev": true, 1544 | "optional": true 1545 | }, 1546 | "esbuild-linux-s390x": { 1547 | "version": "0.14.47", 1548 | "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.47.tgz", 1549 | "integrity": "sha512-eZrWzy0xFAhki1CWRGnhsHVz7IlSKX6yT2tj2Eg8lhAwlRE5E96Hsb0M1mPSE1dHGpt1QVwwVivXIAacF/G6mw==", 1550 | "dev": true, 1551 | "optional": true 1552 | }, 1553 | "esbuild-netbsd-64": { 1554 | "version": "0.14.47", 1555 | "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.47.tgz", 1556 | "integrity": "sha512-Qjdjr+KQQVH5Q2Q1r6HBYswFTToPpss3gqCiSw2Fpq/ua8+eXSQyAMG+UvULPqXceOwpnPo4smyZyHdlkcPppQ==", 1557 | "dev": true, 1558 | "optional": true 1559 | }, 1560 | "esbuild-openbsd-64": { 1561 | "version": "0.14.47", 1562 | "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.47.tgz", 1563 | "integrity": "sha512-QpgN8ofL7B9z8g5zZqJE+eFvD1LehRlxr25PBkjyyasakm4599iroUpaj96rdqRlO2ShuyqwJdr+oNqWwTUmQw==", 1564 | "dev": true, 1565 | "optional": true 1566 | }, 1567 | "esbuild-sunos-64": { 1568 | "version": "0.14.47", 1569 | "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.47.tgz", 1570 | "integrity": "sha512-uOeSgLUwukLioAJOiGYm3kNl+1wJjgJA8R671GYgcPgCx7QR73zfvYqXFFcIO93/nBdIbt5hd8RItqbbf3HtAQ==", 1571 | "dev": true, 1572 | "optional": true 1573 | }, 1574 | "esbuild-windows-32": { 1575 | "version": "0.14.47", 1576 | "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.47.tgz", 1577 | "integrity": "sha512-H0fWsLTp2WBfKLBgwYT4OTfFly4Im/8B5f3ojDv1Kx//kiubVY0IQunP2Koc/fr/0wI7hj3IiBDbSrmKlrNgLQ==", 1578 | "dev": true, 1579 | "optional": true 1580 | }, 1581 | "esbuild-windows-64": { 1582 | "version": "0.14.47", 1583 | "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.47.tgz", 1584 | "integrity": "sha512-/Pk5jIEH34T68r8PweKRi77W49KwanZ8X6lr3vDAtOlH5EumPE4pBHqkCUdELanvsT14yMXLQ/C/8XPi1pAtkQ==", 1585 | "dev": true, 1586 | "optional": true 1587 | }, 1588 | "esbuild-windows-arm64": { 1589 | "version": "0.14.47", 1590 | "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.47.tgz", 1591 | "integrity": "sha512-HFSW2lnp62fl86/qPQlqw6asIwCnEsEoNIL1h2uVMgakddf+vUuMcCbtUY1i8sst7KkgHrVKCJQB33YhhOweCQ==", 1592 | "dev": true, 1593 | "optional": true 1594 | }, 1595 | "escape-string-regexp": { 1596 | "version": "1.0.5", 1597 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 1598 | "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", 1599 | "dev": true 1600 | }, 1601 | "estree-walker": { 1602 | "version": "2.0.2", 1603 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", 1604 | "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", 1605 | "dev": true 1606 | }, 1607 | "filename-reserved-regex": { 1608 | "version": "2.0.0", 1609 | "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", 1610 | "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", 1611 | "dev": true 1612 | }, 1613 | "filenamify": { 1614 | "version": "4.3.0", 1615 | "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", 1616 | "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", 1617 | "dev": true, 1618 | "requires": { 1619 | "filename-reserved-regex": "^2.0.0", 1620 | "strip-outer": "^1.0.1", 1621 | "trim-repeated": "^1.0.0" 1622 | } 1623 | }, 1624 | "fill-range": { 1625 | "version": "7.0.1", 1626 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 1627 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 1628 | "dev": true, 1629 | "requires": { 1630 | "to-regex-range": "^5.0.1" 1631 | } 1632 | }, 1633 | "find-cache-dir": { 1634 | "version": "3.3.2", 1635 | "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", 1636 | "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", 1637 | "dev": true, 1638 | "requires": { 1639 | "commondir": "^1.0.1", 1640 | "make-dir": "^3.0.2", 1641 | "pkg-dir": "^4.1.0" 1642 | } 1643 | }, 1644 | "find-up": { 1645 | "version": "4.1.0", 1646 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", 1647 | "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", 1648 | "dev": true, 1649 | "requires": { 1650 | "locate-path": "^5.0.0", 1651 | "path-exists": "^4.0.0" 1652 | } 1653 | }, 1654 | "fs-extra": { 1655 | "version": "8.1.0", 1656 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", 1657 | "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", 1658 | "dev": true, 1659 | "requires": { 1660 | "graceful-fs": "^4.2.0", 1661 | "jsonfile": "^4.0.0", 1662 | "universalify": "^0.1.0" 1663 | } 1664 | }, 1665 | "fs.realpath": { 1666 | "version": "1.0.0", 1667 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 1668 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", 1669 | "dev": true 1670 | }, 1671 | "fsevents": { 1672 | "version": "2.3.2", 1673 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 1674 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 1675 | "dev": true, 1676 | "optional": true 1677 | }, 1678 | "function-bind": { 1679 | "version": "1.1.1", 1680 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 1681 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 1682 | "dev": true 1683 | }, 1684 | "gh-pages": { 1685 | "version": "4.0.0", 1686 | "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-4.0.0.tgz", 1687 | "integrity": "sha512-p8S0T3aGJc68MtwOcZusul5qPSNZCalap3NWbhRUZYu1YOdp+EjZ+4kPmRM8h3NNRdqw00yuevRjlkuSzCn7iQ==", 1688 | "dev": true, 1689 | "requires": { 1690 | "async": "^2.6.1", 1691 | "commander": "^2.18.0", 1692 | "email-addresses": "^3.0.1", 1693 | "filenamify": "^4.3.0", 1694 | "find-cache-dir": "^3.3.1", 1695 | "fs-extra": "^8.1.0", 1696 | "globby": "^6.1.0" 1697 | } 1698 | }, 1699 | "glob": { 1700 | "version": "7.2.3", 1701 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", 1702 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", 1703 | "dev": true, 1704 | "requires": { 1705 | "fs.realpath": "^1.0.0", 1706 | "inflight": "^1.0.4", 1707 | "inherits": "2", 1708 | "minimatch": "^3.1.1", 1709 | "once": "^1.3.0", 1710 | "path-is-absolute": "^1.0.0" 1711 | } 1712 | }, 1713 | "glob-parent": { 1714 | "version": "5.1.2", 1715 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 1716 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 1717 | "dev": true, 1718 | "requires": { 1719 | "is-glob": "^4.0.1" 1720 | } 1721 | }, 1722 | "globby": { 1723 | "version": "6.1.0", 1724 | "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", 1725 | "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", 1726 | "dev": true, 1727 | "requires": { 1728 | "array-union": "^1.0.1", 1729 | "glob": "^7.0.3", 1730 | "object-assign": "^4.0.1", 1731 | "pify": "^2.0.0", 1732 | "pinkie-promise": "^2.0.0" 1733 | } 1734 | }, 1735 | "graceful-fs": { 1736 | "version": "4.2.10", 1737 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", 1738 | "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", 1739 | "dev": true 1740 | }, 1741 | "gsap": { 1742 | "version": "3.10.4", 1743 | "resolved": "https://registry.npmjs.org/gsap/-/gsap-3.10.4.tgz", 1744 | "integrity": "sha512-6QatdkKxXCMfvCW4rM++0RqyLQAzFX5nwl3yHS0XPgkZBkiSEY3VZVbMltrdtsbER/xZonLtyHt684wRp4erlQ==" 1745 | }, 1746 | "has": { 1747 | "version": "1.0.3", 1748 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 1749 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 1750 | "dev": true, 1751 | "requires": { 1752 | "function-bind": "^1.1.1" 1753 | } 1754 | }, 1755 | "immutable": { 1756 | "version": "4.1.0", 1757 | "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", 1758 | "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", 1759 | "dev": true 1760 | }, 1761 | "inflight": { 1762 | "version": "1.0.6", 1763 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 1764 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 1765 | "dev": true, 1766 | "requires": { 1767 | "once": "^1.3.0", 1768 | "wrappy": "1" 1769 | } 1770 | }, 1771 | "inherits": { 1772 | "version": "2.0.4", 1773 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1774 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 1775 | "dev": true 1776 | }, 1777 | "is-binary-path": { 1778 | "version": "2.1.0", 1779 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 1780 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 1781 | "dev": true, 1782 | "requires": { 1783 | "binary-extensions": "^2.0.0" 1784 | } 1785 | }, 1786 | "is-core-module": { 1787 | "version": "2.9.0", 1788 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", 1789 | "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", 1790 | "dev": true, 1791 | "requires": { 1792 | "has": "^1.0.3" 1793 | } 1794 | }, 1795 | "is-extglob": { 1796 | "version": "2.1.1", 1797 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 1798 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 1799 | "dev": true 1800 | }, 1801 | "is-glob": { 1802 | "version": "4.0.3", 1803 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 1804 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 1805 | "dev": true, 1806 | "requires": { 1807 | "is-extglob": "^2.1.1" 1808 | } 1809 | }, 1810 | "is-number": { 1811 | "version": "7.0.0", 1812 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 1813 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 1814 | "dev": true 1815 | }, 1816 | "jsonfile": { 1817 | "version": "4.0.0", 1818 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", 1819 | "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", 1820 | "dev": true, 1821 | "requires": { 1822 | "graceful-fs": "^4.1.6" 1823 | } 1824 | }, 1825 | "lil-gui": { 1826 | "version": "0.16.1", 1827 | "resolved": "https://registry.npmjs.org/lil-gui/-/lil-gui-0.16.1.tgz", 1828 | "integrity": "sha512-6wnnfBvQxJYRhdLyIA+w5b8utwbuVxNmtpTXElm36OSgHa8lyKp00Xz/4AEx3kvodT0AJYgbfadCFWAM0Q8DgQ==" 1829 | }, 1830 | "locate-path": { 1831 | "version": "5.0.0", 1832 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", 1833 | "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", 1834 | "dev": true, 1835 | "requires": { 1836 | "p-locate": "^4.1.0" 1837 | } 1838 | }, 1839 | "lodash": { 1840 | "version": "4.17.21", 1841 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 1842 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", 1843 | "dev": true 1844 | }, 1845 | "make-dir": { 1846 | "version": "3.1.0", 1847 | "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", 1848 | "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", 1849 | "dev": true, 1850 | "requires": { 1851 | "semver": "^6.0.0" 1852 | } 1853 | }, 1854 | "minimatch": { 1855 | "version": "3.1.2", 1856 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 1857 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 1858 | "dev": true, 1859 | "requires": { 1860 | "brace-expansion": "^1.1.7" 1861 | } 1862 | }, 1863 | "nanoid": { 1864 | "version": "3.3.4", 1865 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", 1866 | "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", 1867 | "dev": true 1868 | }, 1869 | "normalize-path": { 1870 | "version": "3.0.0", 1871 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 1872 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 1873 | "dev": true 1874 | }, 1875 | "object-assign": { 1876 | "version": "4.1.1", 1877 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1878 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", 1879 | "dev": true 1880 | }, 1881 | "once": { 1882 | "version": "1.4.0", 1883 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1884 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 1885 | "dev": true, 1886 | "requires": { 1887 | "wrappy": "1" 1888 | } 1889 | }, 1890 | "p-limit": { 1891 | "version": "2.3.0", 1892 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", 1893 | "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", 1894 | "dev": true, 1895 | "requires": { 1896 | "p-try": "^2.0.0" 1897 | } 1898 | }, 1899 | "p-locate": { 1900 | "version": "4.1.0", 1901 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", 1902 | "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", 1903 | "dev": true, 1904 | "requires": { 1905 | "p-limit": "^2.2.0" 1906 | } 1907 | }, 1908 | "p-try": { 1909 | "version": "2.2.0", 1910 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", 1911 | "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", 1912 | "dev": true 1913 | }, 1914 | "path-exists": { 1915 | "version": "4.0.0", 1916 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 1917 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 1918 | "dev": true 1919 | }, 1920 | "path-is-absolute": { 1921 | "version": "1.0.1", 1922 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1923 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 1924 | "dev": true 1925 | }, 1926 | "path-parse": { 1927 | "version": "1.0.7", 1928 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 1929 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", 1930 | "dev": true 1931 | }, 1932 | "picocolors": { 1933 | "version": "1.0.0", 1934 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", 1935 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", 1936 | "dev": true 1937 | }, 1938 | "picomatch": { 1939 | "version": "2.3.1", 1940 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 1941 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 1942 | "dev": true 1943 | }, 1944 | "pify": { 1945 | "version": "2.3.0", 1946 | "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", 1947 | "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", 1948 | "dev": true 1949 | }, 1950 | "pinkie": { 1951 | "version": "2.0.4", 1952 | "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", 1953 | "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", 1954 | "dev": true 1955 | }, 1956 | "pinkie-promise": { 1957 | "version": "2.0.1", 1958 | "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", 1959 | "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", 1960 | "dev": true, 1961 | "requires": { 1962 | "pinkie": "^2.0.0" 1963 | } 1964 | }, 1965 | "pkg-dir": { 1966 | "version": "4.2.0", 1967 | "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", 1968 | "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", 1969 | "dev": true, 1970 | "requires": { 1971 | "find-up": "^4.0.0" 1972 | } 1973 | }, 1974 | "postcss": { 1975 | "version": "8.4.14", 1976 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", 1977 | "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", 1978 | "dev": true, 1979 | "requires": { 1980 | "nanoid": "^3.3.4", 1981 | "picocolors": "^1.0.0", 1982 | "source-map-js": "^1.0.2" 1983 | } 1984 | }, 1985 | "readdirp": { 1986 | "version": "3.6.0", 1987 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", 1988 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", 1989 | "dev": true, 1990 | "requires": { 1991 | "picomatch": "^2.2.1" 1992 | } 1993 | }, 1994 | "resolve": { 1995 | "version": "1.22.1", 1996 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", 1997 | "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", 1998 | "dev": true, 1999 | "requires": { 2000 | "is-core-module": "^2.9.0", 2001 | "path-parse": "^1.0.7", 2002 | "supports-preserve-symlinks-flag": "^1.0.0" 2003 | } 2004 | }, 2005 | "ress": { 2006 | "version": "5.0.2", 2007 | "resolved": "https://registry.npmjs.org/ress/-/ress-5.0.2.tgz", 2008 | "integrity": "sha512-oHBtOWo/Uc8SzQMbQNIKTcgi8wKmAs7IlNlRywmXudbOtF+c27FlOIq7tnwLDVcTywe6JXYo1pDXHO6kABwNYA==" 2009 | }, 2010 | "rollup": { 2011 | "version": "2.75.7", 2012 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.75.7.tgz", 2013 | "integrity": "sha512-VSE1iy0eaAYNCxEXaleThdFXqZJ42qDBatAwrfnPlENEZ8erQ+0LYX4JXOLPceWfZpV1VtZwZ3dFCuOZiSyFtQ==", 2014 | "dev": true, 2015 | "requires": { 2016 | "fsevents": "~2.3.2" 2017 | } 2018 | }, 2019 | "sass": { 2020 | "version": "1.53.0", 2021 | "resolved": "https://registry.npmjs.org/sass/-/sass-1.53.0.tgz", 2022 | "integrity": "sha512-zb/oMirbKhUgRQ0/GFz8TSAwRq2IlR29vOUJZOx0l8sV+CkHUfHa4u5nqrG+1VceZp7Jfj59SVW9ogdhTvJDcQ==", 2023 | "dev": true, 2024 | "requires": { 2025 | "chokidar": ">=3.0.0 <4.0.0", 2026 | "immutable": "^4.0.0", 2027 | "source-map-js": ">=0.6.2 <2.0.0" 2028 | } 2029 | }, 2030 | "semver": { 2031 | "version": "6.3.0", 2032 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", 2033 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", 2034 | "dev": true 2035 | }, 2036 | "source-map-js": { 2037 | "version": "1.0.2", 2038 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", 2039 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", 2040 | "dev": true 2041 | }, 2042 | "strip-outer": { 2043 | "version": "1.0.1", 2044 | "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", 2045 | "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", 2046 | "dev": true, 2047 | "requires": { 2048 | "escape-string-regexp": "^1.0.2" 2049 | } 2050 | }, 2051 | "supports-preserve-symlinks-flag": { 2052 | "version": "1.0.0", 2053 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 2054 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", 2055 | "dev": true 2056 | }, 2057 | "three": { 2058 | "version": "0.141.0", 2059 | "resolved": "https://registry.npmjs.org/three/-/three-0.141.0.tgz", 2060 | "integrity": "sha512-JaSDAPWuk4RTzG5BYRQm8YZbERUxTfTDVouWgHMisS2to4E5fotMS9F2zPFNOIJyEFTTQDDKPpsgZVThKU3pXA==" 2061 | }, 2062 | "to-regex-range": { 2063 | "version": "5.0.1", 2064 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 2065 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 2066 | "dev": true, 2067 | "requires": { 2068 | "is-number": "^7.0.0" 2069 | } 2070 | }, 2071 | "trim-repeated": { 2072 | "version": "1.0.0", 2073 | "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", 2074 | "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", 2075 | "dev": true, 2076 | "requires": { 2077 | "escape-string-regexp": "^1.0.2" 2078 | } 2079 | }, 2080 | "tslib": { 2081 | "version": "2.4.0", 2082 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", 2083 | "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", 2084 | "dev": true 2085 | }, 2086 | "typescript": { 2087 | "version": "4.7.4", 2088 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", 2089 | "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", 2090 | "dev": true 2091 | }, 2092 | "universalify": { 2093 | "version": "0.1.2", 2094 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", 2095 | "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", 2096 | "dev": true 2097 | }, 2098 | "vite": { 2099 | "version": "2.9.12", 2100 | "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.12.tgz", 2101 | "integrity": "sha512-suxC36dQo9Rq1qMB2qiRorNJtJAdxguu5TMvBHOc/F370KvqAe9t48vYp+/TbPKRNrMh/J55tOUmkuIqstZaew==", 2102 | "dev": true, 2103 | "requires": { 2104 | "esbuild": "^0.14.27", 2105 | "fsevents": "~2.3.2", 2106 | "postcss": "^8.4.13", 2107 | "resolve": "^1.22.0", 2108 | "rollup": "^2.59.0" 2109 | } 2110 | }, 2111 | "vite-plugin-glsl": { 2112 | "version": "0.1.2", 2113 | "resolved": "https://registry.npmjs.org/vite-plugin-glsl/-/vite-plugin-glsl-0.1.2.tgz", 2114 | "integrity": "sha512-RFwoYn8EQFXp4YygIyt8Ex3bQE5/v5927AF0MAgrNfX4NRPlDAX12ciWlpVs4ObKLYro49fctnou4+fajO0FOg==", 2115 | "dev": true, 2116 | "requires": { 2117 | "@rollup/pluginutils": "^4.1.2", 2118 | "tslib": "^2.3.1" 2119 | } 2120 | }, 2121 | "wrappy": { 2122 | "version": "1.0.2", 2123 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 2124 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 2125 | "dev": true 2126 | } 2127 | } 2128 | } 2129 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ghost-veil", 3 | "homepage": "https://nemutas.github.io/ghost-veil/", 4 | "private": true, 5 | "version": "0.0.0", 6 | "scripts": { 7 | "start": "vite", 8 | "build": "tsc && vite build", 9 | "preview": "vite preview", 10 | "deploy": "npm run build && gh-pages -d dist" 11 | }, 12 | "devDependencies": { 13 | "@types/three": "^0.141.0", 14 | "gh-pages": "^4.0.0", 15 | "sass": "^1.53.0", 16 | "typescript": "^4.5.4", 17 | "vite": "^2.9.9", 18 | "vite-plugin-glsl": "^0.1.2" 19 | }, 20 | "dependencies": { 21 | "gsap": "^3.10.4", 22 | "lil-gui": "^0.16.1", 23 | "ress": "^5.0.2", 24 | "three": "^0.141.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /public/assets/images/wlop01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemutas/ghost-veil/5f667c511d61690afa3f2d9acdee153e2da9eb34/public/assets/images/wlop01.jpg -------------------------------------------------------------------------------- /public/assets/images/wlop02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemutas/ghost-veil/5f667c511d61690afa3f2d9acdee153e2da9eb34/public/assets/images/wlop02.jpg -------------------------------------------------------------------------------- /public/assets/images/wlop03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemutas/ghost-veil/5f667c511d61690afa3f2d9acdee153e2da9eb34/public/assets/images/wlop03.jpg -------------------------------------------------------------------------------- /public/assets/images/wlop04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemutas/ghost-veil/5f667c511d61690afa3f2d9acdee153e2da9eb34/public/assets/images/wlop04.jpg -------------------------------------------------------------------------------- /public/meta/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/home/Canvas.ts: -------------------------------------------------------------------------------- 1 | import * as THREE from 'three'; 2 | import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass'; 3 | import { GammaCorrectionShader } from 'three/examples/jsm/shaders/GammaCorrectionShader'; 4 | import { DomSyncPlane } from '../modules/scripts/DomSyncPlane'; 5 | import { TCanvas } from '../modules/scripts/extends/TCanvas'; 6 | import { Flowmap } from '../modules/scripts/flowmap/Flowmap'; 7 | import { Mouse2D } from '../modules/scripts/Mouse2d'; 8 | import planeFrag from './shader/planeFrag.glsl'; 9 | import planeVert from './shader/planeVert.glsl'; 10 | import { datas } from './store'; 11 | 12 | export class Canvas extends TCanvas { 13 | private dsPlanes: DomSyncPlane[] = [] 14 | private flowmap?: Flowmap 15 | private mousePos = new THREE.Vector2() 16 | private currentProgress = datas.scrollProgress.map(() => 0) 17 | private isLoaded: boolean[] = [] 18 | 19 | constructor(private parentNode: ParentNode) { 20 | super(parentNode) 21 | 22 | this.setScene() 23 | this.setPlanes() 24 | this.setPostprocessing() 25 | this.animate(this.update) 26 | } 27 | 28 | private setScene = () => { 29 | this.setOrthographicCamera(-1, 1, 1, -1, 0.01, 10) 30 | this.camera.position.z = 1 31 | } 32 | 33 | private setPlanes = () => { 34 | const elements = this.parentNode.querySelectorAll('.work__image') 35 | 36 | const elementObjects: { element: HTMLImageElement; texture: THREE.Texture }[] = [] 37 | 38 | elements.forEach((element, i) => { 39 | this.isLoaded.push(false) 40 | const texture = new THREE.TextureLoader().load(element.src, () => { 41 | this.isLoaded[i] = true 42 | }) 43 | texture.encoding = THREE.sRGBEncoding 44 | elementObjects.push({ element, texture }) 45 | }) 46 | 47 | const createShaderMaterial = (texture: THREE.Texture) => { 48 | return new THREE.ShaderMaterial({ 49 | uniforms: { 50 | u_texture: { value: texture }, 51 | u_progress: { value: 0 } 52 | }, 53 | vertexShader: planeVert, 54 | fragmentShader: planeFrag 55 | }) 56 | } 57 | 58 | elementObjects.forEach(obj => { 59 | const dsPlane = new DomSyncPlane(obj.element, createShaderMaterial(obj.texture)) 60 | this.scene.add(dsPlane.mesh) 61 | this.dsPlanes.push(dsPlane) 62 | }) 63 | } 64 | 65 | private setPostprocessing = () => { 66 | const sRGBCorrectionPass = new ShaderPass(GammaCorrectionShader) 67 | this.effectComposer.addPass(sRGBCorrectionPass) 68 | 69 | this.flowmap = new Flowmap(this.renderer, this.size.width, this.size.height) 70 | this.effectComposer.addPass(this.flowmap!.pass) 71 | } 72 | 73 | private update = () => { 74 | if (!this.isLoaded.every(x => x)) return 75 | 76 | this.dsPlanes.forEach((plane, i) => { 77 | plane.update() 78 | this.currentProgress[i] = THREE.MathUtils.lerp(this.currentProgress[i], datas.scrollProgress[i], 0.01) 79 | plane.material.uniforms.u_progress.value = this.currentProgress[i] 80 | }) 81 | 82 | const mousePosition = Mouse2D.instance.normalizedPosition 83 | this.flowmap?.update(this.mousePos.set(mousePosition.x, -mousePosition.y)) 84 | } 85 | 86 | disposeCanvas = () => { 87 | this.dispose() 88 | Mouse2D.instance.dispose() 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/home/Home.ts: -------------------------------------------------------------------------------- 1 | import gsap from 'gsap'; 2 | import ScrollTrigger from 'gsap/ScrollTrigger'; 3 | import { lerp } from '../modules/scripts/math'; 4 | import { MouseWheel } from '../modules/scripts/MouseWheel'; 5 | import { Canvas } from './Canvas'; 6 | import { datas } from './store'; 7 | 8 | gsap.registerPlugin(ScrollTrigger) 9 | 10 | class Home { 11 | private parentElement: HTMLElement 12 | private scrollElement: HTMLDivElement 13 | private imageElements: HTMLImageElement[] 14 | 15 | private scrollAnimeId?: number 16 | private scrollCurrent = 0 17 | private scrollTarget = 0 18 | 19 | private gsapTimelines: gsap.core.Timeline[] = [] 20 | 21 | private canvas: Canvas 22 | 23 | constructor() { 24 | this.parentElement = document.querySelector('.home-main')! 25 | this.scrollElement = document.querySelector('.home-contents')! 26 | this.imageElements = Array.from(document.querySelectorAll('.work__image')) 27 | 28 | this.setStoreDatas() 29 | this.setSmoothScroll() 30 | this.setLifecycle() 31 | 32 | window.addEventListener('DOMContentLoaded', () => { 33 | this.setGsapAnimation() 34 | }) 35 | 36 | this.canvas = new Canvas(this.parentElement) 37 | } 38 | 39 | private setStoreDatas = () => { 40 | datas.scrollProgress = this.imageElements.map(() => 0) 41 | } 42 | 43 | private setSmoothScroll = () => { 44 | const wheelEvent = new MouseWheel(this.scrollElement) 45 | wheelEvent.callback = ({ y: directionY }) => { 46 | const dy = directionY === 'none' ? 0 : directionY === 'increase' ? 300 : -300 47 | let scroll = this.scrollElement.scrollLeft + dy 48 | scroll = Math.min(scroll, this.scrollElement.scrollWidth - this.scrollElement.offsetWidth) 49 | this.scrollTarget = scroll 50 | } 51 | 52 | this.scrollElement.onscroll = () => { 53 | if (Math.abs(this.scrollCurrent - this.scrollTarget) < 1) { 54 | this.scrollCurrent = this.scrollElement.scrollLeft 55 | this.scrollTarget = this.scrollElement.scrollLeft 56 | } 57 | } 58 | 59 | const anime = () => { 60 | this.scrollAnimeId = requestAnimationFrame(anime) 61 | 62 | this.scrollCurrent = lerp(this.scrollCurrent, this.scrollTarget, 0.08) 63 | this.scrollElement.scrollTo({ left: this.scrollCurrent }) 64 | } 65 | 66 | anime() 67 | } 68 | 69 | private setGsapAnimation = () => { 70 | this.gsapTimelines = this.imageElements.map((el, i) => { 71 | const tl = gsap.timeline({ 72 | scrollTrigger: { 73 | scroller: this.scrollElement, 74 | trigger: el, 75 | scrub: 0.5, 76 | start: '0 100%', 77 | end: '0 51%', 78 | horizontal: true, 79 | once: true, 80 | onUpdate: self => (datas.scrollProgress[i] = self.progress) 81 | } 82 | }) 83 | tl.set(el, { '--clip-height': '0%' }) 84 | tl.to(el, { '--clip-height': '100%', duration: 1, ease: 'none' }) 85 | return tl 86 | }) 87 | } 88 | 89 | private setLifecycle = () => { 90 | window.addEventListener('beforeunload', () => { 91 | this.dispose() 92 | }) 93 | } 94 | 95 | private dispose = () => { 96 | this.scrollAnimeId && cancelAnimationFrame(this.scrollAnimeId) 97 | 98 | this.gsapTimelines.forEach(tl => { 99 | tl.scrollTrigger?.kill() 100 | tl.kill() 101 | }) 102 | 103 | this.canvas.disposeCanvas() 104 | } 105 | } 106 | 107 | new Home() 108 | -------------------------------------------------------------------------------- /src/home/home.scss: -------------------------------------------------------------------------------- 1 | @import '../modules/styles/common.scss'; 2 | @import '../modules/styles/mixin/media.scss'; 3 | 4 | .home-main { 5 | position: relative; 6 | width: 100%; 7 | height: 100%; 8 | background-color: #f0f0f0; 9 | 10 | display: flex; 11 | justify-content: center; 12 | align-items: center; 13 | } 14 | 15 | .home-contents { 16 | position: relative; 17 | width: fit-content; 18 | height: 100%; 19 | 20 | padding: 5rem 10rem; 21 | display: flex; 22 | flex-direction: row; 23 | align-items: center; 24 | column-gap: 10rem; 25 | 26 | overflow: auto; 27 | } 28 | 29 | .top-text { 30 | min-width: clamp(10vw, 40%, 50vw); 31 | 32 | padding: 5rem; 33 | display: flex; 34 | flex-direction: column; 35 | justify-content: center; 36 | align-items: center; 37 | 38 | &__contents { 39 | &__title { 40 | white-space: nowrap; 41 | font-size: 8rem; 42 | } 43 | &__desc { 44 | font-size: 3rem; 45 | } 46 | } 47 | } 48 | 49 | .works { 50 | counter-reset: section; 51 | 52 | height: 70rem; 53 | 54 | @include md() { 55 | height: 70%; 56 | } 57 | 58 | display: flex; 59 | flex-direction: row; 60 | align-items: center; 61 | column-gap: 10rem; 62 | 63 | list-style: none; 64 | } 65 | 66 | .work { 67 | --clip-height: 0%; 68 | 69 | height: 100%; 70 | 71 | display: flex; 72 | align-items: flex-end; 73 | flex-direction: row; 74 | column-gap: 5rem; 75 | 76 | &__image { 77 | height: 100%; 78 | object-fit: cover; 79 | clip-path: polygon(0 0, 100% 0, 100% var(--clip-height), 0 var(--clip-height)); 80 | } 81 | 82 | &__desc { 83 | min-height: 35%; 84 | 85 | display: flex; 86 | flex-direction: column; 87 | row-gap: 1rem; 88 | 89 | &__title { 90 | font-size: max(20px, 3rem); 91 | 92 | &::before { 93 | counter-increment: section; 94 | font-family: 'Roboto Mono', monospace; 95 | content: counter(section) '.'; 96 | margin-right: 0.3em; 97 | } 98 | } 99 | 100 | &__list { 101 | font-size: max(15px, 2.2rem); 102 | list-style: disc; 103 | padding-left: 1.3em; 104 | 105 | display: flex; 106 | flex-direction: column; 107 | row-gap: 0.2em; 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/home/shader/planeFrag.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D u_texture; 2 | uniform float u_progress; 3 | varying vec2 v_uv; 4 | 5 | #include '../../modules/scripts/glsl/cnoise21.glsl' 6 | 7 | void main() { 8 | vec4 tex = texture2D(u_texture, v_uv); 9 | float gray = (tex.r + tex.g + tex.b) / 3.0; 10 | gray *= 0.5; 11 | 12 | float speed = (cnoise21(v_uv * 10.0) + 1.0) * 0.5; // 0 - 1 13 | speed = speed * (1.0 - 0.2) + 0.2; // 0.2 - 1 14 | float edge = pow(1.0 - u_progress, speed); 15 | float a = step(edge, v_uv.y); 16 | 17 | gl_FragColor = vec4(vec3(gray), a); 18 | } -------------------------------------------------------------------------------- /src/home/shader/planeVert.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 v_uv; 2 | 3 | void main() { 4 | v_uv = uv; 5 | gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); 6 | } -------------------------------------------------------------------------------- /src/home/store.ts: -------------------------------------------------------------------------------- 1 | export const datas: { scrollProgress: number[] } = { 2 | scrollProgress: [] 3 | } 4 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite App 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 | 16 |
17 |
18 |

Ghost Veil

19 |
20 | Ghost Veil is an effect of 'threejs plane' overlaid on 'dom image'.
21 | The images used are excellent work by 22 | WLOP. 23 |
24 |
25 |
26 | 27 |
    28 |
  • 29 | 30 |
    31 |

    Concepts

    32 |
      33 |
    • Dom Sync
    • 34 |
    • Horizontal Scroll
    • 35 |
    • Motion Effect
    • 36 |
    37 |
    38 |
  • 39 |
  • 40 | 41 |
    42 |

    SNS

    43 | 49 |
    50 |
  • 51 |
  • 52 | 53 |
    54 |

    Skills

    55 |
      56 |
    • Three.js
    • 57 |
    • TypeScript
    • 58 |
    • GLSL
    • 59 |
    • GSAP
    • 60 |
    61 |
    62 |
  • 63 |
  • 64 | 65 |
    66 |

    References

    67 | 73 |
    74 |
  • 75 |
76 |
77 |
78 | 79 | 80 | -------------------------------------------------------------------------------- /src/modules/scripts/DomSyncPlane.ts: -------------------------------------------------------------------------------- 1 | import * as THREE from 'three'; 2 | 3 | export class DomSyncPlane { 4 | public mesh: THREE.Mesh 5 | 6 | constructor(private element: HTMLElement, public material: T) { 7 | this.mesh = this.createMesh() 8 | } 9 | 10 | private createMesh = () => { 11 | const geometry = new THREE.PlaneGeometry(2, 2) 12 | return new THREE.Mesh(geometry, this.material) 13 | } 14 | 15 | update = () => { 16 | const rect = this.element.getBoundingClientRect() 17 | const normalizeWidth = rect.width / window.innerWidth 18 | const normalizeHeight = rect.height / window.innerHeight 19 | const centerX = (rect.width / 2 + rect.left - window.innerWidth / 2) * 2 20 | const centerY = (window.innerHeight / 2 - (rect.height / 2 + rect.top)) * 2 21 | const normalizeCenterX = centerX / window.innerWidth 22 | const normalizeCenterY = centerY / window.innerHeight 23 | 24 | this.mesh.scale.set(normalizeWidth, normalizeHeight, 1) 25 | this.mesh.position.set(normalizeCenterX, normalizeCenterY, 0) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/modules/scripts/Mouse2d.ts: -------------------------------------------------------------------------------- 1 | export class Mouse2D { 2 | private static _instance: Mouse2D | null 3 | private _relativePosition: [number, number] = [0, 0] 4 | 5 | private constructor() { 6 | window.addEventListener('mousemove', this._handleMouseMove) 7 | } 8 | 9 | static get instance() { 10 | if (!this._instance) { 11 | this._instance = new Mouse2D() 12 | } 13 | return this._instance 14 | } 15 | 16 | private _handleMouseMove = (e: MouseEvent) => { 17 | this._relativePosition = [e.clientX, e.clientY] 18 | } 19 | 20 | get normalizedPosition() { 21 | const x = (this._relativePosition[0] / window.innerWidth) * 2 - 1 22 | const y = (this._relativePosition[1] / window.innerHeight) * 2 - 1 23 | return { x, y } 24 | } 25 | 26 | get relativePosition() { 27 | return { x: this._relativePosition[0], y: this._relativePosition[1] } 28 | } 29 | 30 | get absolutePosition() { 31 | const x = this._relativePosition[0] + window.pageXOffset 32 | const y = this._relativePosition[1] + window.pageYOffset 33 | return { x, y } 34 | } 35 | 36 | dispose = () => { 37 | window.removeEventListener('mousemove', this._handleMouseMove) 38 | Mouse2D._instance = null 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/modules/scripts/MouseWheel.ts: -------------------------------------------------------------------------------- 1 | export type WheelDirection = 'increase' | 'decrease' | 'none' 2 | 3 | export class MouseWheel { 4 | private prevWheel = { x: 0, y: 0, z: 0 } 5 | callback?: (direction: { x: WheelDirection; y: WheelDirection; z: WheelDirection }) => void 6 | 7 | constructor(private eventTarget?: HTMLElement) { 8 | if (eventTarget) { 9 | eventTarget.onwheel = this.handleWheel 10 | } else { 11 | window.addEventListener('wheel', this.handleWheel) 12 | } 13 | } 14 | 15 | private handleWheel = (e: WheelEvent) => { 16 | const direction: { x: WheelDirection; y: WheelDirection; z: WheelDirection } = { x: 'none', y: 'none', z: 'none' } 17 | 18 | const absDeltaX = Math.abs(e.deltaX) 19 | if (0 <= absDeltaX - this.prevWheel.x) direction.x = 0 < e.deltaX ? 'increase' : 'decrease' 20 | this.prevWheel.x = absDeltaX 21 | 22 | const absDeltaY = Math.abs(e.deltaY) 23 | if (0 <= absDeltaY - this.prevWheel.y) direction.y = 0 < e.deltaY ? 'increase' : 'decrease' 24 | this.prevWheel.y = absDeltaY 25 | 26 | const absDeltaZ = Math.abs(e.deltaZ) 27 | if (0 <= absDeltaZ - this.prevWheel.z) direction.z = 0 < e.deltaZ ? 'increase' : 'decrease' 28 | this.prevWheel.z = absDeltaZ 29 | 30 | this.callback && this.callback(direction) 31 | } 32 | 33 | dispose = () => { 34 | if (!this.eventTarget) { 35 | window.removeEventListener('wheel', this.handleWheel) 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/modules/scripts/extends/TCanvas.ts: -------------------------------------------------------------------------------- 1 | import GUI from 'lil-gui'; 2 | import * as THREE from 'three'; 3 | import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'; 4 | import Stats from 'three/examples/jsm/libs/stats.module'; 5 | import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer'; 6 | import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass'; 7 | 8 | export abstract class TCanvas { 9 | private container: HTMLDivElement 10 | 11 | protected renderer: THREE.WebGLRenderer 12 | protected scene: THREE.Scene 13 | protected camera: THREE.Camera 14 | protected clock: THREE.Clock 15 | 16 | private _orbitControls?: OrbitControls 17 | private _gui?: GUI 18 | private enableOrbitControlsDamping = false 19 | private animeId?: number 20 | private composer?: EffectComposer 21 | private stats?: Stats 22 | 23 | constructor(parentNode: ParentNode, containerClassName = 'three-container') { 24 | let container: HTMLDivElement | null 25 | try { 26 | container = parentNode.querySelector(`.${containerClassName}`) 27 | if (!container) throw new Error(`undefind container: ${containerClassName}`) 28 | } catch (e) { 29 | console.error(e) 30 | throw e 31 | } 32 | 33 | this.container = container! 34 | 35 | const { renderer, scene, camera } = this.init() 36 | this.renderer = renderer 37 | this.scene = scene 38 | this.camera = camera 39 | 40 | this.clock = new THREE.Clock() 41 | 42 | this.addEvents() 43 | } 44 | 45 | // ------------------------------------------------------ 46 | // initialize 47 | private init = () => { 48 | const { width, height, aspect } = this.size 49 | // renderer 50 | const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }) 51 | renderer.setPixelRatio(window.devicePixelRatio) 52 | renderer.setSize(width, height) 53 | renderer.shadowMap.enabled = true 54 | renderer.outputEncoding = THREE.sRGBEncoding 55 | // append canvas element 56 | this.container.appendChild(renderer.domElement) 57 | // scene 58 | const scene = new THREE.Scene() 59 | // camera 60 | const camera = new THREE.PerspectiveCamera(50, aspect, 0.01, 1000) 61 | camera.position.set(0, 0, 5) 62 | 63 | return { renderer, scene, camera } 64 | } 65 | 66 | // ------------------------------------------------------ 67 | // utils 68 | protected get gui() { 69 | if (!this._gui) this._gui = new GUI() 70 | return this._gui 71 | } 72 | 73 | protected get size() { 74 | // const {clientWidth: width, clientHeight: height} = this.container 75 | const { innerWidth: width, innerHeight: height } = window 76 | const aspect = width / height 77 | return { width, height, aspect } 78 | } 79 | 80 | protected get effectComposer() { 81 | if (!this.composer) { 82 | this.composer = new EffectComposer(this.renderer) 83 | this.composer.addPass(new RenderPass(this.scene, this.camera)) 84 | } 85 | return this.composer 86 | } 87 | 88 | protected get orbitControls() { 89 | if (!this._orbitControls) this._orbitControls = new OrbitControls(this.camera, this.renderer.domElement) 90 | return this._orbitControls 91 | } 92 | 93 | protected setOrbitControlsDamping = (damping: number | false = 0.1) => { 94 | if (typeof damping === 'number') { 95 | this.orbitControls.enableDamping = true 96 | this.orbitControls.dampingFactor = damping 97 | } else { 98 | this.orbitControls.enableDamping = false 99 | this.orbitControls.dampingFactor = 0 100 | } 101 | this.enableOrbitControlsDamping = this.orbitControls.enableDamping 102 | } 103 | 104 | protected setPerspectiveCamera = (fov?: number, aspect?: number, near?: number, far?: number) => { 105 | this.camera = new THREE.PerspectiveCamera(fov, aspect, near, far) 106 | } 107 | 108 | protected setOrthographicCamera = ( 109 | left?: number, 110 | right?: number, 111 | top?: number, 112 | bottom?: number, 113 | near?: number, 114 | far?: number 115 | ) => { 116 | this.camera = new THREE.OrthographicCamera(left, right, top, bottom, near, far) 117 | } 118 | 119 | protected setStats = () => { 120 | if (!this.stats) { 121 | this.stats = Stats() 122 | this.container.appendChild(this.stats.dom) 123 | } 124 | } 125 | 126 | // ------------------------------------------------------ 127 | // helper 128 | protected setAxesHelper = (size?: number) => { 129 | const axesHelper = new THREE.AxesHelper(size) 130 | this.scene.add(axesHelper) 131 | } 132 | 133 | // ------------------------------------------------------ 134 | // event 135 | private addEvents = () => { 136 | window.addEventListener('resize', this.handleResize) 137 | } 138 | 139 | private handleResize = () => { 140 | const { width, height, aspect } = this.size 141 | 142 | if (this.camera instanceof THREE.PerspectiveCamera) { 143 | this.camera.aspect = aspect 144 | this.camera.updateProjectionMatrix() 145 | } 146 | 147 | this.renderer.setSize(width, height) 148 | this.composer?.setSize(width, height) 149 | this.render() 150 | } 151 | 152 | // ------------------------------------------------------ 153 | // lifecycle 154 | protected animate = (callback?: () => void) => { 155 | this.animeId = requestAnimationFrame(this.animate.bind(this, callback)) 156 | 157 | this.enableOrbitControlsDamping && this._orbitControls?.update() 158 | this.stats && this.stats.update() 159 | 160 | callback && callback() 161 | 162 | this.render() 163 | } 164 | 165 | protected render = () => { 166 | if (!this.composer) { 167 | this.renderer.render(this.scene, this.camera) 168 | } else { 169 | this.composer.render() 170 | } 171 | } 172 | 173 | dispose = () => { 174 | this.stats && this.container.removeChild(this.stats.dom) 175 | this._gui && this._gui.destroy() 176 | 177 | this.animeId && cancelAnimationFrame(this.animeId) 178 | window.removeEventListener('resize', this.handleResize) 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /src/modules/scripts/flowmap/Flowmap.ts: -------------------------------------------------------------------------------- 1 | import * as THREE from 'three'; 2 | import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass'; 3 | import flowmapFrag from './flowmapFrag.glsl'; 4 | import flowmapVert from './flowmapVert.glsl'; 5 | import { Simulator } from './simulator'; 6 | 7 | export class Flowmap { 8 | public pass: ShaderPass 9 | private simulator: Simulator 10 | private centeredMousePos = new THREE.Vector2() 11 | 12 | private datas = { 13 | power: 0.3, 14 | range: 0.1, 15 | viscosity: 0.04, 16 | isPixel: false, 17 | pixel: 20 18 | } 19 | 20 | constructor(gl: THREE.WebGLRenderer, width: number, height: number) { 21 | this.pass = this.createPass(width / height) 22 | this.simulator = new Simulator(gl, width, height) 23 | } 24 | 25 | private createPass = (aspect: number) => { 26 | const shader: THREE.Shader = { 27 | uniforms: { 28 | tDiffuse: { value: null }, 29 | u_motionTexture: { value: null }, 30 | u_powar: { value: this.datas.power }, 31 | u_aspect: { value: aspect }, 32 | u_pixelMode: { value: this.datas.isPixel }, 33 | u_pixel: { value: this.datas.pixel } 34 | }, 35 | vertexShader: flowmapVert, 36 | fragmentShader: flowmapFrag 37 | } 38 | 39 | return new ShaderPass(shader) 40 | } 41 | 42 | update = (mouse: THREE.Vector2) => { 43 | this.centeredMousePos.set((mouse.x + 1) / 2, (mouse.y + 1) / 2) 44 | this.simulator.compute(this.centeredMousePos, this.datas.range, this.datas.viscosity) 45 | 46 | this.pass.uniforms.u_motionTexture.value = this.simulator.texture 47 | this.pass.uniforms.u_powar.value = this.datas.power 48 | this.pass.uniforms.u_pixelMode.value = this.datas.isPixel 49 | this.pass.uniforms.u_pixel.value = this.datas.pixel 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/modules/scripts/flowmap/Simulator.ts: -------------------------------------------------------------------------------- 1 | import * as THREE from 'three'; 2 | import { GPUComputationRenderer, Variable } from 'three/examples/jsm/misc/GPUComputationRenderer'; 3 | import fragmentShader from './simulatorFrag.glsl'; 4 | 5 | export class Simulator { 6 | private _gpuCompute 7 | private _variables: Variable[] = [] 8 | private _material = new THREE.ShaderMaterial() 9 | 10 | constructor(gl: THREE.WebGLRenderer, private _width: number, private _height: number) { 11 | this._gpuCompute = new GPUComputationRenderer(this._width, this._height, gl) 12 | this._setMotionTexture() 13 | this._setVariableDependencies() 14 | this._gpuCompute.init() 15 | } 16 | 17 | private _setMotionTexture = () => { 18 | // set the default position to texture 19 | const dataTexture = this._gpuCompute.createTexture() 20 | const theArray = dataTexture.image.data 21 | 22 | for (let i = 0; i < theArray.length; i += 4) { 23 | theArray[i + 0] = 0 24 | theArray[i + 1] = 0 25 | theArray[i + 2] = 0 26 | theArray[i + 3] = 0 27 | } 28 | 29 | // set fragment shader 30 | const variable = this._gpuCompute.addVariable('motionTexture', fragmentShader, dataTexture) 31 | variable.wrapS = THREE.RepeatWrapping 32 | variable.wrapT = THREE.RepeatWrapping 33 | 34 | // set uniforms 35 | this._material = variable.material 36 | this._material.uniforms['u_defaultTexture'] = { value: dataTexture.clone() } 37 | this._material.uniforms['u_mouse_pos'] = { value: new THREE.Vector2() } 38 | this._material.uniforms['u_range'] = { value: 0 } 39 | this._material.uniforms['u_viscosity'] = { value: 0 } 40 | 41 | // add variable 42 | this._variables.push(variable) 43 | } 44 | 45 | private _setVariableDependencies = () => { 46 | this._variables.forEach(variable => { 47 | this._gpuCompute.setVariableDependencies(variable, this._variables) 48 | }) 49 | // it means. 50 | // this._gpuCompute.setVariableDependencies(positionVariable, [positionVariable, ...]) 51 | } 52 | 53 | compute = (mouse: THREE.Vector2, range: number, viscosity: number) => { 54 | this._material.uniforms.u_mouse_pos.value.copy(mouse) 55 | this._material.uniforms.u_range.value = range 56 | this._material.uniforms.u_viscosity.value = viscosity 57 | this._gpuCompute.compute() 58 | } 59 | 60 | get texture() { 61 | const variable = this._variables.find(v => v.name === 'motionTexture')! 62 | const target = this._gpuCompute.getCurrentRenderTarget(variable) as THREE.WebGLRenderTarget 63 | return target.texture 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/modules/scripts/flowmap/flowmapFrag.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tDiffuse; 2 | uniform sampler2D u_motionTexture; 3 | uniform float u_powar; 4 | uniform float u_aspect; 5 | uniform bool u_pixelMode; 6 | uniform float u_pixel; 7 | varying vec2 v_uv; 8 | 9 | void main() { 10 | vec2 st = v_uv; 11 | if (u_pixelMode) { 12 | vec2 pixel = vec2(u_aspect * u_pixel, u_pixel); 13 | st = floor(v_uv * pixel) / pixel; 14 | } 15 | vec4 motionTexture = texture2D(u_motionTexture, st); 16 | 17 | vec2 distortion = -motionTexture.xy * u_powar; 18 | vec2 uv = v_uv + distortion; 19 | vec4 tex = texture2D(tDiffuse, uv); 20 | 21 | float a = smoothstep(0.05, 0.0, length(distortion)); 22 | a *= tex.a; 23 | 24 | gl_FragColor = vec4(tex.rgb * a, a); 25 | } -------------------------------------------------------------------------------- /src/modules/scripts/flowmap/flowmapVert.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 v_uv; 2 | 3 | void main() { 4 | v_uv = uv; 5 | gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); 6 | } -------------------------------------------------------------------------------- /src/modules/scripts/flowmap/simulatorFrag.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D u_defaultTexture; 2 | uniform vec2 u_mouse_pos; 3 | uniform float u_range; 4 | uniform float u_viscosity; 5 | 6 | vec2 lerp(vec2 original, vec2 target, float alpha) { 7 | return original * alpha + target * (1.0 - alpha); 8 | } 9 | 10 | void main() { 11 | vec2 uv = gl_FragCoord.xy / resolution.xy; 12 | vec4 tmp = texture2D(motionTexture, uv); 13 | vec4 defTmp = texture2D(u_defaultTexture, uv); 14 | 15 | float dist = 1.0 - smoothstep(0.0, u_range, distance(u_mouse_pos, uv)); 16 | 17 | if(0.0 < dist) { 18 | vec2 speed = u_mouse_pos - tmp.zw; 19 | vec2 distortion = speed * dist * 5.0; 20 | tmp.xy += distortion; 21 | } 22 | 23 | vec4 result; 24 | result.xy = lerp(defTmp.xy, tmp.xy, u_viscosity); 25 | result.xy = clamp(result.xy, -1.0, 1.0); 26 | result.zw = u_mouse_pos; 27 | 28 | gl_FragColor = result; 29 | } -------------------------------------------------------------------------------- /src/modules/scripts/glsl/cnoise21.glsl: -------------------------------------------------------------------------------- 1 | // Classic Perlin 2D Noise 2 | // by Stefan Gustavson 3 | // 4 | vec2 fade(vec2 t) {return t*t*t*(t*(t*6.0-15.0)+10.0);} 5 | vec4 permute(vec4 x){return mod(((x*34.0)+1.0)*x, 289.0);} 6 | 7 | float cnoise21(vec2 P){ 8 | vec4 Pi = floor(P.xyxy) + vec4(0.0, 0.0, 1.0, 1.0); 9 | vec4 Pf = fract(P.xyxy) - vec4(0.0, 0.0, 1.0, 1.0); 10 | Pi = mod(Pi, 289.0); // To avoid truncation effects in permutation 11 | vec4 ix = Pi.xzxz; 12 | vec4 iy = Pi.yyww; 13 | vec4 fx = Pf.xzxz; 14 | vec4 fy = Pf.yyww; 15 | vec4 i = permute(permute(ix) + iy); 16 | vec4 gx = 2.0 * fract(i * 0.0243902439) - 1.0; // 1/41 = 0.024... 17 | vec4 gy = abs(gx) - 0.5; 18 | vec4 tx = floor(gx + 0.5); 19 | gx = gx - tx; 20 | vec2 g00 = vec2(gx.x,gy.x); 21 | vec2 g10 = vec2(gx.y,gy.y); 22 | vec2 g01 = vec2(gx.z,gy.z); 23 | vec2 g11 = vec2(gx.w,gy.w); 24 | vec4 norm = 1.79284291400159 - 0.85373472095314 * 25 | vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11)); 26 | g00 *= norm.x; 27 | g01 *= norm.y; 28 | g10 *= norm.z; 29 | g11 *= norm.w; 30 | float n00 = dot(g00, vec2(fx.x, fy.x)); 31 | float n10 = dot(g10, vec2(fx.y, fy.y)); 32 | float n01 = dot(g01, vec2(fx.z, fy.z)); 33 | float n11 = dot(g11, vec2(fx.w, fy.w)); 34 | vec2 fade_xy = fade(Pf.xy); 35 | vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x); 36 | float n_xy = mix(n_x.x, n_x.y, fade_xy.y); 37 | return 2.3 * n_xy; 38 | } -------------------------------------------------------------------------------- /src/modules/scripts/glsl/random.glsl: -------------------------------------------------------------------------------- 1 | float random11(float n){return fract(sin(n) * 43758.5453123);} -------------------------------------------------------------------------------- /src/modules/scripts/math.ts: -------------------------------------------------------------------------------- 1 | export const lerp = (current: number, target: number, a: number) => { 2 | return current * (1 - a) + target * a 3 | } 4 | -------------------------------------------------------------------------------- /src/modules/scripts/utils.ts: -------------------------------------------------------------------------------- 1 | export const publicPath = (path: string) => { 2 | path.startsWith('/') && (path = path.substring(1)) 3 | return import.meta.env.BASE_URL + path 4 | } 5 | -------------------------------------------------------------------------------- /src/modules/styles/common.scss: -------------------------------------------------------------------------------- 1 | @use 'ress'; 2 | @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300&family=Roboto+Mono:wght@300&display=swap'); 3 | 4 | html { 5 | font-family: 'Poppins', sans-serif; 6 | font-size: clamp(5px, calc(100vw / 1920 * 10), 15px); 7 | color: #1e1e1e; 8 | width: 100%; 9 | height: 100%; 10 | overflow: hidden; 11 | } 12 | 13 | body { 14 | position: relative; 15 | width: 100%; 16 | height: 100%; 17 | } 18 | 19 | .three-container { 20 | position: fixed; 21 | top: 0; 22 | left: 0; 23 | width: 100%; 24 | height: 100%; 25 | pointer-events: none; 26 | z-index: 10; 27 | } 28 | 29 | a { 30 | text-decoration: none; 31 | color: #d00; 32 | } 33 | -------------------------------------------------------------------------------- /src/modules/styles/mixin/media.scss: -------------------------------------------------------------------------------- 1 | @mixin md { 2 | @media screen and (min-width: 768px) { 3 | @content; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/types/glsl.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.glsl' { 2 | const value: string 3 | export default value 4 | } 5 | -------------------------------------------------------------------------------- /src/types/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": ["ESNext", "DOM"], 7 | "moduleResolution": "Node", 8 | "strict": true, 9 | "sourceMap": true, 10 | "resolveJsonModule": true, 11 | "esModuleInterop": true, 12 | "noEmit": true, 13 | "noUnusedLocals": true, 14 | "noUnusedParameters": true, 15 | "noImplicitReturns": true, 16 | "skipLibCheck": true 17 | }, 18 | "include": ["src"] 19 | } 20 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import { defineConfig } from 'vite'; 3 | import glsl from 'vite-plugin-glsl'; 4 | 5 | export default defineConfig({ 6 | root: './src', 7 | base: '/ghost-veil/', 8 | publicDir: '../public', 9 | plugins: [glsl()], 10 | build: { 11 | rollupOptions: { 12 | input: { 13 | home: path.resolve(__dirname, './src/index.html') 14 | } 15 | }, 16 | outDir: '../dist', 17 | emptyOutDir: true 18 | } 19 | }) 20 | --------------------------------------------------------------------------------