@sparkjsdev/spark 0.1.9 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/assets/{worker-BZGuPoka.js.map → worker-BbYVeANL.js.map} +1 -1
- package/dist/assets/{worker-erPBjhH-.js.map → worker-CaMzlx2k.js.map} +1 -1
- package/dist/spark.cjs.js +83 -39
- package/dist/spark.cjs.js.map +1 -1
- package/dist/spark.cjs.min.js +50 -36
- package/dist/spark.cjs.min.js.map +1 -1
- package/dist/spark.module.js +83 -39
- package/dist/spark.module.js.map +1 -1
- package/dist/spark.module.min.js +1044 -1011
- package/dist/spark.module.min.js.map +1 -1
- package/dist/types/SparkRenderer.d.ts +9 -0
- package/dist/types/SplatLoader.d.ts +29 -2
- package/dist/types/index.d.ts +1 -0
- package/dist/types/pcsogs.d.ts +2 -2
- package/dist/types/spz.d.ts +3 -1
- package/dist/types/utils.d.ts +2 -4
- package/package.json +1 -1
package/dist/spark.cjs.js
CHANGED
|
@@ -3184,25 +3184,20 @@ class GunzipReader {
|
|
|
3184
3184
|
}) {
|
|
3185
3185
|
this.fileBytes = fileBytes;
|
|
3186
3186
|
this.chunkBytes = chunkBytes;
|
|
3187
|
-
this.offset = 0;
|
|
3188
3187
|
this.chunks = [];
|
|
3189
3188
|
this.totalBytes = 0;
|
|
3190
|
-
|
|
3189
|
+
const ds = new DecompressionStream("gzip");
|
|
3190
|
+
const decompressionStream = new Blob([fileBytes]).stream().pipeThrough(ds);
|
|
3191
|
+
this.reader = decompressionStream.getReader();
|
|
3192
|
+
}
|
|
3193
|
+
async read(numBytes) {
|
|
3194
|
+
while (this.totalBytes < numBytes) {
|
|
3195
|
+
const { value: chunk, done: readerDone } = await this.reader.read();
|
|
3196
|
+
if (readerDone) {
|
|
3197
|
+
break;
|
|
3198
|
+
}
|
|
3191
3199
|
this.chunks.push(chunk);
|
|
3192
3200
|
this.totalBytes += chunk.length;
|
|
3193
|
-
});
|
|
3194
|
-
}
|
|
3195
|
-
read(numBytes) {
|
|
3196
|
-
while (this.totalBytes < numBytes && this.offset < this.fileBytes.length) {
|
|
3197
|
-
const end = Math.min(
|
|
3198
|
-
this.offset + this.chunkBytes,
|
|
3199
|
-
this.fileBytes.length
|
|
3200
|
-
);
|
|
3201
|
-
this.gunzip.push(this.fileBytes.subarray(this.offset, end), false);
|
|
3202
|
-
this.offset = end;
|
|
3203
|
-
}
|
|
3204
|
-
if (this.totalBytes < numBytes && this.offset >= this.fileBytes.length) {
|
|
3205
|
-
this.gunzip.push(new Uint8Array(0), true);
|
|
3206
3201
|
}
|
|
3207
3202
|
if (this.totalBytes < numBytes) {
|
|
3208
3203
|
throw new Error(
|
|
@@ -8585,7 +8580,7 @@ function getNumSh(properties) {
|
|
|
8585
8580
|
}
|
|
8586
8581
|
return numSh;
|
|
8587
8582
|
}
|
|
8588
|
-
const jsContent = '(function() {\n "use strict";\n let wasm;\n const cachedTextDecoder = typeof TextDecoder !== "undefined" ? new TextDecoder("utf-8", { ignoreBOM: true, fatal: true }) : { decode: () => {\n throw Error("TextDecoder not available");\n } };\n if (typeof TextDecoder !== "undefined") {\n cachedTextDecoder.decode();\n }\n let cachedUint8ArrayMemory0 = null;\n function getUint8ArrayMemory0() {\n if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {\n cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);\n }\n return cachedUint8ArrayMemory0;\n }\n function getStringFromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));\n }\n function sort_splats(num_splats, readback, ordering) {\n const ret = wasm.sort_splats(num_splats, readback, ordering);\n return ret >>> 0;\n }\n function sort32_splats(num_splats, readback, ordering) {\n const ret = wasm.sort32_splats(num_splats, readback, ordering);\n return ret >>> 0;\n }\n async function __wbg_load(module, imports) {\n if (typeof Response === "function" && module instanceof Response) {\n if (typeof WebAssembly.instantiateStreaming === "function") {\n try {\n return await WebAssembly.instantiateStreaming(module, imports);\n } catch (e) {\n if (module.headers.get("Content-Type") != "application/wasm") {\n console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\\n", e);\n } else {\n throw e;\n }\n }\n }\n const bytes = await module.arrayBuffer();\n return await WebAssembly.instantiate(bytes, imports);\n } else {\n const instance = await WebAssembly.instantiate(module, imports);\n if (instance instanceof WebAssembly.Instance) {\n return { instance, module };\n } else {\n return instance;\n }\n }\n }\n function __wbg_get_imports() {\n const imports = {};\n imports.wbg = {};\n imports.wbg.__wbg_buffer_609cc3eee51ed158 = function(arg0) {\n const ret = arg0.buffer;\n return ret;\n };\n imports.wbg.__wbg_length_3b4f022188ae8db6 = function(arg0) {\n const ret = arg0.length;\n return ret;\n };\n imports.wbg.__wbg_length_6ca527665d89694d = function(arg0) {\n const ret = arg0.length;\n return ret;\n };\n imports.wbg.__wbg_length_8cfd2c6409af88ad = function(arg0) {\n const ret = arg0.length;\n return ret;\n };\n imports.wbg.__wbg_new_9fee97a409b32b68 = function(arg0) {\n const ret = new Uint16Array(arg0);\n return ret;\n };\n imports.wbg.__wbg_new_e3b321dcfef89fc7 = function(arg0) {\n const ret = new Uint32Array(arg0);\n return ret;\n };\n imports.wbg.__wbg_newwithbyteoffsetandlength_e6b7e69acd4c7354 = function(arg0, arg1, arg2) {\n const ret = new Float32Array(arg0, arg1 >>> 0, arg2 >>> 0);\n return ret;\n };\n imports.wbg.__wbg_newwithbyteoffsetandlength_f1dead44d1fc7212 = function(arg0, arg1, arg2) {\n const ret = new Uint32Array(arg0, arg1 >>> 0, arg2 >>> 0);\n return ret;\n };\n imports.wbg.__wbg_newwithlength_5a5efe313cfd59f1 = function(arg0) {\n const ret = new Float32Array(arg0 >>> 0);\n return ret;\n };\n imports.wbg.__wbg_set_10bad9bee0e9c58b = function(arg0, arg1, arg2) {\n arg0.set(arg1, arg2 >>> 0);\n };\n imports.wbg.__wbg_set_d23661d19148b229 = function(arg0, arg1, arg2) {\n arg0.set(arg1, arg2 >>> 0);\n };\n imports.wbg.__wbg_set_f4f1f0daa30696fc = function(arg0, arg1, arg2) {\n arg0.set(arg1, arg2 >>> 0);\n };\n imports.wbg.__wbg_subarray_3aaeec89bb2544f0 = function(arg0, arg1, arg2) {\n const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);\n return ret;\n };\n imports.wbg.__wbg_subarray_769e1e0f81bb259b = function(arg0, arg1, arg2) {\n const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);\n return ret;\n };\n imports.wbg.__wbindgen_init_externref_table = function() {\n const table = wasm.__wbindgen_export_0;\n const offset = table.grow(4);\n table.set(0, void 0);\n table.set(offset + 0, void 0);\n table.set(offset + 1, null);\n table.set(offset + 2, true);\n table.set(offset + 3, false);\n };\n imports.wbg.__wbindgen_memory = function() {\n const ret = wasm.memory;\n return ret;\n };\n imports.wbg.__wbindgen_throw = function(arg0, arg1) {\n throw new Error(getStringFromWasm0(arg0, arg1));\n };\n return imports;\n }\n function __wbg_finalize_init(instance, module) {\n wasm = instance.exports;\n __wbg_init.__wbindgen_wasm_module = module;\n cachedUint8ArrayMemory0 = null;\n wasm.__wbindgen_start();\n return wasm;\n }\n async function __wbg_init(module_or_path) {\n if (wasm !== void 0) return wasm;\n if (typeof module_or_path !== "undefined") {\n if (Object.getPrototypeOf(module_or_path) === Object.prototype) {\n ({ module_or_path } = module_or_path);\n } else {\n console.warn("using deprecated parameters for the initialization function; pass a single object instead");\n }\n }\n if (typeof module_or_path === "undefined") {\n module_or_path = new URL("data:application/wasm;base64,AGFzbQEAAAABzAEeYAJ/fwF/YAJ/fwBgA39/fwF/YAF/AX9gA39/fwBgAX8AYAV/f39/fwBgA29/fwFvYAV/f39/fwF/YAFvAW9gA29vfwBgAW8Bf2AAAX9gBH9/f38AYAAAYAR/f39/AX9gA39vbwF/YAF/AW9gAAFvYAF9AX1gBn9/f39/fwBgDX19fX19fX19f29/fX0Bb2AGf39/f39/AX9gBX9/fH9/AGAEf3x/fwBgBX9/fX9/AGAEf31/fwBgBX9/fn9/AGAEf35/fwBgAn19AX0C8gQRA3diZx1fX3diZ19idWZmZXJfNjA5Y2MzZWVlNTFlZDE1OAAJA3diZxpfX3diZ19uZXdfOWZlZTk3YTQwOWIzMmI2OAAJA3diZxpfX3diZ19zZXRfZjRmMWYwZGFhMzA2OTZmYwAKA3diZx1fX3diZ19sZW5ndGhfOGNmZDJjNjQwOWFmODhhZAALA3diZzFfX3diZ19uZXd3aXRoYnl0ZW9mZnNldGFuZGxlbmd0aF9mMWRlYWQ0NGQxZmM3MjEyAAcDd2JnGl9fd2JnX25ld19lM2IzMjFkY2ZlZjg5ZmM3AAkDd2JnGl9fd2JnX3NldF9kMjM2NjFkMTkxNDhiMjI5AAoDd2JnHV9fd2JnX2xlbmd0aF82Y2E1Mjc2NjVkODk2OTRkAAsDd2JnMV9fd2JnX25ld3dpdGhieXRlb2Zmc2V0YW5kbGVuZ3RoX2U2YjdlNjlhY2Q0YzczNTQABwN3YmcaX193Ymdfc2V0XzEwYmFkOWJlZTBlOWM1OGIACgN3YmcdX193YmdfbGVuZ3RoXzNiNGYwMjIxODhhZThkYjYACwN3YmcfX193Ymdfc3ViYXJyYXlfNzY5ZTFlMGY4MWJiMjU5YgAHA3diZx9fX3diZ19zdWJhcnJheV8zYWFlZWM4OWJiMjU0NGYwAAcDd2JnJF9fd2JnX25ld3dpdGhsZW5ndGhfNWE1ZWZlMzEzY2ZkNTlmMQARA3diZxBfX3diaW5kZ2VuX3Rocm93AAEDd2JnEV9fd2JpbmRnZW5fbWVtb3J5ABIDd2JnH19fd2JpbmRnZW5faW5pdF9leHRlcm5yZWZfdGFibGUADgNhYAMAAQIIBQQCEwEMAAEBAgAAAQwBBAYFBQQAAQYFFAENBAAGBQQEAQQOAgECAQAIBAAVARYG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ACIDKAIEQXhxRgRAIAMhAgwBCyABQRkgAkEBdmtBACACQR9HG3QhBQNAIAMgBUEddkEEcWpBEGoiBCgCACICRQ0CIAVBAXQhBSACIQMgAigCBEF4cSABRw0ACwsgAigCCCIBIAA2AgwgAiAANgIIIABBADYCGCAAIAI2AgwgACABNgIIDwsgBCAANgIAIAAgAzYCGCAAIAA2AgwgACAANgIIC/MCAQR/IwBBMGsiACQAAkACQEGQksAAKAIARQRAQaiSwAAoAgAhAUGoksAAQQA2AgAgAUUNASAAQRhqIAERBQAgAEEQaiICIABBJGopAgA3AwAgACAAKQIcNwMIIAAoAhghAUGQksAAKAIAIgMNAgJAIANFDQBBlJLAACgCACICRQ0AQZiSwAAoAgAgAkECdBBlC0GUksAAIAE2AgBBkJLAAEEBNgIAQZiSwAAgACkDCDcCAEGgksAAIABBEGopAwA3AgALIABBMGokAEGUksAADwsgAEEANgIoIABBATYCHCAAQaCHwAA2AhggAEIENwIgIABBGGpBiIjAABBDAAsgAEEoaiACKQMANwIAIAAgACkDCDcCICAAIAE2AhwgAEEBNgIYAkAgAEEYaiIBKAIARQ0AIAEoAgQiAkUNACABKAIIIAJBAnQQZQsgAEEANgIoIABBATYCHCAAQaiIwAA2AhggAEIENwIgIAFBsIjAABBDAAuoAgIDfwF+IwBBQGoiAiQAIAEoAgBBgICAgHhGBEAgASgCDCEDIAJBJGoiBEEANgIAIAJCgICAgBA3AhwgAkEwaiADKAIAIgNBCGopAgA3AwAgAkE4aiADQRBqKQIANwMAIAIgAykCADcDKCACQRxqQcCIwAAgAkEoahAYGiACQRhqIAQoAgAiAzYCACACIAIpAhwiBTcDECABQQhqIAM2AgAgASAFNwIACyABKQIAIQUgAUKAgICAEDcCACACQQhqIgMgAUEIaiIBKAIANgIAIAFBADYCAEGxk8AALQAAGiACIAU3AwBBDEEEEF0iAUUEQEEEQQwQbQALIAEgAikDADcCACABQQhqIAMoAgA2AgAgAEHgisAANgIEIAAgATYCACACQUBrJAAL0gECBH8BfiMAQSBrIgMkACABIAEgAmoiAksEQEEAQQAQUgALQQggACgCACIEQQF0IgEgAiABIAJLGyICIAJBCEkb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QQRqrUKAgICA4ACENwMoIAEgAa1CgICAgOAAhDcDICABIAFBIGo2AhAgAUEIakHIj8AAEEMAC2kCAX8BfiMAQTBrIgMkACADIAE2AgQgAyAANgIAIANBAjYCDCADQfyNwAA2AgggA0ICNwIUIANCgICAgOAAIgQgA62ENwMoIAMgBCADQQRqrYQ3AyAgAyADQSBqNgIQIANBCGogAhBDAAtpAgF/AX4jAEEwayIDJAAgAyAANgIAIAMgATYCBCADQQI2AgwgA0H4kcAANgIIIANCAjcCFCADQoCAgIDgACIEIANBBGqthDcDKCADIAQgA62ENwMgIAMgA0EgajYCECADQQhqIAIQQwALZgAjAEEwayIAJABBsJPAAC0AAARAIABBAjYCDCAAQbCKwAA2AgggAEIBNwIUIAAgATYCLCAAIABBLGqtQoCAgIDgAIQ3AyAgACAAQSBqNgIQIABBCGpB0IrAABBDAAsgAEEwaiQAC5QBAgN/AW8jAEEgayIDJAAgAyAAKAIAEHAiBDYCACADIAI2AgQgAiAERwRAIANBADYCCCADIANBBGogA0EIahBAAAsQWyIEEFMiBSUBEAUhBhAbIgIgBiYBIAVBhAFPBEAgBRAtCyACIAAoAgAgAUECdhBkIAJBhAFPBEAgAhAtCyAEQYQBTwRAIAQQLQsgA0EgaiQAC08BAX8jAEEwayIAJAAgAEEBNgIMIABBwI3AADYCCCAAQgE3AhQgACAAQS9qrUKAgICAoAWENwMgIAAgAEEgajYCECAAQQhqQcSBwAAQQwALQQEBfyACIAAoAgAgACgCCCIDa0sEQCAAIAMgAhAlIAAoAgghAwsgACgCBCADaiABIAIQHxogACACIANqNgIIQQALTQECf0Gxk8AALQAAGiABKAIEIQIgASgCACEDQQhBBBBdIgFFBEBBBEEIEG0ACyABIAI2AgQgASADNgIAIABB8IrAADYCBCAAIAE2AgALQQEBfyACIAAoAgAgACgCCCIDa0sEQCAAIAMgAhApIAAoAgghAwsgACgCBCADaiABIAIQHxogACACIANqNgIIQQALQQEBfyMAQSBrIgIkACACQQA2AhAgAkEBNgIEIAJCBDcCCCACQS42AhwgAiAANgIYIAIgAkEYajYCACACIAEQQwALswIBA38gACgCACECIAEoAhwiAEEQcUUE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ZCByZWN1cnNpdmVseSBvciBhZnRlciBiZWluZyBkcm9wcGVkTGF6eSBpbnN0YW5jZSBoYXMgcHJldmlvdXNseSBiZWVuIHBvaXNvbmVkdgMQACoAAAAvVXNlcnMvZG1hcmNvcy8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby02ZjE3ZDIyYmJhMTUwMDFmL29uY2VfY2VsbC0xLjIxLjMvc3JjL2xpYi5ycwCoAxAAXwAAAAgDAAAZAAAAcmVlbnRyYW50IGluaXQAABgEEAAOAAAAqAMQAF8AAAB6AgAADQAAABYAAAAMAAAABAAAABcAAAAYAAAAGQAAAC9ydXN0L2RlcHMvZGxtYWxsb2MtMC4yLjYvc3JjL2RsbWFsbG9jLnJzYXNzZXJ0aW9uIGZhaWxlZDogcHNpemUgPj0gc2l6ZSArIG1pbl9vdmVyaGVhZABYBBAAKQAAAKgEAAAJAAAAYXNzZXJ0aW9uIGZhaWxlZDogcHNpemUgPD0gc2l6ZSArIG1heF9vdmVyaGVhZAAAWAQQACkAAACuBAAADQAAAEFjY2Vzc0Vycm9ybWVtb3J5IGFsbG9jYXRpb24gb2YgIGJ5dGVzIGZhaWxlZAAAAAsFEAAVAAAAIAUQAA0AAABzdGQvc3JjL2FsbG9jLnJzQAUQABAAAABjAQAACQAAABYAAAAMAAAABAAAABoAAAAAAAAACAAAAAQAAAAbAAAAAAAAAAgAAAAEAAAAHAAAAB0AAAAeAAAAHwAAACAAAAAQAAAABAAAACEAAAAiAAAAIwAAACQAAABFcnJvcgAAACUAAAAMAAAABAAAACYAAAAnAAAAKAAAAGNhcGFjaXR5IG92ZXJmbG93AAAA2AUQABEAAABhbGxvYy9zcmMvcmF3X3ZlYy5yc/QFEAAUAAAAGAAAAAUAQaCMwAAL8AUBAAAAKQAAAGEgZm9ybWF0dGluZyB0cmFpdCBpbXBsZW1lbnRhdGlvbiByZXR1cm5lZCBhbiBlcnJvciB3aGVuIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSBkaWQgbm90YWxsb2Mvc3JjL2ZtdC5ycwAAfgYQABAAAAB+AgAADgAAAEJvcnJvd011dEVycm9yYWxyZWFkeSBib3Jyb3dlZDogrgYQABIAAABpbmRleCBvdXQgb2YgYm91bmRzOiB0aGUgbGVuIGlzICBidXQgdGhlIGluZGV4IGlzIAAAyAYQACAAAADoBhAAEgAAAD09IT1tYXRjaGVzYXNzZXJ0aW9uIGBsZWZ0ICByaWdodGAgZmFpbGVkCiAgbGVmdDogCiByaWdodDogABcHEAAQAAAAJwcQABcAAAA+BxAACQAAACByaWdodGAgZmFpbGVkOiAKICBsZWZ0OiAAAAAXBxAAEAAAAGAHEAAQAAAAcAcQAAkAAAA+BxAACQAAADogAAABAAAAAAAAAJwHEAACAAAAfSB9Y29yZS9zcmMvZm10L251bS5ycwAAswcQABMAAABmAAAAFwAAADB4MDAwMTAyMDMwNDA1MDYwNzA4MDkxMDExMTIxMzE0MTUxNjE3MTgxOTIwMjEyMjIzMjQyNTI2MjcyODI5MzAzMTMyMzMzNDM1MzYzNzM4Mzk0MDQxNDI0MzQ0NDU0NjQ3NDg0OTUwNTE1MjUzNTQ1NTU2NTc1ODU5NjA2MTYyNjM2NDY1NjY2NzY4Njk3MDcxNzI3Mzc0NzU3Njc3Nzg3OTgwODE4MjgzODQ4NTg2ODc4ODg5OTA5MTkyOTM5NDk1OTY5Nzk4OTlyYW5nZSBzdGFydCBpbmRleCAgb3V0IG9mIHJhbmdlIGZvciBzbGljZSBvZiBsZW5ndGggAACiCBAAEgAAALQIEAAiAAAAcmFuZ2UgZW5kIGluZGV4IOgIEAAQAAAAtAgQACIAAAAAAAA/AAAAvwBBqJLAAAsBFABwCXByb2R1Y2VycwIIbGFuZ3VhZ2UBBFJ1c3QADHByb2Nlc3NlZC1ieQMFcnVzdGMdMS44My4wICg5MGIzNWE2MjMgMjAyNC0xMS0yNikGd2FscnVzBjAuMjMuMwx3YXNtLWJpbmRnZW4HMC4yLjEwMABJD3RhcmdldF9mZWF0dXJlcwQrD211dGFibGUtZ2xvYmFscysIc2lnbi1leHQrD3JlZmVyZW5jZS10eXBlcysKbXVsdGl2YWx1ZQ==", self.location.href);\n }\n const imports = __wbg_get_imports();\n if (typeof module_or_path === "string" || typeof Request === "function" && module_or_path instanceof Request || typeof URL === "function" && module_or_path instanceof URL) {\n module_or_path = fetch(module_or_path);\n }\n const { instance, module } = await __wbg_load(await module_or_path, imports);\n return __wbg_finalize_init(instance, module);\n }\n var ch2 = {};\n var wk = function(c, id, msg, transfer, cb) {\n var w = new Worker(ch2[id] || (ch2[id] = URL.createObjectURL(new Blob([\n c + \';addEventListener("error",function(e){e=e.error;postMessage({$e$:[e.message,e.code,e.stack]})})\'\n ], { type: "text/javascript" }))));\n w.onmessage = function(e) {\n var d = e.data, ed = d.$e$;\n if (ed) {\n var err2 = new Error(ed[0]);\n err2["code"] = ed[1];\n err2.stack = ed[2];\n cb(err2, null);\n } else\n cb(null, d);\n };\n w.postMessage(msg, transfer);\n return w;\n };\n var u8 = Uint8Array, u16 = Uint16Array, i32 = Int32Array;\n var fleb = new u8([\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 1,\n 1,\n 1,\n 1,\n 2,\n 2,\n 2,\n 2,\n 3,\n 3,\n 3,\n 3,\n 4,\n 4,\n 4,\n 4,\n 5,\n 5,\n 5,\n 5,\n 0,\n /* unused */\n 0,\n 0,\n /* impossible */\n 0\n ]);\n var fdeb = new u8([\n 0,\n 0,\n 0,\n 0,\n 1,\n 1,\n 2,\n 2,\n 3,\n 3,\n 4,\n 4,\n 5,\n 5,\n 6,\n 6,\n 7,\n 7,\n 8,\n 8,\n 9,\n 9,\n 10,\n 10,\n 11,\n 11,\n 12,\n 12,\n 13,\n 13,\n /* unused */\n 0,\n 0\n ]);\n var clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);\n var freb = function(eb, start) {\n var b = new u16(31);\n for (var i2 = 0; i2 < 31; ++i2) {\n b[i2] = start += 1 << eb[i2 - 1];\n }\n var r = new i32(b[30]);\n for (var i2 = 1; i2 < 30; ++i2) {\n for (var j = b[i2]; j < b[i2 + 1]; ++j) {\n r[j] = j - b[i2] << 5 | i2;\n }\n }\n return { b, r };\n };\n var _a = freb(fleb, 2), fl = _a.b, revfl = _a.r;\n fl[28] = 258, revfl[258] = 28;\n var _b = freb(fdeb, 0), fd = _b.b;\n var rev = new u16(32768);\n for (var i = 0; i < 32768; ++i) {\n var x = (i & 43690) >> 1 | (i & 21845) << 1;\n x = (x & 52428) >> 2 | (x & 13107) << 2;\n x = (x & 61680) >> 4 | (x & 3855) << 4;\n rev[i] = ((x & 65280) >> 8 | (x & 255) << 8) >> 1;\n }\n var hMap = function(cd, mb, r) {\n var s = cd.length;\n var i2 = 0;\n var l = new u16(mb);\n for (; i2 < s; ++i2) {\n if (cd[i2])\n ++l[cd[i2] - 1];\n }\n var le = new u16(mb);\n for (i2 = 1; i2 < mb; ++i2) {\n le[i2] = le[i2 - 1] + l[i2 - 1] << 1;\n }\n var co;\n if (r) {\n co = new u16(1 << mb);\n var rvb = 15 - mb;\n for (i2 = 0; i2 < s; ++i2) {\n if (cd[i2]) {\n var sv = i2 << 4 | cd[i2];\n var r_1 = mb - cd[i2];\n var v = le[cd[i2] - 1]++ << r_1;\n for (var m = v | (1 << r_1) - 1; v <= m; ++v) {\n co[rev[v] >> rvb] = sv;\n }\n }\n }\n } else {\n co = new u16(s);\n for (i2 = 0; i2 < s; ++i2) {\n if (cd[i2]) {\n co[i2] = rev[le[cd[i2] - 1]++] >> 15 - cd[i2];\n }\n }\n }\n return co;\n };\n var flt = new u8(288);\n for (var i = 0; i < 144; ++i)\n flt[i] = 8;\n for (var i = 144; i < 256; ++i)\n flt[i] = 9;\n for (var i = 256; i < 280; ++i)\n flt[i] = 7;\n for (var i = 280; i < 288; ++i)\n flt[i] = 8;\n var fdt = new u8(32);\n for (var i = 0; i < 32; ++i)\n fdt[i] = 5;\n var flrm = /* @__PURE__ */ hMap(flt, 9, 1);\n var fdrm = /* @__PURE__ */ hMap(fdt, 5, 1);\n var max = function(a) {\n var m = a[0];\n for (var i2 = 1; i2 < a.length; ++i2) {\n if (a[i2] > m)\n m = a[i2];\n }\n return m;\n };\n var bits = function(d, p, m) {\n var o = p / 8 | 0;\n return (d[o] | d[o + 1] << 8) >> (p & 7) & m;\n };\n var bits16 = function(d, p) {\n var o = p / 8 | 0;\n return (d[o] | d[o + 1] << 8 | d[o + 2] << 16) >> (p & 7);\n };\n var shft = function(p) {\n return (p + 7) / 8 | 0;\n };\n var slc = function(v, s, e) {\n if (s == null || s < 0)\n s = 0;\n if (e == null || e > v.length)\n e = v.length;\n return new u8(v.subarray(s, e));\n };\n var ec = [\n "unexpected EOF",\n "invalid block type",\n "invalid length/literal",\n "invalid distance",\n "stream finished",\n "no stream handler",\n ,\n "no callback",\n "invalid UTF-8 data",\n "extra field too long",\n "date not in range 1980-2099",\n "filename too long",\n "stream finishing",\n "invalid zip data"\n // determined by unknown compression method\n ];\n var err = function(ind, msg, nt) {\n var e = new Error(msg || ec[ind]);\n e.code = ind;\n if (Error.captureStackTrace)\n Error.captureStackTrace(e, err);\n if (!nt)\n throw e;\n return e;\n };\n var inflt = function(dat, st, buf, dict) {\n var sl = dat.length, dl = dict ? dict.length : 0;\n if (!sl || st.f && !st.l)\n return buf || new u8(0);\n var noBuf = !buf;\n var resize = noBuf || st.i != 2;\n var noSt = st.i;\n if (noBuf)\n buf = new u8(sl * 3);\n var cbuf = function(l2) {\n var bl = buf.length;\n if (l2 > bl) {\n var nbuf = new u8(Math.max(bl * 2, l2));\n nbuf.set(buf);\n buf = nbuf;\n }\n };\n var final = st.f || 0, pos = st.p || 0, bt = st.b || 0, lm = st.l, dm = st.d, lbt = st.m, dbt = st.n;\n var tbts = sl * 8;\n do {\n if (!lm) {\n final = bits(dat, pos, 1);\n var type = bits(dat, pos + 1, 3);\n pos += 3;\n if (!type) {\n var s = shft(pos) + 4, l = dat[s - 4] | dat[s - 3] << 8, t = s + l;\n if (t > sl) {\n if (noSt)\n err(0);\n break;\n }\n if (resize)\n cbuf(bt + l);\n buf.set(dat.subarray(s, t), bt);\n st.b = bt += l, st.p = pos = t * 8, st.f = final;\n continue;\n } else if (type == 1)\n lm = flrm, dm = fdrm, lbt = 9, dbt = 5;\n else if (type == 2) {\n var hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;\n var tl = hLit + bits(dat, pos + 5, 31) + 1;\n pos += 14;\n var ldt = new u8(tl);\n var clt = new u8(19);\n for (var i2 = 0; i2 < hcLen; ++i2) {\n clt[clim[i2]] = bits(dat, pos + i2 * 3, 7);\n }\n pos += hcLen * 3;\n var clb = max(clt), clbmsk = (1 << clb) - 1;\n var clm = hMap(clt, clb, 1);\n for (var i2 = 0; i2 < tl; ) {\n var r = clm[bits(dat, pos, clbmsk)];\n pos += r & 15;\n var s = r >> 4;\n if (s < 16) {\n ldt[i2++] = s;\n } else {\n var c = 0, n = 0;\n if (s == 16)\n n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i2 - 1];\n else if (s == 17)\n n = 3 + bits(dat, pos, 7), pos += 3;\n else if (s == 18)\n n = 11 + bits(dat, pos, 127), pos += 7;\n while (n--)\n ldt[i2++] = c;\n }\n }\n var lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit);\n lbt = max(lt);\n dbt = max(dt);\n lm = hMap(lt, lbt, 1);\n dm = hMap(dt, dbt, 1);\n } else\n err(1);\n if (pos > tbts) {\n if (noSt)\n err(0);\n break;\n }\n }\n if (resize)\n cbuf(bt + 131072);\n var lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;\n var lpos = pos;\n for (; ; lpos = pos) {\n var c = lm[bits16(dat, pos) & lms], sym = c >> 4;\n pos += c & 15;\n if (pos > tbts) {\n if (noSt)\n err(0);\n break;\n }\n if (!c)\n err(2);\n if (sym < 256)\n buf[bt++] = sym;\n else if (sym == 256) {\n lpos = pos, lm = null;\n break;\n } else {\n var add = sym - 254;\n if (sym > 264) {\n var i2 = sym - 257, b = fleb[i2];\n add = bits(dat, pos, (1 << b) - 1) + fl[i2];\n pos += b;\n }\n var d = dm[bits16(dat, pos) & dms], dsym = d >> 4;\n if (!d)\n err(3);\n pos += d & 15;\n var dt = fd[dsym];\n if (dsym > 3) {\n var b = fdeb[dsym];\n dt += bits16(dat, pos) & (1 << b) - 1, pos += b;\n }\n if (pos > tbts) {\n if (noSt)\n err(0);\n break;\n }\n if (resize)\n cbuf(bt + 131072);\n var end = bt + add;\n if (bt < dt) {\n var shift = dl - dt, dend = Math.min(dt, end);\n if (shift + bt < 0)\n err(3);\n for (; bt < dend; ++bt)\n buf[bt] = dict[shift + bt];\n }\n for (; bt < end; ++bt)\n buf[bt] = buf[bt - dt];\n }\n }\n st.l = lm, st.p = lpos, st.b = bt, st.f = final;\n if (lm)\n final = 1, st.m = lbt, st.d = dm, st.n = dbt;\n } while (!final);\n return bt != buf.length && noBuf ? slc(buf, 0, bt) : buf.subarray(0, bt);\n };\n var et = /* @__PURE__ */ new u8(0);\n var mrg = function(a, b) {\n var o = {};\n for (var k in a)\n o[k] = a[k];\n for (var k in b)\n o[k] = b[k];\n return o;\n };\n var wcln = function(fn, fnStr, td2) {\n var dt = fn();\n var st = fn.toString();\n var ks = st.slice(st.indexOf("[") + 1, st.lastIndexOf("]")).replace(/\\s+/g, "").split(",");\n for (var i2 = 0; i2 < dt.length; ++i2) {\n var v = dt[i2], k = ks[i2];\n if (typeof v == "function") {\n fnStr += ";" + k + "=";\n var st_1 = v.toString();\n if (v.prototype) {\n if (st_1.indexOf("[native code]") != -1) {\n var spInd = st_1.indexOf(" ", 8) + 1;\n fnStr += st_1.slice(spInd, st_1.indexOf("(", spInd));\n } else {\n fnStr += st_1;\n for (var t in v.prototype)\n fnStr += ";" + k + ".prototype." + t + "=" + v.prototype[t].toString();\n }\n } else\n fnStr += st_1;\n } else\n td2[k] = v;\n }\n return fnStr;\n };\n var ch = [];\n var cbfs = function(v) {\n var tl = [];\n for (var k in v) {\n if (v[k].buffer) {\n tl.push((v[k] = new v[k].constructor(v[k])).buffer);\n }\n }\n return tl;\n };\n var wrkr = function(fns, init, id, cb) {\n if (!ch[id]) {\n var fnStr = "", td_1 = {}, m = fns.length - 1;\n for (var i2 = 0; i2 < m; ++i2)\n fnStr = wcln(fns[i2], fnStr, td_1);\n ch[id] = { c: wcln(fns[m], fnStr, td_1), e: td_1 };\n }\n var td2 = mrg({}, ch[id].e);\n return wk(ch[id].c + ";onmessage=function(e){for(var k in e.data)self[k]=e.data[k];onmessage=" + init.toString() + "}", id, td2, cbfs(td2), cb);\n };\n var bInflt = function() {\n return [u8, u16, i32, fleb, fdeb, clim, fl, fd, flrm, fdrm, rev, ec, hMap, max, bits, bits16, shft, slc, err, inflt, inflateSync, pbf, gopt];\n };\n var pbf = function(msg) {\n return postMessage(msg, [msg.buffer]);\n };\n var gopt = function(o) {\n return o && {\n out: o.size && new u8(o.size),\n dictionary: o.dictionary\n };\n };\n var cbify = function(dat, opts, fns, init, id, cb) {\n var w = wrkr(fns, init, id, function(err2, dat2) {\n w.terminate();\n cb(err2, dat2);\n });\n w.postMessage([dat, opts], opts.consume ? [dat.buffer] : []);\n return function() {\n w.terminate();\n };\n };\n var b2 = function(d, b) {\n return d[b] | d[b + 1] << 8;\n };\n var b4 = function(d, b) {\n return (d[b] | d[b + 1] << 8 | d[b + 2] << 16 | d[b + 3] << 24) >>> 0;\n };\n var b8 = function(d, b) {\n return b4(d, b) + b4(d, b + 4) * 4294967296;\n };\n var gzs = function(d) {\n if (d[0] != 31 || d[1] != 139 || d[2] != 8)\n err(6, "invalid gzip data");\n var flg = d[3];\n var st = 10;\n if (flg & 4)\n st += (d[10] | d[11] << 8) + 2;\n for (var zs = (flg >> 3 & 1) + (flg >> 4 & 1); zs > 0; zs -= !d[st++])\n ;\n return st + (flg & 2);\n };\n var Inflate = /* @__PURE__ */ function() {\n function Inflate2(opts, cb) {\n if (typeof opts == "function")\n cb = opts, opts = {};\n this.ondata = cb;\n var dict = opts && opts.dictionary && opts.dictionary.subarray(-32768);\n this.s = { i: 0, b: dict ? dict.length : 0 };\n this.o = new u8(32768);\n this.p = new u8(0);\n if (dict)\n this.o.set(dict);\n }\n Inflate2.prototype.e = function(c) {\n if (!this.ondata)\n err(5);\n if (this.d)\n err(4);\n if (!this.p.length)\n this.p = c;\n else if (c.length) {\n var n = new u8(this.p.length + c.length);\n n.set(this.p), n.set(c, this.p.length), this.p = n;\n }\n };\n Inflate2.prototype.c = function(final) {\n this.s.i = +(this.d = final || false);\n var bts = this.s.b;\n var dt = inflt(this.p, this.s, this.o);\n this.ondata(slc(dt, bts, this.s.b), this.d);\n this.o = slc(dt, this.s.b - 32768), this.s.b = this.o.length;\n this.p = slc(this.p, this.s.p / 8 | 0), this.s.p &= 7;\n };\n Inflate2.prototype.push = function(chunk, final) {\n this.e(chunk), this.c(final);\n };\n return Inflate2;\n }();\n function inflate(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != "function")\n err(7);\n return cbify(data, opts, [\n bInflt\n ], function(ev) {\n return pbf(inflateSync(ev.data[0], gopt(ev.data[1])));\n }, 1, cb);\n }\n function inflateSync(data, opts) {\n return inflt(data, { i: 2 }, opts && opts.out, opts && opts.dictionary);\n }\n var Gunzip = /* @__PURE__ */ function() {\n function Gunzip2(opts, cb) {\n this.v = 1;\n this.r = 0;\n Inflate.call(this, opts, cb);\n }\n Gunzip2.prototype.push = function(chunk, final) {\n Inflate.prototype.e.call(this, chunk);\n this.r += chunk.length;\n if (this.v) {\n var p = this.p.subarray(this.v - 1);\n var s = p.length > 3 ? gzs(p) : 4;\n if (s > p.length) {\n if (!final)\n return;\n } else if (this.v > 1 && this.onmember) {\n this.onmember(this.r - p.length);\n }\n this.p = p.subarray(s), this.v = 0;\n }\n Inflate.prototype.c.call(this, final);\n if (this.s.f && !this.s.l && !final) {\n this.v = shft(this.s.p) + 9;\n this.s = { i: 0 };\n this.o = new u8(0);\n this.push(new u8(0), final);\n }\n };\n return Gunzip2;\n }();\n var td = typeof TextDecoder != "undefined" && /* @__PURE__ */ new TextDecoder();\n try {\n td.decode(et, { stream: true });\n } catch (e) {\n }\n var dutf8 = function(d) {\n for (var r = "", i2 = 0; ; ) {\n var c = d[i2++];\n var eb = (c > 127) + (c > 223) + (c > 239);\n if (i2 + eb > d.length)\n return { s: r, r: slc(d, i2 - 1) };\n if (!eb)\n r += String.fromCharCode(c);\n else if (eb == 3) {\n c = ((c & 15) << 18 | (d[i2++] & 63) << 12 | (d[i2++] & 63) << 6 | d[i2++] & 63) - 65536, r += String.fromCharCode(55296 | c >> 10, 56320 | c & 1023);\n } else if (eb & 1)\n r += String.fromCharCode((c & 31) << 6 | d[i2++] & 63);\n else\n r += String.fromCharCode((c & 15) << 12 | (d[i2++] & 63) << 6 | d[i2++] & 63);\n }\n };\n function strFromU8(dat, latin1) {\n if (latin1) {\n var r = "";\n for (var i2 = 0; i2 < dat.length; i2 += 16384)\n r += String.fromCharCode.apply(null, dat.subarray(i2, i2 + 16384));\n return r;\n } else if (td) {\n return td.decode(dat);\n } else {\n var _a2 = dutf8(dat), s = _a2.s, r = _a2.r;\n if (r.length)\n err(8);\n return s;\n }\n }\n var slzh = function(d, b) {\n return b + 30 + b2(d, b + 26) + b2(d, b + 28);\n };\n var zh = function(d, b, z) {\n var fnl = b2(d, b + 28), fn = strFromU8(d.subarray(b + 46, b + 46 + fnl), !(b2(d, b + 8) & 2048)), es = b + 46 + fnl, bs = b4(d, b + 20);\n var _a2 = z && bs == 4294967295 ? z64e(d, es) : [bs, b4(d, b + 24), b4(d, b + 42)], sc = _a2[0], su = _a2[1], off = _a2[2];\n return [b2(d, b + 10), sc, su, fn, es + b2(d, b + 30) + b2(d, b + 32), off];\n };\n var z64e = function(d, b) {\n for (; b2(d, b) != 1; b += 4 + b2(d, b + 2))\n ;\n return [b8(d, b + 12), b8(d, b + 4), b8(d, b + 20)];\n };\n var mt = typeof queueMicrotask == "function" ? queueMicrotask : typeof setTimeout == "function" ? setTimeout : function(fn) {\n fn();\n };\n function unzip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != "function")\n err(7);\n var term = [];\n var tAll = function() {\n for (var i3 = 0; i3 < term.length; ++i3)\n term[i3]();\n };\n var files = {};\n var cbd = function(a, b) {\n mt(function() {\n cb(a, b);\n });\n };\n mt(function() {\n cbd = cb;\n });\n var e = data.length - 22;\n for (; b4(data, e) != 101010256; --e) {\n if (!e || data.length - e > 65558) {\n cbd(err(13, 0, 1), null);\n return tAll;\n }\n }\n var lft = b2(data, e + 8);\n if (lft) {\n var c = lft;\n var o = b4(data, e + 16);\n var z = o == 4294967295 || c == 65535;\n if (z) {\n var ze = b4(data, e - 12);\n z = b4(data, ze) == 101075792;\n if (z) {\n c = lft = b4(data, ze + 32);\n o = b4(data, ze + 48);\n }\n }\n var fltr = opts && opts.filter;\n var _loop_3 = function(i3) {\n var _a2 = zh(data, o, z), c_1 = _a2[0], sc = _a2[1], su = _a2[2], fn = _a2[3], no = _a2[4], off = _a2[5], b = slzh(data, off);\n o = no;\n var cbl = function(e2, d) {\n if (e2) {\n tAll();\n cbd(e2, null);\n } else {\n if (d)\n files[fn] = d;\n if (!--lft)\n cbd(null, files);\n }\n };\n if (!fltr || fltr({\n name: fn,\n size: sc,\n originalSize: su,\n compression: c_1\n })) {\n if (!c_1)\n cbl(null, slc(data, b, b + sc));\n else if (c_1 == 8) {\n var infl = data.subarray(b, b + sc);\n if (su < 524288 || sc > 0.8 * su) {\n try {\n cbl(null, inflateSync(infl, { out: new u8(su) }));\n } catch (e2) {\n cbl(e2, null);\n }\n } else\n term.push(inflate(infl, { size: su }, cbl));\n } else\n cbl(err(14, "unknown compression type " + c_1, 1), null);\n } else\n cbl(null, null);\n };\n for (var i2 = 0; i2 < c; ++i2) {\n _loop_3(i2);\n }\n } else\n cbd(null, {});\n return tAll;\n }\n function unzipSync(data, opts) {\n var files = {};\n var e = data.length - 22;\n for (; b4(data, e) != 101010256; --e) {\n if (!e || data.length - e > 65558)\n err(13);\n }\n var c = b2(data, e + 8);\n if (!c)\n return {};\n var o = b4(data, e + 16);\n var z = o == 4294967295 || c == 65535;\n if (z) {\n var ze = b4(data, e - 12);\n z = b4(data, ze) == 101075792;\n if (z) {\n c = b4(data, ze + 32);\n o = b4(data, ze + 48);\n }\n }\n var fltr = opts && opts.filter;\n for (var i2 = 0; i2 < c; ++i2) {\n var _a2 = zh(data, o, z), c_2 = _a2[0], sc = _a2[1], su = _a2[2], fn = _a2[3], no = _a2[4], off = _a2[5], b = slzh(data, off);\n o = no;\n if (!fltr || fltr({\n name: fn,\n size: sc,\n originalSize: su,\n compression: c_2\n })) {\n if (!c_2)\n files[fn] = slc(data, b, b + sc);\n else if (c_2 == 8)\n files[fn] = inflateSync(data.subarray(b, b + sc), { out: new u8(su) });\n else\n err(14, "unknown compression type " + c_2);\n }\n }\n return files;\n }\n /**\n * @license\n * Copyright 2010-2025 Three.js Authors\n * SPDX-License-Identifier: MIT\n */\n const REVISION = "178";\n const NoColorSpace = "";\n const SRGBColorSpace = "srgb";\n const LinearSRGBColorSpace = "srgb-linear";\n const LinearTransfer = "linear";\n const SRGBTransfer = "srgb";\n function clamp(value, min, max2) {\n return Math.max(min, Math.min(max2, value));\n }\n function euclideanModulo(n, m) {\n return (n % m + m) % m;\n }\n function lerp(x2, y, t) {\n return (1 - t) * x2 + t * y;\n }\n class Quaternion {\n /**\n * Constructs a new quaternion.\n *\n * @param {number} [x=0] - The x value of this quaternion.\n * @param {number} [y=0] - The y value of this quaternion.\n * @param {number} [z=0] - The z value of this quaternion.\n * @param {number} [w=1] - The w value of this quaternion.\n */\n constructor(x2 = 0, y = 0, z = 0, w = 1) {\n this.isQuaternion = true;\n this._x = x2;\n this._y = y;\n this._z = z;\n this._w = w;\n }\n /**\n * Interpolates between two quaternions via SLERP. This implementation assumes the\n * quaternion data are managed in flat arrays.\n *\n * @param {Array<number>} dst - The destination array.\n * @param {number} dstOffset - An offset into the destination array.\n * @param {Array<number>} src0 - The source array of the first quaternion.\n * @param {number} srcOffset0 - An offset into the first source array.\n * @param {Array<number>} src1 - The source array of the second quaternion.\n * @param {number} srcOffset1 - An offset into the second source array.\n * @param {number} t - The interpolation factor in the range `[0,1]`.\n * @see {@link Quaternion#slerp}\n */\n static slerpFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t) {\n let x0 = src0[srcOffset0 + 0], y0 = src0[srcOffset0 + 1], z0 = src0[srcOffset0 + 2], w0 = src0[srcOffset0 + 3];\n const x1 = src1[srcOffset1 + 0], y1 = src1[srcOffset1 + 1], z1 = src1[srcOffset1 + 2], w1 = src1[srcOffset1 + 3];\n if (t === 0) {\n dst[dstOffset + 0] = x0;\n dst[dstOffset + 1] = y0;\n dst[dstOffset + 2] = z0;\n dst[dstOffset + 3] = w0;\n return;\n }\n if (t === 1) {\n dst[dstOffset + 0] = x1;\n dst[dstOffset + 1] = y1;\n dst[dstOffset + 2] = z1;\n dst[dstOffset + 3] = w1;\n return;\n }\n if (w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1) {\n let s = 1 - t;\n const cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1, dir = cos >= 0 ? 1 : -1, sqrSin = 1 - cos * cos;\n if (sqrSin > Number.EPSILON) {\n const sin = Math.sqrt(sqrSin), len = Math.atan2(sin, cos * dir);\n s = Math.sin(s * len) / sin;\n t = Math.sin(t * len) / sin;\n }\n const tDir = t * dir;\n x0 = x0 * s + x1 * tDir;\n y0 = y0 * s + y1 * tDir;\n z0 = z0 * s + z1 * tDir;\n w0 = w0 * s + w1 * tDir;\n if (s === 1 - t) {\n const f = 1 / Math.sqrt(x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0);\n x0 *= f;\n y0 *= f;\n z0 *= f;\n w0 *= f;\n }\n }\n dst[dstOffset] = x0;\n dst[dstOffset + 1] = y0;\n dst[dstOffset + 2] = z0;\n dst[dstOffset + 3] = w0;\n }\n /**\n * Multiplies two quaternions. This implementation assumes the quaternion data are managed\n * in flat arrays.\n *\n * @param {Array<number>} dst - The destination array.\n * @param {number} dstOffset - An offset into the destination array.\n * @param {Array<number>} src0 - The source array of the first quaternion.\n * @param {number} srcOffset0 - An offset into the first source array.\n * @param {Array<number>} src1 - The source array of the second quaternion.\n * @param {number} srcOffset1 - An offset into the second source array.\n * @return {Array<number>} The destination array.\n * @see {@link Quaternion#multiplyQuaternions}.\n */\n static multiplyQuaternionsFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1) {\n const x0 = src0[srcOffset0];\n const y0 = src0[srcOffset0 + 1];\n const z0 = src0[srcOffset0 + 2];\n const w0 = src0[srcOffset0 + 3];\n const x1 = src1[srcOffset1];\n const y1 = src1[srcOffset1 + 1];\n const z1 = src1[srcOffset1 + 2];\n const w1 = src1[srcOffset1 + 3];\n dst[dstOffset] = x0 * w1 + w0 * x1 + y0 * z1 - z0 * y1;\n dst[dstOffset + 1] = y0 * w1 + w0 * y1 + z0 * x1 - x0 * z1;\n dst[dstOffset + 2] = z0 * w1 + w0 * z1 + x0 * y1 - y0 * x1;\n dst[dstOffset + 3] = w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1;\n return dst;\n }\n /**\n * The x value of this quaternion.\n *\n * @type {number}\n * @default 0\n */\n get x() {\n return this._x;\n }\n set x(value) {\n this._x = value;\n this._onChangeCallback();\n }\n /**\n * The y value of this quaternion.\n *\n * @type {number}\n * @default 0\n */\n get y() {\n return this._y;\n }\n set y(value) {\n this._y = value;\n this._onChangeCallback();\n }\n /**\n * The z value of this quaternion.\n *\n * @type {number}\n * @default 0\n */\n get z() {\n return this._z;\n }\n set z(value) {\n this._z = value;\n this._onChangeCallback();\n }\n /**\n * The w value of this quaternion.\n *\n * @type {number}\n * @default 1\n */\n get w() {\n return this._w;\n }\n set w(value) {\n this._w = value;\n this._onChangeCallback();\n }\n /**\n * Sets the quaternion components.\n *\n * @param {number} x - The x value of this quaternion.\n * @param {number} y - The y value of this quaternion.\n * @param {number} z - The z value of this quaternion.\n * @param {number} w - The w value of this quaternion.\n * @return {Quaternion} A reference to this quaternion.\n */\n set(x2, y, z, w) {\n this._x = x2;\n this._y = y;\n this._z = z;\n this._w = w;\n this._onChangeCallback();\n return this;\n }\n /**\n * Returns a new quaternion with copied values from this instance.\n *\n * @return {Quaternion} A clone of this instance.\n */\n clone() {\n return new this.constructor(this._x, this._y, this._z, this._w);\n }\n /**\n * Copies the values of the given quaternion to this instance.\n *\n * @param {Quaternion} quaternion - The quaternion to copy.\n * @return {Quaternion} A reference to this quaternion.\n */\n copy(quaternion) {\n this._x = quaternion.x;\n this._y = quaternion.y;\n this._z = quaternion.z;\n this._w = quaternion.w;\n this._onChangeCallback();\n return this;\n }\n /**\n * Sets this quaternion from the rotation specified by the given\n * Euler angles.\n *\n * @param {Euler} euler - The Euler angles.\n * @param {boolean} [update=true] - Whether the internal `onChange` callback should be executed or not.\n * @return {Quaternion} A reference to this quaternion.\n */\n setFromEuler(euler, update = true) {\n const x2 = euler._x, y = euler._y, z = euler._z, order = euler._order;\n const cos = Math.cos;\n const sin = Math.sin;\n const c1 = cos(x2 / 2);\n const c2 = cos(y / 2);\n const c3 = cos(z / 2);\n const s1 = sin(x2 / 2);\n const s2 = sin(y / 2);\n const s3 = sin(z / 2);\n switch (order) {\n case "XYZ":\n this._x = s1 * c2 * c3 + c1 * s2 * s3;\n this._y = c1 * s2 * c3 - s1 * c2 * s3;\n this._z = c1 * c2 * s3 + s1 * s2 * c3;\n this._w = c1 * c2 * c3 - s1 * s2 * s3;\n break;\n case "YXZ":\n this._x = s1 * c2 * c3 + c1 * s2 * s3;\n this._y = c1 * s2 * c3 - s1 * c2 * s3;\n this._z = c1 * c2 * s3 - s1 * s2 * c3;\n this._w = c1 * c2 * c3 + s1 * s2 * s3;\n break;\n case "ZXY":\n this._x = s1 * c2 * c3 - c1 * s2 * s3;\n this._y = c1 * s2 * c3 + s1 * c2 * s3;\n this._z = c1 * c2 * s3 + s1 * s2 * c3;\n this._w = c1 * c2 * c3 - s1 * s2 * s3;\n break;\n case "ZYX":\n this._x = s1 * c2 * c3 - c1 * s2 * s3;\n this._y = c1 * s2 * c3 + s1 * c2 * s3;\n this._z = c1 * c2 * s3 - s1 * s2 * c3;\n this._w = c1 * c2 * c3 + s1 * s2 * s3;\n break;\n case "YZX":\n this._x = s1 * c2 * c3 + c1 * s2 * s3;\n this._y = c1 * s2 * c3 + s1 * c2 * s3;\n this._z = c1 * c2 * s3 - s1 * s2 * c3;\n this._w = c1 * c2 * c3 - s1 * s2 * s3;\n break;\n case "XZY":\n this._x = s1 * c2 * c3 - c1 * s2 * s3;\n this._y = c1 * s2 * c3 - s1 * c2 * s3;\n this._z = c1 * c2 * s3 + s1 * s2 * c3;\n this._w = c1 * c2 * c3 + s1 * s2 * s3;\n break;\n default:\n console.warn("THREE.Quaternion: .setFromEuler() encountered an unknown order: " + order);\n }\n if (update === true) this._onChangeCallback();\n return this;\n }\n /**\n * Sets this quaternion from the given axis and angle.\n *\n * @param {Vector3} axis - The normalized axis.\n * @param {number} angle - The angle in radians.\n * @return {Quaternion} A reference to this quaternion.\n */\n setFromAxisAngle(axis, angle) {\n const halfAngle = angle / 2, s = Math.sin(halfAngle);\n this._x = axis.x * s;\n this._y = axis.y * s;\n this._z = axis.z * s;\n this._w = Math.cos(halfAngle);\n this._onChangeCallback();\n return this;\n }\n /**\n * Sets this quaternion from the given rotation matrix.\n *\n * @param {Matrix4} m - A 4x4 matrix of which the upper 3x3 of matrix is a pure rotation matrix (i.e. unscaled).\n * @return {Quaternion} A reference to this quaternion.\n */\n setFromRotationMatrix(m) {\n const te = m.elements, m11 = te[0], m12 = te[4], m13 = te[8], m21 = te[1], m22 = te[5], m23 = te[9], m31 = te[2], m32 = te[6], m33 = te[10], trace = m11 + m22 + m33;\n if (trace > 0) {\n const s = 0.5 / Math.sqrt(trace + 1);\n this._w = 0.25 / s;\n this._x = (m32 - m23) * s;\n this._y = (m13 - m31) * s;\n this._z = (m21 - m12) * s;\n } else if (m11 > m22 && m11 > m33) {\n const s = 2 * Math.sqrt(1 + m11 - m22 - m33);\n this._w = (m32 - m23) / s;\n this._x = 0.25 * s;\n this._y = (m12 + m21) / s;\n this._z = (m13 + m31) / s;\n } else if (m22 > m33) {\n const s = 2 * Math.sqrt(1 + m22 - m11 - m33);\n this._w = (m13 - m31) / s;\n this._x = (m12 + m21) / s;\n this._y = 0.25 * s;\n this._z = (m23 + m32) / s;\n } else {\n const s = 2 * Math.sqrt(1 + m33 - m11 - m22);\n this._w = (m21 - m12) / s;\n this._x = (m13 + m31) / s;\n this._y = (m23 + m32) / s;\n this._z = 0.25 * s;\n }\n this._onChangeCallback();\n return this;\n }\n /**\n * Sets this quaternion to the rotation required to rotate the direction vector\n * `vFrom` to the direction vector `vTo`.\n *\n * @param {Vector3} vFrom - The first (normalized) direction vector.\n * @param {Vector3} vTo - The second (normalized) direction vector.\n * @return {Quaternion} A reference to this quaternion.\n */\n setFromUnitVectors(vFrom, vTo) {\n let r = vFrom.dot(vTo) + 1;\n if (r < 1e-8) {\n r = 0;\n if (Math.abs(vFrom.x) > Math.abs(vFrom.z)) {\n this._x = -vFrom.y;\n this._y = vFrom.x;\n this._z = 0;\n this._w = r;\n } else {\n this._x = 0;\n this._y = -vFrom.z;\n this._z = vFrom.y;\n this._w = r;\n }\n } else {\n this._x = vFrom.y * vTo.z - vFrom.z * vTo.y;\n this._y = vFrom.z * vTo.x - vFrom.x * vTo.z;\n this._z = vFrom.x * vTo.y - vFrom.y * vTo.x;\n this._w = r;\n }\n return this.normalize();\n }\n /**\n * Returns the angle between this quaternion and the given one in radians.\n *\n * @param {Quaternion} q - The quaternion to compute the angle with.\n * @return {number} The angle in radians.\n */\n angleTo(q) {\n return 2 * Math.acos(Math.abs(clamp(this.dot(q), -1, 1)));\n }\n /**\n * Rotates this quaternion by a given angular step to the given quaternion.\n * The method ensures that the final quaternion will not overshoot `q`.\n *\n * @param {Quaternion} q - The target quaternion.\n * @param {number} step - The angular step in radians.\n * @return {Quaternion} A reference to this quaternion.\n */\n rotateTowards(q, step) {\n const angle = this.angleTo(q);\n if (angle === 0) return this;\n const t = Math.min(1, step / angle);\n this.slerp(q, t);\n return this;\n }\n /**\n * Sets this quaternion to the identity quaternion; that is, to the\n * quaternion that represents "no rotation".\n *\n * @return {Quaternion} A reference to this quaternion.\n */\n identity() {\n return this.set(0, 0, 0, 1);\n }\n /**\n * Inverts this quaternion via {@link Quaternion#conjugate}. The\n * quaternion is assumed to have unit length.\n *\n * @return {Quaternion} A reference to this quaternion.\n */\n invert() {\n return this.conjugate();\n }\n /**\n * Returns the rotational conjugate of this quaternion. The conjugate of a\n * quaternion represents the same rotation in the opposite direction about\n * the rotational axis.\n *\n * @return {Quaternion} A reference to this quaternion.\n */\n conjugate() {\n this._x *= -1;\n this._y *= -1;\n this._z *= -1;\n this._onChangeCallback();\n return this;\n }\n /**\n * Calculates the dot product of this quaternion and the given one.\n *\n * @param {Quaternion} v - The quaternion to compute the dot product with.\n * @return {number} The result of the dot product.\n */\n dot(v) {\n return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;\n }\n /**\n * Computes the squared Euclidean length (straight-line length) of this quaternion,\n * considered as a 4 dimensional vector. This can be useful if you are comparing the\n * lengths of two quaternions, as this is a slightly more efficient calculation than\n * {@link Quaternion#length}.\n *\n * @return {number} The squared Euclidean length.\n */\n lengthSq() {\n return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;\n }\n /**\n * Computes the Euclidean length (straight-line length) of this quaternion,\n * considered as a 4 dimensional vector.\n *\n * @return {number} The Euclidean length.\n */\n length() {\n return Math.sqrt(this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w);\n }\n /**\n * Normalizes this quaternion - that is, calculated the quaternion that performs\n * the same rotation as this one, but has a length equal to `1`.\n *\n * @return {Quaternion} A reference to this quaternion.\n */\n normalize() {\n let l = this.length();\n if (l === 0) {\n this._x = 0;\n this._y = 0;\n this._z = 0;\n this._w = 1;\n } else {\n l = 1 / l;\n this._x = this._x * l;\n this._y = this._y * l;\n this._z = this._z * l;\n this._w = this._w * l;\n }\n this._onChangeCallback();\n return this;\n }\n /**\n * Multiplies this quaternion by the given one.\n *\n * @param {Quaternion} q - The quaternion.\n * @return {Quaternion} A reference to this quaternion.\n */\n multiply(q) {\n return this.multiplyQuaternions(this, q);\n }\n /**\n * Pre-multiplies this quaternion by the given one.\n *\n * @param {Quaternion} q - The quaternion.\n * @return {Quaternion} A reference to this quaternion.\n */\n premultiply(q) {\n return this.multiplyQuaternions(q, this);\n }\n /**\n * Multiplies the given quaternions and stores the result in this instance.\n *\n * @param {Quaternion} a - The first quaternion.\n * @param {Quaternion} b - The second quaternion.\n * @return {Quaternion} A reference to this quaternion.\n */\n multiplyQuaternions(a, b) {\n const qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;\n const qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;\n this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;\n this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;\n this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;\n this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;\n this._onChangeCallback();\n return this;\n }\n /**\n * Performs a spherical linear interpolation between quaternions.\n *\n * @param {Quaternion} qb - The target quaternion.\n * @param {number} t - The interpolation factor in the closed interval `[0, 1]`.\n * @return {Quaternion} A reference to this quaternion.\n */\n slerp(qb, t) {\n if (t === 0) return this;\n if (t === 1) return this.copy(qb);\n const x2 = this._x, y = this._y, z = this._z, w = this._w;\n let cosHalfTheta = w * qb._w + x2 * qb._x + y * qb._y + z * qb._z;\n if (cosHalfTheta < 0) {\n this._w = -qb._w;\n this._x = -qb._x;\n this._y = -qb._y;\n this._z = -qb._z;\n cosHalfTheta = -cosHalfTheta;\n } else {\n this.copy(qb);\n }\n if (cosHalfTheta >= 1) {\n this._w = w;\n this._x = x2;\n this._y = y;\n this._z = z;\n return this;\n }\n const sqrSinHalfTheta = 1 - cosHalfTheta * cosHalfTheta;\n if (sqrSinHalfTheta <= Number.EPSILON) {\n const s = 1 - t;\n this._w = s * w + t * this._w;\n this._x = s * x2 + t * this._x;\n this._y = s * y + t * this._y;\n this._z = s * z + t * this._z;\n this.normalize();\n return this;\n }\n const sinHalfTheta = Math.sqrt(sqrSinHalfTheta);\n const halfTheta = Math.atan2(sinHalfTheta, cosHalfTheta);\n const ratioA = Math.sin((1 - t) * halfTheta) / sinHalfTheta, ratioB = Math.sin(t * halfTheta) / sinHalfTheta;\n this._w = w * ratioA + this._w * ratioB;\n this._x = x2 * ratioA + this._x * ratioB;\n this._y = y * ratioA + this._y * ratioB;\n this._z = z * ratioA + this._z * ratioB;\n this._onChangeCallback();\n return this;\n }\n /**\n * Performs a spherical linear interpolation between the given quaternions\n * and stores the result in this quaternion.\n *\n * @param {Quaternion} qa - The source quaternion.\n * @param {Quaternion} qb - The target quaternion.\n * @param {number} t - The interpolation factor in the closed interval `[0, 1]`.\n * @return {Quaternion} A reference to this quaternion.\n */\n slerpQuaternions(qa, qb, t) {\n return this.copy(qa).slerp(qb, t);\n }\n /**\n * Sets this quaternion to a uniformly random, normalized quaternion.\n *\n * @return {Quaternion} A reference to this quaternion.\n */\n random() {\n const theta1 = 2 * Math.PI * Math.random();\n const theta2 = 2 * Math.PI * Math.random();\n const x0 = Math.random();\n const r1 = Math.sqrt(1 - x0);\n const r2 = Math.sqrt(x0);\n return this.set(\n r1 * Math.sin(theta1),\n r1 * Math.cos(theta1),\n r2 * Math.sin(theta2),\n r2 * Math.cos(theta2)\n );\n }\n /**\n * Returns `true` if this quaternion is equal with the given one.\n *\n * @param {Quaternion} quaternion - The quaternion to test for equality.\n * @return {boolean} Whether this quaternion is equal with the given one.\n */\n equals(quaternion) {\n return quaternion._x === this._x && quaternion._y === this._y && quaternion._z === this._z && quaternion._w === this._w;\n }\n /**\n * Sets this quaternion\'s components from the given array.\n *\n * @param {Array<number>} array - An array holding the quaternion component values.\n * @param {number} [offset=0] - The offset into the array.\n * @return {Quaternion} A reference to this quaternion.\n */\n fromArray(array, offset = 0) {\n this._x = array[offset];\n this._y = array[offset + 1];\n this._z = array[offset + 2];\n this._w = array[offset + 3];\n this._onChangeCallback();\n return this;\n }\n /**\n * Writes the components of this quaternion to the given array. If no array is provided,\n * the method returns a new instance.\n *\n * @param {Array<number>} [array=[]] - The target array holding the quaternion components.\n * @param {number} [offset=0] - Index of the first element in the array.\n * @return {Array<number>} The quaternion components.\n */\n toArray(array = [], offset = 0) {\n array[offset] = this._x;\n array[offset + 1] = this._y;\n array[offset + 2] = this._z;\n array[offset + 3] = this._w;\n return array;\n }\n /**\n * Sets the components of this quaternion from the given buffer attribute.\n *\n * @param {BufferAttribute} attribute - The buffer attribute holding quaternion data.\n * @param {number} index - The index into the attribute.\n * @return {Quaternion} A reference to this quaternion.\n */\n fromBufferAttribute(attribute, index) {\n this._x = attribute.getX(index);\n this._y = attribute.getY(index);\n this._z = attribute.getZ(index);\n this._w = attribute.getW(index);\n this._onChangeCallback();\n return this;\n }\n /**\n * This methods defines the serialization result of this class. Returns the\n * numerical elements of this quaternion in an array of format `[x, y, z, w]`.\n *\n * @return {Array<number>} The serialized quaternion.\n */\n toJSON() {\n return this.toArray();\n }\n _onChange(callback) {\n this._onChangeCallback = callback;\n return this;\n }\n _onChangeCallback() {\n }\n *[Symbol.iterator]() {\n yield this._x;\n yield this._y;\n yield this._z;\n yield this._w;\n }\n }\n class Vector3 {\n /**\n * Constructs a new 3D vector.\n *\n * @param {number} [x=0] - The x value of this vector.\n * @param {number} [y=0] - The y value of this vector.\n * @param {number} [z=0] - The z value of this vector.\n */\n constructor(x2 = 0, y = 0, z = 0) {\n Vector3.prototype.isVector3 = true;\n this.x = x2;\n this.y = y;\n this.z = z;\n }\n /**\n * Sets the vector components.\n *\n * @param {number} x - The value of the x component.\n * @param {number} y - The value of the y component.\n * @param {number} z - The value of the z component.\n * @return {Vector3} A reference to this vector.\n */\n set(x2, y, z) {\n if (z === void 0) z = this.z;\n this.x = x2;\n this.y = y;\n this.z = z;\n return this;\n }\n /**\n * Sets the vector components to the same value.\n *\n * @param {number} scalar - The value to set for all vector components.\n * @return {Vector3} A reference to this vector.\n */\n setScalar(scalar) {\n this.x = scalar;\n this.y = scalar;\n this.z = scalar;\n return this;\n }\n /**\n * Sets the vector\'s x component to the given value\n *\n * @param {number} x - The value to set.\n * @return {Vector3} A reference to this vector.\n */\n setX(x2) {\n this.x = x2;\n return this;\n }\n /**\n * Sets the vector\'s y component to the given value\n *\n * @param {number} y - The value to set.\n * @return {Vector3} A reference to this vector.\n */\n setY(y) {\n this.y = y;\n return this;\n }\n /**\n * Sets the vector\'s z component to the given value\n *\n * @param {number} z - The value to set.\n * @return {Vector3} A reference to this vector.\n */\n setZ(z) {\n this.z = z;\n return this;\n }\n /**\n * Allows to set a vector component with an index.\n *\n * @param {number} index - The component index. `0` equals to x, `1` equals to y, `2` equals to z.\n * @param {number} value - The value to set.\n * @return {Vector3} A reference to this vector.\n */\n setComponent(index, value) {\n switch (index) {\n case 0:\n this.x = value;\n break;\n case 1:\n this.y = value;\n break;\n case 2:\n this.z = value;\n break;\n default:\n throw new Error("index is out of range: " + index);\n }\n return this;\n }\n /**\n * Returns the value of the vector component which matches the given index.\n *\n * @param {number} index - The component index. `0` equals to x, `1` equals to y, `2` equals to z.\n * @return {number} A vector component value.\n */\n getComponent(index) {\n switch (index) {\n case 0:\n return this.x;\n case 1:\n return this.y;\n case 2:\n return this.z;\n default:\n throw new Error("index is out of range: " + index);\n }\n }\n /**\n * Returns a new vector with copied values from this instance.\n *\n * @return {Vector3} A clone of this instance.\n */\n clone() {\n return new this.constructor(this.x, this.y, this.z);\n }\n /**\n * Copies the values of the given vector to this instance.\n *\n * @param {Vector3} v - The vector to copy.\n * @return {Vector3} A reference to this vector.\n */\n copy(v) {\n this.x = v.x;\n this.y = v.y;\n this.z = v.z;\n return this;\n }\n /**\n * Adds the given vector to this instance.\n *\n * @param {Vector3} v - The vector to add.\n * @return {Vector3} A reference to this vector.\n */\n add(v) {\n this.x += v.x;\n this.y += v.y;\n this.z += v.z;\n return this;\n }\n /**\n * Adds the given scalar value to all components of this instance.\n *\n * @param {number} s - The scalar to add.\n * @return {Vector3} A reference to this vector.\n */\n addScalar(s) {\n this.x += s;\n this.y += s;\n this.z += s;\n return this;\n }\n /**\n * Adds the given vectors and stores the result in this instance.\n *\n * @param {Vector3} a - The first vector.\n * @param {Vector3} b - The second vector.\n * @return {Vector3} A reference to this vector.\n */\n addVectors(a, b) {\n this.x = a.x + b.x;\n this.y = a.y + b.y;\n this.z = a.z + b.z;\n return this;\n }\n /**\n * Adds the given vector scaled by the given factor to this instance.\n *\n * @param {Vector3|Vector4} v - The vector.\n * @param {number} s - The factor that scales `v`.\n * @return {Vector3} A reference to this vector.\n */\n addScaledVector(v, s) {\n this.x += v.x * s;\n this.y += v.y * s;\n this.z += v.z * s;\n return this;\n }\n /**\n * Subtracts the given vector from this instance.\n *\n * @param {Vector3} v - The vector to subtract.\n * @return {Vector3} A reference to this vector.\n */\n sub(v) {\n this.x -= v.x;\n this.y -= v.y;\n this.z -= v.z;\n return this;\n }\n /**\n * Subtracts the given scalar value from all components of this instance.\n *\n * @param {number} s - The scalar to subtract.\n * @return {Vector3} A reference to this vector.\n */\n subScalar(s) {\n this.x -= s;\n this.y -= s;\n this.z -= s;\n return this;\n }\n /**\n * Subtracts the given vectors and stores the result in this instance.\n *\n * @param {Vector3} a - The first vector.\n * @param {Vector3} b - The second vector.\n * @return {Vector3} A reference to this vector.\n */\n subVectors(a, b) {\n this.x = a.x - b.x;\n this.y = a.y - b.y;\n this.z = a.z - b.z;\n return this;\n }\n /**\n * Multiplies the given vector with this instance.\n *\n * @param {Vector3} v - The vector to multiply.\n * @return {Vector3} A reference to this vector.\n */\n multiply(v) {\n this.x *= v.x;\n this.y *= v.y;\n this.z *= v.z;\n return this;\n }\n /**\n * Multiplies the given scalar value with all components of this instance.\n *\n * @param {number} scalar - The scalar to multiply.\n * @return {Vector3} A reference to this vector.\n */\n multiplyScalar(scalar) {\n this.x *= scalar;\n this.y *= scalar;\n this.z *= scalar;\n return this;\n }\n /**\n * Multiplies the given vectors and stores the result in this instance.\n *\n * @param {Vector3} a - The first vector.\n * @param {Vector3} b - The second vector.\n * @return {Vector3} A reference to this vector.\n */\n multiplyVectors(a, b) {\n this.x = a.x * b.x;\n this.y = a.y * b.y;\n this.z = a.z * b.z;\n return this;\n }\n /**\n * Applies the given Euler rotation to this vector.\n *\n * @param {Euler} euler - The Euler angles.\n * @return {Vector3} A reference to this vector.\n */\n applyEuler(euler) {\n return this.applyQuaternion(_quaternion$4.setFromEuler(euler));\n }\n /**\n * Applies a rotation specified by an axis and an angle to this vector.\n *\n * @param {Vector3} axis - A normalized vector representing the rotation axis.\n * @param {number} angle - The angle in radians.\n * @return {Vector3} A reference to this vector.\n */\n applyAxisAngle(axis, angle) {\n return this.applyQuaternion(_quaternion$4.setFromAxisAngle(axis, angle));\n }\n /**\n * Multiplies this vector with the given 3x3 matrix.\n *\n * @param {Matrix3} m - The 3x3 matrix.\n * @return {Vector3} A reference to this vector.\n */\n applyMatrix3(m) {\n const x2 = this.x, y = this.y, z = this.z;\n const e = m.elements;\n this.x = e[0] * x2 + e[3] * y + e[6] * z;\n this.y = e[1] * x2 + e[4] * y + e[7] * z;\n this.z = e[2] * x2 + e[5] * y + e[8] * z;\n return this;\n }\n /**\n * Multiplies this vector by the given normal matrix and normalizes\n * the result.\n *\n * @param {Matrix3} m - The normal matrix.\n * @return {Vector3} A reference to this vector.\n */\n applyNormalMatrix(m) {\n return this.applyMatrix3(m).normalize();\n }\n /**\n * Multiplies this vector (with an implicit 1 in the 4th dimension) by m, and\n * divides by perspective.\n *\n * @param {Matrix4} m - The matrix to apply.\n * @return {Vector3} A reference to this vector.\n */\n applyMatrix4(m) {\n const x2 = this.x, y = this.y, z = this.z;\n const e = m.elements;\n const w = 1 / (e[3] * x2 + e[7] * y + e[11] * z + e[15]);\n this.x = (e[0] * x2 + e[4] * y + e[8] * z + e[12]) * w;\n this.y = (e[1] * x2 + e[5] * y + e[9] * z + e[13]) * w;\n this.z = (e[2] * x2 + e[6] * y + e[10] * z + e[14]) * w;\n return this;\n }\n /**\n * Applies the given Quaternion to this vector.\n *\n * @param {Quaternion} q - The Quaternion.\n * @return {Vector3} A reference to this vector.\n */\n applyQuaternion(q) {\n const vx = this.x, vy = this.y, vz = this.z;\n const qx = q.x, qy = q.y, qz = q.z, qw = q.w;\n const tx = 2 * (qy * vz - qz * vy);\n const ty = 2 * (qz * vx - qx * vz);\n const tz = 2 * (qx * vy - qy * vx);\n this.x = vx + qw * tx + qy * tz - qz * ty;\n this.y = vy + qw * ty + qz * tx - qx * tz;\n this.z = vz + qw * tz + qx * ty - qy * tx;\n return this;\n }\n /**\n * Projects this vector from world space into the camera\'s normalized\n * device coordinate (NDC) space.\n *\n * @param {Camera} camera - The camera.\n * @return {Vector3} A reference to this vector.\n */\n project(camera) {\n return this.applyMatrix4(camera.matrixWorldInverse).applyMatrix4(camera.projectionMatrix);\n }\n /**\n * Unprojects this vector from the camera\'s normalized device coordinate (NDC)\n * space into world space.\n *\n * @param {Camera} camera - The camera.\n * @return {Vector3} A reference to this vector.\n */\n unproject(camera) {\n return this.applyMatrix4(camera.projectionMatrixInverse).applyMatrix4(camera.matrixWorld);\n }\n /**\n * Transforms the direction of this vector by a matrix (the upper left 3 x 3\n * subset of the given 4x4 matrix and then normalizes the result.\n *\n * @param {Matrix4} m - The matrix.\n * @return {Vector3} A reference to this vector.\n */\n transformDirection(m) {\n const x2 = this.x, y = this.y, z = this.z;\n const e = m.elements;\n this.x = e[0] * x2 + e[4] * y + e[8] * z;\n this.y = e[1] * x2 + e[5] * y + e[9] * z;\n this.z = e[2] * x2 + e[6] * y + e[10] * z;\n return this.normalize();\n }\n /**\n * Divides this instance by the given vector.\n *\n * @param {Vector3} v - The vector to divide.\n * @return {Vector3} A reference to this vector.\n */\n divide(v) {\n this.x /= v.x;\n this.y /= v.y;\n this.z /= v.z;\n return this;\n }\n /**\n * Divides this vector by the given scalar.\n *\n * @param {number} scalar - The scalar to divide.\n * @return {Vector3} A reference to this vector.\n */\n divideScalar(scalar) {\n return this.multiplyScalar(1 / scalar);\n }\n /**\n * If this vector\'s x, y or z value is greater than the given vector\'s x, y or z\n * value, replace that value with the corresponding min value.\n *\n * @param {Vector3} v - The vector.\n * @return {Vector3} A reference to this vector.\n */\n min(v) {\n this.x = Math.min(this.x, v.x);\n this.y = Math.min(this.y, v.y);\n this.z = Math.min(this.z, v.z);\n return this;\n }\n /**\n * If this vector\'s x, y or z value is less than the given vector\'s x, y or z\n * value, replace that value with the corresponding max value.\n *\n * @param {Vector3} v - The vector.\n * @return {Vector3} A reference to this vector.\n */\n max(v) {\n this.x = Math.max(this.x, v.x);\n this.y = Math.max(this.y, v.y);\n this.z = Math.max(this.z, v.z);\n return this;\n }\n /**\n * If this vector\'s x, y or z value is greater than the max vector\'s x, y or z\n * value, it is replaced by the corresponding value.\n * If this vector\'s x, y or z value is less than the min vector\'s x, y or z value,\n * it is replaced by the corresponding value.\n *\n * @param {Vector3} min - The minimum x, y and z values.\n * @param {Vector3} max - The maximum x, y and z values in the desired range.\n * @return {Vector3} A reference to this vector.\n */\n clamp(min, max2) {\n this.x = clamp(this.x, min.x, max2.x);\n this.y = clamp(this.y, min.y, max2.y);\n this.z = clamp(this.z, min.z, max2.z);\n return this;\n }\n /**\n * If this vector\'s x, y or z values are greater than the max value, they are\n * replaced by the max value.\n * If this vector\'s x, y or z values are less than the min value, they are\n * replaced by the min value.\n *\n * @param {number} minVal - The minimum value the components will be clamped to.\n * @param {number} maxVal - The maximum value the components will be clamped to.\n * @return {Vector3} A reference to this vector.\n */\n clampScalar(minVal, maxVal) {\n this.x = clamp(this.x, minVal, maxVal);\n this.y = clamp(this.y, minVal, maxVal);\n this.z = clamp(this.z, minVal, maxVal);\n return this;\n }\n /**\n * If this vector\'s length is greater than the max value, it is replaced by\n * the max value.\n * If this vector\'s length is less than the min value, it is replaced by the\n * min value.\n *\n * @param {number} min - The minimum value the vector length will be clamped to.\n * @param {number} max - The maximum value the vector length will be clamped to.\n * @return {Vector3} A reference to this vector.\n */\n clampLength(min, max2) {\n const length = this.length();\n return this.divideScalar(length || 1).multiplyScalar(clamp(length, min, max2));\n }\n /**\n * The components of this vector are rounded down to the nearest integer value.\n *\n * @return {Vector3} A reference to this vector.\n */\n floor() {\n this.x = Math.floor(this.x);\n this.y = Math.floor(this.y);\n this.z = Math.floor(this.z);\n return this;\n }\n /**\n * The components of this vector are rounded up to the nearest integer value.\n *\n * @return {Vector3} A reference to this vector.\n */\n ceil() {\n this.x = Math.ceil(this.x);\n this.y = Math.ceil(this.y);\n this.z = Math.ceil(this.z);\n return this;\n }\n /**\n * The components of this vector are rounded to the nearest integer value\n *\n * @return {Vector3} A reference to this vector.\n */\n round() {\n this.x = Math.round(this.x);\n this.y = Math.round(this.y);\n this.z = Math.round(this.z);\n return this;\n }\n /**\n * The components of this vector are rounded towards zero (up if negative,\n * down if positive) to an integer value.\n *\n * @return {Vector3} A reference to this vector.\n */\n roundToZero() {\n this.x = Math.trunc(this.x);\n this.y = Math.trunc(this.y);\n this.z = Math.trunc(this.z);\n return this;\n }\n /**\n * Inverts this vector - i.e. sets x = -x, y = -y and z = -z.\n *\n * @return {Vector3} A reference to this vector.\n */\n negate() {\n this.x = -this.x;\n this.y = -this.y;\n this.z = -this.z;\n return this;\n }\n /**\n * Calculates the dot product of the given vector with this instance.\n *\n * @param {Vector3} v - The vector to compute the dot product with.\n * @return {number} The result of the dot product.\n */\n dot(v) {\n return this.x * v.x + this.y * v.y + this.z * v.z;\n }\n // TODO lengthSquared?\n /**\n * Computes the square of the Euclidean length (straight-line length) from\n * (0, 0, 0) to (x, y, z). If you are comparing the lengths of vectors, you should\n * compare the length squared instead as it is slightly more efficient to calculate.\n *\n * @return {number} The square length of this vector.\n */\n lengthSq() {\n return this.x * this.x + this.y * this.y + this.z * this.z;\n }\n /**\n * Computes the Euclidean length (straight-line length) from (0, 0, 0) to (x, y, z).\n *\n * @return {number} The length of this vector.\n */\n length() {\n return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);\n }\n /**\n * Computes the Manhattan length of this vector.\n *\n * @return {number} The length of this vector.\n */\n manhattanLength() {\n return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z);\n }\n /**\n * Converts this vector to a unit vector - that is, sets it equal to a vector\n * with the same direction as this one, but with a vector length of `1`.\n *\n * @return {Vector3} A reference to this vector.\n */\n normalize() {\n return this.divideScalar(this.length() || 1);\n }\n /**\n * Sets this vector to a vector with the same direction as this one, but\n * with the specified length.\n *\n * @param {number} length - The new length of this vector.\n * @return {Vector3} A reference to this vector.\n */\n setLength(length) {\n return this.normalize().multiplyScalar(length);\n }\n /**\n * Linearly interpolates between the given vector and this instance, where\n * alpha is the percent distance along the line - alpha = 0 will be this\n * vector, and alpha = 1 will be the given one.\n *\n * @param {Vector3} v - The vector to interpolate towards.\n * @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`.\n * @return {Vector3} A reference to this vector.\n */\n lerp(v, alpha) {\n this.x += (v.x - this.x) * alpha;\n this.y += (v.y - this.y) * alpha;\n this.z += (v.z - this.z) * alpha;\n return this;\n }\n /**\n * Linearly interpolates between the given vectors, where alpha is the percent\n * distance along the line - alpha = 0 will be first vector, and alpha = 1 will\n * be the second one. The result is stored in this instance.\n *\n * @param {Vector3} v1 - The first vector.\n * @param {Vector3} v2 - The second vector.\n * @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`.\n * @return {Vector3} A reference to this vector.\n */\n lerpVectors(v1, v2, alpha) {\n this.x = v1.x + (v2.x - v1.x) * alpha;\n this.y = v1.y + (v2.y - v1.y) * alpha;\n this.z = v1.z + (v2.z - v1.z) * alpha;\n return this;\n }\n /**\n * Calculates the cross product of the given vector with this instance.\n *\n * @param {Vector3} v - The vector to compute the cross product with.\n * @return {Vector3} The result of the cross product.\n */\n cross(v) {\n return this.crossVectors(this, v);\n }\n /**\n * Calculates the cross product of the given vectors and stores the result\n * in this instance.\n *\n * @param {Vector3} a - The first vector.\n * @param {Vector3} b - The second vector.\n * @return {Vector3} A reference to this vector.\n */\n crossVectors(a, b) {\n const ax = a.x, ay = a.y, az = a.z;\n const bx = b.x, by = b.y, bz = b.z;\n this.x = ay * bz - az * by;\n this.y = az * bx - ax * bz;\n this.z = ax * by - ay * bx;\n return this;\n }\n /**\n * Projects this vector onto the given one.\n *\n * @param {Vector3} v - The vector to project to.\n * @return {Vector3} A reference to this vector.\n */\n projectOnVector(v) {\n const denominator = v.lengthSq();\n if (denominator === 0) return this.set(0, 0, 0);\n const scalar = v.dot(this) / denominator;\n return this.copy(v).multiplyScalar(scalar);\n }\n /**\n * Projects this vector onto a plane by subtracting this\n * vector projected onto the plane\'s normal from this vector.\n *\n * @param {Vector3} planeNormal - The plane normal.\n * @return {Vector3} A reference to this vector.\n */\n projectOnPlane(planeNormal) {\n _vector$c.copy(this).projectOnVector(planeNormal);\n return this.sub(_vector$c);\n }\n /**\n * Reflects this vector off a plane orthogonal to the given normal vector.\n *\n * @param {Vector3} normal - The (normalized) normal vector.\n * @return {Vector3} A reference to this vector.\n */\n reflect(normal) {\n return this.sub(_vector$c.copy(normal).multiplyScalar(2 * this.dot(normal)));\n }\n /**\n * Returns the angle between the given vector and this instance in radians.\n *\n * @param {Vector3} v - The vector to compute the angle with.\n * @return {number} The angle in radians.\n */\n angleTo(v) {\n const denominator = Math.sqrt(this.lengthSq() * v.lengthSq());\n if (denominator === 0) return Math.PI / 2;\n const theta = this.dot(v) / denominator;\n return Math.acos(clamp(theta, -1, 1));\n }\n /**\n * Computes the distance from the given vector to this instance.\n *\n * @param {Vector3} v - The vector to compute the distance to.\n * @return {number} The distance.\n */\n distanceTo(v) {\n return Math.sqrt(this.distanceToSquared(v));\n }\n /**\n * Computes the squared distance from the given vector to this instance.\n * If you are just comparing the distance with another distance, you should compare\n * the distance squared instead as it is slightly more efficient to calculate.\n *\n * @param {Vector3} v - The vector to compute the squared distance to.\n * @return {number} The squared distance.\n */\n distanceToSquared(v) {\n const dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;\n return dx * dx + dy * dy + dz * dz;\n }\n /**\n * Computes the Manhattan distance from the given vector to this instance.\n *\n * @param {Vector3} v - The vector to compute the Manhattan distance to.\n * @return {number} The Manhattan distance.\n */\n manhattanDistanceTo(v) {\n return Math.abs(this.x - v.x) + Math.abs(this.y - v.y) + Math.abs(this.z - v.z);\n }\n /**\n * Sets the vector components from the given spherical coordinates.\n *\n * @param {Spherical} s - The spherical coordinates.\n * @return {Vector3} A reference to this vector.\n */\n setFromSpherical(s) {\n return this.setFromSphericalCoords(s.radius, s.phi, s.theta);\n }\n /**\n * Sets the vector components from the given spherical coordinates.\n *\n * @param {number} radius - The radius.\n * @param {number} phi - The phi angle in radians.\n * @param {number} theta - The theta angle in radians.\n * @return {Vector3} A reference to this vector.\n */\n setFromSphericalCoords(radius, phi, theta) {\n const sinPhiRadius = Math.sin(phi) * radius;\n this.x = sinPhiRadius * Math.sin(theta);\n this.y = Math.cos(phi) * radius;\n this.z = sinPhiRadius * Math.cos(theta);\n return this;\n }\n /**\n * Sets the vector components from the given cylindrical coordinates.\n *\n * @param {Cylindrical} c - The cylindrical coordinates.\n * @return {Vector3} A reference to this vector.\n */\n setFromCylindrical(c) {\n return this.setFromCylindricalCoords(c.radius, c.theta, c.y);\n }\n /**\n * Sets the vector components from the given cylindrical coordinates.\n *\n * @param {number} radius - The radius.\n * @param {number} theta - The theta angle in radians.\n * @param {number} y - The y value.\n * @return {Vector3} A reference to this vector.\n */\n setFromCylindricalCoords(radius, theta, y) {\n this.x = radius * Math.sin(theta);\n this.y = y;\n this.z = radius * Math.cos(theta);\n return this;\n }\n /**\n * Sets the vector components to the position elements of the\n * given transformation matrix.\n *\n * @param {Matrix4} m - The 4x4 matrix.\n * @return {Vector3} A reference to this vector.\n */\n setFromMatrixPosition(m) {\n const e = m.elements;\n this.x = e[12];\n this.y = e[13];\n this.z = e[14];\n return this;\n }\n /**\n * Sets the vector components to the scale elements of the\n * given transformation matrix.\n *\n * @param {Matrix4} m - The 4x4 matrix.\n * @return {Vector3} A reference to this vector.\n */\n setFromMatrixScale(m) {\n const sx = this.setFromMatrixColumn(m, 0).length();\n const sy = this.setFromMatrixColumn(m, 1).length();\n const sz = this.setFromMatrixColumn(m, 2).length();\n this.x = sx;\n this.y = sy;\n this.z = sz;\n return this;\n }\n /**\n * Sets the vector components from the specified matrix column.\n *\n * @param {Matrix4} m - The 4x4 matrix.\n * @param {number} index - The column index.\n * @return {Vector3} A reference to this vector.\n */\n setFromMatrixColumn(m, index) {\n return this.fromArray(m.elements, index * 4);\n }\n /**\n * Sets the vector components from the specified matrix column.\n *\n * @param {Matrix3} m - The 3x3 matrix.\n * @param {number} index - The column index.\n * @return {Vector3} A reference to this vector.\n */\n setFromMatrix3Column(m, index) {\n return this.fromArray(m.elements, index * 3);\n }\n /**\n * Sets the vector components from the given Euler angles.\n *\n * @param {Euler} e - The Euler angles to set.\n * @return {Vector3} A reference to this vector.\n */\n setFromEuler(e) {\n this.x = e._x;\n this.y = e._y;\n this.z = e._z;\n return this;\n }\n /**\n * Sets the vector components from the RGB components of the\n * given color.\n *\n * @param {Color} c - The color to set.\n * @return {Vector3} A reference to this vector.\n */\n setFromColor(c) {\n this.x = c.r;\n this.y = c.g;\n this.z = c.b;\n return this;\n }\n /**\n * Returns `true` if this vector is equal with the given one.\n *\n * @param {Vector3} v - The vector to test for equality.\n * @return {boolean} Whether this vector is equal with the given one.\n */\n equals(v) {\n return v.x === this.x && v.y === this.y && v.z === this.z;\n }\n /**\n * Sets this vector\'s x value to be `array[ offset ]`, y value to be `array[ offset + 1 ]`\n * and z value to be `array[ offset + 2 ]`.\n *\n * @param {Array<number>} array - An array holding the vector component values.\n * @param {number} [offset=0] - The offset into the array.\n * @return {Vector3} A reference to this vector.\n */\n fromArray(array, offset = 0) {\n this.x = array[offset];\n this.y = array[offset + 1];\n this.z = array[offset + 2];\n return this;\n }\n /**\n * Writes the components of this vector to the given array. If no array is provided,\n * the method returns a new instance.\n *\n * @param {Array<number>} [array=[]] - The target array holding the vector components.\n * @param {number} [offset=0] - Index of the first element in the array.\n * @return {Array<number>} The vector components.\n */\n toArray(array = [], offset = 0) {\n array[offset] = this.x;\n array[offset + 1] = this.y;\n array[offset + 2] = this.z;\n return array;\n }\n /**\n * Sets the components of this vector from the given buffer attribute.\n *\n * @param {BufferAttribute} attribute - The buffer attribute holding vector data.\n * @param {number} index - The index into the attribute.\n * @return {Vector3} A reference to this vector.\n */\n fromBufferAttribute(attribute, index) {\n this.x = attribute.getX(index);\n this.y = attribute.getY(index);\n this.z = attribute.getZ(index);\n return this;\n }\n /**\n * Sets each component of this vector to a pseudo-random value between `0` and\n * `1`, excluding `1`.\n *\n * @return {Vector3} A reference to this vector.\n */\n random() {\n this.x = Math.random();\n this.y = Math.random();\n this.z = Math.random();\n return this;\n }\n /**\n * Sets this vector to a uniformly random point on a unit sphere.\n *\n * @return {Vector3} A reference to this vector.\n */\n randomDirection() {\n const theta = Math.random() * Math.PI * 2;\n const u = Math.random() * 2 - 1;\n const c = Math.sqrt(1 - u * u);\n this.x = c * Math.cos(theta);\n this.y = u;\n this.z = c * Math.sin(theta);\n return this;\n }\n *[Symbol.iterator]() {\n yield this.x;\n yield this.y;\n yield this.z;\n }\n }\n const _vector$c = /* @__PURE__ */ new Vector3();\n const _quaternion$4 = /* @__PURE__ */ new Quaternion();\n class Matrix3 {\n /**\n * Constructs a new 3x3 matrix. The arguments are supposed to be\n * in row-major order. If no arguments are provided, the constructor\n * initializes the matrix as an identity matrix.\n *\n * @param {number} [n11] - 1-1 matrix element.\n * @param {number} [n12] - 1-2 matrix element.\n * @param {number} [n13] - 1-3 matrix element.\n * @param {number} [n21] - 2-1 matrix element.\n * @param {number} [n22] - 2-2 matrix element.\n * @param {number} [n23] - 2-3 matrix element.\n * @param {number} [n31] - 3-1 matrix element.\n * @param {number} [n32] - 3-2 matrix element.\n * @param {number} [n33] - 3-3 matrix element.\n */\n constructor(n11, n12, n13, n21, n22, n23, n31, n32, n33) {\n Matrix3.prototype.isMatrix3 = true;\n this.elements = [\n 1,\n 0,\n 0,\n 0,\n 1,\n 0,\n 0,\n 0,\n 1\n ];\n if (n11 !== void 0) {\n this.set(n11, n12, n13, n21, n22, n23, n31, n32, n33);\n }\n }\n /**\n * Sets the elements of the matrix.The arguments are supposed to be\n * in row-major order.\n *\n * @param {number} [n11] - 1-1 matrix element.\n * @param {number} [n12] - 1-2 matrix element.\n * @param {number} [n13] - 1-3 matrix element.\n * @param {number} [n21] - 2-1 matrix element.\n * @param {number} [n22] - 2-2 matrix element.\n * @param {number} [n23] - 2-3 matrix element.\n * @param {number} [n31] - 3-1 matrix element.\n * @param {number} [n32] - 3-2 matrix element.\n * @param {number} [n33] - 3-3 matrix element.\n * @return {Matrix3} A reference to this matrix.\n */\n set(n11, n12, n13, n21, n22, n23, n31, n32, n33) {\n const te = this.elements;\n te[0] = n11;\n te[1] = n21;\n te[2] = n31;\n te[3] = n12;\n te[4] = n22;\n te[5] = n32;\n te[6] = n13;\n te[7] = n23;\n te[8] = n33;\n return this;\n }\n /**\n * Sets this matrix to the 3x3 identity matrix.\n *\n * @return {Matrix3} A reference to this matrix.\n */\n identity() {\n this.set(\n 1,\n 0,\n 0,\n 0,\n 1,\n 0,\n 0,\n 0,\n 1\n );\n return this;\n }\n /**\n * Copies the values of the given matrix to this instance.\n *\n * @param {Matrix3} m - The matrix to copy.\n * @return {Matrix3} A reference to this matrix.\n */\n copy(m) {\n const te = this.elements;\n const me = m.elements;\n te[0] = me[0];\n te[1] = me[1];\n te[2] = me[2];\n te[3] = me[3];\n te[4] = me[4];\n te[5] = me[5];\n te[6] = me[6];\n te[7] = me[7];\n te[8] = me[8];\n return this;\n }\n /**\n * Extracts the basis of this matrix into the three axis vectors provided.\n *\n * @param {Vector3} xAxis - The basis\'s x axis.\n * @param {Vector3} yAxis - The basis\'s y axis.\n * @param {Vector3} zAxis - The basis\'s z axis.\n * @return {Matrix3} A reference to this matrix.\n */\n extractBasis(xAxis, yAxis, zAxis) {\n xAxis.setFromMatrix3Column(this, 0);\n yAxis.setFromMatrix3Column(this, 1);\n zAxis.setFromMatrix3Column(this, 2);\n return this;\n }\n /**\n * Set this matrix to the upper 3x3 matrix of the given 4x4 matrix.\n *\n * @param {Matrix4} m - The 4x4 matrix.\n * @return {Matrix3} A reference to this matrix.\n */\n setFromMatrix4(m) {\n const me = m.elements;\n this.set(\n me[0],\n me[4],\n me[8],\n me[1],\n me[5],\n me[9],\n me[2],\n me[6],\n me[10]\n );\n return this;\n }\n /**\n * Post-multiplies this matrix by the given 3x3 matrix.\n *\n * @param {Matrix3} m - The matrix to multiply with.\n * @return {Matrix3} A reference to this matrix.\n */\n multiply(m) {\n return this.multiplyMatrices(this, m);\n }\n /**\n * Pre-multiplies this matrix by the given 3x3 matrix.\n *\n * @param {Matrix3} m - The matrix to multiply with.\n * @return {Matrix3} A reference to this matrix.\n */\n premultiply(m) {\n return this.multiplyMatrices(m, this);\n }\n /**\n * Multiples the given 3x3 matrices and stores the result\n * in this matrix.\n *\n * @param {Matrix3} a - The first matrix.\n * @param {Matrix3} b - The second matrix.\n * @return {Matrix3} A reference to this matrix.\n */\n multiplyMatrices(a, b) {\n const ae = a.elements;\n const be = b.elements;\n const te = this.elements;\n const a11 = ae[0], a12 = ae[3], a13 = ae[6];\n const a21 = ae[1], a22 = ae[4], a23 = ae[7];\n const a31 = ae[2], a32 = ae[5], a33 = ae[8];\n const b11 = be[0], b12 = be[3], b13 = be[6];\n const b21 = be[1], b22 = be[4], b23 = be[7];\n const b31 = be[2], b32 = be[5], b33 = be[8];\n te[0] = a11 * b11 + a12 * b21 + a13 * b31;\n te[3] = a11 * b12 + a12 * b22 + a13 * b32;\n te[6] = a11 * b13 + a12 * b23 + a13 * b33;\n te[1] = a21 * b11 + a22 * b21 + a23 * b31;\n te[4] = a21 * b12 + a22 * b22 + a23 * b32;\n te[7] = a21 * b13 + a22 * b23 + a23 * b33;\n te[2] = a31 * b11 + a32 * b21 + a33 * b31;\n te[5] = a31 * b12 + a32 * b22 + a33 * b32;\n te[8] = a31 * b13 + a32 * b23 + a33 * b33;\n return this;\n }\n /**\n * Multiplies every component of the matrix by the given scalar.\n *\n * @param {number} s - The scalar.\n * @return {Matrix3} A reference to this matrix.\n */\n multiplyScalar(s) {\n const te = this.elements;\n te[0] *= s;\n te[3] *= s;\n te[6] *= s;\n te[1] *= s;\n te[4] *= s;\n te[7] *= s;\n te[2] *= s;\n te[5] *= s;\n te[8] *= s;\n return this;\n }\n /**\n * Computes and returns the determinant of this matrix.\n *\n * @return {number} The determinant.\n */\n determinant() {\n const te = this.elements;\n const a = te[0], b = te[1], c = te[2], d = te[3], e = te[4], f = te[5], g = te[6], h = te[7], i2 = te[8];\n return a * e * i2 - a * f * h - b * d * i2 + b * f * g + c * d * h - c * e * g;\n }\n /**\n * Inverts this matrix, using the [analytic method]{@link https://en.wikipedia.org/wiki/Invertible_matrix#Analytic_solution}.\n * You can not invert with a determinant of zero. If you attempt this, the method produces\n * a zero matrix instead.\n *\n * @return {Matrix3} A reference to this matrix.\n */\n invert() {\n const te = this.elements, n11 = te[0], n21 = te[1], n31 = te[2], n12 = te[3], n22 = te[4], n32 = te[5], n13 = te[6], n23 = te[7], n33 = te[8], t11 = n33 * n22 - n32 * n23, t12 = n32 * n13 - n33 * n12, t13 = n23 * n12 - n22 * n13, det = n11 * t11 + n21 * t12 + n31 * t13;\n if (det === 0) return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0);\n const detInv = 1 / det;\n te[0] = t11 * detInv;\n te[1] = (n31 * n23 - n33 * n21) * detInv;\n te[2] = (n32 * n21 - n31 * n22) * detInv;\n te[3] = t12 * detInv;\n te[4] = (n33 * n11 - n31 * n13) * detInv;\n te[5] = (n31 * n12 - n32 * n11) * detInv;\n te[6] = t13 * detInv;\n te[7] = (n21 * n13 - n23 * n11) * detInv;\n te[8] = (n22 * n11 - n21 * n12) * detInv;\n return this;\n }\n /**\n * Transposes this matrix in place.\n *\n * @return {Matrix3} A reference to this matrix.\n */\n transpose() {\n let tmp;\n const m = this.elements;\n tmp = m[1];\n m[1] = m[3];\n m[3] = tmp;\n tmp = m[2];\n m[2] = m[6];\n m[6] = tmp;\n tmp = m[5];\n m[5] = m[7];\n m[7] = tmp;\n return this;\n }\n /**\n * Computes the normal matrix which is the inverse transpose of the upper\n * left 3x3 portion of the given 4x4 matrix.\n *\n * @param {Matrix4} matrix4 - The 4x4 matrix.\n * @return {Matrix3} A reference to this matrix.\n */\n getNormalMatrix(matrix4) {\n return this.setFromMatrix4(matrix4).invert().transpose();\n }\n /**\n * Transposes this matrix into the supplied array, and returns itself unchanged.\n *\n * @param {Array<number>} r - An array to store the transposed matrix elements.\n * @return {Matrix3} A reference to this matrix.\n */\n transposeIntoArray(r) {\n const m = this.elements;\n r[0] = m[0];\n r[1] = m[3];\n r[2] = m[6];\n r[3] = m[1];\n r[4] = m[4];\n r[5] = m[7];\n r[6] = m[2];\n r[7] = m[5];\n r[8] = m[8];\n return this;\n }\n /**\n * Sets the UV transform matrix from offset, repeat, rotation, and center.\n *\n * @param {number} tx - Offset x.\n * @param {number} ty - Offset y.\n * @param {number} sx - Repeat x.\n * @param {number} sy - Repeat y.\n * @param {number} rotation - Rotation, in radians. Positive values rotate counterclockwise.\n * @param {number} cx - Center x of rotation.\n * @param {number} cy - Center y of rotation\n * @return {Matrix3} A reference to this matrix.\n */\n setUvTransform(tx, ty, sx, sy, rotation, cx, cy) {\n const c = Math.cos(rotation);\n const s = Math.sin(rotation);\n this.set(\n sx * c,\n sx * s,\n -sx * (c * cx + s * cy) + cx + tx,\n -sy * s,\n sy * c,\n -sy * (-s * cx + c * cy) + cy + ty,\n 0,\n 0,\n 1\n );\n return this;\n }\n /**\n * Scales this matrix with the given scalar values.\n *\n * @param {number} sx - The amount to scale in the X axis.\n * @param {number} sy - The amount to scale in the Y axis.\n * @return {Matrix3} A reference to this matrix.\n */\n scale(sx, sy) {\n this.premultiply(_m3.makeScale(sx, sy));\n return this;\n }\n /**\n * Rotates this matrix by the given angle.\n *\n * @param {number} theta - The rotation in radians.\n * @return {Matrix3} A reference to this matrix.\n */\n rotate(theta) {\n this.premultiply(_m3.makeRotation(-theta));\n return this;\n }\n /**\n * Translates this matrix by the given scalar values.\n *\n * @param {number} tx - The amount to translate in the X axis.\n * @param {number} ty - The amount to translate in the Y axis.\n * @return {Matrix3} A reference to this matrix.\n */\n translate(tx, ty) {\n this.premultiply(_m3.makeTranslation(tx, ty));\n return this;\n }\n // for 2D Transforms\n /**\n * Sets this matrix as a 2D translation transform.\n *\n * @param {number|Vector2} x - The amount to translate in the X axis or alternatively a translation vector.\n * @param {number} y - The amount to translate in the Y axis.\n * @return {Matrix3} A reference to this matrix.\n */\n makeTranslation(x2, y) {\n if (x2.isVector2) {\n this.set(\n 1,\n 0,\n x2.x,\n 0,\n 1,\n x2.y,\n 0,\n 0,\n 1\n );\n } else {\n this.set(\n 1,\n 0,\n x2,\n 0,\n 1,\n y,\n 0,\n 0,\n 1\n );\n }\n return this;\n }\n /**\n * Sets this matrix as a 2D rotational transformation.\n *\n * @param {number} theta - The rotation in radians.\n * @return {Matrix3} A reference to this matrix.\n */\n makeRotation(theta) {\n const c = Math.cos(theta);\n const s = Math.sin(theta);\n this.set(\n c,\n -s,\n 0,\n s,\n c,\n 0,\n 0,\n 0,\n 1\n );\n return this;\n }\n /**\n * Sets this matrix as a 2D scale transform.\n *\n * @param {number} x - The amount to scale in the X axis.\n * @param {number} y - The amount to scale in the Y axis.\n * @return {Matrix3} A reference to this matrix.\n */\n makeScale(x2, y) {\n this.set(\n x2,\n 0,\n 0,\n 0,\n y,\n 0,\n 0,\n 0,\n 1\n );\n return this;\n }\n /**\n * Returns `true` if this matrix is equal with the given one.\n *\n * @param {Matrix3} matrix - The matrix to test for equality.\n * @return {boolean} Whether this matrix is equal with the given one.\n */\n equals(matrix) {\n const te = this.elements;\n const me = matrix.elements;\n for (let i2 = 0; i2 < 9; i2++) {\n if (te[i2] !== me[i2]) return false;\n }\n return true;\n }\n /**\n * Sets the elements of the matrix from the given array.\n *\n * @param {Array<number>} array - The matrix elements in column-major order.\n * @param {number} [offset=0] - Index of the first element in the array.\n * @return {Matrix3} A reference to this matrix.\n */\n fromArray(array, offset = 0) {\n for (let i2 = 0; i2 < 9; i2++) {\n this.elements[i2] = array[i2 + offset];\n }\n return this;\n }\n /**\n * Writes the elements of this matrix to the given array. If no array is provided,\n * the method returns a new instance.\n *\n * @param {Array<number>} [array=[]] - The target array holding the matrix elements in column-major order.\n * @param {number} [offset=0] - Index of the first element in the array.\n * @return {Array<number>} The matrix elements in column-major order.\n */\n toArray(array = [], offset = 0) {\n const te = this.elements;\n array[offset] = te[0];\n array[offset + 1] = te[1];\n array[offset + 2] = te[2];\n array[offset + 3] = te[3];\n array[offset + 4] = te[4];\n array[offset + 5] = te[5];\n array[offset + 6] = te[6];\n array[offset + 7] = te[7];\n array[offset + 8] = te[8];\n return array;\n }\n /**\n * Returns a matrix with copied values from this instance.\n *\n * @return {Matrix3} A clone of this instance.\n */\n clone() {\n return new this.constructor().fromArray(this.elements);\n }\n }\n const _m3 = /* @__PURE__ */ new Matrix3();\n const _cache = {};\n function warnOnce(message) {\n if (message in _cache) return;\n _cache[message] = true;\n console.warn(message);\n }\n const LINEAR_REC709_TO_XYZ = /* @__PURE__ */ new Matrix3().set(\n 0.4123908,\n 0.3575843,\n 0.1804808,\n 0.212639,\n 0.7151687,\n 0.0721923,\n 0.0193308,\n 0.1191948,\n 0.9505322\n );\n const XYZ_TO_LINEAR_REC709 = /* @__PURE__ */ new Matrix3().set(\n 3.2409699,\n -1.5373832,\n -0.4986108,\n -0.9692436,\n 1.8759675,\n 0.0415551,\n 0.0556301,\n -0.203977,\n 1.0569715\n );\n function createColorManagement() {\n const ColorManagement2 = {\n enabled: true,\n workingColorSpace: LinearSRGBColorSpace,\n /**\n * Implementations of supported color spaces.\n *\n * Required:\n * - primaries: chromaticity coordinates [ rx ry gx gy bx by ]\n * - whitePoint: reference white [ x y ]\n * - transfer: transfer function (pre-defined)\n * - toXYZ: Matrix3 RGB to XYZ transform\n * - fromXYZ: Matrix3 XYZ to RGB transform\n * - luminanceCoefficients: RGB luminance coefficients\n *\n * Optional:\n * - outputColorSpaceConfig: { drawingBufferColorSpace: ColorSpace }\n * - workingColorSpaceConfig: { unpackColorSpace: ColorSpace }\n *\n * Reference:\n * - https://www.russellcottrell.com/photo/matrixCalculator.htm\n */\n spaces: {},\n convert: function(color, sourceColorSpace, targetColorSpace) {\n if (this.enabled === false || sourceColorSpace === targetColorSpace || !sourceColorSpace || !targetColorSpace) {\n return color;\n }\n if (this.spaces[sourceColorSpace].transfer === SRGBTransfer) {\n color.r = SRGBToLinear(color.r);\n color.g = SRGBToLinear(color.g);\n color.b = SRGBToLinear(color.b);\n }\n if (this.spaces[sourceColorSpace].primaries !== this.spaces[targetColorSpace].primaries) {\n color.applyMatrix3(this.spaces[sourceColorSpace].toXYZ);\n color.applyMatrix3(this.spaces[targetColorSpace].fromXYZ);\n }\n if (this.spaces[targetColorSpace].transfer === SRGBTransfer) {\n color.r = LinearToSRGB(color.r);\n color.g = LinearToSRGB(color.g);\n color.b = LinearToSRGB(color.b);\n }\n return color;\n },\n workingToColorSpace: function(color, targetColorSpace) {\n return this.convert(color, this.workingColorSpace, targetColorSpace);\n },\n colorSpaceToWorking: function(color, sourceColorSpace) {\n return this.convert(color, sourceColorSpace, this.workingColorSpace);\n },\n getPrimaries: function(colorSpace) {\n return this.spaces[colorSpace].primaries;\n },\n getTransfer: function(colorSpace) {\n if (colorSpace === NoColorSpace) return LinearTransfer;\n return this.spaces[colorSpace].transfer;\n },\n getLuminanceCoefficients: function(target, colorSpace = this.workingColorSpace) {\n return target.fromArray(this.spaces[colorSpace].luminanceCoefficients);\n },\n define: function(colorSpaces) {\n Object.assign(this.spaces, colorSpaces);\n },\n // Internal APIs\n _getMatrix: function(targetMatrix, sourceColorSpace, targetColorSpace) {\n return targetMatrix.copy(this.spaces[sourceColorSpace].toXYZ).multiply(this.spaces[targetColorSpace].fromXYZ);\n },\n _getDrawingBufferColorSpace: function(colorSpace) {\n return this.spaces[colorSpace].outputColorSpaceConfig.drawingBufferColorSpace;\n },\n _getUnpackColorSpace: function(colorSpace = this.workingColorSpace) {\n return this.spaces[colorSpace].workingColorSpaceConfig.unpackColorSpace;\n },\n // Deprecated\n fromWorkingColorSpace: function(color, targetColorSpace) {\n warnOnce("THREE.ColorManagement: .fromWorkingColorSpace() has been renamed to .workingToColorSpace().");\n return ColorManagement2.workingToColorSpace(color, targetColorSpace);\n },\n toWorkingColorSpace: function(color, sourceColorSpace) {\n warnOnce("THREE.ColorManagement: .toWorkingColorSpace() has been renamed to .colorSpaceToWorking().");\n return ColorManagement2.colorSpaceToWorking(color, sourceColorSpace);\n }\n };\n const REC709_PRIMARIES = [0.64, 0.33, 0.3, 0.6, 0.15, 0.06];\n const REC709_LUMINANCE_COEFFICIENTS = [0.2126, 0.7152, 0.0722];\n const D65 = [0.3127, 0.329];\n ColorManagement2.define({\n [LinearSRGBColorSpace]: {\n primaries: REC709_PRIMARIES,\n whitePoint: D65,\n transfer: LinearTransfer,\n toXYZ: LINEAR_REC709_TO_XYZ,\n fromXYZ: XYZ_TO_LINEAR_REC709,\n luminanceCoefficients: REC709_LUMINANCE_COEFFICIENTS,\n workingColorSpaceConfig: { unpackColorSpace: SRGBColorSpace },\n outputColorSpaceConfig: { drawingBufferColorSpace: SRGBColorSpace }\n },\n [SRGBColorSpace]: {\n primaries: REC709_PRIMARIES,\n whitePoint: D65,\n transfer: SRGBTransfer,\n toXYZ: LINEAR_REC709_TO_XYZ,\n fromXYZ: XYZ_TO_LINEAR_REC709,\n luminanceCoefficients: REC709_LUMINANCE_COEFFICIENTS,\n outputColorSpaceConfig: { drawingBufferColorSpace: SRGBColorSpace }\n }\n });\n return ColorManagement2;\n }\n const ColorManagement = /* @__PURE__ */ createColorManagement();\n function SRGBToLinear(c) {\n return c < 0.04045 ? c * 0.0773993808 : Math.pow(c * 0.9478672986 + 0.0521327014, 2.4);\n }\n function LinearToSRGB(c) {\n return c < 31308e-7 ? c * 12.92 : 1.055 * Math.pow(c, 0.41666) - 0.055;\n }\n class Box3 {\n /**\n * Constructs a new bounding box.\n *\n * @param {Vector3} [min=(Infinity,Infinity,Infinity)] - A vector representing the lower boundary of the box.\n * @param {Vector3} [max=(-Infinity,-Infinity,-Infinity)] - A vector representing the upper boundary of the box.\n */\n constructor(min = new Vector3(Infinity, Infinity, Infinity), max2 = new Vector3(-Infinity, -Infinity, -Infinity)) {\n this.isBox3 = true;\n this.min = min;\n this.max = max2;\n }\n /**\n * Sets the lower and upper boundaries of this box.\n * Please note that this method only copies the values from the given objects.\n *\n * @param {Vector3} min - The lower boundary of the box.\n * @param {Vector3} max - The upper boundary of the box.\n * @return {Box3} A reference to this bounding box.\n */\n set(min, max2) {\n this.min.copy(min);\n this.max.copy(max2);\n return this;\n }\n /**\n * Sets the upper and lower bounds of this box so it encloses the position data\n * in the given array.\n *\n * @param {Array<number>} array - An array holding 3D position data.\n * @return {Box3} A reference to this bounding box.\n */\n setFromArray(array) {\n this.makeEmpty();\n for (let i2 = 0, il = array.length; i2 < il; i2 += 3) {\n this.expandByPoint(_vector$b.fromArray(array, i2));\n }\n return this;\n }\n /**\n * Sets the upper and lower bounds of this box so it encloses the position data\n * in the given buffer attribute.\n *\n * @param {BufferAttribute} attribute - A buffer attribute holding 3D position data.\n * @return {Box3} A reference to this bounding box.\n */\n setFromBufferAttribute(attribute) {\n this.makeEmpty();\n for (let i2 = 0, il = attribute.count; i2 < il; i2++) {\n this.expandByPoint(_vector$b.fromBufferAttribute(attribute, i2));\n }\n return this;\n }\n /**\n * Sets the upper and lower bounds of this box so it encloses the position data\n * in the given array.\n *\n * @param {Array<Vector3>} points - An array holding 3D position data as instances of {@link Vector3}.\n * @return {Box3} A reference to this bounding box.\n */\n setFromPoints(points) {\n this.makeEmpty();\n for (let i2 = 0, il = points.length; i2 < il; i2++) {\n this.expandByPoint(points[i2]);\n }\n return this;\n }\n /**\n * Centers this box on the given center vector and sets this box\'s width, height and\n * depth to the given size values.\n *\n * @param {Vector3} center - The center of the box.\n * @param {Vector3} size - The x, y and z dimensions of the box.\n * @return {Box3} A reference to this bounding box.\n */\n setFromCenterAndSize(center, size) {\n const halfSize = _vector$b.copy(size).multiplyScalar(0.5);\n this.min.copy(center).sub(halfSize);\n this.max.copy(center).add(halfSize);\n return this;\n }\n /**\n * Computes the world-axis-aligned bounding box for the given 3D object\n * (including its children), accounting for the object\'s, and children\'s,\n * world transforms. The function may result in a larger box than strictly necessary.\n *\n * @param {Object3D} object - The 3D object to compute the bounding box for.\n * @param {boolean} [precise=false] - If set to `true`, the method computes the smallest\n * world-axis-aligned bounding box at the expense of more computation.\n * @return {Box3} A reference to this bounding box.\n */\n setFromObject(object, precise = false) {\n this.makeEmpty();\n return this.expandByObject(object, precise);\n }\n /**\n * Returns a new box with copied values from this instance.\n *\n * @return {Box3} A clone of this instance.\n */\n clone() {\n return new this.constructor().copy(this);\n }\n /**\n * Copies the values of the given box to this instance.\n *\n * @param {Box3} box - The box to copy.\n * @return {Box3} A reference to this bounding box.\n */\n copy(box) {\n this.min.copy(box.min);\n this.max.copy(box.max);\n return this;\n }\n /**\n * Makes this box empty which means in encloses a zero space in 3D.\n *\n * @return {Box3} A reference to this bounding box.\n */\n makeEmpty() {\n this.min.x = this.min.y = this.min.z = Infinity;\n this.max.x = this.max.y = this.max.z = -Infinity;\n return this;\n }\n /**\n * Returns true if this box includes zero points within its bounds.\n * Note that a box with equal lower and upper bounds still includes one\n * point, the one both bounds share.\n *\n * @return {boolean} Whether this box is empty or not.\n */\n isEmpty() {\n return this.max.x < this.min.x || this.max.y < this.min.y || this.max.z < this.min.z;\n }\n /**\n * Returns the center point of this box.\n *\n * @param {Vector3} target - The target vector that is used to store the method\'s result.\n * @return {Vector3} The center point.\n */\n getCenter(target) {\n return this.isEmpty() ? target.set(0, 0, 0) : target.addVectors(this.min, this.max).multiplyScalar(0.5);\n }\n /**\n * Returns the dimensions of this box.\n *\n * @param {Vector3} target - The target vector that is used to store the method\'s result.\n * @return {Vector3} The size.\n */\n getSize(target) {\n return this.isEmpty() ? target.set(0, 0, 0) : target.subVectors(this.max, this.min);\n }\n /**\n * Expands the boundaries of this box to include the given point.\n *\n * @param {Vector3} point - The point that should be included by the bounding box.\n * @return {Box3} A reference to this bounding box.\n */\n expandByPoint(point) {\n this.min.min(point);\n this.max.max(point);\n return this;\n }\n /**\n * Expands this box equilaterally by the given vector. The width of this\n * box will be expanded by the x component of the vector in both\n * directions. The height of this box will be expanded by the y component of\n * the vector in both directions. The depth of this box will be\n * expanded by the z component of the vector in both directions.\n *\n * @param {Vector3} vector - The vector that should expand the bounding box.\n * @return {Box3} A reference to this bounding box.\n */\n expandByVector(vector) {\n this.min.sub(vector);\n this.max.add(vector);\n return this;\n }\n /**\n * Expands each dimension of the box by the given scalar. If negative, the\n * dimensions of the box will be contracted.\n *\n * @param {number} scalar - The scalar value that should expand the bounding box.\n * @return {Box3} A reference to this bounding box.\n */\n expandByScalar(scalar) {\n this.min.addScalar(-scalar);\n this.max.addScalar(scalar);\n return this;\n }\n /**\n * Expands the boundaries of this box to include the given 3D object and\n * its children, accounting for the object\'s, and children\'s, world\n * transforms. The function may result in a larger box than strictly\n * necessary (unless the precise parameter is set to true).\n *\n * @param {Object3D} object - The 3D object that should expand the bounding box.\n * @param {boolean} precise - If set to `true`, the method expands the bounding box\n * as little as necessary at the expense of more computation.\n * @return {Box3} A reference to this bounding box.\n */\n expandByObject(object, precise = false) {\n object.updateWorldMatrix(false, false);\n const geometry = object.geometry;\n if (geometry !== void 0) {\n const positionAttribute = geometry.getAttribute("position");\n if (precise === true && positionAttribute !== void 0 && object.isInstancedMesh !== true) {\n for (let i2 = 0, l = positionAttribute.count; i2 < l; i2++) {\n if (object.isMesh === true) {\n object.getVertexPosition(i2, _vector$b);\n } else {\n _vector$b.fromBufferAttribute(positionAttribute, i2);\n }\n _vector$b.applyMatrix4(object.matrixWorld);\n this.expandByPoint(_vector$b);\n }\n } else {\n if (object.boundingBox !== void 0) {\n if (object.boundingBox === null) {\n object.computeBoundingBox();\n }\n _box$4.copy(object.boundingBox);\n } else {\n if (geometry.boundingBox === null) {\n geometry.computeBoundingBox();\n }\n _box$4.copy(geometry.boundingBox);\n }\n _box$4.applyMatrix4(object.matrixWorld);\n this.union(_box$4);\n }\n }\n const children = object.children;\n for (let i2 = 0, l = children.length; i2 < l; i2++) {\n this.expandByObject(children[i2], precise);\n }\n return this;\n }\n /**\n * Returns `true` if the given point lies within or on the boundaries of this box.\n *\n * @param {Vector3} point - The point to test.\n * @return {boolean} Whether the bounding box contains the given point or not.\n */\n containsPoint(point) {\n return point.x >= this.min.x && point.x <= this.max.x && point.y >= this.min.y && point.y <= this.max.y && point.z >= this.min.z && point.z <= this.max.z;\n }\n /**\n * Returns `true` if this bounding box includes the entirety of the given bounding box.\n * If this box and the given one are identical, this function also returns `true`.\n *\n * @param {Box3} box - The bounding box to test.\n * @return {boolean} Whether the bounding box contains the given bounding box or not.\n */\n containsBox(box) {\n return this.min.x <= box.min.x && box.max.x <= this.max.x && this.min.y <= box.min.y && box.max.y <= this.max.y && this.min.z <= box.min.z && box.max.z <= this.max.z;\n }\n /**\n * Returns a point as a proportion of this box\'s width, height and depth.\n *\n * @param {Vector3} point - A point in 3D space.\n * @param {Vector3} target - The target vector that is used to store the method\'s result.\n * @return {Vector3} A point as a proportion of this box\'s width, height and depth.\n */\n getParameter(point, target) {\n return target.set(\n (point.x - this.min.x) / (this.max.x - this.min.x),\n (point.y - this.min.y) / (this.max.y - this.min.y),\n (point.z - this.min.z) / (this.max.z - this.min.z)\n );\n }\n /**\n * Returns `true` if the given bounding box intersects with this bounding box.\n *\n * @param {Box3} box - The bounding box to test.\n * @return {boolean} Whether the given bounding box intersects with this bounding box.\n */\n intersectsBox(box) {\n return box.max.x >= this.min.x && box.min.x <= this.max.x && box.max.y >= this.min.y && box.min.y <= this.max.y && box.max.z >= this.min.z && box.min.z <= this.max.z;\n }\n /**\n * Returns `true` if the given bounding sphere intersects with this bounding box.\n *\n * @param {Sphere} sphere - The bounding sphere to test.\n * @return {boolean} Whether the given bounding sphere intersects with this bounding box.\n */\n intersectsSphere(sphere) {\n this.clampPoint(sphere.center, _vector$b);\n return _vector$b.distanceToSquared(sphere.center) <= sphere.radius * sphere.radius;\n }\n /**\n * Returns `true` if the given plane intersects with this bounding box.\n *\n * @param {Plane} plane - The plane to test.\n * @return {boolean} Whether the given plane intersects with this bounding box.\n */\n intersectsPlane(plane) {\n let min, max2;\n if (plane.normal.x > 0) {\n min = plane.normal.x * this.min.x;\n max2 = plane.normal.x * this.max.x;\n } else {\n min = plane.normal.x * this.max.x;\n max2 = plane.normal.x * this.min.x;\n }\n if (plane.normal.y > 0) {\n min += plane.normal.y * this.min.y;\n max2 += plane.normal.y * this.max.y;\n } else {\n min += plane.normal.y * this.max.y;\n max2 += plane.normal.y * this.min.y;\n }\n if (plane.normal.z > 0) {\n min += plane.normal.z * this.min.z;\n max2 += plane.normal.z * this.max.z;\n } else {\n min += plane.normal.z * this.max.z;\n max2 += plane.normal.z * this.min.z;\n }\n return min <= -plane.constant && max2 >= -plane.constant;\n }\n /**\n * Returns `true` if the given triangle intersects with this bounding box.\n *\n * @param {Triangle} triangle - The triangle to test.\n * @return {boolean} Whether the given triangle intersects with this bounding box.\n */\n intersectsTriangle(triangle) {\n if (this.isEmpty()) {\n return false;\n }\n this.getCenter(_center);\n _extents.subVectors(this.max, _center);\n _v0$2.subVectors(triangle.a, _center);\n _v1$7.subVectors(triangle.b, _center);\n _v2$4.subVectors(triangle.c, _center);\n _f0.subVectors(_v1$7, _v0$2);\n _f1.subVectors(_v2$4, _v1$7);\n _f2.subVectors(_v0$2, _v2$4);\n let axes = [\n 0,\n -_f0.z,\n _f0.y,\n 0,\n -_f1.z,\n _f1.y,\n 0,\n -_f2.z,\n _f2.y,\n _f0.z,\n 0,\n -_f0.x,\n _f1.z,\n 0,\n -_f1.x,\n _f2.z,\n 0,\n -_f2.x,\n -_f0.y,\n _f0.x,\n 0,\n -_f1.y,\n _f1.x,\n 0,\n -_f2.y,\n _f2.x,\n 0\n ];\n if (!satForAxes(axes, _v0$2, _v1$7, _v2$4, _extents)) {\n return false;\n }\n axes = [1, 0, 0, 0, 1, 0, 0, 0, 1];\n if (!satForAxes(axes, _v0$2, _v1$7, _v2$4, _extents)) {\n return false;\n }\n _triangleNormal.crossVectors(_f0, _f1);\n axes = [_triangleNormal.x, _triangleNormal.y, _triangleNormal.z];\n return satForAxes(axes, _v0$2, _v1$7, _v2$4, _extents);\n }\n /**\n * Clamps the given point within the bounds of this box.\n *\n * @param {Vector3} point - The point to clamp.\n * @param {Vector3} target - The target vector that is used to store the method\'s result.\n * @return {Vector3} The clamped point.\n */\n clampPoint(point, target) {\n return target.copy(point).clamp(this.min, this.max);\n }\n /**\n * Returns the euclidean distance from any edge of this box to the specified point. If\n * the given point lies inside of this box, the distance will be `0`.\n *\n * @param {Vector3} point - The point to compute the distance to.\n * @return {number} The euclidean distance.\n */\n distanceToPoint(point) {\n return this.clampPoint(point, _vector$b).distanceTo(point);\n }\n /**\n * Returns a bounding sphere that encloses this bounding box.\n *\n * @param {Sphere} target - The target sphere that is used to store the method\'s result.\n * @return {Sphere} The bounding sphere that encloses this bounding box.\n */\n getBoundingSphere(target) {\n if (this.isEmpty()) {\n target.makeEmpty();\n } else {\n this.getCenter(target.center);\n target.radius = this.getSize(_vector$b).length() * 0.5;\n }\n return target;\n }\n /**\n * Computes the intersection of this bounding box and the given one, setting the upper\n * bound of this box to the lesser of the two boxes\' upper bounds and the\n * lower bound of this box to the greater of the two boxes\' lower bounds. If\n * there\'s no overlap, makes this box empty.\n *\n * @param {Box3} box - The bounding box to intersect with.\n * @return {Box3} A reference to this bounding box.\n */\n intersect(box) {\n this.min.max(box.min);\n this.max.min(box.max);\n if (this.isEmpty()) this.makeEmpty();\n return this;\n }\n /**\n * Computes the union of this box and another and the given one, setting the upper\n * bound of this box to the greater of the two boxes\' upper bounds and the\n * lower bound of this box to the lesser of the two boxes\' lower bounds.\n *\n * @param {Box3} box - The bounding box that will be unioned with this instance.\n * @return {Box3} A reference to this bounding box.\n */\n union(box) {\n this.min.min(box.min);\n this.max.max(box.max);\n return this;\n }\n /**\n * Transforms this bounding box by the given 4x4 transformation matrix.\n *\n * @param {Matrix4} matrix - The transformation matrix.\n * @return {Box3} A reference to this bounding box.\n */\n applyMatrix4(matrix) {\n if (this.isEmpty()) return this;\n _points[0].set(this.min.x, this.min.y, this.min.z).applyMatrix4(matrix);\n _points[1].set(this.min.x, this.min.y, this.max.z).applyMatrix4(matrix);\n _points[2].set(this.min.x, this.max.y, this.min.z).applyMatrix4(matrix);\n _points[3].set(this.min.x, this.max.y, this.max.z).applyMatrix4(matrix);\n _points[4].set(this.max.x, this.min.y, this.min.z).applyMatrix4(matrix);\n _points[5].set(this.max.x, this.min.y, this.max.z).applyMatrix4(matrix);\n _points[6].set(this.max.x, this.max.y, this.min.z).applyMatrix4(matrix);\n _points[7].set(this.max.x, this.max.y, this.max.z).applyMatrix4(matrix);\n this.setFromPoints(_points);\n return this;\n }\n /**\n * Adds the given offset to both the upper and lower bounds of this bounding box,\n * effectively moving it in 3D space.\n *\n * @param {Vector3} offset - The offset that should be used to translate the bounding box.\n * @return {Box3} A reference to this bounding box.\n */\n translate(offset) {\n this.min.add(offset);\n this.max.add(offset);\n return this;\n }\n /**\n * Returns `true` if this bounding box is equal with the given one.\n *\n * @param {Box3} box - The box to test for equality.\n * @return {boolean} Whether this bounding box is equal with the given one.\n */\n equals(box) {\n return box.min.equals(this.min) && box.max.equals(this.max);\n }\n /**\n * Returns a serialized structure of the bounding box.\n *\n * @return {Object} Serialized structure with fields representing the object state.\n */\n toJSON() {\n return {\n min: this.min.toArray(),\n max: this.max.toArray()\n };\n }\n /**\n * Returns a serialized structure of the bounding box.\n *\n * @param {Object} json - The serialized json to set the box from.\n * @return {Box3} A reference to this bounding box.\n */\n fromJSON(json) {\n this.min.fromArray(json.min);\n this.max.fromArray(json.max);\n return this;\n }\n }\n const _points = [\n /* @__PURE__ */ new Vector3(),\n /* @__PURE__ */ new Vector3(),\n /* @__PURE__ */ new Vector3(),\n /* @__PURE__ */ new Vector3(),\n /* @__PURE__ */ new Vector3(),\n /* @__PURE__ */ new Vector3(),\n /* @__PURE__ */ new Vector3(),\n /* @__PURE__ */ new Vector3()\n ];\n const _vector$b = /* @__PURE__ */ new Vector3();\n const _box$4 = /* @__PURE__ */ new Box3();\n const _v0$2 = /* @__PURE__ */ new Vector3();\n const _v1$7 = /* @__PURE__ */ new Vector3();\n const _v2$4 = /* @__PURE__ */ new Vector3();\n const _f0 = /* @__PURE__ */ new Vector3();\n const _f1 = /* @__PURE__ */ new Vector3();\n const _f2 = /* @__PURE__ */ new Vector3();\n const _center = /* @__PURE__ */ new Vector3();\n const _extents = /* @__PURE__ */ new Vector3();\n const _triangleNormal = /* @__PURE__ */ new Vector3();\n const _testAxis = /* @__PURE__ */ new Vector3();\n function satForAxes(axes, v0, v1, v2, extents) {\n for (let i2 = 0, j = axes.length - 3; i2 <= j; i2 += 3) {\n _testAxis.fromArray(axes, i2);\n const r = extents.x * Math.abs(_testAxis.x) + extents.y * Math.abs(_testAxis.y) + extents.z * Math.abs(_testAxis.z);\n const p0 = v0.dot(_testAxis);\n const p1 = v1.dot(_testAxis);\n const p2 = v2.dot(_testAxis);\n if (Math.max(-Math.max(p0, p1, p2), Math.min(p0, p1, p2)) > r) {\n return false;\n }\n }\n return true;\n }\n const _colorKeywords = {\n "aliceblue": 15792383,\n "antiquewhite": 16444375,\n "aqua": 65535,\n "aquamarine": 8388564,\n "azure": 15794175,\n "beige": 16119260,\n "bisque": 16770244,\n "black": 0,\n "blanchedalmond": 16772045,\n "blue": 255,\n "blueviolet": 9055202,\n "brown": 10824234,\n "burlywood": 14596231,\n "cadetblue": 6266528,\n "chartreuse": 8388352,\n "chocolate": 13789470,\n "coral": 16744272,\n "cornflowerblue": 6591981,\n "cornsilk": 16775388,\n "crimson": 14423100,\n "cyan": 65535,\n "darkblue": 139,\n "darkcyan": 35723,\n "darkgoldenrod": 12092939,\n "darkgray": 11119017,\n "darkgreen": 25600,\n "darkgrey": 11119017,\n "darkkhaki": 12433259,\n "darkmagenta": 9109643,\n "darkolivegreen": 5597999,\n "darkorange": 16747520,\n "darkorchid": 10040012,\n "darkred": 9109504,\n "darksalmon": 15308410,\n "darkseagreen": 9419919,\n "darkslateblue": 4734347,\n "darkslategray": 3100495,\n "darkslategrey": 3100495,\n "darkturquoise": 52945,\n "darkviolet": 9699539,\n "deeppink": 16716947,\n "deepskyblue": 49151,\n "dimgray": 6908265,\n "dimgrey": 6908265,\n "dodgerblue": 2003199,\n "firebrick": 11674146,\n "floralwhite": 16775920,\n "forestgreen": 2263842,\n "fuchsia": 16711935,\n "gainsboro": 14474460,\n "ghostwhite": 16316671,\n "gold": 16766720,\n "goldenrod": 14329120,\n "gray": 8421504,\n "green": 32768,\n "greenyellow": 11403055,\n "grey": 8421504,\n "honeydew": 15794160,\n "hotpink": 16738740,\n "indianred": 13458524,\n "indigo": 4915330,\n "ivory": 16777200,\n "khaki": 15787660,\n "lavender": 15132410,\n "lavenderblush": 16773365,\n "lawngreen": 8190976,\n "lemonchiffon": 16775885,\n "lightblue": 11393254,\n "lightcoral": 15761536,\n "lightcyan": 14745599,\n "lightgoldenrodyellow": 16448210,\n "lightgray": 13882323,\n "lightgreen": 9498256,\n "lightgrey": 13882323,\n "lightpink": 16758465,\n "lightsalmon": 16752762,\n "lightseagreen": 2142890,\n "lightskyblue": 8900346,\n "lightslategray": 7833753,\n "lightslategrey": 7833753,\n "lightsteelblue": 11584734,\n "lightyellow": 16777184,\n "lime": 65280,\n "limegreen": 3329330,\n "linen": 16445670,\n "magenta": 16711935,\n "maroon": 8388608,\n "mediumaquamarine": 6737322,\n "mediumblue": 205,\n "mediumorchid": 12211667,\n "mediumpurple": 9662683,\n "mediumseagreen": 3978097,\n "mediumslateblue": 8087790,\n "mediumspringgreen": 64154,\n "mediumturquoise": 4772300,\n "mediumvioletred": 13047173,\n "midnightblue": 1644912,\n "mintcream": 16121850,\n "mistyrose": 16770273,\n "moccasin": 16770229,\n "navajowhite": 16768685,\n "navy": 128,\n "oldlace": 16643558,\n "olive": 8421376,\n "olivedrab": 7048739,\n "orange": 16753920,\n "orangered": 16729344,\n "orchid": 14315734,\n "palegoldenrod": 15657130,\n "palegreen": 10025880,\n "paleturquoise": 11529966,\n "palevioletred": 14381203,\n "papayawhip": 16773077,\n "peachpuff": 16767673,\n "peru": 13468991,\n "pink": 16761035,\n "plum": 14524637,\n "powderblue": 11591910,\n "purple": 8388736,\n "rebeccapurple": 6697881,\n "red": 16711680,\n "rosybrown": 12357519,\n "royalblue": 4286945,\n "saddlebrown": 9127187,\n "salmon": 16416882,\n "sandybrown": 16032864,\n "seagreen": 3050327,\n "seashell": 16774638,\n "sienna": 10506797,\n "silver": 12632256,\n "skyblue": 8900331,\n "slateblue": 6970061,\n "slategray": 7372944,\n "slategrey": 7372944,\n "snow": 16775930,\n "springgreen": 65407,\n "steelblue": 4620980,\n "tan": 13808780,\n "teal": 32896,\n "thistle": 14204888,\n "tomato": 16737095,\n "turquoise": 4251856,\n "violet": 15631086,\n "wheat": 16113331,\n "white": 16777215,\n "whitesmoke": 16119285,\n "yellow": 16776960,\n "yellowgreen": 10145074\n };\n const _hslA = { h: 0, s: 0, l: 0 };\n const _hslB = { h: 0, s: 0, l: 0 };\n function hue2rgb(p, q, t) {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * 6 * (2 / 3 - t);\n return p;\n }\n class Color {\n /**\n * Constructs a new color.\n *\n * Note that standard method of specifying color in three.js is with a hexadecimal triplet,\n * and that method is used throughout the rest of the documentation.\n *\n * @param {(number|string|Color)} [r] - The red component of the color. If `g` and `b` are\n * not provided, it can be hexadecimal triplet, a CSS-style string or another `Color` instance.\n * @param {number} [g] - The green component.\n * @param {number} [b] - The blue component.\n */\n constructor(r, g, b) {\n this.isColor = true;\n this.r = 1;\n this.g = 1;\n this.b = 1;\n return this.set(r, g, b);\n }\n /**\n * Sets the colors\'s components from the given values.\n *\n * @param {(number|string|Color)} [r] - The red component of the color. If `g` and `b` are\n * not provided, it can be hexadecimal triplet, a CSS-style string or another `Color` instance.\n * @param {number} [g] - The green component.\n * @param {number} [b] - The blue component.\n * @return {Color} A reference to this color.\n */\n set(r, g, b) {\n if (g === void 0 && b === void 0) {\n const value = r;\n if (value && value.isColor) {\n this.copy(value);\n } else if (typeof value === "number") {\n this.setHex(value);\n } else if (typeof value === "string") {\n this.setStyle(value);\n }\n } else {\n this.setRGB(r, g, b);\n }\n return this;\n }\n /**\n * Sets the colors\'s components to the given scalar value.\n *\n * @param {number} scalar - The scalar value.\n * @return {Color} A reference to this color.\n */\n setScalar(scalar) {\n this.r = scalar;\n this.g = scalar;\n this.b = scalar;\n return this;\n }\n /**\n * Sets this color from a hexadecimal value.\n *\n * @param {number} hex - The hexadecimal value.\n * @param {string} [colorSpace=SRGBColorSpace] - The color space.\n * @return {Color} A reference to this color.\n */\n setHex(hex, colorSpace = SRGBColorSpace) {\n hex = Math.floor(hex);\n this.r = (hex >> 16 & 255) / 255;\n this.g = (hex >> 8 & 255) / 255;\n this.b = (hex & 255) / 255;\n ColorManagement.colorSpaceToWorking(this, colorSpace);\n return this;\n }\n /**\n * Sets this color from RGB values.\n *\n * @param {number} r - Red channel value between `0.0` and `1.0`.\n * @param {number} g - Green channel value between `0.0` and `1.0`.\n * @param {number} b - Blue channel value between `0.0` and `1.0`.\n * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space.\n * @return {Color} A reference to this color.\n */\n setRGB(r, g, b, colorSpace = ColorManagement.workingColorSpace) {\n this.r = r;\n this.g = g;\n this.b = b;\n ColorManagement.colorSpaceToWorking(this, colorSpace);\n return this;\n }\n /**\n * Sets this color from RGB values.\n *\n * @param {number} h - Hue value between `0.0` and `1.0`.\n * @param {number} s - Saturation value between `0.0` and `1.0`.\n * @param {number} l - Lightness value between `0.0` and `1.0`.\n * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space.\n * @return {Color} A reference to this color.\n */\n setHSL(h, s, l, colorSpace = ColorManagement.workingColorSpace) {\n h = euclideanModulo(h, 1);\n s = clamp(s, 0, 1);\n l = clamp(l, 0, 1);\n if (s === 0) {\n this.r = this.g = this.b = l;\n } else {\n const p = l <= 0.5 ? l * (1 + s) : l + s - l * s;\n const q = 2 * l - p;\n this.r = hue2rgb(q, p, h + 1 / 3);\n this.g = hue2rgb(q, p, h);\n this.b = hue2rgb(q, p, h - 1 / 3);\n }\n ColorManagement.colorSpaceToWorking(this, colorSpace);\n return this;\n }\n /**\n * Sets this color from a CSS-style string. For example, `rgb(250, 0,0)`,\n * `rgb(100%, 0%, 0%)`, `hsl(0, 100%, 50%)`, `#ff0000`, `#f00`, or `red` ( or\n * any [X11 color name]{@link https://en.wikipedia.org/wiki/X11_color_names#Color_name_chart} -\n * all 140 color names are supported).\n *\n * @param {string} style - Color as a CSS-style string.\n * @param {string} [colorSpace=SRGBColorSpace] - The color space.\n * @return {Color} A reference to this color.\n */\n setStyle(style, colorSpace = SRGBColorSpace) {\n function handleAlpha(string) {\n if (string === void 0) return;\n if (parseFloat(string) < 1) {\n console.warn("THREE.Color: Alpha component of " + style + " will be ignored.");\n }\n }\n let m;\n if (m = /^(\\w+)\\(([^\\)]*)\\)/.exec(style)) {\n let color;\n const name = m[1];\n const components = m[2];\n switch (name) {\n case "rgb":\n case "rgba":\n if (color = /^\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(?:,\\s*(\\d*\\.?\\d+)\\s*)?$/.exec(components)) {\n handleAlpha(color[4]);\n return this.setRGB(\n Math.min(255, parseInt(color[1], 10)) / 255,\n Math.min(255, parseInt(color[2], 10)) / 255,\n Math.min(255, parseInt(color[3], 10)) / 255,\n colorSpace\n );\n }\n if (color = /^\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(?:,\\s*(\\d*\\.?\\d+)\\s*)?$/.exec(components)) {\n handleAlpha(color[4]);\n return this.setRGB(\n Math.min(100, parseInt(color[1], 10)) / 100,\n Math.min(100, parseInt(color[2], 10)) / 100,\n Math.min(100, parseInt(color[3], 10)) / 100,\n colorSpace\n );\n }\n break;\n case "hsl":\n case "hsla":\n if (color = /^\\s*(\\d*\\.?\\d+)\\s*,\\s*(\\d*\\.?\\d+)\\%\\s*,\\s*(\\d*\\.?\\d+)\\%\\s*(?:,\\s*(\\d*\\.?\\d+)\\s*)?$/.exec(components)) {\n handleAlpha(color[4]);\n return this.setHSL(\n parseFloat(color[1]) / 360,\n parseFloat(color[2]) / 100,\n parseFloat(color[3]) / 100,\n colorSpace\n );\n }\n break;\n default:\n console.warn("THREE.Color: Unknown color model " + style);\n }\n } else if (m = /^\\#([A-Fa-f\\d]+)$/.exec(style)) {\n const hex = m[1];\n const size = hex.length;\n if (size === 3) {\n return this.setRGB(\n parseInt(hex.charAt(0), 16) / 15,\n parseInt(hex.charAt(1), 16) / 15,\n parseInt(hex.charAt(2), 16) / 15,\n colorSpace\n );\n } else if (size === 6) {\n return this.setHex(parseInt(hex, 16), colorSpace);\n } else {\n console.warn("THREE.Color: Invalid hex color " + style);\n }\n } else if (style && style.length > 0) {\n return this.setColorName(style, colorSpace);\n }\n return this;\n }\n /**\n * Sets this color from a color name. Faster than {@link Color#setStyle} if\n * you don\'t need the other CSS-style formats.\n *\n * For convenience, the list of names is exposed in `Color.NAMES` as a hash.\n * ```js\n * Color.NAMES.aliceblue // returns 0xF0F8FF\n * ```\n *\n * @param {string} style - The color name.\n * @param {string} [colorSpace=SRGBColorSpace] - The color space.\n * @return {Color} A reference to this color.\n */\n setColorName(style, colorSpace = SRGBColorSpace) {\n const hex = _colorKeywords[style.toLowerCase()];\n if (hex !== void 0) {\n this.setHex(hex, colorSpace);\n } else {\n console.warn("THREE.Color: Unknown color " + style);\n }\n return this;\n }\n /**\n * Returns a new color with copied values from this instance.\n *\n * @return {Color} A clone of this instance.\n */\n clone() {\n return new this.constructor(this.r, this.g, this.b);\n }\n /**\n * Copies the values of the given color to this instance.\n *\n * @param {Color} color - The color to copy.\n * @return {Color} A reference to this color.\n */\n copy(color) {\n this.r = color.r;\n this.g = color.g;\n this.b = color.b;\n return this;\n }\n /**\n * Copies the given color into this color, and then converts this color from\n * `SRGBColorSpace` to `LinearSRGBColorSpace`.\n *\n * @param {Color} color - The color to copy/convert.\n * @return {Color} A reference to this color.\n */\n copySRGBToLinear(color) {\n this.r = SRGBToLinear(color.r);\n this.g = SRGBToLinear(color.g);\n this.b = SRGBToLinear(color.b);\n return this;\n }\n /**\n * Copies the given color into this color, and then converts this color from\n * `LinearSRGBColorSpace` to `SRGBColorSpace`.\n *\n * @param {Color} color - The color to copy/convert.\n * @return {Color} A reference to this color.\n */\n copyLinearToSRGB(color) {\n this.r = LinearToSRGB(color.r);\n this.g = LinearToSRGB(color.g);\n this.b = LinearToSRGB(color.b);\n return this;\n }\n /**\n * Converts this color from `SRGBColorSpace` to `LinearSRGBColorSpace`.\n *\n * @return {Color} A reference to this color.\n */\n convertSRGBToLinear() {\n this.copySRGBToLinear(this);\n return this;\n }\n /**\n * Converts this color from `LinearSRGBColorSpace` to `SRGBColorSpace`.\n *\n * @return {Color} A reference to this color.\n */\n convertLinearToSRGB() {\n this.copyLinearToSRGB(this);\n return this;\n }\n /**\n * Returns the hexadecimal value of this color.\n *\n * @param {string} [colorSpace=SRGBColorSpace] - The color space.\n * @return {number} The hexadecimal value.\n */\n getHex(colorSpace = SRGBColorSpace) {\n ColorManagement.workingToColorSpace(_color.copy(this), colorSpace);\n return Math.round(clamp(_color.r * 255, 0, 255)) * 65536 + Math.round(clamp(_color.g * 255, 0, 255)) * 256 + Math.round(clamp(_color.b * 255, 0, 255));\n }\n /**\n * Returns the hexadecimal value of this color as a string (for example, \'FFFFFF\').\n *\n * @param {string} [colorSpace=SRGBColorSpace] - The color space.\n * @return {string} The hexadecimal value as a string.\n */\n getHexString(colorSpace = SRGBColorSpace) {\n return ("000000" + this.getHex(colorSpace).toString(16)).slice(-6);\n }\n /**\n * Converts the colors RGB values into the HSL format and stores them into the\n * given target object.\n *\n * @param {{h:number,s:number,l:number}} target - The target object that is used to store the method\'s result.\n * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space.\n * @return {{h:number,s:number,l:number}} The HSL representation of this color.\n */\n getHSL(target, colorSpace = ColorManagement.workingColorSpace) {\n ColorManagement.workingToColorSpace(_color.copy(this), colorSpace);\n const r = _color.r, g = _color.g, b = _color.b;\n const max2 = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n let hue, saturation;\n const lightness = (min + max2) / 2;\n if (min === max2) {\n hue = 0;\n saturation = 0;\n } else {\n const delta = max2 - min;\n saturation = lightness <= 0.5 ? delta / (max2 + min) : delta / (2 - max2 - min);\n switch (max2) {\n case r:\n hue = (g - b) / delta + (g < b ? 6 : 0);\n break;\n case g:\n hue = (b - r) / delta + 2;\n break;\n case b:\n hue = (r - g) / delta + 4;\n break;\n }\n hue /= 6;\n }\n target.h = hue;\n target.s = saturation;\n target.l = lightness;\n return target;\n }\n /**\n * Returns the RGB values of this color and stores them into the given target object.\n *\n * @param {Color} target - The target color that is used to store the method\'s result.\n * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space.\n * @return {Color} The RGB representation of this color.\n */\n getRGB(target, colorSpace = ColorManagement.workingColorSpace) {\n ColorManagement.workingToColorSpace(_color.copy(this), colorSpace);\n target.r = _color.r;\n target.g = _color.g;\n target.b = _color.b;\n return target;\n }\n /**\n * Returns the value of this color as a CSS style string. Example: `rgb(255,0,0)`.\n *\n * @param {string} [colorSpace=SRGBColorSpace] - The color space.\n * @return {string} The CSS representation of this color.\n */\n getStyle(colorSpace = SRGBColorSpace) {\n ColorManagement.workingToColorSpace(_color.copy(this), colorSpace);\n const r = _color.r, g = _color.g, b = _color.b;\n if (colorSpace !== SRGBColorSpace) {\n return `color(${colorSpace} ${r.toFixed(3)} ${g.toFixed(3)} ${b.toFixed(3)})`;\n }\n return `rgb(${Math.round(r * 255)},${Math.round(g * 255)},${Math.round(b * 255)})`;\n }\n /**\n * Adds the given HSL values to this color\'s values.\n * Internally, this converts the color\'s RGB values to HSL, adds HSL\n * and then converts the color back to RGB.\n *\n * @param {number} h - Hue value between `0.0` and `1.0`.\n * @param {number} s - Saturation value between `0.0` and `1.0`.\n * @param {number} l - Lightness value between `0.0` and `1.0`.\n * @return {Color} A reference to this color.\n */\n offsetHSL(h, s, l) {\n this.getHSL(_hslA);\n return this.setHSL(_hslA.h + h, _hslA.s + s, _hslA.l + l);\n }\n /**\n * Adds the RGB values of the given color to the RGB values of this color.\n *\n * @param {Color} color - The color to add.\n * @return {Color} A reference to this color.\n */\n add(color) {\n this.r += color.r;\n this.g += color.g;\n this.b += color.b;\n return this;\n }\n /**\n * Adds the RGB values of the given colors and stores the result in this instance.\n *\n * @param {Color} color1 - The first color.\n * @param {Color} color2 - The second color.\n * @return {Color} A reference to this color.\n */\n addColors(color1, color2) {\n this.r = color1.r + color2.r;\n this.g = color1.g + color2.g;\n this.b = color1.b + color2.b;\n return this;\n }\n /**\n * Adds the given scalar value to the RGB values of this color.\n *\n * @param {number} s - The scalar to add.\n * @return {Color} A reference to this color.\n */\n addScalar(s) {\n this.r += s;\n this.g += s;\n this.b += s;\n return this;\n }\n /**\n * Subtracts the RGB values of the given color from the RGB values of this color.\n *\n * @param {Color} color - The color to subtract.\n * @return {Color} A reference to this color.\n */\n sub(color) {\n this.r = Math.max(0, this.r - color.r);\n this.g = Math.max(0, this.g - color.g);\n this.b = Math.max(0, this.b - color.b);\n return this;\n }\n /**\n * Multiplies the RGB values of the given color with the RGB values of this color.\n *\n * @param {Color} color - The color to multiply.\n * @return {Color} A reference to this color.\n */\n multiply(color) {\n this.r *= color.r;\n this.g *= color.g;\n this.b *= color.b;\n return this;\n }\n /**\n * Multiplies the given scalar value with the RGB values of this color.\n *\n * @param {number} s - The scalar to multiply.\n * @return {Color} A reference to this color.\n */\n multiplyScalar(s) {\n this.r *= s;\n this.g *= s;\n this.b *= s;\n return this;\n }\n /**\n * Linearly interpolates this color\'s RGB values toward the RGB values of the\n * given color. The alpha argument can be thought of as the ratio between\n * the two colors, where `0.0` is this color and `1.0` is the first argument.\n *\n * @param {Color} color - The color to converge on.\n * @param {number} alpha - The interpolation factor in the closed interval `[0,1]`.\n * @return {Color} A reference to this color.\n */\n lerp(color, alpha) {\n this.r += (color.r - this.r) * alpha;\n this.g += (color.g - this.g) * alpha;\n this.b += (color.b - this.b) * alpha;\n return this;\n }\n /**\n * Linearly interpolates between the given colors and stores the result in this instance.\n * The alpha argument can be thought of as the ratio between the two colors, where `0.0`\n * is the first and `1.0` is the second color.\n *\n * @param {Color} color1 - The first color.\n * @param {Color} color2 - The second color.\n * @param {number} alpha - The interpolation factor in the closed interval `[0,1]`.\n * @return {Color} A reference to this color.\n */\n lerpColors(color1, color2, alpha) {\n this.r = color1.r + (color2.r - color1.r) * alpha;\n this.g = color1.g + (color2.g - color1.g) * alpha;\n this.b = color1.b + (color2.b - color1.b) * alpha;\n return this;\n }\n /**\n * Linearly interpolates this color\'s HSL values toward the HSL values of the\n * given color. It differs from {@link Color#lerp} by not interpolating straight\n * from one color to the other, but instead going through all the hues in between\n * those two colors. The alpha argument can be thought of as the ratio between\n * the two colors, where 0.0 is this color and 1.0 is the first argument.\n *\n * @param {Color} color - The color to converge on.\n * @param {number} alpha - The interpolation factor in the closed interval `[0,1]`.\n * @return {Color} A reference to this color.\n */\n lerpHSL(color, alpha) {\n this.getHSL(_hslA);\n color.getHSL(_hslB);\n const h = lerp(_hslA.h, _hslB.h, alpha);\n const s = lerp(_hslA.s, _hslB.s, alpha);\n const l = lerp(_hslA.l, _hslB.l, alpha);\n this.setHSL(h, s, l);\n return this;\n }\n /**\n * Sets the color\'s RGB components from the given 3D vector.\n *\n * @param {Vector3} v - The vector to set.\n * @return {Color} A reference to this color.\n */\n setFromVector3(v) {\n this.r = v.x;\n this.g = v.y;\n this.b = v.z;\n return this;\n }\n /**\n * Transforms this color with the given 3x3 matrix.\n *\n * @param {Matrix3} m - The matrix.\n * @return {Color} A reference to this color.\n */\n applyMatrix3(m) {\n const r = this.r, g = this.g, b = this.b;\n const e = m.elements;\n this.r = e[0] * r + e[3] * g + e[6] * b;\n this.g = e[1] * r + e[4] * g + e[7] * b;\n this.b = e[2] * r + e[5] * g + e[8] * b;\n return this;\n }\n /**\n * Returns `true` if this color is equal with the given one.\n *\n * @param {Color} c - The color to test for equality.\n * @return {boolean} Whether this bounding color is equal with the given one.\n */\n equals(c) {\n return c.r === this.r && c.g === this.g && c.b === this.b;\n }\n /**\n * Sets this color\'s RGB components from the given array.\n *\n * @param {Array<number>} array - An array holding the RGB values.\n * @param {number} [offset=0] - The offset into the array.\n * @return {Color} A reference to this color.\n */\n fromArray(array, offset = 0) {\n this.r = array[offset];\n this.g = array[offset + 1];\n this.b = array[offset + 2];\n return this;\n }\n /**\n * Writes the RGB components of this color to the given array. If no array is provided,\n * the method returns a new instance.\n *\n * @param {Array<number>} [array=[]] - The target array holding the color components.\n * @param {number} [offset=0] - Index of the first element in the array.\n * @return {Array<number>} The color components.\n */\n toArray(array = [], offset = 0) {\n array[offset] = this.r;\n array[offset + 1] = this.g;\n array[offset + 2] = this.b;\n return array;\n }\n /**\n * Sets the components of this color from the given buffer attribute.\n *\n * @param {BufferAttribute} attribute - The buffer attribute holding color data.\n * @param {number} index - The index into the attribute.\n * @return {Color} A reference to this color.\n */\n fromBufferAttribute(attribute, index) {\n this.r = attribute.getX(index);\n this.g = attribute.getY(index);\n this.b = attribute.getZ(index);\n return this;\n }\n /**\n * This methods defines the serialization result of this class. Returns the color\n * as a hexadecimal value.\n *\n * @return {number} The hexadecimal value.\n */\n toJSON() {\n return this.getHex();\n }\n *[Symbol.iterator]() {\n yield this.r;\n yield this.g;\n yield this.b;\n }\n }\n const _color = /* @__PURE__ */ new Color();\n Color.NAMES = _colorKeywords;\n if (typeof __THREE_DEVTOOLS__ !== "undefined") {\n __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("register", { detail: {\n revision: REVISION\n } }));\n }\n if (typeof window !== "undefined") {\n if (window.__THREE__) {\n console.warn("WARNING: Multiple instances of Three.js being imported.");\n } else {\n window.__THREE__ = REVISION;\n }\n }\n const LN_SCALE_MIN = -12;\n const LN_SCALE_MAX = 9;\n const LN_SCALE_ZERO = -30;\n const SCALE_ZERO = Math.exp(LN_SCALE_ZERO);\n const SPLAT_TEX_WIDTH_BITS = 11;\n const SPLAT_TEX_HEIGHT_BITS = 11;\n const SPLAT_TEX_WIDTH = 1 << SPLAT_TEX_WIDTH_BITS;\n const SPLAT_TEX_HEIGHT = 1 << SPLAT_TEX_HEIGHT_BITS;\n const SPLAT_TEX_MIN_HEIGHT = 1;\n function unindentLines(s) {\n var _a2;\n let seenNonEmpty = false;\n const lines = s.split("\\n").map((line) => {\n const trimmedLine = line.trimEnd();\n if (seenNonEmpty) {\n return trimmedLine;\n }\n if (trimmedLine.length > 0) {\n seenNonEmpty = true;\n return trimmedLine;\n }\n return null;\n }).filter((line) => line != null);\n while (lines.length > 0 && lines[lines.length - 1].length === 0) {\n lines.pop();\n }\n if (lines.length === 0) {\n return [];\n }\n const indent = (_a2 = lines[0].match(/^\\s*/)) == null ? void 0 : _a2[0];\n if (!indent) {\n return lines;\n }\n const regex = new RegExp(`^${indent}`);\n return lines.map((line) => line.replace(regex, ""));\n }\n function unindent(s) {\n return unindentLines(s).join("\\n");\n }\n const f32buffer = new Float32Array(1);\n const u32buffer = new Uint32Array(f32buffer.buffer);\n const supportsFloat16Array = "Float16Array" in globalThis;\n const f16buffer = supportsFloat16Array ? new globalThis["Float16Array"](1) : null;\n const u16buffer = new Uint16Array(f16buffer == null ? void 0 : f16buffer.buffer);\n function normalize(vec) {\n const norm = Math.sqrt(vec.reduce((acc, v) => acc + v * v, 0));\n return vec.map((v) => v / norm);\n }\n const toHalf = supportsFloat16Array ? toHalfNative : toHalfJS;\n const fromHalf = supportsFloat16Array ? fromHalfNative : fromHalfJS;\n function toHalfNative(f) {\n f16buffer[0] = f;\n return u16buffer[0];\n }\n function toHalfJS(f) {\n f32buffer[0] = f;\n const bits2 = u32buffer[0];\n const sign = bits2 >> 31 & 1;\n const exp = bits2 >> 23 & 255;\n const frac = bits2 & 8388607;\n const halfSign = sign << 15;\n if (exp === 255) {\n if (frac !== 0) {\n return halfSign | 32767;\n }\n return halfSign | 31744;\n }\n const newExp = exp - 127 + 15;\n if (newExp >= 31) {\n return halfSign | 31744;\n }\n if (newExp <= 0) {\n if (newExp < -10) {\n return halfSign;\n }\n const subFrac = (frac | 8388608) >> 1 - newExp + 13;\n return halfSign | subFrac;\n }\n const halfFrac = frac >> 13;\n return halfSign | newExp << 10 | halfFrac;\n }\n function fromHalfNative(u) {\n u16buffer[0] = u;\n return f16buffer[0];\n }\n function fromHalfJS(h) {\n const sign = h >> 15 & 1;\n const exp = h >> 10 & 31;\n const frac = h & 1023;\n let f32bits;\n if (exp === 0) {\n if (frac === 0) {\n f32bits = sign << 31;\n } else {\n let mant = frac;\n let e = -14;\n while ((mant & 1024) === 0) {\n mant <<= 1;\n e--;\n }\n mant &= 1023;\n const newExp = e + 127;\n const newFrac = mant << 13;\n f32bits = sign << 31 | newExp << 23 | newFrac;\n }\n } else if (exp === 31) {\n if (frac === 0) {\n f32bits = sign << 31 | 2139095040;\n } else {\n f32bits = sign << 31 | 2143289344;\n }\n } else {\n const newExp = exp - 15 + 127;\n const newFrac = frac << 13;\n f32bits = sign << 31 | newExp << 23 | newFrac;\n }\n u32buffer[0] = f32bits;\n return f32buffer[0];\n }\n function floatToUint8(v) {\n return Math.max(0, Math.min(255, Math.round(v * 255)));\n }\n function getArrayBuffers(ctx) {\n const buffers = [];\n const seen = /* @__PURE__ */ new Set();\n function traverse(obj) {\n if (obj && typeof obj === "object" && !seen.has(obj)) {\n seen.add(obj);\n if (obj instanceof ArrayBuffer) {\n buffers.push(obj);\n } else if (ArrayBuffer.isView(obj)) {\n buffers.push(obj.buffer);\n } else if (Array.isArray(obj)) {\n obj.forEach(traverse);\n } else {\n Object.values(obj).forEach(traverse);\n }\n }\n }\n traverse(ctx);\n return buffers;\n }\n function setPackedSplat(packedSplats, index, x2, y, z, scaleX, scaleY, scaleZ, quatX, quatY, quatZ, quatW, opacity, r, g, b, encoding) {\n const rgbMin = (encoding == null ? void 0 : encoding.rgbMin) ?? 0;\n const rgbMax = (encoding == null ? void 0 : encoding.rgbMax) ?? 1;\n const rgbRange = rgbMax - rgbMin;\n const uR = floatToUint8((r - rgbMin) / rgbRange);\n const uG = floatToUint8((g - rgbMin) / rgbRange);\n const uB = floatToUint8((b - rgbMin) / rgbRange);\n const uA = floatToUint8(opacity);\n const uQuat = encodeQuatOctXy88R8(\n tempQuaternion.set(quatX, quatY, quatZ, quatW)\n );\n const uQuatX = uQuat & 255;\n const uQuatY = uQuat >>> 8 & 255;\n const uQuatZ = uQuat >>> 16 & 255;\n const lnScaleMin = (encoding == null ? void 0 : encoding.lnScaleMin) ?? LN_SCALE_MIN;\n const lnScaleMax = (encoding == null ? void 0 : encoding.lnScaleMax) ?? LN_SCALE_MAX;\n const lnScaleScale = 254 / (lnScaleMax - lnScaleMin);\n const uScaleX = scaleX < SCALE_ZERO ? 0 : Math.min(\n 255,\n Math.max(\n 1,\n Math.round((Math.log(scaleX) - lnScaleMin) * lnScaleScale) + 1\n )\n );\n const uScaleY = scaleY < SCALE_ZERO ? 0 : Math.min(\n 255,\n Math.max(\n 1,\n Math.round((Math.log(scaleY) - lnScaleMin) * lnScaleScale) + 1\n )\n );\n const uScaleZ = scaleZ < SCALE_ZERO ? 0 : Math.min(\n 255,\n Math.max(\n 1,\n Math.round((Math.log(scaleZ) - lnScaleMin) * lnScaleScale) + 1\n )\n );\n const uCenterX = toHalf(x2);\n const uCenterY = toHalf(y);\n const uCenterZ = toHalf(z);\n const i4 = index * 4;\n packedSplats[i4] = uR | uG << 8 | uB << 16 | uA << 24;\n packedSplats[i4 + 1] = uCenterX | uCenterY << 16;\n packedSplats[i4 + 2] = uCenterZ | uQuatX << 16 | uQuatY << 24;\n packedSplats[i4 + 3] = uScaleX | uScaleY << 8 | uScaleZ << 16 | uQuatZ << 24;\n }\n function setPackedSplatCenter(packedSplats, index, x2, y, z) {\n const uCenterX = toHalf(x2);\n const uCenterY = toHalf(y);\n const uCenterZ = toHalf(z);\n const i4 = index * 4;\n packedSplats[i4 + 1] = uCenterX | uCenterY << 16;\n packedSplats[i4 + 2] = uCenterZ | packedSplats[i4 + 2] & 4294901760;\n }\n function setPackedSplatScales(packedSplats, index, scaleX, scaleY, scaleZ, encoding) {\n const lnScaleMin = (encoding == null ? void 0 : encoding.lnScaleMin) ?? LN_SCALE_MIN;\n const lnScaleMax = (encoding == null ? void 0 : encoding.lnScaleMax) ?? LN_SCALE_MAX;\n const lnScaleScale = 254 / (lnScaleMax - lnScaleMin);\n const uScaleX = scaleX < SCALE_ZERO ? 0 : Math.min(\n 255,\n Math.max(\n 1,\n Math.round((Math.log(scaleX) - lnScaleMin) * lnScaleScale) + 1\n )\n );\n const uScaleY = scaleY < SCALE_ZERO ? 0 : Math.min(\n 255,\n Math.max(\n 1,\n Math.round((Math.log(scaleY) - lnScaleMin) * lnScaleScale) + 1\n )\n );\n const uScaleZ = scaleZ < SCALE_ZERO ? 0 : Math.min(\n 255,\n Math.max(\n 1,\n Math.round((Math.log(scaleZ) - lnScaleMin) * lnScaleScale) + 1\n )\n );\n const i4 = index * 4;\n packedSplats[i4 + 3] = uScaleX | uScaleY << 8 | uScaleZ << 16 | packedSplats[i4 + 3] & 4278190080;\n }\n const tempQuaternion = new Quaternion();\n function setPackedSplatQuat(packedSplats, index, quatX, quatY, quatZ, quatW) {\n const uQuat = encodeQuatOctXy88R8(\n tempQuaternion.set(quatX, quatY, quatZ, quatW)\n );\n const uQuatX = uQuat & 255;\n const uQuatY = uQuat >>> 8 & 255;\n const uQuatZ = uQuat >>> 16 & 255;\n const i4 = index * 4;\n packedSplats[i4 + 2] = packedSplats[i4 + 2] & 65535 | uQuatX << 16 | uQuatY << 24;\n packedSplats[i4 + 3] = packedSplats[i4 + 3] & 16777215 | uQuatZ << 24;\n }\n function setPackedSplatRgba(packedSplats, index, r, g, b, a, encoding) {\n const rgbMin = (encoding == null ? void 0 : encoding.rgbMin) ?? 0;\n const rgbMax = (encoding == null ? void 0 : encoding.rgbMax) ?? 1;\n const rgbRange = rgbMax - rgbMin;\n const uR = floatToUint8((r - rgbMin) / rgbRange);\n const uG = floatToUint8((g - rgbMin) / rgbRange);\n const uB = floatToUint8((b - rgbMin) / rgbRange);\n const uA = floatToUint8(a);\n const i4 = index * 4;\n packedSplats[i4] = uR | uG << 8 | uB << 16 | uA << 24;\n }\n function setPackedSplatRgb(packedSplats, index, r, g, b, encoding) {\n const rgbMin = (encoding == null ? void 0 : encoding.rgbMin) ?? 0;\n const rgbMax = (encoding == null ? void 0 : encoding.rgbMax) ?? 1;\n const rgbRange = rgbMax - rgbMin;\n const uR = floatToUint8((r - rgbMin) / rgbRange);\n const uG = floatToUint8((g - rgbMin) / rgbRange);\n const uB = floatToUint8((b - rgbMin) / rgbRange);\n const i4 = index * 4;\n packedSplats[i4] = uR | uG << 8 | uB << 16 | packedSplats[i4] & 4278190080;\n }\n function setPackedSplatOpacity(packedSplats, index, opacity) {\n const uA = floatToUint8(opacity);\n const i4 = index * 4;\n packedSplats[i4] = packedSplats[i4] & 16777215 | uA << 24;\n }\n new Vector3();\n new Vector3();\n new Color();\n function getTextureSize(numSplats) {\n const width = SPLAT_TEX_WIDTH;\n const height = Math.max(\n SPLAT_TEX_MIN_HEIGHT,\n Math.min(SPLAT_TEX_HEIGHT, Math.ceil(numSplats / width))\n );\n const depth = Math.ceil(numSplats / (width * height));\n const maxSplats = width * height * depth;\n return { width, height, depth, maxSplats };\n }\n function computeMaxSplats(numSplats) {\n const width = SPLAT_TEX_WIDTH;\n const height = Math.max(\n SPLAT_TEX_MIN_HEIGHT,\n Math.min(SPLAT_TEX_HEIGHT, Math.ceil(numSplats / width))\n );\n const depth = Math.ceil(numSplats / (width * height));\n return width * height * depth;\n }\n unindent(`\n precision highp float;\n\n in vec3 position;\n\n void main() {\n gl_Position = vec4(position.xy, 0.0, 1.0);\n }\n`);\n const tempNormalizedQuaternion = new Quaternion();\n const tempAxis = new Vector3();\n function encodeQuatOctXy88R8(q) {\n const qnorm = tempNormalizedQuaternion.copy(q).normalize();\n if (qnorm.w < 0) {\n qnorm.set(-qnorm.x, -qnorm.y, -qnorm.z, -qnorm.w);\n }\n const theta = 2 * Math.acos(qnorm.w);\n const xyz_norm = Math.sqrt(\n qnorm.x * qnorm.x + qnorm.y * qnorm.y + qnorm.z * qnorm.z\n );\n const axis = xyz_norm < 1e-6 ? tempAxis.set(1, 0, 0) : tempAxis.set(qnorm.x, qnorm.y, qnorm.z).divideScalar(xyz_norm);\n const sum = Math.abs(axis.x) + Math.abs(axis.y) + Math.abs(axis.z);\n let p_x = axis.x / sum;\n let p_y = axis.y / sum;\n if (axis.z < 0) {\n const tmp = p_x;\n p_x = (1 - Math.abs(p_y)) * (p_x >= 0 ? 1 : -1);\n p_y = (1 - Math.abs(tmp)) * (p_y >= 0 ? 1 : -1);\n }\n const u_f = p_x * 0.5 + 0.5;\n const v_f = p_y * 0.5 + 0.5;\n const quantU = Math.round(u_f * 255);\n const quantV = Math.round(v_f * 255);\n const angleInt = Math.round(theta * (255 / Math.PI));\n return angleInt << 16 | quantV << 8 | quantU;\n }\n function packSint8Bytes(b0, b1, b22, b3) {\n const clampedB0 = Math.max(-127, Math.min(127, b0 * 127));\n const clampedB1 = Math.max(-127, Math.min(127, b1 * 127));\n const clampedB2 = Math.max(-127, Math.min(127, b22 * 127));\n const clampedB3 = Math.max(-127, Math.min(127, b3 * 127));\n return clampedB0 & 255 | (clampedB1 & 255) << 8 | (clampedB2 & 255) << 16 | (clampedB3 & 255) << 24;\n }\n function encodeSh1Rgb(sh1Array, index, sh1Rgb, encoding) {\n const sh1Min = (encoding == null ? void 0 : encoding.sh1Min) ?? -1;\n const sh1Max = (encoding == null ? void 0 : encoding.sh1Max) ?? 1;\n const sh1Mid = 0.5 * (sh1Min + sh1Max);\n const sh1Scale = 126 / (sh1Max - sh1Min);\n const base = index * 2;\n for (let i2 = 0; i2 < 9; ++i2) {\n const s = (sh1Rgb[i2] - sh1Mid) * sh1Scale;\n const value = Math.round(Math.max(-63, Math.min(63, s))) & 127;\n const bitStart = i2 * 7;\n const bitEnd = bitStart + 7;\n const wordStart = Math.floor(bitStart / 32);\n const bitOffset = bitStart - wordStart * 32;\n const firstWord = value << bitOffset & 4294967295;\n sh1Array[base + wordStart] |= firstWord;\n if (bitEnd > wordStart * 32 + 32) {\n const secondWord = value >>> 32 - bitOffset & 4294967295;\n sh1Array[base + wordStart + 1] |= secondWord;\n }\n }\n }\n function encodeSh2Rgb(sh2Array, index, sh2Rgb, encoding) {\n const sh2Min = (encoding == null ? void 0 : encoding.sh2Min) ?? -1;\n const sh2Max = (encoding == null ? void 0 : encoding.sh2Max) ?? 1;\n const sh2Mid = 0.5 * (sh2Min + sh2Max);\n const sh2Scale = 2 / (sh2Max - sh2Min);\n sh2Array[index * 4 + 0] = packSint8Bytes(\n (sh2Rgb[0] - sh2Mid) * sh2Scale,\n (sh2Rgb[1] - sh2Mid) * sh2Scale,\n (sh2Rgb[2] - sh2Mid) * sh2Scale,\n (sh2Rgb[3] - sh2Mid) * sh2Scale\n );\n sh2Array[index * 4 + 1] = packSint8Bytes(\n (sh2Rgb[4] - sh2Mid) * sh2Scale,\n (sh2Rgb[5] - sh2Mid) * sh2Scale,\n (sh2Rgb[6] - sh2Mid) * sh2Scale,\n (sh2Rgb[7] - sh2Mid) * sh2Scale\n );\n sh2Array[index * 4 + 2] = packSint8Bytes(\n (sh2Rgb[8] - sh2Mid) * sh2Scale,\n (sh2Rgb[9] - sh2Mid) * sh2Scale,\n (sh2Rgb[10] - sh2Mid) * sh2Scale,\n (sh2Rgb[11] - sh2Mid) * sh2Scale\n );\n sh2Array[index * 4 + 3] = packSint8Bytes(\n (sh2Rgb[12] - sh2Mid) * sh2Scale,\n (sh2Rgb[13] - sh2Mid) * sh2Scale,\n (sh2Rgb[14] - sh2Mid) * sh2Scale,\n 0\n );\n }\n function encodeSh3Rgb(sh3Array, index, sh3Rgb, encoding) {\n const sh3Min = (encoding == null ? void 0 : encoding.sh3Min) ?? -1;\n const sh3Max = (encoding == null ? void 0 : encoding.sh3Max) ?? 1;\n const sh3Mid = 0.5 * (sh3Min + sh3Max);\n const sh3Scale = 62 / (sh3Max - sh3Min);\n const base = index * 4;\n for (let i2 = 0; i2 < 21; ++i2) {\n const s = (sh3Rgb[i2] - sh3Mid) * sh3Scale;\n const value = Math.round(Math.max(-31, Math.min(31, s))) & 63;\n const bitStart = i2 * 6;\n const bitEnd = bitStart + 6;\n const wordStart = Math.floor(bitStart / 32);\n const bitOffset = bitStart - wordStart * 32;\n const firstWord = value << bitOffset & 4294967295;\n sh3Array[base + wordStart] |= firstWord;\n if (bitEnd > wordStart * 32 + 32) {\n const secondWord = value >>> 32 - bitOffset & 4294967295;\n sh3Array[base + wordStart + 1] |= secondWord;\n }\n }\n }\n function decompressPartialGzip(fileBytes, numBytes) {\n const chunks = [];\n let totalBytes = 0;\n let result = null;\n const gunzip = new Gunzip((data, final) => {\n chunks.push(data);\n totalBytes += data.length;\n if (final || totalBytes >= numBytes) {\n const allBytes = new Uint8Array(totalBytes);\n let offset2 = 0;\n for (const chunk of chunks) {\n allBytes.set(chunk, offset2);\n offset2 += chunk.length;\n }\n result = allBytes.slice(0, numBytes);\n }\n });\n const CHUNK_SIZE = 1024;\n let offset = 0;\n while (result == null && offset < fileBytes.length) {\n const chunk = fileBytes.slice(offset, offset + CHUNK_SIZE);\n gunzip.push(chunk, false);\n offset += CHUNK_SIZE;\n }\n if (result == null) {\n gunzip.push(new Uint8Array(), true);\n if (result == null) {\n throw new Error("Failed to decompress partial gzip");\n }\n }\n return result;\n }\n class GunzipReader {\n constructor({\n fileBytes,\n chunkBytes = 64 * 1024\n }) {\n this.fileBytes = fileBytes;\n this.chunkBytes = chunkBytes;\n this.offset = 0;\n this.chunks = [];\n this.totalBytes = 0;\n this.gunzip = new Gunzip((chunk, _final) => {\n this.chunks.push(chunk);\n this.totalBytes += chunk.length;\n });\n }\n read(numBytes) {\n while (this.totalBytes < numBytes && this.offset < this.fileBytes.length) {\n const end = Math.min(\n this.offset + this.chunkBytes,\n this.fileBytes.length\n );\n this.gunzip.push(this.fileBytes.subarray(this.offset, end), false);\n this.offset = end;\n }\n if (this.totalBytes < numBytes && this.offset >= this.fileBytes.length) {\n this.gunzip.push(new Uint8Array(0), true);\n }\n if (this.totalBytes < numBytes) {\n throw new Error(\n `Unexpected EOF: needed ${numBytes}, got ${this.totalBytes}`\n );\n }\n const allBytes = new Uint8Array(this.totalBytes);\n let outOffset = 0;\n for (const chunk of this.chunks) {\n allBytes.set(chunk, outOffset);\n outOffset += chunk.length;\n }\n const result = allBytes.subarray(0, numBytes);\n this.chunks = [allBytes.subarray(numBytes)];\n this.totalBytes -= numBytes;\n return result;\n }\n }\n function decodeAntiSplat(fileBytes, initNumSplats, splatCallback) {\n const numSplats = Math.floor(fileBytes.length / 32);\n if (numSplats * 32 !== fileBytes.length) {\n throw new Error("Invalid .splat file size");\n }\n initNumSplats(numSplats);\n const f32 = new Float32Array(fileBytes.buffer);\n for (let i2 = 0; i2 < numSplats; ++i2) {\n const i322 = i2 * 32;\n const i8 = i2 * 8;\n const x2 = f32[i8 + 0];\n const y = f32[i8 + 1];\n const z = f32[i8 + 2];\n const scaleX = f32[i8 + 3];\n const scaleY = f32[i8 + 4];\n const scaleZ = f32[i8 + 5];\n const r = fileBytes[i322 + 24] / 255;\n const g = fileBytes[i322 + 25] / 255;\n const b = fileBytes[i322 + 26] / 255;\n const opacity = fileBytes[i322 + 27] / 255;\n const quatW = (fileBytes[i322 + 28] - 128) / 128;\n const quatX = (fileBytes[i322 + 29] - 128) / 128;\n const quatY = (fileBytes[i322 + 30] - 128) / 128;\n const quatZ = (fileBytes[i322 + 31] - 128) / 128;\n splatCallback(\n i2,\n x2,\n y,\n z,\n scaleX,\n scaleY,\n scaleZ,\n quatX,\n quatY,\n quatZ,\n quatW,\n opacity,\n r,\n g,\n b\n );\n }\n }\n function unpackAntiSplat(fileBytes, splatEncoding) {\n let numSplats = 0;\n let maxSplats = 0;\n let packedArray = new Uint32Array(0);\n decodeAntiSplat(\n fileBytes,\n (cbNumSplats) => {\n numSplats = cbNumSplats;\n maxSplats = computeMaxSplats(numSplats);\n packedArray = new Uint32Array(maxSplats * 4);\n },\n (index, x2, y, z, scaleX, scaleY, scaleZ, quatX, quatY, quatZ, quatW, opacity, r, g, b) => {\n setPackedSplat(\n packedArray,\n index,\n x2,\n y,\n z,\n scaleX,\n scaleY,\n scaleZ,\n quatX,\n quatY,\n quatZ,\n quatW,\n opacity,\n r,\n g,\n b,\n splatEncoding\n );\n }\n );\n return { packedArray, numSplats };\n }\n const KSPLAT_COMPRESSION = {\n 0: {\n bytesPerCenter: 12,\n bytesPerScale: 12,\n bytesPerRotation: 16,\n bytesPerColor: 4,\n bytesPerSphericalHarmonicsComponent: 4,\n scaleOffsetBytes: 12,\n rotationOffsetBytes: 24,\n colorOffsetBytes: 40,\n sphericalHarmonicsOffsetBytes: 44,\n scaleRange: 1\n },\n 1: {\n bytesPerCenter: 6,\n bytesPerScale: 6,\n bytesPerRotation: 8,\n bytesPerColor: 4,\n bytesPerSphericalHarmonicsComponent: 2,\n scaleOffsetBytes: 6,\n rotationOffsetBytes: 12,\n colorOffsetBytes: 20,\n sphericalHarmonicsOffsetBytes: 24,\n scaleRange: 32767\n },\n 2: {\n bytesPerCenter: 6,\n bytesPerScale: 6,\n bytesPerRotation: 8,\n bytesPerColor: 4,\n bytesPerSphericalHarmonicsComponent: 1,\n scaleOffsetBytes: 6,\n rotationOffsetBytes: 12,\n colorOffsetBytes: 20,\n sphericalHarmonicsOffsetBytes: 24,\n scaleRange: 32767\n }\n };\n const KSPLAT_SH_DEGREE_TO_COMPONENTS = {\n 0: 0,\n 1: 9,\n 2: 24,\n 3: 45\n };\n function decodeKsplat(fileBytes, initNumSplats, splatCallback, shCallback) {\n var _a2;\n const HEADER_BYTES = 4096;\n const SECTION_BYTES = 1024;\n let headerOffset = 0;\n const header = new DataView(fileBytes.buffer, headerOffset, HEADER_BYTES);\n headerOffset += HEADER_BYTES;\n const versionMajor = header.getUint8(0);\n const versionMinor = header.getUint8(1);\n if (versionMajor !== 0 || versionMinor < 1) {\n throw new Error(\n `Unsupported .ksplat version: ${versionMajor}.${versionMinor}`\n );\n }\n const maxSectionCount = header.getUint32(4, true);\n header.getUint32(16, true);\n const compressionLevel = header.getUint16(20, true);\n if (compressionLevel < 0 || compressionLevel > 2) {\n throw new Error(`Invalid .ksplat compression level: ${compressionLevel}`);\n }\n const minSphericalHarmonicsCoeff = header.getFloat32(36, true) || -1.5;\n const maxSphericalHarmonicsCoeff = header.getFloat32(40, true) || 1.5;\n let sectionBase = HEADER_BYTES + maxSectionCount * SECTION_BYTES;\n for (let section = 0; section < maxSectionCount; ++section) {\n let getSh = function(splatOffset, component) {\n if (compressionLevel === 0) {\n return data.getFloat32(\n splatOffset + sphericalHarmonicsOffsetBytes + component * 4,\n true\n );\n }\n if (compressionLevel === 1) {\n return fromHalf(\n data.getUint16(\n splatOffset + sphericalHarmonicsOffsetBytes + component * 2,\n true\n )\n );\n }\n const t = data.getUint8(splatOffset + sphericalHarmonicsOffsetBytes + component) / 255;\n return minSphericalHarmonicsCoeff + t * (maxSphericalHarmonicsCoeff - minSphericalHarmonicsCoeff);\n };\n const section2 = new DataView(fileBytes.buffer, headerOffset, SECTION_BYTES);\n headerOffset += SECTION_BYTES;\n const sectionSplatCount = section2.getUint32(0, true);\n const sectionMaxSplatCount = section2.getUint32(4, true);\n const bucketSize = section2.getUint32(8, true);\n const bucketCount = section2.getUint32(12, true);\n const bucketBlockSize = section2.getFloat32(16, true);\n const bucketStorageSizeBytes = section2.getUint16(20, true);\n const compressionScaleRange = (section2.getUint32(24, true) || ((_a2 = KSPLAT_COMPRESSION[compressionLevel]) == null ? void 0 : _a2.scaleRange)) ?? 1;\n const fullBucketCount = section2.getUint32(32, true);\n const fullBucketSplats = fullBucketCount * bucketSize;\n const partiallyFilledBucketCount = section2.getUint32(36, true);\n const bucketsMetaDataSizeBytes = partiallyFilledBucketCount * 4;\n const bucketsStorageSizeBytes = bucketStorageSizeBytes * bucketCount + bucketsMetaDataSizeBytes;\n const sphericalHarmonicsDegree = section2.getUint16(40, true);\n const shComponents = KSPLAT_SH_DEGREE_TO_COMPONENTS[sphericalHarmonicsDegree];\n const {\n bytesPerCenter,\n bytesPerScale,\n bytesPerRotation,\n bytesPerColor,\n bytesPerSphericalHarmonicsComponent,\n scaleOffsetBytes,\n rotationOffsetBytes,\n colorOffsetBytes,\n sphericalHarmonicsOffsetBytes\n } = KSPLAT_COMPRESSION[compressionLevel];\n const bytesPerSplat = bytesPerCenter + bytesPerScale + bytesPerRotation + bytesPerColor + shComponents * bytesPerSphericalHarmonicsComponent;\n const splatDataStorageSizeBytes = bytesPerSplat * sectionMaxSplatCount;\n const storageSizeBytes = splatDataStorageSizeBytes + bucketsStorageSizeBytes;\n const sh1Index = [0, 3, 6, 1, 4, 7, 2, 5, 8];\n const sh2Index = [\n 9,\n 14,\n 19,\n 10,\n 15,\n 20,\n 11,\n 16,\n 21,\n 12,\n 17,\n 22,\n 13,\n 18,\n 23\n ];\n const sh3Index = [\n 24,\n 31,\n 38,\n 25,\n 32,\n 39,\n 26,\n 33,\n 40,\n 27,\n 34,\n 41,\n 28,\n 35,\n 42,\n 29,\n 36,\n 43,\n 30,\n 37,\n 44\n ];\n const sh1 = sphericalHarmonicsDegree >= 1 ? new Float32Array(3 * 3) : void 0;\n const sh2 = sphericalHarmonicsDegree >= 2 ? new Float32Array(5 * 3) : void 0;\n const sh3 = sphericalHarmonicsDegree >= 3 ? new Float32Array(7 * 3) : void 0;\n const compressionScaleFactor = bucketBlockSize / 2 / compressionScaleRange;\n const bucketsBase = sectionBase + bucketsMetaDataSizeBytes;\n const dataBase = sectionBase + bucketsStorageSizeBytes;\n const data = new DataView(\n fileBytes.buffer,\n dataBase,\n splatDataStorageSizeBytes\n );\n const bucketArray = new Float32Array(\n fileBytes.buffer,\n bucketsBase,\n bucketCount * 3\n );\n const partiallyFilledBucketLengths = new Uint32Array(\n fileBytes.buffer,\n sectionBase,\n partiallyFilledBucketCount\n );\n let partialBucketIndex = fullBucketCount;\n let partialBucketBase = fullBucketSplats;\n for (let i2 = 0; i2 < sectionSplatCount; ++i2) {\n const splatOffset = i2 * bytesPerSplat;\n let bucketIndex;\n if (i2 < fullBucketSplats) {\n bucketIndex = Math.floor(i2 / bucketSize);\n } else {\n const bucketLength = partiallyFilledBucketLengths[partialBucketIndex - fullBucketCount];\n if (i2 >= partialBucketBase + bucketLength) {\n partialBucketIndex += 1;\n partialBucketBase += bucketLength;\n }\n bucketIndex = partialBucketIndex;\n }\n const x2 = compressionLevel === 0 ? data.getFloat32(splatOffset + 0, true) : (data.getUint16(splatOffset + 0, true) - compressionScaleRange) * compressionScaleFactor + bucketArray[3 * bucketIndex + 0];\n const y = compressionLevel === 0 ? data.getFloat32(splatOffset + 4, true) : (data.getUint16(splatOffset + 2, true) - compressionScaleRange) * compressionScaleFactor + bucketArray[3 * bucketIndex + 1];\n const z = compressionLevel === 0 ? data.getFloat32(splatOffset + 8, true) : (data.getUint16(splatOffset + 4, true) - compressionScaleRange) * compressionScaleFactor + bucketArray[3 * bucketIndex + 2];\n const scaleX = compressionLevel === 0 ? data.getFloat32(splatOffset + scaleOffsetBytes + 0, true) : fromHalf(data.getUint16(splatOffset + scaleOffsetBytes + 0, true));\n const scaleY = compressionLevel === 0 ? data.getFloat32(splatOffset + scaleOffsetBytes + 4, true) : fromHalf(data.getUint16(splatOffset + scaleOffsetBytes + 2, true));\n const scaleZ = compressionLevel === 0 ? data.getFloat32(splatOffset + scaleOffsetBytes + 8, true) : fromHalf(data.getUint16(splatOffset + scaleOffsetBytes + 4, true));\n const quatW = compressionLevel === 0 ? data.getFloat32(splatOffset + rotationOffsetBytes + 0, true) : fromHalf(\n data.getUint16(splatOffset + rotationOffsetBytes + 0, true)\n );\n const quatX = compressionLevel === 0 ? data.getFloat32(splatOffset + rotationOffsetBytes + 4, true) : fromHalf(\n data.getUint16(splatOffset + rotationOffsetBytes + 2, true)\n );\n const quatY = compressionLevel === 0 ? data.getFloat32(splatOffset + rotationOffsetBytes + 8, true) : fromHalf(\n data.getUint16(splatOffset + rotationOffsetBytes + 4, true)\n );\n const quatZ = compressionLevel === 0 ? data.getFloat32(splatOffset + rotationOffsetBytes + 12, true) : fromHalf(\n data.getUint16(splatOffset + rotationOffsetBytes + 6, true)\n );\n const r = data.getUint8(splatOffset + colorOffsetBytes + 0) / 255;\n const g = data.getUint8(splatOffset + colorOffsetBytes + 1) / 255;\n const b = data.getUint8(splatOffset + colorOffsetBytes + 2) / 255;\n const opacity = data.getUint8(splatOffset + colorOffsetBytes + 3) / 255;\n splatCallback(\n i2,\n x2,\n y,\n z,\n scaleX,\n scaleY,\n scaleZ,\n quatX,\n quatY,\n quatZ,\n quatW,\n opacity,\n r,\n g,\n b\n );\n if (sphericalHarmonicsDegree >= 1 && sh1) {\n for (const [i22, key] of sh1Index.entries()) {\n sh1[i22] = getSh(splatOffset, key);\n }\n if (sh2) {\n for (const [i22, key] of sh2Index.entries()) {\n sh2[i22] = getSh(splatOffset, key);\n }\n }\n if (sh3) {\n for (const [i22, key] of sh3Index.entries()) {\n sh3[i22] = getSh(splatOffset, key);\n }\n }\n shCallback == null ? void 0 : shCallback(i2, sh1, sh2, sh3);\n }\n }\n sectionBase += storageSizeBytes;\n }\n }\n function unpackKsplat(fileBytes, splatEncoding) {\n var _a2;\n const HEADER_BYTES = 4096;\n const SECTION_BYTES = 1024;\n let headerOffset = 0;\n const header = new DataView(fileBytes.buffer, headerOffset, HEADER_BYTES);\n headerOffset += HEADER_BYTES;\n const versionMajor = header.getUint8(0);\n const versionMinor = header.getUint8(1);\n if (versionMajor !== 0 || versionMinor < 1) {\n throw new Error(\n `Unsupported .ksplat version: ${versionMajor}.${versionMinor}`\n );\n }\n const maxSectionCount = header.getUint32(4, true);\n const splatCount = header.getUint32(16, true);\n const compressionLevel = header.getUint16(20, true);\n if (compressionLevel < 0 || compressionLevel > 2) {\n throw new Error(`Invalid .ksplat compression level: ${compressionLevel}`);\n }\n const minSphericalHarmonicsCoeff = header.getFloat32(36, true) || -1.5;\n const maxSphericalHarmonicsCoeff = header.getFloat32(40, true) || 1.5;\n const numSplats = splatCount;\n const maxSplats = computeMaxSplats(numSplats);\n const packedArray = new Uint32Array(maxSplats * 4);\n const extra = {};\n let sectionBase = HEADER_BYTES + maxSectionCount * SECTION_BYTES;\n for (let section = 0; section < maxSectionCount; ++section) {\n let getSh = function(splatOffset, component) {\n if (compressionLevel === 0) {\n return data.getFloat32(\n splatOffset + sphericalHarmonicsOffsetBytes + component * 4,\n true\n );\n }\n if (compressionLevel === 1) {\n return fromHalf(\n data.getUint16(\n splatOffset + sphericalHarmonicsOffsetBytes + component * 2,\n true\n )\n );\n }\n const t = data.getUint8(splatOffset + sphericalHarmonicsOffsetBytes + component) / 255;\n return minSphericalHarmonicsCoeff + t * (maxSphericalHarmonicsCoeff - minSphericalHarmonicsCoeff);\n };\n const section2 = new DataView(fileBytes.buffer, headerOffset, SECTION_BYTES);\n headerOffset += SECTION_BYTES;\n const sectionSplatCount = section2.getUint32(0, true);\n const sectionMaxSplatCount = section2.getUint32(4, true);\n const bucketSize = section2.getUint32(8, true);\n const bucketCount = section2.getUint32(12, true);\n const bucketBlockSize = section2.getFloat32(16, true);\n const bucketStorageSizeBytes = section2.getUint16(20, true);\n const compressionScaleRange = (section2.getUint32(24, true) || ((_a2 = KSPLAT_COMPRESSION[compressionLevel]) == null ? void 0 : _a2.scaleRange)) ?? 1;\n const fullBucketCount = section2.getUint32(32, true);\n const fullBucketSplats = fullBucketCount * bucketSize;\n const partiallyFilledBucketCount = section2.getUint32(36, true);\n const bucketsMetaDataSizeBytes = partiallyFilledBucketCount * 4;\n const bucketsStorageSizeBytes = bucketStorageSizeBytes * bucketCount + bucketsMetaDataSizeBytes;\n const sphericalHarmonicsDegree = section2.getUint16(40, true);\n const shComponents = KSPLAT_SH_DEGREE_TO_COMPONENTS[sphericalHarmonicsDegree];\n const {\n bytesPerCenter,\n bytesPerScale,\n bytesPerRotation,\n bytesPerColor,\n bytesPerSphericalHarmonicsComponent,\n scaleOffsetBytes,\n rotationOffsetBytes,\n colorOffsetBytes,\n sphericalHarmonicsOffsetBytes\n } = KSPLAT_COMPRESSION[compressionLevel];\n const bytesPerSplat = bytesPerCenter + bytesPerScale + bytesPerRotation + bytesPerColor + shComponents * bytesPerSphericalHarmonicsComponent;\n const splatDataStorageSizeBytes = bytesPerSplat * sectionMaxSplatCount;\n const storageSizeBytes = splatDataStorageSizeBytes + bucketsStorageSizeBytes;\n const sh1Index = [0, 3, 6, 1, 4, 7, 2, 5, 8];\n const sh2Index = [\n 9,\n 14,\n 19,\n 10,\n 15,\n 20,\n 11,\n 16,\n 21,\n 12,\n 17,\n 22,\n 13,\n 18,\n 23\n ];\n const sh3Index = [\n 24,\n 31,\n 38,\n 25,\n 32,\n 39,\n 26,\n 33,\n 40,\n 27,\n 34,\n 41,\n 28,\n 35,\n 42,\n 29,\n 36,\n 43,\n 30,\n 37,\n 44\n ];\n const sh1 = sphericalHarmonicsDegree >= 1 ? new Float32Array(3 * 3) : void 0;\n const sh2 = sphericalHarmonicsDegree >= 2 ? new Float32Array(5 * 3) : void 0;\n const sh3 = sphericalHarmonicsDegree >= 3 ? new Float32Array(7 * 3) : void 0;\n const compressionScaleFactor = bucketBlockSize / 2 / compressionScaleRange;\n const bucketsBase = sectionBase + bucketsMetaDataSizeBytes;\n const dataBase = sectionBase + bucketsStorageSizeBytes;\n const data = new DataView(\n fileBytes.buffer,\n dataBase,\n splatDataStorageSizeBytes\n );\n const bucketArray = new Float32Array(\n fileBytes.buffer,\n bucketsBase,\n bucketCount * 3\n );\n const partiallyFilledBucketLengths = new Uint32Array(\n fileBytes.buffer,\n sectionBase,\n partiallyFilledBucketCount\n );\n let partialBucketIndex = fullBucketCount;\n let partialBucketBase = fullBucketSplats;\n for (let i2 = 0; i2 < sectionSplatCount; ++i2) {\n const splatOffset = i2 * bytesPerSplat;\n let bucketIndex;\n if (i2 < fullBucketSplats) {\n bucketIndex = Math.floor(i2 / bucketSize);\n } else {\n const bucketLength = partiallyFilledBucketLengths[partialBucketIndex - fullBucketCount];\n if (i2 >= partialBucketBase + bucketLength) {\n partialBucketIndex += 1;\n partialBucketBase += bucketLength;\n }\n bucketIndex = partialBucketIndex;\n }\n const x2 = compressionLevel === 0 ? data.getFloat32(splatOffset + 0, true) : (data.getUint16(splatOffset + 0, true) - compressionScaleRange) * compressionScaleFactor + bucketArray[3 * bucketIndex + 0];\n const y = compressionLevel === 0 ? data.getFloat32(splatOffset + 4, true) : (data.getUint16(splatOffset + 2, true) - compressionScaleRange) * compressionScaleFactor + bucketArray[3 * bucketIndex + 1];\n const z = compressionLevel === 0 ? data.getFloat32(splatOffset + 8, true) : (data.getUint16(splatOffset + 4, true) - compressionScaleRange) * compressionScaleFactor + bucketArray[3 * bucketIndex + 2];\n const scaleX = compressionLevel === 0 ? data.getFloat32(splatOffset + scaleOffsetBytes + 0, true) : fromHalf(data.getUint16(splatOffset + scaleOffsetBytes + 0, true));\n const scaleY = compressionLevel === 0 ? data.getFloat32(splatOffset + scaleOffsetBytes + 4, true) : fromHalf(data.getUint16(splatOffset + scaleOffsetBytes + 2, true));\n const scaleZ = compressionLevel === 0 ? data.getFloat32(splatOffset + scaleOffsetBytes + 8, true) : fromHalf(data.getUint16(splatOffset + scaleOffsetBytes + 4, true));\n const quatW = compressionLevel === 0 ? data.getFloat32(splatOffset + rotationOffsetBytes + 0, true) : fromHalf(\n data.getUint16(splatOffset + rotationOffsetBytes + 0, true)\n );\n const quatX = compressionLevel === 0 ? data.getFloat32(splatOffset + rotationOffsetBytes + 4, true) : fromHalf(\n data.getUint16(splatOffset + rotationOffsetBytes + 2, true)\n );\n const quatY = compressionLevel === 0 ? data.getFloat32(splatOffset + rotationOffsetBytes + 8, true) : fromHalf(\n data.getUint16(splatOffset + rotationOffsetBytes + 4, true)\n );\n const quatZ = compressionLevel === 0 ? data.getFloat32(splatOffset + rotationOffsetBytes + 12, true) : fromHalf(\n data.getUint16(splatOffset + rotationOffsetBytes + 6, true)\n );\n const r = data.getUint8(splatOffset + colorOffsetBytes + 0) / 255;\n const g = data.getUint8(splatOffset + colorOffsetBytes + 1) / 255;\n const b = data.getUint8(splatOffset + colorOffsetBytes + 2) / 255;\n const opacity = data.getUint8(splatOffset + colorOffsetBytes + 3) / 255;\n setPackedSplat(\n packedArray,\n i2,\n x2,\n y,\n z,\n scaleX,\n scaleY,\n scaleZ,\n quatX,\n quatY,\n quatZ,\n quatW,\n opacity,\n r,\n g,\n b,\n splatEncoding\n );\n if (sphericalHarmonicsDegree >= 1) {\n if (sh1) {\n if (!extra.sh1) {\n extra.sh1 = new Uint32Array(numSplats * 2);\n }\n for (const [i22, key] of sh1Index.entries()) {\n sh1[i22] = getSh(splatOffset, key);\n }\n encodeSh1Rgb(extra.sh1, i2, sh1, splatEncoding);\n }\n if (sh2) {\n if (!extra.sh2) {\n extra.sh2 = new Uint32Array(numSplats * 4);\n }\n for (const [i22, key] of sh2Index.entries()) {\n sh2[i22] = getSh(splatOffset, key);\n }\n encodeSh2Rgb(extra.sh2, i2, sh2, splatEncoding);\n }\n if (sh3) {\n if (!extra.sh3) {\n extra.sh3 = new Uint32Array(numSplats * 4);\n }\n for (const [i22, key] of sh3Index.entries()) {\n sh3[i22] = getSh(splatOffset, key);\n }\n encodeSh3Rgb(extra.sh3, i2, sh3, splatEncoding);\n }\n }\n }\n sectionBase += storageSizeBytes;\n }\n return { packedArray, numSplats, extra };\n }\n const PLY_PROPERTY_TYPES = [\n "char",\n "uchar",\n "short",\n "ushort",\n "int",\n "uint",\n "float",\n "double"\n ];\n const _PlyReader = class _PlyReader {\n // Create a PlyReader from a Uint8Array/ArrayBuffer, no parsing done yet\n constructor({ fileBytes }) {\n this.header = "";\n this.littleEndian = true;\n this.elements = {};\n this.comments = [];\n this.data = null;\n this.numSplats = 0;\n this.fileBytes = fileBytes instanceof ArrayBuffer ? new Uint8Array(fileBytes) : fileBytes;\n }\n // Identify and parse the PLY text header (assumed to be <64KB in size).\n // this.elements will contain all the elements in the file, typically\n // "vertex" contains the Gsplat data.\n async parseHeader() {\n const bufferStream = new ReadableStream({\n start: (controller) => {\n controller.enqueue(this.fileBytes.slice(0, 65536));\n controller.close();\n }\n });\n const decoder = bufferStream.pipeThrough(new TextDecoderStream()).getReader();\n this.header = "";\n const headerTerminator = "end_header\\n";\n while (true) {\n const { value, done } = await decoder.read();\n if (done) {\n throw new Error("Failed to read header");\n }\n this.header += value;\n const endHeader = this.header.indexOf(headerTerminator);\n if (endHeader >= 0) {\n this.header = this.header.slice(0, endHeader + headerTerminator.length);\n break;\n }\n }\n const headerLen = new TextEncoder().encode(this.header).length;\n this.data = new DataView(this.fileBytes.buffer, headerLen);\n this.elements = {};\n let curElement = null;\n this.comments = [];\n this.header.trim().split("\\n").forEach((line, lineIndex) => {\n const trimmedLine = line.trim();\n if (lineIndex === 0) {\n if (trimmedLine !== "ply") {\n throw new Error("Invalid PLY header");\n }\n return;\n }\n if (trimmedLine.length === 0) {\n return;\n }\n const fields = trimmedLine.split(" ");\n switch (fields[0]) {\n case "format":\n if (fields[1] === "binary_little_endian") {\n this.littleEndian = true;\n } else if (fields[1] === "binary_big_endian") {\n this.littleEndian = false;\n } else {\n throw new Error(`Unsupported PLY format: ${fields[1]}`);\n }\n if (fields[2] !== "1.0") {\n throw new Error(`Unsupported PLY version: ${fields[2]}`);\n }\n break;\n case "end_header":\n break;\n case "comment":\n this.comments.push(trimmedLine.slice("comment ".length));\n break;\n case "element": {\n const name = fields[1];\n curElement = {\n name,\n count: Number.parseInt(fields[2]),\n properties: {}\n };\n this.elements[name] = curElement;\n break;\n }\n case "property":\n if (curElement == null) {\n throw new Error("Property must be inside an element");\n }\n if (fields[1] === "list") {\n curElement.properties[fields[4]] = {\n isList: true,\n type: fields[3],\n countType: fields[2]\n };\n } else {\n curElement.properties[fields[2]] = {\n isList: false,\n type: fields[1]\n };\n }\n break;\n }\n });\n if (this.elements.vertex) {\n this.numSplats = this.elements.vertex.count;\n }\n }\n parseData(elementCallback) {\n let offset = 0;\n const data = this.data;\n if (data == null) {\n throw new Error("No data to parse");\n }\n for (const elementName in this.elements) {\n const element = this.elements[elementName];\n const { count, properties } = element;\n const item = createEmptyItem(properties);\n const parseFn = createParseFn(properties, this.littleEndian);\n const callback = elementCallback(element) ?? (() => {\n });\n for (let index = 0; index < count; index++) {\n offset = parseFn(data, offset, item);\n callback(index, item);\n }\n }\n }\n // Parse all the Gsplat data in the PLY file in go, invoking the given\n // callbacks for each Gsplat.\n parseSplats(splatCallback, shCallback) {\n if (this.elements.vertex == null) {\n throw new Error("No vertex element found");\n }\n let isSuperSplat = false;\n const ssChunks = [];\n let numSh = 0;\n let sh1Props = [];\n let sh2Props = [];\n let sh3Props = [];\n let sh1 = void 0;\n let sh2 = void 0;\n let sh3 = void 0;\n function prepareSh() {\n const num_f_rest = NUM_SH_TO_NUM_F_REST[numSh];\n sh1Props = new Array(3).fill(null).flatMap((_, k) => [0, 1, 2].map((_2, d) => k + d * num_f_rest / 3));\n sh2Props = new Array(5).fill(null).flatMap(\n (_, k) => [0, 1, 2].map((_2, d) => 3 + k + d * num_f_rest / 3)\n );\n sh3Props = new Array(7).fill(null).flatMap(\n (_, k) => [0, 1, 2].map((_2, d) => 8 + k + d * num_f_rest / 3)\n );\n sh1 = numSh >= 1 ? new Float32Array(3 * 3) : void 0;\n sh2 = numSh >= 2 ? new Float32Array(5 * 3) : void 0;\n sh3 = numSh >= 3 ? new Float32Array(7 * 3) : void 0;\n }\n function ssShCallback(index, item) {\n if (!sh1) {\n throw new Error("Missing sh1");\n }\n const sh = item.f_rest;\n for (let i2 = 0; i2 < sh1Props.length; i2++) {\n sh1[i2] = sh[sh1Props[i2]] * 8 / 255 - 4;\n }\n if (sh2) {\n for (let i2 = 0; i2 < sh2Props.length; i2++) {\n sh2[i2] = sh[sh2Props[i2]] * 8 / 255 - 4;\n }\n }\n if (sh3) {\n for (let i2 = 0; i2 < sh3Props.length; i2++) {\n sh3[i2] = sh[sh3Props[i2]] * 8 / 255 - 4;\n }\n }\n shCallback == null ? void 0 : shCallback(index, sh1, sh2, sh3);\n }\n function initSuperSplat(element) {\n const {\n min_x,\n min_y,\n min_z,\n max_x,\n max_y,\n max_z,\n min_scale_x,\n min_scale_y,\n min_scale_z,\n max_scale_x,\n max_scale_y,\n max_scale_z\n } = element.properties;\n if (!min_x || !min_y || !min_z || !max_x || !max_y || !max_z || !min_scale_x || !min_scale_y || !min_scale_z || !max_scale_x || !max_scale_y || !max_scale_z) {\n throw new Error("Missing PLY chunk properties");\n }\n isSuperSplat = true;\n return (index, item) => {\n const {\n min_x: min_x2,\n min_y: min_y2,\n min_z: min_z2,\n max_x: max_x2,\n max_y: max_y2,\n max_z: max_z2,\n min_scale_x: min_scale_x2,\n min_scale_y: min_scale_y2,\n min_scale_z: min_scale_z2,\n max_scale_x: max_scale_x2,\n max_scale_y: max_scale_y2,\n max_scale_z: max_scale_z2,\n min_r,\n min_g,\n min_b,\n max_r,\n max_g,\n max_b\n } = item;\n ssChunks.push({\n min_x: min_x2,\n min_y: min_y2,\n min_z: min_z2,\n max_x: max_x2,\n max_y: max_y2,\n max_z: max_z2,\n min_scale_x: min_scale_x2,\n min_scale_y: min_scale_y2,\n min_scale_z: min_scale_z2,\n max_scale_x: max_scale_x2,\n max_scale_y: max_scale_y2,\n max_scale_z: max_scale_z2,\n min_r,\n min_g,\n min_b,\n max_r,\n max_g,\n max_b\n });\n };\n }\n function decodeSuperSplat(element) {\n if (shCallback && element.name === "sh") {\n numSh = getNumSh(element.properties);\n prepareSh();\n return ssShCallback;\n }\n if (element.name !== "vertex") {\n return null;\n }\n const { packed_position, packed_rotation, packed_scale, packed_color } = element.properties;\n if (!packed_position || !packed_rotation || !packed_scale || !packed_color) {\n throw new Error(\n "Missing PLY properties: packed_position, packed_rotation, packed_scale, packed_color"\n );\n }\n const SQRT2 = Math.sqrt(2);\n return (index, item) => {\n const chunk = ssChunks[index >>> 8];\n if (chunk == null) {\n throw new Error("Missing PLY chunk");\n }\n const {\n min_x,\n min_y,\n min_z,\n max_x,\n max_y,\n max_z,\n min_scale_x,\n min_scale_y,\n min_scale_z,\n max_scale_x,\n max_scale_y,\n max_scale_z,\n min_r,\n min_g,\n min_b,\n max_r,\n max_g,\n max_b\n } = chunk;\n const { packed_position: packed_position2, packed_rotation: packed_rotation2, packed_scale: packed_scale2, packed_color: packed_color2 } = item;\n const x2 = (packed_position2 >>> 21 & 2047) / 2047 * (max_x - min_x) + min_x;\n const y = (packed_position2 >>> 11 & 1023) / 1023 * (max_y - min_y) + min_y;\n const z = (packed_position2 & 2047) / 2047 * (max_z - min_z) + min_z;\n const r0 = ((packed_rotation2 >>> 20 & 1023) / 1023 - 0.5) * SQRT2;\n const r1 = ((packed_rotation2 >>> 10 & 1023) / 1023 - 0.5) * SQRT2;\n const r2 = ((packed_rotation2 & 1023) / 1023 - 0.5) * SQRT2;\n const rr = Math.sqrt(Math.max(0, 1 - r0 * r0 - r1 * r1 - r2 * r2));\n const rOrder = packed_rotation2 >>> 30;\n const quatX = rOrder === 0 ? r0 : rOrder === 1 ? rr : r1;\n const quatY = rOrder <= 1 ? r1 : rOrder === 2 ? rr : r2;\n const quatZ = rOrder <= 2 ? r2 : rr;\n const quatW = rOrder === 0 ? rr : r0;\n const scaleX = Math.exp(\n (packed_scale2 >>> 21 & 2047) / 2047 * (max_scale_x - min_scale_x) + min_scale_x\n );\n const scaleY = Math.exp(\n (packed_scale2 >>> 11 & 1023) / 1023 * (max_scale_y - min_scale_y) + min_scale_y\n );\n const scaleZ = Math.exp(\n (packed_scale2 & 2047) / 2047 * (max_scale_z - min_scale_z) + min_scale_z\n );\n const r = (packed_color2 >>> 24 & 255) / 255 * ((max_r ?? 1) - (min_r ?? 0)) + (min_r ?? 0);\n const g = (packed_color2 >>> 16 & 255) / 255 * ((max_g ?? 1) - (min_g ?? 0)) + (min_g ?? 0);\n const b = (packed_color2 >>> 8 & 255) / 255 * ((max_b ?? 1) - (min_b ?? 0)) + (min_b ?? 0);\n const opacity = (packed_color2 & 255) / 255;\n splatCallback(\n index,\n x2,\n y,\n z,\n scaleX,\n scaleY,\n scaleZ,\n quatX,\n quatY,\n quatZ,\n quatW,\n opacity,\n r,\n g,\n b\n );\n };\n }\n const elementCallback = (element) => {\n if (element.name === "chunk") {\n return initSuperSplat(element);\n }\n if (isSuperSplat) {\n return decodeSuperSplat(element);\n }\n if (element.name !== "vertex") {\n return null;\n }\n const {\n x: x2,\n y,\n z,\n scale_0,\n scale_1,\n scale_2,\n rot_0,\n rot_1,\n rot_2,\n rot_3,\n opacity,\n f_dc_0,\n f_dc_1,\n f_dc_2,\n red,\n green,\n blue,\n alpha\n } = element.properties;\n if (!x2 || !y || !z) {\n throw new Error("Missing PLY properties: x, y, z");\n }\n const hasScales = scale_0 && scale_1 && scale_2;\n const hasRots = rot_0 && rot_1 && rot_2 && rot_3;\n const alphaDiv = alpha != null ? FIELD_SCALE[alpha.type] : 1;\n const redDiv = red != null ? FIELD_SCALE[red.type] : 1;\n const greenDiv = green != null ? FIELD_SCALE[green.type] : 1;\n const blueDiv = blue != null ? FIELD_SCALE[blue.type] : 1;\n numSh = getNumSh(element.properties);\n prepareSh();\n return (index, item) => {\n const scaleX = hasScales ? Math.exp(item.scale_0) : _PlyReader.defaultPointScale;\n const scaleY = hasScales ? Math.exp(item.scale_1) : _PlyReader.defaultPointScale;\n const scaleZ = hasScales ? Math.exp(item.scale_2) : _PlyReader.defaultPointScale;\n const quatX = hasRots ? item.rot_1 : 0;\n const quatY = hasRots ? item.rot_2 : 0;\n const quatZ = hasRots ? item.rot_3 : 0;\n const quatW = hasRots ? item.rot_0 : 1;\n const op = opacity != null ? 1 / (1 + Math.exp(-item.opacity)) : alpha != null ? item.alpha / alphaDiv : 1;\n const r = f_dc_0 != null ? item.f_dc_0 * SH_C0$1 + 0.5 : red != null ? item.red / redDiv : 1;\n const g = f_dc_1 != null ? item.f_dc_1 * SH_C0$1 + 0.5 : green != null ? item.green / greenDiv : 1;\n const b = f_dc_2 != null ? item.f_dc_2 * SH_C0$1 + 0.5 : blue != null ? item.blue / blueDiv : 1;\n splatCallback(\n index,\n item.x,\n item.y,\n item.z,\n scaleX,\n scaleY,\n scaleZ,\n quatX,\n quatY,\n quatZ,\n quatW,\n op,\n r,\n g,\n b\n );\n if (shCallback && sh1) {\n const sh = item.f_rest;\n if (sh1) {\n for (let i2 = 0; i2 < sh1Props.length; i2++) {\n sh1[i2] = sh[sh1Props[i2]];\n }\n }\n if (sh2) {\n for (let i2 = 0; i2 < sh2Props.length; i2++) {\n sh2[i2] = sh[sh2Props[i2]];\n }\n }\n if (sh3) {\n for (let i2 = 0; i2 < sh3Props.length; i2++) {\n sh3[i2] = sh[sh3Props[i2]];\n }\n }\n shCallback(index, sh1, sh2, sh3);\n }\n };\n };\n this.parseData(elementCallback);\n }\n // Inject RGBA values into original PLY file, which can be used to modify\n // the color/opacity of the Gsplats and write out the modified PLY file.\n injectRgba(rgba) {\n let offset = 0;\n const data = this.data;\n if (data == null) {\n throw new Error("No parsed data");\n }\n if (rgba.length !== this.numSplats * 4) {\n throw new Error("Invalid RGBA array length");\n }\n for (const elementName in this.elements) {\n const element = this.elements[elementName];\n const { count, properties } = element;\n const parsers = [];\n let rgbaOffset = 0;\n const isVertex = elementName === "vertex";\n if (isVertex) {\n for (const name of ["opacity", "f_dc_0", "f_dc_1", "f_dc_2"]) {\n if (!properties[name] || properties[name].type !== "float") {\n throw new Error(`Can\'t injectRgba due to property: ${name}`);\n }\n }\n }\n for (const [propertyName, property] of Object.entries(properties)) {\n if (!property.isList) {\n if (isVertex) {\n if (propertyName === "f_dc_0" || propertyName === "f_dc_1" || propertyName === "f_dc_2") {\n const component = Number.parseInt(\n propertyName.slice("f_dc_".length)\n );\n parsers.push(() => {\n const value = (rgba[rgbaOffset + component] / 255 - 0.5) / SH_C0$1;\n SET_FIELD[property.type](\n data,\n offset,\n this.littleEndian,\n value\n );\n });\n } else if (propertyName === "opacity") {\n parsers.push(() => {\n const value = Math.max(\n -100,\n Math.min(\n 100,\n -Math.log(1 / (rgba[rgbaOffset + 3] / 255) - 1)\n )\n );\n SET_FIELD[property.type](\n data,\n offset,\n this.littleEndian,\n value\n );\n });\n }\n }\n parsers.push(() => {\n offset += FIELD_BYTES[property.type];\n });\n } else {\n parsers.push(() => {\n const length = PARSE_FIELD[property.countType](\n data,\n offset,\n this.littleEndian\n );\n offset += FIELD_BYTES[property.countType];\n offset += length * FIELD_BYTES[property.type];\n });\n }\n }\n for (let index = 0; index < count; index++) {\n for (const parser of parsers) {\n parser();\n }\n if (isVertex) {\n rgbaOffset += 4;\n }\n }\n }\n }\n };\n _PlyReader.defaultPointScale = 1e-3;\n let PlyReader = _PlyReader;\n const SH_C0$1 = 0.28209479177387814;\n const PARSE_FIELD = {\n char: (data, offset, littleEndian) => {\n return data.getInt8(offset);\n },\n uchar: (data, offset, littleEndian) => {\n return data.getUint8(offset);\n },\n short: (data, offset, littleEndian) => {\n return data.getInt16(offset, littleEndian);\n },\n ushort: (data, offset, littleEndian) => {\n return data.getUint16(offset, littleEndian);\n },\n int: (data, offset, littleEndian) => {\n return data.getInt32(offset, littleEndian);\n },\n uint: (data, offset, littleEndian) => {\n return data.getUint32(offset, littleEndian);\n },\n float: (data, offset, littleEndian) => {\n return data.getFloat32(offset, littleEndian);\n },\n double: (data, offset, littleEndian) => {\n return data.getFloat64(offset, littleEndian);\n }\n };\n const SET_FIELD = {\n char: (data, offset, littleEndian, value) => {\n data.setInt8(offset, value);\n },\n uchar: (data, offset, littleEndian, value) => {\n data.setUint8(offset, value);\n },\n short: (data, offset, littleEndian, value) => {\n data.setInt16(offset, value, littleEndian);\n },\n ushort: (data, offset, littleEndian, value) => {\n data.setUint16(offset, value, littleEndian);\n },\n int: (data, offset, littleEndian, value) => {\n data.setInt32(offset, value, littleEndian);\n },\n uint: (data, offset, littleEndian, value) => {\n data.setUint32(offset, value, littleEndian);\n },\n float: (data, offset, littleEndian, value) => {\n data.setFloat32(offset, value, littleEndian);\n },\n double: (data, offset, littleEndian, value) => {\n data.setFloat64(offset, value, littleEndian);\n }\n };\n const FIELD_BYTES = {\n char: 1,\n uchar: 1,\n short: 2,\n ushort: 2,\n int: 4,\n uint: 4,\n float: 4,\n double: 8\n };\n const FIELD_SCALE = {\n char: 127,\n uchar: 255,\n short: 32767,\n ushort: 65535,\n int: 2147483647,\n uint: 4294967295,\n float: 1,\n double: 1\n };\n const NUM_F_REST_TO_NUM_SH = {\n 0: 0,\n 9: 1,\n 24: 2,\n 45: 3\n };\n const NUM_SH_TO_NUM_F_REST = {\n 0: 0,\n 1: 9,\n 2: 24,\n 3: 45\n };\n const F_REST_REGEX = /^f_rest_([0-9]{1,2})$/;\n function createEmptyItem(properties) {\n const item = {};\n for (const [propertyName, property] of Object.entries(properties)) {\n if (F_REST_REGEX.test(propertyName)) {\n item.f_rest = new Array(getNumSh(properties));\n } else {\n item[propertyName] = property.isList ? [] : 0;\n }\n }\n return item;\n }\n function createParseFn(properties, littleEndian) {\n if (safeToCompile(properties)) {\n return createCompiledParserFn(properties, littleEndian);\n }\n return createDynamicParserFn(properties, littleEndian);\n }\n const UNSAFE_EVAL_ALLOWED = (() => {\n try {\n new Function("return 42;");\n } catch (e) {\n return false;\n }\n return true;\n })();\n const PROPERTY_NAME_REGEX = /^[a-zA-Z0-9_]+$/;\n function safeToCompile(properties) {\n if (!UNSAFE_EVAL_ALLOWED) {\n return false;\n }\n for (const [propertyName, property] of Object.entries(properties)) {\n if (!PROPERTY_NAME_REGEX.test(propertyName)) {\n return false;\n }\n if (property.isList && !PLY_PROPERTY_TYPES.includes(property.countType)) {\n return false;\n }\n if (!PLY_PROPERTY_TYPES.includes(property.type)) {\n return false;\n }\n }\n return true;\n }\n function createCompiledParserFn(properties, littleEndian) {\n const parserSrc = ["let list;"];\n for (const [propertyName, property] of Object.entries(properties)) {\n const fRestMatch = propertyName.match(F_REST_REGEX);\n if (fRestMatch) {\n const fRestIndex = +fRestMatch[1];\n parserSrc.push(\n /*js*/\n `\n item.f_rest[${fRestIndex}] = PARSE_FIELD[\'${property.type}\'](data, offset, ${littleEndian});\n offset += ${FIELD_BYTES[property.type]};\n `\n );\n } else if (!property.isList) {\n parserSrc.push(\n /*js*/\n `\n item[\'${propertyName}\'] = PARSE_FIELD[\'${property.type}\'](data, offset, ${littleEndian});\n offset += ${FIELD_BYTES[property.type]};\n `\n );\n } else {\n parserSrc.push(\n /*js*/\n `\n list = item[\'${propertyName}\'];\n list.length = PARSE_FIELD[\'${property.countType}\'](data, offset, ${littleEndian});\n offset += ${FIELD_BYTES[property.countType]};\n for (let i = 0; i < list.length; i++) {\n list[i] = PARSE_FIELD[\'${property.type}\'](data, offset, ${littleEndian});\n offset += ${FIELD_BYTES[property.type]};\n }\n `\n );\n }\n }\n parserSrc.push("return offset;");\n const fn = new Function(\n "data",\n "offset",\n "item",\n "PARSE_FIELD",\n parserSrc.join("\\n")\n );\n return (data, offset, item) => fn(data, offset, item, PARSE_FIELD);\n }\n function createDynamicParserFn(properties, littleEndian) {\n const parsers = [];\n for (const [propertyName, property] of Object.entries(properties)) {\n const fRestMatch = propertyName.match(F_REST_REGEX);\n if (fRestMatch) {\n const fRestIndex = +fRestMatch[1];\n parsers.push(\n (data, offset, item) => {\n item.f_rest[fRestIndex] = PARSE_FIELD[property.type](\n data,\n offset,\n littleEndian\n );\n return offset + FIELD_BYTES[property.type];\n }\n );\n } else if (!property.isList) {\n parsers.push(\n (data, offset, item) => {\n item[propertyName] = PARSE_FIELD[property.type](\n data,\n offset,\n littleEndian\n );\n return offset + FIELD_BYTES[property.type];\n }\n );\n } else {\n parsers.push(\n (data, offset, item) => {\n const list = item[propertyName];\n list.length = PARSE_FIELD[property.countType](\n data,\n offset,\n littleEndian\n );\n let currentOffset = offset + FIELD_BYTES[property.countType];\n for (let i2 = 0; i2 < list.length; i2++) {\n list[i2] = PARSE_FIELD[property.type](\n data,\n currentOffset,\n littleEndian\n );\n currentOffset += FIELD_BYTES[property.type];\n }\n return currentOffset;\n }\n );\n }\n }\n return (data, offset, item) => {\n let currentOffset = offset;\n for (let parserIndex = 0; parserIndex < parsers.length; parserIndex++) {\n currentOffset = parsers[parserIndex](data, currentOffset, item);\n }\n return currentOffset;\n };\n }\n function getNumSh(properties) {\n let num_f_rest = 0;\n while (properties[`f_rest_${num_f_rest}`]) {\n num_f_rest += 1;\n }\n const numSh = NUM_F_REST_TO_NUM_SH[num_f_rest];\n if (numSh == null) {\n throw new Error(`Unsupported number of SH coefficients: ${num_f_rest}`);\n }\n return numSh;\n }\n var SplatFileType = /* @__PURE__ */ ((SplatFileType2) => {\n SplatFileType2["PLY"] = "ply";\n SplatFileType2["SPZ"] = "spz";\n SplatFileType2["SPLAT"] = "splat";\n SplatFileType2["KSPLAT"] = "ksplat";\n SplatFileType2["PCSOGS"] = "pcsogs";\n SplatFileType2["PCSOGSZIP"] = "pcsogszip";\n return SplatFileType2;\n })(SplatFileType || {});\n function getSplatFileType(fileBytes) {\n const view = new DataView(fileBytes.buffer);\n if ((view.getUint32(0, true) & 16777215) === 7957616) {\n return "ply";\n }\n if ((view.getUint32(0, true) & 16777215) === 559903) {\n const header = decompressPartialGzip(fileBytes, 4);\n const gView = new DataView(header.buffer);\n if (gView.getUint32(0, true) === 1347635022) {\n return "spz";\n }\n return void 0;\n }\n if (view.getUint32(0, true) === 67324752) {\n if (tryPcSogsZip(fileBytes)) {\n return "pcsogszip";\n }\n return void 0;\n }\n return void 0;\n }\n function getFileExtension(pathOrUrl) {\n const noTrailing = pathOrUrl.split(/[?#]/, 1)[0];\n const lastSlash = Math.max(\n noTrailing.lastIndexOf("/"),\n noTrailing.lastIndexOf("\\\\")\n );\n const filename = noTrailing.slice(lastSlash + 1);\n const lastDot = filename.lastIndexOf(".");\n if (lastDot <= 0 || lastDot === filename.length - 1) {\n return "";\n }\n return filename.slice(lastDot + 1).toLowerCase();\n }\n function getSplatFileTypeFromPath(pathOrUrl) {\n const extension = getFileExtension(pathOrUrl);\n if (extension === "ply") {\n return "ply";\n }\n if (extension === "spz") {\n return "spz";\n }\n if (extension === "splat") {\n return "splat";\n }\n if (extension === "ksplat") {\n return "ksplat";\n }\n return void 0;\n }\n function tryPcSogs(input) {\n try {\n let text;\n if (typeof input === "string") {\n text = input;\n } else {\n const fileBytes = input instanceof ArrayBuffer ? new Uint8Array(input) : input;\n if (fileBytes.length > 65536) {\n return void 0;\n }\n text = new TextDecoder().decode(fileBytes);\n }\n const json = JSON.parse(text);\n if (!json || typeof json !== "object" || Array.isArray(json)) {\n return void 0;\n }\n for (const key of ["means", "scales", "quats", "sh0"]) {\n if (!json[key] || typeof json[key] !== "object" || Array.isArray(json[key])) {\n return void 0;\n }\n if (!json[key].shape || !json[key].files) {\n return void 0;\n }\n if (key !== "quats" && (!json[key].mins || !json[key].maxs)) {\n return void 0;\n }\n }\n return json;\n } catch {\n return void 0;\n }\n }\n function tryPcSogsZip(input) {\n try {\n const fileBytes = input instanceof ArrayBuffer ? new Uint8Array(input) : input;\n let metaFilename = null;\n const unzipped = unzipSync(fileBytes, {\n filter: ({ name }) => {\n const filename = name.split(/[\\\\/]/).pop();\n if (filename === "meta.json") {\n metaFilename = name;\n return true;\n }\n return false;\n }\n });\n if (!metaFilename) {\n return void 0;\n }\n const json = tryPcSogs(unzipped[metaFilename]);\n if (!json) {\n return void 0;\n }\n return { name: metaFilename, json };\n } catch {\n return void 0;\n }\n }\n class SplatData {\n constructor({ maxSplats = 1 } = {}) {\n this.numSplats = 0;\n this.maxSplats = getTextureSize(maxSplats).maxSplats;\n this.centers = new Float32Array(this.maxSplats * 3);\n this.scales = new Float32Array(this.maxSplats * 3);\n this.quaternions = new Float32Array(this.maxSplats * 4);\n this.opacities = new Float32Array(this.maxSplats);\n this.colors = new Float32Array(this.maxSplats * 3);\n }\n pushSplat() {\n const index = this.numSplats;\n this.ensureIndex(index);\n this.numSplats += 1;\n return index;\n }\n unpushSplat(index) {\n if (index === this.numSplats - 1) {\n this.numSplats -= 1;\n } else {\n throw new Error("Cannot unpush splat from non-last position");\n }\n }\n ensureCapacity(numSplats) {\n if (numSplats > this.maxSplats) {\n const targetSplats = Math.max(numSplats, this.maxSplats * 2);\n const newCenters = new Float32Array(targetSplats * 3);\n const newScales = new Float32Array(targetSplats * 3);\n const newQuaternions = new Float32Array(targetSplats * 4);\n const newOpacities = new Float32Array(targetSplats);\n const newColors = new Float32Array(targetSplats * 3);\n newCenters.set(this.centers);\n newScales.set(this.scales);\n newQuaternions.set(this.quaternions);\n newOpacities.set(this.opacities);\n newColors.set(this.colors);\n this.centers = newCenters;\n this.scales = newScales;\n this.quaternions = newQuaternions;\n this.opacities = newOpacities;\n this.colors = newColors;\n if (this.sh1) {\n const newSh1 = new Float32Array(targetSplats * 9);\n newSh1.set(this.sh1);\n this.sh1 = newSh1;\n }\n if (this.sh2) {\n const newSh2 = new Float32Array(targetSplats * 15);\n newSh2.set(this.sh2);\n this.sh2 = newSh2;\n }\n if (this.sh3) {\n const newSh3 = new Float32Array(targetSplats * 21);\n newSh3.set(this.sh3);\n this.sh3 = newSh3;\n }\n this.maxSplats = targetSplats;\n }\n }\n ensureIndex(index) {\n this.ensureCapacity(index + 1);\n }\n setCenter(index, x2, y, z) {\n this.centers[index * 3] = x2;\n this.centers[index * 3 + 1] = y;\n this.centers[index * 3 + 2] = z;\n }\n setScale(index, scaleX, scaleY, scaleZ) {\n this.scales[index * 3] = scaleX;\n this.scales[index * 3 + 1] = scaleY;\n this.scales[index * 3 + 2] = scaleZ;\n }\n setQuaternion(index, x2, y, z, w) {\n this.quaternions[index * 4] = x2;\n this.quaternions[index * 4 + 1] = y;\n this.quaternions[index * 4 + 2] = z;\n this.quaternions[index * 4 + 3] = w;\n }\n setOpacity(index, opacity) {\n this.opacities[index] = opacity;\n }\n setColor(index, r, g, b) {\n this.colors[index * 3] = r;\n this.colors[index * 3 + 1] = g;\n this.colors[index * 3 + 2] = b;\n }\n setSh1(index, sh1) {\n if (!this.sh1) {\n this.sh1 = new Float32Array(this.maxSplats * 9);\n }\n for (let j = 0; j < 9; ++j) {\n this.sh1[index * 9 + j] = sh1[j];\n }\n }\n setSh2(index, sh2) {\n if (!this.sh2) {\n this.sh2 = new Float32Array(this.maxSplats * 15);\n }\n for (let j = 0; j < 15; ++j) {\n this.sh2[index * 15 + j] = sh2[j];\n }\n }\n setSh3(index, sh3) {\n if (!this.sh3) {\n this.sh3 = new Float32Array(this.maxSplats * 21);\n }\n for (let j = 0; j < 21; ++j) {\n this.sh3[index * 21 + j] = sh3[j];\n }\n }\n }\n async function unpackPcSogs(json, extraFiles, splatEncoding) {\n if (json.quats.encoding !== "quaternion_packed") {\n throw new Error("Unsupported quaternion encoding");\n }\n const numSplats = json.means.shape[0];\n const maxSplats = computeMaxSplats(numSplats);\n const packedArray = new Uint32Array(maxSplats * 4);\n const extra = {};\n const meansPromise = Promise.all([\n decodeImageRgba(extraFiles[json.means.files[0]]),\n decodeImageRgba(extraFiles[json.means.files[1]])\n ]).then((means) => {\n for (let i2 = 0; i2 < numSplats; ++i2) {\n const i4 = i2 * 4;\n const fx = (means[0][i4 + 0] + (means[1][i4 + 0] << 8)) / 65535;\n const fy = (means[0][i4 + 1] + (means[1][i4 + 1] << 8)) / 65535;\n const fz = (means[0][i4 + 2] + (means[1][i4 + 2] << 8)) / 65535;\n let x2 = json.means.mins[0] + (json.means.maxs[0] - json.means.mins[0]) * fx;\n let y = json.means.mins[1] + (json.means.maxs[1] - json.means.mins[1]) * fy;\n let z = json.means.mins[2] + (json.means.maxs[2] - json.means.mins[2]) * fz;\n x2 = Math.sign(x2) * (Math.exp(Math.abs(x2)) - 1);\n y = Math.sign(y) * (Math.exp(Math.abs(y)) - 1);\n z = Math.sign(z) * (Math.exp(Math.abs(z)) - 1);\n setPackedSplatCenter(packedArray, i2, x2, y, z);\n }\n });\n const scalesPromise = decodeImageRgba(extraFiles[json.scales.files[0]]).then(\n (scales) => {\n const xLookup = new Array(256).fill(0).map(\n (_, i2) => json.scales.mins[0] + (json.scales.maxs[0] - json.scales.mins[0]) * (i2 / 255)\n ).map((x2) => Math.exp(x2));\n const yLookup = new Array(256).fill(0).map(\n (_, i2) => json.scales.mins[1] + (json.scales.maxs[1] - json.scales.mins[1]) * (i2 / 255)\n ).map((x2) => Math.exp(x2));\n const zLookup = new Array(256).fill(0).map(\n (_, i2) => json.scales.mins[2] + (json.scales.maxs[2] - json.scales.mins[2]) * (i2 / 255)\n ).map((x2) => Math.exp(x2));\n for (let i2 = 0; i2 < numSplats; ++i2) {\n const i4 = i2 * 4;\n setPackedSplatScales(\n packedArray,\n i2,\n xLookup[scales[i4 + 0]],\n yLookup[scales[i4 + 1]],\n zLookup[scales[i4 + 2]],\n splatEncoding\n );\n }\n }\n );\n const quatsPromise = decodeImageRgba(extraFiles[json.quats.files[0]]).then(\n (quats) => {\n const SQRT2 = Math.sqrt(2);\n const lookup = new Array(256).fill(0).map((_, i2) => (i2 / 255 - 0.5) * SQRT2);\n for (let i2 = 0; i2 < numSplats; ++i2) {\n const i4 = i2 * 4;\n const r0 = lookup[quats[i4 + 0]];\n const r1 = lookup[quats[i4 + 1]];\n const r2 = lookup[quats[i4 + 2]];\n const rr = Math.sqrt(Math.max(0, 1 - r0 * r0 - r1 * r1 - r2 * r2));\n const rOrder = quats[i4 + 3] - 252;\n const quatX = rOrder === 0 ? r0 : rOrder === 1 ? rr : r1;\n const quatY = rOrder <= 1 ? r1 : rOrder === 2 ? rr : r2;\n const quatZ = rOrder <= 2 ? r2 : rr;\n const quatW = rOrder === 0 ? rr : r0;\n setPackedSplatQuat(packedArray, i2, quatX, quatY, quatZ, quatW);\n }\n }\n );\n const sh0Promise = decodeImageRgba(extraFiles[json.sh0.files[0]]).then(\n (sh0) => {\n const SH_C02 = 0.28209479177387814;\n const rLookup = new Array(256).fill(0).map(\n (_, i2) => json.sh0.mins[0] + (json.sh0.maxs[0] - json.sh0.mins[0]) * (i2 / 255)\n ).map((x2) => SH_C02 * x2 + 0.5);\n const gLookup = new Array(256).fill(0).map(\n (_, i2) => json.sh0.mins[1] + (json.sh0.maxs[1] - json.sh0.mins[1]) * (i2 / 255)\n ).map((x2) => SH_C02 * x2 + 0.5);\n const bLookup = new Array(256).fill(0).map(\n (_, i2) => json.sh0.mins[2] + (json.sh0.maxs[2] - json.sh0.mins[2]) * (i2 / 255)\n ).map((x2) => SH_C02 * x2 + 0.5);\n const aLookup = new Array(256).fill(0).map(\n (_, i2) => json.sh0.mins[3] + (json.sh0.maxs[3] - json.sh0.mins[3]) * (i2 / 255)\n ).map((x2) => 1 / (1 + Math.exp(-x2)));\n for (let i2 = 0; i2 < numSplats; ++i2) {\n const i4 = i2 * 4;\n setPackedSplatRgba(\n packedArray,\n i2,\n rLookup[sh0[i4 + 0]],\n gLookup[sh0[i4 + 1]],\n bLookup[sh0[i4 + 2]],\n aLookup[sh0[i4 + 3]],\n splatEncoding\n );\n }\n }\n );\n const promises = [meansPromise, scalesPromise, quatsPromise, sh0Promise];\n if (json.shN) {\n const useSH3 = json.shN.shape[1] >= 48 - 3;\n const useSH2 = json.shN.shape[1] >= 27 - 3;\n const useSH1 = json.shN.shape[1] >= 12 - 3;\n if (useSH1) extra.sh1 = new Uint32Array(numSplats * 2);\n if (useSH2) extra.sh2 = new Uint32Array(numSplats * 4);\n if (useSH3) extra.sh3 = new Uint32Array(numSplats * 4);\n const sh1 = new Float32Array(9);\n const sh2 = new Float32Array(15);\n const sh3 = new Float32Array(21);\n const shN = json.shN;\n const shNPromise = Promise.all([\n decodeImage(extraFiles[json.shN.files[0]]),\n decodeImage(extraFiles[json.shN.files[1]])\n ]).then(([centroids, labels]) => {\n const lookup = new Array(256).fill(0).map((_, i2) => shN.mins + (shN.maxs - shN.mins) * (i2 / 255));\n for (let i2 = 0; i2 < numSplats; ++i2) {\n const i4 = i2 * 4;\n const label = labels.rgba[i4 + 0] + (labels.rgba[i4 + 1] << 8);\n const col = (label & 63) * 15;\n const row = label >>> 6;\n const offset = row * centroids.width + col;\n for (let d = 0; d < 3; ++d) {\n if (useSH1) {\n for (let k = 0; k < 3; ++k) {\n sh1[k * 3 + d] = lookup[centroids.rgba[(offset + k) * 4 + d]];\n }\n }\n if (useSH2) {\n for (let k = 0; k < 5; ++k) {\n sh2[k * 3 + d] = lookup[centroids.rgba[(offset + 3 + k) * 4 + d]];\n }\n }\n if (useSH3) {\n for (let k = 0; k < 7; ++k) {\n sh3[k * 3 + d] = lookup[centroids.rgba[(offset + 8 + k) * 4 + d]];\n }\n }\n }\n if (useSH1)\n encodeSh1Rgb(extra.sh1, i2, sh1, splatEncoding);\n if (useSH2)\n encodeSh2Rgb(extra.sh2, i2, sh2, splatEncoding);\n if (useSH3)\n encodeSh3Rgb(extra.sh3, i2, sh3, splatEncoding);\n }\n });\n promises.push(shNPromise);\n }\n await Promise.all(promises);\n return { packedArray, numSplats, extra };\n }\n let offscreenGlContext = null;\n async function decodeImage(fileBytes) {\n if (!offscreenGlContext) {\n const canvas = new OffscreenCanvas(1, 1);\n offscreenGlContext = canvas.getContext("webgl2");\n if (!offscreenGlContext) {\n throw new Error("Failed to create WebGL2 context");\n }\n }\n const imageBlob = new Blob([fileBytes]);\n const bitmap = await createImageBitmap(imageBlob, {\n premultiplyAlpha: "none"\n });\n const gl = offscreenGlContext;\n const texture = gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, bitmap);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n const framebuffer = gl.createFramebuffer();\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n gl.COLOR_ATTACHMENT0,\n gl.TEXTURE_2D,\n texture,\n 0\n );\n const data = new Uint8Array(bitmap.width * bitmap.height * 4);\n gl.readPixels(\n 0,\n 0,\n bitmap.width,\n bitmap.height,\n gl.RGBA,\n gl.UNSIGNED_BYTE,\n data\n );\n gl.deleteTexture(texture);\n gl.deleteFramebuffer(framebuffer);\n return { rgba: data, width: bitmap.width, height: bitmap.height };\n }\n async function decodeImageRgba(fileBytes) {\n const { rgba } = await decodeImage(fileBytes);\n return rgba;\n }\n async function unpackPcSogsZip(fileBytes, splatEncoding) {\n var _a2;\n const nameJson = tryPcSogsZip(fileBytes);\n if (!nameJson) {\n throw new Error("Invalid PC SOGS zip file");\n }\n const { name, json } = nameJson;\n const lastSlash = name.lastIndexOf("/");\n const lastBackslash = name.lastIndexOf("\\\\");\n const prefix = name.slice(0, Math.max(lastSlash, lastBackslash) + 1);\n const fileMap = /* @__PURE__ */ new Map();\n const refFiles = [\n ...json.means.files,\n ...json.scales.files,\n ...json.quats.files,\n ...json.sh0.files,\n ...((_a2 = json.shN) == null ? void 0 : _a2.files) ?? []\n ];\n for (const file of refFiles) {\n fileMap.set(prefix + file, file);\n }\n const unzipped = await new Promise(\n (resolve, reject) => {\n unzip(\n fileBytes,\n {\n filter: ({ name: name2 }) => {\n return fileMap.has(name2);\n }\n },\n (err2, files) => {\n if (err2) {\n reject(err2);\n } else {\n resolve(files);\n }\n }\n );\n }\n );\n const extraFiles = {};\n for (const [full, name2] of fileMap.entries()) {\n extraFiles[name2] = unzipped[full];\n }\n return await unpackPcSogs(json, extraFiles, splatEncoding);\n }\n class SpzReader {\n constructor({ fileBytes }) {\n this.fileBytes = fileBytes instanceof ArrayBuffer ? new Uint8Array(fileBytes) : fileBytes;\n this.reader = new GunzipReader({ fileBytes: this.fileBytes });\n const header = new DataView(this.reader.read(16).buffer);\n if (header.getUint32(0, true) !== 1347635022) {\n throw new Error("Invalid SPZ file");\n }\n this.version = header.getUint32(4, true);\n if (this.version < 1 || this.version > 3) {\n throw new Error(`Unsupported SPZ version: ${this.version}`);\n }\n this.numSplats = header.getUint32(8, true);\n this.shDegree = header.getUint8(12);\n this.fractionalBits = header.getUint8(13);\n this.flags = header.getUint8(14);\n this.flagAntiAlias = (this.flags & 1) !== 0;\n this.reserved = header.getUint8(15);\n this.parsed = false;\n }\n parseSplats(centerCallback, alphaCallback, rgbCallback, scalesCallback, quatCallback, shCallback) {\n if (this.parsed) {\n throw new Error("SPZ file already parsed");\n }\n this.parsed = true;\n if (this.version === 1) {\n const centerBytes = this.reader.read(this.numSplats * 3 * 2);\n const centerUint16 = new Uint16Array(centerBytes.buffer);\n for (let i2 = 0; i2 < this.numSplats; i2++) {\n const i3 = i2 * 3;\n const x2 = fromHalf(centerUint16[i3]);\n const y = fromHalf(centerUint16[i3 + 1]);\n const z = fromHalf(centerUint16[i3 + 2]);\n centerCallback == null ? void 0 : centerCallback(i2, x2, y, z);\n }\n } else if (this.version === 2 || this.version === 3) {\n const fixed = 1 << this.fractionalBits;\n const centerBytes = this.reader.read(this.numSplats * 3 * 3);\n for (let i2 = 0; i2 < this.numSplats; i2++) {\n const i9 = i2 * 9;\n const x2 = ((centerBytes[i9 + 2] << 24 | centerBytes[i9 + 1] << 16 | centerBytes[i9] << 8) >> 8) / fixed;\n const y = ((centerBytes[i9 + 5] << 24 | centerBytes[i9 + 4] << 16 | centerBytes[i9 + 3] << 8) >> 8) / fixed;\n const z = ((centerBytes[i9 + 8] << 24 | centerBytes[i9 + 7] << 16 | centerBytes[i9 + 6] << 8) >> 8) / fixed;\n centerCallback == null ? void 0 : centerCallback(i2, x2, y, z);\n }\n } else {\n throw new Error("Unreachable");\n }\n {\n const bytes = this.reader.read(this.numSplats);\n for (let i2 = 0; i2 < this.numSplats; i2++) {\n alphaCallback == null ? void 0 : alphaCallback(i2, bytes[i2] / 255);\n }\n }\n {\n const rgbBytes = this.reader.read(this.numSplats * 3);\n const scale = SH_C0 / 0.15;\n for (let i2 = 0; i2 < this.numSplats; i2++) {\n const i3 = i2 * 3;\n const r = (rgbBytes[i3] / 255 - 0.5) * scale + 0.5;\n const g = (rgbBytes[i3 + 1] / 255 - 0.5) * scale + 0.5;\n const b = (rgbBytes[i3 + 2] / 255 - 0.5) * scale + 0.5;\n rgbCallback == null ? void 0 : rgbCallback(i2, r, g, b);\n }\n }\n {\n const scalesBytes = this.reader.read(this.numSplats * 3);\n for (let i2 = 0; i2 < this.numSplats; i2++) {\n const i3 = i2 * 3;\n const scaleX = Math.exp(scalesBytes[i3] / 16 - 10);\n const scaleY = Math.exp(scalesBytes[i3 + 1] / 16 - 10);\n const scaleZ = Math.exp(scalesBytes[i3 + 2] / 16 - 10);\n scalesCallback == null ? void 0 : scalesCallback(i2, scaleX, scaleY, scaleZ);\n }\n }\n if (this.version === 3) {\n const maxValue = 1 / Math.sqrt(2);\n const quatBytes = this.reader.read(this.numSplats * 4);\n for (let i2 = 0; i2 < this.numSplats; i2++) {\n const i3 = i2 * 4;\n const quaternion = [0, 0, 0, 0];\n const values = [\n quatBytes[i3],\n quatBytes[i3 + 1],\n quatBytes[i3 + 2],\n quatBytes[i3 + 3]\n ];\n const combinedValues = values[0] + (values[1] << 8) + (values[2] << 16) + (values[3] << 24);\n const valueMask = (1 << 9) - 1;\n const largestIndex = combinedValues >>> 30;\n let remainingValues = combinedValues;\n let sumSquares = 0;\n for (let i22 = 3; i22 >= 0; --i22) {\n if (i22 !== largestIndex) {\n const value = remainingValues & valueMask;\n const sign = remainingValues >>> 9 & 1;\n remainingValues = remainingValues >>> 10;\n quaternion[i22] = maxValue * (value / valueMask);\n quaternion[i22] = sign === 0 ? quaternion[i22] : -quaternion[i22];\n sumSquares += quaternion[i22] * quaternion[i22];\n }\n }\n const square = 1 - sumSquares;\n quaternion[largestIndex] = Math.sqrt(Math.max(square, 0));\n quatCallback == null ? void 0 : quatCallback(\n i2,\n quaternion[0],\n quaternion[1],\n quaternion[2],\n quaternion[3]\n );\n }\n } else {\n const quatBytes = this.reader.read(this.numSplats * 3);\n for (let i2 = 0; i2 < this.numSplats; i2++) {\n const i3 = i2 * 3;\n const quatX = quatBytes[i3] / 127.5 - 1;\n const quatY = quatBytes[i3 + 1] / 127.5 - 1;\n const quatZ = quatBytes[i3 + 2] / 127.5 - 1;\n const quatW = Math.sqrt(\n Math.max(0, 1 - quatX * quatX - quatY * quatY - quatZ * quatZ)\n );\n quatCallback == null ? void 0 : quatCallback(i2, quatX, quatY, quatZ, quatW);\n }\n }\n if (shCallback && this.shDegree >= 1) {\n const sh1 = new Float32Array(3 * 3);\n const sh2 = this.shDegree >= 2 ? new Float32Array(5 * 3) : void 0;\n const sh3 = this.shDegree >= 3 ? new Float32Array(7 * 3) : void 0;\n const shBytes = this.reader.read(\n this.numSplats * SH_DEGREE_TO_VECS[this.shDegree] * 3\n );\n let offset = 0;\n for (let i2 = 0; i2 < this.numSplats; i2++) {\n for (let j = 0; j < 9; ++j) {\n sh1[j] = (shBytes[offset + j] - 128) / 128;\n }\n offset += 9;\n if (sh2) {\n for (let j = 0; j < 15; ++j) {\n sh2[j] = (shBytes[offset + j] - 128) / 128;\n }\n offset += 15;\n }\n if (sh3) {\n for (let j = 0; j < 21; ++j) {\n sh3[j] = (shBytes[offset + j] - 128) / 128;\n }\n offset += 21;\n }\n shCallback == null ? void 0 : shCallback(i2, sh1, sh2, sh3);\n }\n }\n }\n }\n const SH_DEGREE_TO_VECS = { 1: 3, 2: 8, 3: 15 };\n const SH_C0 = 0.28209479177387814;\n const SPZ_MAGIC = 1347635022;\n const SPZ_VERSION = 3;\n const FLAG_ANTIALIASED = 1;\n class SpzWriter {\n constructor({\n numSplats,\n shDegree,\n fractionalBits = 12,\n flagAntiAlias = true\n }) {\n this.clippedCount = 0;\n const splatSize = 9 + // Position\n 1 + // Opacity\n 3 + // Scale\n 3 + // DC-rgb\n 4 + // Rotation\n (shDegree >= 1 ? 9 : 0) + (shDegree >= 2 ? 15 : 0) + (shDegree >= 3 ? 21 : 0);\n const bufferSize = 16 + numSplats * splatSize;\n this.buffer = new ArrayBuffer(bufferSize);\n this.view = new DataView(this.buffer);\n this.view.setUint32(0, SPZ_MAGIC, true);\n this.view.setUint32(4, SPZ_VERSION, true);\n this.view.setUint32(8, numSplats, true);\n this.view.setUint8(12, shDegree);\n this.view.setUint8(13, fractionalBits);\n this.view.setUint8(14, flagAntiAlias ? FLAG_ANTIALIASED : 0);\n this.view.setUint8(15, 0);\n this.numSplats = numSplats;\n this.shDegree = shDegree;\n this.fractionalBits = fractionalBits;\n this.fraction = 1 << fractionalBits;\n this.flagAntiAlias = flagAntiAlias;\n }\n setCenter(index, x2, y, z) {\n const xRounded = Math.round(x2 * this.fraction);\n const xInt = Math.max(-8388607, Math.min(8388607, xRounded));\n const yRounded = Math.round(y * this.fraction);\n const yInt = Math.max(-8388607, Math.min(8388607, yRounded));\n const zRounded = Math.round(z * this.fraction);\n const zInt = Math.max(-8388607, Math.min(8388607, zRounded));\n const clipped = xRounded !== xInt || yRounded !== yInt || zRounded !== zInt;\n if (clipped) {\n this.clippedCount += 1;\n }\n const i9 = index * 9;\n const base = 16 + i9;\n this.view.setUint8(base, xInt & 255);\n this.view.setUint8(base + 1, xInt >> 8 & 255);\n this.view.setUint8(base + 2, xInt >> 16 & 255);\n this.view.setUint8(base + 3, yInt & 255);\n this.view.setUint8(base + 4, yInt >> 8 & 255);\n this.view.setUint8(base + 5, yInt >> 16 & 255);\n this.view.setUint8(base + 6, zInt & 255);\n this.view.setUint8(base + 7, zInt >> 8 & 255);\n this.view.setUint8(base + 8, zInt >> 16 & 255);\n }\n setAlpha(index, alpha) {\n const base = 16 + this.numSplats * 9 + index;\n this.view.setUint8(\n base,\n Math.max(0, Math.min(255, Math.round(alpha * 255)))\n );\n }\n static scaleRgb(r) {\n const v = ((r - 0.5) / (SH_C0 / 0.15) + 0.5) * 255;\n return Math.max(0, Math.min(255, Math.round(v)));\n }\n setRgb(index, r, g, b) {\n const base = 16 + this.numSplats * 10 + index * 3;\n this.view.setUint8(base, SpzWriter.scaleRgb(r));\n this.view.setUint8(base + 1, SpzWriter.scaleRgb(g));\n this.view.setUint8(base + 2, SpzWriter.scaleRgb(b));\n }\n setScale(index, scaleX, scaleY, scaleZ) {\n const base = 16 + this.numSplats * 13 + index * 3;\n this.view.setUint8(\n base,\n Math.max(0, Math.min(255, Math.round((Math.log(scaleX) + 10) * 16)))\n );\n this.view.setUint8(\n base + 1,\n Math.max(0, Math.min(255, Math.round((Math.log(scaleY) + 10) * 16)))\n );\n this.view.setUint8(\n base + 2,\n Math.max(0, Math.min(255, Math.round((Math.log(scaleZ) + 10) * 16)))\n );\n }\n setQuat(index, ...q) {\n const base = 16 + this.numSplats * 16 + index * 4;\n const quat = normalize(q);\n let iLargest = 0;\n for (let i2 = 1; i2 < 4; ++i2) {\n if (Math.abs(quat[i2]) > Math.abs(quat[iLargest])) {\n iLargest = i2;\n }\n }\n const negate = quat[iLargest] < 0 ? 1 : 0;\n let comp = iLargest;\n for (let i2 = 0; i2 < 4; ++i2) {\n if (i2 !== iLargest) {\n const negbit = (quat[i2] < 0 ? 1 : 0) ^ negate;\n const mag = Math.floor(\n ((1 << 9) - 1) * (Math.abs(quat[i2]) / Math.SQRT1_2) + 0.5\n );\n comp = comp << 10 | negbit << 9 | mag;\n }\n }\n this.view.setUint8(base, comp & 255);\n this.view.setUint8(base + 1, comp >> 8 & 255);\n this.view.setUint8(base + 2, comp >> 16 & 255);\n this.view.setUint8(base + 3, comp >>> 24 & 255);\n }\n static quantizeSh(sh, bits2) {\n const value = Math.round(sh * 128) + 128;\n const bucketSize = 1 << 8 - bits2;\n const quantized = Math.floor((value + bucketSize / 2) / bucketSize) * bucketSize;\n return Math.max(0, Math.min(255, quantized));\n }\n setSh(index, sh1, sh2, sh3) {\n const shVecs = SH_DEGREE_TO_VECS[this.shDegree] || 0;\n const base1 = 16 + this.numSplats * 20 + index * shVecs * 3;\n for (let j = 0; j < 9; ++j) {\n this.view.setUint8(base1 + j, SpzWriter.quantizeSh(sh1[j], 5));\n }\n if (sh2) {\n const base2 = base1 + 9;\n for (let j = 0; j < 15; ++j) {\n this.view.setUint8(base2 + j, SpzWriter.quantizeSh(sh2[j], 4));\n }\n if (sh3) {\n const base3 = base2 + 15;\n for (let j = 0; j < 21; ++j) {\n this.view.setUint8(base3 + j, SpzWriter.quantizeSh(sh3[j], 4));\n }\n }\n }\n }\n async finalize() {\n const input = new Uint8Array(this.buffer);\n const stream = new ReadableStream({\n async start(controller) {\n controller.enqueue(input);\n controller.close();\n }\n });\n const compressed = stream.pipeThrough(new CompressionStream("gzip"));\n const response = new Response(compressed);\n const buffer = await response.arrayBuffer();\n console.log(\n "Compressed",\n input.length,\n "bytes to",\n buffer.byteLength,\n "bytes"\n );\n return new Uint8Array(buffer);\n }\n }\n async function transcodeSpz(input) {\n var _a2, _b2, _c;\n const splats = new SplatData();\n const {\n inputs,\n clipXyz,\n maxSh,\n fractionalBits = 12,\n opacityThreshold\n } = input;\n for (const input2 of inputs) {\n let transformPos = function(pos) {\n pos.multiplyScalar(scale);\n pos.applyQuaternion(quaternion);\n pos.add(translate);\n return pos;\n }, transformScales = function(scales) {\n scales.multiplyScalar(scale);\n return scales;\n }, transformQuaternion = function(quat) {\n quat.premultiply(quaternion);\n return quat;\n }, withinClip = function(p) {\n return !clip || clip.containsPoint(p);\n }, withinOpacity = function(opacity) {\n return opacityThreshold !== void 0 ? opacity >= opacityThreshold : true;\n };\n const scale = ((_a2 = input2.transform) == null ? void 0 : _a2.scale) ?? 1;\n const quaternion = new Quaternion().fromArray(\n ((_b2 = input2.transform) == null ? void 0 : _b2.quaternion) ?? [0, 0, 0, 1]\n );\n const translate = new Vector3().fromArray(\n ((_c = input2.transform) == null ? void 0 : _c.translate) ?? [0, 0, 0]\n );\n const clip = clipXyz ? new Box3(\n new Vector3().fromArray(clipXyz.min),\n new Vector3().fromArray(clipXyz.max)\n ) : void 0;\n let fileType = input2.fileType;\n if (!fileType) {\n fileType = getSplatFileType(input2.fileBytes);\n if (!fileType && input2.pathOrUrl) {\n fileType = getSplatFileTypeFromPath(input2.pathOrUrl);\n }\n }\n switch (fileType) {\n case SplatFileType.PLY: {\n const ply = new PlyReader({ fileBytes: input2.fileBytes });\n await ply.parseHeader();\n let lastIndex = null;\n ply.parseSplats(\n (index, x2, y, z, scaleX, scaleY, scaleZ, quatX, quatY, quatZ, quatW, opacity, r, g, b) => {\n const center = transformPos(new Vector3(x2, y, z));\n if (withinClip(center) && withinOpacity(opacity)) {\n lastIndex = splats.pushSplat();\n splats.setCenter(lastIndex, center.x, center.y, center.z);\n const scales = transformScales(\n new Vector3(scaleX, scaleY, scaleZ)\n );\n splats.setScale(lastIndex, scales.x, scales.y, scales.z);\n const quaternion2 = transformQuaternion(\n new Quaternion(quatX, quatY, quatZ, quatW)\n );\n splats.setQuaternion(\n lastIndex,\n quaternion2.x,\n quaternion2.y,\n quaternion2.z,\n quaternion2.w\n );\n splats.setOpacity(lastIndex, opacity);\n splats.setColor(lastIndex, r, g, b);\n } else {\n lastIndex = null;\n }\n },\n (index, sh1, sh2, sh3) => {\n if (sh1 && lastIndex !== null) {\n splats.setSh1(lastIndex, sh1);\n }\n if (sh2 && lastIndex !== null) {\n splats.setSh2(lastIndex, sh2);\n }\n if (sh3 && lastIndex !== null) {\n splats.setSh3(lastIndex, sh3);\n }\n }\n );\n break;\n }\n case SplatFileType.SPZ: {\n const spz2 = new SpzReader({ fileBytes: input2.fileBytes });\n const mapping = new Int32Array(spz2.numSplats);\n mapping.fill(-1);\n const centers = new Float32Array(spz2.numSplats * 3);\n const center = new Vector3();\n spz2.parseSplats(\n (index, x2, y, z) => {\n const center2 = transformPos(new Vector3(x2, y, z));\n centers[index * 3] = center2.x;\n centers[index * 3 + 1] = center2.y;\n centers[index * 3 + 2] = center2.z;\n },\n (index, alpha) => {\n center.fromArray(centers, index * 3);\n if (withinClip(center) && withinOpacity(alpha)) {\n mapping[index] = splats.pushSplat();\n splats.setCenter(mapping[index], center.x, center.y, center.z);\n splats.setOpacity(mapping[index], alpha);\n }\n },\n (index, r, g, b) => {\n if (mapping[index] >= 0) {\n splats.setColor(mapping[index], r, g, b);\n }\n },\n (index, scaleX, scaleY, scaleZ) => {\n if (mapping[index] >= 0) {\n const scales = transformScales(\n new Vector3(scaleX, scaleY, scaleZ)\n );\n splats.setScale(mapping[index], scales.x, scales.y, scales.z);\n }\n },\n (index, quatX, quatY, quatZ, quatW) => {\n if (mapping[index] >= 0) {\n const quaternion2 = transformQuaternion(\n new Quaternion(quatX, quatY, quatZ, quatW)\n );\n splats.setQuaternion(\n mapping[index],\n quaternion2.x,\n quaternion2.y,\n quaternion2.z,\n quaternion2.w\n );\n }\n },\n (index, sh1, sh2, sh3) => {\n if (mapping[index] >= 0) {\n splats.setSh1(mapping[index], sh1);\n if (sh2) {\n splats.setSh2(mapping[index], sh2);\n }\n if (sh3) {\n splats.setSh3(mapping[index], sh3);\n }\n }\n }\n );\n break;\n }\n case SplatFileType.SPLAT:\n decodeAntiSplat(\n input2.fileBytes,\n (numSplats) => {\n },\n (index, x2, y, z, scaleX, scaleY, scaleZ, quatX, quatY, quatZ, quatW, opacity, r, g, b) => {\n const center = transformPos(new Vector3(x2, y, z));\n if (withinClip(center) && withinOpacity(opacity)) {\n const index2 = splats.pushSplat();\n splats.setCenter(index2, center.x, center.y, center.z);\n const scales = transformScales(\n new Vector3(scaleX, scaleY, scaleZ)\n );\n splats.setScale(index2, scales.x, scales.y, scales.z);\n const quaternion2 = transformQuaternion(\n new Quaternion(quatX, quatY, quatZ, quatW)\n );\n splats.setQuaternion(\n index2,\n quaternion2.x,\n quaternion2.y,\n quaternion2.z,\n quaternion2.w\n );\n splats.setOpacity(index2, opacity);\n splats.setColor(index2, r, g, b);\n }\n }\n );\n break;\n case SplatFileType.KSPLAT: {\n let lastIndex = null;\n decodeKsplat(\n input2.fileBytes,\n (numSplats) => {\n },\n (index, x2, y, z, scaleX, scaleY, scaleZ, quatX, quatY, quatZ, quatW, opacity, r, g, b) => {\n const center = transformPos(new Vector3(x2, y, z));\n if (withinClip(center) && withinOpacity(opacity)) {\n lastIndex = splats.pushSplat();\n splats.setCenter(lastIndex, center.x, center.y, center.z);\n const scales = transformScales(\n new Vector3(scaleX, scaleY, scaleZ)\n );\n splats.setScale(lastIndex, scales.x, scales.y, scales.z);\n const quaternion2 = transformQuaternion(\n new Quaternion(quatX, quatY, quatZ, quatW)\n );\n splats.setQuaternion(\n lastIndex,\n quaternion2.x,\n quaternion2.y,\n quaternion2.z,\n quaternion2.w\n );\n splats.setOpacity(lastIndex, opacity);\n splats.setColor(lastIndex, r, g, b);\n } else {\n lastIndex = null;\n }\n },\n (index, sh1, sh2, sh3) => {\n if (lastIndex !== null) {\n splats.setSh1(lastIndex, sh1);\n if (sh2) {\n splats.setSh2(lastIndex, sh2);\n }\n if (sh3) {\n splats.setSh3(lastIndex, sh3);\n }\n }\n }\n );\n break;\n }\n default:\n throw new Error(`transcodeSpz not implemented for ${fileType}`);\n }\n }\n const shDegree = Math.min(\n maxSh ?? 3,\n splats.sh3 ? 3 : splats.sh2 ? 2 : splats.sh1 ? 1 : 0\n );\n const spz = new SpzWriter({\n numSplats: splats.numSplats,\n shDegree,\n fractionalBits,\n flagAntiAlias: true\n });\n for (let i2 = 0; i2 < splats.numSplats; ++i2) {\n const i3 = i2 * 3;\n const i4 = i2 * 4;\n spz.setCenter(\n i2,\n splats.centers[i3],\n splats.centers[i3 + 1],\n splats.centers[i3 + 2]\n );\n spz.setScale(\n i2,\n splats.scales[i3],\n splats.scales[i3 + 1],\n splats.scales[i3 + 2]\n );\n spz.setQuat(\n i2,\n splats.quaternions[i4],\n splats.quaternions[i4 + 1],\n splats.quaternions[i4 + 2],\n splats.quaternions[i4 + 3]\n );\n spz.setAlpha(i2, splats.opacities[i2]);\n spz.setRgb(\n i2,\n splats.colors[i3],\n splats.colors[i3 + 1],\n splats.colors[i3 + 2]\n );\n if (splats.sh1 && shDegree >= 1) {\n spz.setSh(\n i2,\n splats.sh1.slice(i2 * 9, (i2 + 1) * 9),\n shDegree >= 2 && splats.sh2 ? splats.sh2.slice(i2 * 15, (i2 + 1) * 15) : void 0,\n shDegree >= 3 && splats.sh3 ? splats.sh3.slice(i2 * 21, (i2 + 1) * 21) : void 0\n );\n }\n }\n const spzBytes = await spz.finalize();\n return { fileBytes: spzBytes, clippedCount: spz.clippedCount };\n }\n async function onMessage(event) {\n const { name, args, id } = event.data;\n let result = void 0;\n let error = void 0;\n try {\n switch (name) {\n case "unpackPly": {\n const { packedArray, fileBytes, splatEncoding } = args;\n const decoded = await unpackPly({\n packedArray,\n fileBytes,\n splatEncoding\n });\n result = {\n id,\n numSplats: decoded.numSplats,\n packedArray: decoded.packedArray,\n extra: decoded.extra\n };\n break;\n }\n case "decodeSpz": {\n const { fileBytes, splatEncoding } = args;\n const decoded = unpackSpz(fileBytes, splatEncoding);\n result = {\n id,\n numSplats: decoded.numSplats,\n packedArray: decoded.packedArray,\n extra: decoded.extra\n };\n break;\n }\n case "decodeAntiSplat": {\n const { fileBytes, splatEncoding } = args;\n const decoded = unpackAntiSplat(fileBytes, splatEncoding);\n result = {\n id,\n numSplats: decoded.numSplats,\n packedArray: decoded.packedArray\n };\n break;\n }\n case "decodeKsplat": {\n const { fileBytes, splatEncoding } = args;\n const decoded = unpackKsplat(fileBytes, splatEncoding);\n result = {\n id,\n numSplats: decoded.numSplats,\n packedArray: decoded.packedArray,\n extra: decoded.extra\n };\n break;\n }\n case "decodePcSogs": {\n const { fileBytes, extraFiles, splatEncoding } = args;\n const json = JSON.parse(\n new TextDecoder().decode(fileBytes)\n );\n const decoded = await unpackPcSogs(json, extraFiles, splatEncoding);\n result = {\n id,\n numSplats: decoded.numSplats,\n packedArray: decoded.packedArray,\n extra: decoded.extra\n };\n break;\n }\n case "decodePcSogsZip": {\n const { fileBytes, splatEncoding } = args;\n const decoded = await unpackPcSogsZip(fileBytes, splatEncoding);\n result = {\n id,\n numSplats: decoded.numSplats,\n packedArray: decoded.packedArray,\n extra: decoded.extra\n };\n break;\n }\n case "sortSplats": {\n const { totalSplats, readback, ordering } = args;\n result = {\n id,\n readback,\n ...sortSplats({ totalSplats, readback, ordering })\n };\n break;\n }\n case "sortDoubleSplats": {\n const { numSplats, readback, ordering } = args;\n {\n result = {\n id,\n readback,\n ordering,\n activeSplats: sort_splats(numSplats, readback, ordering)\n };\n }\n break;\n }\n case "sort32Splats": {\n const { numSplats, readback, ordering } = args;\n {\n result = {\n id,\n readback,\n ordering,\n activeSplats: sort32_splats(numSplats, readback, ordering)\n };\n }\n break;\n }\n case "transcodeSpz": {\n const input = args;\n const spzBytes = await transcodeSpz(input);\n result = {\n id,\n fileBytes: spzBytes,\n input\n };\n break;\n }\n default: {\n throw new Error(`Unknown name: ${name}`);\n }\n }\n } catch (e) {\n error = e;\n console.error(error);\n }\n self.postMessage(\n { id, result, error },\n { transfer: getArrayBuffers(result) }\n );\n }\n async function unpackPly({\n packedArray,\n fileBytes,\n splatEncoding\n }) {\n const ply = new PlyReader({ fileBytes });\n await ply.parseHeader();\n const numSplats = ply.numSplats;\n const extra = {};\n ply.parseSplats(\n (index, x2, y, z, scaleX, scaleY, scaleZ, quatX, quatY, quatZ, quatW, opacity, r, g, b) => {\n setPackedSplat(\n packedArray,\n index,\n x2,\n y,\n z,\n scaleX,\n scaleY,\n scaleZ,\n quatX,\n quatY,\n quatZ,\n quatW,\n opacity,\n r,\n g,\n b,\n splatEncoding\n );\n },\n (index, sh1, sh2, sh3) => {\n if (sh1) {\n if (!extra.sh1) {\n extra.sh1 = new Uint32Array(numSplats * 2);\n }\n encodeSh1Rgb(extra.sh1, index, sh1, splatEncoding);\n }\n if (sh2) {\n if (!extra.sh2) {\n extra.sh2 = new Uint32Array(numSplats * 4);\n }\n encodeSh2Rgb(extra.sh2, index, sh2, splatEncoding);\n }\n if (sh3) {\n if (!extra.sh3) {\n extra.sh3 = new Uint32Array(numSplats * 4);\n }\n encodeSh3Rgb(extra.sh3, index, sh3, splatEncoding);\n }\n }\n );\n return { packedArray, numSplats, extra };\n }\n function unpackSpz(fileBytes, splatEncoding) {\n const spz = new SpzReader({ fileBytes });\n const numSplats = spz.numSplats;\n const maxSplats = computeMaxSplats(numSplats);\n const packedArray = new Uint32Array(maxSplats * 4);\n const extra = {};\n spz.parseSplats(\n (index, x2, y, z) => {\n setPackedSplatCenter(packedArray, index, x2, y, z);\n },\n (index, alpha) => {\n setPackedSplatOpacity(packedArray, index, alpha);\n },\n (index, r, g, b) => {\n setPackedSplatRgb(packedArray, index, r, g, b, splatEncoding);\n },\n (index, scaleX, scaleY, scaleZ) => {\n setPackedSplatScales(\n packedArray,\n index,\n scaleX,\n scaleY,\n scaleZ,\n splatEncoding\n );\n },\n (index, quatX, quatY, quatZ, quatW) => {\n setPackedSplatQuat(packedArray, index, quatX, quatY, quatZ, quatW);\n },\n (index, sh1, sh2, sh3) => {\n if (sh1) {\n if (!extra.sh1) {\n extra.sh1 = new Uint32Array(numSplats * 2);\n }\n encodeSh1Rgb(extra.sh1, index, sh1, splatEncoding);\n }\n if (sh2) {\n if (!extra.sh2) {\n extra.sh2 = new Uint32Array(numSplats * 4);\n }\n encodeSh2Rgb(extra.sh2, index, sh2, splatEncoding);\n }\n if (sh3) {\n if (!extra.sh3) {\n extra.sh3 = new Uint32Array(numSplats * 4);\n }\n encodeSh3Rgb(extra.sh3, index, sh3, splatEncoding);\n }\n }\n );\n return { packedArray, numSplats, extra };\n }\n const DEPTH_INFINITY_F16 = 31744;\n const DEPTH_SIZE_16 = DEPTH_INFINITY_F16 + 1;\n let depthArray16 = null;\n function sortSplats({\n totalSplats,\n readback,\n ordering\n }) {\n if (!depthArray16) {\n depthArray16 = new Uint32Array(DEPTH_SIZE_16);\n }\n depthArray16.fill(0);\n const readbackUint32 = readback.map((layer) => new Uint32Array(layer.buffer));\n const layerSize = readbackUint32[0].length;\n const numLayers = Math.ceil(totalSplats / layerSize);\n let layerBase = 0;\n for (let layer = 0; layer < numLayers; ++layer) {\n const readbackLayer = readbackUint32[layer];\n const layerSplats = Math.min(readbackLayer.length, totalSplats - layerBase);\n for (let i2 = 0; i2 < layerSplats; ++i2) {\n const pri = readbackLayer[i2] & 32767;\n if (pri < DEPTH_INFINITY_F16) {\n depthArray16[pri] += 1;\n }\n }\n layerBase += layerSplats;\n }\n let activeSplats = 0;\n for (let j = 0; j < DEPTH_SIZE_16; ++j) {\n const nextIndex = activeSplats + depthArray16[j];\n depthArray16[j] = activeSplats;\n activeSplats = nextIndex;\n }\n layerBase = 0;\n for (let layer = 0; layer < numLayers; ++layer) {\n const readbackLayer = readbackUint32[layer];\n const layerSplats = Math.min(readbackLayer.length, totalSplats - layerBase);\n for (let i2 = 0; i2 < layerSplats; ++i2) {\n const pri = readbackLayer[i2] & 32767;\n if (pri < DEPTH_INFINITY_F16) {\n ordering[depthArray16[pri]] = layerBase + i2;\n depthArray16[pri] += 1;\n }\n }\n layerBase += layerSplats;\n }\n if (depthArray16[DEPTH_SIZE_16 - 1] !== activeSplats) {\n throw new Error(\n `Expected ${activeSplats} active splats but got ${depthArray16[DEPTH_SIZE_16 - 1]}`\n );\n }\n return { activeSplats, ordering };\n }\n const messageBuffer = [];\n function bufferMessage(event) {\n messageBuffer.push(event);\n }\n async function initialize() {\n self.addEventListener("message", bufferMessage);\n await __wbg_init();\n self.removeEventListener("message", bufferMessage);\n self.addEventListener("message", onMessage);\n for (const event of messageBuffer) {\n onMessage(event);\n }\n messageBuffer.length = 0;\n }\n initialize().catch(console.error);\n})();\n//# sourceMappingURL=worker-erPBjhH-.js.map\n';
|
|
8583
|
+
const jsContent = '(function() {\n "use strict";\n let wasm;\n const cachedTextDecoder = typeof TextDecoder !== "undefined" ? new TextDecoder("utf-8", { ignoreBOM: true, fatal: true }) : { decode: () => {\n throw Error("TextDecoder not available");\n } };\n if (typeof TextDecoder !== "undefined") {\n cachedTextDecoder.decode();\n }\n let cachedUint8ArrayMemory0 = null;\n function getUint8ArrayMemory0() {\n if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {\n cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);\n }\n return cachedUint8ArrayMemory0;\n }\n function getStringFromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));\n }\n function sort_splats(num_splats, readback, ordering) {\n const ret = wasm.sort_splats(num_splats, readback, ordering);\n return ret >>> 0;\n }\n function sort32_splats(num_splats, readback, ordering) {\n const ret = wasm.sort32_splats(num_splats, readback, ordering);\n return ret >>> 0;\n }\n async function __wbg_load(module, imports) {\n if (typeof Response === "function" && module instanceof Response) {\n if (typeof WebAssembly.instantiateStreaming === "function") {\n try {\n return await WebAssembly.instantiateStreaming(module, imports);\n } catch (e) {\n if (module.headers.get("Content-Type") != "application/wasm") {\n console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\\n", e);\n } else {\n throw e;\n }\n }\n }\n const bytes = await module.arrayBuffer();\n return await WebAssembly.instantiate(bytes, imports);\n } else {\n const instance = await WebAssembly.instantiate(module, imports);\n if (instance instanceof WebAssembly.Instance) {\n return { instance, module };\n } else {\n return instance;\n }\n }\n }\n function __wbg_get_imports() {\n const imports = {};\n imports.wbg = {};\n imports.wbg.__wbg_buffer_609cc3eee51ed158 = function(arg0) {\n const ret = arg0.buffer;\n return ret;\n };\n imports.wbg.__wbg_length_3b4f022188ae8db6 = function(arg0) {\n const ret = arg0.length;\n return ret;\n };\n imports.wbg.__wbg_length_6ca527665d89694d = function(arg0) {\n const ret = arg0.length;\n return ret;\n };\n imports.wbg.__wbg_length_8cfd2c6409af88ad = function(arg0) {\n const ret = arg0.length;\n return ret;\n };\n imports.wbg.__wbg_new_9fee97a409b32b68 = function(arg0) {\n const ret = new Uint16Array(arg0);\n return ret;\n };\n imports.wbg.__wbg_new_e3b321dcfef89fc7 = function(arg0) {\n const ret = new Uint32Array(arg0);\n return ret;\n };\n imports.wbg.__wbg_newwithbyteoffsetandlength_e6b7e69acd4c7354 = function(arg0, arg1, arg2) {\n const ret = new Float32Array(arg0, arg1 >>> 0, arg2 >>> 0);\n return ret;\n };\n imports.wbg.__wbg_newwithbyteoffsetandlength_f1dead44d1fc7212 = function(arg0, arg1, arg2) {\n const ret = new Uint32Array(arg0, arg1 >>> 0, arg2 >>> 0);\n return ret;\n };\n imports.wbg.__wbg_newwithlength_5a5efe313cfd59f1 = function(arg0) {\n const ret = new Float32Array(arg0 >>> 0);\n return ret;\n };\n imports.wbg.__wbg_set_10bad9bee0e9c58b = function(arg0, arg1, arg2) {\n arg0.set(arg1, arg2 >>> 0);\n };\n imports.wbg.__wbg_set_d23661d19148b229 = function(arg0, arg1, arg2) {\n arg0.set(arg1, arg2 >>> 0);\n };\n imports.wbg.__wbg_set_f4f1f0daa30696fc = function(arg0, arg1, arg2) {\n arg0.set(arg1, arg2 >>> 0);\n };\n imports.wbg.__wbg_subarray_3aaeec89bb2544f0 = function(arg0, arg1, arg2) {\n const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);\n return ret;\n };\n imports.wbg.__wbg_subarray_769e1e0f81bb259b = function(arg0, arg1, arg2) {\n const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);\n return ret;\n };\n imports.wbg.__wbindgen_init_externref_table = function() {\n const table = wasm.__wbindgen_export_0;\n const offset = table.grow(4);\n table.set(0, void 0);\n table.set(offset + 0, void 0);\n table.set(offset + 1, null);\n table.set(offset + 2, true);\n table.set(offset + 3, false);\n };\n imports.wbg.__wbindgen_memory = function() {\n const ret = wasm.memory;\n return ret;\n };\n imports.wbg.__wbindgen_throw = function(arg0, arg1) {\n throw new Error(getStringFromWasm0(arg0, arg1));\n };\n return imports;\n }\n function __wbg_finalize_init(instance, module) {\n wasm = instance.exports;\n __wbg_init.__wbindgen_wasm_module = module;\n cachedUint8ArrayMemory0 = null;\n wasm.__wbindgen_start();\n return wasm;\n }\n async function __wbg_init(module_or_path) {\n if (wasm !== void 0) return wasm;\n if (typeof module_or_path !== "undefined") {\n if (Object.getPrototypeOf(module_or_path) === Object.prototype) {\n ({ module_or_path } = module_or_path);\n } else {\n console.warn("using deprecated parameters for the initialization function; pass a single object instead");\n }\n }\n if (typeof module_or_path === "undefined") {\n module_or_path = new URL("data:application/wasm;base64,AGFzbQEAAAABzAEeYAJ/fwF/YAJ/fwBgA39/fwF/YAF/AX9gA39/fwBgAX8AYAV/f39/fwBgA29/fwFvYAV/f39/fwF/YAFvAW9gA29vfwBgAW8Bf2AAAX9gBH9/f38AYAAAYAR/f39/AX9gA39vbwF/YAF/AW9gAAFvYAF9AX1gBn9/f39/fwBgDX19fX19fX19f29/fX0Bb2AGf39/f39/AX9gBX9/fH9/AGAEf3x/fwBgBX9/fX9/AGAEf31/fwBgBX9/fn9/AGAEf35/fwBgAn19AX0C8gQRA3diZx1fX3diZ19idWZmZXJfNjA5Y2MzZWVlNTFlZDE1OAAJA3diZxpfX3diZ19uZXdfOWZlZTk3YTQwOWIzMmI2OAAJA3diZxpfX3diZ19zZXRfZjRmMWYwZGFhMzA2OTZmYwAKA3diZx1fX3diZ19sZW5ndGhfOGNmZDJjNjQwOWFmODhhZAALA3diZzFfX3diZ19uZXd3aXRoYnl0ZW9mZnNldGFuZGxlbmd0aF9mMWRlYWQ0NGQxZmM3MjEyAAcDd2JnGl9fd2JnX25ld19lM2IzMjFkY2ZlZjg5ZmM3AAkDd2JnGl9fd2JnX3NldF9kMjM2NjFkMTkxNDhiMjI5AAoDd2JnHV9fd2JnX2xlbmd0aF82Y2E1Mjc2NjVkODk2OTRkAAsDd2JnMV9fd2JnX25ld3dpdGhieXRlb2Zmc2V0YW5kbGVuZ3RoX2U2YjdlNjlhY2Q0YzczNTQABwN3YmcaX193Ymdfc2V0XzEwYmFkOWJlZTBlOWM1OGIACgN3YmcdX193YmdfbGVuZ3RoXzNiNGYwMjIxODhhZThkYjYACwN3YmcfX193Ymdfc3ViYXJyYXlfNzY5ZTFlMGY4MWJiMjU5YgAHA3diZx9fX3diZ19zdWJhcnJheV8zYWFlZWM4OWJiMjU0NGYwAAcDd2JnJF9fd2JnX25ld3dpdGhsZW5ndGhfNWE1ZWZlMzEzY2ZkNTlmMQARA3diZxBfX3diaW5kZ2VuX3Rocm93AAEDd2JnEV9fd2JpbmRnZW5fbWVtb3J5ABIDd2JnH19fd2JpbmRnZW5faW5pdF9leHRlcm5yZWZfdGFibGUADgNhYAMAAQIIBQQCEwEMAAEBAgAAAQwBBAYFBQQAAQYFFAENBAAGBQQEAQQOAgECAQAIBAAVARYG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ACIDKAIEQXhxRgRAIAMhAgwBCyABQRkgAkEBdmtBACACQR9HG3QhBQNAIAMgBUEddkEEcWpBEGoiBCgCACICRQ0CIAVBAXQhBSACIQMgAigCBEF4cSABRw0ACwsgAigCCCIBIAA2AgwgAiAANgIIIABBADYCGCAAIAI2AgwgACABNgIIDwsgBCAANgIAIAAgAzYCGCAAIAA2AgwgACAANgIIC/MCAQR/IwBBMGsiACQAAkACQEGQksAAKAIARQRAQaiSwAAoAgAhAUGoksAAQQA2AgAgAUUNASAAQRhqIAERBQAgAEEQaiICIABBJGopAgA3AwAgACAAKQIcNwMIIAAoAhghAUGQksAAKAIAIgMNAgJAIANFDQBBlJLAACgCACICRQ0AQZiSwAAoAgAgAkECdBBlC0GUksAAIAE2AgBBkJLAAEEBNgIAQZiSwAAgACkDCDcCAEGgksAAIABBEGopAwA3AgALIABBMGokAEGUksAADwsgAEEANgIoIABBATYCHCAAQaCHwAA2AhggAEIENwIgIABBGGpBiIjAABBDAAsgAEEoaiACKQMANwIAIAAgACkDCDcCICAAIAE2AhwgAEEBNgIYAkAgAEEYaiIBKAIARQ0AIAEoAgQiAkUNACABKAIIIAJBAnQQZQsgAEEANgIoIABBATYCHCAAQaiIwAA2AhggAEIENwIgIAFBsIjAABBDAAuoAgIDfwF+IwBBQGoiAiQAIAEoAgBBgICAgHhGBEAgASgCDCEDIAJBJGoiBEEANgIAIAJCgICAgBA3AhwgAkEwaiADKAIAIgNBCGopAgA3AwAgAkE4aiADQRBqKQIANwMAIAIgAykCADcDKCACQRxqQcCIwAAgAkEoahAYGiACQRhqIAQoAgAiAzYCACACIAIpAhwiBTcDECABQQhqIAM2AgAgASAFNwIACyABKQIAIQUgAUKAgICAEDcCACACQQhqIgMgAUEIaiIBKAIANgIAIAFBADYCAEGxk8AALQAAGiACIAU3AwBBDEEEEF0iAUUEQEEEQQwQbQALIAEgAikDADcCACABQQhqIAMoAgA2AgAgAEHgisAANgIEIAAgATYCACACQUBrJAAL0gECBH8BfiMAQSBrIgMkACABIAEgAmoiAksEQEEAQQAQUgALQQggACgCACIEQQF0IgEgAiABIAJLGyICIAJBCEkb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QQRqrUKAgICA4ACENwMoIAEgAa1CgICAgOAAhDcDICABIAFBIGo2AhAgAUEIakHIj8AAEEMAC2kCAX8BfiMAQTBrIgMkACADIAE2AgQgAyAANgIAIANBAjYCDCADQfyNwAA2AgggA0ICNwIUIANCgICAgOAAIgQgA62ENwMoIAMgBCADQQRqrYQ3AyAgAyADQSBqNgIQIANBCGogAhBDAAtpAgF/AX4jAEEwayIDJAAgAyAANgIAIAMgATYCBCADQQI2AgwgA0H4kcAANgIIIANCAjcCFCADQoCAgIDgACIEIANBBGqthDcDKCADIAQgA62ENwMgIAMgA0EgajYCECADQQhqIAIQQwALZgAjAEEwayIAJABBsJPAAC0AAARAIABBAjYCDCAAQbCKwAA2AgggAEIBNwIUIAAgATYCLCAAIABBLGqtQoCAgIDgAIQ3AyAgACAAQSBqNgIQIABBCGpB0IrAABBDAAsgAEEwaiQAC5QBAgN/AW8jAEEgayIDJAAgAyAAKAIAEHAiBDYCACADIAI2AgQgAiAERwRAIANBADYCCCADIANBBGogA0EIahBAAAsQWyIEEFMiBSUBEAUhBhAbIgIgBiYBIAVBhAFPBEAgBRAtCyACIAAoAgAgAUECdhBkIAJBhAFPBEAgAhAtCyAEQYQBTwRAIAQQLQsgA0EgaiQAC08BAX8jAEEwayIAJAAgAEEBNgIMIABBwI3AADYCCCAAQgE3AhQgACAAQS9qrUKAgICAoAWENwMgIAAgAEEgajYCECAAQQhqQcSBwAAQQwALQQEBfyACIAAoAgAgACgCCCIDa0sEQCAAIAMgAhAlIAAoAgghAwsgACgCBCADaiABIAIQHxogACACIANqNgIIQQALTQECf0Gxk8AALQAAGiABKAIEIQIgASgCACEDQQhBBBBdIgFFBEBBBEEIEG0ACyABIAI2AgQgASADNgIAIABB8IrAADYCBCAAIAE2AgALQQEBfyACIAAoAgAgACgCCCIDa0sEQCAAIAMgAhApIAAoAgghAwsgACgCBCADaiABIAIQHxogACACIANqNgIIQQALQQEBfyMAQSBrIgIkACACQQA2AhAgAkEBNgIEIAJCBDcCCCACQS42AhwgAiAANgIYIAIgAkEYajYCACACIAEQQwALswIBA38gACgCACECIAEoAhwiAEEQcUUE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ZCByZWN1cnNpdmVseSBvciBhZnRlciBiZWluZyBkcm9wcGVkTGF6eSBpbnN0YW5jZSBoYXMgcHJldmlvdXNseSBiZWVuIHBvaXNvbmVkdgMQACoAAAAvVXNlcnMvZG1hcmNvcy8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby02ZjE3ZDIyYmJhMTUwMDFmL29uY2VfY2VsbC0xLjIxLjMvc3JjL2xpYi5ycwCoAxAAXwAAAAgDAAAZAAAAcmVlbnRyYW50IGluaXQAABgEEAAOAAAAqAMQAF8AAAB6AgAADQAAABYAAAAMAAAABAAAABcAAAAYAAAAGQAAAC9ydXN0L2RlcHMvZGxtYWxsb2MtMC4yLjYvc3JjL2RsbWFsbG9jLnJzYXNzZXJ0aW9uIGZhaWxlZDogcHNpemUgPj0gc2l6ZSArIG1pbl9vdmVyaGVhZABYBBAAKQAAAKgEAAAJAAAAYXNzZXJ0aW9uIGZhaWxlZDogcHNpemUgPD0gc2l6ZSArIG1heF9vdmVyaGVhZAAAWAQQACkAAACuBAAADQAAAEFjY2Vzc0Vycm9ybWVtb3J5IGFsbG9jYXRpb24gb2YgIGJ5dGVzIGZhaWxlZAAAAAsFEAAVAAAAIAUQAA0AAABzdGQvc3JjL2FsbG9jLnJzQAUQABAAAABjAQAACQAAABYAAAAMAAAABAAAABoAAAAAAAAACAAAAAQAAAAbAAAAAAAAAAgAAAAEAAAAHAAAAB0AAAAeAAAAHwAAACAAAAAQAAAABAAAACEAAAAiAAAAIwAAACQAAABFcnJvcgAAACUAAAAMAAAABAAAACYAAAAnAAAAKAAAAGNhcGFjaXR5IG92ZXJmbG93AAAA2AUQABEAAABhbGxvYy9zcmMvcmF3X3ZlYy5yc/QFEAAUAAAAGAAAAAUAQaCMwAAL8AUBAAAAKQAAAGEgZm9ybWF0dGluZyB0cmFpdCBpbXBsZW1lbnRhdGlvbiByZXR1cm5lZCBhbiBlcnJvciB3aGVuIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSBkaWQgbm90YWxsb2Mvc3JjL2ZtdC5ycwAAfgYQABAAAAB+AgAADgAAAEJvcnJvd011dEVycm9yYWxyZWFkeSBib3Jyb3dlZDogrgYQABIAAABpbmRleCBvdXQgb2YgYm91bmRzOiB0aGUgbGVuIGlzICBidXQgdGhlIGluZGV4IGlzIAAAyAYQACAAAADoBhAAEgAAAD09IT1tYXRjaGVzYXNzZXJ0aW9uIGBsZWZ0ICByaWdodGAgZmFpbGVkCiAgbGVmdDogCiByaWdodDogABcHEAAQAAAAJwcQABcAAAA+BxAACQAAACByaWdodGAgZmFpbGVkOiAKICBsZWZ0OiAAAAAXBxAAEAAAAGAHEAAQAAAAcAcQAAkAAAA+BxAACQAAADogAAABAAAAAAAAAJwHEAACAAAAfSB9Y29yZS9zcmMvZm10L251bS5ycwAAswcQABMAAABmAAAAFwAAADB4MDAwMTAyMDMwNDA1MDYwNzA4MDkxMDExMTIxMzE0MTUxNjE3MTgxOTIwMjEyMjIzMjQyNTI2MjcyODI5MzAzMTMyMzMzNDM1MzYzNzM4Mzk0MDQxNDI0MzQ0NDU0NjQ3NDg0OTUwNTE1MjUzNTQ1NTU2NTc1ODU5NjA2MTYyNjM2NDY1NjY2NzY4Njk3MDcxNzI3Mzc0NzU3Njc3Nzg3OTgwODE4MjgzODQ4NTg2ODc4ODg5OTA5MTkyOTM5NDk1OTY5Nzk4OTlyYW5nZSBzdGFydCBpbmRleCAgb3V0IG9mIHJhbmdlIGZvciBzbGljZSBvZiBsZW5ndGggAACiCBAAEgAAALQIEAAiAAAAcmFuZ2UgZW5kIGluZGV4IOgIEAAQAAAAtAgQACIAAAAAAAA/AAAAvwBBqJLAAAsBFABwCXByb2R1Y2VycwIIbGFuZ3VhZ2UBBFJ1c3QADHByb2Nlc3NlZC1ieQMFcnVzdGMdMS44My4wICg5MGIzNWE2MjMgMjAyNC0xMS0yNikGd2FscnVzBjAuMjMuMwx3YXNtLWJpbmRnZW4HMC4yLjEwMABJD3RhcmdldF9mZWF0dXJlcwQrD211dGFibGUtZ2xvYmFscysIc2lnbi1leHQrD3JlZmVyZW5jZS10eXBlcysKbXVsdGl2YWx1ZQ==", self.location.href);\n }\n const imports = __wbg_get_imports();\n if (typeof module_or_path === "string" || typeof Request === "function" && module_or_path instanceof Request || typeof URL === "function" && module_or_path instanceof URL) {\n module_or_path = fetch(module_or_path);\n }\n const { instance, module } = await __wbg_load(await module_or_path, imports);\n return __wbg_finalize_init(instance, module);\n }\n var ch2 = {};\n var wk = function(c, id, msg, transfer, cb) {\n var w = new Worker(ch2[id] || (ch2[id] = URL.createObjectURL(new Blob([\n c + \';addEventListener("error",function(e){e=e.error;postMessage({$e$:[e.message,e.code,e.stack]})})\'\n ], { type: "text/javascript" }))));\n w.onmessage = function(e) {\n var d = e.data, ed = d.$e$;\n if (ed) {\n var err2 = new Error(ed[0]);\n err2["code"] = ed[1];\n err2.stack = ed[2];\n cb(err2, null);\n } else\n cb(null, d);\n };\n w.postMessage(msg, transfer);\n return w;\n };\n var u8 = Uint8Array, u16 = Uint16Array, i32 = Int32Array;\n var fleb = new u8([\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 1,\n 1,\n 1,\n 1,\n 2,\n 2,\n 2,\n 2,\n 3,\n 3,\n 3,\n 3,\n 4,\n 4,\n 4,\n 4,\n 5,\n 5,\n 5,\n 5,\n 0,\n /* unused */\n 0,\n 0,\n /* impossible */\n 0\n ]);\n var fdeb = new u8([\n 0,\n 0,\n 0,\n 0,\n 1,\n 1,\n 2,\n 2,\n 3,\n 3,\n 4,\n 4,\n 5,\n 5,\n 6,\n 6,\n 7,\n 7,\n 8,\n 8,\n 9,\n 9,\n 10,\n 10,\n 11,\n 11,\n 12,\n 12,\n 13,\n 13,\n /* unused */\n 0,\n 0\n ]);\n var clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);\n var freb = function(eb, start) {\n var b = new u16(31);\n for (var i2 = 0; i2 < 31; ++i2) {\n b[i2] = start += 1 << eb[i2 - 1];\n }\n var r = new i32(b[30]);\n for (var i2 = 1; i2 < 30; ++i2) {\n for (var j = b[i2]; j < b[i2 + 1]; ++j) {\n r[j] = j - b[i2] << 5 | i2;\n }\n }\n return { b, r };\n };\n var _a = freb(fleb, 2), fl = _a.b, revfl = _a.r;\n fl[28] = 258, revfl[258] = 28;\n var _b = freb(fdeb, 0), fd = _b.b;\n var rev = new u16(32768);\n for (var i = 0; i < 32768; ++i) {\n var x = (i & 43690) >> 1 | (i & 21845) << 1;\n x = (x & 52428) >> 2 | (x & 13107) << 2;\n x = (x & 61680) >> 4 | (x & 3855) << 4;\n rev[i] = ((x & 65280) >> 8 | (x & 255) << 8) >> 1;\n }\n var hMap = function(cd, mb, r) {\n var s = cd.length;\n var i2 = 0;\n var l = new u16(mb);\n for (; i2 < s; ++i2) {\n if (cd[i2])\n ++l[cd[i2] - 1];\n }\n var le = new u16(mb);\n for (i2 = 1; i2 < mb; ++i2) {\n le[i2] = le[i2 - 1] + l[i2 - 1] << 1;\n }\n var co;\n if (r) {\n co = new u16(1 << mb);\n var rvb = 15 - mb;\n for (i2 = 0; i2 < s; ++i2) {\n if (cd[i2]) {\n var sv = i2 << 4 | cd[i2];\n var r_1 = mb - cd[i2];\n var v = le[cd[i2] - 1]++ << r_1;\n for (var m = v | (1 << r_1) - 1; v <= m; ++v) {\n co[rev[v] >> rvb] = sv;\n }\n }\n }\n } else {\n co = new u16(s);\n for (i2 = 0; i2 < s; ++i2) {\n if (cd[i2]) {\n co[i2] = rev[le[cd[i2] - 1]++] >> 15 - cd[i2];\n }\n }\n }\n return co;\n };\n var flt = new u8(288);\n for (var i = 0; i < 144; ++i)\n flt[i] = 8;\n for (var i = 144; i < 256; ++i)\n flt[i] = 9;\n for (var i = 256; i < 280; ++i)\n flt[i] = 7;\n for (var i = 280; i < 288; ++i)\n flt[i] = 8;\n var fdt = new u8(32);\n for (var i = 0; i < 32; ++i)\n fdt[i] = 5;\n var flrm = /* @__PURE__ */ hMap(flt, 9, 1);\n var fdrm = /* @__PURE__ */ hMap(fdt, 5, 1);\n var max = function(a) {\n var m = a[0];\n for (var i2 = 1; i2 < a.length; ++i2) {\n if (a[i2] > m)\n m = a[i2];\n }\n return m;\n };\n var bits = function(d, p, m) {\n var o = p / 8 | 0;\n return (d[o] | d[o + 1] << 8) >> (p & 7) & m;\n };\n var bits16 = function(d, p) {\n var o = p / 8 | 0;\n return (d[o] | d[o + 1] << 8 | d[o + 2] << 16) >> (p & 7);\n };\n var shft = function(p) {\n return (p + 7) / 8 | 0;\n };\n var slc = function(v, s, e) {\n if (s == null || s < 0)\n s = 0;\n if (e == null || e > v.length)\n e = v.length;\n return new u8(v.subarray(s, e));\n };\n var ec = [\n "unexpected EOF",\n "invalid block type",\n "invalid length/literal",\n "invalid distance",\n "stream finished",\n "no stream handler",\n ,\n "no callback",\n "invalid UTF-8 data",\n "extra field too long",\n "date not in range 1980-2099",\n "filename too long",\n "stream finishing",\n "invalid zip data"\n // determined by unknown compression method\n ];\n var err = function(ind, msg, nt) {\n var e = new Error(msg || ec[ind]);\n e.code = ind;\n if (Error.captureStackTrace)\n Error.captureStackTrace(e, err);\n if (!nt)\n throw e;\n return e;\n };\n var inflt = function(dat, st, buf, dict) {\n var sl = dat.length, dl = dict ? dict.length : 0;\n if (!sl || st.f && !st.l)\n return buf || new u8(0);\n var noBuf = !buf;\n var resize = noBuf || st.i != 2;\n var noSt = st.i;\n if (noBuf)\n buf = new u8(sl * 3);\n var cbuf = function(l2) {\n var bl = buf.length;\n if (l2 > bl) {\n var nbuf = new u8(Math.max(bl * 2, l2));\n nbuf.set(buf);\n buf = nbuf;\n }\n };\n var final = st.f || 0, pos = st.p || 0, bt = st.b || 0, lm = st.l, dm = st.d, lbt = st.m, dbt = st.n;\n var tbts = sl * 8;\n do {\n if (!lm) {\n final = bits(dat, pos, 1);\n var type = bits(dat, pos + 1, 3);\n pos += 3;\n if (!type) {\n var s = shft(pos) + 4, l = dat[s - 4] | dat[s - 3] << 8, t = s + l;\n if (t > sl) {\n if (noSt)\n err(0);\n break;\n }\n if (resize)\n cbuf(bt + l);\n buf.set(dat.subarray(s, t), bt);\n st.b = bt += l, st.p = pos = t * 8, st.f = final;\n continue;\n } else if (type == 1)\n lm = flrm, dm = fdrm, lbt = 9, dbt = 5;\n else if (type == 2) {\n var hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;\n var tl = hLit + bits(dat, pos + 5, 31) + 1;\n pos += 14;\n var ldt = new u8(tl);\n var clt = new u8(19);\n for (var i2 = 0; i2 < hcLen; ++i2) {\n clt[clim[i2]] = bits(dat, pos + i2 * 3, 7);\n }\n pos += hcLen * 3;\n var clb = max(clt), clbmsk = (1 << clb) - 1;\n var clm = hMap(clt, clb, 1);\n for (var i2 = 0; i2 < tl; ) {\n var r = clm[bits(dat, pos, clbmsk)];\n pos += r & 15;\n var s = r >> 4;\n if (s < 16) {\n ldt[i2++] = s;\n } else {\n var c = 0, n = 0;\n if (s == 16)\n n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i2 - 1];\n else if (s == 17)\n n = 3 + bits(dat, pos, 7), pos += 3;\n else if (s == 18)\n n = 11 + bits(dat, pos, 127), pos += 7;\n while (n--)\n ldt[i2++] = c;\n }\n }\n var lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit);\n lbt = max(lt);\n dbt = max(dt);\n lm = hMap(lt, lbt, 1);\n dm = hMap(dt, dbt, 1);\n } else\n err(1);\n if (pos > tbts) {\n if (noSt)\n err(0);\n break;\n }\n }\n if (resize)\n cbuf(bt + 131072);\n var lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;\n var lpos = pos;\n for (; ; lpos = pos) {\n var c = lm[bits16(dat, pos) & lms], sym = c >> 4;\n pos += c & 15;\n if (pos > tbts) {\n if (noSt)\n err(0);\n break;\n }\n if (!c)\n err(2);\n if (sym < 256)\n buf[bt++] = sym;\n else if (sym == 256) {\n lpos = pos, lm = null;\n break;\n } else {\n var add = sym - 254;\n if (sym > 264) {\n var i2 = sym - 257, b = fleb[i2];\n add = bits(dat, pos, (1 << b) - 1) + fl[i2];\n pos += b;\n }\n var d = dm[bits16(dat, pos) & dms], dsym = d >> 4;\n if (!d)\n err(3);\n pos += d & 15;\n var dt = fd[dsym];\n if (dsym > 3) {\n var b = fdeb[dsym];\n dt += bits16(dat, pos) & (1 << b) - 1, pos += b;\n }\n if (pos > tbts) {\n if (noSt)\n err(0);\n break;\n }\n if (resize)\n cbuf(bt + 131072);\n var end = bt + add;\n if (bt < dt) {\n var shift = dl - dt, dend = Math.min(dt, end);\n if (shift + bt < 0)\n err(3);\n for (; bt < dend; ++bt)\n buf[bt] = dict[shift + bt];\n }\n for (; bt < end; ++bt)\n buf[bt] = buf[bt - dt];\n }\n }\n st.l = lm, st.p = lpos, st.b = bt, st.f = final;\n if (lm)\n final = 1, st.m = lbt, st.d = dm, st.n = dbt;\n } while (!final);\n return bt != buf.length && noBuf ? slc(buf, 0, bt) : buf.subarray(0, bt);\n };\n var et = /* @__PURE__ */ new u8(0);\n var mrg = function(a, b) {\n var o = {};\n for (var k in a)\n o[k] = a[k];\n for (var k in b)\n o[k] = b[k];\n return o;\n };\n var wcln = function(fn, fnStr, td2) {\n var dt = fn();\n var st = fn.toString();\n var ks = st.slice(st.indexOf("[") + 1, st.lastIndexOf("]")).replace(/\\s+/g, "").split(",");\n for (var i2 = 0; i2 < dt.length; ++i2) {\n var v = dt[i2], k = ks[i2];\n if (typeof v == "function") {\n fnStr += ";" + k + "=";\n var st_1 = v.toString();\n if (v.prototype) {\n if (st_1.indexOf("[native code]") != -1) {\n var spInd = st_1.indexOf(" ", 8) + 1;\n fnStr += st_1.slice(spInd, st_1.indexOf("(", spInd));\n } else {\n fnStr += st_1;\n for (var t in v.prototype)\n fnStr += ";" + k + ".prototype." + t + "=" + v.prototype[t].toString();\n }\n } else\n fnStr += st_1;\n } else\n td2[k] = v;\n }\n return fnStr;\n };\n var ch = [];\n var cbfs = function(v) {\n var tl = [];\n for (var k in v) {\n if (v[k].buffer) {\n tl.push((v[k] = new v[k].constructor(v[k])).buffer);\n }\n }\n return tl;\n };\n var wrkr = function(fns, init, id, cb) {\n if (!ch[id]) {\n var fnStr = "", td_1 = {}, m = fns.length - 1;\n for (var i2 = 0; i2 < m; ++i2)\n fnStr = wcln(fns[i2], fnStr, td_1);\n ch[id] = { c: wcln(fns[m], fnStr, td_1), e: td_1 };\n }\n var td2 = mrg({}, ch[id].e);\n return wk(ch[id].c + ";onmessage=function(e){for(var k in e.data)self[k]=e.data[k];onmessage=" + init.toString() + "}", id, td2, cbfs(td2), cb);\n };\n var bInflt = function() {\n return [u8, u16, i32, fleb, fdeb, clim, fl, fd, flrm, fdrm, rev, ec, hMap, max, bits, bits16, shft, slc, err, inflt, inflateSync, pbf, gopt];\n };\n var pbf = function(msg) {\n return postMessage(msg, [msg.buffer]);\n };\n var gopt = function(o) {\n return o && {\n out: o.size && new u8(o.size),\n dictionary: o.dictionary\n };\n };\n var cbify = function(dat, opts, fns, init, id, cb) {\n var w = wrkr(fns, init, id, function(err2, dat2) {\n w.terminate();\n cb(err2, dat2);\n });\n w.postMessage([dat, opts], opts.consume ? [dat.buffer] : []);\n return function() {\n w.terminate();\n };\n };\n var b2 = function(d, b) {\n return d[b] | d[b + 1] << 8;\n };\n var b4 = function(d, b) {\n return (d[b] | d[b + 1] << 8 | d[b + 2] << 16 | d[b + 3] << 24) >>> 0;\n };\n var b8 = function(d, b) {\n return b4(d, b) + b4(d, b + 4) * 4294967296;\n };\n var gzs = function(d) {\n if (d[0] != 31 || d[1] != 139 || d[2] != 8)\n err(6, "invalid gzip data");\n var flg = d[3];\n var st = 10;\n if (flg & 4)\n st += (d[10] | d[11] << 8) + 2;\n for (var zs = (flg >> 3 & 1) + (flg >> 4 & 1); zs > 0; zs -= !d[st++])\n ;\n return st + (flg & 2);\n };\n var Inflate = /* @__PURE__ */ function() {\n function Inflate2(opts, cb) {\n if (typeof opts == "function")\n cb = opts, opts = {};\n this.ondata = cb;\n var dict = opts && opts.dictionary && opts.dictionary.subarray(-32768);\n this.s = { i: 0, b: dict ? dict.length : 0 };\n this.o = new u8(32768);\n this.p = new u8(0);\n if (dict)\n this.o.set(dict);\n }\n Inflate2.prototype.e = function(c) {\n if (!this.ondata)\n err(5);\n if (this.d)\n err(4);\n if (!this.p.length)\n this.p = c;\n else if (c.length) {\n var n = new u8(this.p.length + c.length);\n n.set(this.p), n.set(c, this.p.length), this.p = n;\n }\n };\n Inflate2.prototype.c = function(final) {\n this.s.i = +(this.d = final || false);\n var bts = this.s.b;\n var dt = inflt(this.p, this.s, this.o);\n this.ondata(slc(dt, bts, this.s.b), this.d);\n this.o = slc(dt, this.s.b - 32768), this.s.b = this.o.length;\n this.p = slc(this.p, this.s.p / 8 | 0), this.s.p &= 7;\n };\n Inflate2.prototype.push = function(chunk, final) {\n this.e(chunk), this.c(final);\n };\n return Inflate2;\n }();\n function inflate(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != "function")\n err(7);\n return cbify(data, opts, [\n bInflt\n ], function(ev) {\n return pbf(inflateSync(ev.data[0], gopt(ev.data[1])));\n }, 1, cb);\n }\n function inflateSync(data, opts) {\n return inflt(data, { i: 2 }, opts && opts.out, opts && opts.dictionary);\n }\n var Gunzip = /* @__PURE__ */ function() {\n function Gunzip2(opts, cb) {\n this.v = 1;\n this.r = 0;\n Inflate.call(this, opts, cb);\n }\n Gunzip2.prototype.push = function(chunk, final) {\n Inflate.prototype.e.call(this, chunk);\n this.r += chunk.length;\n if (this.v) {\n var p = this.p.subarray(this.v - 1);\n var s = p.length > 3 ? gzs(p) : 4;\n if (s > p.length) {\n if (!final)\n return;\n } else if (this.v > 1 && this.onmember) {\n this.onmember(this.r - p.length);\n }\n this.p = p.subarray(s), this.v = 0;\n }\n Inflate.prototype.c.call(this, final);\n if (this.s.f && !this.s.l && !final) {\n this.v = shft(this.s.p) + 9;\n this.s = { i: 0 };\n this.o = new u8(0);\n this.push(new u8(0), final);\n }\n };\n return Gunzip2;\n }();\n var td = typeof TextDecoder != "undefined" && /* @__PURE__ */ new TextDecoder();\n try {\n td.decode(et, { stream: true });\n } catch (e) {\n }\n var dutf8 = function(d) {\n for (var r = "", i2 = 0; ; ) {\n var c = d[i2++];\n var eb = (c > 127) + (c > 223) + (c > 239);\n if (i2 + eb > d.length)\n return { s: r, r: slc(d, i2 - 1) };\n if (!eb)\n r += String.fromCharCode(c);\n else if (eb == 3) {\n c = ((c & 15) << 18 | (d[i2++] & 63) << 12 | (d[i2++] & 63) << 6 | d[i2++] & 63) - 65536, r += String.fromCharCode(55296 | c >> 10, 56320 | c & 1023);\n } else if (eb & 1)\n r += String.fromCharCode((c & 31) << 6 | d[i2++] & 63);\n else\n r += String.fromCharCode((c & 15) << 12 | (d[i2++] & 63) << 6 | d[i2++] & 63);\n }\n };\n function strFromU8(dat, latin1) {\n if (latin1) {\n var r = "";\n for (var i2 = 0; i2 < dat.length; i2 += 16384)\n r += String.fromCharCode.apply(null, dat.subarray(i2, i2 + 16384));\n return r;\n } else if (td) {\n return td.decode(dat);\n } else {\n var _a2 = dutf8(dat), s = _a2.s, r = _a2.r;\n if (r.length)\n err(8);\n return s;\n }\n }\n var slzh = function(d, b) {\n return b + 30 + b2(d, b + 26) + b2(d, b + 28);\n };\n var zh = function(d, b, z) {\n var fnl = b2(d, b + 28), fn = strFromU8(d.subarray(b + 46, b + 46 + fnl), !(b2(d, b + 8) & 2048)), es = b + 46 + fnl, bs = b4(d, b + 20);\n var _a2 = z && bs == 4294967295 ? z64e(d, es) : [bs, b4(d, b + 24), b4(d, b + 42)], sc = _a2[0], su = _a2[1], off = _a2[2];\n return [b2(d, b + 10), sc, su, fn, es + b2(d, b + 30) + b2(d, b + 32), off];\n };\n var z64e = function(d, b) {\n for (; b2(d, b) != 1; b += 4 + b2(d, b + 2))\n ;\n return [b8(d, b + 12), b8(d, b + 4), b8(d, b + 20)];\n };\n var mt = typeof queueMicrotask == "function" ? queueMicrotask : typeof setTimeout == "function" ? setTimeout : function(fn) {\n fn();\n };\n function unzip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != "function")\n err(7);\n var term = [];\n var tAll = function() {\n for (var i3 = 0; i3 < term.length; ++i3)\n term[i3]();\n };\n var files = {};\n var cbd = function(a, b) {\n mt(function() {\n cb(a, b);\n });\n };\n mt(function() {\n cbd = cb;\n });\n var e = data.length - 22;\n for (; b4(data, e) != 101010256; --e) {\n if (!e || data.length - e > 65558) {\n cbd(err(13, 0, 1), null);\n return tAll;\n }\n }\n var lft = b2(data, e + 8);\n if (lft) {\n var c = lft;\n var o = b4(data, e + 16);\n var z = o == 4294967295 || c == 65535;\n if (z) {\n var ze = b4(data, e - 12);\n z = b4(data, ze) == 101075792;\n if (z) {\n c = lft = b4(data, ze + 32);\n o = b4(data, ze + 48);\n }\n }\n var fltr = opts && opts.filter;\n var _loop_3 = function(i3) {\n var _a2 = zh(data, o, z), c_1 = _a2[0], sc = _a2[1], su = _a2[2], fn = _a2[3], no = _a2[4], off = _a2[5], b = slzh(data, off);\n o = no;\n var cbl = function(e2, d) {\n if (e2) {\n tAll();\n cbd(e2, null);\n } else {\n if (d)\n files[fn] = d;\n if (!--lft)\n cbd(null, files);\n }\n };\n if (!fltr || fltr({\n name: fn,\n size: sc,\n originalSize: su,\n compression: c_1\n })) {\n if (!c_1)\n cbl(null, slc(data, b, b + sc));\n else if (c_1 == 8) {\n var infl = data.subarray(b, b + sc);\n if (su < 524288 || sc > 0.8 * su) {\n try {\n cbl(null, inflateSync(infl, { out: new u8(su) }));\n } catch (e2) {\n cbl(e2, null);\n }\n } else\n term.push(inflate(infl, { size: su }, cbl));\n } else\n cbl(err(14, "unknown compression type " + c_1, 1), null);\n } else\n cbl(null, null);\n };\n for (var i2 = 0; i2 < c; ++i2) {\n _loop_3(i2);\n }\n } else\n cbd(null, {});\n return tAll;\n }\n function unzipSync(data, opts) {\n var files = {};\n var e = data.length - 22;\n for (; b4(data, e) != 101010256; --e) {\n if (!e || data.length - e > 65558)\n err(13);\n }\n var c = b2(data, e + 8);\n if (!c)\n return {};\n var o = b4(data, e + 16);\n var z = o == 4294967295 || c == 65535;\n if (z) {\n var ze = b4(data, e - 12);\n z = b4(data, ze) == 101075792;\n if (z) {\n c = b4(data, ze + 32);\n o = b4(data, ze + 48);\n }\n }\n var fltr = opts && opts.filter;\n for (var i2 = 0; i2 < c; ++i2) {\n var _a2 = zh(data, o, z), c_2 = _a2[0], sc = _a2[1], su = _a2[2], fn = _a2[3], no = _a2[4], off = _a2[5], b = slzh(data, off);\n o = no;\n if (!fltr || fltr({\n name: fn,\n size: sc,\n originalSize: su,\n compression: c_2\n })) {\n if (!c_2)\n files[fn] = slc(data, b, b + sc);\n else if (c_2 == 8)\n files[fn] = inflateSync(data.subarray(b, b + sc), { out: new u8(su) });\n else\n err(14, "unknown compression type " + c_2);\n }\n }\n return files;\n }\n /**\n * @license\n * Copyright 2010-2025 Three.js Authors\n * SPDX-License-Identifier: MIT\n */\n const REVISION = "178";\n const NoColorSpace = "";\n const SRGBColorSpace = "srgb";\n const LinearSRGBColorSpace = "srgb-linear";\n const LinearTransfer = "linear";\n const SRGBTransfer = "srgb";\n function clamp(value, min, max2) {\n return Math.max(min, Math.min(max2, value));\n }\n function euclideanModulo(n, m) {\n return (n % m + m) % m;\n }\n function lerp(x2, y, t) {\n return (1 - t) * x2 + t * y;\n }\n class Quaternion {\n /**\n * Constructs a new quaternion.\n *\n * @param {number} [x=0] - The x value of this quaternion.\n * @param {number} [y=0] - The y value of this quaternion.\n * @param {number} [z=0] - The z value of this quaternion.\n * @param {number} [w=1] - The w value of this quaternion.\n */\n constructor(x2 = 0, y = 0, z = 0, w = 1) {\n this.isQuaternion = true;\n this._x = x2;\n this._y = y;\n this._z = z;\n this._w = w;\n }\n /**\n * Interpolates between two quaternions via SLERP. This implementation assumes the\n * quaternion data are managed in flat arrays.\n *\n * @param {Array<number>} dst - The destination array.\n * @param {number} dstOffset - An offset into the destination array.\n * @param {Array<number>} src0 - The source array of the first quaternion.\n * @param {number} srcOffset0 - An offset into the first source array.\n * @param {Array<number>} src1 - The source array of the second quaternion.\n * @param {number} srcOffset1 - An offset into the second source array.\n * @param {number} t - The interpolation factor in the range `[0,1]`.\n * @see {@link Quaternion#slerp}\n */\n static slerpFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t) {\n let x0 = src0[srcOffset0 + 0], y0 = src0[srcOffset0 + 1], z0 = src0[srcOffset0 + 2], w0 = src0[srcOffset0 + 3];\n const x1 = src1[srcOffset1 + 0], y1 = src1[srcOffset1 + 1], z1 = src1[srcOffset1 + 2], w1 = src1[srcOffset1 + 3];\n if (t === 0) {\n dst[dstOffset + 0] = x0;\n dst[dstOffset + 1] = y0;\n dst[dstOffset + 2] = z0;\n dst[dstOffset + 3] = w0;\n return;\n }\n if (t === 1) {\n dst[dstOffset + 0] = x1;\n dst[dstOffset + 1] = y1;\n dst[dstOffset + 2] = z1;\n dst[dstOffset + 3] = w1;\n return;\n }\n if (w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1) {\n let s = 1 - t;\n const cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1, dir = cos >= 0 ? 1 : -1, sqrSin = 1 - cos * cos;\n if (sqrSin > Number.EPSILON) {\n const sin = Math.sqrt(sqrSin), len = Math.atan2(sin, cos * dir);\n s = Math.sin(s * len) / sin;\n t = Math.sin(t * len) / sin;\n }\n const tDir = t * dir;\n x0 = x0 * s + x1 * tDir;\n y0 = y0 * s + y1 * tDir;\n z0 = z0 * s + z1 * tDir;\n w0 = w0 * s + w1 * tDir;\n if (s === 1 - t) {\n const f = 1 / Math.sqrt(x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0);\n x0 *= f;\n y0 *= f;\n z0 *= f;\n w0 *= f;\n }\n }\n dst[dstOffset] = x0;\n dst[dstOffset + 1] = y0;\n dst[dstOffset + 2] = z0;\n dst[dstOffset + 3] = w0;\n }\n /**\n * Multiplies two quaternions. This implementation assumes the quaternion data are managed\n * in flat arrays.\n *\n * @param {Array<number>} dst - The destination array.\n * @param {number} dstOffset - An offset into the destination array.\n * @param {Array<number>} src0 - The source array of the first quaternion.\n * @param {number} srcOffset0 - An offset into the first source array.\n * @param {Array<number>} src1 - The source array of the second quaternion.\n * @param {number} srcOffset1 - An offset into the second source array.\n * @return {Array<number>} The destination array.\n * @see {@link Quaternion#multiplyQuaternions}.\n */\n static multiplyQuaternionsFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1) {\n const x0 = src0[srcOffset0];\n const y0 = src0[srcOffset0 + 1];\n const z0 = src0[srcOffset0 + 2];\n const w0 = src0[srcOffset0 + 3];\n const x1 = src1[srcOffset1];\n const y1 = src1[srcOffset1 + 1];\n const z1 = src1[srcOffset1 + 2];\n const w1 = src1[srcOffset1 + 3];\n dst[dstOffset] = x0 * w1 + w0 * x1 + y0 * z1 - z0 * y1;\n dst[dstOffset + 1] = y0 * w1 + w0 * y1 + z0 * x1 - x0 * z1;\n dst[dstOffset + 2] = z0 * w1 + w0 * z1 + x0 * y1 - y0 * x1;\n dst[dstOffset + 3] = w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1;\n return dst;\n }\n /**\n * The x value of this quaternion.\n *\n * @type {number}\n * @default 0\n */\n get x() {\n return this._x;\n }\n set x(value) {\n this._x = value;\n this._onChangeCallback();\n }\n /**\n * The y value of this quaternion.\n *\n * @type {number}\n * @default 0\n */\n get y() {\n return this._y;\n }\n set y(value) {\n this._y = value;\n this._onChangeCallback();\n }\n /**\n * The z value of this quaternion.\n *\n * @type {number}\n * @default 0\n */\n get z() {\n return this._z;\n }\n set z(value) {\n this._z = value;\n this._onChangeCallback();\n }\n /**\n * The w value of this quaternion.\n *\n * @type {number}\n * @default 1\n */\n get w() {\n return this._w;\n }\n set w(value) {\n this._w = value;\n this._onChangeCallback();\n }\n /**\n * Sets the quaternion components.\n *\n * @param {number} x - The x value of this quaternion.\n * @param {number} y - The y value of this quaternion.\n * @param {number} z - The z value of this quaternion.\n * @param {number} w - The w value of this quaternion.\n * @return {Quaternion} A reference to this quaternion.\n */\n set(x2, y, z, w) {\n this._x = x2;\n this._y = y;\n this._z = z;\n this._w = w;\n this._onChangeCallback();\n return this;\n }\n /**\n * Returns a new quaternion with copied values from this instance.\n *\n * @return {Quaternion} A clone of this instance.\n */\n clone() {\n return new this.constructor(this._x, this._y, this._z, this._w);\n }\n /**\n * Copies the values of the given quaternion to this instance.\n *\n * @param {Quaternion} quaternion - The quaternion to copy.\n * @return {Quaternion} A reference to this quaternion.\n */\n copy(quaternion) {\n this._x = quaternion.x;\n this._y = quaternion.y;\n this._z = quaternion.z;\n this._w = quaternion.w;\n this._onChangeCallback();\n return this;\n }\n /**\n * Sets this quaternion from the rotation specified by the given\n * Euler angles.\n *\n * @param {Euler} euler - The Euler angles.\n * @param {boolean} [update=true] - Whether the internal `onChange` callback should be executed or not.\n * @return {Quaternion} A reference to this quaternion.\n */\n setFromEuler(euler, update = true) {\n const x2 = euler._x, y = euler._y, z = euler._z, order = euler._order;\n const cos = Math.cos;\n const sin = Math.sin;\n const c1 = cos(x2 / 2);\n const c2 = cos(y / 2);\n const c3 = cos(z / 2);\n const s1 = sin(x2 / 2);\n const s2 = sin(y / 2);\n const s3 = sin(z / 2);\n switch (order) {\n case "XYZ":\n this._x = s1 * c2 * c3 + c1 * s2 * s3;\n this._y = c1 * s2 * c3 - s1 * c2 * s3;\n this._z = c1 * c2 * s3 + s1 * s2 * c3;\n this._w = c1 * c2 * c3 - s1 * s2 * s3;\n break;\n case "YXZ":\n this._x = s1 * c2 * c3 + c1 * s2 * s3;\n this._y = c1 * s2 * c3 - s1 * c2 * s3;\n this._z = c1 * c2 * s3 - s1 * s2 * c3;\n this._w = c1 * c2 * c3 + s1 * s2 * s3;\n break;\n case "ZXY":\n this._x = s1 * c2 * c3 - c1 * s2 * s3;\n this._y = c1 * s2 * c3 + s1 * c2 * s3;\n this._z = c1 * c2 * s3 + s1 * s2 * c3;\n this._w = c1 * c2 * c3 - s1 * s2 * s3;\n break;\n case "ZYX":\n this._x = s1 * c2 * c3 - c1 * s2 * s3;\n this._y = c1 * s2 * c3 + s1 * c2 * s3;\n this._z = c1 * c2 * s3 - s1 * s2 * c3;\n this._w = c1 * c2 * c3 + s1 * s2 * s3;\n break;\n case "YZX":\n this._x = s1 * c2 * c3 + c1 * s2 * s3;\n this._y = c1 * s2 * c3 + s1 * c2 * s3;\n this._z = c1 * c2 * s3 - s1 * s2 * c3;\n this._w = c1 * c2 * c3 - s1 * s2 * s3;\n break;\n case "XZY":\n this._x = s1 * c2 * c3 - c1 * s2 * s3;\n this._y = c1 * s2 * c3 - s1 * c2 * s3;\n this._z = c1 * c2 * s3 + s1 * s2 * c3;\n this._w = c1 * c2 * c3 + s1 * s2 * s3;\n break;\n default:\n console.warn("THREE.Quaternion: .setFromEuler() encountered an unknown order: " + order);\n }\n if (update === true) this._onChangeCallback();\n return this;\n }\n /**\n * Sets this quaternion from the given axis and angle.\n *\n * @param {Vector3} axis - The normalized axis.\n * @param {number} angle - The angle in radians.\n * @return {Quaternion} A reference to this quaternion.\n */\n setFromAxisAngle(axis, angle) {\n const halfAngle = angle / 2, s = Math.sin(halfAngle);\n this._x = axis.x * s;\n this._y = axis.y * s;\n this._z = axis.z * s;\n this._w = Math.cos(halfAngle);\n this._onChangeCallback();\n return this;\n }\n /**\n * Sets this quaternion from the given rotation matrix.\n *\n * @param {Matrix4} m - A 4x4 matrix of which the upper 3x3 of matrix is a pure rotation matrix (i.e. unscaled).\n * @return {Quaternion} A reference to this quaternion.\n */\n setFromRotationMatrix(m) {\n const te = m.elements, m11 = te[0], m12 = te[4], m13 = te[8], m21 = te[1], m22 = te[5], m23 = te[9], m31 = te[2], m32 = te[6], m33 = te[10], trace = m11 + m22 + m33;\n if (trace > 0) {\n const s = 0.5 / Math.sqrt(trace + 1);\n this._w = 0.25 / s;\n this._x = (m32 - m23) * s;\n this._y = (m13 - m31) * s;\n this._z = (m21 - m12) * s;\n } else if (m11 > m22 && m11 > m33) {\n const s = 2 * Math.sqrt(1 + m11 - m22 - m33);\n this._w = (m32 - m23) / s;\n this._x = 0.25 * s;\n this._y = (m12 + m21) / s;\n this._z = (m13 + m31) / s;\n } else if (m22 > m33) {\n const s = 2 * Math.sqrt(1 + m22 - m11 - m33);\n this._w = (m13 - m31) / s;\n this._x = (m12 + m21) / s;\n this._y = 0.25 * s;\n this._z = (m23 + m32) / s;\n } else {\n const s = 2 * Math.sqrt(1 + m33 - m11 - m22);\n this._w = (m21 - m12) / s;\n this._x = (m13 + m31) / s;\n this._y = (m23 + m32) / s;\n this._z = 0.25 * s;\n }\n this._onChangeCallback();\n return this;\n }\n /**\n * Sets this quaternion to the rotation required to rotate the direction vector\n * `vFrom` to the direction vector `vTo`.\n *\n * @param {Vector3} vFrom - The first (normalized) direction vector.\n * @param {Vector3} vTo - The second (normalized) direction vector.\n * @return {Quaternion} A reference to this quaternion.\n */\n setFromUnitVectors(vFrom, vTo) {\n let r = vFrom.dot(vTo) + 1;\n if (r < 1e-8) {\n r = 0;\n if (Math.abs(vFrom.x) > Math.abs(vFrom.z)) {\n this._x = -vFrom.y;\n this._y = vFrom.x;\n this._z = 0;\n this._w = r;\n } else {\n this._x = 0;\n this._y = -vFrom.z;\n this._z = vFrom.y;\n this._w = r;\n }\n } else {\n this._x = vFrom.y * vTo.z - vFrom.z * vTo.y;\n this._y = vFrom.z * vTo.x - vFrom.x * vTo.z;\n this._z = vFrom.x * vTo.y - vFrom.y * vTo.x;\n this._w = r;\n }\n return this.normalize();\n }\n /**\n * Returns the angle between this quaternion and the given one in radians.\n *\n * @param {Quaternion} q - The quaternion to compute the angle with.\n * @return {number} The angle in radians.\n */\n angleTo(q) {\n return 2 * Math.acos(Math.abs(clamp(this.dot(q), -1, 1)));\n }\n /**\n * Rotates this quaternion by a given angular step to the given quaternion.\n * The method ensures that the final quaternion will not overshoot `q`.\n *\n * @param {Quaternion} q - The target quaternion.\n * @param {number} step - The angular step in radians.\n * @return {Quaternion} A reference to this quaternion.\n */\n rotateTowards(q, step) {\n const angle = this.angleTo(q);\n if (angle === 0) return this;\n const t = Math.min(1, step / angle);\n this.slerp(q, t);\n return this;\n }\n /**\n * Sets this quaternion to the identity quaternion; that is, to the\n * quaternion that represents "no rotation".\n *\n * @return {Quaternion} A reference to this quaternion.\n */\n identity() {\n return this.set(0, 0, 0, 1);\n }\n /**\n * Inverts this quaternion via {@link Quaternion#conjugate}. The\n * quaternion is assumed to have unit length.\n *\n * @return {Quaternion} A reference to this quaternion.\n */\n invert() {\n return this.conjugate();\n }\n /**\n * Returns the rotational conjugate of this quaternion. The conjugate of a\n * quaternion represents the same rotation in the opposite direction about\n * the rotational axis.\n *\n * @return {Quaternion} A reference to this quaternion.\n */\n conjugate() {\n this._x *= -1;\n this._y *= -1;\n this._z *= -1;\n this._onChangeCallback();\n return this;\n }\n /**\n * Calculates the dot product of this quaternion and the given one.\n *\n * @param {Quaternion} v - The quaternion to compute the dot product with.\n * @return {number} The result of the dot product.\n */\n dot(v) {\n return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;\n }\n /**\n * Computes the squared Euclidean length (straight-line length) of this quaternion,\n * considered as a 4 dimensional vector. This can be useful if you are comparing the\n * lengths of two quaternions, as this is a slightly more efficient calculation than\n * {@link Quaternion#length}.\n *\n * @return {number} The squared Euclidean length.\n */\n lengthSq() {\n return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;\n }\n /**\n * Computes the Euclidean length (straight-line length) of this quaternion,\n * considered as a 4 dimensional vector.\n *\n * @return {number} The Euclidean length.\n */\n length() {\n return Math.sqrt(this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w);\n }\n /**\n * Normalizes this quaternion - that is, calculated the quaternion that performs\n * the same rotation as this one, but has a length equal to `1`.\n *\n * @return {Quaternion} A reference to this quaternion.\n */\n normalize() {\n let l = this.length();\n if (l === 0) {\n this._x = 0;\n this._y = 0;\n this._z = 0;\n this._w = 1;\n } else {\n l = 1 / l;\n this._x = this._x * l;\n this._y = this._y * l;\n this._z = this._z * l;\n this._w = this._w * l;\n }\n this._onChangeCallback();\n return this;\n }\n /**\n * Multiplies this quaternion by the given one.\n *\n * @param {Quaternion} q - The quaternion.\n * @return {Quaternion} A reference to this quaternion.\n */\n multiply(q) {\n return this.multiplyQuaternions(this, q);\n }\n /**\n * Pre-multiplies this quaternion by the given one.\n *\n * @param {Quaternion} q - The quaternion.\n * @return {Quaternion} A reference to this quaternion.\n */\n premultiply(q) {\n return this.multiplyQuaternions(q, this);\n }\n /**\n * Multiplies the given quaternions and stores the result in this instance.\n *\n * @param {Quaternion} a - The first quaternion.\n * @param {Quaternion} b - The second quaternion.\n * @return {Quaternion} A reference to this quaternion.\n */\n multiplyQuaternions(a, b) {\n const qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;\n const qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;\n this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;\n this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;\n this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;\n this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;\n this._onChangeCallback();\n return this;\n }\n /**\n * Performs a spherical linear interpolation between quaternions.\n *\n * @param {Quaternion} qb - The target quaternion.\n * @param {number} t - The interpolation factor in the closed interval `[0, 1]`.\n * @return {Quaternion} A reference to this quaternion.\n */\n slerp(qb, t) {\n if (t === 0) return this;\n if (t === 1) return this.copy(qb);\n const x2 = this._x, y = this._y, z = this._z, w = this._w;\n let cosHalfTheta = w * qb._w + x2 * qb._x + y * qb._y + z * qb._z;\n if (cosHalfTheta < 0) {\n this._w = -qb._w;\n this._x = -qb._x;\n this._y = -qb._y;\n this._z = -qb._z;\n cosHalfTheta = -cosHalfTheta;\n } else {\n this.copy(qb);\n }\n if (cosHalfTheta >= 1) {\n this._w = w;\n this._x = x2;\n this._y = y;\n this._z = z;\n return this;\n }\n const sqrSinHalfTheta = 1 - cosHalfTheta * cosHalfTheta;\n if (sqrSinHalfTheta <= Number.EPSILON) {\n const s = 1 - t;\n this._w = s * w + t * this._w;\n this._x = s * x2 + t * this._x;\n this._y = s * y + t * this._y;\n this._z = s * z + t * this._z;\n this.normalize();\n return this;\n }\n const sinHalfTheta = Math.sqrt(sqrSinHalfTheta);\n const halfTheta = Math.atan2(sinHalfTheta, cosHalfTheta);\n const ratioA = Math.sin((1 - t) * halfTheta) / sinHalfTheta, ratioB = Math.sin(t * halfTheta) / sinHalfTheta;\n this._w = w * ratioA + this._w * ratioB;\n this._x = x2 * ratioA + this._x * ratioB;\n this._y = y * ratioA + this._y * ratioB;\n this._z = z * ratioA + this._z * ratioB;\n this._onChangeCallback();\n return this;\n }\n /**\n * Performs a spherical linear interpolation between the given quaternions\n * and stores the result in this quaternion.\n *\n * @param {Quaternion} qa - The source quaternion.\n * @param {Quaternion} qb - The target quaternion.\n * @param {number} t - The interpolation factor in the closed interval `[0, 1]`.\n * @return {Quaternion} A reference to this quaternion.\n */\n slerpQuaternions(qa, qb, t) {\n return this.copy(qa).slerp(qb, t);\n }\n /**\n * Sets this quaternion to a uniformly random, normalized quaternion.\n *\n * @return {Quaternion} A reference to this quaternion.\n */\n random() {\n const theta1 = 2 * Math.PI * Math.random();\n const theta2 = 2 * Math.PI * Math.random();\n const x0 = Math.random();\n const r1 = Math.sqrt(1 - x0);\n const r2 = Math.sqrt(x0);\n return this.set(\n r1 * Math.sin(theta1),\n r1 * Math.cos(theta1),\n r2 * Math.sin(theta2),\n r2 * Math.cos(theta2)\n );\n }\n /**\n * Returns `true` if this quaternion is equal with the given one.\n *\n * @param {Quaternion} quaternion - The quaternion to test for equality.\n * @return {boolean} Whether this quaternion is equal with the given one.\n */\n equals(quaternion) {\n return quaternion._x === this._x && quaternion._y === this._y && quaternion._z === this._z && quaternion._w === this._w;\n }\n /**\n * Sets this quaternion\'s components from the given array.\n *\n * @param {Array<number>} array - An array holding the quaternion component values.\n * @param {number} [offset=0] - The offset into the array.\n * @return {Quaternion} A reference to this quaternion.\n */\n fromArray(array, offset = 0) {\n this._x = array[offset];\n this._y = array[offset + 1];\n this._z = array[offset + 2];\n this._w = array[offset + 3];\n this._onChangeCallback();\n return this;\n }\n /**\n * Writes the components of this quaternion to the given array. If no array is provided,\n * the method returns a new instance.\n *\n * @param {Array<number>} [array=[]] - The target array holding the quaternion components.\n * @param {number} [offset=0] - Index of the first element in the array.\n * @return {Array<number>} The quaternion components.\n */\n toArray(array = [], offset = 0) {\n array[offset] = this._x;\n array[offset + 1] = this._y;\n array[offset + 2] = this._z;\n array[offset + 3] = this._w;\n return array;\n }\n /**\n * Sets the components of this quaternion from the given buffer attribute.\n *\n * @param {BufferAttribute} attribute - The buffer attribute holding quaternion data.\n * @param {number} index - The index into the attribute.\n * @return {Quaternion} A reference to this quaternion.\n */\n fromBufferAttribute(attribute, index) {\n this._x = attribute.getX(index);\n this._y = attribute.getY(index);\n this._z = attribute.getZ(index);\n this._w = attribute.getW(index);\n this._onChangeCallback();\n return this;\n }\n /**\n * This methods defines the serialization result of this class. Returns the\n * numerical elements of this quaternion in an array of format `[x, y, z, w]`.\n *\n * @return {Array<number>} The serialized quaternion.\n */\n toJSON() {\n return this.toArray();\n }\n _onChange(callback) {\n this._onChangeCallback = callback;\n return this;\n }\n _onChangeCallback() {\n }\n *[Symbol.iterator]() {\n yield this._x;\n yield this._y;\n yield this._z;\n yield this._w;\n }\n }\n class Vector3 {\n /**\n * Constructs a new 3D vector.\n *\n * @param {number} [x=0] - The x value of this vector.\n * @param {number} [y=0] - The y value of this vector.\n * @param {number} [z=0] - The z value of this vector.\n */\n constructor(x2 = 0, y = 0, z = 0) {\n Vector3.prototype.isVector3 = true;\n this.x = x2;\n this.y = y;\n this.z = z;\n }\n /**\n * Sets the vector components.\n *\n * @param {number} x - The value of the x component.\n * @param {number} y - The value of the y component.\n * @param {number} z - The value of the z component.\n * @return {Vector3} A reference to this vector.\n */\n set(x2, y, z) {\n if (z === void 0) z = this.z;\n this.x = x2;\n this.y = y;\n this.z = z;\n return this;\n }\n /**\n * Sets the vector components to the same value.\n *\n * @param {number} scalar - The value to set for all vector components.\n * @return {Vector3} A reference to this vector.\n */\n setScalar(scalar) {\n this.x = scalar;\n this.y = scalar;\n this.z = scalar;\n return this;\n }\n /**\n * Sets the vector\'s x component to the given value\n *\n * @param {number} x - The value to set.\n * @return {Vector3} A reference to this vector.\n */\n setX(x2) {\n this.x = x2;\n return this;\n }\n /**\n * Sets the vector\'s y component to the given value\n *\n * @param {number} y - The value to set.\n * @return {Vector3} A reference to this vector.\n */\n setY(y) {\n this.y = y;\n return this;\n }\n /**\n * Sets the vector\'s z component to the given value\n *\n * @param {number} z - The value to set.\n * @return {Vector3} A reference to this vector.\n */\n setZ(z) {\n this.z = z;\n return this;\n }\n /**\n * Allows to set a vector component with an index.\n *\n * @param {number} index - The component index. `0` equals to x, `1` equals to y, `2` equals to z.\n * @param {number} value - The value to set.\n * @return {Vector3} A reference to this vector.\n */\n setComponent(index, value) {\n switch (index) {\n case 0:\n this.x = value;\n break;\n case 1:\n this.y = value;\n break;\n case 2:\n this.z = value;\n break;\n default:\n throw new Error("index is out of range: " + index);\n }\n return this;\n }\n /**\n * Returns the value of the vector component which matches the given index.\n *\n * @param {number} index - The component index. `0` equals to x, `1` equals to y, `2` equals to z.\n * @return {number} A vector component value.\n */\n getComponent(index) {\n switch (index) {\n case 0:\n return this.x;\n case 1:\n return this.y;\n case 2:\n return this.z;\n default:\n throw new Error("index is out of range: " + index);\n }\n }\n /**\n * Returns a new vector with copied values from this instance.\n *\n * @return {Vector3} A clone of this instance.\n */\n clone() {\n return new this.constructor(this.x, this.y, this.z);\n }\n /**\n * Copies the values of the given vector to this instance.\n *\n * @param {Vector3} v - The vector to copy.\n * @return {Vector3} A reference to this vector.\n */\n copy(v) {\n this.x = v.x;\n this.y = v.y;\n this.z = v.z;\n return this;\n }\n /**\n * Adds the given vector to this instance.\n *\n * @param {Vector3} v - The vector to add.\n * @return {Vector3} A reference to this vector.\n */\n add(v) {\n this.x += v.x;\n this.y += v.y;\n this.z += v.z;\n return this;\n }\n /**\n * Adds the given scalar value to all components of this instance.\n *\n * @param {number} s - The scalar to add.\n * @return {Vector3} A reference to this vector.\n */\n addScalar(s) {\n this.x += s;\n this.y += s;\n this.z += s;\n return this;\n }\n /**\n * Adds the given vectors and stores the result in this instance.\n *\n * @param {Vector3} a - The first vector.\n * @param {Vector3} b - The second vector.\n * @return {Vector3} A reference to this vector.\n */\n addVectors(a, b) {\n this.x = a.x + b.x;\n this.y = a.y + b.y;\n this.z = a.z + b.z;\n return this;\n }\n /**\n * Adds the given vector scaled by the given factor to this instance.\n *\n * @param {Vector3|Vector4} v - The vector.\n * @param {number} s - The factor that scales `v`.\n * @return {Vector3} A reference to this vector.\n */\n addScaledVector(v, s) {\n this.x += v.x * s;\n this.y += v.y * s;\n this.z += v.z * s;\n return this;\n }\n /**\n * Subtracts the given vector from this instance.\n *\n * @param {Vector3} v - The vector to subtract.\n * @return {Vector3} A reference to this vector.\n */\n sub(v) {\n this.x -= v.x;\n this.y -= v.y;\n this.z -= v.z;\n return this;\n }\n /**\n * Subtracts the given scalar value from all components of this instance.\n *\n * @param {number} s - The scalar to subtract.\n * @return {Vector3} A reference to this vector.\n */\n subScalar(s) {\n this.x -= s;\n this.y -= s;\n this.z -= s;\n return this;\n }\n /**\n * Subtracts the given vectors and stores the result in this instance.\n *\n * @param {Vector3} a - The first vector.\n * @param {Vector3} b - The second vector.\n * @return {Vector3} A reference to this vector.\n */\n subVectors(a, b) {\n this.x = a.x - b.x;\n this.y = a.y - b.y;\n this.z = a.z - b.z;\n return this;\n }\n /**\n * Multiplies the given vector with this instance.\n *\n * @param {Vector3} v - The vector to multiply.\n * @return {Vector3} A reference to this vector.\n */\n multiply(v) {\n this.x *= v.x;\n this.y *= v.y;\n this.z *= v.z;\n return this;\n }\n /**\n * Multiplies the given scalar value with all components of this instance.\n *\n * @param {number} scalar - The scalar to multiply.\n * @return {Vector3} A reference to this vector.\n */\n multiplyScalar(scalar) {\n this.x *= scalar;\n this.y *= scalar;\n this.z *= scalar;\n return this;\n }\n /**\n * Multiplies the given vectors and stores the result in this instance.\n *\n * @param {Vector3} a - The first vector.\n * @param {Vector3} b - The second vector.\n * @return {Vector3} A reference to this vector.\n */\n multiplyVectors(a, b) {\n this.x = a.x * b.x;\n this.y = a.y * b.y;\n this.z = a.z * b.z;\n return this;\n }\n /**\n * Applies the given Euler rotation to this vector.\n *\n * @param {Euler} euler - The Euler angles.\n * @return {Vector3} A reference to this vector.\n */\n applyEuler(euler) {\n return this.applyQuaternion(_quaternion$4.setFromEuler(euler));\n }\n /**\n * Applies a rotation specified by an axis and an angle to this vector.\n *\n * @param {Vector3} axis - A normalized vector representing the rotation axis.\n * @param {number} angle - The angle in radians.\n * @return {Vector3} A reference to this vector.\n */\n applyAxisAngle(axis, angle) {\n return this.applyQuaternion(_quaternion$4.setFromAxisAngle(axis, angle));\n }\n /**\n * Multiplies this vector with the given 3x3 matrix.\n *\n * @param {Matrix3} m - The 3x3 matrix.\n * @return {Vector3} A reference to this vector.\n */\n applyMatrix3(m) {\n const x2 = this.x, y = this.y, z = this.z;\n const e = m.elements;\n this.x = e[0] * x2 + e[3] * y + e[6] * z;\n this.y = e[1] * x2 + e[4] * y + e[7] * z;\n this.z = e[2] * x2 + e[5] * y + e[8] * z;\n return this;\n }\n /**\n * Multiplies this vector by the given normal matrix and normalizes\n * the result.\n *\n * @param {Matrix3} m - The normal matrix.\n * @return {Vector3} A reference to this vector.\n */\n applyNormalMatrix(m) {\n return this.applyMatrix3(m).normalize();\n }\n /**\n * Multiplies this vector (with an implicit 1 in the 4th dimension) by m, and\n * divides by perspective.\n *\n * @param {Matrix4} m - The matrix to apply.\n * @return {Vector3} A reference to this vector.\n */\n applyMatrix4(m) {\n const x2 = this.x, y = this.y, z = this.z;\n const e = m.elements;\n const w = 1 / (e[3] * x2 + e[7] * y + e[11] * z + e[15]);\n this.x = (e[0] * x2 + e[4] * y + e[8] * z + e[12]) * w;\n this.y = (e[1] * x2 + e[5] * y + e[9] * z + e[13]) * w;\n this.z = (e[2] * x2 + e[6] * y + e[10] * z + e[14]) * w;\n return this;\n }\n /**\n * Applies the given Quaternion to this vector.\n *\n * @param {Quaternion} q - The Quaternion.\n * @return {Vector3} A reference to this vector.\n */\n applyQuaternion(q) {\n const vx = this.x, vy = this.y, vz = this.z;\n const qx = q.x, qy = q.y, qz = q.z, qw = q.w;\n const tx = 2 * (qy * vz - qz * vy);\n const ty = 2 * (qz * vx - qx * vz);\n const tz = 2 * (qx * vy - qy * vx);\n this.x = vx + qw * tx + qy * tz - qz * ty;\n this.y = vy + qw * ty + qz * tx - qx * tz;\n this.z = vz + qw * tz + qx * ty - qy * tx;\n return this;\n }\n /**\n * Projects this vector from world space into the camera\'s normalized\n * device coordinate (NDC) space.\n *\n * @param {Camera} camera - The camera.\n * @return {Vector3} A reference to this vector.\n */\n project(camera) {\n return this.applyMatrix4(camera.matrixWorldInverse).applyMatrix4(camera.projectionMatrix);\n }\n /**\n * Unprojects this vector from the camera\'s normalized device coordinate (NDC)\n * space into world space.\n *\n * @param {Camera} camera - The camera.\n * @return {Vector3} A reference to this vector.\n */\n unproject(camera) {\n return this.applyMatrix4(camera.projectionMatrixInverse).applyMatrix4(camera.matrixWorld);\n }\n /**\n * Transforms the direction of this vector by a matrix (the upper left 3 x 3\n * subset of the given 4x4 matrix and then normalizes the result.\n *\n * @param {Matrix4} m - The matrix.\n * @return {Vector3} A reference to this vector.\n */\n transformDirection(m) {\n const x2 = this.x, y = this.y, z = this.z;\n const e = m.elements;\n this.x = e[0] * x2 + e[4] * y + e[8] * z;\n this.y = e[1] * x2 + e[5] * y + e[9] * z;\n this.z = e[2] * x2 + e[6] * y + e[10] * z;\n return this.normalize();\n }\n /**\n * Divides this instance by the given vector.\n *\n * @param {Vector3} v - The vector to divide.\n * @return {Vector3} A reference to this vector.\n */\n divide(v) {\n this.x /= v.x;\n this.y /= v.y;\n this.z /= v.z;\n return this;\n }\n /**\n * Divides this vector by the given scalar.\n *\n * @param {number} scalar - The scalar to divide.\n * @return {Vector3} A reference to this vector.\n */\n divideScalar(scalar) {\n return this.multiplyScalar(1 / scalar);\n }\n /**\n * If this vector\'s x, y or z value is greater than the given vector\'s x, y or z\n * value, replace that value with the corresponding min value.\n *\n * @param {Vector3} v - The vector.\n * @return {Vector3} A reference to this vector.\n */\n min(v) {\n this.x = Math.min(this.x, v.x);\n this.y = Math.min(this.y, v.y);\n this.z = Math.min(this.z, v.z);\n return this;\n }\n /**\n * If this vector\'s x, y or z value is less than the given vector\'s x, y or z\n * value, replace that value with the corresponding max value.\n *\n * @param {Vector3} v - The vector.\n * @return {Vector3} A reference to this vector.\n */\n max(v) {\n this.x = Math.max(this.x, v.x);\n this.y = Math.max(this.y, v.y);\n this.z = Math.max(this.z, v.z);\n return this;\n }\n /**\n * If this vector\'s x, y or z value is greater than the max vector\'s x, y or z\n * value, it is replaced by the corresponding value.\n * If this vector\'s x, y or z value is less than the min vector\'s x, y or z value,\n * it is replaced by the corresponding value.\n *\n * @param {Vector3} min - The minimum x, y and z values.\n * @param {Vector3} max - The maximum x, y and z values in the desired range.\n * @return {Vector3} A reference to this vector.\n */\n clamp(min, max2) {\n this.x = clamp(this.x, min.x, max2.x);\n this.y = clamp(this.y, min.y, max2.y);\n this.z = clamp(this.z, min.z, max2.z);\n return this;\n }\n /**\n * If this vector\'s x, y or z values are greater than the max value, they are\n * replaced by the max value.\n * If this vector\'s x, y or z values are less than the min value, they are\n * replaced by the min value.\n *\n * @param {number} minVal - The minimum value the components will be clamped to.\n * @param {number} maxVal - The maximum value the components will be clamped to.\n * @return {Vector3} A reference to this vector.\n */\n clampScalar(minVal, maxVal) {\n this.x = clamp(this.x, minVal, maxVal);\n this.y = clamp(this.y, minVal, maxVal);\n this.z = clamp(this.z, minVal, maxVal);\n return this;\n }\n /**\n * If this vector\'s length is greater than the max value, it is replaced by\n * the max value.\n * If this vector\'s length is less than the min value, it is replaced by the\n * min value.\n *\n * @param {number} min - The minimum value the vector length will be clamped to.\n * @param {number} max - The maximum value the vector length will be clamped to.\n * @return {Vector3} A reference to this vector.\n */\n clampLength(min, max2) {\n const length = this.length();\n return this.divideScalar(length || 1).multiplyScalar(clamp(length, min, max2));\n }\n /**\n * The components of this vector are rounded down to the nearest integer value.\n *\n * @return {Vector3} A reference to this vector.\n */\n floor() {\n this.x = Math.floor(this.x);\n this.y = Math.floor(this.y);\n this.z = Math.floor(this.z);\n return this;\n }\n /**\n * The components of this vector are rounded up to the nearest integer value.\n *\n * @return {Vector3} A reference to this vector.\n */\n ceil() {\n this.x = Math.ceil(this.x);\n this.y = Math.ceil(this.y);\n this.z = Math.ceil(this.z);\n return this;\n }\n /**\n * The components of this vector are rounded to the nearest integer value\n *\n * @return {Vector3} A reference to this vector.\n */\n round() {\n this.x = Math.round(this.x);\n this.y = Math.round(this.y);\n this.z = Math.round(this.z);\n return this;\n }\n /**\n * The components of this vector are rounded towards zero (up if negative,\n * down if positive) to an integer value.\n *\n * @return {Vector3} A reference to this vector.\n */\n roundToZero() {\n this.x = Math.trunc(this.x);\n this.y = Math.trunc(this.y);\n this.z = Math.trunc(this.z);\n return this;\n }\n /**\n * Inverts this vector - i.e. sets x = -x, y = -y and z = -z.\n *\n * @return {Vector3} A reference to this vector.\n */\n negate() {\n this.x = -this.x;\n this.y = -this.y;\n this.z = -this.z;\n return this;\n }\n /**\n * Calculates the dot product of the given vector with this instance.\n *\n * @param {Vector3} v - The vector to compute the dot product with.\n * @return {number} The result of the dot product.\n */\n dot(v) {\n return this.x * v.x + this.y * v.y + this.z * v.z;\n }\n // TODO lengthSquared?\n /**\n * Computes the square of the Euclidean length (straight-line length) from\n * (0, 0, 0) to (x, y, z). If you are comparing the lengths of vectors, you should\n * compare the length squared instead as it is slightly more efficient to calculate.\n *\n * @return {number} The square length of this vector.\n */\n lengthSq() {\n return this.x * this.x + this.y * this.y + this.z * this.z;\n }\n /**\n * Computes the Euclidean length (straight-line length) from (0, 0, 0) to (x, y, z).\n *\n * @return {number} The length of this vector.\n */\n length() {\n return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);\n }\n /**\n * Computes the Manhattan length of this vector.\n *\n * @return {number} The length of this vector.\n */\n manhattanLength() {\n return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z);\n }\n /**\n * Converts this vector to a unit vector - that is, sets it equal to a vector\n * with the same direction as this one, but with a vector length of `1`.\n *\n * @return {Vector3} A reference to this vector.\n */\n normalize() {\n return this.divideScalar(this.length() || 1);\n }\n /**\n * Sets this vector to a vector with the same direction as this one, but\n * with the specified length.\n *\n * @param {number} length - The new length of this vector.\n * @return {Vector3} A reference to this vector.\n */\n setLength(length) {\n return this.normalize().multiplyScalar(length);\n }\n /**\n * Linearly interpolates between the given vector and this instance, where\n * alpha is the percent distance along the line - alpha = 0 will be this\n * vector, and alpha = 1 will be the given one.\n *\n * @param {Vector3} v - The vector to interpolate towards.\n * @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`.\n * @return {Vector3} A reference to this vector.\n */\n lerp(v, alpha) {\n this.x += (v.x - this.x) * alpha;\n this.y += (v.y - this.y) * alpha;\n this.z += (v.z - this.z) * alpha;\n return this;\n }\n /**\n * Linearly interpolates between the given vectors, where alpha is the percent\n * distance along the line - alpha = 0 will be first vector, and alpha = 1 will\n * be the second one. The result is stored in this instance.\n *\n * @param {Vector3} v1 - The first vector.\n * @param {Vector3} v2 - The second vector.\n * @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`.\n * @return {Vector3} A reference to this vector.\n */\n lerpVectors(v1, v2, alpha) {\n this.x = v1.x + (v2.x - v1.x) * alpha;\n this.y = v1.y + (v2.y - v1.y) * alpha;\n this.z = v1.z + (v2.z - v1.z) * alpha;\n return this;\n }\n /**\n * Calculates the cross product of the given vector with this instance.\n *\n * @param {Vector3} v - The vector to compute the cross product with.\n * @return {Vector3} The result of the cross product.\n */\n cross(v) {\n return this.crossVectors(this, v);\n }\n /**\n * Calculates the cross product of the given vectors and stores the result\n * in this instance.\n *\n * @param {Vector3} a - The first vector.\n * @param {Vector3} b - The second vector.\n * @return {Vector3} A reference to this vector.\n */\n crossVectors(a, b) {\n const ax = a.x, ay = a.y, az = a.z;\n const bx = b.x, by = b.y, bz = b.z;\n this.x = ay * bz - az * by;\n this.y = az * bx - ax * bz;\n this.z = ax * by - ay * bx;\n return this;\n }\n /**\n * Projects this vector onto the given one.\n *\n * @param {Vector3} v - The vector to project to.\n * @return {Vector3} A reference to this vector.\n */\n projectOnVector(v) {\n const denominator = v.lengthSq();\n if (denominator === 0) return this.set(0, 0, 0);\n const scalar = v.dot(this) / denominator;\n return this.copy(v).multiplyScalar(scalar);\n }\n /**\n * Projects this vector onto a plane by subtracting this\n * vector projected onto the plane\'s normal from this vector.\n *\n * @param {Vector3} planeNormal - The plane normal.\n * @return {Vector3} A reference to this vector.\n */\n projectOnPlane(planeNormal) {\n _vector$c.copy(this).projectOnVector(planeNormal);\n return this.sub(_vector$c);\n }\n /**\n * Reflects this vector off a plane orthogonal to the given normal vector.\n *\n * @param {Vector3} normal - The (normalized) normal vector.\n * @return {Vector3} A reference to this vector.\n */\n reflect(normal) {\n return this.sub(_vector$c.copy(normal).multiplyScalar(2 * this.dot(normal)));\n }\n /**\n * Returns the angle between the given vector and this instance in radians.\n *\n * @param {Vector3} v - The vector to compute the angle with.\n * @return {number} The angle in radians.\n */\n angleTo(v) {\n const denominator = Math.sqrt(this.lengthSq() * v.lengthSq());\n if (denominator === 0) return Math.PI / 2;\n const theta = this.dot(v) / denominator;\n return Math.acos(clamp(theta, -1, 1));\n }\n /**\n * Computes the distance from the given vector to this instance.\n *\n * @param {Vector3} v - The vector to compute the distance to.\n * @return {number} The distance.\n */\n distanceTo(v) {\n return Math.sqrt(this.distanceToSquared(v));\n }\n /**\n * Computes the squared distance from the given vector to this instance.\n * If you are just comparing the distance with another distance, you should compare\n * the distance squared instead as it is slightly more efficient to calculate.\n *\n * @param {Vector3} v - The vector to compute the squared distance to.\n * @return {number} The squared distance.\n */\n distanceToSquared(v) {\n const dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;\n return dx * dx + dy * dy + dz * dz;\n }\n /**\n * Computes the Manhattan distance from the given vector to this instance.\n *\n * @param {Vector3} v - The vector to compute the Manhattan distance to.\n * @return {number} The Manhattan distance.\n */\n manhattanDistanceTo(v) {\n return Math.abs(this.x - v.x) + Math.abs(this.y - v.y) + Math.abs(this.z - v.z);\n }\n /**\n * Sets the vector components from the given spherical coordinates.\n *\n * @param {Spherical} s - The spherical coordinates.\n * @return {Vector3} A reference to this vector.\n */\n setFromSpherical(s) {\n return this.setFromSphericalCoords(s.radius, s.phi, s.theta);\n }\n /**\n * Sets the vector components from the given spherical coordinates.\n *\n * @param {number} radius - The radius.\n * @param {number} phi - The phi angle in radians.\n * @param {number} theta - The theta angle in radians.\n * @return {Vector3} A reference to this vector.\n */\n setFromSphericalCoords(radius, phi, theta) {\n const sinPhiRadius = Math.sin(phi) * radius;\n this.x = sinPhiRadius * Math.sin(theta);\n this.y = Math.cos(phi) * radius;\n this.z = sinPhiRadius * Math.cos(theta);\n return this;\n }\n /**\n * Sets the vector components from the given cylindrical coordinates.\n *\n * @param {Cylindrical} c - The cylindrical coordinates.\n * @return {Vector3} A reference to this vector.\n */\n setFromCylindrical(c) {\n return this.setFromCylindricalCoords(c.radius, c.theta, c.y);\n }\n /**\n * Sets the vector components from the given cylindrical coordinates.\n *\n * @param {number} radius - The radius.\n * @param {number} theta - The theta angle in radians.\n * @param {number} y - The y value.\n * @return {Vector3} A reference to this vector.\n */\n setFromCylindricalCoords(radius, theta, y) {\n this.x = radius * Math.sin(theta);\n this.y = y;\n this.z = radius * Math.cos(theta);\n return this;\n }\n /**\n * Sets the vector components to the position elements of the\n * given transformation matrix.\n *\n * @param {Matrix4} m - The 4x4 matrix.\n * @return {Vector3} A reference to this vector.\n */\n setFromMatrixPosition(m) {\n const e = m.elements;\n this.x = e[12];\n this.y = e[13];\n this.z = e[14];\n return this;\n }\n /**\n * Sets the vector components to the scale elements of the\n * given transformation matrix.\n *\n * @param {Matrix4} m - The 4x4 matrix.\n * @return {Vector3} A reference to this vector.\n */\n setFromMatrixScale(m) {\n const sx = this.setFromMatrixColumn(m, 0).length();\n const sy = this.setFromMatrixColumn(m, 1).length();\n const sz = this.setFromMatrixColumn(m, 2).length();\n this.x = sx;\n this.y = sy;\n this.z = sz;\n return this;\n }\n /**\n * Sets the vector components from the specified matrix column.\n *\n * @param {Matrix4} m - The 4x4 matrix.\n * @param {number} index - The column index.\n * @return {Vector3} A reference to this vector.\n */\n setFromMatrixColumn(m, index) {\n return this.fromArray(m.elements, index * 4);\n }\n /**\n * Sets the vector components from the specified matrix column.\n *\n * @param {Matrix3} m - The 3x3 matrix.\n * @param {number} index - The column index.\n * @return {Vector3} A reference to this vector.\n */\n setFromMatrix3Column(m, index) {\n return this.fromArray(m.elements, index * 3);\n }\n /**\n * Sets the vector components from the given Euler angles.\n *\n * @param {Euler} e - The Euler angles to set.\n * @return {Vector3} A reference to this vector.\n */\n setFromEuler(e) {\n this.x = e._x;\n this.y = e._y;\n this.z = e._z;\n return this;\n }\n /**\n * Sets the vector components from the RGB components of the\n * given color.\n *\n * @param {Color} c - The color to set.\n * @return {Vector3} A reference to this vector.\n */\n setFromColor(c) {\n this.x = c.r;\n this.y = c.g;\n this.z = c.b;\n return this;\n }\n /**\n * Returns `true` if this vector is equal with the given one.\n *\n * @param {Vector3} v - The vector to test for equality.\n * @return {boolean} Whether this vector is equal with the given one.\n */\n equals(v) {\n return v.x === this.x && v.y === this.y && v.z === this.z;\n }\n /**\n * Sets this vector\'s x value to be `array[ offset ]`, y value to be `array[ offset + 1 ]`\n * and z value to be `array[ offset + 2 ]`.\n *\n * @param {Array<number>} array - An array holding the vector component values.\n * @param {number} [offset=0] - The offset into the array.\n * @return {Vector3} A reference to this vector.\n */\n fromArray(array, offset = 0) {\n this.x = array[offset];\n this.y = array[offset + 1];\n this.z = array[offset + 2];\n return this;\n }\n /**\n * Writes the components of this vector to the given array. If no array is provided,\n * the method returns a new instance.\n *\n * @param {Array<number>} [array=[]] - The target array holding the vector components.\n * @param {number} [offset=0] - Index of the first element in the array.\n * @return {Array<number>} The vector components.\n */\n toArray(array = [], offset = 0) {\n array[offset] = this.x;\n array[offset + 1] = this.y;\n array[offset + 2] = this.z;\n return array;\n }\n /**\n * Sets the components of this vector from the given buffer attribute.\n *\n * @param {BufferAttribute} attribute - The buffer attribute holding vector data.\n * @param {number} index - The index into the attribute.\n * @return {Vector3} A reference to this vector.\n */\n fromBufferAttribute(attribute, index) {\n this.x = attribute.getX(index);\n this.y = attribute.getY(index);\n this.z = attribute.getZ(index);\n return this;\n }\n /**\n * Sets each component of this vector to a pseudo-random value between `0` and\n * `1`, excluding `1`.\n *\n * @return {Vector3} A reference to this vector.\n */\n random() {\n this.x = Math.random();\n this.y = Math.random();\n this.z = Math.random();\n return this;\n }\n /**\n * Sets this vector to a uniformly random point on a unit sphere.\n *\n * @return {Vector3} A reference to this vector.\n */\n randomDirection() {\n const theta = Math.random() * Math.PI * 2;\n const u = Math.random() * 2 - 1;\n const c = Math.sqrt(1 - u * u);\n this.x = c * Math.cos(theta);\n this.y = u;\n this.z = c * Math.sin(theta);\n return this;\n }\n *[Symbol.iterator]() {\n yield this.x;\n yield this.y;\n yield this.z;\n }\n }\n const _vector$c = /* @__PURE__ */ new Vector3();\n const _quaternion$4 = /* @__PURE__ */ new Quaternion();\n class Matrix3 {\n /**\n * Constructs a new 3x3 matrix. The arguments are supposed to be\n * in row-major order. If no arguments are provided, the constructor\n * initializes the matrix as an identity matrix.\n *\n * @param {number} [n11] - 1-1 matrix element.\n * @param {number} [n12] - 1-2 matrix element.\n * @param {number} [n13] - 1-3 matrix element.\n * @param {number} [n21] - 2-1 matrix element.\n * @param {number} [n22] - 2-2 matrix element.\n * @param {number} [n23] - 2-3 matrix element.\n * @param {number} [n31] - 3-1 matrix element.\n * @param {number} [n32] - 3-2 matrix element.\n * @param {number} [n33] - 3-3 matrix element.\n */\n constructor(n11, n12, n13, n21, n22, n23, n31, n32, n33) {\n Matrix3.prototype.isMatrix3 = true;\n this.elements = [\n 1,\n 0,\n 0,\n 0,\n 1,\n 0,\n 0,\n 0,\n 1\n ];\n if (n11 !== void 0) {\n this.set(n11, n12, n13, n21, n22, n23, n31, n32, n33);\n }\n }\n /**\n * Sets the elements of the matrix.The arguments are supposed to be\n * in row-major order.\n *\n * @param {number} [n11] - 1-1 matrix element.\n * @param {number} [n12] - 1-2 matrix element.\n * @param {number} [n13] - 1-3 matrix element.\n * @param {number} [n21] - 2-1 matrix element.\n * @param {number} [n22] - 2-2 matrix element.\n * @param {number} [n23] - 2-3 matrix element.\n * @param {number} [n31] - 3-1 matrix element.\n * @param {number} [n32] - 3-2 matrix element.\n * @param {number} [n33] - 3-3 matrix element.\n * @return {Matrix3} A reference to this matrix.\n */\n set(n11, n12, n13, n21, n22, n23, n31, n32, n33) {\n const te = this.elements;\n te[0] = n11;\n te[1] = n21;\n te[2] = n31;\n te[3] = n12;\n te[4] = n22;\n te[5] = n32;\n te[6] = n13;\n te[7] = n23;\n te[8] = n33;\n return this;\n }\n /**\n * Sets this matrix to the 3x3 identity matrix.\n *\n * @return {Matrix3} A reference to this matrix.\n */\n identity() {\n this.set(\n 1,\n 0,\n 0,\n 0,\n 1,\n 0,\n 0,\n 0,\n 1\n );\n return this;\n }\n /**\n * Copies the values of the given matrix to this instance.\n *\n * @param {Matrix3} m - The matrix to copy.\n * @return {Matrix3} A reference to this matrix.\n */\n copy(m) {\n const te = this.elements;\n const me = m.elements;\n te[0] = me[0];\n te[1] = me[1];\n te[2] = me[2];\n te[3] = me[3];\n te[4] = me[4];\n te[5] = me[5];\n te[6] = me[6];\n te[7] = me[7];\n te[8] = me[8];\n return this;\n }\n /**\n * Extracts the basis of this matrix into the three axis vectors provided.\n *\n * @param {Vector3} xAxis - The basis\'s x axis.\n * @param {Vector3} yAxis - The basis\'s y axis.\n * @param {Vector3} zAxis - The basis\'s z axis.\n * @return {Matrix3} A reference to this matrix.\n */\n extractBasis(xAxis, yAxis, zAxis) {\n xAxis.setFromMatrix3Column(this, 0);\n yAxis.setFromMatrix3Column(this, 1);\n zAxis.setFromMatrix3Column(this, 2);\n return this;\n }\n /**\n * Set this matrix to the upper 3x3 matrix of the given 4x4 matrix.\n *\n * @param {Matrix4} m - The 4x4 matrix.\n * @return {Matrix3} A reference to this matrix.\n */\n setFromMatrix4(m) {\n const me = m.elements;\n this.set(\n me[0],\n me[4],\n me[8],\n me[1],\n me[5],\n me[9],\n me[2],\n me[6],\n me[10]\n );\n return this;\n }\n /**\n * Post-multiplies this matrix by the given 3x3 matrix.\n *\n * @param {Matrix3} m - The matrix to multiply with.\n * @return {Matrix3} A reference to this matrix.\n */\n multiply(m) {\n return this.multiplyMatrices(this, m);\n }\n /**\n * Pre-multiplies this matrix by the given 3x3 matrix.\n *\n * @param {Matrix3} m - The matrix to multiply with.\n * @return {Matrix3} A reference to this matrix.\n */\n premultiply(m) {\n return this.multiplyMatrices(m, this);\n }\n /**\n * Multiples the given 3x3 matrices and stores the result\n * in this matrix.\n *\n * @param {Matrix3} a - The first matrix.\n * @param {Matrix3} b - The second matrix.\n * @return {Matrix3} A reference to this matrix.\n */\n multiplyMatrices(a, b) {\n const ae = a.elements;\n const be = b.elements;\n const te = this.elements;\n const a11 = ae[0], a12 = ae[3], a13 = ae[6];\n const a21 = ae[1], a22 = ae[4], a23 = ae[7];\n const a31 = ae[2], a32 = ae[5], a33 = ae[8];\n const b11 = be[0], b12 = be[3], b13 = be[6];\n const b21 = be[1], b22 = be[4], b23 = be[7];\n const b31 = be[2], b32 = be[5], b33 = be[8];\n te[0] = a11 * b11 + a12 * b21 + a13 * b31;\n te[3] = a11 * b12 + a12 * b22 + a13 * b32;\n te[6] = a11 * b13 + a12 * b23 + a13 * b33;\n te[1] = a21 * b11 + a22 * b21 + a23 * b31;\n te[4] = a21 * b12 + a22 * b22 + a23 * b32;\n te[7] = a21 * b13 + a22 * b23 + a23 * b33;\n te[2] = a31 * b11 + a32 * b21 + a33 * b31;\n te[5] = a31 * b12 + a32 * b22 + a33 * b32;\n te[8] = a31 * b13 + a32 * b23 + a33 * b33;\n return this;\n }\n /**\n * Multiplies every component of the matrix by the given scalar.\n *\n * @param {number} s - The scalar.\n * @return {Matrix3} A reference to this matrix.\n */\n multiplyScalar(s) {\n const te = this.elements;\n te[0] *= s;\n te[3] *= s;\n te[6] *= s;\n te[1] *= s;\n te[4] *= s;\n te[7] *= s;\n te[2] *= s;\n te[5] *= s;\n te[8] *= s;\n return this;\n }\n /**\n * Computes and returns the determinant of this matrix.\n *\n * @return {number} The determinant.\n */\n determinant() {\n const te = this.elements;\n const a = te[0], b = te[1], c = te[2], d = te[3], e = te[4], f = te[5], g = te[6], h = te[7], i2 = te[8];\n return a * e * i2 - a * f * h - b * d * i2 + b * f * g + c * d * h - c * e * g;\n }\n /**\n * Inverts this matrix, using the [analytic method]{@link https://en.wikipedia.org/wiki/Invertible_matrix#Analytic_solution}.\n * You can not invert with a determinant of zero. If you attempt this, the method produces\n * a zero matrix instead.\n *\n * @return {Matrix3} A reference to this matrix.\n */\n invert() {\n const te = this.elements, n11 = te[0], n21 = te[1], n31 = te[2], n12 = te[3], n22 = te[4], n32 = te[5], n13 = te[6], n23 = te[7], n33 = te[8], t11 = n33 * n22 - n32 * n23, t12 = n32 * n13 - n33 * n12, t13 = n23 * n12 - n22 * n13, det = n11 * t11 + n21 * t12 + n31 * t13;\n if (det === 0) return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0);\n const detInv = 1 / det;\n te[0] = t11 * detInv;\n te[1] = (n31 * n23 - n33 * n21) * detInv;\n te[2] = (n32 * n21 - n31 * n22) * detInv;\n te[3] = t12 * detInv;\n te[4] = (n33 * n11 - n31 * n13) * detInv;\n te[5] = (n31 * n12 - n32 * n11) * detInv;\n te[6] = t13 * detInv;\n te[7] = (n21 * n13 - n23 * n11) * detInv;\n te[8] = (n22 * n11 - n21 * n12) * detInv;\n return this;\n }\n /**\n * Transposes this matrix in place.\n *\n * @return {Matrix3} A reference to this matrix.\n */\n transpose() {\n let tmp;\n const m = this.elements;\n tmp = m[1];\n m[1] = m[3];\n m[3] = tmp;\n tmp = m[2];\n m[2] = m[6];\n m[6] = tmp;\n tmp = m[5];\n m[5] = m[7];\n m[7] = tmp;\n return this;\n }\n /**\n * Computes the normal matrix which is the inverse transpose of the upper\n * left 3x3 portion of the given 4x4 matrix.\n *\n * @param {Matrix4} matrix4 - The 4x4 matrix.\n * @return {Matrix3} A reference to this matrix.\n */\n getNormalMatrix(matrix4) {\n return this.setFromMatrix4(matrix4).invert().transpose();\n }\n /**\n * Transposes this matrix into the supplied array, and returns itself unchanged.\n *\n * @param {Array<number>} r - An array to store the transposed matrix elements.\n * @return {Matrix3} A reference to this matrix.\n */\n transposeIntoArray(r) {\n const m = this.elements;\n r[0] = m[0];\n r[1] = m[3];\n r[2] = m[6];\n r[3] = m[1];\n r[4] = m[4];\n r[5] = m[7];\n r[6] = m[2];\n r[7] = m[5];\n r[8] = m[8];\n return this;\n }\n /**\n * Sets the UV transform matrix from offset, repeat, rotation, and center.\n *\n * @param {number} tx - Offset x.\n * @param {number} ty - Offset y.\n * @param {number} sx - Repeat x.\n * @param {number} sy - Repeat y.\n * @param {number} rotation - Rotation, in radians. Positive values rotate counterclockwise.\n * @param {number} cx - Center x of rotation.\n * @param {number} cy - Center y of rotation\n * @return {Matrix3} A reference to this matrix.\n */\n setUvTransform(tx, ty, sx, sy, rotation, cx, cy) {\n const c = Math.cos(rotation);\n const s = Math.sin(rotation);\n this.set(\n sx * c,\n sx * s,\n -sx * (c * cx + s * cy) + cx + tx,\n -sy * s,\n sy * c,\n -sy * (-s * cx + c * cy) + cy + ty,\n 0,\n 0,\n 1\n );\n return this;\n }\n /**\n * Scales this matrix with the given scalar values.\n *\n * @param {number} sx - The amount to scale in the X axis.\n * @param {number} sy - The amount to scale in the Y axis.\n * @return {Matrix3} A reference to this matrix.\n */\n scale(sx, sy) {\n this.premultiply(_m3.makeScale(sx, sy));\n return this;\n }\n /**\n * Rotates this matrix by the given angle.\n *\n * @param {number} theta - The rotation in radians.\n * @return {Matrix3} A reference to this matrix.\n */\n rotate(theta) {\n this.premultiply(_m3.makeRotation(-theta));\n return this;\n }\n /**\n * Translates this matrix by the given scalar values.\n *\n * @param {number} tx - The amount to translate in the X axis.\n * @param {number} ty - The amount to translate in the Y axis.\n * @return {Matrix3} A reference to this matrix.\n */\n translate(tx, ty) {\n this.premultiply(_m3.makeTranslation(tx, ty));\n return this;\n }\n // for 2D Transforms\n /**\n * Sets this matrix as a 2D translation transform.\n *\n * @param {number|Vector2} x - The amount to translate in the X axis or alternatively a translation vector.\n * @param {number} y - The amount to translate in the Y axis.\n * @return {Matrix3} A reference to this matrix.\n */\n makeTranslation(x2, y) {\n if (x2.isVector2) {\n this.set(\n 1,\n 0,\n x2.x,\n 0,\n 1,\n x2.y,\n 0,\n 0,\n 1\n );\n } else {\n this.set(\n 1,\n 0,\n x2,\n 0,\n 1,\n y,\n 0,\n 0,\n 1\n );\n }\n return this;\n }\n /**\n * Sets this matrix as a 2D rotational transformation.\n *\n * @param {number} theta - The rotation in radians.\n * @return {Matrix3} A reference to this matrix.\n */\n makeRotation(theta) {\n const c = Math.cos(theta);\n const s = Math.sin(theta);\n this.set(\n c,\n -s,\n 0,\n s,\n c,\n 0,\n 0,\n 0,\n 1\n );\n return this;\n }\n /**\n * Sets this matrix as a 2D scale transform.\n *\n * @param {number} x - The amount to scale in the X axis.\n * @param {number} y - The amount to scale in the Y axis.\n * @return {Matrix3} A reference to this matrix.\n */\n makeScale(x2, y) {\n this.set(\n x2,\n 0,\n 0,\n 0,\n y,\n 0,\n 0,\n 0,\n 1\n );\n return this;\n }\n /**\n * Returns `true` if this matrix is equal with the given one.\n *\n * @param {Matrix3} matrix - The matrix to test for equality.\n * @return {boolean} Whether this matrix is equal with the given one.\n */\n equals(matrix) {\n const te = this.elements;\n const me = matrix.elements;\n for (let i2 = 0; i2 < 9; i2++) {\n if (te[i2] !== me[i2]) return false;\n }\n return true;\n }\n /**\n * Sets the elements of the matrix from the given array.\n *\n * @param {Array<number>} array - The matrix elements in column-major order.\n * @param {number} [offset=0] - Index of the first element in the array.\n * @return {Matrix3} A reference to this matrix.\n */\n fromArray(array, offset = 0) {\n for (let i2 = 0; i2 < 9; i2++) {\n this.elements[i2] = array[i2 + offset];\n }\n return this;\n }\n /**\n * Writes the elements of this matrix to the given array. If no array is provided,\n * the method returns a new instance.\n *\n * @param {Array<number>} [array=[]] - The target array holding the matrix elements in column-major order.\n * @param {number} [offset=0] - Index of the first element in the array.\n * @return {Array<number>} The matrix elements in column-major order.\n */\n toArray(array = [], offset = 0) {\n const te = this.elements;\n array[offset] = te[0];\n array[offset + 1] = te[1];\n array[offset + 2] = te[2];\n array[offset + 3] = te[3];\n array[offset + 4] = te[4];\n array[offset + 5] = te[5];\n array[offset + 6] = te[6];\n array[offset + 7] = te[7];\n array[offset + 8] = te[8];\n return array;\n }\n /**\n * Returns a matrix with copied values from this instance.\n *\n * @return {Matrix3} A clone of this instance.\n */\n clone() {\n return new this.constructor().fromArray(this.elements);\n }\n }\n const _m3 = /* @__PURE__ */ new Matrix3();\n const _cache = {};\n function warnOnce(message) {\n if (message in _cache) return;\n _cache[message] = true;\n console.warn(message);\n }\n const LINEAR_REC709_TO_XYZ = /* @__PURE__ */ new Matrix3().set(\n 0.4123908,\n 0.3575843,\n 0.1804808,\n 0.212639,\n 0.7151687,\n 0.0721923,\n 0.0193308,\n 0.1191948,\n 0.9505322\n );\n const XYZ_TO_LINEAR_REC709 = /* @__PURE__ */ new Matrix3().set(\n 3.2409699,\n -1.5373832,\n -0.4986108,\n -0.9692436,\n 1.8759675,\n 0.0415551,\n 0.0556301,\n -0.203977,\n 1.0569715\n );\n function createColorManagement() {\n const ColorManagement2 = {\n enabled: true,\n workingColorSpace: LinearSRGBColorSpace,\n /**\n * Implementations of supported color spaces.\n *\n * Required:\n * - primaries: chromaticity coordinates [ rx ry gx gy bx by ]\n * - whitePoint: reference white [ x y ]\n * - transfer: transfer function (pre-defined)\n * - toXYZ: Matrix3 RGB to XYZ transform\n * - fromXYZ: Matrix3 XYZ to RGB transform\n * - luminanceCoefficients: RGB luminance coefficients\n *\n * Optional:\n * - outputColorSpaceConfig: { drawingBufferColorSpace: ColorSpace }\n * - workingColorSpaceConfig: { unpackColorSpace: ColorSpace }\n *\n * Reference:\n * - https://www.russellcottrell.com/photo/matrixCalculator.htm\n */\n spaces: {},\n convert: function(color, sourceColorSpace, targetColorSpace) {\n if (this.enabled === false || sourceColorSpace === targetColorSpace || !sourceColorSpace || !targetColorSpace) {\n return color;\n }\n if (this.spaces[sourceColorSpace].transfer === SRGBTransfer) {\n color.r = SRGBToLinear(color.r);\n color.g = SRGBToLinear(color.g);\n color.b = SRGBToLinear(color.b);\n }\n if (this.spaces[sourceColorSpace].primaries !== this.spaces[targetColorSpace].primaries) {\n color.applyMatrix3(this.spaces[sourceColorSpace].toXYZ);\n color.applyMatrix3(this.spaces[targetColorSpace].fromXYZ);\n }\n if (this.spaces[targetColorSpace].transfer === SRGBTransfer) {\n color.r = LinearToSRGB(color.r);\n color.g = LinearToSRGB(color.g);\n color.b = LinearToSRGB(color.b);\n }\n return color;\n },\n workingToColorSpace: function(color, targetColorSpace) {\n return this.convert(color, this.workingColorSpace, targetColorSpace);\n },\n colorSpaceToWorking: function(color, sourceColorSpace) {\n return this.convert(color, sourceColorSpace, this.workingColorSpace);\n },\n getPrimaries: function(colorSpace) {\n return this.spaces[colorSpace].primaries;\n },\n getTransfer: function(colorSpace) {\n if (colorSpace === NoColorSpace) return LinearTransfer;\n return this.spaces[colorSpace].transfer;\n },\n getLuminanceCoefficients: function(target, colorSpace = this.workingColorSpace) {\n return target.fromArray(this.spaces[colorSpace].luminanceCoefficients);\n },\n define: function(colorSpaces) {\n Object.assign(this.spaces, colorSpaces);\n },\n // Internal APIs\n _getMatrix: function(targetMatrix, sourceColorSpace, targetColorSpace) {\n return targetMatrix.copy(this.spaces[sourceColorSpace].toXYZ).multiply(this.spaces[targetColorSpace].fromXYZ);\n },\n _getDrawingBufferColorSpace: function(colorSpace) {\n return this.spaces[colorSpace].outputColorSpaceConfig.drawingBufferColorSpace;\n },\n _getUnpackColorSpace: function(colorSpace = this.workingColorSpace) {\n return this.spaces[colorSpace].workingColorSpaceConfig.unpackColorSpace;\n },\n // Deprecated\n fromWorkingColorSpace: function(color, targetColorSpace) {\n warnOnce("THREE.ColorManagement: .fromWorkingColorSpace() has been renamed to .workingToColorSpace().");\n return ColorManagement2.workingToColorSpace(color, targetColorSpace);\n },\n toWorkingColorSpace: function(color, sourceColorSpace) {\n warnOnce("THREE.ColorManagement: .toWorkingColorSpace() has been renamed to .colorSpaceToWorking().");\n return ColorManagement2.colorSpaceToWorking(color, sourceColorSpace);\n }\n };\n const REC709_PRIMARIES = [0.64, 0.33, 0.3, 0.6, 0.15, 0.06];\n const REC709_LUMINANCE_COEFFICIENTS = [0.2126, 0.7152, 0.0722];\n const D65 = [0.3127, 0.329];\n ColorManagement2.define({\n [LinearSRGBColorSpace]: {\n primaries: REC709_PRIMARIES,\n whitePoint: D65,\n transfer: LinearTransfer,\n toXYZ: LINEAR_REC709_TO_XYZ,\n fromXYZ: XYZ_TO_LINEAR_REC709,\n luminanceCoefficients: REC709_LUMINANCE_COEFFICIENTS,\n workingColorSpaceConfig: { unpackColorSpace: SRGBColorSpace },\n outputColorSpaceConfig: { drawingBufferColorSpace: SRGBColorSpace }\n },\n [SRGBColorSpace]: {\n primaries: REC709_PRIMARIES,\n whitePoint: D65,\n transfer: SRGBTransfer,\n toXYZ: LINEAR_REC709_TO_XYZ,\n fromXYZ: XYZ_TO_LINEAR_REC709,\n luminanceCoefficients: REC709_LUMINANCE_COEFFICIENTS,\n outputColorSpaceConfig: { drawingBufferColorSpace: SRGBColorSpace }\n }\n });\n return ColorManagement2;\n }\n const ColorManagement = /* @__PURE__ */ createColorManagement();\n function SRGBToLinear(c) {\n return c < 0.04045 ? c * 0.0773993808 : Math.pow(c * 0.9478672986 + 0.0521327014, 2.4);\n }\n function LinearToSRGB(c) {\n return c < 31308e-7 ? c * 12.92 : 1.055 * Math.pow(c, 0.41666) - 0.055;\n }\n class Box3 {\n /**\n * Constructs a new bounding box.\n *\n * @param {Vector3} [min=(Infinity,Infinity,Infinity)] - A vector representing the lower boundary of the box.\n * @param {Vector3} [max=(-Infinity,-Infinity,-Infinity)] - A vector representing the upper boundary of the box.\n */\n constructor(min = new Vector3(Infinity, Infinity, Infinity), max2 = new Vector3(-Infinity, -Infinity, -Infinity)) {\n this.isBox3 = true;\n this.min = min;\n this.max = max2;\n }\n /**\n * Sets the lower and upper boundaries of this box.\n * Please note that this method only copies the values from the given objects.\n *\n * @param {Vector3} min - The lower boundary of the box.\n * @param {Vector3} max - The upper boundary of the box.\n * @return {Box3} A reference to this bounding box.\n */\n set(min, max2) {\n this.min.copy(min);\n this.max.copy(max2);\n return this;\n }\n /**\n * Sets the upper and lower bounds of this box so it encloses the position data\n * in the given array.\n *\n * @param {Array<number>} array - An array holding 3D position data.\n * @return {Box3} A reference to this bounding box.\n */\n setFromArray(array) {\n this.makeEmpty();\n for (let i2 = 0, il = array.length; i2 < il; i2 += 3) {\n this.expandByPoint(_vector$b.fromArray(array, i2));\n }\n return this;\n }\n /**\n * Sets the upper and lower bounds of this box so it encloses the position data\n * in the given buffer attribute.\n *\n * @param {BufferAttribute} attribute - A buffer attribute holding 3D position data.\n * @return {Box3} A reference to this bounding box.\n */\n setFromBufferAttribute(attribute) {\n this.makeEmpty();\n for (let i2 = 0, il = attribute.count; i2 < il; i2++) {\n this.expandByPoint(_vector$b.fromBufferAttribute(attribute, i2));\n }\n return this;\n }\n /**\n * Sets the upper and lower bounds of this box so it encloses the position data\n * in the given array.\n *\n * @param {Array<Vector3>} points - An array holding 3D position data as instances of {@link Vector3}.\n * @return {Box3} A reference to this bounding box.\n */\n setFromPoints(points) {\n this.makeEmpty();\n for (let i2 = 0, il = points.length; i2 < il; i2++) {\n this.expandByPoint(points[i2]);\n }\n return this;\n }\n /**\n * Centers this box on the given center vector and sets this box\'s width, height and\n * depth to the given size values.\n *\n * @param {Vector3} center - The center of the box.\n * @param {Vector3} size - The x, y and z dimensions of the box.\n * @return {Box3} A reference to this bounding box.\n */\n setFromCenterAndSize(center, size) {\n const halfSize = _vector$b.copy(size).multiplyScalar(0.5);\n this.min.copy(center).sub(halfSize);\n this.max.copy(center).add(halfSize);\n return this;\n }\n /**\n * Computes the world-axis-aligned bounding box for the given 3D object\n * (including its children), accounting for the object\'s, and children\'s,\n * world transforms. The function may result in a larger box than strictly necessary.\n *\n * @param {Object3D} object - The 3D object to compute the bounding box for.\n * @param {boolean} [precise=false] - If set to `true`, the method computes the smallest\n * world-axis-aligned bounding box at the expense of more computation.\n * @return {Box3} A reference to this bounding box.\n */\n setFromObject(object, precise = false) {\n this.makeEmpty();\n return this.expandByObject(object, precise);\n }\n /**\n * Returns a new box with copied values from this instance.\n *\n * @return {Box3} A clone of this instance.\n */\n clone() {\n return new this.constructor().copy(this);\n }\n /**\n * Copies the values of the given box to this instance.\n *\n * @param {Box3} box - The box to copy.\n * @return {Box3} A reference to this bounding box.\n */\n copy(box) {\n this.min.copy(box.min);\n this.max.copy(box.max);\n return this;\n }\n /**\n * Makes this box empty which means in encloses a zero space in 3D.\n *\n * @return {Box3} A reference to this bounding box.\n */\n makeEmpty() {\n this.min.x = this.min.y = this.min.z = Infinity;\n this.max.x = this.max.y = this.max.z = -Infinity;\n return this;\n }\n /**\n * Returns true if this box includes zero points within its bounds.\n * Note that a box with equal lower and upper bounds still includes one\n * point, the one both bounds share.\n *\n * @return {boolean} Whether this box is empty or not.\n */\n isEmpty() {\n return this.max.x < this.min.x || this.max.y < this.min.y || this.max.z < this.min.z;\n }\n /**\n * Returns the center point of this box.\n *\n * @param {Vector3} target - The target vector that is used to store the method\'s result.\n * @return {Vector3} The center point.\n */\n getCenter(target) {\n return this.isEmpty() ? target.set(0, 0, 0) : target.addVectors(this.min, this.max).multiplyScalar(0.5);\n }\n /**\n * Returns the dimensions of this box.\n *\n * @param {Vector3} target - The target vector that is used to store the method\'s result.\n * @return {Vector3} The size.\n */\n getSize(target) {\n return this.isEmpty() ? target.set(0, 0, 0) : target.subVectors(this.max, this.min);\n }\n /**\n * Expands the boundaries of this box to include the given point.\n *\n * @param {Vector3} point - The point that should be included by the bounding box.\n * @return {Box3} A reference to this bounding box.\n */\n expandByPoint(point) {\n this.min.min(point);\n this.max.max(point);\n return this;\n }\n /**\n * Expands this box equilaterally by the given vector. The width of this\n * box will be expanded by the x component of the vector in both\n * directions. The height of this box will be expanded by the y component of\n * the vector in both directions. The depth of this box will be\n * expanded by the z component of the vector in both directions.\n *\n * @param {Vector3} vector - The vector that should expand the bounding box.\n * @return {Box3} A reference to this bounding box.\n */\n expandByVector(vector) {\n this.min.sub(vector);\n this.max.add(vector);\n return this;\n }\n /**\n * Expands each dimension of the box by the given scalar. If negative, the\n * dimensions of the box will be contracted.\n *\n * @param {number} scalar - The scalar value that should expand the bounding box.\n * @return {Box3} A reference to this bounding box.\n */\n expandByScalar(scalar) {\n this.min.addScalar(-scalar);\n this.max.addScalar(scalar);\n return this;\n }\n /**\n * Expands the boundaries of this box to include the given 3D object and\n * its children, accounting for the object\'s, and children\'s, world\n * transforms. The function may result in a larger box than strictly\n * necessary (unless the precise parameter is set to true).\n *\n * @param {Object3D} object - The 3D object that should expand the bounding box.\n * @param {boolean} precise - If set to `true`, the method expands the bounding box\n * as little as necessary at the expense of more computation.\n * @return {Box3} A reference to this bounding box.\n */\n expandByObject(object, precise = false) {\n object.updateWorldMatrix(false, false);\n const geometry = object.geometry;\n if (geometry !== void 0) {\n const positionAttribute = geometry.getAttribute("position");\n if (precise === true && positionAttribute !== void 0 && object.isInstancedMesh !== true) {\n for (let i2 = 0, l = positionAttribute.count; i2 < l; i2++) {\n if (object.isMesh === true) {\n object.getVertexPosition(i2, _vector$b);\n } else {\n _vector$b.fromBufferAttribute(positionAttribute, i2);\n }\n _vector$b.applyMatrix4(object.matrixWorld);\n this.expandByPoint(_vector$b);\n }\n } else {\n if (object.boundingBox !== void 0) {\n if (object.boundingBox === null) {\n object.computeBoundingBox();\n }\n _box$4.copy(object.boundingBox);\n } else {\n if (geometry.boundingBox === null) {\n geometry.computeBoundingBox();\n }\n _box$4.copy(geometry.boundingBox);\n }\n _box$4.applyMatrix4(object.matrixWorld);\n this.union(_box$4);\n }\n }\n const children = object.children;\n for (let i2 = 0, l = children.length; i2 < l; i2++) {\n this.expandByObject(children[i2], precise);\n }\n return this;\n }\n /**\n * Returns `true` if the given point lies within or on the boundaries of this box.\n *\n * @param {Vector3} point - The point to test.\n * @return {boolean} Whether the bounding box contains the given point or not.\n */\n containsPoint(point) {\n return point.x >= this.min.x && point.x <= this.max.x && point.y >= this.min.y && point.y <= this.max.y && point.z >= this.min.z && point.z <= this.max.z;\n }\n /**\n * Returns `true` if this bounding box includes the entirety of the given bounding box.\n * If this box and the given one are identical, this function also returns `true`.\n *\n * @param {Box3} box - The bounding box to test.\n * @return {boolean} Whether the bounding box contains the given bounding box or not.\n */\n containsBox(box) {\n return this.min.x <= box.min.x && box.max.x <= this.max.x && this.min.y <= box.min.y && box.max.y <= this.max.y && this.min.z <= box.min.z && box.max.z <= this.max.z;\n }\n /**\n * Returns a point as a proportion of this box\'s width, height and depth.\n *\n * @param {Vector3} point - A point in 3D space.\n * @param {Vector3} target - The target vector that is used to store the method\'s result.\n * @return {Vector3} A point as a proportion of this box\'s width, height and depth.\n */\n getParameter(point, target) {\n return target.set(\n (point.x - this.min.x) / (this.max.x - this.min.x),\n (point.y - this.min.y) / (this.max.y - this.min.y),\n (point.z - this.min.z) / (this.max.z - this.min.z)\n );\n }\n /**\n * Returns `true` if the given bounding box intersects with this bounding box.\n *\n * @param {Box3} box - The bounding box to test.\n * @return {boolean} Whether the given bounding box intersects with this bounding box.\n */\n intersectsBox(box) {\n return box.max.x >= this.min.x && box.min.x <= this.max.x && box.max.y >= this.min.y && box.min.y <= this.max.y && box.max.z >= this.min.z && box.min.z <= this.max.z;\n }\n /**\n * Returns `true` if the given bounding sphere intersects with this bounding box.\n *\n * @param {Sphere} sphere - The bounding sphere to test.\n * @return {boolean} Whether the given bounding sphere intersects with this bounding box.\n */\n intersectsSphere(sphere) {\n this.clampPoint(sphere.center, _vector$b);\n return _vector$b.distanceToSquared(sphere.center) <= sphere.radius * sphere.radius;\n }\n /**\n * Returns `true` if the given plane intersects with this bounding box.\n *\n * @param {Plane} plane - The plane to test.\n * @return {boolean} Whether the given plane intersects with this bounding box.\n */\n intersectsPlane(plane) {\n let min, max2;\n if (plane.normal.x > 0) {\n min = plane.normal.x * this.min.x;\n max2 = plane.normal.x * this.max.x;\n } else {\n min = plane.normal.x * this.max.x;\n max2 = plane.normal.x * this.min.x;\n }\n if (plane.normal.y > 0) {\n min += plane.normal.y * this.min.y;\n max2 += plane.normal.y * this.max.y;\n } else {\n min += plane.normal.y * this.max.y;\n max2 += plane.normal.y * this.min.y;\n }\n if (plane.normal.z > 0) {\n min += plane.normal.z * this.min.z;\n max2 += plane.normal.z * this.max.z;\n } else {\n min += plane.normal.z * this.max.z;\n max2 += plane.normal.z * this.min.z;\n }\n return min <= -plane.constant && max2 >= -plane.constant;\n }\n /**\n * Returns `true` if the given triangle intersects with this bounding box.\n *\n * @param {Triangle} triangle - The triangle to test.\n * @return {boolean} Whether the given triangle intersects with this bounding box.\n */\n intersectsTriangle(triangle) {\n if (this.isEmpty()) {\n return false;\n }\n this.getCenter(_center);\n _extents.subVectors(this.max, _center);\n _v0$2.subVectors(triangle.a, _center);\n _v1$7.subVectors(triangle.b, _center);\n _v2$4.subVectors(triangle.c, _center);\n _f0.subVectors(_v1$7, _v0$2);\n _f1.subVectors(_v2$4, _v1$7);\n _f2.subVectors(_v0$2, _v2$4);\n let axes = [\n 0,\n -_f0.z,\n _f0.y,\n 0,\n -_f1.z,\n _f1.y,\n 0,\n -_f2.z,\n _f2.y,\n _f0.z,\n 0,\n -_f0.x,\n _f1.z,\n 0,\n -_f1.x,\n _f2.z,\n 0,\n -_f2.x,\n -_f0.y,\n _f0.x,\n 0,\n -_f1.y,\n _f1.x,\n 0,\n -_f2.y,\n _f2.x,\n 0\n ];\n if (!satForAxes(axes, _v0$2, _v1$7, _v2$4, _extents)) {\n return false;\n }\n axes = [1, 0, 0, 0, 1, 0, 0, 0, 1];\n if (!satForAxes(axes, _v0$2, _v1$7, _v2$4, _extents)) {\n return false;\n }\n _triangleNormal.crossVectors(_f0, _f1);\n axes = [_triangleNormal.x, _triangleNormal.y, _triangleNormal.z];\n return satForAxes(axes, _v0$2, _v1$7, _v2$4, _extents);\n }\n /**\n * Clamps the given point within the bounds of this box.\n *\n * @param {Vector3} point - The point to clamp.\n * @param {Vector3} target - The target vector that is used to store the method\'s result.\n * @return {Vector3} The clamped point.\n */\n clampPoint(point, target) {\n return target.copy(point).clamp(this.min, this.max);\n }\n /**\n * Returns the euclidean distance from any edge of this box to the specified point. If\n * the given point lies inside of this box, the distance will be `0`.\n *\n * @param {Vector3} point - The point to compute the distance to.\n * @return {number} The euclidean distance.\n */\n distanceToPoint(point) {\n return this.clampPoint(point, _vector$b).distanceTo(point);\n }\n /**\n * Returns a bounding sphere that encloses this bounding box.\n *\n * @param {Sphere} target - The target sphere that is used to store the method\'s result.\n * @return {Sphere} The bounding sphere that encloses this bounding box.\n */\n getBoundingSphere(target) {\n if (this.isEmpty()) {\n target.makeEmpty();\n } else {\n this.getCenter(target.center);\n target.radius = this.getSize(_vector$b).length() * 0.5;\n }\n return target;\n }\n /**\n * Computes the intersection of this bounding box and the given one, setting the upper\n * bound of this box to the lesser of the two boxes\' upper bounds and the\n * lower bound of this box to the greater of the two boxes\' lower bounds. If\n * there\'s no overlap, makes this box empty.\n *\n * @param {Box3} box - The bounding box to intersect with.\n * @return {Box3} A reference to this bounding box.\n */\n intersect(box) {\n this.min.max(box.min);\n this.max.min(box.max);\n if (this.isEmpty()) this.makeEmpty();\n return this;\n }\n /**\n * Computes the union of this box and another and the given one, setting the upper\n * bound of this box to the greater of the two boxes\' upper bounds and the\n * lower bound of this box to the lesser of the two boxes\' lower bounds.\n *\n * @param {Box3} box - The bounding box that will be unioned with this instance.\n * @return {Box3} A reference to this bounding box.\n */\n union(box) {\n this.min.min(box.min);\n this.max.max(box.max);\n return this;\n }\n /**\n * Transforms this bounding box by the given 4x4 transformation matrix.\n *\n * @param {Matrix4} matrix - The transformation matrix.\n * @return {Box3} A reference to this bounding box.\n */\n applyMatrix4(matrix) {\n if (this.isEmpty()) return this;\n _points[0].set(this.min.x, this.min.y, this.min.z).applyMatrix4(matrix);\n _points[1].set(this.min.x, this.min.y, this.max.z).applyMatrix4(matrix);\n _points[2].set(this.min.x, this.max.y, this.min.z).applyMatrix4(matrix);\n _points[3].set(this.min.x, this.max.y, this.max.z).applyMatrix4(matrix);\n _points[4].set(this.max.x, this.min.y, this.min.z).applyMatrix4(matrix);\n _points[5].set(this.max.x, this.min.y, this.max.z).applyMatrix4(matrix);\n _points[6].set(this.max.x, this.max.y, this.min.z).applyMatrix4(matrix);\n _points[7].set(this.max.x, this.max.y, this.max.z).applyMatrix4(matrix);\n this.setFromPoints(_points);\n return this;\n }\n /**\n * Adds the given offset to both the upper and lower bounds of this bounding box,\n * effectively moving it in 3D space.\n *\n * @param {Vector3} offset - The offset that should be used to translate the bounding box.\n * @return {Box3} A reference to this bounding box.\n */\n translate(offset) {\n this.min.add(offset);\n this.max.add(offset);\n return this;\n }\n /**\n * Returns `true` if this bounding box is equal with the given one.\n *\n * @param {Box3} box - The box to test for equality.\n * @return {boolean} Whether this bounding box is equal with the given one.\n */\n equals(box) {\n return box.min.equals(this.min) && box.max.equals(this.max);\n }\n /**\n * Returns a serialized structure of the bounding box.\n *\n * @return {Object} Serialized structure with fields representing the object state.\n */\n toJSON() {\n return {\n min: this.min.toArray(),\n max: this.max.toArray()\n };\n }\n /**\n * Returns a serialized structure of the bounding box.\n *\n * @param {Object} json - The serialized json to set the box from.\n * @return {Box3} A reference to this bounding box.\n */\n fromJSON(json) {\n this.min.fromArray(json.min);\n this.max.fromArray(json.max);\n return this;\n }\n }\n const _points = [\n /* @__PURE__ */ new Vector3(),\n /* @__PURE__ */ new Vector3(),\n /* @__PURE__ */ new Vector3(),\n /* @__PURE__ */ new Vector3(),\n /* @__PURE__ */ new Vector3(),\n /* @__PURE__ */ new Vector3(),\n /* @__PURE__ */ new Vector3(),\n /* @__PURE__ */ new Vector3()\n ];\n const _vector$b = /* @__PURE__ */ new Vector3();\n const _box$4 = /* @__PURE__ */ new Box3();\n const _v0$2 = /* @__PURE__ */ new Vector3();\n const _v1$7 = /* @__PURE__ */ new Vector3();\n const _v2$4 = /* @__PURE__ */ new Vector3();\n const _f0 = /* @__PURE__ */ new Vector3();\n const _f1 = /* @__PURE__ */ new Vector3();\n const _f2 = /* @__PURE__ */ new Vector3();\n const _center = /* @__PURE__ */ new Vector3();\n const _extents = /* @__PURE__ */ new Vector3();\n const _triangleNormal = /* @__PURE__ */ new Vector3();\n const _testAxis = /* @__PURE__ */ new Vector3();\n function satForAxes(axes, v0, v1, v2, extents) {\n for (let i2 = 0, j = axes.length - 3; i2 <= j; i2 += 3) {\n _testAxis.fromArray(axes, i2);\n const r = extents.x * Math.abs(_testAxis.x) + extents.y * Math.abs(_testAxis.y) + extents.z * Math.abs(_testAxis.z);\n const p0 = v0.dot(_testAxis);\n const p1 = v1.dot(_testAxis);\n const p2 = v2.dot(_testAxis);\n if (Math.max(-Math.max(p0, p1, p2), Math.min(p0, p1, p2)) > r) {\n return false;\n }\n }\n return true;\n }\n const _colorKeywords = {\n "aliceblue": 15792383,\n "antiquewhite": 16444375,\n "aqua": 65535,\n "aquamarine": 8388564,\n "azure": 15794175,\n "beige": 16119260,\n "bisque": 16770244,\n "black": 0,\n "blanchedalmond": 16772045,\n "blue": 255,\n "blueviolet": 9055202,\n "brown": 10824234,\n "burlywood": 14596231,\n "cadetblue": 6266528,\n "chartreuse": 8388352,\n "chocolate": 13789470,\n "coral": 16744272,\n "cornflowerblue": 6591981,\n "cornsilk": 16775388,\n "crimson": 14423100,\n "cyan": 65535,\n "darkblue": 139,\n "darkcyan": 35723,\n "darkgoldenrod": 12092939,\n "darkgray": 11119017,\n "darkgreen": 25600,\n "darkgrey": 11119017,\n "darkkhaki": 12433259,\n "darkmagenta": 9109643,\n "darkolivegreen": 5597999,\n "darkorange": 16747520,\n "darkorchid": 10040012,\n "darkred": 9109504,\n "darksalmon": 15308410,\n "darkseagreen": 9419919,\n "darkslateblue": 4734347,\n "darkslategray": 3100495,\n "darkslategrey": 3100495,\n "darkturquoise": 52945,\n "darkviolet": 9699539,\n "deeppink": 16716947,\n "deepskyblue": 49151,\n "dimgray": 6908265,\n "dimgrey": 6908265,\n "dodgerblue": 2003199,\n "firebrick": 11674146,\n "floralwhite": 16775920,\n "forestgreen": 2263842,\n "fuchsia": 16711935,\n "gainsboro": 14474460,\n "ghostwhite": 16316671,\n "gold": 16766720,\n "goldenrod": 14329120,\n "gray": 8421504,\n "green": 32768,\n "greenyellow": 11403055,\n "grey": 8421504,\n "honeydew": 15794160,\n "hotpink": 16738740,\n "indianred": 13458524,\n "indigo": 4915330,\n "ivory": 16777200,\n "khaki": 15787660,\n "lavender": 15132410,\n "lavenderblush": 16773365,\n "lawngreen": 8190976,\n "lemonchiffon": 16775885,\n "lightblue": 11393254,\n "lightcoral": 15761536,\n "lightcyan": 14745599,\n "lightgoldenrodyellow": 16448210,\n "lightgray": 13882323,\n "lightgreen": 9498256,\n "lightgrey": 13882323,\n "lightpink": 16758465,\n "lightsalmon": 16752762,\n "lightseagreen": 2142890,\n "lightskyblue": 8900346,\n "lightslategray": 7833753,\n "lightslategrey": 7833753,\n "lightsteelblue": 11584734,\n "lightyellow": 16777184,\n "lime": 65280,\n "limegreen": 3329330,\n "linen": 16445670,\n "magenta": 16711935,\n "maroon": 8388608,\n "mediumaquamarine": 6737322,\n "mediumblue": 205,\n "mediumorchid": 12211667,\n "mediumpurple": 9662683,\n "mediumseagreen": 3978097,\n "mediumslateblue": 8087790,\n "mediumspringgreen": 64154,\n "mediumturquoise": 4772300,\n "mediumvioletred": 13047173,\n "midnightblue": 1644912,\n "mintcream": 16121850,\n "mistyrose": 16770273,\n "moccasin": 16770229,\n "navajowhite": 16768685,\n "navy": 128,\n "oldlace": 16643558,\n "olive": 8421376,\n "olivedrab": 7048739,\n "orange": 16753920,\n "orangered": 16729344,\n "orchid": 14315734,\n "palegoldenrod": 15657130,\n "palegreen": 10025880,\n "paleturquoise": 11529966,\n "palevioletred": 14381203,\n "papayawhip": 16773077,\n "peachpuff": 16767673,\n "peru": 13468991,\n "pink": 16761035,\n "plum": 14524637,\n "powderblue": 11591910,\n "purple": 8388736,\n "rebeccapurple": 6697881,\n "red": 16711680,\n "rosybrown": 12357519,\n "royalblue": 4286945,\n "saddlebrown": 9127187,\n "salmon": 16416882,\n "sandybrown": 16032864,\n "seagreen": 3050327,\n "seashell": 16774638,\n "sienna": 10506797,\n "silver": 12632256,\n "skyblue": 8900331,\n "slateblue": 6970061,\n "slategray": 7372944,\n "slategrey": 7372944,\n "snow": 16775930,\n "springgreen": 65407,\n "steelblue": 4620980,\n "tan": 13808780,\n "teal": 32896,\n "thistle": 14204888,\n "tomato": 16737095,\n "turquoise": 4251856,\n "violet": 15631086,\n "wheat": 16113331,\n "white": 16777215,\n "whitesmoke": 16119285,\n "yellow": 16776960,\n "yellowgreen": 10145074\n };\n const _hslA = { h: 0, s: 0, l: 0 };\n const _hslB = { h: 0, s: 0, l: 0 };\n function hue2rgb(p, q, t) {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * 6 * (2 / 3 - t);\n return p;\n }\n class Color {\n /**\n * Constructs a new color.\n *\n * Note that standard method of specifying color in three.js is with a hexadecimal triplet,\n * and that method is used throughout the rest of the documentation.\n *\n * @param {(number|string|Color)} [r] - The red component of the color. If `g` and `b` are\n * not provided, it can be hexadecimal triplet, a CSS-style string or another `Color` instance.\n * @param {number} [g] - The green component.\n * @param {number} [b] - The blue component.\n */\n constructor(r, g, b) {\n this.isColor = true;\n this.r = 1;\n this.g = 1;\n this.b = 1;\n return this.set(r, g, b);\n }\n /**\n * Sets the colors\'s components from the given values.\n *\n * @param {(number|string|Color)} [r] - The red component of the color. If `g` and `b` are\n * not provided, it can be hexadecimal triplet, a CSS-style string or another `Color` instance.\n * @param {number} [g] - The green component.\n * @param {number} [b] - The blue component.\n * @return {Color} A reference to this color.\n */\n set(r, g, b) {\n if (g === void 0 && b === void 0) {\n const value = r;\n if (value && value.isColor) {\n this.copy(value);\n } else if (typeof value === "number") {\n this.setHex(value);\n } else if (typeof value === "string") {\n this.setStyle(value);\n }\n } else {\n this.setRGB(r, g, b);\n }\n return this;\n }\n /**\n * Sets the colors\'s components to the given scalar value.\n *\n * @param {number} scalar - The scalar value.\n * @return {Color} A reference to this color.\n */\n setScalar(scalar) {\n this.r = scalar;\n this.g = scalar;\n this.b = scalar;\n return this;\n }\n /**\n * Sets this color from a hexadecimal value.\n *\n * @param {number} hex - The hexadecimal value.\n * @param {string} [colorSpace=SRGBColorSpace] - The color space.\n * @return {Color} A reference to this color.\n */\n setHex(hex, colorSpace = SRGBColorSpace) {\n hex = Math.floor(hex);\n this.r = (hex >> 16 & 255) / 255;\n this.g = (hex >> 8 & 255) / 255;\n this.b = (hex & 255) / 255;\n ColorManagement.colorSpaceToWorking(this, colorSpace);\n return this;\n }\n /**\n * Sets this color from RGB values.\n *\n * @param {number} r - Red channel value between `0.0` and `1.0`.\n * @param {number} g - Green channel value between `0.0` and `1.0`.\n * @param {number} b - Blue channel value between `0.0` and `1.0`.\n * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space.\n * @return {Color} A reference to this color.\n */\n setRGB(r, g, b, colorSpace = ColorManagement.workingColorSpace) {\n this.r = r;\n this.g = g;\n this.b = b;\n ColorManagement.colorSpaceToWorking(this, colorSpace);\n return this;\n }\n /**\n * Sets this color from RGB values.\n *\n * @param {number} h - Hue value between `0.0` and `1.0`.\n * @param {number} s - Saturation value between `0.0` and `1.0`.\n * @param {number} l - Lightness value between `0.0` and `1.0`.\n * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space.\n * @return {Color} A reference to this color.\n */\n setHSL(h, s, l, colorSpace = ColorManagement.workingColorSpace) {\n h = euclideanModulo(h, 1);\n s = clamp(s, 0, 1);\n l = clamp(l, 0, 1);\n if (s === 0) {\n this.r = this.g = this.b = l;\n } else {\n const p = l <= 0.5 ? l * (1 + s) : l + s - l * s;\n const q = 2 * l - p;\n this.r = hue2rgb(q, p, h + 1 / 3);\n this.g = hue2rgb(q, p, h);\n this.b = hue2rgb(q, p, h - 1 / 3);\n }\n ColorManagement.colorSpaceToWorking(this, colorSpace);\n return this;\n }\n /**\n * Sets this color from a CSS-style string. For example, `rgb(250, 0,0)`,\n * `rgb(100%, 0%, 0%)`, `hsl(0, 100%, 50%)`, `#ff0000`, `#f00`, or `red` ( or\n * any [X11 color name]{@link https://en.wikipedia.org/wiki/X11_color_names#Color_name_chart} -\n * all 140 color names are supported).\n *\n * @param {string} style - Color as a CSS-style string.\n * @param {string} [colorSpace=SRGBColorSpace] - The color space.\n * @return {Color} A reference to this color.\n */\n setStyle(style, colorSpace = SRGBColorSpace) {\n function handleAlpha(string) {\n if (string === void 0) return;\n if (parseFloat(string) < 1) {\n console.warn("THREE.Color: Alpha component of " + style + " will be ignored.");\n }\n }\n let m;\n if (m = /^(\\w+)\\(([^\\)]*)\\)/.exec(style)) {\n let color;\n const name = m[1];\n const components = m[2];\n switch (name) {\n case "rgb":\n case "rgba":\n if (color = /^\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(?:,\\s*(\\d*\\.?\\d+)\\s*)?$/.exec(components)) {\n handleAlpha(color[4]);\n return this.setRGB(\n Math.min(255, parseInt(color[1], 10)) / 255,\n Math.min(255, parseInt(color[2], 10)) / 255,\n Math.min(255, parseInt(color[3], 10)) / 255,\n colorSpace\n );\n }\n if (color = /^\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(?:,\\s*(\\d*\\.?\\d+)\\s*)?$/.exec(components)) {\n handleAlpha(color[4]);\n return this.setRGB(\n Math.min(100, parseInt(color[1], 10)) / 100,\n Math.min(100, parseInt(color[2], 10)) / 100,\n Math.min(100, parseInt(color[3], 10)) / 100,\n colorSpace\n );\n }\n break;\n case "hsl":\n case "hsla":\n if (color = /^\\s*(\\d*\\.?\\d+)\\s*,\\s*(\\d*\\.?\\d+)\\%\\s*,\\s*(\\d*\\.?\\d+)\\%\\s*(?:,\\s*(\\d*\\.?\\d+)\\s*)?$/.exec(components)) {\n handleAlpha(color[4]);\n return this.setHSL(\n parseFloat(color[1]) / 360,\n parseFloat(color[2]) / 100,\n parseFloat(color[3]) / 100,\n colorSpace\n );\n }\n break;\n default:\n console.warn("THREE.Color: Unknown color model " + style);\n }\n } else if (m = /^\\#([A-Fa-f\\d]+)$/.exec(style)) {\n const hex = m[1];\n const size = hex.length;\n if (size === 3) {\n return this.setRGB(\n parseInt(hex.charAt(0), 16) / 15,\n parseInt(hex.charAt(1), 16) / 15,\n parseInt(hex.charAt(2), 16) / 15,\n colorSpace\n );\n } else if (size === 6) {\n return this.setHex(parseInt(hex, 16), colorSpace);\n } else {\n console.warn("THREE.Color: Invalid hex color " + style);\n }\n } else if (style && style.length > 0) {\n return this.setColorName(style, colorSpace);\n }\n return this;\n }\n /**\n * Sets this color from a color name. Faster than {@link Color#setStyle} if\n * you don\'t need the other CSS-style formats.\n *\n * For convenience, the list of names is exposed in `Color.NAMES` as a hash.\n * ```js\n * Color.NAMES.aliceblue // returns 0xF0F8FF\n * ```\n *\n * @param {string} style - The color name.\n * @param {string} [colorSpace=SRGBColorSpace] - The color space.\n * @return {Color} A reference to this color.\n */\n setColorName(style, colorSpace = SRGBColorSpace) {\n const hex = _colorKeywords[style.toLowerCase()];\n if (hex !== void 0) {\n this.setHex(hex, colorSpace);\n } else {\n console.warn("THREE.Color: Unknown color " + style);\n }\n return this;\n }\n /**\n * Returns a new color with copied values from this instance.\n *\n * @return {Color} A clone of this instance.\n */\n clone() {\n return new this.constructor(this.r, this.g, this.b);\n }\n /**\n * Copies the values of the given color to this instance.\n *\n * @param {Color} color - The color to copy.\n * @return {Color} A reference to this color.\n */\n copy(color) {\n this.r = color.r;\n this.g = color.g;\n this.b = color.b;\n return this;\n }\n /**\n * Copies the given color into this color, and then converts this color from\n * `SRGBColorSpace` to `LinearSRGBColorSpace`.\n *\n * @param {Color} color - The color to copy/convert.\n * @return {Color} A reference to this color.\n */\n copySRGBToLinear(color) {\n this.r = SRGBToLinear(color.r);\n this.g = SRGBToLinear(color.g);\n this.b = SRGBToLinear(color.b);\n return this;\n }\n /**\n * Copies the given color into this color, and then converts this color from\n * `LinearSRGBColorSpace` to `SRGBColorSpace`.\n *\n * @param {Color} color - The color to copy/convert.\n * @return {Color} A reference to this color.\n */\n copyLinearToSRGB(color) {\n this.r = LinearToSRGB(color.r);\n this.g = LinearToSRGB(color.g);\n this.b = LinearToSRGB(color.b);\n return this;\n }\n /**\n * Converts this color from `SRGBColorSpace` to `LinearSRGBColorSpace`.\n *\n * @return {Color} A reference to this color.\n */\n convertSRGBToLinear() {\n this.copySRGBToLinear(this);\n return this;\n }\n /**\n * Converts this color from `LinearSRGBColorSpace` to `SRGBColorSpace`.\n *\n * @return {Color} A reference to this color.\n */\n convertLinearToSRGB() {\n this.copyLinearToSRGB(this);\n return this;\n }\n /**\n * Returns the hexadecimal value of this color.\n *\n * @param {string} [colorSpace=SRGBColorSpace] - The color space.\n * @return {number} The hexadecimal value.\n */\n getHex(colorSpace = SRGBColorSpace) {\n ColorManagement.workingToColorSpace(_color.copy(this), colorSpace);\n return Math.round(clamp(_color.r * 255, 0, 255)) * 65536 + Math.round(clamp(_color.g * 255, 0, 255)) * 256 + Math.round(clamp(_color.b * 255, 0, 255));\n }\n /**\n * Returns the hexadecimal value of this color as a string (for example, \'FFFFFF\').\n *\n * @param {string} [colorSpace=SRGBColorSpace] - The color space.\n * @return {string} The hexadecimal value as a string.\n */\n getHexString(colorSpace = SRGBColorSpace) {\n return ("000000" + this.getHex(colorSpace).toString(16)).slice(-6);\n }\n /**\n * Converts the colors RGB values into the HSL format and stores them into the\n * given target object.\n *\n * @param {{h:number,s:number,l:number}} target - The target object that is used to store the method\'s result.\n * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space.\n * @return {{h:number,s:number,l:number}} The HSL representation of this color.\n */\n getHSL(target, colorSpace = ColorManagement.workingColorSpace) {\n ColorManagement.workingToColorSpace(_color.copy(this), colorSpace);\n const r = _color.r, g = _color.g, b = _color.b;\n const max2 = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n let hue, saturation;\n const lightness = (min + max2) / 2;\n if (min === max2) {\n hue = 0;\n saturation = 0;\n } else {\n const delta = max2 - min;\n saturation = lightness <= 0.5 ? delta / (max2 + min) : delta / (2 - max2 - min);\n switch (max2) {\n case r:\n hue = (g - b) / delta + (g < b ? 6 : 0);\n break;\n case g:\n hue = (b - r) / delta + 2;\n break;\n case b:\n hue = (r - g) / delta + 4;\n break;\n }\n hue /= 6;\n }\n target.h = hue;\n target.s = saturation;\n target.l = lightness;\n return target;\n }\n /**\n * Returns the RGB values of this color and stores them into the given target object.\n *\n * @param {Color} target - The target color that is used to store the method\'s result.\n * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space.\n * @return {Color} The RGB representation of this color.\n */\n getRGB(target, colorSpace = ColorManagement.workingColorSpace) {\n ColorManagement.workingToColorSpace(_color.copy(this), colorSpace);\n target.r = _color.r;\n target.g = _color.g;\n target.b = _color.b;\n return target;\n }\n /**\n * Returns the value of this color as a CSS style string. Example: `rgb(255,0,0)`.\n *\n * @param {string} [colorSpace=SRGBColorSpace] - The color space.\n * @return {string} The CSS representation of this color.\n */\n getStyle(colorSpace = SRGBColorSpace) {\n ColorManagement.workingToColorSpace(_color.copy(this), colorSpace);\n const r = _color.r, g = _color.g, b = _color.b;\n if (colorSpace !== SRGBColorSpace) {\n return `color(${colorSpace} ${r.toFixed(3)} ${g.toFixed(3)} ${b.toFixed(3)})`;\n }\n return `rgb(${Math.round(r * 255)},${Math.round(g * 255)},${Math.round(b * 255)})`;\n }\n /**\n * Adds the given HSL values to this color\'s values.\n * Internally, this converts the color\'s RGB values to HSL, adds HSL\n * and then converts the color back to RGB.\n *\n * @param {number} h - Hue value between `0.0` and `1.0`.\n * @param {number} s - Saturation value between `0.0` and `1.0`.\n * @param {number} l - Lightness value between `0.0` and `1.0`.\n * @return {Color} A reference to this color.\n */\n offsetHSL(h, s, l) {\n this.getHSL(_hslA);\n return this.setHSL(_hslA.h + h, _hslA.s + s, _hslA.l + l);\n }\n /**\n * Adds the RGB values of the given color to the RGB values of this color.\n *\n * @param {Color} color - The color to add.\n * @return {Color} A reference to this color.\n */\n add(color) {\n this.r += color.r;\n this.g += color.g;\n this.b += color.b;\n return this;\n }\n /**\n * Adds the RGB values of the given colors and stores the result in this instance.\n *\n * @param {Color} color1 - The first color.\n * @param {Color} color2 - The second color.\n * @return {Color} A reference to this color.\n */\n addColors(color1, color2) {\n this.r = color1.r + color2.r;\n this.g = color1.g + color2.g;\n this.b = color1.b + color2.b;\n return this;\n }\n /**\n * Adds the given scalar value to the RGB values of this color.\n *\n * @param {number} s - The scalar to add.\n * @return {Color} A reference to this color.\n */\n addScalar(s) {\n this.r += s;\n this.g += s;\n this.b += s;\n return this;\n }\n /**\n * Subtracts the RGB values of the given color from the RGB values of this color.\n *\n * @param {Color} color - The color to subtract.\n * @return {Color} A reference to this color.\n */\n sub(color) {\n this.r = Math.max(0, this.r - color.r);\n this.g = Math.max(0, this.g - color.g);\n this.b = Math.max(0, this.b - color.b);\n return this;\n }\n /**\n * Multiplies the RGB values of the given color with the RGB values of this color.\n *\n * @param {Color} color - The color to multiply.\n * @return {Color} A reference to this color.\n */\n multiply(color) {\n this.r *= color.r;\n this.g *= color.g;\n this.b *= color.b;\n return this;\n }\n /**\n * Multiplies the given scalar value with the RGB values of this color.\n *\n * @param {number} s - The scalar to multiply.\n * @return {Color} A reference to this color.\n */\n multiplyScalar(s) {\n this.r *= s;\n this.g *= s;\n this.b *= s;\n return this;\n }\n /**\n * Linearly interpolates this color\'s RGB values toward the RGB values of the\n * given color. The alpha argument can be thought of as the ratio between\n * the two colors, where `0.0` is this color and `1.0` is the first argument.\n *\n * @param {Color} color - The color to converge on.\n * @param {number} alpha - The interpolation factor in the closed interval `[0,1]`.\n * @return {Color} A reference to this color.\n */\n lerp(color, alpha) {\n this.r += (color.r - this.r) * alpha;\n this.g += (color.g - this.g) * alpha;\n this.b += (color.b - this.b) * alpha;\n return this;\n }\n /**\n * Linearly interpolates between the given colors and stores the result in this instance.\n * The alpha argument can be thought of as the ratio between the two colors, where `0.0`\n * is the first and `1.0` is the second color.\n *\n * @param {Color} color1 - The first color.\n * @param {Color} color2 - The second color.\n * @param {number} alpha - The interpolation factor in the closed interval `[0,1]`.\n * @return {Color} A reference to this color.\n */\n lerpColors(color1, color2, alpha) {\n this.r = color1.r + (color2.r - color1.r) * alpha;\n this.g = color1.g + (color2.g - color1.g) * alpha;\n this.b = color1.b + (color2.b - color1.b) * alpha;\n return this;\n }\n /**\n * Linearly interpolates this color\'s HSL values toward the HSL values of the\n * given color. It differs from {@link Color#lerp} by not interpolating straight\n * from one color to the other, but instead going through all the hues in between\n * those two colors. The alpha argument can be thought of as the ratio between\n * the two colors, where 0.0 is this color and 1.0 is the first argument.\n *\n * @param {Color} color - The color to converge on.\n * @param {number} alpha - The interpolation factor in the closed interval `[0,1]`.\n * @return {Color} A reference to this color.\n */\n lerpHSL(color, alpha) {\n this.getHSL(_hslA);\n color.getHSL(_hslB);\n const h = lerp(_hslA.h, _hslB.h, alpha);\n const s = lerp(_hslA.s, _hslB.s, alpha);\n const l = lerp(_hslA.l, _hslB.l, alpha);\n this.setHSL(h, s, l);\n return this;\n }\n /**\n * Sets the color\'s RGB components from the given 3D vector.\n *\n * @param {Vector3} v - The vector to set.\n * @return {Color} A reference to this color.\n */\n setFromVector3(v) {\n this.r = v.x;\n this.g = v.y;\n this.b = v.z;\n return this;\n }\n /**\n * Transforms this color with the given 3x3 matrix.\n *\n * @param {Matrix3} m - The matrix.\n * @return {Color} A reference to this color.\n */\n applyMatrix3(m) {\n const r = this.r, g = this.g, b = this.b;\n const e = m.elements;\n this.r = e[0] * r + e[3] * g + e[6] * b;\n this.g = e[1] * r + e[4] * g + e[7] * b;\n this.b = e[2] * r + e[5] * g + e[8] * b;\n return this;\n }\n /**\n * Returns `true` if this color is equal with the given one.\n *\n * @param {Color} c - The color to test for equality.\n * @return {boolean} Whether this bounding color is equal with the given one.\n */\n equals(c) {\n return c.r === this.r && c.g === this.g && c.b === this.b;\n }\n /**\n * Sets this color\'s RGB components from the given array.\n *\n * @param {Array<number>} array - An array holding the RGB values.\n * @param {number} [offset=0] - The offset into the array.\n * @return {Color} A reference to this color.\n */\n fromArray(array, offset = 0) {\n this.r = array[offset];\n this.g = array[offset + 1];\n this.b = array[offset + 2];\n return this;\n }\n /**\n * Writes the RGB components of this color to the given array. If no array is provided,\n * the method returns a new instance.\n *\n * @param {Array<number>} [array=[]] - The target array holding the color components.\n * @param {number} [offset=0] - Index of the first element in the array.\n * @return {Array<number>} The color components.\n */\n toArray(array = [], offset = 0) {\n array[offset] = this.r;\n array[offset + 1] = this.g;\n array[offset + 2] = this.b;\n return array;\n }\n /**\n * Sets the components of this color from the given buffer attribute.\n *\n * @param {BufferAttribute} attribute - The buffer attribute holding color data.\n * @param {number} index - The index into the attribute.\n * @return {Color} A reference to this color.\n */\n fromBufferAttribute(attribute, index) {\n this.r = attribute.getX(index);\n this.g = attribute.getY(index);\n this.b = attribute.getZ(index);\n return this;\n }\n /**\n * This methods defines the serialization result of this class. Returns the color\n * as a hexadecimal value.\n *\n * @return {number} The hexadecimal value.\n */\n toJSON() {\n return this.getHex();\n }\n *[Symbol.iterator]() {\n yield this.r;\n yield this.g;\n yield this.b;\n }\n }\n const _color = /* @__PURE__ */ new Color();\n Color.NAMES = _colorKeywords;\n if (typeof __THREE_DEVTOOLS__ !== "undefined") {\n __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("register", { detail: {\n revision: REVISION\n } }));\n }\n if (typeof window !== "undefined") {\n if (window.__THREE__) {\n console.warn("WARNING: Multiple instances of Three.js being imported.");\n } else {\n window.__THREE__ = REVISION;\n }\n }\n const LN_SCALE_MIN = -12;\n const LN_SCALE_MAX = 9;\n const LN_SCALE_ZERO = -30;\n const SCALE_ZERO = Math.exp(LN_SCALE_ZERO);\n const SPLAT_TEX_WIDTH_BITS = 11;\n const SPLAT_TEX_HEIGHT_BITS = 11;\n const SPLAT_TEX_WIDTH = 1 << SPLAT_TEX_WIDTH_BITS;\n const SPLAT_TEX_HEIGHT = 1 << SPLAT_TEX_HEIGHT_BITS;\n const SPLAT_TEX_MIN_HEIGHT = 1;\n function unindentLines(s) {\n var _a2;\n let seenNonEmpty = false;\n const lines = s.split("\\n").map((line) => {\n const trimmedLine = line.trimEnd();\n if (seenNonEmpty) {\n return trimmedLine;\n }\n if (trimmedLine.length > 0) {\n seenNonEmpty = true;\n return trimmedLine;\n }\n return null;\n }).filter((line) => line != null);\n while (lines.length > 0 && lines[lines.length - 1].length === 0) {\n lines.pop();\n }\n if (lines.length === 0) {\n return [];\n }\n const indent = (_a2 = lines[0].match(/^\\s*/)) == null ? void 0 : _a2[0];\n if (!indent) {\n return lines;\n }\n const regex = new RegExp(`^${indent}`);\n return lines.map((line) => line.replace(regex, ""));\n }\n function unindent(s) {\n return unindentLines(s).join("\\n");\n }\n const f32buffer = new Float32Array(1);\n const u32buffer = new Uint32Array(f32buffer.buffer);\n const supportsFloat16Array = "Float16Array" in globalThis;\n const f16buffer = supportsFloat16Array ? new globalThis["Float16Array"](1) : null;\n const u16buffer = new Uint16Array(f16buffer == null ? void 0 : f16buffer.buffer);\n function normalize(vec) {\n const norm = Math.sqrt(vec.reduce((acc, v) => acc + v * v, 0));\n return vec.map((v) => v / norm);\n }\n const toHalf = supportsFloat16Array ? toHalfNative : toHalfJS;\n const fromHalf = supportsFloat16Array ? fromHalfNative : fromHalfJS;\n function toHalfNative(f) {\n f16buffer[0] = f;\n return u16buffer[0];\n }\n function toHalfJS(f) {\n f32buffer[0] = f;\n const bits2 = u32buffer[0];\n const sign = bits2 >> 31 & 1;\n const exp = bits2 >> 23 & 255;\n const frac = bits2 & 8388607;\n const halfSign = sign << 15;\n if (exp === 255) {\n if (frac !== 0) {\n return halfSign | 32767;\n }\n return halfSign | 31744;\n }\n const newExp = exp - 127 + 15;\n if (newExp >= 31) {\n return halfSign | 31744;\n }\n if (newExp <= 0) {\n if (newExp < -10) {\n return halfSign;\n }\n const subFrac = (frac | 8388608) >> 1 - newExp + 13;\n return halfSign | subFrac;\n }\n const halfFrac = frac >> 13;\n return halfSign | newExp << 10 | halfFrac;\n }\n function fromHalfNative(u) {\n u16buffer[0] = u;\n return f16buffer[0];\n }\n function fromHalfJS(h) {\n const sign = h >> 15 & 1;\n const exp = h >> 10 & 31;\n const frac = h & 1023;\n let f32bits;\n if (exp === 0) {\n if (frac === 0) {\n f32bits = sign << 31;\n } else {\n let mant = frac;\n let e = -14;\n while ((mant & 1024) === 0) {\n mant <<= 1;\n e--;\n }\n mant &= 1023;\n const newExp = e + 127;\n const newFrac = mant << 13;\n f32bits = sign << 31 | newExp << 23 | newFrac;\n }\n } else if (exp === 31) {\n if (frac === 0) {\n f32bits = sign << 31 | 2139095040;\n } else {\n f32bits = sign << 31 | 2143289344;\n }\n } else {\n const newExp = exp - 15 + 127;\n const newFrac = frac << 13;\n f32bits = sign << 31 | newExp << 23 | newFrac;\n }\n u32buffer[0] = f32bits;\n return f32buffer[0];\n }\n function floatToUint8(v) {\n return Math.max(0, Math.min(255, Math.round(v * 255)));\n }\n function getArrayBuffers(ctx) {\n const buffers = [];\n const seen = /* @__PURE__ */ new Set();\n function traverse(obj) {\n if (obj && typeof obj === "object" && !seen.has(obj)) {\n seen.add(obj);\n if (obj instanceof ArrayBuffer) {\n buffers.push(obj);\n } else if (ArrayBuffer.isView(obj)) {\n buffers.push(obj.buffer);\n } else if (Array.isArray(obj)) {\n obj.forEach(traverse);\n } else {\n Object.values(obj).forEach(traverse);\n }\n }\n }\n traverse(ctx);\n return buffers;\n }\n function setPackedSplat(packedSplats, index, x2, y, z, scaleX, scaleY, scaleZ, quatX, quatY, quatZ, quatW, opacity, r, g, b, encoding) {\n const rgbMin = (encoding == null ? void 0 : encoding.rgbMin) ?? 0;\n const rgbMax = (encoding == null ? void 0 : encoding.rgbMax) ?? 1;\n const rgbRange = rgbMax - rgbMin;\n const uR = floatToUint8((r - rgbMin) / rgbRange);\n const uG = floatToUint8((g - rgbMin) / rgbRange);\n const uB = floatToUint8((b - rgbMin) / rgbRange);\n const uA = floatToUint8(opacity);\n const uQuat = encodeQuatOctXy88R8(\n tempQuaternion.set(quatX, quatY, quatZ, quatW)\n );\n const uQuatX = uQuat & 255;\n const uQuatY = uQuat >>> 8 & 255;\n const uQuatZ = uQuat >>> 16 & 255;\n const lnScaleMin = (encoding == null ? void 0 : encoding.lnScaleMin) ?? LN_SCALE_MIN;\n const lnScaleMax = (encoding == null ? void 0 : encoding.lnScaleMax) ?? LN_SCALE_MAX;\n const lnScaleScale = 254 / (lnScaleMax - lnScaleMin);\n const uScaleX = scaleX < SCALE_ZERO ? 0 : Math.min(\n 255,\n Math.max(\n 1,\n Math.round((Math.log(scaleX) - lnScaleMin) * lnScaleScale) + 1\n )\n );\n const uScaleY = scaleY < SCALE_ZERO ? 0 : Math.min(\n 255,\n Math.max(\n 1,\n Math.round((Math.log(scaleY) - lnScaleMin) * lnScaleScale) + 1\n )\n );\n const uScaleZ = scaleZ < SCALE_ZERO ? 0 : Math.min(\n 255,\n Math.max(\n 1,\n Math.round((Math.log(scaleZ) - lnScaleMin) * lnScaleScale) + 1\n )\n );\n const uCenterX = toHalf(x2);\n const uCenterY = toHalf(y);\n const uCenterZ = toHalf(z);\n const i4 = index * 4;\n packedSplats[i4] = uR | uG << 8 | uB << 16 | uA << 24;\n packedSplats[i4 + 1] = uCenterX | uCenterY << 16;\n packedSplats[i4 + 2] = uCenterZ | uQuatX << 16 | uQuatY << 24;\n packedSplats[i4 + 3] = uScaleX | uScaleY << 8 | uScaleZ << 16 | uQuatZ << 24;\n }\n function setPackedSplatCenter(packedSplats, index, x2, y, z) {\n const uCenterX = toHalf(x2);\n const uCenterY = toHalf(y);\n const uCenterZ = toHalf(z);\n const i4 = index * 4;\n packedSplats[i4 + 1] = uCenterX | uCenterY << 16;\n packedSplats[i4 + 2] = uCenterZ | packedSplats[i4 + 2] & 4294901760;\n }\n function setPackedSplatScales(packedSplats, index, scaleX, scaleY, scaleZ, encoding) {\n const lnScaleMin = (encoding == null ? void 0 : encoding.lnScaleMin) ?? LN_SCALE_MIN;\n const lnScaleMax = (encoding == null ? void 0 : encoding.lnScaleMax) ?? LN_SCALE_MAX;\n const lnScaleScale = 254 / (lnScaleMax - lnScaleMin);\n const uScaleX = scaleX < SCALE_ZERO ? 0 : Math.min(\n 255,\n Math.max(\n 1,\n Math.round((Math.log(scaleX) - lnScaleMin) * lnScaleScale) + 1\n )\n );\n const uScaleY = scaleY < SCALE_ZERO ? 0 : Math.min(\n 255,\n Math.max(\n 1,\n Math.round((Math.log(scaleY) - lnScaleMin) * lnScaleScale) + 1\n )\n );\n const uScaleZ = scaleZ < SCALE_ZERO ? 0 : Math.min(\n 255,\n Math.max(\n 1,\n Math.round((Math.log(scaleZ) - lnScaleMin) * lnScaleScale) + 1\n )\n );\n const i4 = index * 4;\n packedSplats[i4 + 3] = uScaleX | uScaleY << 8 | uScaleZ << 16 | packedSplats[i4 + 3] & 4278190080;\n }\n const tempQuaternion = new Quaternion();\n function setPackedSplatQuat(packedSplats, index, quatX, quatY, quatZ, quatW) {\n const uQuat = encodeQuatOctXy88R8(\n tempQuaternion.set(quatX, quatY, quatZ, quatW)\n );\n const uQuatX = uQuat & 255;\n const uQuatY = uQuat >>> 8 & 255;\n const uQuatZ = uQuat >>> 16 & 255;\n const i4 = index * 4;\n packedSplats[i4 + 2] = packedSplats[i4 + 2] & 65535 | uQuatX << 16 | uQuatY << 24;\n packedSplats[i4 + 3] = packedSplats[i4 + 3] & 16777215 | uQuatZ << 24;\n }\n function setPackedSplatRgba(packedSplats, index, r, g, b, a, encoding) {\n const rgbMin = (encoding == null ? void 0 : encoding.rgbMin) ?? 0;\n const rgbMax = (encoding == null ? void 0 : encoding.rgbMax) ?? 1;\n const rgbRange = rgbMax - rgbMin;\n const uR = floatToUint8((r - rgbMin) / rgbRange);\n const uG = floatToUint8((g - rgbMin) / rgbRange);\n const uB = floatToUint8((b - rgbMin) / rgbRange);\n const uA = floatToUint8(a);\n const i4 = index * 4;\n packedSplats[i4] = uR | uG << 8 | uB << 16 | uA << 24;\n }\n function setPackedSplatRgb(packedSplats, index, r, g, b, encoding) {\n const rgbMin = (encoding == null ? void 0 : encoding.rgbMin) ?? 0;\n const rgbMax = (encoding == null ? void 0 : encoding.rgbMax) ?? 1;\n const rgbRange = rgbMax - rgbMin;\n const uR = floatToUint8((r - rgbMin) / rgbRange);\n const uG = floatToUint8((g - rgbMin) / rgbRange);\n const uB = floatToUint8((b - rgbMin) / rgbRange);\n const i4 = index * 4;\n packedSplats[i4] = uR | uG << 8 | uB << 16 | packedSplats[i4] & 4278190080;\n }\n function setPackedSplatOpacity(packedSplats, index, opacity) {\n const uA = floatToUint8(opacity);\n const i4 = index * 4;\n packedSplats[i4] = packedSplats[i4] & 16777215 | uA << 24;\n }\n new Vector3();\n new Vector3();\n new Color();\n function getTextureSize(numSplats) {\n const width = SPLAT_TEX_WIDTH;\n const height = Math.max(\n SPLAT_TEX_MIN_HEIGHT,\n Math.min(SPLAT_TEX_HEIGHT, Math.ceil(numSplats / width))\n );\n const depth = Math.ceil(numSplats / (width * height));\n const maxSplats = width * height * depth;\n return { width, height, depth, maxSplats };\n }\n function computeMaxSplats(numSplats) {\n const width = SPLAT_TEX_WIDTH;\n const height = Math.max(\n SPLAT_TEX_MIN_HEIGHT,\n Math.min(SPLAT_TEX_HEIGHT, Math.ceil(numSplats / width))\n );\n const depth = Math.ceil(numSplats / (width * height));\n return width * height * depth;\n }\n unindent(`\n precision highp float;\n\n in vec3 position;\n\n void main() {\n gl_Position = vec4(position.xy, 0.0, 1.0);\n }\n`);\n const tempNormalizedQuaternion = new Quaternion();\n const tempAxis = new Vector3();\n function encodeQuatOctXy88R8(q) {\n const qnorm = tempNormalizedQuaternion.copy(q).normalize();\n if (qnorm.w < 0) {\n qnorm.set(-qnorm.x, -qnorm.y, -qnorm.z, -qnorm.w);\n }\n const theta = 2 * Math.acos(qnorm.w);\n const xyz_norm = Math.sqrt(\n qnorm.x * qnorm.x + qnorm.y * qnorm.y + qnorm.z * qnorm.z\n );\n const axis = xyz_norm < 1e-6 ? tempAxis.set(1, 0, 0) : tempAxis.set(qnorm.x, qnorm.y, qnorm.z).divideScalar(xyz_norm);\n const sum = Math.abs(axis.x) + Math.abs(axis.y) + Math.abs(axis.z);\n let p_x = axis.x / sum;\n let p_y = axis.y / sum;\n if (axis.z < 0) {\n const tmp = p_x;\n p_x = (1 - Math.abs(p_y)) * (p_x >= 0 ? 1 : -1);\n p_y = (1 - Math.abs(tmp)) * (p_y >= 0 ? 1 : -1);\n }\n const u_f = p_x * 0.5 + 0.5;\n const v_f = p_y * 0.5 + 0.5;\n const quantU = Math.round(u_f * 255);\n const quantV = Math.round(v_f * 255);\n const angleInt = Math.round(theta * (255 / Math.PI));\n return angleInt << 16 | quantV << 8 | quantU;\n }\n function packSint8Bytes(b0, b1, b22, b3) {\n const clampedB0 = Math.max(-127, Math.min(127, b0 * 127));\n const clampedB1 = Math.max(-127, Math.min(127, b1 * 127));\n const clampedB2 = Math.max(-127, Math.min(127, b22 * 127));\n const clampedB3 = Math.max(-127, Math.min(127, b3 * 127));\n return clampedB0 & 255 | (clampedB1 & 255) << 8 | (clampedB2 & 255) << 16 | (clampedB3 & 255) << 24;\n }\n function encodeSh1Rgb(sh1Array, index, sh1Rgb, encoding) {\n const sh1Min = (encoding == null ? void 0 : encoding.sh1Min) ?? -1;\n const sh1Max = (encoding == null ? void 0 : encoding.sh1Max) ?? 1;\n const sh1Mid = 0.5 * (sh1Min + sh1Max);\n const sh1Scale = 126 / (sh1Max - sh1Min);\n const base = index * 2;\n for (let i2 = 0; i2 < 9; ++i2) {\n const s = (sh1Rgb[i2] - sh1Mid) * sh1Scale;\n const value = Math.round(Math.max(-63, Math.min(63, s))) & 127;\n const bitStart = i2 * 7;\n const bitEnd = bitStart + 7;\n const wordStart = Math.floor(bitStart / 32);\n const bitOffset = bitStart - wordStart * 32;\n const firstWord = value << bitOffset & 4294967295;\n sh1Array[base + wordStart] |= firstWord;\n if (bitEnd > wordStart * 32 + 32) {\n const secondWord = value >>> 32 - bitOffset & 4294967295;\n sh1Array[base + wordStart + 1] |= secondWord;\n }\n }\n }\n function encodeSh2Rgb(sh2Array, index, sh2Rgb, encoding) {\n const sh2Min = (encoding == null ? void 0 : encoding.sh2Min) ?? -1;\n const sh2Max = (encoding == null ? void 0 : encoding.sh2Max) ?? 1;\n const sh2Mid = 0.5 * (sh2Min + sh2Max);\n const sh2Scale = 2 / (sh2Max - sh2Min);\n sh2Array[index * 4 + 0] = packSint8Bytes(\n (sh2Rgb[0] - sh2Mid) * sh2Scale,\n (sh2Rgb[1] - sh2Mid) * sh2Scale,\n (sh2Rgb[2] - sh2Mid) * sh2Scale,\n (sh2Rgb[3] - sh2Mid) * sh2Scale\n );\n sh2Array[index * 4 + 1] = packSint8Bytes(\n (sh2Rgb[4] - sh2Mid) * sh2Scale,\n (sh2Rgb[5] - sh2Mid) * sh2Scale,\n (sh2Rgb[6] - sh2Mid) * sh2Scale,\n (sh2Rgb[7] - sh2Mid) * sh2Scale\n );\n sh2Array[index * 4 + 2] = packSint8Bytes(\n (sh2Rgb[8] - sh2Mid) * sh2Scale,\n (sh2Rgb[9] - sh2Mid) * sh2Scale,\n (sh2Rgb[10] - sh2Mid) * sh2Scale,\n (sh2Rgb[11] - sh2Mid) * sh2Scale\n );\n sh2Array[index * 4 + 3] = packSint8Bytes(\n (sh2Rgb[12] - sh2Mid) * sh2Scale,\n (sh2Rgb[13] - sh2Mid) * sh2Scale,\n (sh2Rgb[14] - sh2Mid) * sh2Scale,\n 0\n );\n }\n function encodeSh3Rgb(sh3Array, index, sh3Rgb, encoding) {\n const sh3Min = (encoding == null ? void 0 : encoding.sh3Min) ?? -1;\n const sh3Max = (encoding == null ? void 0 : encoding.sh3Max) ?? 1;\n const sh3Mid = 0.5 * (sh3Min + sh3Max);\n const sh3Scale = 62 / (sh3Max - sh3Min);\n const base = index * 4;\n for (let i2 = 0; i2 < 21; ++i2) {\n const s = (sh3Rgb[i2] - sh3Mid) * sh3Scale;\n const value = Math.round(Math.max(-31, Math.min(31, s))) & 63;\n const bitStart = i2 * 6;\n const bitEnd = bitStart + 6;\n const wordStart = Math.floor(bitStart / 32);\n const bitOffset = bitStart - wordStart * 32;\n const firstWord = value << bitOffset & 4294967295;\n sh3Array[base + wordStart] |= firstWord;\n if (bitEnd > wordStart * 32 + 32) {\n const secondWord = value >>> 32 - bitOffset & 4294967295;\n sh3Array[base + wordStart + 1] |= secondWord;\n }\n }\n }\n function decompressPartialGzip(fileBytes, numBytes) {\n const chunks = [];\n let totalBytes = 0;\n let result = null;\n const gunzip = new Gunzip((data, final) => {\n chunks.push(data);\n totalBytes += data.length;\n if (final || totalBytes >= numBytes) {\n const allBytes = new Uint8Array(totalBytes);\n let offset2 = 0;\n for (const chunk of chunks) {\n allBytes.set(chunk, offset2);\n offset2 += chunk.length;\n }\n result = allBytes.slice(0, numBytes);\n }\n });\n const CHUNK_SIZE = 1024;\n let offset = 0;\n while (result == null && offset < fileBytes.length) {\n const chunk = fileBytes.slice(offset, offset + CHUNK_SIZE);\n gunzip.push(chunk, false);\n offset += CHUNK_SIZE;\n }\n if (result == null) {\n gunzip.push(new Uint8Array(), true);\n if (result == null) {\n throw new Error("Failed to decompress partial gzip");\n }\n }\n return result;\n }\n class GunzipReader {\n constructor({\n fileBytes,\n chunkBytes = 64 * 1024\n }) {\n this.fileBytes = fileBytes;\n this.chunkBytes = chunkBytes;\n this.chunks = [];\n this.totalBytes = 0;\n const ds = new DecompressionStream("gzip");\n const decompressionStream = new Blob([fileBytes]).stream().pipeThrough(ds);\n this.reader = decompressionStream.getReader();\n }\n async read(numBytes) {\n while (this.totalBytes < numBytes) {\n const { value: chunk, done: readerDone } = await this.reader.read();\n if (readerDone) {\n break;\n }\n this.chunks.push(chunk);\n this.totalBytes += chunk.length;\n }\n if (this.totalBytes < numBytes) {\n throw new Error(\n `Unexpected EOF: needed ${numBytes}, got ${this.totalBytes}`\n );\n }\n const allBytes = new Uint8Array(this.totalBytes);\n let outOffset = 0;\n for (const chunk of this.chunks) {\n allBytes.set(chunk, outOffset);\n outOffset += chunk.length;\n }\n const result = allBytes.subarray(0, numBytes);\n this.chunks = [allBytes.subarray(numBytes)];\n this.totalBytes -= numBytes;\n return result;\n }\n }\n function decodeAntiSplat(fileBytes, initNumSplats, splatCallback) {\n const numSplats = Math.floor(fileBytes.length / 32);\n if (numSplats * 32 !== fileBytes.length) {\n throw new Error("Invalid .splat file size");\n }\n initNumSplats(numSplats);\n const f32 = new Float32Array(fileBytes.buffer);\n for (let i2 = 0; i2 < numSplats; ++i2) {\n const i322 = i2 * 32;\n const i8 = i2 * 8;\n const x2 = f32[i8 + 0];\n const y = f32[i8 + 1];\n const z = f32[i8 + 2];\n const scaleX = f32[i8 + 3];\n const scaleY = f32[i8 + 4];\n const scaleZ = f32[i8 + 5];\n const r = fileBytes[i322 + 24] / 255;\n const g = fileBytes[i322 + 25] / 255;\n const b = fileBytes[i322 + 26] / 255;\n const opacity = fileBytes[i322 + 27] / 255;\n const quatW = (fileBytes[i322 + 28] - 128) / 128;\n const quatX = (fileBytes[i322 + 29] - 128) / 128;\n const quatY = (fileBytes[i322 + 30] - 128) / 128;\n const quatZ = (fileBytes[i322 + 31] - 128) / 128;\n splatCallback(\n i2,\n x2,\n y,\n z,\n scaleX,\n scaleY,\n scaleZ,\n quatX,\n quatY,\n quatZ,\n quatW,\n opacity,\n r,\n g,\n b\n );\n }\n }\n function unpackAntiSplat(fileBytes, splatEncoding) {\n let numSplats = 0;\n let maxSplats = 0;\n let packedArray = new Uint32Array(0);\n decodeAntiSplat(\n fileBytes,\n (cbNumSplats) => {\n numSplats = cbNumSplats;\n maxSplats = computeMaxSplats(numSplats);\n packedArray = new Uint32Array(maxSplats * 4);\n },\n (index, x2, y, z, scaleX, scaleY, scaleZ, quatX, quatY, quatZ, quatW, opacity, r, g, b) => {\n setPackedSplat(\n packedArray,\n index,\n x2,\n y,\n z,\n scaleX,\n scaleY,\n scaleZ,\n quatX,\n quatY,\n quatZ,\n quatW,\n opacity,\n r,\n g,\n b,\n splatEncoding\n );\n }\n );\n return { packedArray, numSplats };\n }\n const KSPLAT_COMPRESSION = {\n 0: {\n bytesPerCenter: 12,\n bytesPerScale: 12,\n bytesPerRotation: 16,\n bytesPerColor: 4,\n bytesPerSphericalHarmonicsComponent: 4,\n scaleOffsetBytes: 12,\n rotationOffsetBytes: 24,\n colorOffsetBytes: 40,\n sphericalHarmonicsOffsetBytes: 44,\n scaleRange: 1\n },\n 1: {\n bytesPerCenter: 6,\n bytesPerScale: 6,\n bytesPerRotation: 8,\n bytesPerColor: 4,\n bytesPerSphericalHarmonicsComponent: 2,\n scaleOffsetBytes: 6,\n rotationOffsetBytes: 12,\n colorOffsetBytes: 20,\n sphericalHarmonicsOffsetBytes: 24,\n scaleRange: 32767\n },\n 2: {\n bytesPerCenter: 6,\n bytesPerScale: 6,\n bytesPerRotation: 8,\n bytesPerColor: 4,\n bytesPerSphericalHarmonicsComponent: 1,\n scaleOffsetBytes: 6,\n rotationOffsetBytes: 12,\n colorOffsetBytes: 20,\n sphericalHarmonicsOffsetBytes: 24,\n scaleRange: 32767\n }\n };\n const KSPLAT_SH_DEGREE_TO_COMPONENTS = {\n 0: 0,\n 1: 9,\n 2: 24,\n 3: 45\n };\n function decodeKsplat(fileBytes, initNumSplats, splatCallback, shCallback) {\n var _a2;\n const HEADER_BYTES = 4096;\n const SECTION_BYTES = 1024;\n let headerOffset = 0;\n const header = new DataView(fileBytes.buffer, headerOffset, HEADER_BYTES);\n headerOffset += HEADER_BYTES;\n const versionMajor = header.getUint8(0);\n const versionMinor = header.getUint8(1);\n if (versionMajor !== 0 || versionMinor < 1) {\n throw new Error(\n `Unsupported .ksplat version: ${versionMajor}.${versionMinor}`\n );\n }\n const maxSectionCount = header.getUint32(4, true);\n header.getUint32(16, true);\n const compressionLevel = header.getUint16(20, true);\n if (compressionLevel < 0 || compressionLevel > 2) {\n throw new Error(`Invalid .ksplat compression level: ${compressionLevel}`);\n }\n const minSphericalHarmonicsCoeff = header.getFloat32(36, true) || -1.5;\n const maxSphericalHarmonicsCoeff = header.getFloat32(40, true) || 1.5;\n let sectionBase = HEADER_BYTES + maxSectionCount * SECTION_BYTES;\n for (let section = 0; section < maxSectionCount; ++section) {\n let getSh = function(splatOffset, component) {\n if (compressionLevel === 0) {\n return data.getFloat32(\n splatOffset + sphericalHarmonicsOffsetBytes + component * 4,\n true\n );\n }\n if (compressionLevel === 1) {\n return fromHalf(\n data.getUint16(\n splatOffset + sphericalHarmonicsOffsetBytes + component * 2,\n true\n )\n );\n }\n const t = data.getUint8(splatOffset + sphericalHarmonicsOffsetBytes + component) / 255;\n return minSphericalHarmonicsCoeff + t * (maxSphericalHarmonicsCoeff - minSphericalHarmonicsCoeff);\n };\n const section2 = new DataView(fileBytes.buffer, headerOffset, SECTION_BYTES);\n headerOffset += SECTION_BYTES;\n const sectionSplatCount = section2.getUint32(0, true);\n const sectionMaxSplatCount = section2.getUint32(4, true);\n const bucketSize = section2.getUint32(8, true);\n const bucketCount = section2.getUint32(12, true);\n const bucketBlockSize = section2.getFloat32(16, true);\n const bucketStorageSizeBytes = section2.getUint16(20, true);\n const compressionScaleRange = (section2.getUint32(24, true) || ((_a2 = KSPLAT_COMPRESSION[compressionLevel]) == null ? void 0 : _a2.scaleRange)) ?? 1;\n const fullBucketCount = section2.getUint32(32, true);\n const fullBucketSplats = fullBucketCount * bucketSize;\n const partiallyFilledBucketCount = section2.getUint32(36, true);\n const bucketsMetaDataSizeBytes = partiallyFilledBucketCount * 4;\n const bucketsStorageSizeBytes = bucketStorageSizeBytes * bucketCount + bucketsMetaDataSizeBytes;\n const sphericalHarmonicsDegree = section2.getUint16(40, true);\n const shComponents = KSPLAT_SH_DEGREE_TO_COMPONENTS[sphericalHarmonicsDegree];\n const {\n bytesPerCenter,\n bytesPerScale,\n bytesPerRotation,\n bytesPerColor,\n bytesPerSphericalHarmonicsComponent,\n scaleOffsetBytes,\n rotationOffsetBytes,\n colorOffsetBytes,\n sphericalHarmonicsOffsetBytes\n } = KSPLAT_COMPRESSION[compressionLevel];\n const bytesPerSplat = bytesPerCenter + bytesPerScale + bytesPerRotation + bytesPerColor + shComponents * bytesPerSphericalHarmonicsComponent;\n const splatDataStorageSizeBytes = bytesPerSplat * sectionMaxSplatCount;\n const storageSizeBytes = splatDataStorageSizeBytes + bucketsStorageSizeBytes;\n const sh1Index = [0, 3, 6, 1, 4, 7, 2, 5, 8];\n const sh2Index = [\n 9,\n 14,\n 19,\n 10,\n 15,\n 20,\n 11,\n 16,\n 21,\n 12,\n 17,\n 22,\n 13,\n 18,\n 23\n ];\n const sh3Index = [\n 24,\n 31,\n 38,\n 25,\n 32,\n 39,\n 26,\n 33,\n 40,\n 27,\n 34,\n 41,\n 28,\n 35,\n 42,\n 29,\n 36,\n 43,\n 30,\n 37,\n 44\n ];\n const sh1 = sphericalHarmonicsDegree >= 1 ? new Float32Array(3 * 3) : void 0;\n const sh2 = sphericalHarmonicsDegree >= 2 ? new Float32Array(5 * 3) : void 0;\n const sh3 = sphericalHarmonicsDegree >= 3 ? new Float32Array(7 * 3) : void 0;\n const compressionScaleFactor = bucketBlockSize / 2 / compressionScaleRange;\n const bucketsBase = sectionBase + bucketsMetaDataSizeBytes;\n const dataBase = sectionBase + bucketsStorageSizeBytes;\n const data = new DataView(\n fileBytes.buffer,\n dataBase,\n splatDataStorageSizeBytes\n );\n const bucketArray = new Float32Array(\n fileBytes.buffer,\n bucketsBase,\n bucketCount * 3\n );\n const partiallyFilledBucketLengths = new Uint32Array(\n fileBytes.buffer,\n sectionBase,\n partiallyFilledBucketCount\n );\n let partialBucketIndex = fullBucketCount;\n let partialBucketBase = fullBucketSplats;\n for (let i2 = 0; i2 < sectionSplatCount; ++i2) {\n const splatOffset = i2 * bytesPerSplat;\n let bucketIndex;\n if (i2 < fullBucketSplats) {\n bucketIndex = Math.floor(i2 / bucketSize);\n } else {\n const bucketLength = partiallyFilledBucketLengths[partialBucketIndex - fullBucketCount];\n if (i2 >= partialBucketBase + bucketLength) {\n partialBucketIndex += 1;\n partialBucketBase += bucketLength;\n }\n bucketIndex = partialBucketIndex;\n }\n const x2 = compressionLevel === 0 ? data.getFloat32(splatOffset + 0, true) : (data.getUint16(splatOffset + 0, true) - compressionScaleRange) * compressionScaleFactor + bucketArray[3 * bucketIndex + 0];\n const y = compressionLevel === 0 ? data.getFloat32(splatOffset + 4, true) : (data.getUint16(splatOffset + 2, true) - compressionScaleRange) * compressionScaleFactor + bucketArray[3 * bucketIndex + 1];\n const z = compressionLevel === 0 ? data.getFloat32(splatOffset + 8, true) : (data.getUint16(splatOffset + 4, true) - compressionScaleRange) * compressionScaleFactor + bucketArray[3 * bucketIndex + 2];\n const scaleX = compressionLevel === 0 ? data.getFloat32(splatOffset + scaleOffsetBytes + 0, true) : fromHalf(data.getUint16(splatOffset + scaleOffsetBytes + 0, true));\n const scaleY = compressionLevel === 0 ? data.getFloat32(splatOffset + scaleOffsetBytes + 4, true) : fromHalf(data.getUint16(splatOffset + scaleOffsetBytes + 2, true));\n const scaleZ = compressionLevel === 0 ? data.getFloat32(splatOffset + scaleOffsetBytes + 8, true) : fromHalf(data.getUint16(splatOffset + scaleOffsetBytes + 4, true));\n const quatW = compressionLevel === 0 ? data.getFloat32(splatOffset + rotationOffsetBytes + 0, true) : fromHalf(\n data.getUint16(splatOffset + rotationOffsetBytes + 0, true)\n );\n const quatX = compressionLevel === 0 ? data.getFloat32(splatOffset + rotationOffsetBytes + 4, true) : fromHalf(\n data.getUint16(splatOffset + rotationOffsetBytes + 2, true)\n );\n const quatY = compressionLevel === 0 ? data.getFloat32(splatOffset + rotationOffsetBytes + 8, true) : fromHalf(\n data.getUint16(splatOffset + rotationOffsetBytes + 4, true)\n );\n const quatZ = compressionLevel === 0 ? data.getFloat32(splatOffset + rotationOffsetBytes + 12, true) : fromHalf(\n data.getUint16(splatOffset + rotationOffsetBytes + 6, true)\n );\n const r = data.getUint8(splatOffset + colorOffsetBytes + 0) / 255;\n const g = data.getUint8(splatOffset + colorOffsetBytes + 1) / 255;\n const b = data.getUint8(splatOffset + colorOffsetBytes + 2) / 255;\n const opacity = data.getUint8(splatOffset + colorOffsetBytes + 3) / 255;\n splatCallback(\n i2,\n x2,\n y,\n z,\n scaleX,\n scaleY,\n scaleZ,\n quatX,\n quatY,\n quatZ,\n quatW,\n opacity,\n r,\n g,\n b\n );\n if (sphericalHarmonicsDegree >= 1 && sh1) {\n for (const [i22, key] of sh1Index.entries()) {\n sh1[i22] = getSh(splatOffset, key);\n }\n if (sh2) {\n for (const [i22, key] of sh2Index.entries()) {\n sh2[i22] = getSh(splatOffset, key);\n }\n }\n if (sh3) {\n for (const [i22, key] of sh3Index.entries()) {\n sh3[i22] = getSh(splatOffset, key);\n }\n }\n shCallback == null ? void 0 : shCallback(i2, sh1, sh2, sh3);\n }\n }\n sectionBase += storageSizeBytes;\n }\n }\n function unpackKsplat(fileBytes, splatEncoding) {\n var _a2;\n const HEADER_BYTES = 4096;\n const SECTION_BYTES = 1024;\n let headerOffset = 0;\n const header = new DataView(fileBytes.buffer, headerOffset, HEADER_BYTES);\n headerOffset += HEADER_BYTES;\n const versionMajor = header.getUint8(0);\n const versionMinor = header.getUint8(1);\n if (versionMajor !== 0 || versionMinor < 1) {\n throw new Error(\n `Unsupported .ksplat version: ${versionMajor}.${versionMinor}`\n );\n }\n const maxSectionCount = header.getUint32(4, true);\n const splatCount = header.getUint32(16, true);\n const compressionLevel = header.getUint16(20, true);\n if (compressionLevel < 0 || compressionLevel > 2) {\n throw new Error(`Invalid .ksplat compression level: ${compressionLevel}`);\n }\n const minSphericalHarmonicsCoeff = header.getFloat32(36, true) || -1.5;\n const maxSphericalHarmonicsCoeff = header.getFloat32(40, true) || 1.5;\n const numSplats = splatCount;\n const maxSplats = computeMaxSplats(numSplats);\n const packedArray = new Uint32Array(maxSplats * 4);\n const extra = {};\n let sectionBase = HEADER_BYTES + maxSectionCount * SECTION_BYTES;\n for (let section = 0; section < maxSectionCount; ++section) {\n let getSh = function(splatOffset, component) {\n if (compressionLevel === 0) {\n return data.getFloat32(\n splatOffset + sphericalHarmonicsOffsetBytes + component * 4,\n true\n );\n }\n if (compressionLevel === 1) {\n return fromHalf(\n data.getUint16(\n splatOffset + sphericalHarmonicsOffsetBytes + component * 2,\n true\n )\n );\n }\n const t = data.getUint8(splatOffset + sphericalHarmonicsOffsetBytes + component) / 255;\n return minSphericalHarmonicsCoeff + t * (maxSphericalHarmonicsCoeff - minSphericalHarmonicsCoeff);\n };\n const section2 = new DataView(fileBytes.buffer, headerOffset, SECTION_BYTES);\n headerOffset += SECTION_BYTES;\n const sectionSplatCount = section2.getUint32(0, true);\n const sectionMaxSplatCount = section2.getUint32(4, true);\n const bucketSize = section2.getUint32(8, true);\n const bucketCount = section2.getUint32(12, true);\n const bucketBlockSize = section2.getFloat32(16, true);\n const bucketStorageSizeBytes = section2.getUint16(20, true);\n const compressionScaleRange = (section2.getUint32(24, true) || ((_a2 = KSPLAT_COMPRESSION[compressionLevel]) == null ? void 0 : _a2.scaleRange)) ?? 1;\n const fullBucketCount = section2.getUint32(32, true);\n const fullBucketSplats = fullBucketCount * bucketSize;\n const partiallyFilledBucketCount = section2.getUint32(36, true);\n const bucketsMetaDataSizeBytes = partiallyFilledBucketCount * 4;\n const bucketsStorageSizeBytes = bucketStorageSizeBytes * bucketCount + bucketsMetaDataSizeBytes;\n const sphericalHarmonicsDegree = section2.getUint16(40, true);\n const shComponents = KSPLAT_SH_DEGREE_TO_COMPONENTS[sphericalHarmonicsDegree];\n const {\n bytesPerCenter,\n bytesPerScale,\n bytesPerRotation,\n bytesPerColor,\n bytesPerSphericalHarmonicsComponent,\n scaleOffsetBytes,\n rotationOffsetBytes,\n colorOffsetBytes,\n sphericalHarmonicsOffsetBytes\n } = KSPLAT_COMPRESSION[compressionLevel];\n const bytesPerSplat = bytesPerCenter + bytesPerScale + bytesPerRotation + bytesPerColor + shComponents * bytesPerSphericalHarmonicsComponent;\n const splatDataStorageSizeBytes = bytesPerSplat * sectionMaxSplatCount;\n const storageSizeBytes = splatDataStorageSizeBytes + bucketsStorageSizeBytes;\n const sh1Index = [0, 3, 6, 1, 4, 7, 2, 5, 8];\n const sh2Index = [\n 9,\n 14,\n 19,\n 10,\n 15,\n 20,\n 11,\n 16,\n 21,\n 12,\n 17,\n 22,\n 13,\n 18,\n 23\n ];\n const sh3Index = [\n 24,\n 31,\n 38,\n 25,\n 32,\n 39,\n 26,\n 33,\n 40,\n 27,\n 34,\n 41,\n 28,\n 35,\n 42,\n 29,\n 36,\n 43,\n 30,\n 37,\n 44\n ];\n const sh1 = sphericalHarmonicsDegree >= 1 ? new Float32Array(3 * 3) : void 0;\n const sh2 = sphericalHarmonicsDegree >= 2 ? new Float32Array(5 * 3) : void 0;\n const sh3 = sphericalHarmonicsDegree >= 3 ? new Float32Array(7 * 3) : void 0;\n const compressionScaleFactor = bucketBlockSize / 2 / compressionScaleRange;\n const bucketsBase = sectionBase + bucketsMetaDataSizeBytes;\n const dataBase = sectionBase + bucketsStorageSizeBytes;\n const data = new DataView(\n fileBytes.buffer,\n dataBase,\n splatDataStorageSizeBytes\n );\n const bucketArray = new Float32Array(\n fileBytes.buffer,\n bucketsBase,\n bucketCount * 3\n );\n const partiallyFilledBucketLengths = new Uint32Array(\n fileBytes.buffer,\n sectionBase,\n partiallyFilledBucketCount\n );\n let partialBucketIndex = fullBucketCount;\n let partialBucketBase = fullBucketSplats;\n for (let i2 = 0; i2 < sectionSplatCount; ++i2) {\n const splatOffset = i2 * bytesPerSplat;\n let bucketIndex;\n if (i2 < fullBucketSplats) {\n bucketIndex = Math.floor(i2 / bucketSize);\n } else {\n const bucketLength = partiallyFilledBucketLengths[partialBucketIndex - fullBucketCount];\n if (i2 >= partialBucketBase + bucketLength) {\n partialBucketIndex += 1;\n partialBucketBase += bucketLength;\n }\n bucketIndex = partialBucketIndex;\n }\n const x2 = compressionLevel === 0 ? data.getFloat32(splatOffset + 0, true) : (data.getUint16(splatOffset + 0, true) - compressionScaleRange) * compressionScaleFactor + bucketArray[3 * bucketIndex + 0];\n const y = compressionLevel === 0 ? data.getFloat32(splatOffset + 4, true) : (data.getUint16(splatOffset + 2, true) - compressionScaleRange) * compressionScaleFactor + bucketArray[3 * bucketIndex + 1];\n const z = compressionLevel === 0 ? data.getFloat32(splatOffset + 8, true) : (data.getUint16(splatOffset + 4, true) - compressionScaleRange) * compressionScaleFactor + bucketArray[3 * bucketIndex + 2];\n const scaleX = compressionLevel === 0 ? data.getFloat32(splatOffset + scaleOffsetBytes + 0, true) : fromHalf(data.getUint16(splatOffset + scaleOffsetBytes + 0, true));\n const scaleY = compressionLevel === 0 ? data.getFloat32(splatOffset + scaleOffsetBytes + 4, true) : fromHalf(data.getUint16(splatOffset + scaleOffsetBytes + 2, true));\n const scaleZ = compressionLevel === 0 ? data.getFloat32(splatOffset + scaleOffsetBytes + 8, true) : fromHalf(data.getUint16(splatOffset + scaleOffsetBytes + 4, true));\n const quatW = compressionLevel === 0 ? data.getFloat32(splatOffset + rotationOffsetBytes + 0, true) : fromHalf(\n data.getUint16(splatOffset + rotationOffsetBytes + 0, true)\n );\n const quatX = compressionLevel === 0 ? data.getFloat32(splatOffset + rotationOffsetBytes + 4, true) : fromHalf(\n data.getUint16(splatOffset + rotationOffsetBytes + 2, true)\n );\n const quatY = compressionLevel === 0 ? data.getFloat32(splatOffset + rotationOffsetBytes + 8, true) : fromHalf(\n data.getUint16(splatOffset + rotationOffsetBytes + 4, true)\n );\n const quatZ = compressionLevel === 0 ? data.getFloat32(splatOffset + rotationOffsetBytes + 12, true) : fromHalf(\n data.getUint16(splatOffset + rotationOffsetBytes + 6, true)\n );\n const r = data.getUint8(splatOffset + colorOffsetBytes + 0) / 255;\n const g = data.getUint8(splatOffset + colorOffsetBytes + 1) / 255;\n const b = data.getUint8(splatOffset + colorOffsetBytes + 2) / 255;\n const opacity = data.getUint8(splatOffset + colorOffsetBytes + 3) / 255;\n setPackedSplat(\n packedArray,\n i2,\n x2,\n y,\n z,\n scaleX,\n scaleY,\n scaleZ,\n quatX,\n quatY,\n quatZ,\n quatW,\n opacity,\n r,\n g,\n b,\n splatEncoding\n );\n if (sphericalHarmonicsDegree >= 1) {\n if (sh1) {\n if (!extra.sh1) {\n extra.sh1 = new Uint32Array(numSplats * 2);\n }\n for (const [i22, key] of sh1Index.entries()) {\n sh1[i22] = getSh(splatOffset, key);\n }\n encodeSh1Rgb(extra.sh1, i2, sh1, splatEncoding);\n }\n if (sh2) {\n if (!extra.sh2) {\n extra.sh2 = new Uint32Array(numSplats * 4);\n }\n for (const [i22, key] of sh2Index.entries()) {\n sh2[i22] = getSh(splatOffset, key);\n }\n encodeSh2Rgb(extra.sh2, i2, sh2, splatEncoding);\n }\n if (sh3) {\n if (!extra.sh3) {\n extra.sh3 = new Uint32Array(numSplats * 4);\n }\n for (const [i22, key] of sh3Index.entries()) {\n sh3[i22] = getSh(splatOffset, key);\n }\n encodeSh3Rgb(extra.sh3, i2, sh3, splatEncoding);\n }\n }\n }\n sectionBase += storageSizeBytes;\n }\n return { packedArray, numSplats, extra };\n }\n const PLY_PROPERTY_TYPES = [\n "char",\n "uchar",\n "short",\n "ushort",\n "int",\n "uint",\n "float",\n "double"\n ];\n const _PlyReader = class _PlyReader {\n // Create a PlyReader from a Uint8Array/ArrayBuffer, no parsing done yet\n constructor({ fileBytes }) {\n this.header = "";\n this.littleEndian = true;\n this.elements = {};\n this.comments = [];\n this.data = null;\n this.numSplats = 0;\n this.fileBytes = fileBytes instanceof ArrayBuffer ? new Uint8Array(fileBytes) : fileBytes;\n }\n // Identify and parse the PLY text header (assumed to be <64KB in size).\n // this.elements will contain all the elements in the file, typically\n // "vertex" contains the Gsplat data.\n async parseHeader() {\n const bufferStream = new ReadableStream({\n start: (controller) => {\n controller.enqueue(this.fileBytes.slice(0, 65536));\n controller.close();\n }\n });\n const decoder = bufferStream.pipeThrough(new TextDecoderStream()).getReader();\n this.header = "";\n const headerTerminator = "end_header\\n";\n while (true) {\n const { value, done } = await decoder.read();\n if (done) {\n throw new Error("Failed to read header");\n }\n this.header += value;\n const endHeader = this.header.indexOf(headerTerminator);\n if (endHeader >= 0) {\n this.header = this.header.slice(0, endHeader + headerTerminator.length);\n break;\n }\n }\n const headerLen = new TextEncoder().encode(this.header).length;\n this.data = new DataView(this.fileBytes.buffer, headerLen);\n this.elements = {};\n let curElement = null;\n this.comments = [];\n this.header.trim().split("\\n").forEach((line, lineIndex) => {\n const trimmedLine = line.trim();\n if (lineIndex === 0) {\n if (trimmedLine !== "ply") {\n throw new Error("Invalid PLY header");\n }\n return;\n }\n if (trimmedLine.length === 0) {\n return;\n }\n const fields = trimmedLine.split(" ");\n switch (fields[0]) {\n case "format":\n if (fields[1] === "binary_little_endian") {\n this.littleEndian = true;\n } else if (fields[1] === "binary_big_endian") {\n this.littleEndian = false;\n } else {\n throw new Error(`Unsupported PLY format: ${fields[1]}`);\n }\n if (fields[2] !== "1.0") {\n throw new Error(`Unsupported PLY version: ${fields[2]}`);\n }\n break;\n case "end_header":\n break;\n case "comment":\n this.comments.push(trimmedLine.slice("comment ".length));\n break;\n case "element": {\n const name = fields[1];\n curElement = {\n name,\n count: Number.parseInt(fields[2]),\n properties: {}\n };\n this.elements[name] = curElement;\n break;\n }\n case "property":\n if (curElement == null) {\n throw new Error("Property must be inside an element");\n }\n if (fields[1] === "list") {\n curElement.properties[fields[4]] = {\n isList: true,\n type: fields[3],\n countType: fields[2]\n };\n } else {\n curElement.properties[fields[2]] = {\n isList: false,\n type: fields[1]\n };\n }\n break;\n }\n });\n if (this.elements.vertex) {\n this.numSplats = this.elements.vertex.count;\n }\n }\n parseData(elementCallback) {\n let offset = 0;\n const data = this.data;\n if (data == null) {\n throw new Error("No data to parse");\n }\n for (const elementName in this.elements) {\n const element = this.elements[elementName];\n const { count, properties } = element;\n const item = createEmptyItem(properties);\n const parseFn = createParseFn(properties, this.littleEndian);\n const callback = elementCallback(element) ?? (() => {\n });\n for (let index = 0; index < count; index++) {\n offset = parseFn(data, offset, item);\n callback(index, item);\n }\n }\n }\n // Parse all the Gsplat data in the PLY file in go, invoking the given\n // callbacks for each Gsplat.\n parseSplats(splatCallback, shCallback) {\n if (this.elements.vertex == null) {\n throw new Error("No vertex element found");\n }\n let isSuperSplat = false;\n const ssChunks = [];\n let numSh = 0;\n let sh1Props = [];\n let sh2Props = [];\n let sh3Props = [];\n let sh1 = void 0;\n let sh2 = void 0;\n let sh3 = void 0;\n function prepareSh() {\n const num_f_rest = NUM_SH_TO_NUM_F_REST[numSh];\n sh1Props = new Array(3).fill(null).flatMap((_, k) => [0, 1, 2].map((_2, d) => k + d * num_f_rest / 3));\n sh2Props = new Array(5).fill(null).flatMap(\n (_, k) => [0, 1, 2].map((_2, d) => 3 + k + d * num_f_rest / 3)\n );\n sh3Props = new Array(7).fill(null).flatMap(\n (_, k) => [0, 1, 2].map((_2, d) => 8 + k + d * num_f_rest / 3)\n );\n sh1 = numSh >= 1 ? new Float32Array(3 * 3) : void 0;\n sh2 = numSh >= 2 ? new Float32Array(5 * 3) : void 0;\n sh3 = numSh >= 3 ? new Float32Array(7 * 3) : void 0;\n }\n function ssShCallback(index, item) {\n if (!sh1) {\n throw new Error("Missing sh1");\n }\n const sh = item.f_rest;\n for (let i2 = 0; i2 < sh1Props.length; i2++) {\n sh1[i2] = sh[sh1Props[i2]] * 8 / 255 - 4;\n }\n if (sh2) {\n for (let i2 = 0; i2 < sh2Props.length; i2++) {\n sh2[i2] = sh[sh2Props[i2]] * 8 / 255 - 4;\n }\n }\n if (sh3) {\n for (let i2 = 0; i2 < sh3Props.length; i2++) {\n sh3[i2] = sh[sh3Props[i2]] * 8 / 255 - 4;\n }\n }\n shCallback == null ? void 0 : shCallback(index, sh1, sh2, sh3);\n }\n function initSuperSplat(element) {\n const {\n min_x,\n min_y,\n min_z,\n max_x,\n max_y,\n max_z,\n min_scale_x,\n min_scale_y,\n min_scale_z,\n max_scale_x,\n max_scale_y,\n max_scale_z\n } = element.properties;\n if (!min_x || !min_y || !min_z || !max_x || !max_y || !max_z || !min_scale_x || !min_scale_y || !min_scale_z || !max_scale_x || !max_scale_y || !max_scale_z) {\n throw new Error("Missing PLY chunk properties");\n }\n isSuperSplat = true;\n return (index, item) => {\n const {\n min_x: min_x2,\n min_y: min_y2,\n min_z: min_z2,\n max_x: max_x2,\n max_y: max_y2,\n max_z: max_z2,\n min_scale_x: min_scale_x2,\n min_scale_y: min_scale_y2,\n min_scale_z: min_scale_z2,\n max_scale_x: max_scale_x2,\n max_scale_y: max_scale_y2,\n max_scale_z: max_scale_z2,\n min_r,\n min_g,\n min_b,\n max_r,\n max_g,\n max_b\n } = item;\n ssChunks.push({\n min_x: min_x2,\n min_y: min_y2,\n min_z: min_z2,\n max_x: max_x2,\n max_y: max_y2,\n max_z: max_z2,\n min_scale_x: min_scale_x2,\n min_scale_y: min_scale_y2,\n min_scale_z: min_scale_z2,\n max_scale_x: max_scale_x2,\n max_scale_y: max_scale_y2,\n max_scale_z: max_scale_z2,\n min_r,\n min_g,\n min_b,\n max_r,\n max_g,\n max_b\n });\n };\n }\n function decodeSuperSplat(element) {\n if (shCallback && element.name === "sh") {\n numSh = getNumSh(element.properties);\n prepareSh();\n return ssShCallback;\n }\n if (element.name !== "vertex") {\n return null;\n }\n const { packed_position, packed_rotation, packed_scale, packed_color } = element.properties;\n if (!packed_position || !packed_rotation || !packed_scale || !packed_color) {\n throw new Error(\n "Missing PLY properties: packed_position, packed_rotation, packed_scale, packed_color"\n );\n }\n const SQRT2 = Math.sqrt(2);\n return (index, item) => {\n const chunk = ssChunks[index >>> 8];\n if (chunk == null) {\n throw new Error("Missing PLY chunk");\n }\n const {\n min_x,\n min_y,\n min_z,\n max_x,\n max_y,\n max_z,\n min_scale_x,\n min_scale_y,\n min_scale_z,\n max_scale_x,\n max_scale_y,\n max_scale_z,\n min_r,\n min_g,\n min_b,\n max_r,\n max_g,\n max_b\n } = chunk;\n const { packed_position: packed_position2, packed_rotation: packed_rotation2, packed_scale: packed_scale2, packed_color: packed_color2 } = item;\n const x2 = (packed_position2 >>> 21 & 2047) / 2047 * (max_x - min_x) + min_x;\n const y = (packed_position2 >>> 11 & 1023) / 1023 * (max_y - min_y) + min_y;\n const z = (packed_position2 & 2047) / 2047 * (max_z - min_z) + min_z;\n const r0 = ((packed_rotation2 >>> 20 & 1023) / 1023 - 0.5) * SQRT2;\n const r1 = ((packed_rotation2 >>> 10 & 1023) / 1023 - 0.5) * SQRT2;\n const r2 = ((packed_rotation2 & 1023) / 1023 - 0.5) * SQRT2;\n const rr = Math.sqrt(Math.max(0, 1 - r0 * r0 - r1 * r1 - r2 * r2));\n const rOrder = packed_rotation2 >>> 30;\n const quatX = rOrder === 0 ? r0 : rOrder === 1 ? rr : r1;\n const quatY = rOrder <= 1 ? r1 : rOrder === 2 ? rr : r2;\n const quatZ = rOrder <= 2 ? r2 : rr;\n const quatW = rOrder === 0 ? rr : r0;\n const scaleX = Math.exp(\n (packed_scale2 >>> 21 & 2047) / 2047 * (max_scale_x - min_scale_x) + min_scale_x\n );\n const scaleY = Math.exp(\n (packed_scale2 >>> 11 & 1023) / 1023 * (max_scale_y - min_scale_y) + min_scale_y\n );\n const scaleZ = Math.exp(\n (packed_scale2 & 2047) / 2047 * (max_scale_z - min_scale_z) + min_scale_z\n );\n const r = (packed_color2 >>> 24 & 255) / 255 * ((max_r ?? 1) - (min_r ?? 0)) + (min_r ?? 0);\n const g = (packed_color2 >>> 16 & 255) / 255 * ((max_g ?? 1) - (min_g ?? 0)) + (min_g ?? 0);\n const b = (packed_color2 >>> 8 & 255) / 255 * ((max_b ?? 1) - (min_b ?? 0)) + (min_b ?? 0);\n const opacity = (packed_color2 & 255) / 255;\n splatCallback(\n index,\n x2,\n y,\n z,\n scaleX,\n scaleY,\n scaleZ,\n quatX,\n quatY,\n quatZ,\n quatW,\n opacity,\n r,\n g,\n b\n );\n };\n }\n const elementCallback = (element) => {\n if (element.name === "chunk") {\n return initSuperSplat(element);\n }\n if (isSuperSplat) {\n return decodeSuperSplat(element);\n }\n if (element.name !== "vertex") {\n return null;\n }\n const {\n x: x2,\n y,\n z,\n scale_0,\n scale_1,\n scale_2,\n rot_0,\n rot_1,\n rot_2,\n rot_3,\n opacity,\n f_dc_0,\n f_dc_1,\n f_dc_2,\n red,\n green,\n blue,\n alpha\n } = element.properties;\n if (!x2 || !y || !z) {\n throw new Error("Missing PLY properties: x, y, z");\n }\n const hasScales = scale_0 && scale_1 && scale_2;\n const hasRots = rot_0 && rot_1 && rot_2 && rot_3;\n const alphaDiv = alpha != null ? FIELD_SCALE[alpha.type] : 1;\n const redDiv = red != null ? FIELD_SCALE[red.type] : 1;\n const greenDiv = green != null ? FIELD_SCALE[green.type] : 1;\n const blueDiv = blue != null ? FIELD_SCALE[blue.type] : 1;\n numSh = getNumSh(element.properties);\n prepareSh();\n return (index, item) => {\n const scaleX = hasScales ? Math.exp(item.scale_0) : _PlyReader.defaultPointScale;\n const scaleY = hasScales ? Math.exp(item.scale_1) : _PlyReader.defaultPointScale;\n const scaleZ = hasScales ? Math.exp(item.scale_2) : _PlyReader.defaultPointScale;\n const quatX = hasRots ? item.rot_1 : 0;\n const quatY = hasRots ? item.rot_2 : 0;\n const quatZ = hasRots ? item.rot_3 : 0;\n const quatW = hasRots ? item.rot_0 : 1;\n const op = opacity != null ? 1 / (1 + Math.exp(-item.opacity)) : alpha != null ? item.alpha / alphaDiv : 1;\n const r = f_dc_0 != null ? item.f_dc_0 * SH_C0$1 + 0.5 : red != null ? item.red / redDiv : 1;\n const g = f_dc_1 != null ? item.f_dc_1 * SH_C0$1 + 0.5 : green != null ? item.green / greenDiv : 1;\n const b = f_dc_2 != null ? item.f_dc_2 * SH_C0$1 + 0.5 : blue != null ? item.blue / blueDiv : 1;\n splatCallback(\n index,\n item.x,\n item.y,\n item.z,\n scaleX,\n scaleY,\n scaleZ,\n quatX,\n quatY,\n quatZ,\n quatW,\n op,\n r,\n g,\n b\n );\n if (shCallback && sh1) {\n const sh = item.f_rest;\n if (sh1) {\n for (let i2 = 0; i2 < sh1Props.length; i2++) {\n sh1[i2] = sh[sh1Props[i2]];\n }\n }\n if (sh2) {\n for (let i2 = 0; i2 < sh2Props.length; i2++) {\n sh2[i2] = sh[sh2Props[i2]];\n }\n }\n if (sh3) {\n for (let i2 = 0; i2 < sh3Props.length; i2++) {\n sh3[i2] = sh[sh3Props[i2]];\n }\n }\n shCallback(index, sh1, sh2, sh3);\n }\n };\n };\n this.parseData(elementCallback);\n }\n // Inject RGBA values into original PLY file, which can be used to modify\n // the color/opacity of the Gsplats and write out the modified PLY file.\n injectRgba(rgba) {\n let offset = 0;\n const data = this.data;\n if (data == null) {\n throw new Error("No parsed data");\n }\n if (rgba.length !== this.numSplats * 4) {\n throw new Error("Invalid RGBA array length");\n }\n for (const elementName in this.elements) {\n const element = this.elements[elementName];\n const { count, properties } = element;\n const parsers = [];\n let rgbaOffset = 0;\n const isVertex = elementName === "vertex";\n if (isVertex) {\n for (const name of ["opacity", "f_dc_0", "f_dc_1", "f_dc_2"]) {\n if (!properties[name] || properties[name].type !== "float") {\n throw new Error(`Can\'t injectRgba due to property: ${name}`);\n }\n }\n }\n for (const [propertyName, property] of Object.entries(properties)) {\n if (!property.isList) {\n if (isVertex) {\n if (propertyName === "f_dc_0" || propertyName === "f_dc_1" || propertyName === "f_dc_2") {\n const component = Number.parseInt(\n propertyName.slice("f_dc_".length)\n );\n parsers.push(() => {\n const value = (rgba[rgbaOffset + component] / 255 - 0.5) / SH_C0$1;\n SET_FIELD[property.type](\n data,\n offset,\n this.littleEndian,\n value\n );\n });\n } else if (propertyName === "opacity") {\n parsers.push(() => {\n const value = Math.max(\n -100,\n Math.min(\n 100,\n -Math.log(1 / (rgba[rgbaOffset + 3] / 255) - 1)\n )\n );\n SET_FIELD[property.type](\n data,\n offset,\n this.littleEndian,\n value\n );\n });\n }\n }\n parsers.push(() => {\n offset += FIELD_BYTES[property.type];\n });\n } else {\n parsers.push(() => {\n const length = PARSE_FIELD[property.countType](\n data,\n offset,\n this.littleEndian\n );\n offset += FIELD_BYTES[property.countType];\n offset += length * FIELD_BYTES[property.type];\n });\n }\n }\n for (let index = 0; index < count; index++) {\n for (const parser of parsers) {\n parser();\n }\n if (isVertex) {\n rgbaOffset += 4;\n }\n }\n }\n }\n };\n _PlyReader.defaultPointScale = 1e-3;\n let PlyReader = _PlyReader;\n const SH_C0$1 = 0.28209479177387814;\n const PARSE_FIELD = {\n char: (data, offset, littleEndian) => {\n return data.getInt8(offset);\n },\n uchar: (data, offset, littleEndian) => {\n return data.getUint8(offset);\n },\n short: (data, offset, littleEndian) => {\n return data.getInt16(offset, littleEndian);\n },\n ushort: (data, offset, littleEndian) => {\n return data.getUint16(offset, littleEndian);\n },\n int: (data, offset, littleEndian) => {\n return data.getInt32(offset, littleEndian);\n },\n uint: (data, offset, littleEndian) => {\n return data.getUint32(offset, littleEndian);\n },\n float: (data, offset, littleEndian) => {\n return data.getFloat32(offset, littleEndian);\n },\n double: (data, offset, littleEndian) => {\n return data.getFloat64(offset, littleEndian);\n }\n };\n const SET_FIELD = {\n char: (data, offset, littleEndian, value) => {\n data.setInt8(offset, value);\n },\n uchar: (data, offset, littleEndian, value) => {\n data.setUint8(offset, value);\n },\n short: (data, offset, littleEndian, value) => {\n data.setInt16(offset, value, littleEndian);\n },\n ushort: (data, offset, littleEndian, value) => {\n data.setUint16(offset, value, littleEndian);\n },\n int: (data, offset, littleEndian, value) => {\n data.setInt32(offset, value, littleEndian);\n },\n uint: (data, offset, littleEndian, value) => {\n data.setUint32(offset, value, littleEndian);\n },\n float: (data, offset, littleEndian, value) => {\n data.setFloat32(offset, value, littleEndian);\n },\n double: (data, offset, littleEndian, value) => {\n data.setFloat64(offset, value, littleEndian);\n }\n };\n const FIELD_BYTES = {\n char: 1,\n uchar: 1,\n short: 2,\n ushort: 2,\n int: 4,\n uint: 4,\n float: 4,\n double: 8\n };\n const FIELD_SCALE = {\n char: 127,\n uchar: 255,\n short: 32767,\n ushort: 65535,\n int: 2147483647,\n uint: 4294967295,\n float: 1,\n double: 1\n };\n const NUM_F_REST_TO_NUM_SH = {\n 0: 0,\n 9: 1,\n 24: 2,\n 45: 3\n };\n const NUM_SH_TO_NUM_F_REST = {\n 0: 0,\n 1: 9,\n 2: 24,\n 3: 45\n };\n const F_REST_REGEX = /^f_rest_([0-9]{1,2})$/;\n function createEmptyItem(properties) {\n const item = {};\n for (const [propertyName, property] of Object.entries(properties)) {\n if (F_REST_REGEX.test(propertyName)) {\n item.f_rest = new Array(getNumSh(properties));\n } else {\n item[propertyName] = property.isList ? [] : 0;\n }\n }\n return item;\n }\n function createParseFn(properties, littleEndian) {\n if (safeToCompile(properties)) {\n return createCompiledParserFn(properties, littleEndian);\n }\n return createDynamicParserFn(properties, littleEndian);\n }\n const UNSAFE_EVAL_ALLOWED = (() => {\n try {\n new Function("return 42;");\n } catch (e) {\n return false;\n }\n return true;\n })();\n const PROPERTY_NAME_REGEX = /^[a-zA-Z0-9_]+$/;\n function safeToCompile(properties) {\n if (!UNSAFE_EVAL_ALLOWED) {\n return false;\n }\n for (const [propertyName, property] of Object.entries(properties)) {\n if (!PROPERTY_NAME_REGEX.test(propertyName)) {\n return false;\n }\n if (property.isList && !PLY_PROPERTY_TYPES.includes(property.countType)) {\n return false;\n }\n if (!PLY_PROPERTY_TYPES.includes(property.type)) {\n return false;\n }\n }\n return true;\n }\n function createCompiledParserFn(properties, littleEndian) {\n const parserSrc = ["let list;"];\n for (const [propertyName, property] of Object.entries(properties)) {\n const fRestMatch = propertyName.match(F_REST_REGEX);\n if (fRestMatch) {\n const fRestIndex = +fRestMatch[1];\n parserSrc.push(\n /*js*/\n `\n item.f_rest[${fRestIndex}] = PARSE_FIELD[\'${property.type}\'](data, offset, ${littleEndian});\n offset += ${FIELD_BYTES[property.type]};\n `\n );\n } else if (!property.isList) {\n parserSrc.push(\n /*js*/\n `\n item[\'${propertyName}\'] = PARSE_FIELD[\'${property.type}\'](data, offset, ${littleEndian});\n offset += ${FIELD_BYTES[property.type]};\n `\n );\n } else {\n parserSrc.push(\n /*js*/\n `\n list = item[\'${propertyName}\'];\n list.length = PARSE_FIELD[\'${property.countType}\'](data, offset, ${littleEndian});\n offset += ${FIELD_BYTES[property.countType]};\n for (let i = 0; i < list.length; i++) {\n list[i] = PARSE_FIELD[\'${property.type}\'](data, offset, ${littleEndian});\n offset += ${FIELD_BYTES[property.type]};\n }\n `\n );\n }\n }\n parserSrc.push("return offset;");\n const fn = new Function(\n "data",\n "offset",\n "item",\n "PARSE_FIELD",\n parserSrc.join("\\n")\n );\n return (data, offset, item) => fn(data, offset, item, PARSE_FIELD);\n }\n function createDynamicParserFn(properties, littleEndian) {\n const parsers = [];\n for (const [propertyName, property] of Object.entries(properties)) {\n const fRestMatch = propertyName.match(F_REST_REGEX);\n if (fRestMatch) {\n const fRestIndex = +fRestMatch[1];\n parsers.push(\n (data, offset, item) => {\n item.f_rest[fRestIndex] = PARSE_FIELD[property.type](\n data,\n offset,\n littleEndian\n );\n return offset + FIELD_BYTES[property.type];\n }\n );\n } else if (!property.isList) {\n parsers.push(\n (data, offset, item) => {\n item[propertyName] = PARSE_FIELD[property.type](\n data,\n offset,\n littleEndian\n );\n return offset + FIELD_BYTES[property.type];\n }\n );\n } else {\n parsers.push(\n (data, offset, item) => {\n const list = item[propertyName];\n list.length = PARSE_FIELD[property.countType](\n data,\n offset,\n littleEndian\n );\n let currentOffset = offset + FIELD_BYTES[property.countType];\n for (let i2 = 0; i2 < list.length; i2++) {\n list[i2] = PARSE_FIELD[property.type](\n data,\n currentOffset,\n littleEndian\n );\n currentOffset += FIELD_BYTES[property.type];\n }\n return currentOffset;\n }\n );\n }\n }\n return (data, offset, item) => {\n let currentOffset = offset;\n for (let parserIndex = 0; parserIndex < parsers.length; parserIndex++) {\n currentOffset = parsers[parserIndex](data, currentOffset, item);\n }\n return currentOffset;\n };\n }\n function getNumSh(properties) {\n let num_f_rest = 0;\n while (properties[`f_rest_${num_f_rest}`]) {\n num_f_rest += 1;\n }\n const numSh = NUM_F_REST_TO_NUM_SH[num_f_rest];\n if (numSh == null) {\n throw new Error(`Unsupported number of SH coefficients: ${num_f_rest}`);\n }\n return numSh;\n }\n var SplatFileType = /* @__PURE__ */ ((SplatFileType2) => {\n SplatFileType2["PLY"] = "ply";\n SplatFileType2["SPZ"] = "spz";\n SplatFileType2["SPLAT"] = "splat";\n SplatFileType2["KSPLAT"] = "ksplat";\n SplatFileType2["PCSOGS"] = "pcsogs";\n SplatFileType2["PCSOGSZIP"] = "pcsogszip";\n return SplatFileType2;\n })(SplatFileType || {});\n function getSplatFileType(fileBytes) {\n const view = new DataView(fileBytes.buffer);\n if ((view.getUint32(0, true) & 16777215) === 7957616) {\n return "ply";\n }\n if ((view.getUint32(0, true) & 16777215) === 559903) {\n const header = decompressPartialGzip(fileBytes, 4);\n const gView = new DataView(header.buffer);\n if (gView.getUint32(0, true) === 1347635022) {\n return "spz";\n }\n return void 0;\n }\n if (view.getUint32(0, true) === 67324752) {\n if (tryPcSogsZip(fileBytes)) {\n return "pcsogszip";\n }\n return void 0;\n }\n return void 0;\n }\n function getFileExtension(pathOrUrl) {\n const noTrailing = pathOrUrl.split(/[?#]/, 1)[0];\n const lastSlash = Math.max(\n noTrailing.lastIndexOf("/"),\n noTrailing.lastIndexOf("\\\\")\n );\n const filename = noTrailing.slice(lastSlash + 1);\n const lastDot = filename.lastIndexOf(".");\n if (lastDot <= 0 || lastDot === filename.length - 1) {\n return "";\n }\n return filename.slice(lastDot + 1).toLowerCase();\n }\n function getSplatFileTypeFromPath(pathOrUrl) {\n const extension = getFileExtension(pathOrUrl);\n if (extension === "ply") {\n return "ply";\n }\n if (extension === "spz") {\n return "spz";\n }\n if (extension === "splat") {\n return "splat";\n }\n if (extension === "ksplat") {\n return "ksplat";\n }\n if (extension === "sog") {\n return "pcsogszip";\n }\n return void 0;\n }\n function tryPcSogs(input) {\n try {\n let text;\n if (typeof input === "string") {\n text = input;\n } else {\n const fileBytes = input instanceof ArrayBuffer ? new Uint8Array(input) : input;\n if (fileBytes.length > 65536) {\n return void 0;\n }\n text = new TextDecoder().decode(fileBytes);\n }\n const json = JSON.parse(text);\n if (!json || typeof json !== "object" || Array.isArray(json)) {\n return void 0;\n }\n const isVersion2 = json.version === 2;\n for (const key of ["means", "scales", "quats", "sh0"]) {\n if (!json[key] || typeof json[key] !== "object" || Array.isArray(json[key])) {\n return void 0;\n }\n if (isVersion2) {\n if (!json[key].files) {\n return void 0;\n }\n if ((key === "scales" || key === "sh0") && !json[key].codebook) {\n return void 0;\n }\n if (key === "means" && (!json[key].mins || !json[key].maxs)) {\n return void 0;\n }\n } else {\n if (!json[key].shape || !json[key].files) {\n return void 0;\n }\n if (key !== "quats" && (!json[key].mins || !json[key].maxs)) {\n return void 0;\n }\n }\n }\n return json;\n } catch {\n return void 0;\n }\n }\n function tryPcSogsZip(input) {\n try {\n const fileBytes = input instanceof ArrayBuffer ? new Uint8Array(input) : input;\n let metaFilename = null;\n const unzipped = unzipSync(fileBytes, {\n filter: ({ name }) => {\n const filename = name.split(/[\\\\/]/).pop();\n if (filename === "meta.json") {\n metaFilename = name;\n return true;\n }\n return false;\n }\n });\n if (!metaFilename) {\n return void 0;\n }\n const json = tryPcSogs(unzipped[metaFilename]);\n if (!json) {\n return void 0;\n }\n return { name: metaFilename, json };\n } catch {\n return void 0;\n }\n }\n class SplatData {\n constructor({ maxSplats = 1 } = {}) {\n this.numSplats = 0;\n this.maxSplats = getTextureSize(maxSplats).maxSplats;\n this.centers = new Float32Array(this.maxSplats * 3);\n this.scales = new Float32Array(this.maxSplats * 3);\n this.quaternions = new Float32Array(this.maxSplats * 4);\n this.opacities = new Float32Array(this.maxSplats);\n this.colors = new Float32Array(this.maxSplats * 3);\n }\n pushSplat() {\n const index = this.numSplats;\n this.ensureIndex(index);\n this.numSplats += 1;\n return index;\n }\n unpushSplat(index) {\n if (index === this.numSplats - 1) {\n this.numSplats -= 1;\n } else {\n throw new Error("Cannot unpush splat from non-last position");\n }\n }\n ensureCapacity(numSplats) {\n if (numSplats > this.maxSplats) {\n const targetSplats = Math.max(numSplats, this.maxSplats * 2);\n const newCenters = new Float32Array(targetSplats * 3);\n const newScales = new Float32Array(targetSplats * 3);\n const newQuaternions = new Float32Array(targetSplats * 4);\n const newOpacities = new Float32Array(targetSplats);\n const newColors = new Float32Array(targetSplats * 3);\n newCenters.set(this.centers);\n newScales.set(this.scales);\n newQuaternions.set(this.quaternions);\n newOpacities.set(this.opacities);\n newColors.set(this.colors);\n this.centers = newCenters;\n this.scales = newScales;\n this.quaternions = newQuaternions;\n this.opacities = newOpacities;\n this.colors = newColors;\n if (this.sh1) {\n const newSh1 = new Float32Array(targetSplats * 9);\n newSh1.set(this.sh1);\n this.sh1 = newSh1;\n }\n if (this.sh2) {\n const newSh2 = new Float32Array(targetSplats * 15);\n newSh2.set(this.sh2);\n this.sh2 = newSh2;\n }\n if (this.sh3) {\n const newSh3 = new Float32Array(targetSplats * 21);\n newSh3.set(this.sh3);\n this.sh3 = newSh3;\n }\n this.maxSplats = targetSplats;\n }\n }\n ensureIndex(index) {\n this.ensureCapacity(index + 1);\n }\n setCenter(index, x2, y, z) {\n this.centers[index * 3] = x2;\n this.centers[index * 3 + 1] = y;\n this.centers[index * 3 + 2] = z;\n }\n setScale(index, scaleX, scaleY, scaleZ) {\n this.scales[index * 3] = scaleX;\n this.scales[index * 3 + 1] = scaleY;\n this.scales[index * 3 + 2] = scaleZ;\n }\n setQuaternion(index, x2, y, z, w) {\n this.quaternions[index * 4] = x2;\n this.quaternions[index * 4 + 1] = y;\n this.quaternions[index * 4 + 2] = z;\n this.quaternions[index * 4 + 3] = w;\n }\n setOpacity(index, opacity) {\n this.opacities[index] = opacity;\n }\n setColor(index, r, g, b) {\n this.colors[index * 3] = r;\n this.colors[index * 3 + 1] = g;\n this.colors[index * 3 + 2] = b;\n }\n setSh1(index, sh1) {\n if (!this.sh1) {\n this.sh1 = new Float32Array(this.maxSplats * 9);\n }\n for (let j = 0; j < 9; ++j) {\n this.sh1[index * 9 + j] = sh1[j];\n }\n }\n setSh2(index, sh2) {\n if (!this.sh2) {\n this.sh2 = new Float32Array(this.maxSplats * 15);\n }\n for (let j = 0; j < 15; ++j) {\n this.sh2[index * 15 + j] = sh2[j];\n }\n }\n setSh3(index, sh3) {\n if (!this.sh3) {\n this.sh3 = new Float32Array(this.maxSplats * 21);\n }\n for (let j = 0; j < 21; ++j) {\n this.sh3[index * 21 + j] = sh3[j];\n }\n }\n }\n async function unpackPcSogs(json, extraFiles, splatEncoding) {\n const isVersion2 = "version" in json;\n if (!isVersion2 && json.quats.encoding !== "quaternion_packed") {\n throw new Error("Unsupported quaternion encoding");\n }\n const numSplats = isVersion2 ? json.count : json.means.shape[0];\n const maxSplats = computeMaxSplats(numSplats);\n const packedArray = new Uint32Array(maxSplats * 4);\n const extra = {};\n const meansPromise = Promise.all([\n decodeImageRgba(extraFiles[json.means.files[0]]),\n decodeImageRgba(extraFiles[json.means.files[1]])\n ]).then((means) => {\n for (let i2 = 0; i2 < numSplats; ++i2) {\n const i4 = i2 * 4;\n const fx = (means[0][i4 + 0] + (means[1][i4 + 0] << 8)) / 65535;\n const fy = (means[0][i4 + 1] + (means[1][i4 + 1] << 8)) / 65535;\n const fz = (means[0][i4 + 2] + (means[1][i4 + 2] << 8)) / 65535;\n let x2 = json.means.mins[0] + (json.means.maxs[0] - json.means.mins[0]) * fx;\n let y = json.means.mins[1] + (json.means.maxs[1] - json.means.mins[1]) * fy;\n let z = json.means.mins[2] + (json.means.maxs[2] - json.means.mins[2]) * fz;\n x2 = Math.sign(x2) * (Math.exp(Math.abs(x2)) - 1);\n y = Math.sign(y) * (Math.exp(Math.abs(y)) - 1);\n z = Math.sign(z) * (Math.exp(Math.abs(z)) - 1);\n setPackedSplatCenter(packedArray, i2, x2, y, z);\n }\n });\n const scalesPromise = decodeImageRgba(extraFiles[json.scales.files[0]]).then(\n (scales) => {\n let xLookup;\n let yLookup;\n let zLookup;\n if (isVersion2) {\n xLookup = yLookup = zLookup = json.scales.codebook.map((x2) => Math.exp(x2));\n } else {\n xLookup = new Array(256).fill(0).map(\n (_, i2) => json.scales.mins[0] + (json.scales.maxs[0] - json.scales.mins[0]) * (i2 / 255)\n ).map((x2) => Math.exp(x2));\n yLookup = new Array(256).fill(0).map(\n (_, i2) => json.scales.mins[1] + (json.scales.maxs[1] - json.scales.mins[1]) * (i2 / 255)\n ).map((x2) => Math.exp(x2));\n zLookup = new Array(256).fill(0).map(\n (_, i2) => json.scales.mins[2] + (json.scales.maxs[2] - json.scales.mins[2]) * (i2 / 255)\n ).map((x2) => Math.exp(x2));\n }\n for (let i2 = 0; i2 < numSplats; ++i2) {\n const i4 = i2 * 4;\n setPackedSplatScales(\n packedArray,\n i2,\n xLookup[scales[i4 + 0]],\n yLookup[scales[i4 + 1]],\n zLookup[scales[i4 + 2]],\n splatEncoding\n );\n }\n }\n );\n const quatsPromise = decodeImageRgba(extraFiles[json.quats.files[0]]).then(\n (quats) => {\n const SQRT2 = Math.sqrt(2);\n const lookup = new Array(256).fill(0).map((_, i2) => (i2 / 255 - 0.5) * SQRT2);\n for (let i2 = 0; i2 < numSplats; ++i2) {\n const i4 = i2 * 4;\n const r0 = lookup[quats[i4 + 0]];\n const r1 = lookup[quats[i4 + 1]];\n const r2 = lookup[quats[i4 + 2]];\n const rr = Math.sqrt(Math.max(0, 1 - r0 * r0 - r1 * r1 - r2 * r2));\n const rOrder = quats[i4 + 3] - 252;\n const quatX = rOrder === 0 ? r0 : rOrder === 1 ? rr : r1;\n const quatY = rOrder <= 1 ? r1 : rOrder === 2 ? rr : r2;\n const quatZ = rOrder <= 2 ? r2 : rr;\n const quatW = rOrder === 0 ? rr : r0;\n setPackedSplatQuat(packedArray, i2, quatX, quatY, quatZ, quatW);\n }\n }\n );\n const sh0Promise = decodeImageRgba(extraFiles[json.sh0.files[0]]).then(\n (sh0) => {\n const SH_C02 = 0.28209479177387814;\n let rLookup;\n let gLookup;\n let bLookup;\n let aLookup;\n if (isVersion2) {\n rLookup = gLookup = bLookup = json.sh0.codebook.map((x2) => SH_C02 * x2 + 0.5);\n aLookup = new Array(256).fill(0).map((_, i2) => i2 / 255);\n } else {\n rLookup = new Array(256).fill(0).map(\n (_, i2) => json.sh0.mins[0] + (json.sh0.maxs[0] - json.sh0.mins[0]) * (i2 / 255)\n ).map((x2) => SH_C02 * x2 + 0.5);\n gLookup = new Array(256).fill(0).map(\n (_, i2) => json.sh0.mins[1] + (json.sh0.maxs[1] - json.sh0.mins[1]) * (i2 / 255)\n ).map((x2) => SH_C02 * x2 + 0.5);\n bLookup = new Array(256).fill(0).map(\n (_, i2) => json.sh0.mins[2] + (json.sh0.maxs[2] - json.sh0.mins[2]) * (i2 / 255)\n ).map((x2) => SH_C02 * x2 + 0.5);\n aLookup = new Array(256).fill(0).map(\n (_, i2) => json.sh0.mins[3] + (json.sh0.maxs[3] - json.sh0.mins[3]) * (i2 / 255)\n ).map((x2) => 1 / (1 + Math.exp(-x2)));\n }\n for (let i2 = 0; i2 < numSplats; ++i2) {\n const i4 = i2 * 4;\n setPackedSplatRgba(\n packedArray,\n i2,\n rLookup[sh0[i4 + 0]],\n gLookup[sh0[i4 + 1]],\n bLookup[sh0[i4 + 2]],\n aLookup[sh0[i4 + 3]],\n splatEncoding\n );\n }\n }\n );\n const promises = [meansPromise, scalesPromise, quatsPromise, sh0Promise];\n if (json.shN) {\n const useSH3 = isVersion2 ? json.shN.bands >= 3 : json.shN.shape[1] >= 48 - 3;\n const useSH2 = isVersion2 ? json.shN.bands >= 2 : json.shN.shape[1] >= 27 - 3;\n const useSH1 = isVersion2 ? json.shN.bands >= 1 : json.shN.shape[1] >= 12 - 3;\n if (useSH1) extra.sh1 = new Uint32Array(numSplats * 2);\n if (useSH2) extra.sh2 = new Uint32Array(numSplats * 4);\n if (useSH3) extra.sh3 = new Uint32Array(numSplats * 4);\n const sh1 = new Float32Array(9);\n const sh2 = new Float32Array(15);\n const sh3 = new Float32Array(21);\n const shN = json.shN;\n const shNPromise = Promise.all([\n decodeImage(extraFiles[json.shN.files[0]]),\n decodeImage(extraFiles[json.shN.files[1]])\n ]).then(([centroids, labels]) => {\n const lookup = "codebook" in shN ? shN.codebook : new Array(256).fill(0).map((_, i2) => shN.mins + (shN.maxs - shN.mins) * (i2 / 255));\n for (let i2 = 0; i2 < numSplats; ++i2) {\n const i4 = i2 * 4;\n const label = labels.rgba[i4 + 0] + (labels.rgba[i4 + 1] << 8);\n const col = (label & 63) * 15;\n const row = label >>> 6;\n const offset = row * centroids.width + col;\n for (let d = 0; d < 3; ++d) {\n if (useSH1) {\n for (let k = 0; k < 3; ++k) {\n sh1[k * 3 + d] = lookup[centroids.rgba[(offset + k) * 4 + d]];\n }\n }\n if (useSH2) {\n for (let k = 0; k < 5; ++k) {\n sh2[k * 3 + d] = lookup[centroids.rgba[(offset + 3 + k) * 4 + d]];\n }\n }\n if (useSH3) {\n for (let k = 0; k < 7; ++k) {\n sh3[k * 3 + d] = lookup[centroids.rgba[(offset + 8 + k) * 4 + d]];\n }\n }\n }\n if (useSH1)\n encodeSh1Rgb(extra.sh1, i2, sh1, splatEncoding);\n if (useSH2)\n encodeSh2Rgb(extra.sh2, i2, sh2, splatEncoding);\n if (useSH3)\n encodeSh3Rgb(extra.sh3, i2, sh3, splatEncoding);\n }\n });\n promises.push(shNPromise);\n }\n await Promise.all(promises);\n return { packedArray, numSplats, extra };\n }\n let offscreenGlContext = null;\n async function decodeImage(fileBytes) {\n if (!offscreenGlContext) {\n const canvas = new OffscreenCanvas(1, 1);\n offscreenGlContext = canvas.getContext("webgl2");\n if (!offscreenGlContext) {\n throw new Error("Failed to create WebGL2 context");\n }\n }\n const imageBlob = new Blob([fileBytes]);\n const bitmap = await createImageBitmap(imageBlob, {\n premultiplyAlpha: "none"\n });\n const gl = offscreenGlContext;\n const texture = gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, bitmap);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n const framebuffer = gl.createFramebuffer();\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n gl.COLOR_ATTACHMENT0,\n gl.TEXTURE_2D,\n texture,\n 0\n );\n const data = new Uint8Array(bitmap.width * bitmap.height * 4);\n gl.readPixels(\n 0,\n 0,\n bitmap.width,\n bitmap.height,\n gl.RGBA,\n gl.UNSIGNED_BYTE,\n data\n );\n gl.deleteTexture(texture);\n gl.deleteFramebuffer(framebuffer);\n return { rgba: data, width: bitmap.width, height: bitmap.height };\n }\n async function decodeImageRgba(fileBytes) {\n const { rgba } = await decodeImage(fileBytes);\n return rgba;\n }\n async function unpackPcSogsZip(fileBytes, splatEncoding) {\n var _a2;\n const nameJson = tryPcSogsZip(fileBytes);\n if (!nameJson) {\n throw new Error("Invalid PC SOGS zip file");\n }\n const { name, json } = nameJson;\n const lastSlash = name.lastIndexOf("/");\n const lastBackslash = name.lastIndexOf("\\\\");\n const prefix = name.slice(0, Math.max(lastSlash, lastBackslash) + 1);\n const fileMap = /* @__PURE__ */ new Map();\n const refFiles = [\n ...json.means.files,\n ...json.scales.files,\n ...json.quats.files,\n ...json.sh0.files,\n ...((_a2 = json.shN) == null ? void 0 : _a2.files) ?? []\n ];\n for (const file of refFiles) {\n fileMap.set(prefix + file, file);\n }\n const unzipped = await new Promise(\n (resolve, reject) => {\n unzip(\n fileBytes,\n {\n filter: ({ name: name2 }) => {\n return fileMap.has(name2);\n }\n },\n (err2, files) => {\n if (err2) {\n reject(err2);\n } else {\n resolve(files);\n }\n }\n );\n }\n );\n const extraFiles = {};\n for (const [full, name2] of fileMap.entries()) {\n extraFiles[name2] = unzipped[full];\n }\n return await unpackPcSogs(json, extraFiles, splatEncoding);\n }\n class SpzReader {\n constructor({ fileBytes }) {\n this.version = -1;\n this.numSplats = 0;\n this.shDegree = 0;\n this.fractionalBits = 0;\n this.flags = 0;\n this.flagAntiAlias = false;\n this.reserved = 0;\n this.headerParsed = false;\n this.parsed = false;\n this.fileBytes = fileBytes instanceof ArrayBuffer ? new Uint8Array(fileBytes) : fileBytes;\n this.reader = new GunzipReader({ fileBytes: this.fileBytes });\n }\n async parseHeader() {\n if (this.headerParsed) {\n throw new Error("SPZ file header already parsed");\n }\n const header = new DataView((await this.reader.read(16)).buffer);\n if (header.getUint32(0, true) !== 1347635022) {\n throw new Error("Invalid SPZ file");\n }\n this.version = header.getUint32(4, true);\n if (this.version < 1 || this.version > 3) {\n throw new Error(`Unsupported SPZ version: ${this.version}`);\n }\n this.numSplats = header.getUint32(8, true);\n this.shDegree = header.getUint8(12);\n this.fractionalBits = header.getUint8(13);\n this.flags = header.getUint8(14);\n this.flagAntiAlias = (this.flags & 1) !== 0;\n this.reserved = header.getUint8(15);\n this.headerParsed = true;\n this.parsed = false;\n }\n async parseSplats(centerCallback, alphaCallback, rgbCallback, scalesCallback, quatCallback, shCallback) {\n if (!this.headerParsed) {\n throw new Error("SPZ file header must be parsed first");\n }\n if (this.parsed) {\n throw new Error("SPZ file already parsed");\n }\n this.parsed = true;\n if (this.version === 1) {\n const centerBytes = await this.reader.read(this.numSplats * 3 * 2);\n const centerUint16 = new Uint16Array(centerBytes.buffer);\n for (let i2 = 0; i2 < this.numSplats; i2++) {\n const i3 = i2 * 3;\n const x2 = fromHalf(centerUint16[i3]);\n const y = fromHalf(centerUint16[i3 + 1]);\n const z = fromHalf(centerUint16[i3 + 2]);\n centerCallback == null ? void 0 : centerCallback(i2, x2, y, z);\n }\n } else if (this.version === 2 || this.version === 3) {\n const fixed = 1 << this.fractionalBits;\n const centerBytes = await this.reader.read(this.numSplats * 3 * 3);\n for (let i2 = 0; i2 < this.numSplats; i2++) {\n const i9 = i2 * 9;\n const x2 = ((centerBytes[i9 + 2] << 24 | centerBytes[i9 + 1] << 16 | centerBytes[i9] << 8) >> 8) / fixed;\n const y = ((centerBytes[i9 + 5] << 24 | centerBytes[i9 + 4] << 16 | centerBytes[i9 + 3] << 8) >> 8) / fixed;\n const z = ((centerBytes[i9 + 8] << 24 | centerBytes[i9 + 7] << 16 | centerBytes[i9 + 6] << 8) >> 8) / fixed;\n centerCallback == null ? void 0 : centerCallback(i2, x2, y, z);\n }\n } else {\n throw new Error("Unreachable");\n }\n {\n const bytes = await this.reader.read(this.numSplats);\n for (let i2 = 0; i2 < this.numSplats; i2++) {\n alphaCallback == null ? void 0 : alphaCallback(i2, bytes[i2] / 255);\n }\n }\n {\n const rgbBytes = await this.reader.read(this.numSplats * 3);\n const scale = SH_C0 / 0.15;\n for (let i2 = 0; i2 < this.numSplats; i2++) {\n const i3 = i2 * 3;\n const r = (rgbBytes[i3] / 255 - 0.5) * scale + 0.5;\n const g = (rgbBytes[i3 + 1] / 255 - 0.5) * scale + 0.5;\n const b = (rgbBytes[i3 + 2] / 255 - 0.5) * scale + 0.5;\n rgbCallback == null ? void 0 : rgbCallback(i2, r, g, b);\n }\n }\n {\n const scalesBytes = await this.reader.read(this.numSplats * 3);\n for (let i2 = 0; i2 < this.numSplats; i2++) {\n const i3 = i2 * 3;\n const scaleX = Math.exp(scalesBytes[i3] / 16 - 10);\n const scaleY = Math.exp(scalesBytes[i3 + 1] / 16 - 10);\n const scaleZ = Math.exp(scalesBytes[i3 + 2] / 16 - 10);\n scalesCallback == null ? void 0 : scalesCallback(i2, scaleX, scaleY, scaleZ);\n }\n }\n if (this.version === 3) {\n const maxValue = 1 / Math.sqrt(2);\n const quatBytes = await this.reader.read(this.numSplats * 4);\n for (let i2 = 0; i2 < this.numSplats; i2++) {\n const i3 = i2 * 4;\n const quaternion = [0, 0, 0, 0];\n const values = [\n quatBytes[i3],\n quatBytes[i3 + 1],\n quatBytes[i3 + 2],\n quatBytes[i3 + 3]\n ];\n const combinedValues = values[0] + (values[1] << 8) + (values[2] << 16) + (values[3] << 24);\n const valueMask = (1 << 9) - 1;\n const largestIndex = combinedValues >>> 30;\n let remainingValues = combinedValues;\n let sumSquares = 0;\n for (let i22 = 3; i22 >= 0; --i22) {\n if (i22 !== largestIndex) {\n const value = remainingValues & valueMask;\n const sign = remainingValues >>> 9 & 1;\n remainingValues = remainingValues >>> 10;\n quaternion[i22] = maxValue * (value / valueMask);\n quaternion[i22] = sign === 0 ? quaternion[i22] : -quaternion[i22];\n sumSquares += quaternion[i22] * quaternion[i22];\n }\n }\n const square = 1 - sumSquares;\n quaternion[largestIndex] = Math.sqrt(Math.max(square, 0));\n quatCallback == null ? void 0 : quatCallback(\n i2,\n quaternion[0],\n quaternion[1],\n quaternion[2],\n quaternion[3]\n );\n }\n } else {\n const quatBytes = await this.reader.read(this.numSplats * 3);\n for (let i2 = 0; i2 < this.numSplats; i2++) {\n const i3 = i2 * 3;\n const quatX = quatBytes[i3] / 127.5 - 1;\n const quatY = quatBytes[i3 + 1] / 127.5 - 1;\n const quatZ = quatBytes[i3 + 2] / 127.5 - 1;\n const quatW = Math.sqrt(\n Math.max(0, 1 - quatX * quatX - quatY * quatY - quatZ * quatZ)\n );\n quatCallback == null ? void 0 : quatCallback(i2, quatX, quatY, quatZ, quatW);\n }\n }\n if (shCallback && this.shDegree >= 1) {\n const sh1 = new Float32Array(3 * 3);\n const sh2 = this.shDegree >= 2 ? new Float32Array(5 * 3) : void 0;\n const sh3 = this.shDegree >= 3 ? new Float32Array(7 * 3) : void 0;\n const shBytes = await this.reader.read(\n this.numSplats * SH_DEGREE_TO_VECS[this.shDegree] * 3\n );\n let offset = 0;\n for (let i2 = 0; i2 < this.numSplats; i2++) {\n for (let j = 0; j < 9; ++j) {\n sh1[j] = (shBytes[offset + j] - 128) / 128;\n }\n offset += 9;\n if (sh2) {\n for (let j = 0; j < 15; ++j) {\n sh2[j] = (shBytes[offset + j] - 128) / 128;\n }\n offset += 15;\n }\n if (sh3) {\n for (let j = 0; j < 21; ++j) {\n sh3[j] = (shBytes[offset + j] - 128) / 128;\n }\n offset += 21;\n }\n shCallback == null ? void 0 : shCallback(i2, sh1, sh2, sh3);\n }\n }\n }\n }\n const SH_DEGREE_TO_VECS = { 1: 3, 2: 8, 3: 15 };\n const SH_C0 = 0.28209479177387814;\n const SPZ_MAGIC = 1347635022;\n const SPZ_VERSION = 3;\n const FLAG_ANTIALIASED = 1;\n class SpzWriter {\n constructor({\n numSplats,\n shDegree,\n fractionalBits = 12,\n flagAntiAlias = true\n }) {\n this.clippedCount = 0;\n const splatSize = 9 + // Position\n 1 + // Opacity\n 3 + // Scale\n 3 + // DC-rgb\n 4 + // Rotation\n (shDegree >= 1 ? 9 : 0) + (shDegree >= 2 ? 15 : 0) + (shDegree >= 3 ? 21 : 0);\n const bufferSize = 16 + numSplats * splatSize;\n this.buffer = new ArrayBuffer(bufferSize);\n this.view = new DataView(this.buffer);\n this.view.setUint32(0, SPZ_MAGIC, true);\n this.view.setUint32(4, SPZ_VERSION, true);\n this.view.setUint32(8, numSplats, true);\n this.view.setUint8(12, shDegree);\n this.view.setUint8(13, fractionalBits);\n this.view.setUint8(14, flagAntiAlias ? FLAG_ANTIALIASED : 0);\n this.view.setUint8(15, 0);\n this.numSplats = numSplats;\n this.shDegree = shDegree;\n this.fractionalBits = fractionalBits;\n this.fraction = 1 << fractionalBits;\n this.flagAntiAlias = flagAntiAlias;\n }\n setCenter(index, x2, y, z) {\n const xRounded = Math.round(x2 * this.fraction);\n const xInt = Math.max(-8388607, Math.min(8388607, xRounded));\n const yRounded = Math.round(y * this.fraction);\n const yInt = Math.max(-8388607, Math.min(8388607, yRounded));\n const zRounded = Math.round(z * this.fraction);\n const zInt = Math.max(-8388607, Math.min(8388607, zRounded));\n const clipped = xRounded !== xInt || yRounded !== yInt || zRounded !== zInt;\n if (clipped) {\n this.clippedCount += 1;\n }\n const i9 = index * 9;\n const base = 16 + i9;\n this.view.setUint8(base, xInt & 255);\n this.view.setUint8(base + 1, xInt >> 8 & 255);\n this.view.setUint8(base + 2, xInt >> 16 & 255);\n this.view.setUint8(base + 3, yInt & 255);\n this.view.setUint8(base + 4, yInt >> 8 & 255);\n this.view.setUint8(base + 5, yInt >> 16 & 255);\n this.view.setUint8(base + 6, zInt & 255);\n this.view.setUint8(base + 7, zInt >> 8 & 255);\n this.view.setUint8(base + 8, zInt >> 16 & 255);\n }\n setAlpha(index, alpha) {\n const base = 16 + this.numSplats * 9 + index;\n this.view.setUint8(\n base,\n Math.max(0, Math.min(255, Math.round(alpha * 255)))\n );\n }\n static scaleRgb(r) {\n const v = ((r - 0.5) / (SH_C0 / 0.15) + 0.5) * 255;\n return Math.max(0, Math.min(255, Math.round(v)));\n }\n setRgb(index, r, g, b) {\n const base = 16 + this.numSplats * 10 + index * 3;\n this.view.setUint8(base, SpzWriter.scaleRgb(r));\n this.view.setUint8(base + 1, SpzWriter.scaleRgb(g));\n this.view.setUint8(base + 2, SpzWriter.scaleRgb(b));\n }\n setScale(index, scaleX, scaleY, scaleZ) {\n const base = 16 + this.numSplats * 13 + index * 3;\n this.view.setUint8(\n base,\n Math.max(0, Math.min(255, Math.round((Math.log(scaleX) + 10) * 16)))\n );\n this.view.setUint8(\n base + 1,\n Math.max(0, Math.min(255, Math.round((Math.log(scaleY) + 10) * 16)))\n );\n this.view.setUint8(\n base + 2,\n Math.max(0, Math.min(255, Math.round((Math.log(scaleZ) + 10) * 16)))\n );\n }\n setQuat(index, ...q) {\n const base = 16 + this.numSplats * 16 + index * 4;\n const quat = normalize(q);\n let iLargest = 0;\n for (let i2 = 1; i2 < 4; ++i2) {\n if (Math.abs(quat[i2]) > Math.abs(quat[iLargest])) {\n iLargest = i2;\n }\n }\n const negate = quat[iLargest] < 0 ? 1 : 0;\n let comp = iLargest;\n for (let i2 = 0; i2 < 4; ++i2) {\n if (i2 !== iLargest) {\n const negbit = (quat[i2] < 0 ? 1 : 0) ^ negate;\n const mag = Math.floor(\n ((1 << 9) - 1) * (Math.abs(quat[i2]) / Math.SQRT1_2) + 0.5\n );\n comp = comp << 10 | negbit << 9 | mag;\n }\n }\n this.view.setUint8(base, comp & 255);\n this.view.setUint8(base + 1, comp >> 8 & 255);\n this.view.setUint8(base + 2, comp >> 16 & 255);\n this.view.setUint8(base + 3, comp >>> 24 & 255);\n }\n static quantizeSh(sh, bits2) {\n const value = Math.round(sh * 128) + 128;\n const bucketSize = 1 << 8 - bits2;\n const quantized = Math.floor((value + bucketSize / 2) / bucketSize) * bucketSize;\n return Math.max(0, Math.min(255, quantized));\n }\n setSh(index, sh1, sh2, sh3) {\n const shVecs = SH_DEGREE_TO_VECS[this.shDegree] || 0;\n const base1 = 16 + this.numSplats * 20 + index * shVecs * 3;\n for (let j = 0; j < 9; ++j) {\n this.view.setUint8(base1 + j, SpzWriter.quantizeSh(sh1[j], 5));\n }\n if (sh2) {\n const base2 = base1 + 9;\n for (let j = 0; j < 15; ++j) {\n this.view.setUint8(base2 + j, SpzWriter.quantizeSh(sh2[j], 4));\n }\n if (sh3) {\n const base3 = base2 + 15;\n for (let j = 0; j < 21; ++j) {\n this.view.setUint8(base3 + j, SpzWriter.quantizeSh(sh3[j], 4));\n }\n }\n }\n }\n async finalize() {\n const input = new Uint8Array(this.buffer);\n const stream = new ReadableStream({\n async start(controller) {\n controller.enqueue(input);\n controller.close();\n }\n });\n const compressed = stream.pipeThrough(new CompressionStream("gzip"));\n const response = new Response(compressed);\n const buffer = await response.arrayBuffer();\n console.log(\n "Compressed",\n input.length,\n "bytes to",\n buffer.byteLength,\n "bytes"\n );\n return new Uint8Array(buffer);\n }\n }\n async function transcodeSpz(input) {\n var _a2, _b2, _c;\n const splats = new SplatData();\n const {\n inputs,\n clipXyz,\n maxSh,\n fractionalBits = 12,\n opacityThreshold\n } = input;\n for (const input2 of inputs) {\n let transformPos = function(pos) {\n pos.multiplyScalar(scale);\n pos.applyQuaternion(quaternion);\n pos.add(translate);\n return pos;\n }, transformScales = function(scales) {\n scales.multiplyScalar(scale);\n return scales;\n }, transformQuaternion = function(quat) {\n quat.premultiply(quaternion);\n return quat;\n }, withinClip = function(p) {\n return !clip || clip.containsPoint(p);\n }, withinOpacity = function(opacity) {\n return opacityThreshold !== void 0 ? opacity >= opacityThreshold : true;\n };\n const scale = ((_a2 = input2.transform) == null ? void 0 : _a2.scale) ?? 1;\n const quaternion = new Quaternion().fromArray(\n ((_b2 = input2.transform) == null ? void 0 : _b2.quaternion) ?? [0, 0, 0, 1]\n );\n const translate = new Vector3().fromArray(\n ((_c = input2.transform) == null ? void 0 : _c.translate) ?? [0, 0, 0]\n );\n const clip = clipXyz ? new Box3(\n new Vector3().fromArray(clipXyz.min),\n new Vector3().fromArray(clipXyz.max)\n ) : void 0;\n let fileType = input2.fileType;\n if (!fileType) {\n fileType = getSplatFileType(input2.fileBytes);\n if (!fileType && input2.pathOrUrl) {\n fileType = getSplatFileTypeFromPath(input2.pathOrUrl);\n }\n }\n switch (fileType) {\n case SplatFileType.PLY: {\n const ply = new PlyReader({ fileBytes: input2.fileBytes });\n await ply.parseHeader();\n let lastIndex = null;\n ply.parseSplats(\n (index, x2, y, z, scaleX, scaleY, scaleZ, quatX, quatY, quatZ, quatW, opacity, r, g, b) => {\n const center = transformPos(new Vector3(x2, y, z));\n if (withinClip(center) && withinOpacity(opacity)) {\n lastIndex = splats.pushSplat();\n splats.setCenter(lastIndex, center.x, center.y, center.z);\n const scales = transformScales(\n new Vector3(scaleX, scaleY, scaleZ)\n );\n splats.setScale(lastIndex, scales.x, scales.y, scales.z);\n const quaternion2 = transformQuaternion(\n new Quaternion(quatX, quatY, quatZ, quatW)\n );\n splats.setQuaternion(\n lastIndex,\n quaternion2.x,\n quaternion2.y,\n quaternion2.z,\n quaternion2.w\n );\n splats.setOpacity(lastIndex, opacity);\n splats.setColor(lastIndex, r, g, b);\n } else {\n lastIndex = null;\n }\n },\n (index, sh1, sh2, sh3) => {\n if (sh1 && lastIndex !== null) {\n splats.setSh1(lastIndex, sh1);\n }\n if (sh2 && lastIndex !== null) {\n splats.setSh2(lastIndex, sh2);\n }\n if (sh3 && lastIndex !== null) {\n splats.setSh3(lastIndex, sh3);\n }\n }\n );\n break;\n }\n case SplatFileType.SPZ: {\n const spz2 = new SpzReader({ fileBytes: input2.fileBytes });\n await spz2.parseHeader();\n const mapping = new Int32Array(spz2.numSplats);\n mapping.fill(-1);\n const centers = new Float32Array(spz2.numSplats * 3);\n const center = new Vector3();\n spz2.parseSplats(\n (index, x2, y, z) => {\n const center2 = transformPos(new Vector3(x2, y, z));\n centers[index * 3] = center2.x;\n centers[index * 3 + 1] = center2.y;\n centers[index * 3 + 2] = center2.z;\n },\n (index, alpha) => {\n center.fromArray(centers, index * 3);\n if (withinClip(center) && withinOpacity(alpha)) {\n mapping[index] = splats.pushSplat();\n splats.setCenter(mapping[index], center.x, center.y, center.z);\n splats.setOpacity(mapping[index], alpha);\n }\n },\n (index, r, g, b) => {\n if (mapping[index] >= 0) {\n splats.setColor(mapping[index], r, g, b);\n }\n },\n (index, scaleX, scaleY, scaleZ) => {\n if (mapping[index] >= 0) {\n const scales = transformScales(\n new Vector3(scaleX, scaleY, scaleZ)\n );\n splats.setScale(mapping[index], scales.x, scales.y, scales.z);\n }\n },\n (index, quatX, quatY, quatZ, quatW) => {\n if (mapping[index] >= 0) {\n const quaternion2 = transformQuaternion(\n new Quaternion(quatX, quatY, quatZ, quatW)\n );\n splats.setQuaternion(\n mapping[index],\n quaternion2.x,\n quaternion2.y,\n quaternion2.z,\n quaternion2.w\n );\n }\n },\n (index, sh1, sh2, sh3) => {\n if (mapping[index] >= 0) {\n splats.setSh1(mapping[index], sh1);\n if (sh2) {\n splats.setSh2(mapping[index], sh2);\n }\n if (sh3) {\n splats.setSh3(mapping[index], sh3);\n }\n }\n }\n );\n break;\n }\n case SplatFileType.SPLAT:\n decodeAntiSplat(\n input2.fileBytes,\n (numSplats) => {\n },\n (index, x2, y, z, scaleX, scaleY, scaleZ, quatX, quatY, quatZ, quatW, opacity, r, g, b) => {\n const center = transformPos(new Vector3(x2, y, z));\n if (withinClip(center) && withinOpacity(opacity)) {\n const index2 = splats.pushSplat();\n splats.setCenter(index2, center.x, center.y, center.z);\n const scales = transformScales(\n new Vector3(scaleX, scaleY, scaleZ)\n );\n splats.setScale(index2, scales.x, scales.y, scales.z);\n const quaternion2 = transformQuaternion(\n new Quaternion(quatX, quatY, quatZ, quatW)\n );\n splats.setQuaternion(\n index2,\n quaternion2.x,\n quaternion2.y,\n quaternion2.z,\n quaternion2.w\n );\n splats.setOpacity(index2, opacity);\n splats.setColor(index2, r, g, b);\n }\n }\n );\n break;\n case SplatFileType.KSPLAT: {\n let lastIndex = null;\n decodeKsplat(\n input2.fileBytes,\n (numSplats) => {\n },\n (index, x2, y, z, scaleX, scaleY, scaleZ, quatX, quatY, quatZ, quatW, opacity, r, g, b) => {\n const center = transformPos(new Vector3(x2, y, z));\n if (withinClip(center) && withinOpacity(opacity)) {\n lastIndex = splats.pushSplat();\n splats.setCenter(lastIndex, center.x, center.y, center.z);\n const scales = transformScales(\n new Vector3(scaleX, scaleY, scaleZ)\n );\n splats.setScale(lastIndex, scales.x, scales.y, scales.z);\n const quaternion2 = transformQuaternion(\n new Quaternion(quatX, quatY, quatZ, quatW)\n );\n splats.setQuaternion(\n lastIndex,\n quaternion2.x,\n quaternion2.y,\n quaternion2.z,\n quaternion2.w\n );\n splats.setOpacity(lastIndex, opacity);\n splats.setColor(lastIndex, r, g, b);\n } else {\n lastIndex = null;\n }\n },\n (index, sh1, sh2, sh3) => {\n if (lastIndex !== null) {\n splats.setSh1(lastIndex, sh1);\n if (sh2) {\n splats.setSh2(lastIndex, sh2);\n }\n if (sh3) {\n splats.setSh3(lastIndex, sh3);\n }\n }\n }\n );\n break;\n }\n default:\n throw new Error(`transcodeSpz not implemented for ${fileType}`);\n }\n }\n const shDegree = Math.min(\n maxSh ?? 3,\n splats.sh3 ? 3 : splats.sh2 ? 2 : splats.sh1 ? 1 : 0\n );\n const spz = new SpzWriter({\n numSplats: splats.numSplats,\n shDegree,\n fractionalBits,\n flagAntiAlias: true\n });\n for (let i2 = 0; i2 < splats.numSplats; ++i2) {\n const i3 = i2 * 3;\n const i4 = i2 * 4;\n spz.setCenter(\n i2,\n splats.centers[i3],\n splats.centers[i3 + 1],\n splats.centers[i3 + 2]\n );\n spz.setScale(\n i2,\n splats.scales[i3],\n splats.scales[i3 + 1],\n splats.scales[i3 + 2]\n );\n spz.setQuat(\n i2,\n splats.quaternions[i4],\n splats.quaternions[i4 + 1],\n splats.quaternions[i4 + 2],\n splats.quaternions[i4 + 3]\n );\n spz.setAlpha(i2, splats.opacities[i2]);\n spz.setRgb(\n i2,\n splats.colors[i3],\n splats.colors[i3 + 1],\n splats.colors[i3 + 2]\n );\n if (splats.sh1 && shDegree >= 1) {\n spz.setSh(\n i2,\n splats.sh1.slice(i2 * 9, (i2 + 1) * 9),\n shDegree >= 2 && splats.sh2 ? splats.sh2.slice(i2 * 15, (i2 + 1) * 15) : void 0,\n shDegree >= 3 && splats.sh3 ? splats.sh3.slice(i2 * 21, (i2 + 1) * 21) : void 0\n );\n }\n }\n const spzBytes = await spz.finalize();\n return { fileBytes: spzBytes, clippedCount: spz.clippedCount };\n }\n async function onMessage(event) {\n const { name, args, id } = event.data;\n let result = void 0;\n let error = void 0;\n try {\n switch (name) {\n case "unpackPly": {\n const { packedArray, fileBytes, splatEncoding } = args;\n const decoded = await unpackPly({\n packedArray,\n fileBytes,\n splatEncoding\n });\n result = {\n id,\n numSplats: decoded.numSplats,\n packedArray: decoded.packedArray,\n extra: decoded.extra\n };\n break;\n }\n case "decodeSpz": {\n const { fileBytes, splatEncoding } = args;\n const decoded = await unpackSpz(fileBytes, splatEncoding);\n result = {\n id,\n numSplats: decoded.numSplats,\n packedArray: decoded.packedArray,\n extra: decoded.extra\n };\n break;\n }\n case "decodeAntiSplat": {\n const { fileBytes, splatEncoding } = args;\n const decoded = unpackAntiSplat(fileBytes, splatEncoding);\n result = {\n id,\n numSplats: decoded.numSplats,\n packedArray: decoded.packedArray\n };\n break;\n }\n case "decodeKsplat": {\n const { fileBytes, splatEncoding } = args;\n const decoded = unpackKsplat(fileBytes, splatEncoding);\n result = {\n id,\n numSplats: decoded.numSplats,\n packedArray: decoded.packedArray,\n extra: decoded.extra\n };\n break;\n }\n case "decodePcSogs": {\n const { fileBytes, extraFiles, splatEncoding } = args;\n const json = JSON.parse(\n new TextDecoder().decode(fileBytes)\n );\n const decoded = await unpackPcSogs(json, extraFiles, splatEncoding);\n result = {\n id,\n numSplats: decoded.numSplats,\n packedArray: decoded.packedArray,\n extra: decoded.extra\n };\n break;\n }\n case "decodePcSogsZip": {\n const { fileBytes, splatEncoding } = args;\n const decoded = await unpackPcSogsZip(fileBytes, splatEncoding);\n result = {\n id,\n numSplats: decoded.numSplats,\n packedArray: decoded.packedArray,\n extra: decoded.extra\n };\n break;\n }\n case "sortSplats": {\n const { totalSplats, readback, ordering } = args;\n result = {\n id,\n readback,\n ...sortSplats({ totalSplats, readback, ordering })\n };\n break;\n }\n case "sortDoubleSplats": {\n const { numSplats, readback, ordering } = args;\n {\n result = {\n id,\n readback,\n ordering,\n activeSplats: sort_splats(numSplats, readback, ordering)\n };\n }\n break;\n }\n case "sort32Splats": {\n const { numSplats, readback, ordering } = args;\n {\n result = {\n id,\n readback,\n ordering,\n activeSplats: sort32_splats(numSplats, readback, ordering)\n };\n }\n break;\n }\n case "transcodeSpz": {\n const input = args;\n const spzBytes = await transcodeSpz(input);\n result = {\n id,\n fileBytes: spzBytes,\n input\n };\n break;\n }\n default: {\n throw new Error(`Unknown name: ${name}`);\n }\n }\n } catch (e) {\n error = e;\n console.error(error);\n }\n self.postMessage(\n { id, result, error },\n { transfer: getArrayBuffers(result) }\n );\n }\n async function unpackPly({\n packedArray,\n fileBytes,\n splatEncoding\n }) {\n const ply = new PlyReader({ fileBytes });\n await ply.parseHeader();\n const numSplats = ply.numSplats;\n const extra = {};\n ply.parseSplats(\n (index, x2, y, z, scaleX, scaleY, scaleZ, quatX, quatY, quatZ, quatW, opacity, r, g, b) => {\n setPackedSplat(\n packedArray,\n index,\n x2,\n y,\n z,\n scaleX,\n scaleY,\n scaleZ,\n quatX,\n quatY,\n quatZ,\n quatW,\n opacity,\n r,\n g,\n b,\n splatEncoding\n );\n },\n (index, sh1, sh2, sh3) => {\n if (sh1) {\n if (!extra.sh1) {\n extra.sh1 = new Uint32Array(numSplats * 2);\n }\n encodeSh1Rgb(extra.sh1, index, sh1, splatEncoding);\n }\n if (sh2) {\n if (!extra.sh2) {\n extra.sh2 = new Uint32Array(numSplats * 4);\n }\n encodeSh2Rgb(extra.sh2, index, sh2, splatEncoding);\n }\n if (sh3) {\n if (!extra.sh3) {\n extra.sh3 = new Uint32Array(numSplats * 4);\n }\n encodeSh3Rgb(extra.sh3, index, sh3, splatEncoding);\n }\n }\n );\n return { packedArray, numSplats, extra };\n }\n async function unpackSpz(fileBytes, splatEncoding) {\n const spz = new SpzReader({ fileBytes });\n await spz.parseHeader();\n const numSplats = spz.numSplats;\n const maxSplats = computeMaxSplats(numSplats);\n const packedArray = new Uint32Array(maxSplats * 4);\n const extra = {};\n await spz.parseSplats(\n (index, x2, y, z) => {\n setPackedSplatCenter(packedArray, index, x2, y, z);\n },\n (index, alpha) => {\n setPackedSplatOpacity(packedArray, index, alpha);\n },\n (index, r, g, b) => {\n setPackedSplatRgb(packedArray, index, r, g, b, splatEncoding);\n },\n (index, scaleX, scaleY, scaleZ) => {\n setPackedSplatScales(\n packedArray,\n index,\n scaleX,\n scaleY,\n scaleZ,\n splatEncoding\n );\n },\n (index, quatX, quatY, quatZ, quatW) => {\n setPackedSplatQuat(packedArray, index, quatX, quatY, quatZ, quatW);\n },\n (index, sh1, sh2, sh3) => {\n if (sh1) {\n if (!extra.sh1) {\n extra.sh1 = new Uint32Array(numSplats * 2);\n }\n encodeSh1Rgb(extra.sh1, index, sh1, splatEncoding);\n }\n if (sh2) {\n if (!extra.sh2) {\n extra.sh2 = new Uint32Array(numSplats * 4);\n }\n encodeSh2Rgb(extra.sh2, index, sh2, splatEncoding);\n }\n if (sh3) {\n if (!extra.sh3) {\n extra.sh3 = new Uint32Array(numSplats * 4);\n }\n encodeSh3Rgb(extra.sh3, index, sh3, splatEncoding);\n }\n }\n );\n return { packedArray, numSplats, extra };\n }\n const DEPTH_INFINITY_F16 = 31744;\n const DEPTH_SIZE_16 = DEPTH_INFINITY_F16 + 1;\n let depthArray16 = null;\n function sortSplats({\n totalSplats,\n readback,\n ordering\n }) {\n if (!depthArray16) {\n depthArray16 = new Uint32Array(DEPTH_SIZE_16);\n }\n depthArray16.fill(0);\n const readbackUint32 = readback.map((layer) => new Uint32Array(layer.buffer));\n const layerSize = readbackUint32[0].length;\n const numLayers = Math.ceil(totalSplats / layerSize);\n let layerBase = 0;\n for (let layer = 0; layer < numLayers; ++layer) {\n const readbackLayer = readbackUint32[layer];\n const layerSplats = Math.min(readbackLayer.length, totalSplats - layerBase);\n for (let i2 = 0; i2 < layerSplats; ++i2) {\n const pri = readbackLayer[i2] & 32767;\n if (pri < DEPTH_INFINITY_F16) {\n depthArray16[pri] += 1;\n }\n }\n layerBase += layerSplats;\n }\n let activeSplats = 0;\n for (let j = 0; j < DEPTH_SIZE_16; ++j) {\n const nextIndex = activeSplats + depthArray16[j];\n depthArray16[j] = activeSplats;\n activeSplats = nextIndex;\n }\n layerBase = 0;\n for (let layer = 0; layer < numLayers; ++layer) {\n const readbackLayer = readbackUint32[layer];\n const layerSplats = Math.min(readbackLayer.length, totalSplats - layerBase);\n for (let i2 = 0; i2 < layerSplats; ++i2) {\n const pri = readbackLayer[i2] & 32767;\n if (pri < DEPTH_INFINITY_F16) {\n ordering[depthArray16[pri]] = layerBase + i2;\n depthArray16[pri] += 1;\n }\n }\n layerBase += layerSplats;\n }\n if (depthArray16[DEPTH_SIZE_16 - 1] !== activeSplats) {\n throw new Error(\n `Expected ${activeSplats} active splats but got ${depthArray16[DEPTH_SIZE_16 - 1]}`\n );\n }\n return { activeSplats, ordering };\n }\n const messageBuffer = [];\n function bufferMessage(event) {\n messageBuffer.push(event);\n }\n async function initialize() {\n self.addEventListener("message", bufferMessage);\n await __wbg_init();\n self.removeEventListener("message", bufferMessage);\n self.addEventListener("message", onMessage);\n for (const event of messageBuffer) {\n onMessage(event);\n }\n messageBuffer.length = 0;\n }\n initialize().catch(console.error);\n})();\n//# sourceMappingURL=worker-CaMzlx2k.js.map\n';
|
|
8589
8584
|
const blob = typeof self !== "undefined" && self.Blob && new Blob([jsContent], { type: "text/javascript;charset=utf-8" });
|
|
8590
8585
|
function WorkerWrapper(options) {
|
|
8591
8586
|
let objURL;
|
|
@@ -8906,6 +8901,9 @@ function getSplatFileTypeFromPath(pathOrUrl) {
|
|
|
8906
8901
|
if (extension === "ksplat") {
|
|
8907
8902
|
return "ksplat";
|
|
8908
8903
|
}
|
|
8904
|
+
if (extension === "sog") {
|
|
8905
|
+
return "pcsogszip";
|
|
8906
|
+
}
|
|
8909
8907
|
return void 0;
|
|
8910
8908
|
}
|
|
8911
8909
|
function isPcSogs(input) {
|
|
@@ -8927,15 +8925,28 @@ function tryPcSogs(input) {
|
|
|
8927
8925
|
if (!json || typeof json !== "object" || Array.isArray(json)) {
|
|
8928
8926
|
return void 0;
|
|
8929
8927
|
}
|
|
8928
|
+
const isVersion2 = json.version === 2;
|
|
8930
8929
|
for (const key of ["means", "scales", "quats", "sh0"]) {
|
|
8931
8930
|
if (!json[key] || typeof json[key] !== "object" || Array.isArray(json[key])) {
|
|
8932
8931
|
return void 0;
|
|
8933
8932
|
}
|
|
8934
|
-
if (
|
|
8935
|
-
|
|
8936
|
-
|
|
8937
|
-
|
|
8938
|
-
|
|
8933
|
+
if (isVersion2) {
|
|
8934
|
+
if (!json[key].files) {
|
|
8935
|
+
return void 0;
|
|
8936
|
+
}
|
|
8937
|
+
if ((key === "scales" || key === "sh0") && !json[key].codebook) {
|
|
8938
|
+
return void 0;
|
|
8939
|
+
}
|
|
8940
|
+
if (key === "means" && (!json[key].mins || !json[key].maxs)) {
|
|
8941
|
+
return void 0;
|
|
8942
|
+
}
|
|
8943
|
+
} else {
|
|
8944
|
+
if (!json[key].shape || !json[key].files) {
|
|
8945
|
+
return void 0;
|
|
8946
|
+
}
|
|
8947
|
+
if (key !== "quats" && (!json[key].mins || !json[key].maxs)) {
|
|
8948
|
+
return void 0;
|
|
8949
|
+
}
|
|
8939
8950
|
}
|
|
8940
8951
|
}
|
|
8941
8952
|
return json;
|
|
@@ -9971,7 +9982,7 @@ const _SparkViewpoint = class _SparkViewpoint {
|
|
|
9971
9982
|
// The method cannot be private because then SparkRenderer would
|
|
9972
9983
|
// not be able to call it.
|
|
9973
9984
|
autoPoll({ accumulator }) {
|
|
9974
|
-
var _a2, _b2, _c
|
|
9985
|
+
var _a2, _b2, _c;
|
|
9975
9986
|
if (this.camera) {
|
|
9976
9987
|
this.camera.updateMatrixWorld();
|
|
9977
9988
|
this.viewToWorld = this.camera.matrixWorld.clone();
|
|
@@ -9984,9 +9995,14 @@ const _SparkViewpoint = class _SparkViewpoint {
|
|
|
9984
9995
|
needsSort = true;
|
|
9985
9996
|
const { mappingVersion } = this.display.accumulator;
|
|
9986
9997
|
if (accumulator.mappingVersion === mappingVersion) {
|
|
9998
|
+
accumulator.refCount += 1;
|
|
9987
9999
|
this.spark.releaseAccumulator(this.display.accumulator);
|
|
9988
10000
|
this.display.accumulator = accumulator;
|
|
10001
|
+
this.display.viewToWorld.copy(this.viewToWorld);
|
|
9989
10002
|
displayed = true;
|
|
10003
|
+
if (this.spark.viewpoint === this) {
|
|
10004
|
+
this.spark.prepareViewpoint(this);
|
|
10005
|
+
}
|
|
9990
10006
|
}
|
|
9991
10007
|
}
|
|
9992
10008
|
const latestView = ((_a2 = this.sorting) == null ? void 0 : _a2.viewToWorld) ?? ((_b2 = this.display) == null ? void 0 : _b2.viewToWorld);
|
|
@@ -10009,7 +10025,7 @@ const _SparkViewpoint = class _SparkViewpoint {
|
|
|
10009
10025
|
if (accumulator) {
|
|
10010
10026
|
accumulator.refCount += 1;
|
|
10011
10027
|
}
|
|
10012
|
-
if (
|
|
10028
|
+
if ((_c = this.pending) == null ? void 0 : _c.accumulator) {
|
|
10013
10029
|
this.spark.releaseAccumulator(this.pending.accumulator);
|
|
10014
10030
|
}
|
|
10015
10031
|
this.pending = { accumulator, viewToWorld: this.viewToWorld, displayed };
|
|
@@ -10022,9 +10038,9 @@ const _SparkViewpoint = class _SparkViewpoint {
|
|
|
10022
10038
|
return;
|
|
10023
10039
|
}
|
|
10024
10040
|
const { viewToWorld, displayed } = this.pending;
|
|
10025
|
-
let accumulator = this.pending.accumulator
|
|
10041
|
+
let accumulator = this.pending.accumulator;
|
|
10026
10042
|
if (!accumulator) {
|
|
10027
|
-
accumulator = this.spark.active;
|
|
10043
|
+
accumulator = ((_a2 = this.display) == null ? void 0 : _a2.accumulator) ?? this.spark.active;
|
|
10028
10044
|
accumulator.refCount += 1;
|
|
10029
10045
|
}
|
|
10030
10046
|
this.pending = null;
|
|
@@ -10034,6 +10050,7 @@ const _SparkViewpoint = class _SparkViewpoint {
|
|
|
10034
10050
|
this.sorting = { viewToWorld };
|
|
10035
10051
|
await this.sortUpdate({ accumulator, viewToWorld, displayed });
|
|
10036
10052
|
this.sorting = null;
|
|
10053
|
+
this.spark.releaseAccumulator(accumulator);
|
|
10037
10054
|
}
|
|
10038
10055
|
}
|
|
10039
10056
|
async sortUpdate({
|
|
@@ -10126,6 +10143,7 @@ const _SparkViewpoint = class _SparkViewpoint {
|
|
|
10126
10143
|
displayed = false
|
|
10127
10144
|
}) {
|
|
10128
10145
|
if (!this.display) {
|
|
10146
|
+
accumulator.refCount += 1;
|
|
10129
10147
|
this.display = {
|
|
10130
10148
|
accumulator,
|
|
10131
10149
|
viewToWorld,
|
|
@@ -10133,6 +10151,7 @@ const _SparkViewpoint = class _SparkViewpoint {
|
|
|
10133
10151
|
};
|
|
10134
10152
|
} else {
|
|
10135
10153
|
if (!displayed && accumulator !== this.display.accumulator) {
|
|
10154
|
+
accumulator.refCount += 1;
|
|
10136
10155
|
this.spark.releaseAccumulator(this.display.accumulator);
|
|
10137
10156
|
this.display.accumulator = accumulator;
|
|
10138
10157
|
}
|
|
@@ -10335,7 +10354,7 @@ class SplatAccumulator {
|
|
|
10335
10354
|
numSplats = Math.max(numSplats, base + count);
|
|
10336
10355
|
}
|
|
10337
10356
|
this.splats.numSplats = numSplats;
|
|
10338
|
-
this.toWorld
|
|
10357
|
+
this.toWorld.copy(originToWorld);
|
|
10339
10358
|
this.mapping = generators2;
|
|
10340
10359
|
return updated !== 0;
|
|
10341
10360
|
}
|
|
@@ -10356,8 +10375,8 @@ class SplatAccumulator {
|
|
|
10356
10375
|
}
|
|
10357
10376
|
}
|
|
10358
10377
|
var splatDefines_default = "const float LN_SCALE_MIN = -12.0;\nconst float LN_SCALE_MAX = 9.0;\n\nconst uint SPLAT_TEX_WIDTH_BITS = 11u;\nconst uint SPLAT_TEX_HEIGHT_BITS = 11u;\nconst uint SPLAT_TEX_DEPTH_BITS = 11u;\nconst uint SPLAT_TEX_LAYER_BITS = SPLAT_TEX_WIDTH_BITS + SPLAT_TEX_HEIGHT_BITS;\n\nconst uint SPLAT_TEX_WIDTH = 1u << SPLAT_TEX_WIDTH_BITS;\nconst uint SPLAT_TEX_HEIGHT = 1u << SPLAT_TEX_HEIGHT_BITS;\nconst uint SPLAT_TEX_DEPTH = 1u << SPLAT_TEX_DEPTH_BITS;\n\nconst uint SPLAT_TEX_WIDTH_MASK = SPLAT_TEX_WIDTH - 1u;\nconst uint SPLAT_TEX_HEIGHT_MASK = SPLAT_TEX_HEIGHT - 1u;\nconst uint SPLAT_TEX_DEPTH_MASK = SPLAT_TEX_DEPTH - 1u;\n\nconst uint F16_INF = 0x7c00u;\nconst float PI = 3.1415926535897932384626433832795;\n\nconst float INFINITY = 1.0 / 0.0;\nconst float NEG_INFINITY = -INFINITY;\n\nfloat sqr(float x) {\n return x * x;\n}\n\nfloat pow4(float x) {\n float x2 = x * x;\n return x2 * x2;\n}\n\nfloat pow8(float x) {\n float x4 = pow4(x);\n return x4 * x4;\n}\n\nvec3 srgbToLinear(vec3 rgb) {\n return pow(rgb, vec3(2.2));\n}\n\nvec3 linearToSrgb(vec3 rgb) {\n return pow(rgb, vec3(1.0 / 2.2));\n}\n\nuint encodeQuatOctXy88R8(vec4 q) {\n \n if (q.w < 0.0) {\n q = -q;\n }\n \n float theta = 2.0 * acos(q.w);\n float halfTheta = theta * 0.5;\n float s = sin(halfTheta);\n \n vec3 axis = (abs(s) < 1e-6) ? vec3(1.0, 0.0, 0.0) : q.xyz / s;\n \n \n \n float sum = abs(axis.x) + abs(axis.y) + abs(axis.z);\n vec2 p = vec2(axis.x, axis.y) / sum;\n \n if (axis.z < 0.0) {\n float oldPx = p.x;\n p.x = (1.0 - abs(p.y)) * (p.x >= 0.0 ? 1.0 : -1.0);\n p.y = (1.0 - abs(oldPx)) * (p.y >= 0.0 ? 1.0 : -1.0);\n }\n \n float u_f = p.x * 0.5 + 0.5;\n float v_f = p.y * 0.5 + 0.5;\n \n uint quantU = uint(clamp(round(u_f * 255.0), 0.0, 255.0));\n uint quantV = uint(clamp(round(v_f * 255.0), 0.0, 255.0));\n \n \n \n uint angleInt = uint(clamp(round((theta / 3.14159265359) * 255.0), 0.0, 255.0));\n \n \n return (angleInt << 16u) | (quantV << 8u) | quantU;\n}\n\nvec4 decodeQuatOctXy88R8(uint encoded) {\n \n uint quantU = encoded & uint(0xFFu); \n uint quantV = (encoded >> 8u) & uint(0xFFu); \n uint angleInt = encoded >> 16u; \n\n \n float u_f = float(quantU) / 255.0;\n float v_f = float(quantV) / 255.0;\n vec2 f = vec2(u_f * 2.0 - 1.0, v_f * 2.0 - 1.0);\n\n vec3 axis = vec3(f.xy, 1.0 - abs(f.x) - abs(f.y));\n float t = max(-axis.z, 0.0);\n axis.x += (axis.x >= 0.0) ? -t : t;\n axis.y += (axis.y >= 0.0) ? -t : t;\n axis = normalize(axis);\n \n \n float theta = (float(angleInt) / 255.0) * 3.14159265359;\n float halfTheta = theta * 0.5;\n float s = sin(halfTheta);\n float w = cos(halfTheta);\n \n return vec4(axis * s, w);\n}\n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\nuvec4 packSplatEncoding(\n vec3 center, vec3 scales, vec4 quaternion, vec4 rgba, vec4 rgbMinMaxLnScaleMinMax\n) {\n float rgbMin = rgbMinMaxLnScaleMinMax.x;\n float rgbMax = rgbMinMaxLnScaleMinMax.y;\n vec3 encRgb = (rgba.rgb - vec3(rgbMin)) / (rgbMax - rgbMin);\n uvec4 uRgba = uvec4(round(clamp(vec4(encRgb, rgba.a) * 255.0, 0.0, 255.0)));\n\n uint uQuat = encodeQuatOctXy88R8(quaternion);\n \n \n uvec3 uQuat3 = uvec3(uQuat & 0xffu, (uQuat >> 8u) & 0xffu, (uQuat >> 16u) & 0xffu);\n\n \n float lnScaleMin = rgbMinMaxLnScaleMinMax.z;\n float lnScaleMax = rgbMinMaxLnScaleMinMax.w;\n float lnScaleScale = 254.0 / (lnScaleMax - lnScaleMin);\n uvec3 uScales = uvec3(\n (scales.x == 0.0) ? 0u : uint(round(clamp((log(scales.x) - lnScaleMin) * lnScaleScale, 0.0, 254.0))) + 1u,\n (scales.y == 0.0) ? 0u : uint(round(clamp((log(scales.y) - lnScaleMin) * lnScaleScale, 0.0, 254.0))) + 1u,\n (scales.z == 0.0) ? 0u : uint(round(clamp((log(scales.z) - lnScaleMin) * lnScaleScale, 0.0, 254.0))) + 1u\n );\n\n \n uint word0 = uRgba.r | (uRgba.g << 8u) | (uRgba.b << 16u) | (uRgba.a << 24u);\n uint word1 = packHalf2x16(center.xy);\n uint word2 = packHalf2x16(vec2(center.z, 0.0)) | (uQuat3.x << 16u) | (uQuat3.y << 24u);\n uint word3 = uScales.x | (uScales.y << 8u) | (uScales.z << 16u) | (uQuat3.z << 24u);\n return uvec4(word0, word1, word2, word3);\n}\n\nuvec4 packSplat(vec3 center, vec3 scales, vec4 quaternion, vec4 rgba) {\n return packSplatEncoding(center, scales, quaternion, rgba, vec4(0.0, 1.0, LN_SCALE_MIN, LN_SCALE_MAX));\n}\n\nvoid unpackSplatEncoding(uvec4 packed, out vec3 center, out vec3 scales, out vec4 quaternion, out vec4 rgba, vec4 rgbMinMaxLnScaleMinMax) {\n uint word0 = packed.x, word1 = packed.y, word2 = packed.z, word3 = packed.w;\n\n uvec4 uRgba = uvec4(word0 & 0xffu, (word0 >> 8u) & 0xffu, (word0 >> 16u) & 0xffu, (word0 >> 24u) & 0xffu);\n float rgbMin = rgbMinMaxLnScaleMinMax.x;\n float rgbMax = rgbMinMaxLnScaleMinMax.y;\n rgba = (vec4(uRgba) / 255.0);\n rgba.rgb = rgba.rgb * (rgbMax - rgbMin) + rgbMin;\n\n center = vec4(\n unpackHalf2x16(word1),\n unpackHalf2x16(word2 & 0xffffu)\n ).xyz;\n\n uvec3 uScales = uvec3(word3 & 0xffu, (word3 >> 8u) & 0xffu, (word3 >> 16u) & 0xffu);\n float lnScaleMin = rgbMinMaxLnScaleMinMax.z;\n float lnScaleMax = rgbMinMaxLnScaleMinMax.w;\n float lnScaleScale = (lnScaleMax - lnScaleMin) / 254.0;\n scales = vec3(\n (uScales.x == 0u) ? 0.0 : exp(lnScaleMin + float(uScales.x - 1u) * lnScaleScale),\n (uScales.y == 0u) ? 0.0 : exp(lnScaleMin + float(uScales.y - 1u) * lnScaleScale),\n (uScales.z == 0u) ? 0.0 : exp(lnScaleMin + float(uScales.z - 1u) * lnScaleScale)\n );\n\n uint uQuat = ((word2 >> 16u) & 0xFFFFu) | ((word3 >> 8u) & 0xFF0000u);\n quaternion = decodeQuatOctXy88R8(uQuat);\n \n \n}\n\nvoid unpackSplat(uvec4 packed, out vec3 center, out vec3 scales, out vec4 quaternion, out vec4 rgba) {\n unpackSplatEncoding(packed, center, scales, quaternion, rgba, vec4(0.0, 1.0, LN_SCALE_MIN, LN_SCALE_MAX));\n}\n\nvec3 quatVec(vec4 q, vec3 v) {\n \n vec3 t = 2.0 * cross(q.xyz, v);\n return v + q.w * t + cross(q.xyz, t);\n}\n\nvec4 quatQuat(vec4 q1, vec4 q2) {\n return vec4(\n q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y,\n q1.w * q2.y - q1.x * q2.z + q1.y * q2.w + q1.z * q2.x,\n q1.w * q2.z + q1.x * q2.y - q1.y * q2.x + q1.z * q2.w,\n q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z\n );\n}\n\nmat3 scaleQuaternionToMatrix(vec3 s, vec4 q) {\n \n return mat3(\n s.x * (1.0 - 2.0 * (q.y * q.y + q.z * q.z)),\n s.x * (2.0 * (q.x * q.y + q.w * q.z)),\n s.x * (2.0 * (q.x * q.z - q.w * q.y)),\n s.y * (2.0 * (q.x * q.y - q.w * q.z)),\n s.y * (1.0 - 2.0 * (q.x * q.x + q.z * q.z)),\n s.y * (2.0 * (q.y * q.z + q.w * q.x)),\n s.z * (2.0 * (q.x * q.z + q.w * q.y)),\n s.z * (2.0 * (q.y * q.z - q.w * q.x)),\n s.z * (1.0 - 2.0 * (q.x * q.x + q.y * q.y))\n );\n}\n\nvec4 slerp(vec4 q1, vec4 q2, float t) {\n \n float cosHalfTheta = dot(q1, q2);\n\n \n if (abs(cosHalfTheta) >= 0.999) {\n return q1;\n }\n \n \n \n if (cosHalfTheta < 0.0) {\n q2 = -q2;\n cosHalfTheta = -cosHalfTheta;\n }\n\n \n float halfTheta = acos(cosHalfTheta);\n float sinHalfTheta = sqrt(1.0 - cosHalfTheta * cosHalfTheta);\n\n \n float ratioA = sin((1.0 - t) * halfTheta) / sinHalfTheta;\n float ratioB = sin(t * halfTheta) / sinHalfTheta;\n\n \n return q1 * ratioA + q2 * ratioB;\n}\n\nivec3 splatTexCoord(int index) {\n uint x = uint(index) & SPLAT_TEX_WIDTH_MASK;\n uint y = (uint(index) >> SPLAT_TEX_WIDTH_BITS) & SPLAT_TEX_HEIGHT_MASK;\n uint z = uint(index) >> SPLAT_TEX_LAYER_BITS;\n return ivec3(x, y, z);\n}";
|
|
10359
|
-
var splatFragment_default = "precision highp float;\nprecision highp int;\n\n#include <splatDefines>\n\nuniform float near;\nuniform float far;\nuniform bool encodeLinear;\nuniform float time;\nuniform bool debugFlag;\nuniform float maxStdDev;\nuniform float minAlpha;\nuniform bool stochastic;\nuniform bool disableFalloff;\nuniform float falloff;\n\nuniform bool splatTexEnable;\nuniform sampler3D splatTexture;\nuniform mat2 splatTexMul;\nuniform vec2 splatTexAdd;\nuniform float splatTexNear;\nuniform float splatTexFar;\nuniform float splatTexMid;\n\nout vec4 fragColor;\n\nin vec4 vRgba;\nin vec2 vSplatUv;\nin vec3 vNdc;\nflat in uint vSplatIndex;\n\nvoid main() {\n vec4 rgba = vRgba;\n\n float z = dot(vSplatUv, vSplatUv);\n if (!splatTexEnable) {\n if (z > (maxStdDev * maxStdDev)) {\n discard;\n }\n } else {\n vec2 uv = splatTexMul * vSplatUv + splatTexAdd;\n float ndcZ = vNdc.z;\n float depth = (2.0 * near * far) / (far + near - ndcZ * (far - near));\n float clampedFar = max(splatTexFar, splatTexNear);\n float clampedDepth = clamp(depth, splatTexNear, clampedFar);\n float logDepth = log2(clampedDepth + 1.0);\n float logNear = log2(splatTexNear + 1.0);\n float logFar = log2(clampedFar + 1.0);\n\n float texZ;\n if (splatTexMid > 0.0) {\n float clampedMid = clamp(splatTexMid, splatTexNear, clampedFar);\n float logMid = log2(clampedMid + 1.0);\n texZ = (clampedDepth <= clampedMid) ?\n (0.5 * ((logDepth - logNear) / (logMid - logNear))) :\n (0.5 * ((logDepth - logMid) / (logFar - logMid)) + 0.5);\n } else {\n texZ = (logDepth - logNear) / (logFar - logNear);\n }\n\n vec4 modulate = texture(splatTexture, vec3(uv, 1.0 - texZ));\n rgba *= modulate;\n }\n\n rgba.a *= mix(1.0, exp(-0.5 * z), falloff);\n\n if (rgba.a < minAlpha) {\n discard;\n }\n if (encodeLinear) {\n rgba.rgb = srgbToLinear(rgba.rgb);\n }\n\n if (stochastic) {\n const bool STEADY = false;\n uint uTime = STEADY ? 0u : floatBitsToUint(time);\n uvec2 coord = uvec2(gl_FragCoord.xy);\n uint state = uTime + 0x9e3779b9u * coord.x + 0x85ebca6bu * coord.y + 0xc2b2ae35u * uint(vSplatIndex);\n state = state * 747796405u + 2891336453u;\n uint hash = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u;\n hash = (hash >> 22u) ^ hash;\n float rand = float(hash) / 4294967296.0;\n if (rand < rgba.a) {\n fragColor = vec4(rgba.rgb, 1.0);\n } else {\n discard;\n }\n } else {\n #ifdef PREMULTIPLIED_ALPHA\n fragColor = vec4(rgba.rgb * rgba.a, rgba.a);\n #else\n fragColor = rgba;\n #endif\n }\n}";
|
|
10360
|
-
var splatVertex_default = "precision highp float;\nprecision highp int;\nprecision highp usampler2DArray;\n\n#include <splatDefines>\n\nattribute uint splatIndex;\n\nout vec4 vRgba;\nout vec2 vSplatUv;\nout vec3 vNdc;\nflat out uint vSplatIndex;\n\nuniform vec2 renderSize;\nuniform uint numSplats;\nuniform vec4 renderToViewQuat;\nuniform vec3 renderToViewPos;\nuniform float maxStdDev;\nuniform float maxPixelRadius;\nuniform float time;\nuniform float deltaTime;\nuniform bool debugFlag;\nuniform float minAlpha;\nuniform bool stochastic;\nuniform bool enable2DGS;\nuniform float blurAmount;\nuniform float preBlurAmount;\nuniform float focalDistance;\nuniform float apertureAngle;\nuniform float clipXY;\nuniform float focalAdjustment;\n\nuniform usampler2DArray packedSplats;\nuniform vec4 rgbMinMaxLnScaleMinMax;\n\nvoid main() {\n \n gl_Position = vec4(0.0, 0.0, 2.0, 1.0);\n\n if (uint(gl_InstanceID) >= numSplats) {\n return;\n }\n\n ivec3 texCoord;\n if (stochastic) {\n texCoord = ivec3(\n uint(gl_InstanceID) & SPLAT_TEX_WIDTH_MASK,\n (uint(gl_InstanceID) >> SPLAT_TEX_WIDTH_BITS) & SPLAT_TEX_HEIGHT_MASK,\n (uint(gl_InstanceID) >> SPLAT_TEX_LAYER_BITS)\n );\n } else {\n if (splatIndex == 0xffffffffu) {\n \n return;\n }\n texCoord = ivec3(\n splatIndex & SPLAT_TEX_WIDTH_MASK,\n (splatIndex >> SPLAT_TEX_WIDTH_BITS) & SPLAT_TEX_HEIGHT_MASK,\n splatIndex >> SPLAT_TEX_LAYER_BITS\n );\n }\n uvec4 packed = texelFetch(packedSplats, texCoord, 0);\n\n vec3 center, scales;\n vec4 quaternion, rgba;\n unpackSplatEncoding(packed, center, scales, quaternion, rgba, rgbMinMaxLnScaleMinMax);\n\n if (rgba.a < minAlpha) {\n return;\n }\n bvec3 zeroScales = equal(scales, vec3(0.0));\n if (all(zeroScales)) {\n return;\n }\n\n \n vec3 viewCenter = quatVec(renderToViewQuat, center) + renderToViewPos;\n\n \n if (viewCenter.z >= 0.0) {\n return;\n }\n\n \n vec4 clipCenter = projectionMatrix * vec4(viewCenter, 1.0);\n\n \n if (abs(clipCenter.z) >= clipCenter.w) {\n return;\n }\n\n \n float clip = clipXY * clipCenter.w;\n if (abs(clipCenter.x) > clip || abs(clipCenter.y) > clip) {\n return;\n }\n\n \n vSplatIndex = splatIndex;\n\n \n vec4 viewQuaternion = quatQuat(renderToViewQuat, quaternion);\n\n if (enable2DGS && any(zeroScales)) {\n vRgba = rgba;\n vSplatUv = position.xy * maxStdDev;\n\n vec3 offset;\n if (zeroScales.z) {\n offset = vec3(vSplatUv.xy * scales.xy, 0.0);\n } else if (zeroScales.y) {\n offset = vec3(vSplatUv.x * scales.x, 0.0, vSplatUv.y * scales.z);\n } else {\n offset = vec3(0.0, vSplatUv.xy * scales.yz);\n }\n\n vec3 viewPos = viewCenter + quatVec(viewQuaternion, offset);\n gl_Position = projectionMatrix * vec4(viewPos, 1.0);\n vNdc = gl_Position.xyz / gl_Position.w;\n return;\n }\n\n \n vec3 ndcCenter = clipCenter.xyz / clipCenter.w;\n\n \n mat3 RS = scaleQuaternionToMatrix(scales, viewQuaternion);\n mat3 cov3D = RS * transpose(RS);\n\n \n vec2 scaledRenderSize = renderSize * focalAdjustment;\n vec2 focal = 0.5 * scaledRenderSize * vec2(projectionMatrix[0][0], projectionMatrix[1][1]);\n\n mat3 J;\n if(isOrthographic) {\n J = mat3(\n focal.x, 0.0, 0.0,\n 0.0, focal.y, 0.0,\n 0.0, 0.0, 0.0\n );\n } else {\n float invZ = 1.0 / viewCenter.z;\n vec2 J1 = focal * invZ;\n vec2 J2 = -(J1 * viewCenter.xy) * invZ;\n J = mat3(\n J1.x, 0.0, J2.x,\n 0.0, J1.y, J2.y,\n 0.0, 0.0, 0.0\n );\n }\n\n \n \n \n \n \n \n \n mat3 cov2D = transpose(J) * cov3D * J;\n float a = cov2D[0][0];\n float d = cov2D[1][1];\n float b = cov2D[0][1];\n\n \n a += preBlurAmount;\n d += preBlurAmount;\n\n float fullBlurAmount = blurAmount;\n if ((focalDistance > 0.0) && (apertureAngle > 0.0)) {\n float focusRadius = maxPixelRadius;\n if (viewCenter.z < 0.0) {\n float focusBlur = abs((-viewCenter.z - focalDistance) / viewCenter.z);\n float apertureRadius = focal.x * tan(0.5 * apertureAngle);\n focusRadius = focusBlur * apertureRadius;\n }\n fullBlurAmount = clamp(sqr(focusRadius), blurAmount, sqr(maxPixelRadius));\n }\n\n \n float detOrig = a * d - b * b;\n a += fullBlurAmount;\n d += fullBlurAmount;\n float det = a * d - b * b;\n\n \n float blurAdjust = sqrt(max(0.0, detOrig / det));\n rgba.a *= blurAdjust;\n if (rgba.a < minAlpha) {\n return;\n }\n\n \n float eigenAvg = 0.5 * (a + d);\n float eigenDelta = sqrt(max(0.0, eigenAvg * eigenAvg - det));\n float eigen1 = eigenAvg + eigenDelta;\n float eigen2 = eigenAvg - eigenDelta;\n\n vec2 eigenVec1 = normalize(vec2((abs(b) < 0.001) ? 1.0 : b, eigen1 - a));\n vec2 eigenVec2 = vec2(eigenVec1.y, -eigenVec1.x);\n\n float scale1 =
|
|
10378
|
+
var splatFragment_default = "precision highp float;\nprecision highp int;\n\n#include <splatDefines>\n#include <logdepthbuf_pars_fragment>\n\nuniform float near;\nuniform float far;\nuniform bool encodeLinear;\nuniform float time;\nuniform bool debugFlag;\nuniform float maxStdDev;\nuniform float minAlpha;\nuniform bool stochastic;\nuniform bool disableFalloff;\nuniform float falloff;\n\nuniform bool splatTexEnable;\nuniform sampler3D splatTexture;\nuniform mat2 splatTexMul;\nuniform vec2 splatTexAdd;\nuniform float splatTexNear;\nuniform float splatTexFar;\nuniform float splatTexMid;\n\nout vec4 fragColor;\n\nin vec4 vRgba;\nin vec2 vSplatUv;\nin vec3 vNdc;\nflat in uint vSplatIndex;\n\nvoid main() {\n vec4 rgba = vRgba;\n\n float z = dot(vSplatUv, vSplatUv);\n if (!splatTexEnable) {\n if (z > (maxStdDev * maxStdDev)) {\n discard;\n }\n } else {\n vec2 uv = splatTexMul * vSplatUv + splatTexAdd;\n float ndcZ = vNdc.z;\n float depth = (2.0 * near * far) / (far + near - ndcZ * (far - near));\n float clampedFar = max(splatTexFar, splatTexNear);\n float clampedDepth = clamp(depth, splatTexNear, clampedFar);\n float logDepth = log2(clampedDepth + 1.0);\n float logNear = log2(splatTexNear + 1.0);\n float logFar = log2(clampedFar + 1.0);\n\n float texZ;\n if (splatTexMid > 0.0) {\n float clampedMid = clamp(splatTexMid, splatTexNear, clampedFar);\n float logMid = log2(clampedMid + 1.0);\n texZ = (clampedDepth <= clampedMid) ?\n (0.5 * ((logDepth - logNear) / (logMid - logNear))) :\n (0.5 * ((logDepth - logMid) / (logFar - logMid)) + 0.5);\n } else {\n texZ = (logDepth - logNear) / (logFar - logNear);\n }\n\n vec4 modulate = texture(splatTexture, vec3(uv, 1.0 - texZ));\n rgba *= modulate;\n }\n\n rgba.a *= mix(1.0, exp(-0.5 * z), falloff);\n\n if (rgba.a < minAlpha) {\n discard;\n }\n if (encodeLinear) {\n rgba.rgb = srgbToLinear(rgba.rgb);\n }\n\n if (stochastic) {\n const bool STEADY = false;\n uint uTime = STEADY ? 0u : floatBitsToUint(time);\n uvec2 coord = uvec2(gl_FragCoord.xy);\n uint state = uTime + 0x9e3779b9u * coord.x + 0x85ebca6bu * coord.y + 0xc2b2ae35u * uint(vSplatIndex);\n state = state * 747796405u + 2891336453u;\n uint hash = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u;\n hash = (hash >> 22u) ^ hash;\n float rand = float(hash) / 4294967296.0;\n if (rand < rgba.a) {\n fragColor = vec4(rgba.rgb, 1.0);\n } else {\n discard;\n }\n } else {\n #ifdef PREMULTIPLIED_ALPHA\n fragColor = vec4(rgba.rgb * rgba.a, rgba.a);\n #else\n fragColor = rgba;\n #endif\n }\n #include <logdepthbuf_fragment>\n}";
|
|
10379
|
+
var splatVertex_default = "precision highp float;\nprecision highp int;\nprecision highp usampler2DArray;\n\n#include <splatDefines>\n#include <logdepthbuf_pars_vertex>\n\nattribute uint splatIndex;\n\nout vec4 vRgba;\nout vec2 vSplatUv;\nout vec3 vNdc;\nflat out uint vSplatIndex;\n\nuniform vec2 renderSize;\nuniform uint numSplats;\nuniform vec4 renderToViewQuat;\nuniform vec3 renderToViewPos;\nuniform float maxStdDev;\nuniform float minPixelRadius;\nuniform float maxPixelRadius;\nuniform float time;\nuniform float deltaTime;\nuniform bool debugFlag;\nuniform float minAlpha;\nuniform bool stochastic;\nuniform bool enable2DGS;\nuniform float blurAmount;\nuniform float preBlurAmount;\nuniform float focalDistance;\nuniform float apertureAngle;\nuniform float clipXY;\nuniform float focalAdjustment;\n\nuniform usampler2DArray packedSplats;\nuniform vec4 rgbMinMaxLnScaleMinMax;\n\n#ifdef USE_LOGDEPTHBUF\n bool isPerspectiveMatrix( mat4 m ) {\n return m[ 2 ][ 3 ] == - 1.0;\n }\n#endif\n\nvoid main() {\n \n gl_Position = vec4(0.0, 0.0, 2.0, 1.0);\n\n if (uint(gl_InstanceID) >= numSplats) {\n return;\n }\n\n ivec3 texCoord;\n if (stochastic) {\n texCoord = ivec3(\n uint(gl_InstanceID) & SPLAT_TEX_WIDTH_MASK,\n (uint(gl_InstanceID) >> SPLAT_TEX_WIDTH_BITS) & SPLAT_TEX_HEIGHT_MASK,\n (uint(gl_InstanceID) >> SPLAT_TEX_LAYER_BITS)\n );\n } else {\n if (splatIndex == 0xffffffffu) {\n \n return;\n }\n texCoord = ivec3(\n splatIndex & SPLAT_TEX_WIDTH_MASK,\n (splatIndex >> SPLAT_TEX_WIDTH_BITS) & SPLAT_TEX_HEIGHT_MASK,\n splatIndex >> SPLAT_TEX_LAYER_BITS\n );\n }\n uvec4 packed = texelFetch(packedSplats, texCoord, 0);\n\n vec3 center, scales;\n vec4 quaternion, rgba;\n unpackSplatEncoding(packed, center, scales, quaternion, rgba, rgbMinMaxLnScaleMinMax);\n\n if (rgba.a < minAlpha) {\n return;\n }\n bvec3 zeroScales = equal(scales, vec3(0.0));\n if (all(zeroScales)) {\n return;\n }\n\n \n vec3 viewCenter = quatVec(renderToViewQuat, center) + renderToViewPos;\n\n \n if (viewCenter.z >= 0.0) {\n return;\n }\n\n \n vec4 clipCenter = projectionMatrix * vec4(viewCenter, 1.0);\n\n \n if (abs(clipCenter.z) >= clipCenter.w) {\n return;\n }\n\n \n float clip = clipXY * clipCenter.w;\n if (abs(clipCenter.x) > clip || abs(clipCenter.y) > clip) {\n return;\n }\n\n \n vSplatIndex = splatIndex;\n\n \n vec4 viewQuaternion = quatQuat(renderToViewQuat, quaternion);\n\n if (enable2DGS && any(zeroScales)) {\n vRgba = rgba;\n vSplatUv = position.xy * maxStdDev;\n\n vec3 offset;\n if (zeroScales.z) {\n offset = vec3(vSplatUv.xy * scales.xy, 0.0);\n } else if (zeroScales.y) {\n offset = vec3(vSplatUv.x * scales.x, 0.0, vSplatUv.y * scales.z);\n } else {\n offset = vec3(0.0, vSplatUv.xy * scales.yz);\n }\n\n vec3 viewPos = viewCenter + quatVec(viewQuaternion, offset);\n gl_Position = projectionMatrix * vec4(viewPos, 1.0);\n vNdc = gl_Position.xyz / gl_Position.w;\n return;\n }\n\n \n vec3 ndcCenter = clipCenter.xyz / clipCenter.w;\n\n \n mat3 RS = scaleQuaternionToMatrix(scales, viewQuaternion);\n mat3 cov3D = RS * transpose(RS);\n\n \n vec2 scaledRenderSize = renderSize * focalAdjustment;\n vec2 focal = 0.5 * scaledRenderSize * vec2(projectionMatrix[0][0], projectionMatrix[1][1]);\n\n mat3 J;\n if(isOrthographic) {\n J = mat3(\n focal.x, 0.0, 0.0,\n 0.0, focal.y, 0.0,\n 0.0, 0.0, 0.0\n );\n } else {\n float invZ = 1.0 / viewCenter.z;\n vec2 J1 = focal * invZ;\n vec2 J2 = -(J1 * viewCenter.xy) * invZ;\n J = mat3(\n J1.x, 0.0, J2.x,\n 0.0, J1.y, J2.y,\n 0.0, 0.0, 0.0\n );\n }\n\n \n \n \n \n \n \n \n mat3 cov2D = transpose(J) * cov3D * J;\n float a = cov2D[0][0];\n float d = cov2D[1][1];\n float b = cov2D[0][1];\n\n \n a += preBlurAmount;\n d += preBlurAmount;\n\n float fullBlurAmount = blurAmount;\n if ((focalDistance > 0.0) && (apertureAngle > 0.0)) {\n float focusRadius = maxPixelRadius;\n if (viewCenter.z < 0.0) {\n float focusBlur = abs((-viewCenter.z - focalDistance) / viewCenter.z);\n float apertureRadius = focal.x * tan(0.5 * apertureAngle);\n focusRadius = focusBlur * apertureRadius;\n }\n fullBlurAmount = clamp(sqr(focusRadius), blurAmount, sqr(maxPixelRadius));\n }\n\n \n float detOrig = a * d - b * b;\n a += fullBlurAmount;\n d += fullBlurAmount;\n float det = a * d - b * b;\n\n \n float blurAdjust = sqrt(max(0.0, detOrig / det));\n rgba.a *= blurAdjust;\n if (rgba.a < minAlpha) {\n return;\n }\n\n \n float eigenAvg = 0.5 * (a + d);\n float eigenDelta = sqrt(max(0.0, eigenAvg * eigenAvg - det));\n float eigen1 = eigenAvg + eigenDelta;\n float eigen2 = eigenAvg - eigenDelta;\n\n vec2 eigenVec1 = normalize(vec2((abs(b) < 0.001) ? 1.0 : b, eigen1 - a));\n vec2 eigenVec2 = vec2(eigenVec1.y, -eigenVec1.x);\n\n float scale1 = min(maxPixelRadius, maxStdDev * sqrt(eigen1));\n float scale2 = min(maxPixelRadius, maxStdDev * sqrt(eigen2));\n if (scale1 < minPixelRadius && scale2 < minPixelRadius) {\n return;\n }\n\n \n vec2 pixelOffset = position.x * eigenVec1 * scale1 + position.y * eigenVec2 * scale2;\n vec2 ndcOffset = (2.0 / scaledRenderSize) * pixelOffset;\n vec3 ndc = vec3(ndcCenter.xy + ndcOffset, ndcCenter.z);\n\n vRgba = rgba;\n vSplatUv = position.xy * maxStdDev;\n vNdc = ndc;\n gl_Position = vec4(ndc.xy * clipCenter.w, clipCenter.zw);\n #include <logdepthbuf_vertex>\n}";
|
|
10361
10380
|
let shaders = null;
|
|
10362
10381
|
function getShaders() {
|
|
10363
10382
|
if (!shaders) {
|
|
@@ -10426,6 +10445,7 @@ const _SparkRenderer = class _SparkRenderer extends THREE__namespace.Mesh {
|
|
|
10426
10445
|
this.needsUpdate = false;
|
|
10427
10446
|
this.originDistance = options.originDistance ?? 1;
|
|
10428
10447
|
this.maxStdDev = options.maxStdDev ?? Math.sqrt(8);
|
|
10448
|
+
this.minPixelRadius = options.minPixelRadius ?? 0;
|
|
10429
10449
|
this.maxPixelRadius = options.maxPixelRadius ?? 512;
|
|
10430
10450
|
this.minAlpha = options.minAlpha ?? 0.5 * (1 / 255);
|
|
10431
10451
|
this.enable2DGS = options.enable2DGS ?? false;
|
|
@@ -10438,6 +10458,7 @@ const _SparkRenderer = class _SparkRenderer extends THREE__namespace.Mesh {
|
|
|
10438
10458
|
this.focalAdjustment = options.focalAdjustment ?? 1;
|
|
10439
10459
|
this.splatEncoding = options.splatEncoding ?? { ...DEFAULT_SPLAT_ENCODING };
|
|
10440
10460
|
this.active = new SplatAccumulator();
|
|
10461
|
+
this.active.refCount = 1;
|
|
10441
10462
|
this.accumulatorCount = 1;
|
|
10442
10463
|
this.freeAccumulators = [];
|
|
10443
10464
|
for (let count = 0; count < 1; ++count) {
|
|
@@ -10468,6 +10489,8 @@ const _SparkRenderer = class _SparkRenderer extends THREE__namespace.Mesh {
|
|
|
10468
10489
|
renderToViewPos: { value: new THREE__namespace.Vector3() },
|
|
10469
10490
|
// Maximum distance (in stddevs) from Gsplat center to render
|
|
10470
10491
|
maxStdDev: { value: 1 },
|
|
10492
|
+
// Minimum pixel radius for splat rendering
|
|
10493
|
+
minPixelRadius: { value: 0 },
|
|
10471
10494
|
// Maximum pixel radius for splat rendering
|
|
10472
10495
|
maxPixelRadius: { value: 512 },
|
|
10473
10496
|
// Minimum alpha value for splat rendering
|
|
@@ -10602,6 +10625,7 @@ const _SparkRenderer = class _SparkRenderer extends THREE__namespace.Mesh {
|
|
|
10602
10625
|
this.uniforms.far.value = typedCamera.far;
|
|
10603
10626
|
this.uniforms.encodeLinear.value = viewpoint.encodeLinear;
|
|
10604
10627
|
this.uniforms.maxStdDev.value = this.maxStdDev;
|
|
10628
|
+
this.uniforms.minPixelRadius.value = this.minPixelRadius;
|
|
10605
10629
|
this.uniforms.maxPixelRadius.value = this.maxPixelRadius;
|
|
10606
10630
|
this.uniforms.minAlpha.value = this.minAlpha;
|
|
10607
10631
|
this.uniforms.stochastic.value = viewpoint.stochastic;
|
|
@@ -10773,7 +10797,7 @@ const _SparkRenderer = class _SparkRenderer extends THREE__namespace.Mesh {
|
|
|
10773
10797
|
}
|
|
10774
10798
|
const originChanged = !withinCoorientDist({
|
|
10775
10799
|
matrix1: originToWorld,
|
|
10776
|
-
matrix2:
|
|
10800
|
+
matrix2: accumulator.toWorld,
|
|
10777
10801
|
maxDistance: 1e-5,
|
|
10778
10802
|
minCoorient: 0.99999
|
|
10779
10803
|
});
|
|
@@ -11298,9 +11322,23 @@ function decodeKsplat(fileBytes, initNumSplats, splatCallback, shCallback) {
|
|
|
11298
11322
|
}
|
|
11299
11323
|
class SpzReader {
|
|
11300
11324
|
constructor({ fileBytes }) {
|
|
11325
|
+
this.version = -1;
|
|
11326
|
+
this.numSplats = 0;
|
|
11327
|
+
this.shDegree = 0;
|
|
11328
|
+
this.fractionalBits = 0;
|
|
11329
|
+
this.flags = 0;
|
|
11330
|
+
this.flagAntiAlias = false;
|
|
11331
|
+
this.reserved = 0;
|
|
11332
|
+
this.headerParsed = false;
|
|
11333
|
+
this.parsed = false;
|
|
11301
11334
|
this.fileBytes = fileBytes instanceof ArrayBuffer ? new Uint8Array(fileBytes) : fileBytes;
|
|
11302
11335
|
this.reader = new GunzipReader({ fileBytes: this.fileBytes });
|
|
11303
|
-
|
|
11336
|
+
}
|
|
11337
|
+
async parseHeader() {
|
|
11338
|
+
if (this.headerParsed) {
|
|
11339
|
+
throw new Error("SPZ file header already parsed");
|
|
11340
|
+
}
|
|
11341
|
+
const header = new DataView((await this.reader.read(16)).buffer);
|
|
11304
11342
|
if (header.getUint32(0, true) !== 1347635022) {
|
|
11305
11343
|
throw new Error("Invalid SPZ file");
|
|
11306
11344
|
}
|
|
@@ -11314,15 +11352,19 @@ class SpzReader {
|
|
|
11314
11352
|
this.flags = header.getUint8(14);
|
|
11315
11353
|
this.flagAntiAlias = (this.flags & 1) !== 0;
|
|
11316
11354
|
this.reserved = header.getUint8(15);
|
|
11355
|
+
this.headerParsed = true;
|
|
11317
11356
|
this.parsed = false;
|
|
11318
11357
|
}
|
|
11319
|
-
parseSplats(centerCallback, alphaCallback, rgbCallback, scalesCallback, quatCallback, shCallback) {
|
|
11358
|
+
async parseSplats(centerCallback, alphaCallback, rgbCallback, scalesCallback, quatCallback, shCallback) {
|
|
11359
|
+
if (!this.headerParsed) {
|
|
11360
|
+
throw new Error("SPZ file header must be parsed first");
|
|
11361
|
+
}
|
|
11320
11362
|
if (this.parsed) {
|
|
11321
11363
|
throw new Error("SPZ file already parsed");
|
|
11322
11364
|
}
|
|
11323
11365
|
this.parsed = true;
|
|
11324
11366
|
if (this.version === 1) {
|
|
11325
|
-
const centerBytes = this.reader.read(this.numSplats * 3 * 2);
|
|
11367
|
+
const centerBytes = await this.reader.read(this.numSplats * 3 * 2);
|
|
11326
11368
|
const centerUint16 = new Uint16Array(centerBytes.buffer);
|
|
11327
11369
|
for (let i = 0; i < this.numSplats; i++) {
|
|
11328
11370
|
const i3 = i * 3;
|
|
@@ -11333,7 +11375,7 @@ class SpzReader {
|
|
|
11333
11375
|
}
|
|
11334
11376
|
} else if (this.version === 2 || this.version === 3) {
|
|
11335
11377
|
const fixed = 1 << this.fractionalBits;
|
|
11336
|
-
const centerBytes = this.reader.read(this.numSplats * 3 * 3);
|
|
11378
|
+
const centerBytes = await this.reader.read(this.numSplats * 3 * 3);
|
|
11337
11379
|
for (let i = 0; i < this.numSplats; i++) {
|
|
11338
11380
|
const i9 = i * 9;
|
|
11339
11381
|
const x = ((centerBytes[i9 + 2] << 24 | centerBytes[i9 + 1] << 16 | centerBytes[i9] << 8) >> 8) / fixed;
|
|
@@ -11345,13 +11387,13 @@ class SpzReader {
|
|
|
11345
11387
|
throw new Error("Unreachable");
|
|
11346
11388
|
}
|
|
11347
11389
|
{
|
|
11348
|
-
const bytes = this.reader.read(this.numSplats);
|
|
11390
|
+
const bytes = await this.reader.read(this.numSplats);
|
|
11349
11391
|
for (let i = 0; i < this.numSplats; i++) {
|
|
11350
11392
|
alphaCallback == null ? void 0 : alphaCallback(i, bytes[i] / 255);
|
|
11351
11393
|
}
|
|
11352
11394
|
}
|
|
11353
11395
|
{
|
|
11354
|
-
const rgbBytes = this.reader.read(this.numSplats * 3);
|
|
11396
|
+
const rgbBytes = await this.reader.read(this.numSplats * 3);
|
|
11355
11397
|
const scale = SH_C0 / 0.15;
|
|
11356
11398
|
for (let i = 0; i < this.numSplats; i++) {
|
|
11357
11399
|
const i3 = i * 3;
|
|
@@ -11362,7 +11404,7 @@ class SpzReader {
|
|
|
11362
11404
|
}
|
|
11363
11405
|
}
|
|
11364
11406
|
{
|
|
11365
|
-
const scalesBytes = this.reader.read(this.numSplats * 3);
|
|
11407
|
+
const scalesBytes = await this.reader.read(this.numSplats * 3);
|
|
11366
11408
|
for (let i = 0; i < this.numSplats; i++) {
|
|
11367
11409
|
const i3 = i * 3;
|
|
11368
11410
|
const scaleX = Math.exp(scalesBytes[i3] / 16 - 10);
|
|
@@ -11373,7 +11415,7 @@ class SpzReader {
|
|
|
11373
11415
|
}
|
|
11374
11416
|
if (this.version === 3) {
|
|
11375
11417
|
const maxValue = 1 / Math.sqrt(2);
|
|
11376
|
-
const quatBytes = this.reader.read(this.numSplats * 4);
|
|
11418
|
+
const quatBytes = await this.reader.read(this.numSplats * 4);
|
|
11377
11419
|
for (let i = 0; i < this.numSplats; i++) {
|
|
11378
11420
|
const i3 = i * 4;
|
|
11379
11421
|
const quaternion = [0, 0, 0, 0];
|
|
@@ -11409,7 +11451,7 @@ class SpzReader {
|
|
|
11409
11451
|
);
|
|
11410
11452
|
}
|
|
11411
11453
|
} else {
|
|
11412
|
-
const quatBytes = this.reader.read(this.numSplats * 3);
|
|
11454
|
+
const quatBytes = await this.reader.read(this.numSplats * 3);
|
|
11413
11455
|
for (let i = 0; i < this.numSplats; i++) {
|
|
11414
11456
|
const i3 = i * 3;
|
|
11415
11457
|
const quatX = quatBytes[i3] / 127.5 - 1;
|
|
@@ -11425,7 +11467,7 @@ class SpzReader {
|
|
|
11425
11467
|
const sh1 = new Float32Array(3 * 3);
|
|
11426
11468
|
const sh2 = this.shDegree >= 2 ? new Float32Array(5 * 3) : void 0;
|
|
11427
11469
|
const sh3 = this.shDegree >= 3 ? new Float32Array(7 * 3) : void 0;
|
|
11428
|
-
const shBytes = this.reader.read(
|
|
11470
|
+
const shBytes = await this.reader.read(
|
|
11429
11471
|
this.numSplats * SH_DEGREE_TO_VECS[this.shDegree] * 3
|
|
11430
11472
|
);
|
|
11431
11473
|
let offset = 0;
|
|
@@ -11704,6 +11746,7 @@ async function transcodeSpz(input) {
|
|
|
11704
11746
|
}
|
|
11705
11747
|
case SplatFileType.SPZ: {
|
|
11706
11748
|
const spz2 = new SpzReader({ fileBytes: input2.fileBytes });
|
|
11749
|
+
await spz2.parseHeader();
|
|
11707
11750
|
const mapping = new Int32Array(spz2.numSplats);
|
|
11708
11751
|
mapping.fill(-1);
|
|
11709
11752
|
const centers = new Float32Array(spz2.numSplats * 3);
|
|
@@ -13747,6 +13790,7 @@ exports.PackedSplats = PackedSplats;
|
|
|
13747
13790
|
exports.PlyReader = PlyReader;
|
|
13748
13791
|
exports.PointerControls = PointerControls;
|
|
13749
13792
|
exports.Readback = Readback;
|
|
13793
|
+
exports.RgbaArray = RgbaArray;
|
|
13750
13794
|
exports.Sint8ToFloat = Sint8ToFloat;
|
|
13751
13795
|
exports.SparkControls = SparkControls;
|
|
13752
13796
|
exports.SparkRenderer = SparkRenderer;
|