feat: integrate Draco compression for GLB models and implement encryption for secure loading
- Added DRACOLoader to starter.js for handling compressed GLB models. - Created a createGltfLoader function to initialize GLTFLoader with DRACOLoader. - Implemented dracoModels plugin in vite.config.js to compress GLB models during build. - Introduced model_loader.js for loading encrypted GLB models with WebCrypto. - Developed encryptModels plugin to encrypt GLB files, ensuring no clear models are exposed. - Updated asset handling to remove uncompressed GLB files post-build.
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
# Il configuratore è servito dal backend Laravel (/configuratore/) e usa l'API sulla stessa origine:
|
# Il configuratore è servito dal backend Laravel (/configuratore/) e usa l'API sulla stessa origine:
|
||||||
# non serve configurare nulla. Solo per puntare a un'API su un altro dominio:
|
# non serve configurare nulla. Solo per puntare a un'API su un altro dominio:
|
||||||
# VITE_PREVENTIVI_API_BASE=https://altro-dominio.example/api
|
# VITE_PREVENTIVI_API_BASE=https://altro-dominio.example/api
|
||||||
|
MODELS_KEY=e03163a53325b29a83a4e84dd80af8e7ed3b15791a3e4563d75db4457cb9cea0
|
||||||
@@ -1,3 +1,10 @@
|
|||||||
# Opzionale: il configuratore usa di default l'API sulla stessa origine da cui è servito
|
# Opzionale: il configuratore usa di default l'API sulla stessa origine da cui è servito
|
||||||
# (/configuratore/ sul backend Laravel). Impostare solo per un'API su un dominio diverso.
|
# (/configuratore/ sul backend Laravel). Impostare solo per un'API su un dominio diverso.
|
||||||
# VITE_PREVENTIVI_API_BASE=https://preventivi.kreiosinfissi.it/api
|
# VITE_PREVENTIVI_API_BASE=https://preventivi.kreiosinfissi.it/api
|
||||||
|
|
||||||
|
# (Cifratura modelli NON attiva per ora, vedi vite-plugins/encrypt-models.js.)
|
||||||
|
# Chiave AES-256 per cifrare i modelli 3D (64 caratteri esadecimali). Generarla una volta con
|
||||||
|
# openssl rand -hex 32
|
||||||
|
# e tenerla fissa: se cambia, cambiano gli URL dei modelli e i browser li riscaricano.
|
||||||
|
# Se manca, ogni build usa una chiave casuale.
|
||||||
|
# MODELS_KEY=
|
||||||
|
|||||||
@@ -22,6 +22,10 @@
|
|||||||
"vite-plugin-static-copy": "^2.3.0"
|
"vite-plugin-static-copy": "^2.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@gltf-transform/core": "^4.5.1",
|
||||||
|
"@gltf-transform/extensions": "^4.5.1",
|
||||||
|
"@gltf-transform/functions": "^4.5.1",
|
||||||
|
"draco3dgltf": "^1.5.9",
|
||||||
"vite": "^6.2.4",
|
"vite": "^6.2.4",
|
||||||
"vite-plugin-minify": "^2.1.0"
|
"vite-plugin-minify": "^2.1.0"
|
||||||
},
|
},
|
||||||
|
|||||||
Generated
+448
@@ -30,6 +30,18 @@ importers:
|
|||||||
specifier: ^2.3.0
|
specifier: ^2.3.0
|
||||||
version: 2.3.2(vite@6.4.5(terser@5.51.2))
|
version: 2.3.2(vite@6.4.5(terser@5.51.2))
|
||||||
devDependencies:
|
devDependencies:
|
||||||
|
'@gltf-transform/core':
|
||||||
|
specifier: ^4.5.1
|
||||||
|
version: 4.5.1
|
||||||
|
'@gltf-transform/extensions':
|
||||||
|
specifier: ^4.5.1
|
||||||
|
version: 4.5.1
|
||||||
|
'@gltf-transform/functions':
|
||||||
|
specifier: ^4.5.1
|
||||||
|
version: 4.5.1
|
||||||
|
draco3dgltf:
|
||||||
|
specifier: ^1.5.9
|
||||||
|
version: 1.5.9
|
||||||
vite:
|
vite:
|
||||||
specifier: ^6.2.4
|
specifier: ^6.2.4
|
||||||
version: 6.4.5(terser@5.51.2)
|
version: 6.4.5(terser@5.51.2)
|
||||||
@@ -39,6 +51,9 @@ importers:
|
|||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
|
'@emnapi/runtime@1.11.3':
|
||||||
|
resolution: {integrity: sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==}
|
||||||
|
|
||||||
'@esbuild/aix-ppc64@0.25.12':
|
'@esbuild/aix-ppc64@0.25.12':
|
||||||
resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==}
|
resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
@@ -199,6 +214,177 @@ packages:
|
|||||||
resolution: {integrity: sha512-JUOtgFW6k9u4Y+xeIaEiLr3+cjoUPiAuLXoyKOJSia6Duzb7pq+A76P9ZdPDoAoxHdHzq6gE9/jKBGXlZT8FbA==}
|
resolution: {integrity: sha512-JUOtgFW6k9u4Y+xeIaEiLr3+cjoUPiAuLXoyKOJSia6Duzb7pq+A76P9ZdPDoAoxHdHzq6gE9/jKBGXlZT8FbA==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
|
'@gltf-transform/core@4.5.1':
|
||||||
|
resolution: {integrity: sha512-OWgBYssKHKoXMIrMb2N20jXqWRnMP9HdtcTFQBEAJtz4P+OOxx5fozl5eAeK7nktIs5uDE/lu4NbkE5VCZaR9g==}
|
||||||
|
|
||||||
|
'@gltf-transform/extensions@4.5.1':
|
||||||
|
resolution: {integrity: sha512-3jTe+GWRy4fj1TU790LPsO+rpO/4byUWPTpNkjy6M6h8RvrUivRf12Mptc0770K4ZczibpJDNHXZFkFsFMRDLA==}
|
||||||
|
|
||||||
|
'@gltf-transform/functions@4.5.1':
|
||||||
|
resolution: {integrity: sha512-rfm4nQY2DJ+ip1e15xp7YfQwhRno3kPLcGw4EZiRk1dVwMV3cdFMcF08glYcO/+oLyYkUEs3xXMJYXa0cPgcTg==}
|
||||||
|
|
||||||
|
'@img/colour@1.1.0':
|
||||||
|
resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==}
|
||||||
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
|
'@img/sharp-darwin-arm64@0.35.5':
|
||||||
|
resolution: {integrity: sha512-QRUlFQ0WxvdWyqqG/WtI3iupfD5rBzmCHXSdPsY91sAtVtTo7Q4cb6zOccZ3gqEqkr0f1As1ehLqmEpDsRf+lg==}
|
||||||
|
engines: {node: '>=20.9.0'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
'@img/sharp-darwin-x64@0.35.5':
|
||||||
|
resolution: {integrity: sha512-+BR255RhDlpygUpOc/Jdt1nT6DQ3XG/ERo5wbcdOf5Q320dKtPCKPLR1LJs9VGXRaMa8l1uUa0tkCNOXiAxZUw==}
|
||||||
|
engines: {node: '>=20.9.0'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
'@img/sharp-freebsd-wasm32@0.35.5':
|
||||||
|
resolution: {integrity: sha512-Y/z91nEZ4uIBX5X3nfTovjU9lHNKFYbL2lpHCLVNmXQK03VIZvXBBt0KxbPGp2SdGSF+2mQU4e+hQaWOt86iAw==}
|
||||||
|
engines: {node: '>=20.9.0'}
|
||||||
|
os: [freebsd]
|
||||||
|
|
||||||
|
'@img/sharp-libvips-darwin-arm64@1.3.4':
|
||||||
|
resolution: {integrity: sha512-5R89nBYiRdUlSWJxPhO+GVtaXzXSxKnRu/xqMn3KTA3L9EB9Oy/P+Nn2f2vlhPuUdy/Zusb2DarbyTpGCfEDuw==}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
'@img/sharp-libvips-darwin-x64@1.3.4':
|
||||||
|
resolution: {integrity: sha512-iR2OKH80yi0U+dUplyh3/xdpFvps6YkCwsXenIJxqxR1v9o+xtKTGbS9H7cps+2Vxjc8B1j96p75NmTGjIhtpQ==}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linux-arm64@1.3.4':
|
||||||
|
resolution: {integrity: sha512-Y3dgX/6lE2QhQb+Gxy0WZxfg9MEm/JBjamZpS2IklP7xIQoKN4hzAm7KcMVGtaVDt3neE9OKBC7vAfonA/Lr1A==}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linux-arm@1.3.4':
|
||||||
|
resolution: {integrity: sha512-LmRtTsOHuvM2+wlO2Db37dx5MiZhB0FvSunciw48YjdOkZz9KAiRbm8ujeMOA1INqmei5NapFxYEK1D1ZSidmw==}
|
||||||
|
cpu: [arm]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linux-ppc64@1.3.4':
|
||||||
|
resolution: {integrity: sha512-Le6boB8Tai0Nis+gIxIpKx68UDVVIqdR8Tin5Yf1z2LJJQLDJvCDRqRu+jC2qCoD+eIomonmOwB4smBRxfVpYQ==}
|
||||||
|
cpu: [ppc64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linux-riscv64@1.3.4':
|
||||||
|
resolution: {integrity: sha512-aHkkIEHPRdQEegJN20MLmGtxYD9R2wQr3Cwpddnu5+YKMt6Uzax7S9h5gpZTo8wyrGuZSlfQ63OevL5mTyOC7Q==}
|
||||||
|
cpu: [riscv64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linux-s390x@1.3.4':
|
||||||
|
resolution: {integrity: sha512-ra/mB6MikESDUO7Yg+Mi95bFBb9GsObURuhnOv3OqknjGe9sZrG8tCe9q0xSIGrtLgvgw0gKnFWcK4blSgQOuQ==}
|
||||||
|
cpu: [s390x]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linux-x64@1.3.4':
|
||||||
|
resolution: {integrity: sha512-GJ//SSXbnwSDes02umB3nDJLFcQzw8a18V8fyhqr6tV515tOEMdImjjxj1AoafMRz56F3PHgftnj1QEKSU1zkw==}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linuxmusl-arm64@1.3.4':
|
||||||
|
resolution: {integrity: sha512-hvulFwtjUcagsis6BBxHwGFwWoNZjgYmULGVrZcyfNbjA8hKILbRxGg15/7w5HDyXHXUos/j6baAWqnCyQ2DWA==}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linuxmusl-x64@1.3.4':
|
||||||
|
resolution: {integrity: sha512-6zXKeE/p39I1AmA3cJG35eyBGNqNddLnUXjhwBnsGjFPWqf5VKkDBEqaEkPDoTEtkxwi2vv8Tcr2mDyP4So7Fg==}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
|
'@img/sharp-linux-arm64@0.35.5':
|
||||||
|
resolution: {integrity: sha512-LYVx5JTsOM2CBzmxreh+nl64/3H6Xb09iSLknqH47z2T2DFFxDeFLP5y4dJwe6H7uGQlHPyEEtIqyo3DYsRwdQ==}
|
||||||
|
engines: {node: '>=20.9.0'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@img/sharp-linux-arm@0.35.5':
|
||||||
|
resolution: {integrity: sha512-LEaXK2WdXVK5ykcw0buWyPMsmLLL2vpHLD6yrNSW+JGEL3BZPA4tpKN6iaMc4AxTTAoaX/sU1rOL51lcIz48ZQ==}
|
||||||
|
engines: {node: '>=20.9.0'}
|
||||||
|
cpu: [arm]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@img/sharp-linux-ppc64@0.35.5':
|
||||||
|
resolution: {integrity: sha512-QVxAAq8evVRI9ia2vqgwrmWucn5Dfv+JdWzj75pD8omHLPSP7f8p20O8jxzjCcuCEQEOtYOZUmX1hkiZ0kdevA==}
|
||||||
|
engines: {node: '>=20.9.0'}
|
||||||
|
cpu: [ppc64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@img/sharp-linux-riscv64@0.35.5':
|
||||||
|
resolution: {integrity: sha512-LtdreXguaavKODPIfzJ4kffx7UNt1omwtK0rch4EBbbSTXPnxWmYSayXdLJw0fJzQ97kHt1gL/yh4tvU+nCyRQ==}
|
||||||
|
engines: {node: '>=20.9.0'}
|
||||||
|
cpu: [riscv64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@img/sharp-linux-s390x@0.35.5':
|
||||||
|
resolution: {integrity: sha512-UZasTOFiYzotTsGOCu42BfUzP6Tu6Do/947iRm1RsLKvlllxwGcn4RN27LibGWceix4Y+Pmw3jsnTcCQIgWjqA==}
|
||||||
|
engines: {node: '>=20.9.0'}
|
||||||
|
cpu: [s390x]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@img/sharp-linux-x64@0.35.5':
|
||||||
|
resolution: {integrity: sha512-SxFtLTeJInhAA9Q836kux2vZNeOBQEx658qvbboZScr0wIARym3IcGmW7KpVD5sbVg0Ojy+udFQdayYIZyoNog==}
|
||||||
|
engines: {node: '>=20.9.0'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@img/sharp-linuxmusl-arm64@0.35.5':
|
||||||
|
resolution: {integrity: sha512-9HbMclmI1zlNkFRs3z9/eBtDjfD0sGlrX1z6b1qwmiFY5ElDLh4BC0LPBdVp7z1DXFiKlIcznf+ZlsuZzLxQqg==}
|
||||||
|
engines: {node: '>=20.9.0'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
|
'@img/sharp-linuxmusl-x64@0.35.5':
|
||||||
|
resolution: {integrity: sha512-4KOphqB035HrVdqLZfCgMzzERrQkkzOwRhl4OAkRO1YCldbaFjySXMaK534Mo0V+LndnlJk+sbUyLeU0ULyD1A==}
|
||||||
|
engines: {node: '>=20.9.0'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
|
'@img/sharp-wasm32@0.35.5':
|
||||||
|
resolution: {integrity: sha512-Ptsga1su4tQx+LLF1ECS9U6nz5kmrXKo6XVbtR48Ke3ZRxxgaWBu7IDtEe1quo8hiupwm6WFqxVlXaSf7IINGQ==}
|
||||||
|
engines: {node: '>=20.9.0'}
|
||||||
|
|
||||||
|
'@img/sharp-webcontainers-wasm32@0.35.5':
|
||||||
|
resolution: {integrity: sha512-hfhF/FmoQyTUkA0bIKFOtw536BQSeBMe6BF6QyWlrPxT754+TFLaZ7sKKTfvvM0yJgKgaYTwnFCIZ/GuDw5SUA==}
|
||||||
|
engines: {node: '>=20.9.0'}
|
||||||
|
cpu: [wasm32]
|
||||||
|
|
||||||
|
'@img/sharp-win32-arm64@0.35.5':
|
||||||
|
resolution: {integrity: sha512-X4t7g+7ZA5DKblCBEXGjUqqemj4vczING/5viFwAL8h4N3qYeyjwdCvRLHi4EdOUI+2Z7UFlp1VM+p/AuEtm6Q==}
|
||||||
|
engines: {node: '>=20.9.0'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [win32]
|
||||||
|
|
||||||
|
'@img/sharp-win32-ia32@0.35.5':
|
||||||
|
resolution: {integrity: sha512-5Zm82LoBc43nhwNybZlG7Y1KO//Zhsn306fQl29ZOuStHLGTo3BWL83q3cznX0poxSAMuYL1On/BHBxkBeKr6A==}
|
||||||
|
engines: {node: ^20.9.0}
|
||||||
|
cpu: [ia32]
|
||||||
|
os: [win32]
|
||||||
|
|
||||||
|
'@img/sharp-win32-x64@0.35.5':
|
||||||
|
resolution: {integrity: sha512-x76eH0vEiHlcMQu8Y8IenntaACtddpT6W0wmXtWrnKcnKI7ME5DdgqhAD6SEWOEl1v2zDvkZDhFA9KnURwpfqg==}
|
||||||
|
engines: {node: '>=20.9.0'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [win32]
|
||||||
|
|
||||||
'@jridgewell/gen-mapping@0.3.13':
|
'@jridgewell/gen-mapping@0.3.13':
|
||||||
resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
|
resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
|
||||||
|
|
||||||
@@ -381,6 +567,9 @@ packages:
|
|||||||
'@types/html-minifier-terser@7.0.2':
|
'@types/html-minifier-terser@7.0.2':
|
||||||
resolution: {integrity: sha512-mm2HqV22l8lFQh4r2oSsOEVea+m0qqxEmwpc9kC1p/XzmjLWrReR9D/GRs8Pex2NX/imyEH9c5IU/7tMBQCHOA==}
|
resolution: {integrity: sha512-mm2HqV22l8lFQh4r2oSsOEVea+m0qqxEmwpc9kC1p/XzmjLWrReR9D/GRs8Pex2NX/imyEH9c5IU/7tMBQCHOA==}
|
||||||
|
|
||||||
|
'@types/ndarray@1.1.0':
|
||||||
|
resolution: {integrity: sha512-go+C6vHBUuO9jH6Tj6qEZ63JEGoMSxFdmd+6QAtthGD6xumBfIz3RbNDDs2aoRVLf9naH8lk5jnWy2UHHKgYQQ==}
|
||||||
|
|
||||||
acorn@8.19.0:
|
acorn@8.19.0:
|
||||||
resolution: {integrity: sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==}
|
resolution: {integrity: sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==}
|
||||||
engines: {node: '>=0.4.0'}
|
engines: {node: '>=0.4.0'}
|
||||||
@@ -429,9 +618,19 @@ packages:
|
|||||||
commander@2.20.3:
|
commander@2.20.3:
|
||||||
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
|
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
|
||||||
|
|
||||||
|
cwise-compiler@1.1.3:
|
||||||
|
resolution: {integrity: sha512-WXlK/m+Di8DMMcCjcWr4i+XzcQra9eCdXIJrgh4TUgh0pIS/yJduLxS9JgefsHJ/YVLdgPtXm9r62W92MvanEQ==}
|
||||||
|
|
||||||
|
detect-libc@2.1.2:
|
||||||
|
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
dot-case@3.0.4:
|
dot-case@3.0.4:
|
||||||
resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==}
|
resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==}
|
||||||
|
|
||||||
|
draco3dgltf@1.5.9:
|
||||||
|
resolution: {integrity: sha512-nIRZumqUwjqVYAdtt8q0F3FZc5qo2rCPTBH2hHhfSvHSPVJazzaepEHFdAZv4wrQKk5CkaclWGHhpyJ4eUdcJQ==}
|
||||||
|
|
||||||
entities@4.5.0:
|
entities@4.5.0:
|
||||||
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
|
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
|
||||||
engines: {node: '>=0.12'}
|
engines: {node: '>=0.12'}
|
||||||
@@ -485,10 +684,16 @@ packages:
|
|||||||
engines: {node: ^14.13.1 || >=16.0.0}
|
engines: {node: ^14.13.1 || >=16.0.0}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
iota-array@1.0.0:
|
||||||
|
resolution: {integrity: sha512-pZ2xT+LOHckCatGQ3DcG/a+QuEqvoxqkiL7tvE8nn3uuu+f6i1TtpB5/FtWFbxUuVr5PZCx8KskuGatbJDXOWA==}
|
||||||
|
|
||||||
is-binary-path@2.1.0:
|
is-binary-path@2.1.0:
|
||||||
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
|
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
|
is-buffer@1.1.6:
|
||||||
|
resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==}
|
||||||
|
|
||||||
is-extglob@2.1.1:
|
is-extglob@2.1.1:
|
||||||
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
|
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -507,6 +712,9 @@ packages:
|
|||||||
jsonfile@6.2.1:
|
jsonfile@6.2.1:
|
||||||
resolution: {integrity: sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==}
|
resolution: {integrity: sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==}
|
||||||
|
|
||||||
|
ktx-parse@1.1.0:
|
||||||
|
resolution: {integrity: sha512-mKp3y+FaYgR7mXWAbyyzpa/r1zDWeaunH+INJO4fou3hb45XuNSwar+7llrRyvpMWafxSIi99RNFJ05MHedaJQ==}
|
||||||
|
|
||||||
lower-case@2.0.2:
|
lower-case@2.0.2:
|
||||||
resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
|
resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
|
||||||
|
|
||||||
@@ -523,6 +731,18 @@ packages:
|
|||||||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
ndarray-lanczos@0.3.0:
|
||||||
|
resolution: {integrity: sha512-5kBmmG3Zvyj77qxIAC4QFLKuYdDIBJwCG+DukT6jQHNa1Ft74/hPH1z5mbQXeHBt8yvGPBGVrr3wEOdJPYYZYg==}
|
||||||
|
|
||||||
|
ndarray-ops@1.2.2:
|
||||||
|
resolution: {integrity: sha512-BppWAFRjMYF7N/r6Ie51q6D4fs0iiGmeXIACKY66fLpnwIui3Wc3CXiD/30mgLbDjPpSLrsqcp3Z62+IcHZsDw==}
|
||||||
|
|
||||||
|
ndarray-pixels@5.2.0:
|
||||||
|
resolution: {integrity: sha512-lTh4tFKziAatVTa9crIsidUyn+lqujVOQpzfdBWvdFu2wo9Uo6z261lVX7SgMyP89xGmj3TMTPbbxl9YDnV4SA==}
|
||||||
|
|
||||||
|
ndarray@1.1.1:
|
||||||
|
resolution: {integrity: sha512-AsE8w/M2MS+0pD3nP5qbRRtJFeJJJaJ+qXZaZr0XjVGXhy6LIj2TERTlkpdK2AI3WufoOP+pwPk3q2ilAJcZ9g==}
|
||||||
|
|
||||||
no-case@3.0.4:
|
no-case@3.0.4:
|
||||||
resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==}
|
resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==}
|
||||||
|
|
||||||
@@ -555,6 +775,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-YUbWYCgErwnMAVkjUnYa+KlMBzGpHwiIt/DE7f0G33AuX2LH9UcTk6KgWxd3zRU+pN3u/C+Xl3EnMLM4Hea7Sg==}
|
resolution: {integrity: sha512-YUbWYCgErwnMAVkjUnYa+KlMBzGpHwiIt/DE7f0G33AuX2LH9UcTk6KgWxd3zRU+pN3u/C+Xl3EnMLM4Hea7Sg==}
|
||||||
engines: {node: ^10 || ^12 || >=14}
|
engines: {node: ^10 || ^12 || >=14}
|
||||||
|
|
||||||
|
property-graph@4.1.0:
|
||||||
|
resolution: {integrity: sha512-AvPcP7XECNWy4LGmFQ77k7un4lSKM4eS29PTvW4ck95uYeLxXPWJM7hLuBqK91FaHqCcgJvIUCuNJjjxKE7VKQ==}
|
||||||
|
|
||||||
queue-microtask@1.2.3:
|
queue-microtask@1.2.3:
|
||||||
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
||||||
|
|
||||||
@@ -578,6 +801,20 @@ packages:
|
|||||||
run-parallel@1.2.0:
|
run-parallel@1.2.0:
|
||||||
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
|
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
|
||||||
|
|
||||||
|
semver@7.8.5:
|
||||||
|
resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
|
sharp@0.35.5:
|
||||||
|
resolution: {integrity: sha512-Ywn4OnzGukp7CDMrp08RQ50YKmuwG47brZgIVPTvBaaAfQlRlygrRqSrxdCiL9M+LlzLBiJ68IR1QqvzHyjC7g==}
|
||||||
|
engines: {node: '>=20.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/node': '*'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/node':
|
||||||
|
optional: true
|
||||||
|
|
||||||
source-map-js@1.2.2:
|
source-map-js@1.2.2:
|
||||||
resolution: {integrity: sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==}
|
resolution: {integrity: sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -608,6 +845,9 @@ packages:
|
|||||||
tslib@2.8.1:
|
tslib@2.8.1:
|
||||||
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
|
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
|
||||||
|
|
||||||
|
uniq@1.0.1:
|
||||||
|
resolution: {integrity: sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==}
|
||||||
|
|
||||||
universalify@2.0.1:
|
universalify@2.0.1:
|
||||||
resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
|
resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
|
||||||
engines: {node: '>= 10.0.0'}
|
engines: {node: '>= 10.0.0'}
|
||||||
@@ -665,6 +905,11 @@ packages:
|
|||||||
|
|
||||||
snapshots:
|
snapshots:
|
||||||
|
|
||||||
|
'@emnapi/runtime@1.11.3':
|
||||||
|
dependencies:
|
||||||
|
tslib: 2.8.1
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@esbuild/aix-ppc64@0.25.12':
|
'@esbuild/aix-ppc64@0.25.12':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -745,6 +990,132 @@ snapshots:
|
|||||||
|
|
||||||
'@fortawesome/fontawesome-free@6.7.2': {}
|
'@fortawesome/fontawesome-free@6.7.2': {}
|
||||||
|
|
||||||
|
'@gltf-transform/core@4.5.1':
|
||||||
|
dependencies:
|
||||||
|
property-graph: 4.1.0
|
||||||
|
|
||||||
|
'@gltf-transform/extensions@4.5.1':
|
||||||
|
dependencies:
|
||||||
|
'@gltf-transform/core': 4.5.1
|
||||||
|
ktx-parse: 1.1.0
|
||||||
|
|
||||||
|
'@gltf-transform/functions@4.5.1':
|
||||||
|
dependencies:
|
||||||
|
'@gltf-transform/core': 4.5.1
|
||||||
|
'@gltf-transform/extensions': 4.5.1
|
||||||
|
ktx-parse: 1.1.0
|
||||||
|
ndarray: 1.1.1
|
||||||
|
ndarray-lanczos: 0.3.0
|
||||||
|
ndarray-pixels: 5.2.0
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@types/node'
|
||||||
|
|
||||||
|
'@img/colour@1.1.0': {}
|
||||||
|
|
||||||
|
'@img/sharp-darwin-arm64@0.35.5':
|
||||||
|
optionalDependencies:
|
||||||
|
'@img/sharp-libvips-darwin-arm64': 1.3.4
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-darwin-x64@0.35.5':
|
||||||
|
optionalDependencies:
|
||||||
|
'@img/sharp-libvips-darwin-x64': 1.3.4
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-freebsd-wasm32@0.35.5':
|
||||||
|
dependencies:
|
||||||
|
'@img/sharp-wasm32': 0.35.5
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-libvips-darwin-arm64@1.3.4':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-libvips-darwin-x64@1.3.4':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linux-arm64@1.3.4':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linux-arm@1.3.4':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linux-ppc64@1.3.4':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linux-riscv64@1.3.4':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linux-s390x@1.3.4':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linux-x64@1.3.4':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linuxmusl-arm64@1.3.4':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linuxmusl-x64@1.3.4':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-linux-arm64@0.35.5':
|
||||||
|
optionalDependencies:
|
||||||
|
'@img/sharp-libvips-linux-arm64': 1.3.4
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-linux-arm@0.35.5':
|
||||||
|
optionalDependencies:
|
||||||
|
'@img/sharp-libvips-linux-arm': 1.3.4
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-linux-ppc64@0.35.5':
|
||||||
|
optionalDependencies:
|
||||||
|
'@img/sharp-libvips-linux-ppc64': 1.3.4
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-linux-riscv64@0.35.5':
|
||||||
|
optionalDependencies:
|
||||||
|
'@img/sharp-libvips-linux-riscv64': 1.3.4
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-linux-s390x@0.35.5':
|
||||||
|
optionalDependencies:
|
||||||
|
'@img/sharp-libvips-linux-s390x': 1.3.4
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-linux-x64@0.35.5':
|
||||||
|
optionalDependencies:
|
||||||
|
'@img/sharp-libvips-linux-x64': 1.3.4
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-linuxmusl-arm64@0.35.5':
|
||||||
|
optionalDependencies:
|
||||||
|
'@img/sharp-libvips-linuxmusl-arm64': 1.3.4
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-linuxmusl-x64@0.35.5':
|
||||||
|
optionalDependencies:
|
||||||
|
'@img/sharp-libvips-linuxmusl-x64': 1.3.4
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-wasm32@0.35.5':
|
||||||
|
dependencies:
|
||||||
|
'@emnapi/runtime': 1.11.3
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-webcontainers-wasm32@0.35.5':
|
||||||
|
dependencies:
|
||||||
|
'@img/sharp-wasm32': 0.35.5
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-win32-arm64@0.35.5':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-win32-ia32@0.35.5':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-win32-x64@0.35.5':
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@jridgewell/gen-mapping@0.3.13':
|
'@jridgewell/gen-mapping@0.3.13':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@jridgewell/sourcemap-codec': 1.6.0
|
'@jridgewell/sourcemap-codec': 1.6.0
|
||||||
@@ -860,6 +1231,8 @@ snapshots:
|
|||||||
|
|
||||||
'@types/html-minifier-terser@7.0.2': {}
|
'@types/html-minifier-terser@7.0.2': {}
|
||||||
|
|
||||||
|
'@types/ndarray@1.1.0': {}
|
||||||
|
|
||||||
acorn@8.19.0: {}
|
acorn@8.19.0: {}
|
||||||
|
|
||||||
anymatch@3.1.3:
|
anymatch@3.1.3:
|
||||||
@@ -908,11 +1281,19 @@ snapshots:
|
|||||||
|
|
||||||
commander@2.20.3: {}
|
commander@2.20.3: {}
|
||||||
|
|
||||||
|
cwise-compiler@1.1.3:
|
||||||
|
dependencies:
|
||||||
|
uniq: 1.0.1
|
||||||
|
|
||||||
|
detect-libc@2.1.2: {}
|
||||||
|
|
||||||
dot-case@3.0.4:
|
dot-case@3.0.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
no-case: 3.0.4
|
no-case: 3.0.4
|
||||||
tslib: 2.8.1
|
tslib: 2.8.1
|
||||||
|
|
||||||
|
draco3dgltf@1.5.9: {}
|
||||||
|
|
||||||
entities@4.5.0: {}
|
entities@4.5.0: {}
|
||||||
|
|
||||||
esbuild@0.25.12:
|
esbuild@0.25.12:
|
||||||
@@ -991,10 +1372,14 @@ snapshots:
|
|||||||
relateurl: 0.2.7
|
relateurl: 0.2.7
|
||||||
terser: 5.51.2
|
terser: 5.51.2
|
||||||
|
|
||||||
|
iota-array@1.0.0: {}
|
||||||
|
|
||||||
is-binary-path@2.1.0:
|
is-binary-path@2.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
binary-extensions: 2.3.0
|
binary-extensions: 2.3.0
|
||||||
|
|
||||||
|
is-buffer@1.1.6: {}
|
||||||
|
|
||||||
is-extglob@2.1.1: {}
|
is-extglob@2.1.1: {}
|
||||||
|
|
||||||
is-glob@4.0.3:
|
is-glob@4.0.3:
|
||||||
@@ -1011,6 +1396,8 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
graceful-fs: 4.2.11
|
graceful-fs: 4.2.11
|
||||||
|
|
||||||
|
ktx-parse@1.1.0: {}
|
||||||
|
|
||||||
lower-case@2.0.2:
|
lower-case@2.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib: 2.8.1
|
tslib: 2.8.1
|
||||||
@@ -1024,6 +1411,29 @@ snapshots:
|
|||||||
|
|
||||||
nanoid@3.3.20: {}
|
nanoid@3.3.20: {}
|
||||||
|
|
||||||
|
ndarray-lanczos@0.3.0:
|
||||||
|
dependencies:
|
||||||
|
'@types/ndarray': 1.1.0
|
||||||
|
ndarray: 1.1.1
|
||||||
|
|
||||||
|
ndarray-ops@1.2.2:
|
||||||
|
dependencies:
|
||||||
|
cwise-compiler: 1.1.3
|
||||||
|
|
||||||
|
ndarray-pixels@5.2.0:
|
||||||
|
dependencies:
|
||||||
|
'@types/ndarray': 1.1.0
|
||||||
|
ndarray: 1.1.1
|
||||||
|
ndarray-ops: 1.2.2
|
||||||
|
sharp: 0.35.5
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@types/node'
|
||||||
|
|
||||||
|
ndarray@1.1.1:
|
||||||
|
dependencies:
|
||||||
|
iota-array: 1.0.0
|
||||||
|
is-buffer: 1.1.6
|
||||||
|
|
||||||
no-case@3.0.4:
|
no-case@3.0.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
lower-case: 2.0.2
|
lower-case: 2.0.2
|
||||||
@@ -1055,6 +1465,8 @@ snapshots:
|
|||||||
picocolors: 1.1.1
|
picocolors: 1.1.1
|
||||||
source-map-js: 1.2.2
|
source-map-js: 1.2.2
|
||||||
|
|
||||||
|
property-graph@4.1.0: {}
|
||||||
|
|
||||||
queue-microtask@1.2.3: {}
|
queue-microtask@1.2.3: {}
|
||||||
|
|
||||||
readdirp@3.6.0:
|
readdirp@3.6.0:
|
||||||
@@ -1101,6 +1513,40 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
queue-microtask: 1.2.3
|
queue-microtask: 1.2.3
|
||||||
|
|
||||||
|
semver@7.8.5: {}
|
||||||
|
|
||||||
|
sharp@0.35.5:
|
||||||
|
dependencies:
|
||||||
|
'@img/colour': 1.1.0
|
||||||
|
detect-libc: 2.1.2
|
||||||
|
semver: 7.8.5
|
||||||
|
optionalDependencies:
|
||||||
|
'@img/sharp-darwin-arm64': 0.35.5
|
||||||
|
'@img/sharp-darwin-x64': 0.35.5
|
||||||
|
'@img/sharp-freebsd-wasm32': 0.35.5
|
||||||
|
'@img/sharp-libvips-darwin-arm64': 1.3.4
|
||||||
|
'@img/sharp-libvips-darwin-x64': 1.3.4
|
||||||
|
'@img/sharp-libvips-linux-arm': 1.3.4
|
||||||
|
'@img/sharp-libvips-linux-arm64': 1.3.4
|
||||||
|
'@img/sharp-libvips-linux-ppc64': 1.3.4
|
||||||
|
'@img/sharp-libvips-linux-riscv64': 1.3.4
|
||||||
|
'@img/sharp-libvips-linux-s390x': 1.3.4
|
||||||
|
'@img/sharp-libvips-linux-x64': 1.3.4
|
||||||
|
'@img/sharp-libvips-linuxmusl-arm64': 1.3.4
|
||||||
|
'@img/sharp-libvips-linuxmusl-x64': 1.3.4
|
||||||
|
'@img/sharp-linux-arm': 0.35.5
|
||||||
|
'@img/sharp-linux-arm64': 0.35.5
|
||||||
|
'@img/sharp-linux-ppc64': 0.35.5
|
||||||
|
'@img/sharp-linux-riscv64': 0.35.5
|
||||||
|
'@img/sharp-linux-s390x': 0.35.5
|
||||||
|
'@img/sharp-linux-x64': 0.35.5
|
||||||
|
'@img/sharp-linuxmusl-arm64': 0.35.5
|
||||||
|
'@img/sharp-linuxmusl-x64': 0.35.5
|
||||||
|
'@img/sharp-webcontainers-wasm32': 0.35.5
|
||||||
|
'@img/sharp-win32-arm64': 0.35.5
|
||||||
|
'@img/sharp-win32-ia32': 0.35.5
|
||||||
|
'@img/sharp-win32-x64': 0.35.5
|
||||||
|
|
||||||
source-map-js@1.2.2: {}
|
source-map-js@1.2.2: {}
|
||||||
|
|
||||||
source-map-support@0.5.21:
|
source-map-support@0.5.21:
|
||||||
@@ -1130,6 +1576,8 @@ snapshots:
|
|||||||
|
|
||||||
tslib@2.8.1: {}
|
tslib@2.8.1: {}
|
||||||
|
|
||||||
|
uniq@1.0.1: {}
|
||||||
|
|
||||||
universalify@2.0.1: {}
|
universalify@2.0.1: {}
|
||||||
|
|
||||||
vite-plugin-minify@2.1.0(vite@6.4.5(terser@5.51.2)):
|
vite-plugin-minify@2.1.0(vite@6.4.5(terser@5.51.2)):
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
// NON ATTIVO: per ora nessuno lo importa (vedi vite-plugins/encrypt-models.js).
|
||||||
|
//
|
||||||
|
// Carica un modello GLB cifrato in build (vedi vite-plugins/encrypt-models.js): scarica il .bin,
|
||||||
|
// lo decifra in memoria con WebCrypto e lo passa al GLTFLoader. Nessun .glb in chiaro passa in rete.
|
||||||
|
//
|
||||||
|
// WebCrypto richiede un contesto sicuro: https, oppure http://localhost.
|
||||||
|
|
||||||
|
/* global __KREIOS_MK__, __KREIOS_MM__ */
|
||||||
|
|
||||||
|
let keyPromise = null;
|
||||||
|
|
||||||
|
function rawKey() {
|
||||||
|
const masked = __KREIOS_MK__;
|
||||||
|
const mask = __KREIOS_MM__;
|
||||||
|
return Uint8Array.from(masked, (b, i) => b ^ mask[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getKey() {
|
||||||
|
keyPromise ??= (async () => {
|
||||||
|
const raw = rawKey();
|
||||||
|
const cryptoKey = await crypto.subtle.importKey('raw', raw, 'AES-GCM', false, ['decrypt']);
|
||||||
|
return { raw, cryptoKey };
|
||||||
|
})();
|
||||||
|
return keyPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fileName(raw, relPath) {
|
||||||
|
const data = new Uint8Array([...raw, ...new TextEncoder().encode(relPath)]);
|
||||||
|
const digest = new Uint8Array(await crypto.subtle.digest('SHA-256', data));
|
||||||
|
return [...digest].map((b) => b.toString(16).padStart(2, '0')).join('').slice(0, 32) + '.bin';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scarica con avanzamento, compatibile con il callback di progresso del GLTFLoader ({ loaded, total }).
|
||||||
|
async function download(url, onProgress) {
|
||||||
|
const res = await fetch(url);
|
||||||
|
if (!res.ok) throw new Error(`Modello non disponibile (${res.status})`);
|
||||||
|
|
||||||
|
const total = Number(res.headers.get('Content-Length')) || 0;
|
||||||
|
if (!res.body || !total) {
|
||||||
|
const buf = await res.arrayBuffer();
|
||||||
|
onProgress?.({ loaded: buf.byteLength, total: buf.byteLength });
|
||||||
|
return new Uint8Array(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
const out = new Uint8Array(total);
|
||||||
|
const reader = res.body.getReader();
|
||||||
|
let loaded = 0;
|
||||||
|
for (;;) {
|
||||||
|
const { done, value } = await reader.read();
|
||||||
|
if (done) break;
|
||||||
|
out.set(value, loaded);
|
||||||
|
loaded += value.length;
|
||||||
|
onProgress?.({ loaded, total });
|
||||||
|
}
|
||||||
|
return out.subarray(0, loaded);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {import('three/examples/jsm/loaders/GLTFLoader').GLTFLoader} loader
|
||||||
|
* @param {string} relPath percorso sotto assets/models, es. "pvc/finestra_1_anta.glb"
|
||||||
|
*/
|
||||||
|
export async function caricaModelloCifrato(loader, relPath, onProgress) {
|
||||||
|
const { raw, cryptoKey } = await getKey();
|
||||||
|
const data = await download(`./assets/m/${await fileName(raw, relPath)}`, onProgress);
|
||||||
|
|
||||||
|
const glb = await crypto.subtle.decrypt(
|
||||||
|
{ name: 'AES-GCM', iv: data.subarray(0, 12), additionalData: new TextEncoder().encode(relPath) },
|
||||||
|
cryptoKey,
|
||||||
|
data.subarray(12),
|
||||||
|
);
|
||||||
|
|
||||||
|
const dir = relPath.includes('/') ? relPath.slice(0, relPath.lastIndexOf('/') + 1) : '';
|
||||||
|
return loader.parseAsync(glb, `./assets/models/${dir}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Stessa firma di GLTFLoader.load, ma su modelli cifrati. */
|
||||||
|
export function loadModello(loader, relPath, onLoad, onProgress, onError) {
|
||||||
|
caricaModelloCifrato(loader, relPath, onProgress).then(onLoad, (err) => (onError ? onError(err) : console.error(err)));
|
||||||
|
}
|
||||||
+10
-3
@@ -2,6 +2,7 @@
|
|||||||
import * as THREE from 'three';
|
import * as THREE from 'three';
|
||||||
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
|
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
|
||||||
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
|
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
|
||||||
|
import { DRACOLoader, DRACO_GLTF_CONFIG } from 'three/examples/jsm/loaders/DRACOLoader';
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { APP } from './app.js';
|
import { APP } from './app.js';
|
||||||
import ParamsParser from './params_parser.js';
|
import ParamsParser from './params_parser.js';
|
||||||
@@ -20,7 +21,13 @@ import { API_BASE as PREVENTIVI_API_BASE } from './api_base.js';
|
|||||||
window.$ = $;
|
window.$ = $;
|
||||||
window.THREE = THREE; // Used by APP Scripts.
|
window.THREE = THREE; // Used by APP Scripts.
|
||||||
window.OrbitControls = OrbitControls; // Used by APP Scripts.
|
window.OrbitControls = OrbitControls; // Used by APP Scripts.
|
||||||
window.GLTFLoader = GLTFLoader; // Used by APP Scripts.
|
|
||||||
|
// I modelli sono compressi con Draco in build (vite-plugins/draco-models.js). I decoder (versione
|
||||||
|
// ridotta per glTF) li risolve three via import.meta.url e Vite li include nella build.
|
||||||
|
const dracoLoader = new DRACOLoader().setDecoderPath(DRACO_GLTF_CONFIG);
|
||||||
|
function createGltfLoader() {
|
||||||
|
return new GLTFLoader().setDRACOLoader(dracoLoader);
|
||||||
|
}
|
||||||
|
|
||||||
// --- Integrazione backend preventivi ---
|
// --- Integrazione backend preventivi ---
|
||||||
const CART_TOKEN_KEY = 'kreios_cart_token';
|
const CART_TOKEN_KEY = 'kreios_cart_token';
|
||||||
@@ -239,7 +246,7 @@ const start = async () => {
|
|||||||
playerOff.rotateBackground(Math.PI);
|
playerOff.rotateBackground(Math.PI);
|
||||||
playerOff.setSize(playerOff.dom.clientWidth, playerOff.dom.clientHeight);
|
playerOff.setSize(playerOff.dom.clientWidth, playerOff.dom.clientHeight);
|
||||||
|
|
||||||
var gltfLoader = new GLTFLoader();
|
var gltfLoader = createGltfLoader();
|
||||||
|
|
||||||
gltfLoader.load(`./assets/models/${params.sistema}/${modello.modello}`, function (gltf) {
|
gltfLoader.load(`./assets/models/${params.sistema}/${modello.modello}`, function (gltf) {
|
||||||
document.getElementById('loadingBarContainer').style.display = 'none';
|
document.getElementById('loadingBarContainer').style.display = 'none';
|
||||||
@@ -446,7 +453,7 @@ const start = async () => {
|
|||||||
document.getElementById('loadingBarProgressAlt').style.width = '0%';
|
document.getElementById('loadingBarProgressAlt').style.width = '0%';
|
||||||
document.getElementById('loadingPercentageAlt').innerText = '0%';
|
document.getElementById('loadingPercentageAlt').innerText = '0%';
|
||||||
|
|
||||||
var gltfLoader = new GLTFLoader();
|
var gltfLoader = createGltfLoader();
|
||||||
|
|
||||||
gltfLoader.load(`./assets/models/${modello}`, function (gltf) {
|
gltfLoader.load(`./assets/models/${modello}`, function (gltf) {
|
||||||
document.getElementById('loadingBarContainerAlt').style.display = 'none';
|
document.getElementById('loadingBarContainerAlt').style.display = 'none';
|
||||||
|
|||||||
@@ -0,0 +1,128 @@
|
|||||||
|
// Comprime con Draco i modelli GLB in fase di build.
|
||||||
|
//
|
||||||
|
// Ogni src/assets/models/<percorso>.glb viene scritto compresso in <outDir>/assets/models/<percorso>.glb
|
||||||
|
// (stesso URL di prima). Nel browser li decomprime il DRACOLoader di three.js (vedi starter.js).
|
||||||
|
//
|
||||||
|
// La compressione è lenta, quindi i risultati sono in cache (node_modules/.cache/draco-models) e
|
||||||
|
// ricalcolati solo quando cambia il sorgente o le opzioni di compressione.
|
||||||
|
import crypto from 'node:crypto';
|
||||||
|
import fs from 'node:fs/promises';
|
||||||
|
import path from 'node:path';
|
||||||
|
import { NodeIO } from '@gltf-transform/core';
|
||||||
|
import { ALL_EXTENSIONS } from '@gltf-transform/extensions';
|
||||||
|
import { draco, weld } from '@gltf-transform/functions';
|
||||||
|
import draco3d from 'draco3dgltf';
|
||||||
|
|
||||||
|
// Bit di quantizzazione: valori più alti = più fedeltà e file più grandi.
|
||||||
|
// Le posizioni a 14 bit sono sotto il decimo di millimetro sulle dimensioni di un infisso.
|
||||||
|
const DRACO_OPTIONS = {
|
||||||
|
method: 'edgebreaker',
|
||||||
|
encodeSpeed: 5,
|
||||||
|
decodeSpeed: 5,
|
||||||
|
quantizePosition: 14,
|
||||||
|
quantizeNormal: 10,
|
||||||
|
quantizeTexcoord: 12,
|
||||||
|
quantizeColor: 8,
|
||||||
|
quantizeGeneric: 12,
|
||||||
|
};
|
||||||
|
const CACHE_VERSION = 1;
|
||||||
|
|
||||||
|
async function listGlb(dir, base = dir) {
|
||||||
|
const out = [];
|
||||||
|
for (const entry of await fs.readdir(dir, { withFileTypes: true })) {
|
||||||
|
const full = path.join(dir, entry.name);
|
||||||
|
if (entry.isDirectory()) out.push(...(await listGlb(full, base)));
|
||||||
|
else if (entry.name.toLowerCase().endsWith('.glb')) out.push(path.relative(base, full));
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function removePlainGlb(dir) {
|
||||||
|
let entries;
|
||||||
|
try {
|
||||||
|
entries = await fs.readdir(dir, { withFileTypes: true });
|
||||||
|
} catch {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (const entry of entries) {
|
||||||
|
const full = path.join(dir, entry.name);
|
||||||
|
if (entry.isDirectory()) await removePlainGlb(full);
|
||||||
|
else if (entry.name.toLowerCase().endsWith('.glb')) await fs.rm(full);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function dracoModels({ modelsDir, cacheDir }) {
|
||||||
|
let outDir;
|
||||||
|
let ioPromise = null;
|
||||||
|
|
||||||
|
const getIO = () =>
|
||||||
|
(ioPromise ??= (async () =>
|
||||||
|
new NodeIO().registerExtensions(ALL_EXTENSIONS).registerDependencies({
|
||||||
|
'draco3d.encoder': await draco3d.createEncoderModule(),
|
||||||
|
'draco3d.decoder': await draco3d.createDecoderModule(),
|
||||||
|
}))());
|
||||||
|
|
||||||
|
async function compress(src) {
|
||||||
|
const io = await getIO();
|
||||||
|
const doc = await io.read(src);
|
||||||
|
// Draco lavora su primitive indicizzate: weld unisce solo i vertici identici in tutti gli
|
||||||
|
// attributi (posizione, normale, uv...), quindi non cambia l'aspetto del modello.
|
||||||
|
await doc.transform(weld(), draco(DRACO_OPTIONS));
|
||||||
|
return Buffer.from(await io.writeBinary(doc));
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: 'kreios-draco-models',
|
||||||
|
apply: 'build',
|
||||||
|
|
||||||
|
configResolved(config) {
|
||||||
|
outDir = config.build.outDir;
|
||||||
|
},
|
||||||
|
|
||||||
|
// sequential: parte dopo il writeBundle di vite-plugin-static-copy.
|
||||||
|
writeBundle: {
|
||||||
|
sequential: true,
|
||||||
|
order: 'post',
|
||||||
|
async handler() {
|
||||||
|
// Nessun GLB non compresso deve finire online (es. file archiviati in assets/data).
|
||||||
|
await removePlainGlb(path.join(outDir, 'assets'));
|
||||||
|
await fs.mkdir(cacheDir, { recursive: true });
|
||||||
|
|
||||||
|
const files = await listGlb(modelsDir);
|
||||||
|
let compressed = 0;
|
||||||
|
let before = 0;
|
||||||
|
let after = 0;
|
||||||
|
|
||||||
|
for (const rel of files) {
|
||||||
|
const src = path.join(modelsDir, rel);
|
||||||
|
const data = await fs.readFile(src);
|
||||||
|
const hash = crypto
|
||||||
|
.createHash('sha256')
|
||||||
|
.update(JSON.stringify({ v: CACHE_VERSION, DRACO_OPTIONS }))
|
||||||
|
.update(data)
|
||||||
|
.digest('hex');
|
||||||
|
const cached = path.join(cacheDir, `${hash}.glb`);
|
||||||
|
|
||||||
|
let out = await fs.readFile(cached).catch(() => null);
|
||||||
|
if (!out) {
|
||||||
|
out = await compress(src);
|
||||||
|
await fs.writeFile(cached, out);
|
||||||
|
compressed++;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dest = path.join(outDir, 'assets/models', rel);
|
||||||
|
await fs.mkdir(path.dirname(dest), { recursive: true });
|
||||||
|
await fs.writeFile(dest, out);
|
||||||
|
before += data.length;
|
||||||
|
after += out.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mb = (n) => (n / 1024 / 1024).toFixed(1);
|
||||||
|
console.log(
|
||||||
|
`[draco-models] ${files.length} modelli (${compressed} ricompressi): ` +
|
||||||
|
`${mb(before)} MB -> ${mb(after)} MB`,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
// NON ATTIVO: non è registrato in vite.config.js. Per usarlo va aggiunto ai plugin dopo dracoModels
|
||||||
|
// (facendogli cifrare i GLB già compressi in <outDir>/assets/models) e i caricamenti in starter.js vanno
|
||||||
|
// fatti con loadModello() di src/js/model_loader.js, impostando sul GLTFLoader anche il DRACOLoader.
|
||||||
|
//
|
||||||
|
// Cifra i modelli GLB in fase di build, così nella cartella pubblica non esiste nessun .glb in chiaro.
|
||||||
|
//
|
||||||
|
// Ogni src/assets/models/<percorso>.glb diventa <outDir>/assets/m/<hash>.bin, dove:
|
||||||
|
// - hash = sha256(chiave || percorso) troncato: l'URL non rivela il nome del modello;
|
||||||
|
// - contenuto = IV (12 byte) + AES-256-GCM(glb), con il percorso come dato autenticato.
|
||||||
|
// La chiave arriva da MODELS_KEY (64 caratteri esadecimali, in .env / .env.production) ed è iniettata
|
||||||
|
// nel bundle offuscata; il browser la ricostruisce e decifra con WebCrypto (src/js/model_loader.js).
|
||||||
|
//
|
||||||
|
// È una protezione contro il download diretto (tab Network, estensioni "scarica modelli 3D"), non una
|
||||||
|
// protezione assoluta: chi legge il JS e fa debug della pagina può comunque recuperare la geometria.
|
||||||
|
import crypto from 'node:crypto';
|
||||||
|
import fs from 'node:fs/promises';
|
||||||
|
import path from 'node:path';
|
||||||
|
import { loadEnv } from 'vite';
|
||||||
|
|
||||||
|
const OUT_SUBDIR = 'assets/m';
|
||||||
|
|
||||||
|
async function listGlb(dir, base = dir) {
|
||||||
|
const out = [];
|
||||||
|
for (const entry of await fs.readdir(dir, { withFileTypes: true })) {
|
||||||
|
const full = path.join(dir, entry.name);
|
||||||
|
if (entry.isDirectory()) out.push(...(await listGlb(full, base)));
|
||||||
|
else if (entry.name.toLowerCase().endsWith('.glb')) out.push(path.relative(base, full).split(path.sep).join('/'));
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Elimina gli eventuali .glb copiati in chiaro da vite-plugin-static-copy (es. file archiviati in assets/data).
|
||||||
|
async function removePlainGlb(dir) {
|
||||||
|
let entries;
|
||||||
|
try {
|
||||||
|
entries = await fs.readdir(dir, { withFileTypes: true });
|
||||||
|
} catch {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (const entry of entries) {
|
||||||
|
const full = path.join(dir, entry.name);
|
||||||
|
if (entry.isDirectory()) await removePlainGlb(full);
|
||||||
|
else if (entry.name.toLowerCase().endsWith('.glb')) await fs.rm(full);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function modelFileName(key, relPath) {
|
||||||
|
return crypto.createHash('sha256').update(key).update(relPath, 'utf8').digest('hex').slice(0, 32) + '.bin';
|
||||||
|
}
|
||||||
|
|
||||||
|
function encrypt(key, relPath, data) {
|
||||||
|
const iv = crypto.randomBytes(12);
|
||||||
|
const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
|
||||||
|
cipher.setAAD(Buffer.from(relPath, 'utf8'));
|
||||||
|
const body = Buffer.concat([cipher.update(data), cipher.final()]);
|
||||||
|
// Formato WebCrypto: ciphertext seguito dal tag di 16 byte.
|
||||||
|
return Buffer.concat([iv, body, cipher.getAuthTag()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function encryptModels({ modelsDir }) {
|
||||||
|
let key;
|
||||||
|
let outDir;
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: 'kreios-encrypt-models',
|
||||||
|
apply: 'build',
|
||||||
|
|
||||||
|
config(userConfig, { mode }) {
|
||||||
|
const envDir = userConfig.envDir ?? process.cwd();
|
||||||
|
const hex = (loadEnv(mode, envDir, '').MODELS_KEY ?? process.env.MODELS_KEY ?? '').trim();
|
||||||
|
if (/^[0-9a-fA-F]{64}$/.test(hex)) {
|
||||||
|
key = Buffer.from(hex, 'hex');
|
||||||
|
} else {
|
||||||
|
if (hex) throw new Error('MODELS_KEY deve essere di 64 caratteri esadecimali (32 byte).');
|
||||||
|
// Senza chiave fissa ogni build ne genera una nuova: funziona, ma cambia tutti gli URL
|
||||||
|
// dei modelli e i browser li riscaricano a ogni deploy.
|
||||||
|
key = crypto.randomBytes(32);
|
||||||
|
console.warn('[encrypt-models] MODELS_KEY non impostata: uso una chiave casuale per questa build.');
|
||||||
|
}
|
||||||
|
// La chiave nel bundle è mascherata (XOR) per non comparire come costante leggibile.
|
||||||
|
const mask = crypto.randomBytes(32);
|
||||||
|
const masked = Buffer.from(key.map((b, i) => b ^ mask[i]));
|
||||||
|
return {
|
||||||
|
define: {
|
||||||
|
__KREIOS_MK__: JSON.stringify([...masked]),
|
||||||
|
__KREIOS_MM__: JSON.stringify([...mask]),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
configResolved(config) {
|
||||||
|
outDir = config.build.outDir;
|
||||||
|
},
|
||||||
|
|
||||||
|
// sequential: parte dopo il writeBundle di vite-plugin-static-copy.
|
||||||
|
writeBundle: {
|
||||||
|
sequential: true,
|
||||||
|
order: 'post',
|
||||||
|
async handler() {
|
||||||
|
await removePlainGlb(path.join(outDir, 'assets'));
|
||||||
|
|
||||||
|
const target = path.join(outDir, OUT_SUBDIR);
|
||||||
|
await fs.mkdir(target, { recursive: true });
|
||||||
|
|
||||||
|
const files = await listGlb(modelsDir);
|
||||||
|
for (const rel of files) {
|
||||||
|
const src = path.join(modelsDir, rel);
|
||||||
|
const dest = path.join(target, modelFileName(key, rel));
|
||||||
|
// In watch mode non ricifra i modelli che non sono cambiati.
|
||||||
|
const [s, d] = await Promise.all([fs.stat(src), fs.stat(dest).catch(() => null)]);
|
||||||
|
if (d && d.mtimeMs >= s.mtimeMs) continue;
|
||||||
|
await fs.writeFile(dest, encrypt(key, rel, await fs.readFile(src)));
|
||||||
|
}
|
||||||
|
console.log(`[encrypt-models] ${files.length} modelli cifrati in ${OUT_SUBDIR}/`);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
+10
-2
@@ -2,6 +2,9 @@ import { defineConfig } from 'vite';
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { viteStaticCopy } from 'vite-plugin-static-copy';
|
import { viteStaticCopy } from 'vite-plugin-static-copy';
|
||||||
import { ViteMinifyPlugin } from 'vite-plugin-minify'
|
import { ViteMinifyPlugin } from 'vite-plugin-minify'
|
||||||
|
import dracoModels from './vite-plugins/draco-models.js';
|
||||||
|
// Cifratura dei modelli, pronta ma non attiva: vedi vite-plugins/encrypt-models.js.
|
||||||
|
// import encryptModels from './vite-plugins/encrypt-models.js';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
// Il configuratore è servito da Laravel sotto /configuratore/ (stessa origine dell'API):
|
// Il configuratore è servito da Laravel sotto /configuratore/ (stessa origine dell'API):
|
||||||
@@ -26,11 +29,16 @@ export default defineConfig({
|
|||||||
viteStaticCopy({
|
viteStaticCopy({
|
||||||
targets: [
|
targets: [
|
||||||
{
|
{
|
||||||
src: 'assets',
|
// I modelli 3D non vengono copiati così come sono: li comprime dracoModels.
|
||||||
dest: ''
|
src: ['assets/*', '!assets/models'],
|
||||||
|
dest: 'assets'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
|
dracoModels({
|
||||||
|
modelsDir: path.resolve(__dirname, 'src/assets/models'),
|
||||||
|
cacheDir: path.resolve(__dirname, 'node_modules/.cache/draco-models'),
|
||||||
|
}),
|
||||||
ViteMinifyPlugin({
|
ViteMinifyPlugin({
|
||||||
minify: {
|
minify: {
|
||||||
removeComments: true,
|
removeComments: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user