{"version":3,"file":"gaussian-splats-3d.module.min.js","sources":["../src/AbortablePromise.js","../src/Util.js","../src/loaders/UncompressedSplatArray.js","../src/Constants.js","../src/loaders/SplatBuffer.js","../src/loaders/ply/PlayCanvasCompressedPlyParser.js","../src/loaders/ply/PlyFormat.js","../src/loaders/ply/PlyParserUtils.js","../src/loaders/ply/INRIAV1PlyParser.js","../src/loaders/ply/INRIAV2PlyParser.js","../src/loaders/ply/PlyParser.js","../src/loaders/SplatPartitioner.js","../src/loaders/SplatBufferGenerator.js","../src/loaders/LoaderStatus.js","../src/loaders/DirectLoadError.js","../src/loaders/InternalLoadType.js","../src/loaders/ply/PlyLoader.js","../src/loaders/Compression.js","../src/loaders/spz/SpzLoader.js","../src/loaders/splat/SplatParser.js","../src/loaders/splat/SplatLoader.js","../src/loaders/ksplat/KSplatLoader.js","../src/loaders/SceneFormat.js","../src/loaders/Utils.js","../src/OrbitControls.js","../src/ui/LoadingSpinner.js","../src/ui/Util.js","../src/ui/LoadingProgressBar.js","../src/ui/InfoPanel.js","../src/ArrowHelper.js","../src/SceneHelper.js","../src/raycaster/Ray.js","../src/raycaster/Hit.js","../src/SplatRenderMode.js","../src/raycaster/Raycaster.js","../src/splatmesh/SplatMaterial.js","../src/splatmesh/SplatMaterial3D.js","../src/splatmesh/SplatMaterial2D.js","../src/splatmesh/SplatGeometry.js","../src/splatmesh/SplatScene.js","../src/splattree/SplatTree.js","../src/three-shim/WebGLExtensions.js","../src/three-shim/WebGLCapabilities.js","../src/SceneRevealMode.js","../src/LogLevel.js","../src/splatmesh/SplatMesh.js","../src/worker/sorter.wasm","../src/worker/sorter_no_simd.wasm","../src/worker/SortWorker.js","../src/webxr/WebXRMode.js","../src/webxr/VRButton.js","../src/webxr/ARButton.js","../src/RenderMode.js","../src/Viewer.js","../src/worker/sorter_non_shared.wasm","../src/worker/sorter_no_simd_non_shared.wasm","../src/DropInViewer.js"],"sourcesContent":["/**\n * AbortablePromise: A quick & dirty wrapper for JavaScript's Promise class that allows the underlying\n * asynchronous operation to be cancelled. It is only meant for simple situations where no complex promise\n * chaining or merging occurs. It needs a significant amount of work to truly replicate the full\n * functionality of JavaScript's Promise class. Look at Util.fetchWithProgress() for example usage.\n *\n * This class was primarily added to allow splat scene downloads to be cancelled. It has not been tested\n * very thoroughly and the implementation is kinda janky. If you can at all help it, please avoid using it :)\n */\nexport class AbortablePromise {\n\n    static idGen = 0;\n\n    constructor(promiseFunc, abortHandler) {\n\n        let resolver;\n        let rejecter;\n        this.promise = new Promise((resolve, reject) => {\n            resolver = resolve;\n            rejecter = reject;\n        });\n\n        const promiseResolve = resolver.bind(this);\n        const promiseReject = rejecter.bind(this);\n\n        const resolve = (...args) => {\n            promiseResolve(...args);\n        };\n\n        const reject = (error) => {\n            promiseReject(error);\n        };\n\n        promiseFunc(resolve.bind(this), reject.bind(this));\n        this.abortHandler = abortHandler;\n        this.id = AbortablePromise.idGen++;\n    }\n\n    then(onResolve) {\n        return new AbortablePromise((resolve, reject) => {\n            this.promise = this.promise\n            .then((...args) => {\n                const onResolveResult = onResolve(...args);\n                if (onResolveResult instanceof Promise || onResolveResult instanceof AbortablePromise) {\n                    onResolveResult.then((...args2) => {\n                        resolve(...args2);\n                    });\n                } else {\n                    resolve(onResolveResult);\n                }\n            })\n            .catch((error) => {\n                reject(error);\n            });\n        }, this.abortHandler);\n    }\n\n    catch(onFail) {\n        return new AbortablePromise((resolve) => {\n            this.promise = this.promise.then((...args) => {\n                resolve(...args);\n            })\n            .catch(onFail);\n        }, this.abortHandler);\n    }\n\n    abort(reason) {\n        if (this.abortHandler) this.abortHandler(reason);\n    }\n\n}\n\nexport class AbortedPromiseError extends Error {\n\n    constructor(msg) {\n        super(msg);\n    }\n\n}\n","import { AbortablePromise, AbortedPromiseError } from './AbortablePromise.js';\n\nexport const floatToHalf = function() {\n\n    const floatView = new Float32Array(1);\n    const int32View = new Int32Array(floatView.buffer);\n\n    return function(val) {\n        floatView[0] = val;\n        const x = int32View[0];\n\n        let bits = (x >> 16) & 0x8000;\n        let m = (x >> 12) & 0x07ff;\n        const e = (x >> 23) & 0xff;\n\n        if (e < 103) return bits;\n\n        if (e > 142) {\n            bits |= 0x7c00;\n            bits |= ((e == 255) ? 0 : 1) && (x & 0x007fffff);\n            return bits;\n        }\n\n        if (e < 113) {\n            m |= 0x0800;\n            bits |= (m >> (114 - e)) + ((m >> (113 - e)) & 1);\n            return bits;\n        }\n\n        bits |= (( e - 112) << 10) | (m >> 1);\n        bits += m & 1;\n        return bits;\n    };\n\n}();\n\nexport const uintEncodedFloat = function() {\n\n    const floatView = new Float32Array(1);\n    const int32View = new Int32Array(floatView.buffer);\n\n    return function(f) {\n        floatView[0] = f;\n        return int32View[0];\n    };\n\n}();\n\nexport const rgbaToInteger = function(r, g, b, a) {\n    return r + (g << 8) + (b << 16) + (a << 24);\n};\n\nexport const rgbaArrayToInteger = function(arr, offset) {\n    return arr[offset] + (arr[offset + 1] << 8) + (arr[offset + 2] << 16) + (arr[offset + 3] << 24);\n};\n\nexport const fetchWithProgress = function(path, onProgress, saveChunks = true, headers) {\n\n    const abortController = new AbortController();\n    const signal = abortController.signal;\n    let aborted = false;\n    const abortHandler = (reason) => {\n        abortController.abort(reason);\n        aborted = true;\n    };\n\n    let onProgressCalledAtComplete = false;\n    const localOnProgress = (percent, percentLabel, chunk, fileSize) => {\n        if (onProgress && !onProgressCalledAtComplete) {\n            onProgress(percent, percentLabel, chunk, fileSize);\n            if (percent === 100) {\n                onProgressCalledAtComplete = true;\n            }\n        }\n    };\n\n    return new AbortablePromise((resolve, reject) => {\n        const fetchOptions = { signal };\n        if (headers) fetchOptions.headers = headers;\n         fetch(path, fetchOptions)\n        .then(async (data) => {\n            // Handle error conditions where data is still returned\n            if (!data.ok) {\n                const errorText = await data.text();\n                reject(new Error(`Fetch failed: ${data.status} ${data.statusText} ${errorText}`));\n                return;\n            }\n\n            const reader = data.body.getReader();\n            let bytesDownloaded = 0;\n            let _fileSize = data.headers.get('Content-Length');\n            let fileSize = _fileSize ? parseInt(_fileSize) : undefined;\n\n            const chunks = [];\n\n            while (!aborted) {\n                try {\n                    const { value: chunk, done } = await reader.read();\n                    if (done) {\n                        localOnProgress(100, '100%', chunk, fileSize);\n                        if (saveChunks) {\n                            const buffer = new Blob(chunks).arrayBuffer();\n                            resolve(buffer);\n                        } else {\n                            resolve();\n                        }\n                        break;\n                    }\n                    bytesDownloaded += chunk.length;\n                    let percent;\n                    let percentLabel;\n                    if (fileSize !== undefined) {\n                        percent = bytesDownloaded / fileSize * 100;\n                        percentLabel = `${percent.toFixed(2)}%`;\n                    }\n                    if (saveChunks) {\n                        chunks.push(chunk);\n                    }\n                    localOnProgress(percent, percentLabel, chunk, fileSize);\n                } catch (error) {\n                    reject(error);\n                    return;\n                }\n            }\n        })\n        .catch((error) => {\n            reject(new AbortedPromiseError(error));\n        });\n    }, abortHandler);\n\n};\n\nexport const clamp = function(val, min, max) {\n    return Math.max(Math.min(val, max), min);\n};\n\nexport const getCurrentTime = function() {\n    return performance.now() / 1000;\n};\n\nexport const disposeAllMeshes = (object3D) => {\n    if (object3D.geometry) {\n        object3D.geometry.dispose();\n        object3D.geometry = null;\n    }\n    if (object3D.material) {\n        object3D.material.dispose();\n        object3D.material = null;\n    }\n    if (object3D.children) {\n        for (let child of object3D.children) {\n            disposeAllMeshes(child);\n        }\n    }\n};\n\nexport const delayedExecute = (func, fast) => {\n    return new Promise((resolve) => {\n        window.setTimeout(() => {\n            resolve(func ? func() : undefined);\n        }, fast ? 1 : 50);\n    });\n};\n\n\nexport const getSphericalHarmonicsComponentCountForDegree = (sphericalHarmonicsDegree = 0) => {\n    let shCoeffPerSplat = 0;\n    if (sphericalHarmonicsDegree === 1) {\n        shCoeffPerSplat = 9;\n    } else if (sphericalHarmonicsDegree === 2) {\n        shCoeffPerSplat = 24;\n    } else if (sphericalHarmonicsDegree === 3) {\n        shCoeffPerSplat = 45;\n    } else if (sphericalHarmonicsDegree > 3) {\n        throw new Error('getSphericalHarmonicsComponentCountForDegree() -> Invalid spherical harmonics degree');\n    }\n    return shCoeffPerSplat;\n};\n\nexport const nativePromiseWithExtractedComponents = () => {\n    let resolver;\n    let rejecter;\n    const promise = new Promise((resolve, reject) => {\n        resolver = resolve;\n        rejecter = reject;\n    });\n    return {\n        'promise': promise,\n        'resolve': resolver,\n        'reject': rejecter\n    };\n};\n\nexport const abortablePromiseWithExtractedComponents = (abortHandler) => {\n    let resolver;\n    let rejecter;\n    if (!abortHandler) {\n        abortHandler = () => {};\n    }\n    const promise = new AbortablePromise((resolve, reject) => {\n        resolver = resolve;\n        rejecter = reject;\n    }, abortHandler);\n    return {\n        'promise': promise,\n        'resolve': resolver,\n        'reject': rejecter\n    };\n};\n\nclass Semver {\n    constructor(major, minor, patch) {\n        this.major = major;\n        this.minor = minor;\n        this.patch = patch;\n    }\n\n    toString() {\n        return `${this.major}_${this.minor}_${this.patch}`;\n    }\n}\n\nexport function isIOS() {\n    const ua = navigator.userAgent;\n    return ua.indexOf('iPhone') > 0 || ua.indexOf('iPad') > 0;\n}\n\nexport function getIOSSemever() {\n    if (isIOS()) {\n        const extract = navigator.userAgent.match(/OS (\\d+)_(\\d+)_?(\\d+)?/);\n        return new Semver(\n            parseInt(extract[1] || 0, 10),\n            parseInt(extract[2] || 0, 10),\n            parseInt(extract[3] || 0, 10)\n        );\n    } else {\n        return null; // or [0,0,0]\n    }\n}\n","import { getSphericalHarmonicsComponentCountForDegree } from '../Util.js';\n\nconst BASE_COMPONENT_COUNT = 14;\n\nexport class UncompressedSplatArray {\n\n    static OFFSET = {\n        X: 0,\n        Y: 1,\n        Z: 2,\n        SCALE0: 3,\n        SCALE1: 4,\n        SCALE2: 5,\n        ROTATION0: 6,\n        ROTATION1: 7,\n        ROTATION2: 8,\n        ROTATION3: 9,\n        FDC0: 10,\n        FDC1: 11,\n        FDC2: 12,\n        OPACITY: 13,\n        FRC0: 14,\n        FRC1: 15,\n        FRC2: 16,\n        FRC3: 17,\n        FRC4: 18,\n        FRC5: 19,\n        FRC6: 20,\n        FRC7: 21,\n        FRC8: 22,\n        FRC9: 23,\n        FRC10: 24,\n        FRC11: 25,\n        FRC12: 26,\n        FRC13: 27,\n        FRC14: 28,\n        FRC15: 29,\n        FRC16: 30,\n        FRC17: 31,\n        FRC18: 32,\n        FRC19: 33,\n        FRC20: 34,\n        FRC21: 35,\n        FRC22: 36,\n        FRC23: 37\n    };\n\n    constructor(sphericalHarmonicsDegree = 0) {\n        this.sphericalHarmonicsDegree = sphericalHarmonicsDegree;\n        this.sphericalHarmonicsCount = getSphericalHarmonicsComponentCountForDegree(this.sphericalHarmonicsDegree);\n        this.componentCount = this.sphericalHarmonicsCount + BASE_COMPONENT_COUNT;\n        this.defaultSphericalHarmonics = new Array(this.sphericalHarmonicsCount).fill(0);\n        this.splats = [];\n        this.splatCount = 0;\n    }\n\n    static createSplat(sphericalHarmonicsDegree = 0) {\n        const baseSplat = [0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0];\n        let shEntries = getSphericalHarmonicsComponentCountForDegree(sphericalHarmonicsDegree);\n        for (let i = 0; i < shEntries; i++) baseSplat.push(0);\n        return baseSplat;\n    }\n\n    addSplat(splat) {\n        this.splats.push(splat);\n        this.splatCount++;\n    }\n\n    getSplat(index) {\n        return this.splats[index];\n    }\n\n    addDefaultSplat() {\n        const newSplat = UncompressedSplatArray.createSplat(this.sphericalHarmonicsDegree);\n        this.addSplat(newSplat);\n        return newSplat;\n    }\n\n    addSplatFromComonents(x, y, z, scale0, scale1, scale2, rot0, rot1, rot2, rot3, r, g, b, opacity, ...rest) {\n        const newSplat = [x, y, z, scale0, scale1, scale2, rot0, rot1, rot2, rot3, r, g, b, opacity, ...this.defaultSphericalHarmonics];\n        for (let i = 0; i < rest.length && i < this.sphericalHarmonicsCount; i++) {\n            newSplat[i] = rest[i];\n        }\n        this.addSplat(newSplat);\n        return newSplat;\n    }\n\n    addSplatFromArray(src, srcIndex) {\n        const srcSplat = src.splats[srcIndex];\n        const newSplat = UncompressedSplatArray.createSplat(this.sphericalHarmonicsDegree);\n        for (let i = 0; i < this.componentCount && i < srcSplat.length; i++) {\n            newSplat[i] = srcSplat[i];\n        }\n        this.addSplat(newSplat);\n    }\n}\n","export class Constants {\n\n    static DefaultSplatSortDistanceMapPrecision = 16;\n    static MemoryPageSize = 65536;\n    static BytesPerFloat = 4;\n    static BytesPerInt = 4;\n    static MaxScenes = 32;\n    static ProgressiveLoadSectionSize = 262144;\n    static ProgressiveLoadSectionDelayDuration = 15;\n    static SphericalHarmonics8BitCompressionRange = 3;\n}\n","import * as THREE from 'three';\nimport { UncompressedSplatArray } from './UncompressedSplatArray.js';\nimport { clamp, getSphericalHarmonicsComponentCountForDegree } from '../Util.js';\nimport { Constants } from '../Constants.js';\n\nconst DefaultSphericalHarmonics8BitCompressionRange = Constants.SphericalHarmonics8BitCompressionRange;\nconst DefaultSphericalHarmonics8BitCompressionHalfRange = DefaultSphericalHarmonics8BitCompressionRange / 2.0;\n\nconst toHalfFloat = THREE.DataUtils.toHalfFloat.bind(THREE.DataUtils);\nconst fromHalfFloat = THREE.DataUtils.fromHalfFloat.bind(THREE.DataUtils);\n\nconst toUncompressedFloat = (f, compressionLevel, isSH = false, range8BitMin, range8BitMax) => {\n    if (compressionLevel === 0) {\n        return f;\n    } else if (compressionLevel === 1 || compressionLevel === 2 && !isSH) {\n        return THREE.DataUtils.fromHalfFloat(f);\n    } else if (compressionLevel === 2) {\n        return fromUint8(f, range8BitMin, range8BitMax);\n    }\n};\n\nconst toUint8 = (v, rangeMin, rangeMax) => {\n    v = clamp(v, rangeMin, rangeMax);\n    const range = (rangeMax - rangeMin);\n    return clamp(Math.floor((v - rangeMin) / range * 255), 0, 255);\n};\n\nconst fromUint8 = (v, rangeMin, rangeMax) => {\n    const range = (rangeMax - rangeMin);\n    return (v / 255 * range + rangeMin);\n};\n\nconst fromHalfFloatToUint8 = (v, rangeMin, rangeMax) => {\n    return toUint8(fromHalfFloat(v, rangeMin, rangeMax));\n};\n\nconst fromUint8ToHalfFloat = (v, rangeMin, rangeMax) => {\n    return toHalfFloat(fromUint8(v, rangeMin, rangeMax));\n};\n\nconst dataViewFloatForCompressionLevel = (dataView, floatIndex, compressionLevel, isSH = false) => {\n    if (compressionLevel === 0) {\n        return dataView.getFloat32(floatIndex * 4, true);\n    } else if (compressionLevel === 1 || compressionLevel === 2 && !isSH) {\n        return dataView.getUint16(floatIndex * 2, true);\n    } else {\n        return dataView.getUint8(floatIndex, true);\n    }\n};\n\nconst convertBetweenCompressionLevels = function() {\n\n    const noop = (v) => v;\n\n    return function(val, fromLevel, toLevel, isSH = false) {\n        if (fromLevel === toLevel) return val;\n        let outputConversionFunc = noop;\n\n        if (fromLevel === 2 && isSH) {\n            if (toLevel === 1) outputConversionFunc = fromUint8ToHalfFloat;\n            else if (toLevel == 0) {\n                outputConversionFunc = fromUint8;\n            }\n        } else if (fromLevel === 2 || fromLevel === 1) {\n            if (toLevel === 0) outputConversionFunc = fromHalfFloat;\n            else if (toLevel == 2) {\n                if (!isSH) outputConversionFunc = noop;\n                else outputConversionFunc = fromHalfFloatToUint8;\n            }\n        } else if (fromLevel === 0) {\n            if (toLevel === 1) outputConversionFunc = toHalfFloat;\n            else if (toLevel == 2) {\n                if (!isSH) outputConversionFunc = toHalfFloat;\n                else outputConversionFunc = toUint8;\n            }\n        }\n\n        return outputConversionFunc(val);\n    };\n\n}();\n\nconst copyBetweenBuffers = (srcBuffer, srcOffset, destBuffer, destOffset, byteCount = 0) => {\n    const src = new Uint8Array(srcBuffer, srcOffset);\n    const dest = new Uint8Array(destBuffer, destOffset);\n    for (let i = 0; i < byteCount; i++) {\n        dest[i] = src[i];\n    }\n};\n\n/**\n * SplatBuffer: Container for splat data from a single scene/file and capable of (mediocre) compression.\n */\nexport class SplatBuffer {\n\n    static CurrentMajorVersion = 0;\n    static CurrentMinorVersion = 1;\n\n    static CenterComponentCount = 3;\n    static ScaleComponentCount = 3;\n    static RotationComponentCount = 4;\n    static ColorComponentCount = 4;\n    static CovarianceComponentCount = 6;\n\n    static SplatScaleOffsetFloat = 3;\n    static SplatRotationOffsetFloat = 6;\n\n    static CompressionLevels = {\n        0: {\n            BytesPerCenter: 12,\n            BytesPerScale: 12,\n            BytesPerRotation: 16,\n            BytesPerColor: 4,\n            ScaleOffsetBytes: 12,\n            RotationffsetBytes: 24,\n            ColorOffsetBytes: 40,\n            SphericalHarmonicsOffsetBytes: 44,\n            ScaleRange: 1,\n            BytesPerSphericalHarmonicsComponent: 4,\n            SphericalHarmonicsOffsetFloat: 11,\n            SphericalHarmonicsDegrees: {\n                0: { BytesPerSplat: 44 },\n                1: { BytesPerSplat: 80 },\n                2: { BytesPerSplat: 140 }\n            },\n        },\n        1: {\n            BytesPerCenter: 6,\n            BytesPerScale: 6,\n            BytesPerRotation: 8,\n            BytesPerColor: 4,\n            ScaleOffsetBytes: 6,\n            RotationffsetBytes: 12,\n            ColorOffsetBytes: 20,\n            SphericalHarmonicsOffsetBytes: 24,\n            ScaleRange: 32767,\n            BytesPerSphericalHarmonicsComponent: 2,\n            SphericalHarmonicsOffsetFloat: 12,\n            SphericalHarmonicsDegrees: {\n                0: { BytesPerSplat: 24 },\n                1: { BytesPerSplat: 42 },\n                2: { BytesPerSplat: 72 }\n            },\n        },\n        2: {\n            BytesPerCenter: 6,\n            BytesPerScale: 6,\n            BytesPerRotation: 8,\n            BytesPerColor: 4,\n            ScaleOffsetBytes: 6,\n            RotationffsetBytes: 12,\n            ColorOffsetBytes: 20,\n            SphericalHarmonicsOffsetBytes: 24,\n            ScaleRange: 32767,\n            BytesPerSphericalHarmonicsComponent: 1,\n            SphericalHarmonicsOffsetFloat: 12,\n            SphericalHarmonicsDegrees: {\n                0: { BytesPerSplat: 24 },\n                1: { BytesPerSplat: 33 },\n                2: { BytesPerSplat: 48 }\n            },\n        }\n    };\n\n    static CovarianceSizeFloats = 6;\n\n    static HeaderSizeBytes = 4096;\n    static SectionHeaderSizeBytes = 1024;\n\n    static BucketStorageSizeBytes = 12;\n    static BucketStorageSizeFloats = 3;\n\n    static BucketBlockSize = 5.0;\n    static BucketSize = 256;\n\n    constructor(bufferData, secLoadedCountsToMax = true) {\n        this.constructFromBuffer(bufferData, secLoadedCountsToMax);\n    }\n\n    getSplatCount() {\n        return this.splatCount;\n    }\n\n    getMaxSplatCount() {\n        return this.maxSplatCount;\n    }\n\n    getMinSphericalHarmonicsDegree() {\n        let minSphericalHarmonicsDegree = 0;\n        for (let i = 0; i < this.sections.length; i++) {\n            const section = this.sections[i];\n            if (i === 0 || section.sphericalHarmonicsDegree < minSphericalHarmonicsDegree) {\n                minSphericalHarmonicsDegree = section.sphericalHarmonicsDegree;\n            }\n        }\n        return minSphericalHarmonicsDegree;\n    }\n\n    getBucketIndex(section, localSplatIndex) {\n        let bucketIndex;\n        const maxSplatIndexInFullBuckets = section.fullBucketCount * section.bucketSize;\n        if (localSplatIndex < maxSplatIndexInFullBuckets) {\n            bucketIndex = Math.floor(localSplatIndex / section.bucketSize);\n        } else {\n            let bucketSplatIndex = maxSplatIndexInFullBuckets;\n            bucketIndex = section.fullBucketCount;\n            let partiallyFullBucketIndex = 0;\n            while (bucketSplatIndex < section.splatCount) {\n                let currentPartiallyFilledBucketSize = section.partiallyFilledBucketLengths[partiallyFullBucketIndex];\n                if (localSplatIndex >= bucketSplatIndex && localSplatIndex < bucketSplatIndex + currentPartiallyFilledBucketSize) {\n                    break;\n                }\n                bucketSplatIndex += currentPartiallyFilledBucketSize;\n                bucketIndex++;\n                partiallyFullBucketIndex++;\n            }\n        }\n        return bucketIndex;\n    }\n\n    getSplatCenter(globalSplatIndex, outCenter, transform) {\n        const sectionIndex = this.globalSplatIndexToSectionMap[globalSplatIndex];\n        const section = this.sections[sectionIndex];\n        const localSplatIndex = globalSplatIndex - section.splatCountOffset;\n\n        const srcSplatCentersBase = section.bytesPerSplat * localSplatIndex;\n        const dataView = new DataView(this.bufferData, section.dataBase + srcSplatCentersBase);\n\n        const x = dataViewFloatForCompressionLevel(dataView, 0, this.compressionLevel);\n        const y = dataViewFloatForCompressionLevel(dataView, 1, this.compressionLevel);\n        const z = dataViewFloatForCompressionLevel(dataView, 2, this.compressionLevel);\n        if (this.compressionLevel >= 1) {\n            const bucketIndex = this.getBucketIndex(section, localSplatIndex);\n            const bucketBase = bucketIndex * SplatBuffer.BucketStorageSizeFloats;\n            const sf = section.compressionScaleFactor;\n            const sr = section.compressionScaleRange;\n            outCenter.x = (x - sr) * sf + section.bucketArray[bucketBase];\n            outCenter.y = (y - sr) * sf + section.bucketArray[bucketBase + 1];\n            outCenter.z = (z - sr) * sf + section.bucketArray[bucketBase + 2];\n        } else {\n            outCenter.x = x;\n            outCenter.y = y;\n            outCenter.z = z;\n        }\n        if (transform) outCenter.applyMatrix4(transform);\n    }\n\n    getSplatScaleAndRotation = function() {\n\n        const scaleMatrix = new THREE.Matrix4();\n        const rotationMatrix = new THREE.Matrix4();\n        const tempMatrix = new THREE.Matrix4();\n        const tempPosition = new THREE.Vector3();\n        const scale = new THREE.Vector3();\n        const rotation = new THREE.Quaternion();\n\n        return function(index, outScale, outRotation, transform, scaleOverride) {\n            const sectionIndex = this.globalSplatIndexToSectionMap[index];\n            const section = this.sections[sectionIndex];\n            const localSplatIndex = index - section.splatCountOffset;\n\n            const srcSplatScalesBase = section.bytesPerSplat * localSplatIndex +\n                                       SplatBuffer.CompressionLevels[this.compressionLevel].ScaleOffsetBytes;\n\n            const dataView = new DataView(this.bufferData, section.dataBase + srcSplatScalesBase);\n\n            scale.set(toUncompressedFloat(dataViewFloatForCompressionLevel(dataView, 0, this.compressionLevel), this.compressionLevel),\n                      toUncompressedFloat(dataViewFloatForCompressionLevel(dataView, 1, this.compressionLevel), this.compressionLevel),\n                      toUncompressedFloat(dataViewFloatForCompressionLevel(dataView, 2, this.compressionLevel), this.compressionLevel));\n            if (scaleOverride) {\n                if (scaleOverride.x !== undefined) scale.x = scaleOverride.x;\n                if (scaleOverride.y !== undefined) scale.y = scaleOverride.y;\n                if (scaleOverride.z !== undefined) scale.z = scaleOverride.z;\n            }\n\n            rotation.set(toUncompressedFloat(dataViewFloatForCompressionLevel(dataView, 4, this.compressionLevel), this.compressionLevel),\n                         toUncompressedFloat(dataViewFloatForCompressionLevel(dataView, 5, this.compressionLevel), this.compressionLevel),\n                         toUncompressedFloat(dataViewFloatForCompressionLevel(dataView, 6, this.compressionLevel), this.compressionLevel),\n                         toUncompressedFloat(dataViewFloatForCompressionLevel(dataView, 3, this.compressionLevel), this.compressionLevel));\n\n            if (transform) {\n                scaleMatrix.makeScale(scale.x, scale.y, scale.z);\n                rotationMatrix.makeRotationFromQuaternion(rotation);\n                tempMatrix.copy(scaleMatrix).multiply(rotationMatrix).multiply(transform);\n                tempMatrix.decompose(tempPosition, outRotation, outScale);\n            } else {\n                outScale.copy(scale);\n                outRotation.copy(rotation);\n            }\n        };\n\n    }();\n\n    getSplatColor(globalSplatIndex, outColor) {\n        const sectionIndex = this.globalSplatIndexToSectionMap[globalSplatIndex];\n        const section = this.sections[sectionIndex];\n        const localSplatIndex = globalSplatIndex - section.splatCountOffset;\n\n        const srcSplatColorsBase = section.bytesPerSplat * localSplatIndex +\n                                   SplatBuffer.CompressionLevels[this.compressionLevel].ColorOffsetBytes;\n        const splatColorsArray = new Uint8Array(this.bufferData, section.dataBase + srcSplatColorsBase, 4);\n\n        outColor.set(splatColorsArray[0], splatColorsArray[1],\n                     splatColorsArray[2], splatColorsArray[3]);\n    }\n\n    fillSplatCenterArray(outCenterArray, transform, srcFrom, srcTo, destFrom) {\n        const splatCount = this.splatCount;\n\n        srcFrom = srcFrom || 0;\n        srcTo = srcTo || splatCount - 1;\n        if (destFrom === undefined) destFrom = srcFrom;\n\n        const center = new THREE.Vector3();\n        for (let i = srcFrom; i <= srcTo; i++) {\n            const sectionIndex = this.globalSplatIndexToSectionMap[i];\n            const section = this.sections[sectionIndex];\n            const localSplatIndex = i - section.splatCountOffset;\n            const centerDestBase = (i - srcFrom + destFrom) * SplatBuffer.CenterComponentCount;\n\n            const srcSplatCentersBase = section.bytesPerSplat * localSplatIndex;\n            const dataView = new DataView(this.bufferData, section.dataBase + srcSplatCentersBase);\n\n            const x = dataViewFloatForCompressionLevel(dataView, 0, this.compressionLevel);\n            const y = dataViewFloatForCompressionLevel(dataView, 1, this.compressionLevel);\n            const z = dataViewFloatForCompressionLevel(dataView, 2, this.compressionLevel);\n            if (this.compressionLevel >= 1) {\n                const bucketIndex = this.getBucketIndex(section, localSplatIndex);\n                const bucketBase = bucketIndex * SplatBuffer.BucketStorageSizeFloats;\n                const sf = section.compressionScaleFactor;\n                const sr = section.compressionScaleRange;\n                center.x = (x - sr) * sf + section.bucketArray[bucketBase];\n                center.y = (y - sr) * sf + section.bucketArray[bucketBase + 1];\n                center.z = (z - sr) * sf + section.bucketArray[bucketBase + 2];\n            } else {\n                center.x = x;\n                center.y = y;\n                center.z = z;\n            }\n            if (transform) {\n                center.applyMatrix4(transform);\n            }\n            outCenterArray[centerDestBase] = center.x;\n            outCenterArray[centerDestBase + 1] = center.y;\n            outCenterArray[centerDestBase + 2] = center.z;\n        }\n    }\n\n    fillSplatScaleRotationArray = function() {\n\n        const scaleMatrix = new THREE.Matrix4();\n        const rotationMatrix = new THREE.Matrix4();\n        const tempMatrix = new THREE.Matrix4();\n        const scale = new THREE.Vector3();\n        const rotation = new THREE.Quaternion();\n        const tempPosition = new THREE.Vector3();\n\n        const ensurePositiveW = (quaternion) => {\n            const flip = quaternion.w < 0 ? -1 : 1;\n            quaternion.x *= flip;\n            quaternion.y *= flip;\n            quaternion.z *= flip;\n            quaternion.w *= flip;\n        };\n\n        return function(outScaleArray, outRotationArray, transform, srcFrom, srcTo, destFrom,\n                        desiredOutputCompressionLevel, scaleOverride) {\n            const splatCount = this.splatCount;\n\n            srcFrom = srcFrom || 0;\n            srcTo = srcTo || splatCount - 1;\n            if (destFrom === undefined) destFrom = srcFrom;\n\n            const outputConversion = (value, srcCompressionLevel) => {\n                if (srcCompressionLevel === undefined) srcCompressionLevel = this.compressionLevel;\n                return convertBetweenCompressionLevels(value, srcCompressionLevel, desiredOutputCompressionLevel);\n            };\n\n            for (let i = srcFrom; i <= srcTo; i++) {\n                const sectionIndex = this.globalSplatIndexToSectionMap[i];\n                const section = this.sections[sectionIndex];\n                const localSplatIndex = i - section.splatCountOffset;\n\n                const srcSplatScalesBase = section.bytesPerSplat * localSplatIndex +\n                                        SplatBuffer.CompressionLevels[this.compressionLevel].ScaleOffsetBytes;\n\n                const scaleDestBase = (i - srcFrom + destFrom) * SplatBuffer.ScaleComponentCount;\n                const rotationDestBase = (i - srcFrom + destFrom) * SplatBuffer.RotationComponentCount;\n                const dataView = new DataView(this.bufferData, section.dataBase + srcSplatScalesBase);\n\n                const srcScaleX = (scaleOverride && scaleOverride.x !== undefined) ? scaleOverride.x :\n                                   dataViewFloatForCompressionLevel(dataView, 0, this.compressionLevel);\n                const srcScaleY = (scaleOverride && scaleOverride.y !== undefined) ? scaleOverride.y :\n                                   dataViewFloatForCompressionLevel(dataView, 1, this.compressionLevel);\n                const srcScaleZ = (scaleOverride && scaleOverride.z !== undefined) ? scaleOverride.z :\n                                   dataViewFloatForCompressionLevel(dataView, 2, this.compressionLevel);\n\n                const srcRotationW = dataViewFloatForCompressionLevel(dataView, 3, this.compressionLevel);\n                const srcRotationX = dataViewFloatForCompressionLevel(dataView, 4, this.compressionLevel);\n                const srcRotationY = dataViewFloatForCompressionLevel(dataView, 5, this.compressionLevel);\n                const srcRotationZ = dataViewFloatForCompressionLevel(dataView, 6, this.compressionLevel);\n\n                scale.set(toUncompressedFloat(srcScaleX, this.compressionLevel),\n                          toUncompressedFloat(srcScaleY, this.compressionLevel),\n                          toUncompressedFloat(srcScaleZ, this.compressionLevel));\n\n                rotation.set(toUncompressedFloat(srcRotationX, this.compressionLevel),\n                             toUncompressedFloat(srcRotationY, this.compressionLevel),\n                             toUncompressedFloat(srcRotationZ, this.compressionLevel),\n                             toUncompressedFloat(srcRotationW, this.compressionLevel)).normalize();\n\n                if (transform) {\n                    tempPosition.set(0, 0, 0);\n                    scaleMatrix.makeScale(scale.x, scale.y, scale.z);\n                    rotationMatrix.makeRotationFromQuaternion(rotation);\n                    tempMatrix.identity().premultiply(scaleMatrix).premultiply(rotationMatrix);\n                    tempMatrix.premultiply(transform);\n                    tempMatrix.decompose(tempPosition, rotation, scale);\n                    rotation.normalize();\n                }\n\n                ensurePositiveW(rotation);\n\n                if (outScaleArray) {\n                    outScaleArray[scaleDestBase] = outputConversion(scale.x, 0);\n                    outScaleArray[scaleDestBase + 1] = outputConversion(scale.y, 0);\n                    outScaleArray[scaleDestBase + 2] = outputConversion(scale.z, 0);\n                }\n\n                if (outRotationArray) {\n                    outRotationArray[rotationDestBase] = outputConversion(rotation.x, 0);\n                    outRotationArray[rotationDestBase + 1] = outputConversion(rotation.y, 0);\n                    outRotationArray[rotationDestBase + 2] = outputConversion(rotation.z, 0);\n                    outRotationArray[rotationDestBase + 3] = outputConversion(rotation.w, 0);\n                }\n            }\n        };\n    }();\n\n    static computeCovariance = function() {\n\n        const tempMatrix4 = new THREE.Matrix4();\n        const scaleMatrix = new THREE.Matrix3();\n        const rotationMatrix = new THREE.Matrix3();\n        const covarianceMatrix = new THREE.Matrix3();\n        const transformedCovariance = new THREE.Matrix3();\n        const transform3x3 = new THREE.Matrix3();\n        const transform3x3Transpose = new THREE.Matrix3();\n\n        return function(scale, rotation, transform, outCovariance, outOffset = 0, desiredOutputCompressionLevel) {\n\n            tempMatrix4.makeScale(scale.x, scale.y, scale.z);\n            scaleMatrix.setFromMatrix4(tempMatrix4);\n\n            tempMatrix4.makeRotationFromQuaternion(rotation);\n            rotationMatrix.setFromMatrix4(tempMatrix4);\n\n            covarianceMatrix.copy(rotationMatrix).multiply(scaleMatrix);\n            transformedCovariance.copy(covarianceMatrix).transpose().premultiply(covarianceMatrix);\n\n            if (transform) {\n                transform3x3.setFromMatrix4(transform);\n                transform3x3Transpose.copy(transform3x3).transpose();\n                transformedCovariance.multiply(transform3x3Transpose);\n                transformedCovariance.premultiply(transform3x3);\n            }\n\n            if (desiredOutputCompressionLevel >= 1) {\n                outCovariance[outOffset] = toHalfFloat(transformedCovariance.elements[0]);\n                outCovariance[outOffset + 1] = toHalfFloat(transformedCovariance.elements[3]);\n                outCovariance[outOffset + 2] = toHalfFloat(transformedCovariance.elements[6]);\n                outCovariance[outOffset + 3] = toHalfFloat(transformedCovariance.elements[4]);\n                outCovariance[outOffset + 4] = toHalfFloat(transformedCovariance.elements[7]);\n                outCovariance[outOffset + 5] = toHalfFloat(transformedCovariance.elements[8]);\n            } else {\n                outCovariance[outOffset] = transformedCovariance.elements[0];\n                outCovariance[outOffset + 1] = transformedCovariance.elements[3];\n                outCovariance[outOffset + 2] = transformedCovariance.elements[6];\n                outCovariance[outOffset + 3] = transformedCovariance.elements[4];\n                outCovariance[outOffset + 4] = transformedCovariance.elements[7];\n                outCovariance[outOffset + 5] = transformedCovariance.elements[8];\n            }\n\n        };\n\n    }();\n\n    fillSplatCovarianceArray(covarianceArray, transform, srcFrom, srcTo, destFrom, desiredOutputCompressionLevel) {\n        const splatCount = this.splatCount;\n\n        const scale = new THREE.Vector3();\n        const rotation = new THREE.Quaternion();\n\n        srcFrom = srcFrom || 0;\n        srcTo = srcTo || splatCount - 1;\n        if (destFrom === undefined) destFrom = srcFrom;\n\n        for (let i = srcFrom; i <= srcTo; i++) {\n            const sectionIndex = this.globalSplatIndexToSectionMap[i];\n            const section = this.sections[sectionIndex];\n            const localSplatIndex = i - section.splatCountOffset;\n\n            const covarianceDestBase = (i - srcFrom + destFrom) * SplatBuffer.CovarianceComponentCount;\n            const srcSplatScalesBase = section.bytesPerSplat * localSplatIndex +\n                                       SplatBuffer.CompressionLevels[this.compressionLevel].ScaleOffsetBytes;\n\n            const dataView = new DataView(this.bufferData, section.dataBase + srcSplatScalesBase);\n\n            scale.set(toUncompressedFloat(dataViewFloatForCompressionLevel(dataView, 0, this.compressionLevel), this.compressionLevel),\n                      toUncompressedFloat(dataViewFloatForCompressionLevel(dataView, 1, this.compressionLevel), this.compressionLevel),\n                      toUncompressedFloat(dataViewFloatForCompressionLevel(dataView, 2, this.compressionLevel), this.compressionLevel));\n\n            rotation.set(toUncompressedFloat(dataViewFloatForCompressionLevel(dataView, 4, this.compressionLevel), this.compressionLevel),\n                         toUncompressedFloat(dataViewFloatForCompressionLevel(dataView, 5, this.compressionLevel), this.compressionLevel),\n                         toUncompressedFloat(dataViewFloatForCompressionLevel(dataView, 6, this.compressionLevel), this.compressionLevel),\n                         toUncompressedFloat(dataViewFloatForCompressionLevel(dataView, 3, this.compressionLevel), this.compressionLevel));\n\n            SplatBuffer.computeCovariance(scale, rotation, transform, covarianceArray, covarianceDestBase, desiredOutputCompressionLevel);\n        }\n    }\n\n    fillSplatColorArray(outColorArray, minimumAlpha, srcFrom, srcTo, destFrom) {\n        const splatCount = this.splatCount;\n\n        srcFrom = srcFrom || 0;\n        srcTo = srcTo || splatCount - 1;\n        if (destFrom === undefined) destFrom = srcFrom;\n\n        for (let i = srcFrom; i <= srcTo; i++) {\n\n            const sectionIndex = this.globalSplatIndexToSectionMap[i];\n            const section = this.sections[sectionIndex];\n            const localSplatIndex = i - section.splatCountOffset;\n\n            const colorDestBase = (i - srcFrom + destFrom) * SplatBuffer.ColorComponentCount;\n            const srcSplatColorsBase = section.bytesPerSplat * localSplatIndex +\n                                       SplatBuffer.CompressionLevels[this.compressionLevel].ColorOffsetBytes;\n\n            const dataView = new Uint8Array(this.bufferData, section.dataBase + srcSplatColorsBase);\n\n            let alpha = dataView[3];\n            alpha = (alpha >= minimumAlpha) ? alpha : 0;\n\n            outColorArray[colorDestBase] = dataView[0];\n            outColorArray[colorDestBase + 1] = dataView[1];\n            outColorArray[colorDestBase + 2] = dataView[2];\n            outColorArray[colorDestBase + 3] = alpha;\n        }\n    }\n\n    fillSphericalHarmonicsArray = function() {\n\n        const sphericalHarmonicVectors = [];\n        for (let i = 0; i < 15; i++) {\n            sphericalHarmonicVectors[i] = new THREE.Vector3();\n        }\n\n        const tempMatrix3 = new THREE.Matrix3();\n        const tempMatrix4 = new THREE.Matrix4();\n\n        const tempTranslation = new THREE.Vector3();\n        const tempScale = new THREE.Vector3();\n        const tempRotation = new THREE.Quaternion();\n\n        const sh11 = [];\n        const sh12 = [];\n        const sh13 = [];\n\n        const sh21 = [];\n        const sh22 = [];\n        const sh23 = [];\n        const sh24 = [];\n        const sh25 = [];\n\n        const shIn1 = [];\n        const shIn2 = [];\n        const shIn3 = [];\n        const shIn4 = [];\n        const shIn5 = [];\n\n        const shOut1 = [];\n        const shOut2 = [];\n        const shOut3 = [];\n        const shOut4 = [];\n        const shOut5 = [];\n\n        const noop = (v) => v;\n\n        const set3 = (array, val1, val2, val3) => {\n            array[0] = val1;\n            array[1] = val2;\n            array[2] = val3;\n        };\n\n        const set3FromArray = (array, srcDestView, stride, srcBase, compressionLevel) => {\n            array[0] = dataViewFloatForCompressionLevel(srcDestView, srcBase, compressionLevel, true);\n            array[1] = dataViewFloatForCompressionLevel(srcDestView, srcBase + stride, compressionLevel, true);\n            array[2] = dataViewFloatForCompressionLevel(srcDestView, srcBase + stride + stride, compressionLevel, true);\n        };\n\n        const copy3 = (srcArray, destArray) => {\n            destArray[0] = srcArray[0];\n            destArray[1] = srcArray[1];\n            destArray[2] = srcArray[2];\n        };\n\n        const setOutput3 = (srcArray, destArray, destBase, conversionFunc) => {\n            destArray[destBase] = conversionFunc(srcArray[0]);\n            destArray[destBase + 1] = conversionFunc(srcArray[1]);\n            destArray[destBase + 2] = conversionFunc(srcArray[2]);\n        };\n\n        const toUncompressedFloatArray3 = (src, dest, compressionLevel, range8BitMin, range8BitMax) => {\n            dest[0] = toUncompressedFloat(src[0], compressionLevel, true, range8BitMin, range8BitMax);\n            dest[1] = toUncompressedFloat(src[1], compressionLevel, true, range8BitMin, range8BitMax);\n            dest[2] = toUncompressedFloat(src[2], compressionLevel, true, range8BitMin, range8BitMax);\n            return dest;\n        };\n\n        return function(outSphericalHarmonicsArray, outSphericalHarmonicsDegree, transform,\n                        srcFrom, srcTo, destFrom, desiredOutputCompressionLevel) {\n            const splatCount = this.splatCount;\n\n            srcFrom = srcFrom || 0;\n            srcTo = srcTo || splatCount - 1;\n            if (destFrom === undefined) destFrom = srcFrom;\n\n            if (transform && outSphericalHarmonicsDegree >= 1) {\n                tempMatrix4.copy(transform);\n                tempMatrix4.decompose(tempTranslation, tempRotation, tempScale);\n                tempRotation.normalize();\n                tempMatrix4.makeRotationFromQuaternion(tempRotation);\n                tempMatrix3.setFromMatrix4(tempMatrix4);\n                set3(sh11, tempMatrix3.elements[4], -tempMatrix3.elements[7], tempMatrix3.elements[1]);\n                set3(sh12, -tempMatrix3.elements[5], tempMatrix3.elements[8], -tempMatrix3.elements[2]);\n                set3(sh13, tempMatrix3.elements[3], -tempMatrix3.elements[6], tempMatrix3.elements[0]);\n            }\n\n            const localFromHalfFloatToUint8 = (v) => {\n                return fromHalfFloatToUint8(v, this.minSphericalHarmonicsCoeff, this.maxSphericalHarmonicsCoeff);\n            };\n\n            const localToUint8 = (v) => {\n                return toUint8(v, this.minSphericalHarmonicsCoeff, this.maxSphericalHarmonicsCoeff);\n            };\n\n            for (let i = srcFrom; i <= srcTo; i++) {\n\n                const sectionIndex = this.globalSplatIndexToSectionMap[i];\n                const section = this.sections[sectionIndex];\n                outSphericalHarmonicsDegree = Math.min(outSphericalHarmonicsDegree, section.sphericalHarmonicsDegree);\n                const outSphericalHarmonicsComponentsCount = getSphericalHarmonicsComponentCountForDegree(outSphericalHarmonicsDegree);\n\n                const localSplatIndex = i - section.splatCountOffset;\n\n                const srcSplatSHBase = section.bytesPerSplat * localSplatIndex +\n                                       SplatBuffer.CompressionLevels[this.compressionLevel].SphericalHarmonicsOffsetBytes;\n\n                const dataView = new DataView(this.bufferData, section.dataBase + srcSplatSHBase);\n\n                const shDestBase = (i - srcFrom + destFrom) * outSphericalHarmonicsComponentsCount;\n\n                let compressionLevelForOutputConversion = transform ? 0 : this.compressionLevel;\n                let outputConversionFunc = noop;\n                if (compressionLevelForOutputConversion !== desiredOutputCompressionLevel) {\n                    if (compressionLevelForOutputConversion === 1) {\n                        if (desiredOutputCompressionLevel === 0) outputConversionFunc = fromHalfFloat;\n                        else if (desiredOutputCompressionLevel == 2) outputConversionFunc = localFromHalfFloatToUint8;\n                    } else if (compressionLevelForOutputConversion === 0) {\n                        if (desiredOutputCompressionLevel === 1) outputConversionFunc = toHalfFloat;\n                        else if (desiredOutputCompressionLevel == 2) outputConversionFunc = localToUint8;\n                    }\n                }\n\n                const minShCoeff = this.minSphericalHarmonicsCoeff;\n                const maxShCoeff = this.maxSphericalHarmonicsCoeff;\n\n                if (outSphericalHarmonicsDegree >= 1) {\n\n                    set3FromArray(shIn1, dataView, 3, 0, this.compressionLevel);\n                    set3FromArray(shIn2, dataView, 3, 1, this.compressionLevel);\n                    set3FromArray(shIn3, dataView, 3, 2, this.compressionLevel);\n\n                    if (transform) {\n                        toUncompressedFloatArray3(shIn1, shIn1, this.compressionLevel, minShCoeff, maxShCoeff);\n                        toUncompressedFloatArray3(shIn2, shIn2, this.compressionLevel, minShCoeff, maxShCoeff);\n                        toUncompressedFloatArray3(shIn3, shIn3, this.compressionLevel, minShCoeff, maxShCoeff);\n                        SplatBuffer.rotateSphericalHarmonics3(shIn1, shIn2, shIn3, sh11, sh12, sh13, shOut1, shOut2, shOut3);\n                    } else {\n                        copy3(shIn1, shOut1);\n                        copy3(shIn2, shOut2);\n                        copy3(shIn3, shOut3);\n                    }\n\n                    setOutput3(shOut1, outSphericalHarmonicsArray, shDestBase, outputConversionFunc);\n                    setOutput3(shOut2, outSphericalHarmonicsArray, shDestBase + 3, outputConversionFunc);\n                    setOutput3(shOut3, outSphericalHarmonicsArray, shDestBase + 6, outputConversionFunc);\n\n                    if (outSphericalHarmonicsDegree >= 2) {\n\n                        set3FromArray(shIn1, dataView, 5, 9, this.compressionLevel);\n                        set3FromArray(shIn2, dataView, 5, 10, this.compressionLevel);\n                        set3FromArray(shIn3, dataView, 5, 11, this.compressionLevel);\n                        set3FromArray(shIn4, dataView, 5, 12, this.compressionLevel);\n                        set3FromArray(shIn5, dataView, 5, 13, this.compressionLevel);\n\n                        if (transform) {\n                            toUncompressedFloatArray3(shIn1, shIn1, this.compressionLevel, minShCoeff, maxShCoeff);\n                            toUncompressedFloatArray3(shIn2, shIn2, this.compressionLevel, minShCoeff, maxShCoeff);\n                            toUncompressedFloatArray3(shIn3, shIn3, this.compressionLevel, minShCoeff, maxShCoeff);\n                            toUncompressedFloatArray3(shIn4, shIn4, this.compressionLevel, minShCoeff, maxShCoeff);\n                            toUncompressedFloatArray3(shIn5, shIn5, this.compressionLevel, minShCoeff, maxShCoeff);\n                            SplatBuffer.rotateSphericalHarmonics5(shIn1, shIn2, shIn3, shIn4, shIn5,\n                                                                  sh11, sh12, sh13, sh21, sh22, sh23, sh24, sh25,\n                                                                  shOut1, shOut2, shOut3, shOut4, shOut5);\n                        } else {\n                            copy3(shIn1, shOut1);\n                            copy3(shIn2, shOut2);\n                            copy3(shIn3, shOut3);\n                            copy3(shIn4, shOut4);\n                            copy3(shIn5, shOut5);\n                        }\n\n                        setOutput3(shOut1, outSphericalHarmonicsArray, shDestBase + 9, outputConversionFunc);\n                        setOutput3(shOut2, outSphericalHarmonicsArray, shDestBase + 12, outputConversionFunc);\n                        setOutput3(shOut3, outSphericalHarmonicsArray, shDestBase + 15, outputConversionFunc);\n                        setOutput3(shOut4, outSphericalHarmonicsArray, shDestBase + 18, outputConversionFunc);\n                        setOutput3(shOut5, outSphericalHarmonicsArray, shDestBase + 21, outputConversionFunc);\n                    }\n                }\n            }\n        };\n\n    }();\n\n    static dot3 = (v1, v2, v3, transformRow, outArray) => {\n        outArray[0] = outArray[1] = outArray[2] = 0;\n        const t0 = transformRow[0];\n        const t1 = transformRow[1];\n        const t2 = transformRow[2];\n        SplatBuffer.addInto3(v1[0] * t0, v1[1] * t0, v1[2] * t0, outArray);\n        SplatBuffer.addInto3(v2[0] * t1, v2[1] * t1, v2[2] * t1, outArray);\n        SplatBuffer.addInto3(v3[0] * t2, v3[1] * t2, v3[2] * t2, outArray);\n    };\n\n    static addInto3 = (val1, val2, val3, destArray) => {\n        destArray[0] = destArray[0] + val1;\n        destArray[1] = destArray[1] + val2;\n        destArray[2] = destArray[2] + val3;\n    };\n\n    static dot5 = (v1, v2, v3, v4, v5, transformRow, outArray) => {\n        outArray[0] = outArray[1] = outArray[2] = 0;\n        const t0 = transformRow[0];\n        const t1 = transformRow[1];\n        const t2 = transformRow[2];\n        const t3 = transformRow[3];\n        const t4 = transformRow[4];\n        SplatBuffer.addInto3(v1[0] * t0, v1[1] * t0, v1[2] * t0, outArray);\n        SplatBuffer.addInto3(v2[0] * t1, v2[1] * t1, v2[2] * t1, outArray);\n        SplatBuffer.addInto3(v3[0] * t2, v3[1] * t2, v3[2] * t2, outArray);\n        SplatBuffer.addInto3(v4[0] * t3, v4[1] * t3, v4[2] * t3, outArray);\n        SplatBuffer.addInto3(v5[0] * t4, v5[1] * t4, v5[2] * t4, outArray);\n    };\n\n    static rotateSphericalHarmonics3 = (in1, in2, in3, tsh11, tsh12, tsh13, out1, out2, out3) => {\n        SplatBuffer.dot3(in1, in2, in3, tsh11, out1);\n        SplatBuffer.dot3(in1, in2, in3, tsh12, out2);\n        SplatBuffer.dot3(in1, in2, in3, tsh13, out3);\n    };\n\n    static rotateSphericalHarmonics5 = (in1, in2, in3, in4, in5, tsh11, tsh12, tsh13,\n                                        tsh21, tsh22, tsh23, tsh24, tsh25, out1, out2, out3, out4, out5) => {\n\n        const kSqrt0104 = Math.sqrt(1.0 / 4.0);\n        const kSqrt0304 = Math.sqrt(3.0 / 4.0);\n        const kSqrt0103 = Math.sqrt(1.0 / 3.0);\n        const kSqrt0403 = Math.sqrt(4.0 / 3.0);\n        const kSqrt0112 = Math.sqrt(1.0 / 12.0);\n\n        tsh21[0] = kSqrt0104 * ((tsh13[2] * tsh11[0] + tsh13[0] * tsh11[2]) + (tsh11[2] * tsh13[0] + tsh11[0] * tsh13[2]));\n        tsh21[1] = (tsh13[1] * tsh11[0] + tsh11[1] * tsh13[0]);\n        tsh21[2] = kSqrt0304 * (tsh13[1] * tsh11[1] + tsh11[1] * tsh13[1]);\n        tsh21[3] = (tsh13[1] * tsh11[2] + tsh11[1] * tsh13[2]);\n        tsh21[4] = kSqrt0104 * ((tsh13[2] * tsh11[2] - tsh13[0] * tsh11[0]) + (tsh11[2] * tsh13[2] - tsh11[0] * tsh13[0]));\n        SplatBuffer.dot5(in1, in2, in3, in4, in5, tsh21, out1);\n\n        tsh22[0] = kSqrt0104 * ((tsh12[2] * tsh11[0] + tsh12[0] * tsh11[2]) + (tsh11[2] * tsh12[0] + tsh11[0] * tsh12[2]));\n        tsh22[1] = tsh12[1] * tsh11[0] + tsh11[1] * tsh12[0];\n        tsh22[2] = kSqrt0304 * (tsh12[1] * tsh11[1] + tsh11[1] * tsh12[1]);\n        tsh22[3] = tsh12[1] * tsh11[2] + tsh11[1] * tsh12[2];\n        tsh22[4] = kSqrt0104 * ((tsh12[2] * tsh11[2] - tsh12[0] * tsh11[0]) + (tsh11[2] * tsh12[2] - tsh11[0] * tsh12[0]));\n        SplatBuffer.dot5(in1, in2, in3, in4, in5, tsh22, out2);\n\n        tsh23[0] = kSqrt0103 * (tsh12[2] * tsh12[0] + tsh12[0] * tsh12[2]) + -kSqrt0112 *\n                   ((tsh13[2] * tsh13[0] + tsh13[0] * tsh13[2]) + (tsh11[2] * tsh11[0] + tsh11[0] * tsh11[2]));\n        tsh23[1] = kSqrt0403 * tsh12[1] * tsh12[0] + -kSqrt0103 * (tsh13[1] * tsh13[0] + tsh11[1] * tsh11[0]);\n        tsh23[2] = tsh12[1] * tsh12[1] + -kSqrt0104 * (tsh13[1] * tsh13[1] + tsh11[1] * tsh11[1]);\n        tsh23[3] = kSqrt0403 * tsh12[1] * tsh12[2] + -kSqrt0103 * (tsh13[1] * tsh13[2] + tsh11[1] * tsh11[2]);\n        tsh23[4] = kSqrt0103 * (tsh12[2] * tsh12[2] - tsh12[0] * tsh12[0]) + -kSqrt0112 *\n                   ((tsh13[2] * tsh13[2] - tsh13[0] * tsh13[0]) + (tsh11[2] * tsh11[2] - tsh11[0] * tsh11[0]));\n        SplatBuffer.dot5(in1, in2, in3, in4, in5, tsh23, out3);\n\n        tsh24[0] = kSqrt0104 * ((tsh12[2] * tsh13[0] + tsh12[0] * tsh13[2]) + (tsh13[2] * tsh12[0] + tsh13[0] * tsh12[2]));\n        tsh24[1] = tsh12[1] * tsh13[0] + tsh13[1] * tsh12[0];\n        tsh24[2] = kSqrt0304 * (tsh12[1] * tsh13[1] + tsh13[1] * tsh12[1]);\n        tsh24[3] = tsh12[1] * tsh13[2] + tsh13[1] * tsh12[2];\n        tsh24[4] = kSqrt0104 * ((tsh12[2] * tsh13[2] - tsh12[0] * tsh13[0]) + (tsh13[2] * tsh12[2] - tsh13[0] * tsh12[0]));\n        SplatBuffer.dot5(in1, in2, in3, in4, in5, tsh24, out4);\n\n        tsh25[0] = kSqrt0104 * ((tsh13[2] * tsh13[0] + tsh13[0] * tsh13[2]) - (tsh11[2] * tsh11[0] + tsh11[0] * tsh11[2]));\n        tsh25[1] = (tsh13[1] * tsh13[0] - tsh11[1] * tsh11[0]);\n        tsh25[2] = kSqrt0304 * (tsh13[1] * tsh13[1] - tsh11[1] * tsh11[1]);\n        tsh25[3] = (tsh13[1] * tsh13[2] - tsh11[1] * tsh11[2]);\n        tsh25[4] = kSqrt0104 * ((tsh13[2] * tsh13[2] - tsh13[0] * tsh13[0]) - (tsh11[2] * tsh11[2] - tsh11[0] * tsh11[0]));\n        SplatBuffer.dot5(in1, in2, in3, in4, in5, tsh25, out5);\n    };\n\n    static parseHeader(buffer) {\n        const headerArrayUint8 = new Uint8Array(buffer, 0, SplatBuffer.HeaderSizeBytes);\n        const headerArrayUint16 = new Uint16Array(buffer, 0, SplatBuffer.HeaderSizeBytes / 2);\n        const headerArrayUint32 = new Uint32Array(buffer, 0, SplatBuffer.HeaderSizeBytes / 4);\n        const headerArrayFloat32 = new Float32Array(buffer, 0, SplatBuffer.HeaderSizeBytes / 4);\n        const versionMajor = headerArrayUint8[0];\n        const versionMinor = headerArrayUint8[1];\n        const maxSectionCount = headerArrayUint32[1];\n        const sectionCount = headerArrayUint32[2];\n        const maxSplatCount = headerArrayUint32[3];\n        const splatCount = headerArrayUint32[4];\n        const compressionLevel = headerArrayUint16[10];\n        const sceneCenter = new THREE.Vector3(headerArrayFloat32[6], headerArrayFloat32[7], headerArrayFloat32[8]);\n\n        const minSphericalHarmonicsCoeff = headerArrayFloat32[9] || -DefaultSphericalHarmonics8BitCompressionHalfRange;\n        const maxSphericalHarmonicsCoeff = headerArrayFloat32[10] || DefaultSphericalHarmonics8BitCompressionHalfRange;\n\n        return {\n            versionMajor,\n            versionMinor,\n            maxSectionCount,\n            sectionCount,\n            maxSplatCount,\n            splatCount,\n            compressionLevel,\n            sceneCenter,\n            minSphericalHarmonicsCoeff,\n            maxSphericalHarmonicsCoeff\n        };\n    }\n\n    static writeHeaderCountsToBuffer(sectionCount, splatCount, buffer) {\n        const headerArrayUint32 = new Uint32Array(buffer, 0, SplatBuffer.HeaderSizeBytes / 4);\n        headerArrayUint32[2] = sectionCount;\n        headerArrayUint32[4] = splatCount;\n    }\n\n    static writeHeaderToBuffer(header, buffer) {\n        const headerArrayUint8 = new Uint8Array(buffer, 0, SplatBuffer.HeaderSizeBytes);\n        const headerArrayUint16 = new Uint16Array(buffer, 0, SplatBuffer.HeaderSizeBytes / 2);\n        const headerArrayUint32 = new Uint32Array(buffer, 0, SplatBuffer.HeaderSizeBytes / 4);\n        const headerArrayFloat32 = new Float32Array(buffer, 0, SplatBuffer.HeaderSizeBytes / 4);\n        headerArrayUint8[0] = header.versionMajor;\n        headerArrayUint8[1] = header.versionMinor;\n        headerArrayUint8[2] = 0; // unused for now\n        headerArrayUint8[3] = 0; // unused for now\n        headerArrayUint32[1] = header.maxSectionCount;\n        headerArrayUint32[2] = header.sectionCount;\n        headerArrayUint32[3] = header.maxSplatCount;\n        headerArrayUint32[4] = header.splatCount;\n        headerArrayUint16[10] = header.compressionLevel;\n        headerArrayFloat32[6] = header.sceneCenter.x;\n        headerArrayFloat32[7] = header.sceneCenter.y;\n        headerArrayFloat32[8] = header.sceneCenter.z;\n        headerArrayFloat32[9] = header.minSphericalHarmonicsCoeff || -DefaultSphericalHarmonics8BitCompressionHalfRange;\n        headerArrayFloat32[10] = header.maxSphericalHarmonicsCoeff || DefaultSphericalHarmonics8BitCompressionHalfRange;\n    }\n\n    static parseSectionHeaders(header, buffer, offset = 0, secLoadedCountsToMax) {\n        const compressionLevel = header.compressionLevel;\n\n        const maxSectionCount = header.maxSectionCount;\n        const sectionHeaderArrayUint16 = new Uint16Array(buffer, offset, maxSectionCount * SplatBuffer.SectionHeaderSizeBytes / 2);\n        const sectionHeaderArrayUint32 = new Uint32Array(buffer, offset, maxSectionCount * SplatBuffer.SectionHeaderSizeBytes / 4);\n        const sectionHeaderArrayFloat32 = new Float32Array(buffer, offset, maxSectionCount * SplatBuffer.SectionHeaderSizeBytes / 4);\n\n        const sectionHeaders = [];\n        let sectionHeaderBase = 0;\n        let sectionHeaderBaseUint16 = sectionHeaderBase / 2;\n        let sectionHeaderBaseUint32 = sectionHeaderBase / 4;\n        let sectionBase = SplatBuffer.HeaderSizeBytes + header.maxSectionCount * SplatBuffer.SectionHeaderSizeBytes;\n        let splatCountOffset = 0;\n        for (let i = 0; i < maxSectionCount; i++) {\n            const maxSplatCount = sectionHeaderArrayUint32[sectionHeaderBaseUint32 + 1];\n            const bucketSize = sectionHeaderArrayUint32[sectionHeaderBaseUint32 + 2];\n            const bucketCount = sectionHeaderArrayUint32[sectionHeaderBaseUint32 + 3];\n            const bucketBlockSize = sectionHeaderArrayFloat32[sectionHeaderBaseUint32 + 4];\n            const halfBucketBlockSize = bucketBlockSize / 2.0;\n            const bucketStorageSizeBytes = sectionHeaderArrayUint16[sectionHeaderBaseUint16 + 10];\n            const compressionScaleRange = sectionHeaderArrayUint32[sectionHeaderBaseUint32 + 6] ||\n                                          SplatBuffer.CompressionLevels[compressionLevel].ScaleRange;\n            const fullBucketCount = sectionHeaderArrayUint32[sectionHeaderBaseUint32 + 8];\n            const partiallyFilledBucketCount = sectionHeaderArrayUint32[sectionHeaderBaseUint32 + 9];\n            const bucketsMetaDataSizeBytes = partiallyFilledBucketCount * 4;\n            const bucketsStorageSizeBytes = bucketStorageSizeBytes * bucketCount + bucketsMetaDataSizeBytes;\n\n            const sphericalHarmonicsDegree = sectionHeaderArrayUint16[sectionHeaderBaseUint16 + 20];\n            const { bytesPerSplat } = SplatBuffer.calculateComponentStorage(compressionLevel, sphericalHarmonicsDegree);\n\n            const splatDataStorageSizeBytes = bytesPerSplat * maxSplatCount;\n            const storageSizeBytes = splatDataStorageSizeBytes + bucketsStorageSizeBytes;\n            const sectionHeader = {\n                bytesPerSplat: bytesPerSplat,\n                splatCountOffset: splatCountOffset,\n                splatCount: secLoadedCountsToMax ? maxSplatCount : 0,\n                maxSplatCount: maxSplatCount,\n                bucketSize: bucketSize,\n                bucketCount: bucketCount,\n                bucketBlockSize: bucketBlockSize,\n                halfBucketBlockSize: halfBucketBlockSize,\n                bucketStorageSizeBytes: bucketStorageSizeBytes,\n                bucketsStorageSizeBytes: bucketsStorageSizeBytes,\n                splatDataStorageSizeBytes: splatDataStorageSizeBytes,\n                storageSizeBytes: storageSizeBytes,\n                compressionScaleRange: compressionScaleRange,\n                compressionScaleFactor: halfBucketBlockSize / compressionScaleRange,\n                base: sectionBase,\n                bucketsBase: sectionBase + bucketsMetaDataSizeBytes,\n                dataBase: sectionBase + bucketsStorageSizeBytes,\n                fullBucketCount: fullBucketCount,\n                partiallyFilledBucketCount: partiallyFilledBucketCount,\n                sphericalHarmonicsDegree: sphericalHarmonicsDegree\n            };\n            sectionHeaders[i] = sectionHeader;\n            sectionBase += storageSizeBytes;\n            sectionHeaderBase += SplatBuffer.SectionHeaderSizeBytes;\n            sectionHeaderBaseUint16 = sectionHeaderBase / 2;\n            sectionHeaderBaseUint32 = sectionHeaderBase / 4;\n            splatCountOffset += maxSplatCount;\n        }\n\n        return sectionHeaders;\n    }\n\n\n    static writeSectionHeaderToBuffer(sectionHeader, compressionLevel, buffer, offset = 0) {\n        const sectionHeadeArrayUint16 = new Uint16Array(buffer, offset, SplatBuffer.SectionHeaderSizeBytes / 2);\n        const sectionHeadeArrayUint32 = new Uint32Array(buffer, offset, SplatBuffer.SectionHeaderSizeBytes / 4);\n        const sectionHeadeArrayFloat32 = new Float32Array(buffer, offset, SplatBuffer.SectionHeaderSizeBytes / 4);\n\n        sectionHeadeArrayUint32[0] = sectionHeader.splatCount;\n        sectionHeadeArrayUint32[1] = sectionHeader.maxSplatCount;\n        sectionHeadeArrayUint32[2] = compressionLevel >= 1 ? sectionHeader.bucketSize : 0;\n        sectionHeadeArrayUint32[3] = compressionLevel >= 1 ? sectionHeader.bucketCount : 0;\n        sectionHeadeArrayFloat32[4] = compressionLevel >= 1 ? sectionHeader.bucketBlockSize : 0.0;\n        sectionHeadeArrayUint16[10] = compressionLevel >= 1 ? SplatBuffer.BucketStorageSizeBytes : 0;\n        sectionHeadeArrayUint32[6] = compressionLevel >= 1 ? sectionHeader.compressionScaleRange : 0;\n        sectionHeadeArrayUint32[7] = sectionHeader.storageSizeBytes;\n        sectionHeadeArrayUint32[8] = compressionLevel >= 1 ? sectionHeader.fullBucketCount : 0;\n        sectionHeadeArrayUint32[9] = compressionLevel >= 1 ? sectionHeader.partiallyFilledBucketCount : 0;\n        sectionHeadeArrayUint16[20] = sectionHeader.sphericalHarmonicsDegree;\n\n    }\n\n    static writeSectionHeaderSplatCountToBuffer(splatCount, buffer, offset = 0) {\n        const sectionHeadeArrayUint32 = new Uint32Array(buffer, offset, SplatBuffer.SectionHeaderSizeBytes / 4);\n        sectionHeadeArrayUint32[0] = splatCount;\n    }\n\n    constructFromBuffer(bufferData, secLoadedCountsToMax) {\n        this.bufferData = bufferData;\n\n        this.globalSplatIndexToLocalSplatIndexMap = [];\n        this.globalSplatIndexToSectionMap = [];\n\n        const header = SplatBuffer.parseHeader(this.bufferData);\n        this.versionMajor = header.versionMajor;\n        this.versionMinor = header.versionMinor;\n        this.maxSectionCount = header.maxSectionCount;\n        this.sectionCount = secLoadedCountsToMax ? header.maxSectionCount : 0;\n        this.maxSplatCount = header.maxSplatCount;\n        this.splatCount = secLoadedCountsToMax ? header.maxSplatCount : 0;\n        this.compressionLevel = header.compressionLevel;\n        this.sceneCenter = new THREE.Vector3().copy(header.sceneCenter);\n        this.minSphericalHarmonicsCoeff = header.minSphericalHarmonicsCoeff;\n        this.maxSphericalHarmonicsCoeff = header.maxSphericalHarmonicsCoeff;\n\n        this.sections = SplatBuffer.parseSectionHeaders(header, this.bufferData, SplatBuffer.HeaderSizeBytes, secLoadedCountsToMax);\n\n        this.linkBufferArrays();\n        this.buildMaps();\n    }\n\n    static calculateComponentStorage(compressionLevel, sphericalHarmonicsDegree) {\n        const bytesPerCenter = SplatBuffer.CompressionLevels[compressionLevel].BytesPerCenter;\n        const bytesPerScale = SplatBuffer.CompressionLevels[compressionLevel].BytesPerScale;\n        const bytesPerRotation = SplatBuffer.CompressionLevels[compressionLevel].BytesPerRotation;\n        const bytesPerColor = SplatBuffer.CompressionLevels[compressionLevel].BytesPerColor;\n        const sphericalHarmonicsComponentsPerSplat = getSphericalHarmonicsComponentCountForDegree(sphericalHarmonicsDegree);\n        const sphericalHarmonicsBytesPerSplat = SplatBuffer.CompressionLevels[compressionLevel].BytesPerSphericalHarmonicsComponent *\n                                                sphericalHarmonicsComponentsPerSplat;\n        const bytesPerSplat = bytesPerCenter + bytesPerScale + bytesPerRotation +\n                              bytesPerColor + sphericalHarmonicsBytesPerSplat;\n        return {\n            bytesPerCenter,\n            bytesPerScale,\n            bytesPerRotation,\n            bytesPerColor,\n            sphericalHarmonicsComponentsPerSplat,\n            sphericalHarmonicsBytesPerSplat,\n            bytesPerSplat\n        };\n    }\n\n    linkBufferArrays() {\n        for (let i = 0; i < this.maxSectionCount; i++) {\n            const section = this.sections[i];\n            section.bucketArray = new Float32Array(this.bufferData, section.bucketsBase,\n                                                   section.bucketCount * SplatBuffer.BucketStorageSizeFloats);\n            if (section.partiallyFilledBucketCount > 0) {\n                section.partiallyFilledBucketLengths = new Uint32Array(this.bufferData, section.base,\n                                                                       section.partiallyFilledBucketCount);\n            }\n        }\n    }\n\n    buildMaps() {\n        let cumulativeSplatCount = 0;\n        for (let i = 0; i < this.maxSectionCount; i++) {\n            const section = this.sections[i];\n            for (let j = 0; j < section.maxSplatCount; j++) {\n                const globalSplatIndex = cumulativeSplatCount + j;\n                this.globalSplatIndexToLocalSplatIndexMap[globalSplatIndex] = j;\n                this.globalSplatIndexToSectionMap[globalSplatIndex] = i;\n            }\n            cumulativeSplatCount += section.maxSplatCount;\n        }\n    }\n\n    updateLoadedCounts(newSectionCount, newSplatCount) {\n        SplatBuffer.writeHeaderCountsToBuffer(newSectionCount, newSplatCount, this.bufferData);\n        this.sectionCount = newSectionCount;\n        this.splatCount = newSplatCount;\n    }\n\n    updateSectionLoadedCounts(sectionIndex, newSplatCount) {\n        const sectionHeaderOffset = SplatBuffer.HeaderSizeBytes + SplatBuffer.SectionHeaderSizeBytes * sectionIndex;\n        SplatBuffer.writeSectionHeaderSplatCountToBuffer(newSplatCount, this.bufferData, sectionHeaderOffset);\n        this.sections[sectionIndex].splatCount = newSplatCount;\n    }\n\n    static writeSplatDataToSectionBuffer = function() {\n\n        const tempCenterBuffer = new ArrayBuffer(12);\n        const tempScaleBuffer = new ArrayBuffer(12);\n        const tempRotationBuffer = new ArrayBuffer(16);\n        const tempColorBuffer = new ArrayBuffer(4);\n        const tempSHBuffer = new ArrayBuffer(256);\n        const tempRot = new THREE.Quaternion();\n        const tempScale = new THREE.Vector3();\n        const bucketCenterDelta = new THREE.Vector3();\n\n        const {\n            X: OFFSET_X, Y: OFFSET_Y, Z: OFFSET_Z,\n            SCALE0: OFFSET_SCALE0, SCALE1: OFFSET_SCALE1, SCALE2: OFFSET_SCALE2,\n            ROTATION0: OFFSET_ROT0, ROTATION1: OFFSET_ROT1, ROTATION2: OFFSET_ROT2, ROTATION3: OFFSET_ROT3,\n            FDC0: OFFSET_FDC0, FDC1: OFFSET_FDC1, FDC2: OFFSET_FDC2, OPACITY: OFFSET_OPACITY,\n            FRC0: OFFSET_FRC0, FRC9: OFFSET_FRC9,\n        } = UncompressedSplatArray.OFFSET;\n\n        const compressPositionOffset = (v, compressionScaleFactor, compressionScaleRange) => {\n            const doubleCompressionScaleRange = compressionScaleRange * 2 + 1;\n            v = Math.round(v * compressionScaleFactor) + compressionScaleRange;\n            return clamp(v, 0, doubleCompressionScaleRange);\n        };\n\n        return function(targetSplat, sectionBuffer, bufferOffset, compressionLevel, sphericalHarmonicsDegree,\n                        bucketCenter, compressionScaleFactor, compressionScaleRange,\n                        minSphericalHarmonicsCoeff = -DefaultSphericalHarmonics8BitCompressionHalfRange,\n                        maxSphericalHarmonicsCoeff = DefaultSphericalHarmonics8BitCompressionHalfRange) {\n\n            const sphericalHarmonicsComponentsPerSplat = getSphericalHarmonicsComponentCountForDegree(sphericalHarmonicsDegree);\n            const bytesPerCenter = SplatBuffer.CompressionLevels[compressionLevel].BytesPerCenter;\n            const bytesPerScale = SplatBuffer.CompressionLevels[compressionLevel].BytesPerScale;\n            const bytesPerRotation = SplatBuffer.CompressionLevels[compressionLevel].BytesPerRotation;\n            const bytesPerColor = SplatBuffer.CompressionLevels[compressionLevel].BytesPerColor;\n\n            const centerBase = bufferOffset;\n            const scaleBase = centerBase + bytesPerCenter;\n            const rotationBase = scaleBase + bytesPerScale;\n            const colorBase = rotationBase + bytesPerRotation;\n            const sphericalHarmonicsBase = colorBase + bytesPerColor;\n\n            if (targetSplat[OFFSET_ROT0] !== undefined) {\n                tempRot.set(targetSplat[OFFSET_ROT0], targetSplat[OFFSET_ROT1], targetSplat[OFFSET_ROT2], targetSplat[OFFSET_ROT3]);\n                tempRot.normalize();\n            } else {\n                tempRot.set(1.0, 0.0, 0.0, 0.0);\n            }\n\n            if (targetSplat[OFFSET_SCALE0] !== undefined) {\n                tempScale.set(targetSplat[OFFSET_SCALE0] || 0,\n                              targetSplat[OFFSET_SCALE1] || 0,\n                              targetSplat[OFFSET_SCALE2] || 0);\n            } else {\n                tempScale.set(0, 0, 0);\n            }\n\n            if (compressionLevel === 0) {\n                const center = new Float32Array(sectionBuffer, centerBase, SplatBuffer.CenterComponentCount);\n                const rot = new Float32Array(sectionBuffer, rotationBase, SplatBuffer.RotationComponentCount);\n                const scale = new Float32Array(sectionBuffer, scaleBase, SplatBuffer.ScaleComponentCount);\n\n                rot.set([tempRot.x, tempRot.y, tempRot.z, tempRot.w]);\n                scale.set([tempScale.x, tempScale.y, tempScale.z]);\n                center.set([targetSplat[OFFSET_X], targetSplat[OFFSET_Y], targetSplat[OFFSET_Z]]);\n\n                if (sphericalHarmonicsDegree > 0) {\n                    const shOut = new Float32Array(sectionBuffer, sphericalHarmonicsBase, sphericalHarmonicsComponentsPerSplat);\n                    if (sphericalHarmonicsDegree >= 1) {\n                            for (let s = 0; s < 9; s++) shOut[s] = targetSplat[OFFSET_FRC0 + s] || 0;\n                            if (sphericalHarmonicsDegree >= 2) {\n                                for (let s = 0; s < 15; s++) shOut[s + 9] = targetSplat[OFFSET_FRC9 + s] || 0;\n                            }\n                    }\n                }\n            } else {\n                const center = new Uint16Array(tempCenterBuffer, 0, SplatBuffer.CenterComponentCount);\n                const rot = new Uint16Array(tempRotationBuffer, 0, SplatBuffer.RotationComponentCount);\n                const scale = new Uint16Array(tempScaleBuffer, 0, SplatBuffer.ScaleComponentCount);\n\n                rot.set([toHalfFloat(tempRot.x), toHalfFloat(tempRot.y), toHalfFloat(tempRot.z), toHalfFloat(tempRot.w)]);\n                scale.set([toHalfFloat(tempScale.x), toHalfFloat(tempScale.y), toHalfFloat(tempScale.z)]);\n\n                bucketCenterDelta.set(targetSplat[OFFSET_X], targetSplat[OFFSET_Y], targetSplat[OFFSET_Z]).sub(bucketCenter);\n                bucketCenterDelta.x = compressPositionOffset(bucketCenterDelta.x, compressionScaleFactor, compressionScaleRange);\n                bucketCenterDelta.y = compressPositionOffset(bucketCenterDelta.y, compressionScaleFactor, compressionScaleRange);\n                bucketCenterDelta.z = compressPositionOffset(bucketCenterDelta.z, compressionScaleFactor, compressionScaleRange);\n                center.set([bucketCenterDelta.x, bucketCenterDelta.y, bucketCenterDelta.z]);\n\n                if (sphericalHarmonicsDegree > 0) {\n                    const SHArrayType = compressionLevel === 1 ? Uint16Array : Uint8Array;\n                    const bytesPerSHComponent = compressionLevel === 1 ? 2 : 1;\n                    const shOut = new SHArrayType(tempSHBuffer, 0, sphericalHarmonicsComponentsPerSplat);\n                    if (sphericalHarmonicsDegree >= 1) {\n                        for (let s = 0; s < 9; s++) {\n                            const srcVal = targetSplat[OFFSET_FRC0 + s] || 0;\n                            shOut[s] = compressionLevel === 1 ? toHalfFloat(srcVal) :\n                                       toUint8(srcVal, minSphericalHarmonicsCoeff, maxSphericalHarmonicsCoeff);\n                        }\n                        const degree1ByteCount = 9 * bytesPerSHComponent;\n                        copyBetweenBuffers(shOut.buffer, 0, sectionBuffer, sphericalHarmonicsBase, degree1ByteCount);\n                        if (sphericalHarmonicsDegree >= 2) {\n                            for (let s = 0; s < 15; s++) {\n                                const srcVal = targetSplat[OFFSET_FRC9 + s] || 0;\n                                shOut[s + 9] = compressionLevel === 1 ? toHalfFloat(srcVal) :\n                                               toUint8(srcVal, minSphericalHarmonicsCoeff, maxSphericalHarmonicsCoeff);\n                            }\n                            copyBetweenBuffers(shOut.buffer, degree1ByteCount, sectionBuffer,\n                                               sphericalHarmonicsBase + degree1ByteCount, 15 * bytesPerSHComponent);\n                        }\n                    }\n                }\n\n                copyBetweenBuffers(center.buffer, 0, sectionBuffer, centerBase, 6);\n                copyBetweenBuffers(scale.buffer, 0, sectionBuffer, scaleBase, 6);\n                copyBetweenBuffers(rot.buffer, 0, sectionBuffer, rotationBase, 8);\n            }\n\n            const rgba = new Uint8ClampedArray(tempColorBuffer, 0, 4);\n            rgba.set([targetSplat[OFFSET_FDC0] || 0, targetSplat[OFFSET_FDC1] || 0, targetSplat[OFFSET_FDC2] || 0]);\n            rgba[3] = targetSplat[OFFSET_OPACITY] || 0;\n\n            copyBetweenBuffers(rgba.buffer, 0, sectionBuffer, colorBase, 4);\n        };\n\n    }();\n\n    static generateFromUncompressedSplatArrays(splatArrays, minimumAlpha, compressionLevel,\n                                               sceneCenter, blockSize, bucketSize, options = []) {\n\n        let shDegree = 0;\n        for (let sa = 0; sa < splatArrays.length; sa ++) {\n            const splatArray = splatArrays[sa];\n            shDegree = Math.max(splatArray.sphericalHarmonicsDegree, shDegree);\n        }\n\n        let minSphericalHarmonicsCoeff;\n        let maxSphericalHarmonicsCoeff;\n\n        for (let sa = 0; sa < splatArrays.length; sa ++) {\n            const splatArray = splatArrays[sa];\n            for (let i = 0; i < splatArray.splats.length; i++) {\n                const splat = splatArray.splats[i];\n                for (let sc = UncompressedSplatArray.OFFSET.FRC0; sc < UncompressedSplatArray.OFFSET.FRC23 && sc < splat.length; sc++) {\n                    if (!minSphericalHarmonicsCoeff || splat[sc] < minSphericalHarmonicsCoeff) {\n                        minSphericalHarmonicsCoeff = splat[sc];\n                    }\n                    if (!maxSphericalHarmonicsCoeff || splat[sc] > maxSphericalHarmonicsCoeff) {\n                        maxSphericalHarmonicsCoeff = splat[sc];\n                    }\n                }\n            }\n        }\n\n        minSphericalHarmonicsCoeff = minSphericalHarmonicsCoeff || -DefaultSphericalHarmonics8BitCompressionHalfRange;\n        maxSphericalHarmonicsCoeff = maxSphericalHarmonicsCoeff || DefaultSphericalHarmonics8BitCompressionHalfRange;\n\n        const { bytesPerSplat } = SplatBuffer.calculateComponentStorage(compressionLevel, shDegree);\n        const compressionScaleRange = SplatBuffer.CompressionLevels[compressionLevel].ScaleRange;\n\n        const sectionBuffers = [];\n        const sectionHeaderBuffers = [];\n        let totalSplatCount = 0;\n\n        for (let sa = 0; sa < splatArrays.length; sa ++) {\n            const splatArray = splatArrays[sa];\n            const validSplats = new UncompressedSplatArray(shDegree);\n            for (let i = 0; i < splatArray.splatCount; i++) {\n                const targetSplat = splatArray.splats[i];\n                if ((targetSplat[UncompressedSplatArray.OFFSET.OPACITY] || 0) >= minimumAlpha) {\n                    validSplats.addSplat(targetSplat);\n                }\n            }\n\n            const sectionOptions = options[sa] || {};\n            const sectionBlockSize = (sectionOptions.blockSizeFactor || 1) * (blockSize || SplatBuffer.BucketBlockSize);\n            const sectionBucketSize = Math.ceil((sectionOptions.bucketSizeFactor || 1) * (bucketSize || SplatBuffer.BucketSize));\n\n            const bucketInfo = SplatBuffer.computeBucketsForUncompressedSplatArray(validSplats, sectionBlockSize, sectionBucketSize);\n            const fullBucketCount = bucketInfo.fullBuckets.length;\n            const partiallyFullBucketLengths = bucketInfo.partiallyFullBuckets.map((bucket) => bucket.splats.length);\n            const partiallyFilledBucketCount = partiallyFullBucketLengths.length;\n            const buckets = [...bucketInfo.fullBuckets, ...bucketInfo.partiallyFullBuckets];\n\n            const sectionDataSizeBytes = validSplats.splats.length * bytesPerSplat;\n            const bucketMetaDataSizeBytes = partiallyFilledBucketCount * 4;\n            const bucketDataBytes = compressionLevel >= 1 ? buckets.length *\n                                                            SplatBuffer.BucketStorageSizeBytes + bucketMetaDataSizeBytes : 0;\n            const sectionSizeBytes = sectionDataSizeBytes + bucketDataBytes;\n            const sectionBuffer = new ArrayBuffer(sectionSizeBytes);\n\n            const compressionScaleFactor = compressionScaleRange / (sectionBlockSize * 0.5);\n            const bucketCenter = new THREE.Vector3();\n\n            let outSplatCount = 0;\n            for (let b = 0; b < buckets.length; b++) {\n                const bucket = buckets[b];\n                bucketCenter.fromArray(bucket.center);\n                for (let i = 0; i < bucket.splats.length; i++) {\n                    let row = bucket.splats[i];\n                    const targetSplat = validSplats.splats[row];\n                    const bufferOffset = bucketDataBytes + outSplatCount * bytesPerSplat;\n                    SplatBuffer.writeSplatDataToSectionBuffer(targetSplat, sectionBuffer, bufferOffset, compressionLevel, shDegree,\n                                                              bucketCenter, compressionScaleFactor, compressionScaleRange,\n                                                              minSphericalHarmonicsCoeff, maxSphericalHarmonicsCoeff);\n                    outSplatCount++;\n                }\n            }\n            totalSplatCount += outSplatCount;\n\n            if (compressionLevel >= 1) {\n                const bucketMetaDataArray = new Uint32Array(sectionBuffer, 0, partiallyFullBucketLengths.length * 4);\n                for (let pfb = 0; pfb < partiallyFullBucketLengths.length; pfb ++) {\n                    bucketMetaDataArray[pfb] = partiallyFullBucketLengths[pfb];\n                }\n                const bucketArray = new Float32Array(sectionBuffer, bucketMetaDataSizeBytes,\n                                                     buckets.length * SplatBuffer.BucketStorageSizeFloats);\n                for (let b = 0; b < buckets.length; b++) {\n                    const bucket = buckets[b];\n                    const base = b * 3;\n                    bucketArray[base] = bucket.center[0];\n                    bucketArray[base + 1] = bucket.center[1];\n                    bucketArray[base + 2] = bucket.center[2];\n                }\n            }\n            sectionBuffers.push(sectionBuffer);\n\n            const sectionHeaderBuffer = new ArrayBuffer(SplatBuffer.SectionHeaderSizeBytes);\n            SplatBuffer.writeSectionHeaderToBuffer({\n                maxSplatCount: outSplatCount,\n                splatCount: outSplatCount,\n                bucketSize: sectionBucketSize,\n                bucketCount: buckets.length,\n                bucketBlockSize: sectionBlockSize,\n                compressionScaleRange: compressionScaleRange,\n                storageSizeBytes: sectionSizeBytes,\n                fullBucketCount: fullBucketCount,\n                partiallyFilledBucketCount: partiallyFilledBucketCount,\n                sphericalHarmonicsDegree: shDegree\n            }, compressionLevel, sectionHeaderBuffer, 0);\n            sectionHeaderBuffers.push(sectionHeaderBuffer);\n\n        }\n\n        let sectionsCumulativeSizeBytes = 0;\n        for (let sectionBuffer of sectionBuffers) sectionsCumulativeSizeBytes += sectionBuffer.byteLength;\n        const unifiedBufferSize = SplatBuffer.HeaderSizeBytes +\n                                  SplatBuffer.SectionHeaderSizeBytes * sectionBuffers.length + sectionsCumulativeSizeBytes;\n        const unifiedBuffer = new ArrayBuffer(unifiedBufferSize);\n\n        SplatBuffer.writeHeaderToBuffer({\n            versionMajor: 0,\n            versionMinor: 1,\n            maxSectionCount: sectionBuffers.length,\n            sectionCount: sectionBuffers.length,\n            maxSplatCount: totalSplatCount,\n            splatCount: totalSplatCount,\n            compressionLevel: compressionLevel,\n            sceneCenter: sceneCenter,\n            minSphericalHarmonicsCoeff: minSphericalHarmonicsCoeff,\n            maxSphericalHarmonicsCoeff: maxSphericalHarmonicsCoeff\n        }, unifiedBuffer);\n\n        let currentUnifiedBase = SplatBuffer.HeaderSizeBytes;\n        for (let sectionHeaderBuffer of sectionHeaderBuffers) {\n            new Uint8Array(unifiedBuffer, currentUnifiedBase, SplatBuffer.SectionHeaderSizeBytes).set(new Uint8Array(sectionHeaderBuffer));\n            currentUnifiedBase += SplatBuffer.SectionHeaderSizeBytes;\n        }\n\n        for (let sectionBuffer of sectionBuffers) {\n            new Uint8Array(unifiedBuffer, currentUnifiedBase, sectionBuffer.byteLength).set(new Uint8Array(sectionBuffer));\n            currentUnifiedBase += sectionBuffer.byteLength;\n        }\n\n        const splatBuffer = new SplatBuffer(unifiedBuffer);\n        return splatBuffer;\n    }\n\n    static computeBucketsForUncompressedSplatArray(splatArray, blockSize, bucketSize) {\n        let splatCount = splatArray.splatCount;\n        const halfBlockSize = blockSize / 2.0;\n\n        const min = new THREE.Vector3();\n        const max = new THREE.Vector3();\n\n        for (let i = 0; i < splatCount; i++) {\n            const targetSplat = splatArray.splats[i];\n            const center = [targetSplat[UncompressedSplatArray.OFFSET.X],\n                            targetSplat[UncompressedSplatArray.OFFSET.Y],\n                            targetSplat[UncompressedSplatArray.OFFSET.Z]];\n            if (i === 0 || center[0] < min.x) min.x = center[0];\n            if (i === 0 || center[0] > max.x) max.x = center[0];\n            if (i === 0 || center[1] < min.y) min.y = center[1];\n            if (i === 0 || center[1] > max.y) max.y = center[1];\n            if (i === 0 || center[2] < min.z) min.z = center[2];\n            if (i === 0 || center[2] > max.z) max.z = center[2];\n        }\n\n        const dimensions = new THREE.Vector3().copy(max).sub(min);\n        const yBlocks = Math.ceil(dimensions.y / blockSize);\n        const zBlocks = Math.ceil(dimensions.z / blockSize);\n\n        const blockCenter = new THREE.Vector3();\n        const fullBuckets = [];\n        const partiallyFullBuckets = {};\n\n        for (let i = 0; i < splatCount; i++) {\n            const targetSplat = splatArray.splats[i];\n            const center = [targetSplat[UncompressedSplatArray.OFFSET.X],\n                            targetSplat[UncompressedSplatArray.OFFSET.Y],\n                            targetSplat[UncompressedSplatArray.OFFSET.Z]];\n            const xBlock = Math.floor((center[0] - min.x) / blockSize);\n            const yBlock = Math.floor((center[1] - min.y) / blockSize);\n            const zBlock = Math.floor((center[2] - min.z) / blockSize);\n\n            blockCenter.x = xBlock * blockSize + min.x + halfBlockSize;\n            blockCenter.y = yBlock * blockSize + min.y + halfBlockSize;\n            blockCenter.z = zBlock * blockSize + min.z + halfBlockSize;\n\n            const bucketId = xBlock * (yBlocks * zBlocks) + yBlock * zBlocks + zBlock;\n            let bucket = partiallyFullBuckets[bucketId];\n            if (!bucket) {\n                partiallyFullBuckets[bucketId] = bucket = {\n                    'splats': [],\n                    'center': blockCenter.toArray()\n                };\n            }\n\n            bucket.splats.push(i);\n            if (bucket.splats.length >= bucketSize) {\n                fullBuckets.push(bucket);\n                partiallyFullBuckets[bucketId] = null;\n            }\n        }\n\n        const partiallyFullBucketArray = [];\n        for (let bucketId in partiallyFullBuckets) {\n            if (partiallyFullBuckets.hasOwnProperty(bucketId)) {\n                const bucket = partiallyFullBuckets[bucketId];\n                if (bucket) {\n                    partiallyFullBucketArray.push(bucket);\n                }\n            }\n        }\n\n        return {\n            'fullBuckets': fullBuckets,\n            'partiallyFullBuckets': partiallyFullBucketArray,\n        };\n    }\n\n    static preallocateUncompressed(splatCount, sphericalHarmonicsDegrees) {\n        const shDescriptor = SplatBuffer.CompressionLevels[0].SphericalHarmonicsDegrees[sphericalHarmonicsDegrees];\n        const splatBufferDataOffsetBytes = SplatBuffer.HeaderSizeBytes + SplatBuffer.SectionHeaderSizeBytes;\n        const splatBufferSizeBytes = splatBufferDataOffsetBytes + shDescriptor.BytesPerSplat * splatCount;\n        const outBuffer = new ArrayBuffer(splatBufferSizeBytes);\n        SplatBuffer.writeHeaderToBuffer({\n            versionMajor: SplatBuffer.CurrentMajorVersion,\n            versionMinor: SplatBuffer.CurrentMinorVersion,\n            maxSectionCount: 1,\n            sectionCount: 1,\n            maxSplatCount: splatCount,\n            splatCount: splatCount,\n            compressionLevel: 0,\n            sceneCenter: new THREE.Vector3()\n        }, outBuffer);\n\n        SplatBuffer.writeSectionHeaderToBuffer({\n            maxSplatCount: splatCount,\n            splatCount: splatCount,\n            bucketSize: 0,\n            bucketCount: 0,\n            bucketBlockSize: 0,\n            compressionScaleRange: 0,\n            storageSizeBytes: 0,\n            fullBucketCount: 0,\n            partiallyFilledBucketCount: 0,\n            sphericalHarmonicsDegree: sphericalHarmonicsDegrees\n        }, 0, outBuffer, SplatBuffer.HeaderSizeBytes);\n\n        return {\n            splatBuffer: new SplatBuffer(outBuffer, true),\n            splatBufferDataOffsetBytes\n        };\n    }\n}\n","import { UncompressedSplatArray } from '../UncompressedSplatArray.js';\nimport { SplatBuffer } from '../SplatBuffer.js';\nimport { clamp } from '../../Util.js';\nimport * as THREE from 'three';\n\nconst HeaderMagicBytes = new Uint8Array([112, 108, 121, 10]);\nconst HeaderEndTokenBytes = new Uint8Array([10, 101, 110, 100, 95, 104, 101, 97, 100, 101, 114, 10]);\nconst HeaderEndToken = 'end_header';\n\nconst DataTypeMap = new Map([\n  ['char', Int8Array],\n  ['uchar', Uint8Array],\n  ['short', Int16Array],\n  ['ushort', Uint16Array],\n  ['int', Int32Array],\n  ['uint', Uint32Array],\n  ['float', Float32Array],\n  ['double', Float64Array],\n]);\n\nconst unpackUnorm = (value, bits) => {\n  const t = (1 << bits) - 1;\n  return (value & t) / t;\n};\n\nconst unpack111011 = (result, value) => {\n  result.x = unpackUnorm(value >>> 21, 11);\n  result.y = unpackUnorm(value >>> 11, 10);\n  result.z = unpackUnorm(value, 11);\n};\n\nconst unpack8888 = (result, value) => {\n  result.x = unpackUnorm(value >>> 24, 8);\n  result.y = unpackUnorm(value >>> 16, 8);\n  result.z = unpackUnorm(value >>> 8, 8);\n  result.w = unpackUnorm(value, 8);\n};\n\n// unpack quaternion with 2,10,10,10 format (largest element, 3x10bit element)\nconst unpackRot = (result, value) => {\n  const norm = 1.0 / (Math.sqrt(2) * 0.5);\n  const a = (unpackUnorm(value >>> 20, 10) - 0.5) * norm;\n  const b = (unpackUnorm(value >>> 10, 10) - 0.5) * norm;\n  const c = (unpackUnorm(value, 10) - 0.5) * norm;\n  const m = Math.sqrt(1.0 - (a * a + b * b + c * c));\n\n  switch (value >>> 30) {\n    case 0:\n      result.set(m, a, b, c);\n      break;\n    case 1:\n      result.set(a, m, b, c);\n      break;\n    case 2:\n      result.set(a, b, m, c);\n      break;\n    case 3:\n      result.set(a, b, c, m);\n      break;\n  }\n};\n\nconst lerp = (a, b, t) => {\n  return a * (1 - t) + b * t;\n};\n\nconst getElementPropStorage = (element, name) => {\n  return element.properties.find((p) => p.name === name && p.storage)\n    ?.storage;\n};\n\nexport class PlayCanvasCompressedPlyParser {\n\n  static decodeHeaderText(headerText) {\n\n    let element;\n    let chunkElement;\n    let vertexElement;\n    let shElement;\n\n    const headerLines = headerText.split('\\n').filter((line) => !line.startsWith('comment '));\n\n    let bytesPerSplat = 0;\n    let done = false;\n    for (let i = 1; i < headerLines.length; ++i) {\n      const words = headerLines[i].split(' ');\n\n      switch (words[0]) {\n        case 'format':\n          if (words[1] !== 'binary_little_endian') {\n            throw new Error('Unsupported ply format');\n          }\n          break;\n        case 'element':\n          element = {\n            name: words[1],\n            count: parseInt(words[2], 10),\n            properties: [],\n            storageSizeBytes: 0\n          };\n          if (element.name === 'chunk') chunkElement = element;\n          else if (element.name === 'vertex') vertexElement = element;\n          else if (element.name === 'sh') shElement = element;\n          break;\n        case 'property': {\n          if (!DataTypeMap.has(words[1])) {\n            throw new Error(\n              `Unrecognized property data type '${words[1]}' in ply header`\n            );\n          }\n          const StorageType = DataTypeMap.get(words[1]);\n          const storageSizeByes = StorageType.BYTES_PER_ELEMENT * element.count;\n          if (element.name === 'vertex') bytesPerSplat += StorageType.BYTES_PER_ELEMENT;\n          element.properties.push({\n            type: words[1],\n            name: words[2],\n            storage: null,\n            byteSize: StorageType.BYTES_PER_ELEMENT,\n            storageSizeByes: storageSizeByes\n          });\n          element.storageSizeBytes += storageSizeByes;\n          break;\n        }\n        case HeaderEndToken:\n          done = true;\n        break;\n        default:\n          throw new Error(\n            `Unrecognized header value '${words[0]}' in ply header`\n          );\n      }\n      if (done) break;\n    }\n\n    let sphericalHarmonicsDegree = 0;\n    let sphericalHarmonicsPerSplat = 0;\n    if (shElement) {\n      sphericalHarmonicsPerSplat = shElement.properties.length;\n      if (shElement.properties.length >= 45) {\n        sphericalHarmonicsDegree = 3;\n      } else if (shElement.properties.length >= 24) {\n        sphericalHarmonicsDegree = 2;\n      } else if (shElement.properties.length >= 9) {\n        sphericalHarmonicsDegree = 1;\n      }\n    }\n\n    return {\n      'chunkElement': chunkElement,\n      'vertexElement': vertexElement,\n      'shElement': shElement,\n      'bytesPerSplat': bytesPerSplat,\n      'headerSizeBytes': headerText.indexOf(HeaderEndToken) + HeaderEndToken.length + 1,\n      'sphericalHarmonicsDegree': sphericalHarmonicsDegree,\n      'sphericalHarmonicsPerSplat': sphericalHarmonicsPerSplat\n    };\n  }\n\n  static decodeHeader(plyBuffer) {\n\n    /**\n     * Searches for the first occurrence of a sequence within a buffer.\n     * @example\n     * find(new Uint8Array([1, 2, 3, 4]), new Uint8Array([3, 4])); // 2\n     * @param {Uint8Array} buf - The buffer in which to search.\n     * @param {Uint8Array} search - The sequence to search for.\n     * @return {number} The index of the first occurrence of the search sequence in the buffer, or -1 if not found.\n     */\n    const find = (buf, search) => {\n      const endIndex = buf.length - search.length;\n      let i;\n      let j;\n      for (i = 0; i <= endIndex; ++i) {\n        for (j = 0; j < search.length; ++j) {\n          if (buf[i + j] !== search[j]) {\n            break;\n          }\n        }\n        if (j === search.length) {\n          return i;\n        }\n      }\n      return -1;\n    };\n\n    /**\n     * Checks if array 'a' starts with the same elements as array 'b'.\n     * @example\n     * startsWith(new Uint8Array([1, 2, 3, 4]), new Uint8Array([1, 2])); // true\n     * @param {Uint8Array} a - The array to check against.\n     * @param {Uint8Array} b - The array of elements to look for at the start of 'a'.\n     * @return {boolean} - True if 'a' starts with all elements of 'b', otherwise false.\n     */\n    const startsWith = (a, b) => {\n      if (a.length < b.length) {\n        return false;\n      }\n\n      for (let i = 0; i < b.length; ++i) {\n        if (a[i] !== b[i]) {\n          return false;\n        }\n      }\n\n      return true;\n    };\n\n    let buf = new Uint8Array(plyBuffer);\n    let endHeaderTokenOffset;\n\n    if (buf.length >= HeaderMagicBytes.length && !startsWith(buf, HeaderMagicBytes)) {\n      throw new Error('Invalid PLY header');\n    }\n\n    endHeaderTokenOffset = find(buf, HeaderEndTokenBytes);\n    if (endHeaderTokenOffset === -1) {\n      throw new Error('End of PLY header not found');\n    }\n\n    const headerText = new TextDecoder('ascii').decode(\n      buf.slice(0, endHeaderTokenOffset)\n    );\n\n    const {\n      chunkElement,\n      vertexElement,\n      shElement,\n      sphericalHarmonicsDegree,\n      sphericalHarmonicsPerSplat,\n      bytesPerSplat\n    } = PlayCanvasCompressedPlyParser.decodeHeaderText(headerText);\n\n    return {\n      'headerSizeBytes': endHeaderTokenOffset + HeaderEndTokenBytes.length,\n      'bytesPerSplat': bytesPerSplat,\n      'chunkElement': chunkElement,\n      'vertexElement': vertexElement,\n      'shElement': shElement,\n      'sphericalHarmonicsDegree': sphericalHarmonicsDegree,\n      'sphericalHarmonicsPerSplat': sphericalHarmonicsPerSplat\n    };\n  }\n\n  static readElementData(element, readBuffer, readOffset, fromIndex, toIndex, propertyFilter = null) {\n\n    let dataView = readBuffer instanceof DataView ? readBuffer : new DataView(readBuffer);\n\n    fromIndex = fromIndex || 0;\n    toIndex = toIndex || element.count - 1;\n    for (let e = fromIndex; e <= toIndex; ++e) {\n      for (let j = 0; j < element.properties.length; ++j) {\n        const property = element.properties[j];\n\n        const StorageType = DataTypeMap.get(property.type);\n        const requiredStorageSizeBytes = StorageType.BYTES_PER_ELEMENT * element.count;\n        if ((!property.storage || property.storage.byteLength < requiredStorageSizeBytes) &&\n            (!propertyFilter || propertyFilter(property.name))) {\n          property.storage = new StorageType(element.count);\n        }\n\n        if (property.storage) {\n          switch (property.type) {\n            case 'char':\n              property.storage[e] = dataView.getInt8(readOffset);\n              break;\n            case 'uchar':\n              property.storage[e] = dataView.getUint8(readOffset);\n              break;\n            case 'short':\n              property.storage[e] = dataView.getInt16(readOffset, true);\n              break;\n            case 'ushort':\n              property.storage[e] = dataView.getUint16(readOffset, true);\n              break;\n            case 'int':\n              property.storage[e] = dataView.getInt32(readOffset, true);\n              break;\n            case 'uint':\n              property.storage[e] = dataView.getUint32(readOffset, true);\n              break;\n            case 'float':\n              property.storage[e] = dataView.getFloat32(readOffset, true);\n              break;\n            case 'double':\n              property.storage[e] = dataView.getFloat64(readOffset, true);\n              break;\n          }\n        }\n\n        readOffset += property.byteSize;\n      }\n    }\n\n    return readOffset;\n  }\n\n  static readPly(plyBuffer, propertyFilter = null) {\n\n    const header = PlayCanvasCompressedPlyParser.decodeHeader(plyBuffer);\n\n    let readIndex = PlayCanvasCompressedPlyParser.readElementData(header.chunkElement, plyBuffer,\n                                                                  header.headerSizeBytes, null, null, propertyFilter);\n    readIndex = PlayCanvasCompressedPlyParser.readElementData(header.vertexElement, plyBuffer, readIndex, null, null, propertyFilter);\n    PlayCanvasCompressedPlyParser.readElementData(header.shElement, plyBuffer, readIndex, null, null, propertyFilter);\n\n    return {\n      'chunkElement': header.chunkElement,\n      'vertexElement': header.vertexElement,\n      'shElement': header.shElement,\n      'sphericalHarmonicsDegree': header.sphericalHarmonicsDegree,\n      'sphericalHarmonicsPerSplat': header.sphericalHarmonicsPerSplat\n    };\n  }\n\n  static getElementStorageArrays(chunkElement, vertexElement, shElement) {\n    const storageArrays = {};\n\n    if (vertexElement) {\n      const minR = getElementPropStorage(chunkElement, 'min_r');\n      const minG = getElementPropStorage(chunkElement, 'min_g');\n      const minB = getElementPropStorage(chunkElement, 'min_b');\n      const maxR = getElementPropStorage(chunkElement, 'max_r');\n      const maxG = getElementPropStorage(chunkElement, 'max_g');\n      const maxB = getElementPropStorage(chunkElement, 'max_b');\n      const minX = getElementPropStorage(chunkElement, 'min_x');\n      const minY = getElementPropStorage(chunkElement, 'min_y');\n      const minZ = getElementPropStorage(chunkElement, 'min_z');\n      const maxX = getElementPropStorage(chunkElement, 'max_x');\n      const maxY = getElementPropStorage(chunkElement, 'max_y');\n      const maxZ = getElementPropStorage(chunkElement, 'max_z');\n      const minScaleX = getElementPropStorage(chunkElement, 'min_scale_x');\n      const minScaleY = getElementPropStorage(chunkElement, 'min_scale_y');\n      const minScaleZ = getElementPropStorage(chunkElement, 'min_scale_z');\n      const maxScaleX = getElementPropStorage(chunkElement, 'max_scale_x');\n      const maxScaleY = getElementPropStorage(chunkElement, 'max_scale_y');\n      const maxScaleZ = getElementPropStorage(chunkElement, 'max_scale_z');\n      const position = getElementPropStorage(vertexElement, 'packed_position');\n      const rotation = getElementPropStorage(vertexElement, 'packed_rotation');\n      const scale = getElementPropStorage(vertexElement, 'packed_scale');\n      const color = getElementPropStorage(vertexElement, 'packed_color');\n\n      storageArrays['colorExtremes'] = {\n        minR, maxR,\n        minG, maxG,\n        minB, maxB\n      };\n      storageArrays['positionExtremes'] = {\n        minX, maxX,\n        minY, maxY,\n        minZ, maxZ\n      };\n      storageArrays['scaleExtremes'] = {\n        minScaleX, maxScaleX, minScaleY,\n        maxScaleY, minScaleZ, maxScaleZ\n      };\n      storageArrays['position'] = position;\n      storageArrays['rotation'] = rotation;\n      storageArrays['scale'] = scale;\n      storageArrays['color'] = color;\n    }\n\n    if (shElement) {\n      const shStorageArrays = {};\n      for (let i = 0; i < 45; i++) {\n        const fRestKey = `f_rest_${i}`;\n        const fRest = getElementPropStorage(shElement, fRestKey);\n        if (fRest) {\n          shStorageArrays[fRestKey] = fRest;\n        } else {\n          break;\n        }\n      }\n      storageArrays['sh'] = shStorageArrays;\n    }\n\n    return storageArrays;\n  }\n\n  static decompressBaseSplat = function() {\n\n    const p = new THREE.Vector3();\n    const r = new THREE.Quaternion();\n    const s = new THREE.Vector3();\n    const c = new THREE.Vector4();\n\n    const OFFSET = UncompressedSplatArray.OFFSET;\n\n    return function(index, chunkSplatIndexOffset, positionArray, positionExtremes, scaleArray, scaleExtremes,\n                    rotationArray, colorExtremes, colorArray, outSplat) {\n      outSplat = outSplat || UncompressedSplatArray.createSplat();\n\n      const chunkIndex = Math.floor((chunkSplatIndexOffset + index) / 256);\n\n      unpack111011(p, positionArray[index]);\n      unpackRot(r, rotationArray[index]);\n      unpack111011(s, scaleArray[index]);\n      unpack8888(c, colorArray[index]);\n\n      outSplat[OFFSET.X] = lerp(positionExtremes.minX[chunkIndex], positionExtremes.maxX[chunkIndex], p.x);\n      outSplat[OFFSET.Y] = lerp(positionExtremes.minY[chunkIndex], positionExtremes.maxY[chunkIndex], p.y);\n      outSplat[OFFSET.Z] = lerp(positionExtremes.minZ[chunkIndex], positionExtremes.maxZ[chunkIndex], p.z);\n\n      outSplat[OFFSET.ROTATION0] = r.x;\n      outSplat[OFFSET.ROTATION1] = r.y;\n      outSplat[OFFSET.ROTATION2] = r.z;\n      outSplat[OFFSET.ROTATION3] = r.w;\n\n      outSplat[OFFSET.SCALE0] = Math.exp(lerp(scaleExtremes.minScaleX[chunkIndex], scaleExtremes.maxScaleX[chunkIndex], s.x));\n      outSplat[OFFSET.SCALE1] = Math.exp(lerp(scaleExtremes.minScaleY[chunkIndex], scaleExtremes.maxScaleY[chunkIndex], s.y));\n      outSplat[OFFSET.SCALE2] = Math.exp(lerp(scaleExtremes.minScaleZ[chunkIndex], scaleExtremes.maxScaleZ[chunkIndex], s.z));\n\n      if (colorExtremes.minR && colorExtremes.maxR) {\n        outSplat[OFFSET.FDC0] = clamp(Math.round(lerp(colorExtremes.minR[chunkIndex], colorExtremes.maxR[chunkIndex], c.x) * 255), 0, 255);\n      } else {\n        outSplat[OFFSET.FDC0] = clamp(Math.floor(c.x * 255), 0, 255);\n      }\n      if (colorExtremes.minG && colorExtremes.maxG) {\n        outSplat[OFFSET.FDC1] = clamp(Math.round(lerp(colorExtremes.minG[chunkIndex], colorExtremes.maxG[chunkIndex], c.y) * 255), 0, 255);\n      } else {\n        outSplat[OFFSET.FDC1] = clamp(Math.floor(c.y * 255), 0, 255);\n      }\n      if (colorExtremes.minB && colorExtremes.maxB) {\n        outSplat[OFFSET.FDC2] = clamp(Math.round(lerp(colorExtremes.minB[chunkIndex], colorExtremes.maxB[chunkIndex], c.z) * 255), 0, 255);\n      } else {\n        outSplat[OFFSET.FDC2] = clamp(Math.floor(c.z * 255), 0, 255);\n      }\n      outSplat[OFFSET.OPACITY] = clamp(Math.floor(c.w * 255), 0, 255);\n\n      return outSplat;\n    };\n\n  }();\n\n  static decompressSphericalHarmonics = function() {\n\n    const shCoeffMap = [0, 3, 8, 15];\n\n    const shIndexMap = [\n      0, 1, 2, 9, 10, 11, 12, 13, 24, 25, 26, 27, 28, 29, 30,\n      3, 4, 5, 14, 15, 16, 17, 18, 31, 32, 33, 34, 35, 36, 37,\n      6, 7, 8, 19, 20, 21, 22, 23, 38, 39, 40, 41, 42, 43, 44\n    ];\n\n    return function(index, shArray, outSphericalHarmonicsDegree, readSphericalHarmonicsDegree, outSplat) {\n      outSplat = outSplat || UncompressedSplatArray.createSplat();\n      let outSHCoeff = shCoeffMap[outSphericalHarmonicsDegree];\n      let readSHCoeff = shCoeffMap[readSphericalHarmonicsDegree];\n      for (let j = 0; j < 3; ++j) {\n        for (let k = 0; k < 15; ++k) {\n          const outIndex = shIndexMap[j * 15 + k];\n          if (k < outSHCoeff && k < readSHCoeff) {\n            outSplat[UncompressedSplatArray.OFFSET.FRC0 + outIndex] = (shArray[j * readSHCoeff + k][index] * (8 / 255) - 4);\n          }\n        }\n      }\n\n      return outSplat;\n    };\n\n  }();\n\n  static parseToUncompressedSplatBufferSection(chunkElement, vertexElement, fromIndex, toIndex, chunkSplatIndexOffset,\n                                               vertexDataBuffer, outBuffer, outOffset, propertyFilter = null) {\n\n    PlayCanvasCompressedPlyParser.readElementData(vertexElement, vertexDataBuffer, 0, fromIndex, toIndex, propertyFilter);\n\n    const outBytesPerSplat = SplatBuffer.CompressionLevels[0].SphericalHarmonicsDegrees[0].BytesPerSplat;\n\n    const { positionExtremes, scaleExtremes, colorExtremes, position, rotation, scale, color } =\n      PlayCanvasCompressedPlyParser.getElementStorageArrays(chunkElement, vertexElement);\n\n    const tempSplat = UncompressedSplatArray.createSplat();\n\n    for (let i = fromIndex; i <= toIndex; ++i) {\n      PlayCanvasCompressedPlyParser.decompressBaseSplat(i, chunkSplatIndexOffset, position, positionExtremes,\n                                                        scale, scaleExtremes, rotation, colorExtremes, color, tempSplat);\n      const outBase = i * outBytesPerSplat + outOffset;\n      SplatBuffer.writeSplatDataToSectionBuffer(tempSplat, outBuffer, outBase, 0, 0);\n    }\n  }\n\n  static parseToUncompressedSplatArraySection(chunkElement, vertexElement, fromIndex, toIndex, chunkSplatIndexOffset,\n                                              vertexDataBuffer, splatArray, propertyFilter = null) {\n\n    PlayCanvasCompressedPlyParser.readElementData(vertexElement, vertexDataBuffer, 0, fromIndex, toIndex, propertyFilter);\n\n    const { positionExtremes, scaleExtremes, colorExtremes, position, rotation, scale, color } =\n      PlayCanvasCompressedPlyParser.getElementStorageArrays(chunkElement, vertexElement);\n\n    for (let i = fromIndex; i <= toIndex; ++i) {\n      const tempSplat = UncompressedSplatArray.createSplat();\n      PlayCanvasCompressedPlyParser.decompressBaseSplat(i, chunkSplatIndexOffset, position, positionExtremes,\n                                                        scale, scaleExtremes, rotation, colorExtremes, color, tempSplat);\n      splatArray.addSplat(tempSplat);\n    }\n  }\n\n  static parseSphericalHarmonicsToUncompressedSplatArraySection(chunkElement, shElement, fromIndex, toIndex,\n    vertexDataBuffer, vertexReadOffset, outSphericalHarmonicsDegree, readSphericalHarmonicsDegree, splatArray, propertyFilter = null) {\n\n    PlayCanvasCompressedPlyParser.readElementData(shElement, vertexDataBuffer, vertexReadOffset, fromIndex, toIndex, propertyFilter);\n\n    const { sh } = PlayCanvasCompressedPlyParser.getElementStorageArrays(chunkElement, undefined, shElement);\n    const shArrays = Object.values(sh);\n\n    for (let i = fromIndex; i <= toIndex; ++i) {\n      PlayCanvasCompressedPlyParser.decompressSphericalHarmonics(\n        i, shArrays, outSphericalHarmonicsDegree, readSphericalHarmonicsDegree, splatArray.splats[i]\n      );\n    }\n  }\n\n  static parseToUncompressedSplatArray(plyBuffer, outSphericalHarmonicsDegree) {\n    const { chunkElement, vertexElement, shElement, sphericalHarmonicsDegree } = PlayCanvasCompressedPlyParser.readPly(plyBuffer);\n\n    outSphericalHarmonicsDegree = Math.min(outSphericalHarmonicsDegree, sphericalHarmonicsDegree);\n\n    const splatArray = new UncompressedSplatArray(outSphericalHarmonicsDegree);\n\n    const { positionExtremes, scaleExtremes, colorExtremes, position, rotation, scale, color } =\n      PlayCanvasCompressedPlyParser.getElementStorageArrays(chunkElement, vertexElement);\n\n    let shArrays;\n    if (outSphericalHarmonicsDegree > 0) {\n      const { sh } = PlayCanvasCompressedPlyParser.getElementStorageArrays(chunkElement, undefined, shElement);\n      shArrays = Object.values(sh);\n    }\n\n    for (let i = 0; i < vertexElement.count; ++i) {\n\n      splatArray.addDefaultSplat();\n      const newSplat = splatArray.getSplat(splatArray.splatCount - 1);\n\n      PlayCanvasCompressedPlyParser.decompressBaseSplat(i, 0, position, positionExtremes, scale,\n                                                        scaleExtremes, rotation, colorExtremes, color, newSplat);\n\n      if (outSphericalHarmonicsDegree > 0) {\n        PlayCanvasCompressedPlyParser.decompressSphericalHarmonics(\n          i, shArrays, outSphericalHarmonicsDegree, sphericalHarmonicsDegree, newSplat\n        );\n      }\n    }\n\n    return splatArray;\n  }\n\n  static parseToUncompressedSplatBuffer(plyBuffer, outSphericalHarmonicsDegree) {\n    const { chunkElement, vertexElement, shElement, sphericalHarmonicsDegree } = PlayCanvasCompressedPlyParser.readPly(plyBuffer);\n\n    outSphericalHarmonicsDegree = Math.min(outSphericalHarmonicsDegree, sphericalHarmonicsDegree);\n\n    const {\n      splatBuffer,\n      splatBufferDataOffsetBytes\n    } = SplatBuffer.preallocateUncompressed(vertexElement.count, outSphericalHarmonicsDegree);\n\n    const { positionExtremes, scaleExtremes, colorExtremes, position, rotation, scale, color } =\n    PlayCanvasCompressedPlyParser.getElementStorageArrays(chunkElement, vertexElement);\n\n    let shArrays;\n    if (outSphericalHarmonicsDegree > 0) {\n      const { sh } = PlayCanvasCompressedPlyParser.getElementStorageArrays(chunkElement, undefined, shElement);\n      shArrays = Object.values(sh);\n    }\n\n    const outBytesPerSplat = SplatBuffer.CompressionLevels[0].SphericalHarmonicsDegrees[outSphericalHarmonicsDegree].BytesPerSplat;\n\n    const newSplat = UncompressedSplatArray.createSplat(outSphericalHarmonicsDegree);\n\n    for (let i = 0; i < vertexElement.count; ++i) {\n      PlayCanvasCompressedPlyParser.decompressBaseSplat(\n        i, 0, position, positionExtremes, scale, scaleExtremes, rotation, colorExtremes, color, newSplat\n      );\n      if (outSphericalHarmonicsDegree > 0) {\n        PlayCanvasCompressedPlyParser.decompressSphericalHarmonics(\n          i, shArrays, outSphericalHarmonicsDegree, sphericalHarmonicsDegree, newSplat\n        );\n      }\n\n      const outBase = i * outBytesPerSplat + splatBufferDataOffsetBytes;\n      SplatBuffer.writeSplatDataToSectionBuffer(newSplat, splatBuffer.bufferData, outBase, 0, outSphericalHarmonicsDegree);\n    }\n\n    return splatBuffer;\n  }\n\n}\n","export const PlyFormat = {\n    'INRIAV1': 0,\n    'INRIAV2': 1,\n    'PlayCanvasCompressed': 2\n};\n","import { PlyFormat } from './PlyFormat.js';\n\nconst [\n        FieldSizeIdDouble, FieldSizeIdInt, FieldSizeIdUInt, FieldSizeIdFloat, FieldSizeIdShort, FieldSizeIdUShort, FieldSizeIdUChar\n      ] = [0, 1, 2, 3, 4, 5, 6];\n\nconst FieldSizeStringMap = {\n    'double': FieldSizeIdDouble,\n    'int': FieldSizeIdInt,\n    'uint': FieldSizeIdUInt,\n    'float': FieldSizeIdFloat,\n    'short': FieldSizeIdShort,\n    'ushort': FieldSizeIdUShort,\n    'uchar': FieldSizeIdUChar,\n};\n\nconst FieldSize = {\n    [FieldSizeIdDouble]: 8,\n    [FieldSizeIdInt]: 4,\n    [FieldSizeIdUInt]: 4,\n    [FieldSizeIdFloat]: 4,\n    [FieldSizeIdShort]: 2,\n    [FieldSizeIdUShort]: 2,\n    [FieldSizeIdUChar]: 1,\n};\n\nexport class PlyParserUtils {\n\n    static HeaderEndToken = 'end_header';\n\n    static decodeSectionHeader(headerLines, fieldNameIdMap, headerStartLine = 0) {\n\n        const extractedLines = [];\n\n        let processingSection = false;\n        let headerEndLine = -1;\n        let vertexCount = 0;\n        let endOfHeader = false;\n        let sectionName = null;\n\n        const fieldIds = [];\n        const fieldTypes = [];\n        const allFieldNames = [];\n        const usedFieldNames = [];\n        const fieldTypesByName = {};\n\n        for (let i = headerStartLine; i < headerLines.length; i++) {\n            const line = headerLines[i].trim();\n            if (line.startsWith('element')) {\n                if (processingSection) {\n                    headerEndLine--;\n                    break;\n                } else {\n                    processingSection = true;\n                    headerStartLine = i;\n                    headerEndLine = i;\n                    const lineComponents = line.split(' ');\n                    let validComponents = 0;\n                    for (let lineComponent of lineComponents) {\n                        const trimmedComponent = lineComponent.trim();\n                        if (trimmedComponent.length > 0) {\n                            validComponents++;\n                            if (validComponents === 2) {\n                                sectionName = trimmedComponent;\n                            } else if (validComponents === 3) {\n                                vertexCount = parseInt(trimmedComponent);\n                            }\n                        }\n                    }\n                }\n            } else if (line.startsWith('property')) {\n                const fieldMatch = line.match(/(\\w+)\\s+(\\w+)\\s+(\\w+)/);\n                if (fieldMatch) {\n                    const fieldTypeStr = fieldMatch[2];\n                    const fieldName = fieldMatch[3];\n                    allFieldNames.push(fieldName);\n                    const fieldId = fieldNameIdMap[fieldName];\n                    fieldTypesByName[fieldName] = fieldTypeStr;\n                    const fieldType = FieldSizeStringMap[fieldTypeStr];\n                    if (fieldId !== undefined) {\n                        usedFieldNames.push(fieldName);\n                        fieldIds.push(fieldId);\n                        fieldTypes[fieldId] = fieldType;\n                    }\n                }\n            }\n            if (line === PlyParserUtils.HeaderEndToken) {\n                endOfHeader = true;\n                break;\n            }\n            if (processingSection) {\n                extractedLines.push(line);\n                headerEndLine++;\n            }\n        }\n\n        const fieldOffsets = [];\n        let bytesPerVertex = 0;\n        for (let fieldName of allFieldNames) {\n            const fieldType = fieldTypesByName[fieldName];\n            if (fieldTypesByName.hasOwnProperty(fieldName)) {\n                const fieldId = fieldNameIdMap[fieldName];\n                if (fieldId !== undefined) {\n                    fieldOffsets[fieldId] = bytesPerVertex;\n                }\n            }\n            bytesPerVertex += FieldSize[FieldSizeStringMap[fieldType]];\n        }\n\n        const sphericalHarmonics = PlyParserUtils.decodeSphericalHarmonicsFromSectionHeader(allFieldNames, fieldNameIdMap);\n\n        return {\n            'headerLines': extractedLines,\n            'headerStartLine': headerStartLine,\n            'headerEndLine': headerEndLine,\n            'fieldTypes': fieldTypes,\n            'fieldIds': fieldIds,\n            'fieldOffsets': fieldOffsets,\n            'bytesPerVertex': bytesPerVertex,\n            'vertexCount': vertexCount,\n            'dataSizeBytes': bytesPerVertex * vertexCount,\n            'endOfHeader': endOfHeader,\n            'sectionName': sectionName,\n            'sphericalHarmonicsDegree': sphericalHarmonics.degree,\n            'sphericalHarmonicsCoefficientsPerChannel': sphericalHarmonics.coefficientsPerChannel,\n            'sphericalHarmonicsDegree1Fields': sphericalHarmonics.degree1Fields,\n            'sphericalHarmonicsDegree2Fields': sphericalHarmonics.degree2Fields\n        };\n\n    }\n\n    static decodeSphericalHarmonicsFromSectionHeader(fieldNames, fieldNameIdMap) {\n        let sphericalHarmonicsFieldCount = 0;\n        let coefficientsPerChannel = 0;\n        for (let fieldName of fieldNames) {\n            if (fieldName.startsWith('f_rest')) sphericalHarmonicsFieldCount++;\n        }\n        coefficientsPerChannel = sphericalHarmonicsFieldCount / 3;\n        let degree = 0;\n        if (coefficientsPerChannel >= 3) degree = 1;\n        if (coefficientsPerChannel >= 8) degree = 2;\n\n        let degree1Fields = [];\n        let degree2Fields = [];\n\n        for (let rgb = 0; rgb < 3; rgb++) {\n            if (degree >= 1) {\n                for (let i = 0; i < 3; i++) {\n                    degree1Fields.push(fieldNameIdMap['f_rest_' + (i + coefficientsPerChannel * rgb)]);\n                }\n            }\n            if (degree >= 2) {\n                for (let i = 0; i < 5; i++) {\n                    degree2Fields.push(fieldNameIdMap['f_rest_' + (i + coefficientsPerChannel * rgb + 3)]);\n                }\n            }\n        }\n\n        return {\n            'degree': degree,\n            'coefficientsPerChannel': coefficientsPerChannel,\n            'degree1Fields': degree1Fields,\n            'degree2Fields': degree2Fields\n        };\n    }\n\n    static getHeaderSectionNames(headerLines) {\n        const sectionNames = [];\n        for (let headerLine of headerLines) {\n            if (headerLine.startsWith('element')) {\n                const lineComponents = headerLine.split(' ');\n                let validComponents = 0;\n                for (let lineComponent of lineComponents) {\n                    const trimmedComponent = lineComponent.trim();\n                    if (trimmedComponent.length > 0) {\n                        validComponents++;\n                        if (validComponents === 2) {\n                            sectionNames.push(trimmedComponent);\n                        }\n                    }\n                }\n            }\n        }\n        return sectionNames;\n    }\n\n    static checkTextForEndHeader(endHeaderTestText) {\n        if (endHeaderTestText.includes(PlyParserUtils.HeaderEndToken)) {\n            return true;\n        }\n        return false;\n    }\n\n    static checkBufferForEndHeader(buffer, searchOfset, chunkSize, decoder) {\n        const endHeaderTestChunk = new Uint8Array(buffer, Math.max(0, searchOfset - chunkSize), chunkSize);\n        const endHeaderTestText = decoder.decode(endHeaderTestChunk);\n        return PlyParserUtils.checkTextForEndHeader(endHeaderTestText);\n    }\n\n    static extractHeaderFromBufferToText(plyBuffer) {\n        const decoder = new TextDecoder();\n        let headerOffset = 0;\n        let headerText = '';\n        const readChunkSize = 100;\n\n        while (true) {\n            if (headerOffset + readChunkSize >= plyBuffer.byteLength) {\n                throw new Error('End of file reached while searching for end of header');\n            }\n            const headerChunk = new Uint8Array(plyBuffer, headerOffset, readChunkSize);\n            headerText += decoder.decode(headerChunk);\n            headerOffset += readChunkSize;\n\n            if (PlyParserUtils.checkBufferForEndHeader(plyBuffer, headerOffset, readChunkSize * 2, decoder)) {\n                break;\n            }\n        }\n\n        return headerText;\n    }\n\n    static readHeaderFromBuffer(plyBuffer) {\n        const decoder = new TextDecoder();\n        let headerOffset = 0;\n        let headerText = '';\n        const readChunkSize = 100;\n\n        while (true) {\n            if (headerOffset + readChunkSize >= plyBuffer.byteLength) {\n                throw new Error('End of file reached while searching for end of header');\n            }\n            const headerChunk = new Uint8Array(plyBuffer, headerOffset, readChunkSize);\n            headerText += decoder.decode(headerChunk);\n            headerOffset += readChunkSize;\n\n            if (PlyParserUtils.checkBufferForEndHeader(plyBuffer, headerOffset, readChunkSize * 2, decoder)) {\n                break;\n            }\n        }\n\n        return headerText;\n    }\n\n    static convertHeaderTextToLines(headerText) {\n        const headerLines = headerText.split('\\n');\n        const prunedLines = [];\n        for (let i = 0; i < headerLines.length; i++) {\n            const line = headerLines[i].trim();\n            prunedLines.push(line);\n            if (line === PlyParserUtils.HeaderEndToken) {\n                break;\n            }\n        }\n        return prunedLines;\n    }\n\n    static determineHeaderFormatFromHeaderText(headertText) {\n        const headerLines = PlyParserUtils.convertHeaderTextToLines(headertText);\n        let format = PlyFormat.INRIAV1;\n        for (let i = 0; i < headerLines.length; i++) {\n            const line = headerLines[i].trim();\n            if (line.startsWith('element chunk') || line.match(/[A-Za-z]*packed_[A-Za-z]*/)) {\n                format = PlyFormat.PlayCanvasCompressed;\n            } else if (line.startsWith('element codebook_centers')) {\n                format = PlyFormat.INRIAV2;\n            } else if (line === PlyParserUtils.HeaderEndToken) {\n                break;\n            }\n        }\n        return format;\n    }\n\n    static determineHeaderFormatFromPlyBuffer(plyBuffer) {\n        const headertText = PlyParserUtils.extractHeaderFromBufferToText(plyBuffer);\n        return PlyParserUtils.determineHeaderFormatFromHeaderText(headertText);\n    }\n\n    static readVertex(vertexData, header, row, dataOffset, fieldsToRead, rawVertex, normalize = true) {\n        const offset = row * header.bytesPerVertex + dataOffset;\n        const fieldOffsets = header.fieldOffsets;\n        const fieldTypes = header.fieldTypes;\n        for (let fieldId of fieldsToRead) {\n            const fieldType = fieldTypes[fieldId];\n            if (fieldType === FieldSizeIdFloat) {\n                rawVertex[fieldId] = vertexData.getFloat32(offset + fieldOffsets[fieldId], true);\n            } else if (fieldType === FieldSizeIdShort) {\n                rawVertex[fieldId] = vertexData.getInt16(offset + fieldOffsets[fieldId], true);\n            } else if (fieldType === FieldSizeIdUShort) {\n                rawVertex[fieldId] = vertexData.getUint16(offset + fieldOffsets[fieldId], true);\n            } else if (fieldType === FieldSizeIdInt) {\n                rawVertex[fieldId] = vertexData.getInt32(offset + fieldOffsets[fieldId], true);\n            } else if (fieldType === FieldSizeIdUInt) {\n                rawVertex[fieldId] = vertexData.getUint32(offset + fieldOffsets[fieldId], true);\n            } else if (fieldType === FieldSizeIdUChar) {\n                if (normalize) {\n                    rawVertex[fieldId] = vertexData.getUint8(offset + fieldOffsets[fieldId]) / 255.0;\n                } else {\n                    rawVertex[fieldId] = vertexData.getUint8(offset + fieldOffsets[fieldId]);\n                }\n            }\n        }\n    }\n}\n","import * as THREE from 'three';\nimport { clamp } from '../../Util.js';\nimport { UncompressedSplatArray } from '../UncompressedSplatArray.js';\nimport { SplatBuffer } from '../SplatBuffer.js';\nimport { PlyParserUtils } from './PlyParserUtils.js';\n\nconst BaseFieldNamesToRead = ['scale_0', 'scale_1', 'scale_2', 'rot_0', 'rot_1', 'rot_2', 'rot_3', 'x', 'y', 'z',\n                              'f_dc_0', 'f_dc_1', 'f_dc_2', 'opacity', 'red', 'green', 'blue', 'f_rest_0'];\n\nconst BaseFieldsToReadIndexes = BaseFieldNamesToRead.map((e, i) => i);\n\nconst [\n        SCALE_0, SCALE_1, SCALE_2, ROT_0, ROT_1, ROT_2, ROT_3, X, Y, Z, F_DC_0, F_DC_1, F_DC_2, OPACITY, RED, GREEN, BLUE, F_REST_0\n      ] = BaseFieldsToReadIndexes;\n\nexport class INRIAV1PlyParser {\n\n    static decodeHeaderLines(headerLines) {\n\n        let shLineCount = 0;\n        headerLines.forEach((line) => {\n            if (line.includes('f_rest_')) shLineCount++;\n        });\n\n        let shFieldsToReadCount = 0;\n        if (shLineCount >= 45) {\n            shFieldsToReadCount = 45;\n        } else if (shLineCount >= 24) {\n            shFieldsToReadCount = 24;\n        } else if (shLineCount >= 9) {\n            shFieldsToReadCount = 9;\n        }\n\n        const shFieldIndexesToMap = Array.from(Array(Math.max(shFieldsToReadCount - 1, 0)));\n        let shRemainingFieldNamesToRead = shFieldIndexesToMap.map((element, index) => `f_rest_${index + 1}`);\n\n        const fieldNamesToRead = [...BaseFieldNamesToRead, ...shRemainingFieldNamesToRead];\n        const fieldsToReadIndexes = fieldNamesToRead.map((e, i) => i);\n\n        const fieldNameIdMap = fieldsToReadIndexes.reduce((acc, element) => {\n            acc[fieldNamesToRead[element]] = element;\n            return acc;\n        }, {});\n        const header = PlyParserUtils.decodeSectionHeader(headerLines, fieldNameIdMap, 0);\n        header.splatCount = header.vertexCount;\n        header.bytesPerSplat = header.bytesPerVertex;\n        header.fieldsToReadIndexes = fieldsToReadIndexes;\n        return header;\n    }\n\n    static decodeHeaderText(headerText) {\n        const headerLines = PlyParserUtils.convertHeaderTextToLines(headerText);\n        const header = INRIAV1PlyParser.decodeHeaderLines(headerLines);\n        header.headerText = headerText;\n        header.headerSizeBytes = headerText.indexOf(PlyParserUtils.HeaderEndToken) + PlyParserUtils.HeaderEndToken.length + 1;\n        return header;\n    }\n\n    static decodeHeaderFromBuffer(plyBuffer) {\n        const headerText = PlyParserUtils.readHeaderFromBuffer(plyBuffer);\n        return INRIAV1PlyParser.decodeHeaderText(headerText);\n    }\n\n    static findSplatData(plyBuffer, header) {\n        return new DataView(plyBuffer, header.headerSizeBytes);\n    }\n\n    static parseToUncompressedSplatBufferSection(header, fromSplat, toSplat, splatData, splatDataOffset,\n                                                 toBuffer, toOffset, outSphericalHarmonicsDegree = 0) {\n        outSphericalHarmonicsDegree = Math.min(outSphericalHarmonicsDegree, header.sphericalHarmonicsDegree);\n        const outBytesPerSplat = SplatBuffer.CompressionLevels[0].SphericalHarmonicsDegrees[outSphericalHarmonicsDegree].BytesPerSplat;\n\n        for (let i = fromSplat; i <= toSplat; i++) {\n            const parsedSplat = INRIAV1PlyParser.parseToUncompressedSplat(splatData, i, header,\n                                                                          splatDataOffset, outSphericalHarmonicsDegree);\n            const outBase = i * outBytesPerSplat + toOffset;\n            SplatBuffer.writeSplatDataToSectionBuffer(parsedSplat, toBuffer, outBase, 0, outSphericalHarmonicsDegree);\n        }\n    }\n\n    static parseToUncompressedSplatArraySection(header, fromSplat, toSplat, splatData, splatDataOffset,\n                                         splatArray, outSphericalHarmonicsDegree = 0) {\n        outSphericalHarmonicsDegree = Math.min(outSphericalHarmonicsDegree, header.sphericalHarmonicsDegree);\n        for (let i = fromSplat; i <= toSplat; i++) {\n            const parsedSplat = INRIAV1PlyParser.parseToUncompressedSplat(splatData, i, header,\n                                                                          splatDataOffset, outSphericalHarmonicsDegree);\n            splatArray.addSplat(parsedSplat);\n        }\n    }\n\n    static decodeSectionSplatData(sectionSplatData, splatCount, sectionHeader, outSphericalHarmonicsDegree, toSplatArray = true) {\n        outSphericalHarmonicsDegree = Math.min(outSphericalHarmonicsDegree, sectionHeader.sphericalHarmonicsDegree);\n        if (toSplatArray) {\n            const splatArray = new UncompressedSplatArray(outSphericalHarmonicsDegree);\n            for (let row = 0; row < splatCount; row++) {\n                const newSplat = INRIAV1PlyParser.parseToUncompressedSplat(sectionSplatData, row, sectionHeader,\n                                                                           0, outSphericalHarmonicsDegree);\n                splatArray.addSplat(newSplat);\n            }\n            return splatArray;\n        } else {\n            const {\n                splatBuffer,\n                splatBufferDataOffsetBytes\n              } = SplatBuffer.preallocateUncompressed(splatCount, outSphericalHarmonicsDegree);\n            INRIAV1PlyParser.parseToUncompressedSplatBufferSection(\n                sectionHeader, 0, splatCount - 1, sectionSplatData, 0,\n                splatBuffer.bufferData, splatBufferDataOffsetBytes, outSphericalHarmonicsDegree\n            );\n            return splatBuffer;\n        }\n    }\n\n    static parseToUncompressedSplat = function() {\n\n        let rawSplat = [];\n        const tempRotation = new THREE.Quaternion();\n\n        const OFFSET_X = UncompressedSplatArray.OFFSET.X;\n        const OFFSET_Y = UncompressedSplatArray.OFFSET.Y;\n        const OFFSET_Z = UncompressedSplatArray.OFFSET.Z;\n\n        const OFFSET_SCALE0 = UncompressedSplatArray.OFFSET.SCALE0;\n        const OFFSET_SCALE1 = UncompressedSplatArray.OFFSET.SCALE1;\n        const OFFSET_SCALE2 = UncompressedSplatArray.OFFSET.SCALE2;\n\n        const OFFSET_ROTATION0 = UncompressedSplatArray.OFFSET.ROTATION0;\n        const OFFSET_ROTATION1 = UncompressedSplatArray.OFFSET.ROTATION1;\n        const OFFSET_ROTATION2 = UncompressedSplatArray.OFFSET.ROTATION2;\n        const OFFSET_ROTATION3 = UncompressedSplatArray.OFFSET.ROTATION3;\n\n        const OFFSET_FDC0 = UncompressedSplatArray.OFFSET.FDC0;\n        const OFFSET_FDC1 = UncompressedSplatArray.OFFSET.FDC1;\n        const OFFSET_FDC2 = UncompressedSplatArray.OFFSET.FDC2;\n        const OFFSET_OPACITY = UncompressedSplatArray.OFFSET.OPACITY;\n\n        const OFFSET_FRC = [];\n\n        for (let i = 0; i < 45; i++) {\n            OFFSET_FRC[i] = UncompressedSplatArray.OFFSET.FRC0 + i;\n        }\n\n        return function(splatData, row, header, splatDataOffset = 0, outSphericalHarmonicsDegree = 0) {\n            outSphericalHarmonicsDegree = Math.min(outSphericalHarmonicsDegree, header.sphericalHarmonicsDegree);\n            INRIAV1PlyParser.readSplat(splatData, header, row, splatDataOffset, rawSplat);\n            const newSplat = UncompressedSplatArray.createSplat(outSphericalHarmonicsDegree);\n            if (rawSplat[SCALE_0] !== undefined) {\n                newSplat[OFFSET_SCALE0] = Math.exp(rawSplat[SCALE_0]);\n                newSplat[OFFSET_SCALE1] = Math.exp(rawSplat[SCALE_1]);\n                newSplat[OFFSET_SCALE2] = Math.exp(rawSplat[SCALE_2]);\n            } else {\n                newSplat[OFFSET_SCALE0] = 0.01;\n                newSplat[OFFSET_SCALE1] = 0.01;\n                newSplat[OFFSET_SCALE2] = 0.01;\n            }\n\n            if (rawSplat[F_DC_0] !== undefined) {\n                const SH_C0 = 0.28209479177387814;\n                newSplat[OFFSET_FDC0] = (0.5 + SH_C0 * rawSplat[F_DC_0]) * 255;\n                newSplat[OFFSET_FDC1] = (0.5 + SH_C0 * rawSplat[F_DC_1]) * 255;\n                newSplat[OFFSET_FDC2] = (0.5 + SH_C0 * rawSplat[F_DC_2]) * 255;\n            } else if (rawSplat[RED] !== undefined) {\n                newSplat[OFFSET_FDC0] = rawSplat[RED] * 255;\n                newSplat[OFFSET_FDC1] = rawSplat[GREEN] * 255;\n                newSplat[OFFSET_FDC2] = rawSplat[BLUE] * 255;\n            } else {\n                newSplat[OFFSET_FDC0] = 0;\n                newSplat[OFFSET_FDC1] = 0;\n                newSplat[OFFSET_FDC2] = 0;\n            }\n\n            if (rawSplat[OPACITY] !== undefined) {\n                newSplat[OFFSET_OPACITY] = (1 / (1 + Math.exp(-rawSplat[OPACITY]))) * 255;\n            }\n\n            newSplat[OFFSET_FDC0] = clamp(Math.floor(newSplat[OFFSET_FDC0]), 0, 255);\n            newSplat[OFFSET_FDC1] = clamp(Math.floor(newSplat[OFFSET_FDC1]), 0, 255);\n            newSplat[OFFSET_FDC2] = clamp(Math.floor(newSplat[OFFSET_FDC2]), 0, 255);\n            newSplat[OFFSET_OPACITY] = clamp(Math.floor(newSplat[OFFSET_OPACITY]), 0, 255);\n\n            if (outSphericalHarmonicsDegree >= 1) {\n                if (rawSplat[F_REST_0] !== undefined) {\n                    for (let i = 0; i < 9; i++) {\n                        newSplat[OFFSET_FRC[i]] = rawSplat[header.sphericalHarmonicsDegree1Fields[i]];\n                    }\n                    if (outSphericalHarmonicsDegree >= 2) {\n                        for (let i = 0; i < 15; i++) {\n                            newSplat[OFFSET_FRC[9 + i]] = rawSplat[header.sphericalHarmonicsDegree2Fields[i]];\n                        }\n                    }\n                }\n            }\n\n            tempRotation.set(rawSplat[ROT_0], rawSplat[ROT_1], rawSplat[ROT_2], rawSplat[ROT_3]);\n            tempRotation.normalize();\n\n            newSplat[OFFSET_ROTATION0] = tempRotation.x;\n            newSplat[OFFSET_ROTATION1] = tempRotation.y;\n            newSplat[OFFSET_ROTATION2] = tempRotation.z;\n            newSplat[OFFSET_ROTATION3] = tempRotation.w;\n\n            newSplat[OFFSET_X] = rawSplat[X];\n            newSplat[OFFSET_Y] = rawSplat[Y];\n            newSplat[OFFSET_Z] = rawSplat[Z];\n\n            return newSplat;\n        };\n\n    }();\n\n    static readSplat(splatData, header, row, dataOffset, rawSplat) {\n        return PlyParserUtils.readVertex(splatData, header, row, dataOffset, header.fieldsToReadIndexes, rawSplat, true);\n    }\n\n    static parseToUncompressedSplatArray(plyBuffer, outSphericalHarmonicsDegree = 0) {\n        const { header, splatCount, splatData } = separatePlyHeaderAndData(plyBuffer);\n        return INRIAV1PlyParser.decodeSectionSplatData(splatData, splatCount, header, outSphericalHarmonicsDegree, true);\n    }\n\n    static parseToUncompressedSplatBuffer(plyBuffer, outSphericalHarmonicsDegree = 0) {\n        const { header, splatCount, splatData } = separatePlyHeaderAndData(plyBuffer);\n        return INRIAV1PlyParser.decodeSectionSplatData(splatData, splatCount, header, outSphericalHarmonicsDegree, false);\n    }\n}\n\nfunction separatePlyHeaderAndData(plyBuffer) {\n    const header = INRIAV1PlyParser.decodeHeaderFromBuffer(plyBuffer);\n    const splatCount = header.splatCount;\n    const splatData = INRIAV1PlyParser.findSplatData(plyBuffer, header);\n    return {\n        header,\n        splatCount,\n        splatData\n    };\n}\n","import * as THREE from 'three';\nimport { PlyParserUtils } from './PlyParserUtils.js';\nimport { UncompressedSplatArray } from '../UncompressedSplatArray.js';\nimport { clamp } from '../../Util.js';\n\nconst CodeBookEntryNamesToRead = [\n    'features_dc', 'features_rest_0', 'features_rest_1', 'features_rest_2', 'features_rest_3', 'features_rest_4', 'features_rest_5',\n    'features_rest_6', 'features_rest_7', 'features_rest_8', 'features_rest_9', 'features_rest_10', 'features_rest_11', 'features_rest_12',\n    'features_rest_13', 'features_rest_14', 'opacity', 'scaling', 'rotation_re', 'rotation_im'\n];\nconst CodeBookEntriesToReadIndexes = CodeBookEntryNamesToRead.map((e, i) => i);\n\nconst [\n        CB_FEATURES_DC, CB_FEATURES_REST_0, CB_FEATURES_REST_3, CB_OPACITY, CB_SCALING, CB_ROTATION_RE, CB_ROTATION_IM\n      ] = [0, 1, 4, 16, 17, 18, 19];\n\nconst FieldNamesToRead = ['scale_0', 'scale_1', 'scale_2', 'rot_0', 'rot_1', 'rot_2', 'rot_3',\n                          'x', 'y', 'z', 'f_dc_0', 'f_dc_1', 'f_dc_2', 'opacity', 'red', 'green', 'blue',\n                          'f_rest_0', 'f_rest_1', 'f_rest_2', 'f_rest_3', 'f_rest_4', 'f_rest_5', 'f_rest_6', 'f_rest_7', 'f_rest_8',\n                          'f_rest_9', 'f_rest_10', 'f_rest_11', 'f_rest_12', 'f_rest_13', 'f_rest_14', 'f_rest_15', 'f_rest_16',\n                          'f_rest_17', 'f_rest_18', 'f_rest_19', 'f_rest_20', 'f_rest_21', 'f_rest_22', 'f_rest_23', 'f_rest_24',\n                          'f_rest_25', 'f_rest_26', 'f_rest_27', 'f_rest_28', 'f_rest_29', 'f_rest_30', 'f_rest_31', 'f_rest_32',\n                          'f_rest_33', 'f_rest_34', 'f_rest_35', 'f_rest_36', 'f_rest_37', 'f_rest_38', 'f_rest_39', 'f_rest_40',\n                          'f_rest_41', 'f_rest_42', 'f_rest_43', 'f_rest_44', 'f_rest_45'\n                         ];\nconst FieldsToReadIndexes = FieldNamesToRead.map((e, i) => i);\n\nconst [\n        PLY_SCALE_0, PLY_SCALE_1, PLY_SCALE_2, PLY_ROT_0, PLY_ROT_1, PLY_ROT_2, PLY_ROT_3, PLY_X, PLY_Y, PLY_Z,\n        PLY_F_DC_0, PLY_F_DC_1, PLY_F_DC_2, PLY_OPACITY,\n      ] = FieldsToReadIndexes;\n\nconst PLY_RED = PLY_F_DC_0;\nconst PLY_GREEN = PLY_F_DC_1;\nconst PLY_BLUE = PLY_F_DC_2;\n\nconst fromHalfFloat = (hf) =>{\n    const t = (31744 & hf) >> 10;\n    const a = 1023 & hf;\n    return (hf >> 15 ? -1 : 1)*(t ? t === 31 ? a ? NaN : 1/0 : Math.pow(2, t - 15) *( 1 + a / 1024) : a / 1024*6103515625e-14);\n};\n\nexport class INRIAV2PlyParser {\n\n    static decodeSectionHeadersFromHeaderLines(headerLines) {\n        const fieldNameIdMap = FieldsToReadIndexes.reduce((acc, element) => {\n            acc[FieldNamesToRead[element]] = element;\n            return acc;\n        }, {});\n\n        const codeBookEntriesToReadIdMap = CodeBookEntriesToReadIndexes.reduce((acc, element) => {\n            acc[CodeBookEntryNamesToRead[element]] = element;\n            return acc;\n        }, {});\n\n        const sectionNames = PlyParserUtils.getHeaderSectionNames(headerLines);\n        let codeBookSectionIndex;\n        for (let s = 0; s < sectionNames.length; s++) {\n            const sectionName = sectionNames[s];\n            if (sectionName === 'codebook_centers') {\n                codeBookSectionIndex = s;\n            }\n        }\n\n        let currentStartLine = 0;\n        let lastSectionFound = false;\n        const sectionHeaders = [];\n        let sectionIndex = 0;\n        while (!lastSectionFound) {\n            let sectionHeader;\n            if (sectionIndex === codeBookSectionIndex) {\n                sectionHeader = PlyParserUtils.decodeSectionHeader(headerLines, codeBookEntriesToReadIdMap, currentStartLine);\n            } else {\n                sectionHeader = PlyParserUtils.decodeSectionHeader(headerLines, fieldNameIdMap, currentStartLine);\n            }\n            lastSectionFound = sectionHeader.endOfHeader;\n            currentStartLine = sectionHeader.headerEndLine + 1;\n            if (!lastSectionFound) {\n                sectionHeader.splatCount = sectionHeader.vertexCount;\n                sectionHeader.bytesPerSplat = sectionHeader.bytesPerVertex;\n            }\n            sectionHeaders.push(sectionHeader);\n            sectionIndex++;\n        }\n        return sectionHeaders;\n    }\n\n    static decodeSectionHeadersFromHeaderText(headerText) {\n        const headerLines = PlyParserUtils.convertHeaderTextToLines(headerText);\n        return INRIAV2PlyParser.decodeSectionHeadersFromHeaderLines(headerLines);\n    }\n\n    static getSplatCountFromSectionHeaders(sectionHeaders) {\n        let splatCount = 0;\n        for (let sectionHeader of sectionHeaders) {\n            if (sectionHeader.sectionName !== 'codebook_centers') {\n                splatCount += sectionHeader.vertexCount;\n            }\n        }\n        return splatCount;\n    }\n\n    static decodeHeaderFromHeaderText(headerText) {\n        const headerSizeBytes = headerText.indexOf(PlyParserUtils.HeaderEndToken) + PlyParserUtils.HeaderEndToken.length + 1;\n        const sectionHeaders = INRIAV2PlyParser.decodeSectionHeadersFromHeaderText(headerText);\n        const splatCount = INRIAV2PlyParser.getSplatCountFromSectionHeaders(sectionHeaders);\n        return {\n            'headerSizeBytes': headerSizeBytes,\n            'sectionHeaders': sectionHeaders,\n            'splatCount': splatCount\n        };\n    }\n\n    static decodeHeaderFromBuffer(plyBuffer) {\n        const headerText = PlyParserUtils.readHeaderFromBuffer(plyBuffer);\n        return INRIAV2PlyParser.decodeHeaderFromHeaderText(headerText);\n    }\n\n    static findVertexData(plyBuffer, header, targetSection) {\n        let byteOffset = header.headerSizeBytes;\n        for (let s = 0; s < targetSection && s < header.sectionHeaders.length; s++) {\n            const sectionHeader = header.sectionHeaders[s];\n            byteOffset += sectionHeader.dataSizeBytes;\n        }\n        return new DataView(plyBuffer, byteOffset, header.sectionHeaders[targetSection].dataSizeBytes);\n    }\n\n    static decodeCodeBook(codeBookData, sectionHeader) {\n\n        const rawVertex = [];\n        const codeBook = [];\n        for (let row = 0; row < sectionHeader.vertexCount; row++) {\n            PlyParserUtils.readVertex(codeBookData, sectionHeader, row, 0, CodeBookEntriesToReadIndexes, rawVertex);\n            for (let index of CodeBookEntriesToReadIndexes) {\n                const codeBookElementOffset = CodeBookEntriesToReadIndexes[index];\n                let codeBookPage = codeBook[codeBookElementOffset];\n                if (!codeBookPage) {\n                    codeBook[codeBookElementOffset] = codeBookPage = [];\n                }\n                codeBookPage.push(rawVertex[index]);\n            }\n        }\n        for (let page = 0; page < codeBook.length; page++) {\n            const codeBookPage = codeBook[page];\n            const SH_C0 = 0.28209479177387814;\n            for (let i = 0; i < codeBookPage.length; i++) {\n               const baseValue = fromHalfFloat(codeBookPage[i]);\n                if (page === CB_OPACITY) {\n                    codeBookPage[i] = Math.round((1 / (1 + Math.exp(-baseValue))) * 255);\n                } else if (page === CB_FEATURES_DC) {\n                    codeBookPage[i] = Math.round((0.5 + SH_C0 * baseValue) * 255);\n                } else if (page === CB_SCALING) {\n                    codeBookPage[i] = Math.exp(baseValue);\n                } else {\n                    codeBookPage[i] = baseValue;\n                }\n            }\n        }\n        return codeBook;\n    }\n\n    static decodeSectionSplatData(sectionSplatData, splatCount, sectionHeader, codeBook, outSphericalHarmonicsDegree) {\n        outSphericalHarmonicsDegree = Math.min(outSphericalHarmonicsDegree, sectionHeader.sphericalHarmonicsDegree);\n        const splatArray = new UncompressedSplatArray(outSphericalHarmonicsDegree);\n        for (let row = 0; row < splatCount; row++) {\n            const newSplat = INRIAV2PlyParser.parseToUncompressedSplat(sectionSplatData, row, sectionHeader, codeBook,\n                                                                       0, outSphericalHarmonicsDegree);\n            splatArray.addSplat(newSplat);\n        }\n        return splatArray;\n    }\n\n    static parseToUncompressedSplat = function() {\n\n        let rawSplat = [];\n        const tempRotation = new THREE.Quaternion();\n\n        const OFFSET_X = UncompressedSplatArray.OFFSET.X;\n        const OFFSET_Y = UncompressedSplatArray.OFFSET.Y;\n        const OFFSET_Z = UncompressedSplatArray.OFFSET.Z;\n\n        const OFFSET_SCALE0 = UncompressedSplatArray.OFFSET.SCALE0;\n        const OFFSET_SCALE1 = UncompressedSplatArray.OFFSET.SCALE1;\n        const OFFSET_SCALE2 = UncompressedSplatArray.OFFSET.SCALE2;\n\n        const OFFSET_ROTATION0 = UncompressedSplatArray.OFFSET.ROTATION0;\n        const OFFSET_ROTATION1 = UncompressedSplatArray.OFFSET.ROTATION1;\n        const OFFSET_ROTATION2 = UncompressedSplatArray.OFFSET.ROTATION2;\n        const OFFSET_ROTATION3 = UncompressedSplatArray.OFFSET.ROTATION3;\n\n        const OFFSET_FDC0 = UncompressedSplatArray.OFFSET.FDC0;\n        const OFFSET_FDC1 = UncompressedSplatArray.OFFSET.FDC1;\n        const OFFSET_FDC2 = UncompressedSplatArray.OFFSET.FDC2;\n        const OFFSET_OPACITY = UncompressedSplatArray.OFFSET.OPACITY;\n\n        const OFFSET_FRC = [];\n\n        for (let i = 0; i < 45; i++) {\n            OFFSET_FRC[i] = UncompressedSplatArray.OFFSET.FRC0 + i;\n        }\n\n        return function(splatData, row, header, codeBook, splatDataOffset = 0, outSphericalHarmonicsDegree = 0) {\n            outSphericalHarmonicsDegree = Math.min(outSphericalHarmonicsDegree, header.sphericalHarmonicsDegree);\n            INRIAV2PlyParser.readSplat(splatData, header, row, splatDataOffset, rawSplat);\n            const newSplat = UncompressedSplatArray.createSplat(outSphericalHarmonicsDegree);\n            if (rawSplat[PLY_SCALE_0] !== undefined) {\n                newSplat[OFFSET_SCALE0] = codeBook[CB_SCALING][rawSplat[PLY_SCALE_0]];\n                newSplat[OFFSET_SCALE1] = codeBook[CB_SCALING][rawSplat[PLY_SCALE_1]];\n                newSplat[OFFSET_SCALE2] = codeBook[CB_SCALING][rawSplat[PLY_SCALE_2]];\n            } else {\n                newSplat[OFFSET_SCALE0] = 0.01;\n                newSplat[OFFSET_SCALE1] = 0.01;\n                newSplat[OFFSET_SCALE2] = 0.01;\n            }\n\n            if (rawSplat[PLY_F_DC_0] !== undefined) {\n                newSplat[OFFSET_FDC0] = codeBook[CB_FEATURES_DC][rawSplat[PLY_F_DC_0]];\n                newSplat[OFFSET_FDC1] = codeBook[CB_FEATURES_DC][rawSplat[PLY_F_DC_1]];\n                newSplat[OFFSET_FDC2] = codeBook[CB_FEATURES_DC][rawSplat[PLY_F_DC_2]];\n            } else if (rawSplat[PLY_RED] !== undefined) {\n                newSplat[OFFSET_FDC0] = rawSplat[PLY_RED] * 255;\n                newSplat[OFFSET_FDC1] = rawSplat[PLY_GREEN] * 255;\n                newSplat[OFFSET_FDC2] = rawSplat[PLY_BLUE] * 255;\n            } else {\n                newSplat[OFFSET_FDC0] = 0;\n                newSplat[OFFSET_FDC1] = 0;\n                newSplat[OFFSET_FDC2] = 0;\n            }\n\n            if (rawSplat[PLY_OPACITY] !== undefined) {\n                newSplat[OFFSET_OPACITY] = codeBook[CB_OPACITY][rawSplat[PLY_OPACITY]];\n            }\n\n            newSplat[OFFSET_FDC0] = clamp(Math.floor(newSplat[OFFSET_FDC0]), 0, 255);\n            newSplat[OFFSET_FDC1] = clamp(Math.floor(newSplat[OFFSET_FDC1]), 0, 255);\n            newSplat[OFFSET_FDC2] = clamp(Math.floor(newSplat[OFFSET_FDC2]), 0, 255);\n            newSplat[OFFSET_OPACITY] = clamp(Math.floor(newSplat[OFFSET_OPACITY]), 0, 255);\n\n            if (outSphericalHarmonicsDegree >= 1 && header.sphericalHarmonicsDegree >= 1) {\n                for (let i = 0; i < 9; i++) {\n                    const codeBookPage = codeBook[CB_FEATURES_REST_0 + i % 3];\n                    newSplat[OFFSET_FRC[i]] = codeBookPage[rawSplat[header.sphericalHarmonicsDegree1Fields[i]]];\n                }\n                if (outSphericalHarmonicsDegree >= 2 && header.sphericalHarmonicsDegree >= 2) {\n                    for (let i = 0; i < 15; i++) {\n                        const codeBookPage = codeBook[CB_FEATURES_REST_3 + i % 5];\n                        newSplat[OFFSET_FRC[9 + i]] = codeBookPage[rawSplat[header.sphericalHarmonicsDegree2Fields[i]]];\n                    }\n                }\n            }\n\n            const rot0 = codeBook[CB_ROTATION_RE][rawSplat[PLY_ROT_0]];\n            const rot1 = codeBook[CB_ROTATION_IM][rawSplat[PLY_ROT_1]];\n            const rot2 = codeBook[CB_ROTATION_IM][rawSplat[PLY_ROT_2]];\n            const rot3 = codeBook[CB_ROTATION_IM][rawSplat[PLY_ROT_3]];\n            tempRotation.set(rot0, rot1, rot2, rot3);\n            tempRotation.normalize();\n\n            newSplat[OFFSET_ROTATION0] = tempRotation.x;\n            newSplat[OFFSET_ROTATION1] = tempRotation.y;\n            newSplat[OFFSET_ROTATION2] = tempRotation.z;\n            newSplat[OFFSET_ROTATION3] = tempRotation.w;\n\n            newSplat[OFFSET_X] = fromHalfFloat(rawSplat[PLY_X]);\n            newSplat[OFFSET_Y] = fromHalfFloat(rawSplat[PLY_Y]);\n            newSplat[OFFSET_Z] = fromHalfFloat(rawSplat[PLY_Z]);\n\n            return newSplat;\n        };\n\n    }();\n\n    static readSplat(splatData, header, row, dataOffset, rawSplat) {\n        return PlyParserUtils.readVertex(splatData, header, row, dataOffset, FieldsToReadIndexes, rawSplat, false);\n    }\n\n    static parseToUncompressedSplatArray(plyBuffer, outSphericalHarmonicsDegree = 0) {\n        const splatArrays = [];\n        const header = INRIAV2PlyParser.decodeHeaderFromBuffer(plyBuffer, outSphericalHarmonicsDegree);\n        let codeBook;\n\n        for (let s = 0; s < header.sectionHeaders.length; s++) {\n            const sectionHeader = header.sectionHeaders[s];\n            if (sectionHeader.sectionName === 'codebook_centers') {\n                const codeBookData = INRIAV2PlyParser.findVertexData(plyBuffer, header, s);\n                codeBook = INRIAV2PlyParser.decodeCodeBook(codeBookData, sectionHeader);\n            }\n        }\n        for (let s = 0; s < header.sectionHeaders.length; s++) {\n            const sectionHeader = header.sectionHeaders[s];\n            if (sectionHeader.sectionName !== 'codebook_centers') {\n                const splatCount = sectionHeader.vertexCount;\n                const vertexData = INRIAV2PlyParser.findVertexData(plyBuffer, header, s);\n                const splatArray = INRIAV2PlyParser.decodeSectionSplatData(vertexData, splatCount, sectionHeader,\n                                                               codeBook, outSphericalHarmonicsDegree);\n                splatArrays.push(splatArray);\n            }\n        }\n\n        const unified = new UncompressedSplatArray(outSphericalHarmonicsDegree);\n        for (let splatArray of splatArrays) {\n            for (let splat of splatArray.splats) {\n                unified.addSplat(splat);\n            }\n        }\n\n        return unified;\n    }\n}\n","import { PlayCanvasCompressedPlyParser } from './PlayCanvasCompressedPlyParser.js';\nimport { INRIAV1PlyParser } from './INRIAV1PlyParser.js';\nimport { INRIAV2PlyParser } from './INRIAV2PlyParser.js';\nimport { PlyParserUtils } from './PlyParserUtils.js';\nimport { PlyFormat } from './PlyFormat.js';\n\nexport class PlyParser {\n\n    static parseToUncompressedSplatArray(plyBuffer, outSphericalHarmonicsDegree = 0) {\n        const plyFormat = PlyParserUtils.determineHeaderFormatFromPlyBuffer(plyBuffer);\n        if (plyFormat === PlyFormat.PlayCanvasCompressed) {\n            return PlayCanvasCompressedPlyParser.parseToUncompressedSplatArray(plyBuffer, outSphericalHarmonicsDegree);\n        } else if (plyFormat === PlyFormat.INRIAV1) {\n            return INRIAV1PlyParser.parseToUncompressedSplatArray(plyBuffer, outSphericalHarmonicsDegree);\n        } else if (plyFormat === PlyFormat.INRIAV2) {\n            return INRIAV2PlyParser.parseToUncompressedSplatArray(plyBuffer, outSphericalHarmonicsDegree);\n        }\n    }\n\n    static parseToUncompressedSplatBuffer(plyBuffer, outSphericalHarmonicsDegree = 0) {\n        const plyFormat = PlyParserUtils.determineHeaderFormatFromPlyBuffer(plyBuffer);\n        if (plyFormat === PlyFormat.PlayCanvasCompressed) {\n            return PlayCanvasCompressedPlyParser.parseToUncompressedSplatBuffer(plyBuffer, outSphericalHarmonicsDegree);\n        } else if (plyFormat === PlyFormat.INRIAV1) {\n            return INRIAV1PlyParser.parseToUncompressedSplatBuffer(plyBuffer, outSphericalHarmonicsDegree);\n        } else if (plyFormat === PlyFormat.INRIAV2) {\n             // TODO: Implement!\n            throw new Error('parseToUncompressedSplatBuffer() is not implemented for INRIA V2 PLY files');\n        }\n    }\n\n}\n","import * as THREE from 'three';\nimport { UncompressedSplatArray } from './UncompressedSplatArray.js';\nimport { SplatBuffer } from './SplatBuffer.js';\n\nexport class SplatPartitioner {\n\n    constructor(sectionCount, sectionFilters, groupingParameters, partitionGenerator) {\n        this.sectionCount = sectionCount;\n        this.sectionFilters = sectionFilters;\n        this.groupingParameters = groupingParameters;\n        this.partitionGenerator = partitionGenerator;\n    }\n\n    partitionUncompressedSplatArray(splatArray) {\n        let groupingParameters;\n        let sectionCount;\n        let sectionFilters;\n        if (this.partitionGenerator) {\n            const results = this.partitionGenerator(splatArray);\n            groupingParameters = results.groupingParameters;\n            sectionCount = results.sectionCount;\n            sectionFilters = results.sectionFilters;\n        } else {\n            groupingParameters = this.groupingParameters;\n            sectionCount = this.sectionCount;\n            sectionFilters = this.sectionFilters;\n        }\n\n        const newArrays = [];\n        for (let s = 0; s < sectionCount; s++) {\n            const sectionSplats = new UncompressedSplatArray(splatArray.sphericalHarmonicsDegree);\n            const sectionFilter = sectionFilters[s];\n            for (let i = 0; i < splatArray.splatCount; i++) {\n                if (sectionFilter(i)) {\n                    sectionSplats.addSplat(splatArray.splats[i]);\n                }\n            }\n            newArrays.push(sectionSplats);\n        }\n        return {\n            splatArrays: newArrays,\n            parameters: groupingParameters\n        };\n    }\n\n    static getStandardPartitioner(partitionSize = 0, sceneCenter = new THREE.Vector3(),\n                                  blockSize = SplatBuffer.BucketBlockSize, bucketSize = SplatBuffer.BucketSize) {\n\n        const partitionGenerator = (splatArray) => {\n\n            const OFFSET_X = UncompressedSplatArray.OFFSET.X;\n            const OFFSET_Y = UncompressedSplatArray.OFFSET.Y;\n            const OFFSET_Z = UncompressedSplatArray.OFFSET.Z;\n\n            if (partitionSize <= 0) partitionSize = splatArray.splatCount;\n\n            const center = new THREE.Vector3();\n            const clampDistance = 0.5;\n            const clampPoint = (point) => {\n                point.x = Math.floor(point.x / clampDistance) * clampDistance;\n                point.y = Math.floor(point.y / clampDistance) * clampDistance;\n                point.z = Math.floor(point.z / clampDistance) * clampDistance;\n            };\n            splatArray.splats.forEach((splat) => {\n                center.set(splat[OFFSET_X], splat[OFFSET_Y], splat[OFFSET_Z]).sub(sceneCenter);\n                clampPoint(center);\n                splat.centerDist = center.lengthSq();\n            });\n            splatArray.splats.sort((a, b) => {\n                let centerADist = a.centerDist;\n                let centerBDist = b.centerDist;\n                if (centerADist > centerBDist) return 1;\n                else return -1;\n            });\n\n            const sectionFilters = [];\n            const groupingParameters = [];\n            partitionSize = Math.min(splatArray.splatCount, partitionSize);\n            const patitionCount = Math.ceil(splatArray.splatCount / partitionSize);\n            let currentStartSplat = 0;\n            for (let i = 0; i < patitionCount; i ++) {\n                let startSplat = currentStartSplat;\n                sectionFilters.push((splatIndex) => {\n                    return splatIndex >= startSplat && splatIndex < startSplat + partitionSize;\n                });\n                groupingParameters.push({\n                    'blocksSize': blockSize,\n                    'bucketSize': bucketSize,\n                });\n                currentStartSplat += partitionSize;\n            }\n            return {\n                'sectionCount': sectionFilters.length,\n                sectionFilters,\n                groupingParameters\n            };\n        };\n        return new SplatPartitioner(undefined, undefined, undefined, partitionGenerator);\n    }\n}\n","import * as THREE from 'three';\nimport { SplatPartitioner } from './SplatPartitioner.js';\nimport { SplatBuffer } from './SplatBuffer.js';\n\nexport class SplatBufferGenerator {\n\n    constructor(splatPartitioner, alphaRemovalThreshold, compressionLevel, sectionSize, sceneCenter, blockSize, bucketSize) {\n        this.splatPartitioner = splatPartitioner;\n        this.alphaRemovalThreshold = alphaRemovalThreshold;\n        this.compressionLevel = compressionLevel;\n        this.sectionSize = sectionSize;\n        this.sceneCenter = sceneCenter ? new THREE.Vector3().copy(sceneCenter) : undefined;\n        this.blockSize = blockSize;\n        this.bucketSize = bucketSize;\n    }\n\n    generateFromUncompressedSplatArray(splatArray) {\n        const partitionResults = this.splatPartitioner.partitionUncompressedSplatArray(splatArray);\n        return SplatBuffer.generateFromUncompressedSplatArrays(partitionResults.splatArrays,\n                                                               this.alphaRemovalThreshold, this.compressionLevel,\n                                                               this.sceneCenter, this.blockSize, this.bucketSize,\n                                                               partitionResults.parameters);\n    }\n\n    static getStandardGenerator(alphaRemovalThreshold = 1, compressionLevel = 1, sectionSize = 0, sceneCenter = new THREE.Vector3(),\n                                blockSize = SplatBuffer.BucketBlockSize, bucketSize = SplatBuffer.BucketSize) {\n        const splatPartitioner = SplatPartitioner.getStandardPartitioner(sectionSize, sceneCenter, blockSize, bucketSize);\n        return new SplatBufferGenerator(splatPartitioner, alphaRemovalThreshold, compressionLevel,\n                                        sectionSize, sceneCenter, blockSize, bucketSize);\n    }\n}\n","export const LoaderStatus = {\n    'Downloading': 0,\n    'Processing': 1,\n    'Done': 2\n};\n","export class DirectLoadError extends Error {\n\n    constructor(msg) {\n        super(msg);\n    }\n\n}\n","export const InternalLoadType = {\n    ProgressiveToSplatBuffer: 0,\n    ProgressiveToSplatArray: 1,\n    DownloadBeforeProcessing: 2\n};\n","import * as THREE from 'three';\nimport { PlyParser } from './PlyParser.js';\nimport { PlyParserUtils } from './PlyParserUtils.js';\nimport { INRIAV1PlyParser } from './INRIAV1PlyParser.js';\nimport { PlayCanvasCompressedPlyParser } from './PlayCanvasCompressedPlyParser.js';\nimport { PlyFormat } from './PlyFormat.js';\nimport { fetchWithProgress, delayedExecute, nativePromiseWithExtractedComponents } from '../../Util.js';\nimport { SplatBuffer } from '../SplatBuffer.js';\nimport { SplatBufferGenerator } from '../SplatBufferGenerator.js';\nimport { LoaderStatus } from '../LoaderStatus.js';\nimport { DirectLoadError } from '../DirectLoadError.js';\nimport { Constants } from '../../Constants.js';\nimport { UncompressedSplatArray } from '../UncompressedSplatArray.js';\nimport { InternalLoadType } from '../InternalLoadType.js';\n\nfunction storeChunksInBuffer(chunks, buffer) {\n    let inBytes = 0;\n    for (let chunk of chunks) inBytes += chunk.sizeBytes;\n\n    if (!buffer || buffer.byteLength < inBytes) {\n        buffer = new ArrayBuffer(inBytes);\n    }\n\n    let offset = 0;\n    for (let chunk of chunks) {\n        new Uint8Array(buffer, offset, chunk.sizeBytes).set(chunk.data);\n        offset += chunk.sizeBytes;\n    }\n\n    return buffer;\n}\n\nfunction finalize(splatData, optimizeSplatData, minimumAlpha, compressionLevel, sectionSize, sceneCenter, blockSize, bucketSize) {\n    if (optimizeSplatData) {\n        const splatBufferGenerator = SplatBufferGenerator.getStandardGenerator(minimumAlpha, compressionLevel,\n                                                                               sectionSize, sceneCenter,\n                                                                               blockSize, bucketSize);\n        return splatBufferGenerator.generateFromUncompressedSplatArray(splatData);\n    } else {\n        return SplatBuffer.generateFromUncompressedSplatArrays([splatData], minimumAlpha, 0, new THREE.Vector3());\n    }\n}\n\nexport class PlyLoader {\n\n    static loadFromURL(fileName, onProgress, progressiveLoadToSplatBuffer, onProgressiveLoadSectionProgress,\n                       minimumAlpha, compressionLevel, optimizeSplatData = true, outSphericalHarmonicsDegree = 0,\n                       headers, sectionSize, sceneCenter, blockSize, bucketSize) {\n\n        let internalLoadType;\n        if (!progressiveLoadToSplatBuffer && !optimizeSplatData) {\n            internalLoadType = InternalLoadType.DownloadBeforeProcessing;\n        } else {\n            if (optimizeSplatData) internalLoadType = InternalLoadType.ProgressiveToSplatArray;\n            else internalLoadType = InternalLoadType.ProgressiveToSplatBuffer;\n        }\n\n        const directLoadSectionSizeBytes = Constants.ProgressiveLoadSectionSize;\n        const splatBufferDataOffsetBytes = SplatBuffer.HeaderSizeBytes + SplatBuffer.SectionHeaderSizeBytes;\n        const sectionCount = 1;\n\n        let plyFormat;\n        let directLoadBufferIn;\n        let directLoadBufferOut;\n        let directLoadSplatBuffer;\n        let compressedPlyHeaderChunksBuffer;\n        let maxSplatCount = 0;\n        let processedBaseSplatCount = 0;\n        let processedSphericalHarmonicsSplatCount = 0;\n\n        let headerLoaded = false;\n        let readyToLoadSplatData = false;\n        let baseSplatDataLoaded = false;\n\n        const loadPromise = nativePromiseWithExtractedComponents();\n\n        let numBytesStreamed = 0;\n        let numBytesParsed = 0;\n        let numBytesDownloaded = 0;\n        let endOfBaseSplatDataBytes = 0;\n        let headerText = '';\n        let header = null;\n        let chunks = [];\n\n        let standardLoadUncompressedSplatArray;\n\n        const textDecoder = new TextDecoder();\n\n        const localOnProgress = (percent, percentLabel, chunkData) => {\n            const loadComplete = percent >= 100;\n\n            if (chunkData) {\n                chunks.push({\n                    'data': chunkData,\n                    'sizeBytes': chunkData.byteLength,\n                    'startBytes': numBytesDownloaded,\n                    'endBytes': numBytesDownloaded + chunkData.byteLength\n                });\n                numBytesDownloaded += chunkData.byteLength;\n            }\n\n            if (internalLoadType === InternalLoadType.DownloadBeforeProcessing) {\n                if (loadComplete) {\n                    loadPromise.resolve(chunks);\n                }\n            } else {\n                if (!headerLoaded) {\n                    headerText += textDecoder.decode(chunkData);\n                    if (PlyParserUtils.checkTextForEndHeader(headerText)) {\n                        plyFormat = PlyParserUtils.determineHeaderFormatFromHeaderText(headerText);\n                        if (plyFormat === PlyFormat.INRIAV1) {\n                            header = INRIAV1PlyParser.decodeHeaderText(headerText);\n                            outSphericalHarmonicsDegree = Math.min(outSphericalHarmonicsDegree, header.sphericalHarmonicsDegree);\n                            maxSplatCount = header.splatCount;\n                            readyToLoadSplatData = true;\n                            endOfBaseSplatDataBytes = header.headerSizeBytes + header.bytesPerSplat * maxSplatCount;\n                        } else if (plyFormat === PlyFormat.PlayCanvasCompressed) {\n                            header = PlayCanvasCompressedPlyParser.decodeHeaderText(headerText);\n                            outSphericalHarmonicsDegree = Math.min(outSphericalHarmonicsDegree, header.sphericalHarmonicsDegree);\n                            if (internalLoadType === InternalLoadType.ProgressiveToSplatBuffer && outSphericalHarmonicsDegree > 0) {\n                                throw new DirectLoadError(\n                                    'PlyLoader.loadFromURL() -> Selected PLY format has spherical ' +\n                                    'harmonics data that cannot be progressively loaded.'\n                                );\n                            }\n                            maxSplatCount = header.vertexElement.count;\n                            endOfBaseSplatDataBytes = header.headerSizeBytes + header.bytesPerSplat * maxSplatCount +\n                                                      header.chunkElement.storageSizeBytes;\n                        } else {\n                            if (internalLoadType === InternalLoadType.ProgressiveToSplatBuffer) {\n                                throw new DirectLoadError(\n                                    'PlyLoader.loadFromURL() -> Selected PLY format cannot be progressively loaded.'\n                                );\n                            } else {\n                                internalLoadType = InternalLoadType.DownloadBeforeProcessing;\n                                return;\n                            }\n                        }\n\n                        if (internalLoadType === InternalLoadType.ProgressiveToSplatBuffer) {\n                            const shDescriptor = SplatBuffer.CompressionLevels[0].SphericalHarmonicsDegrees[outSphericalHarmonicsDegree];\n                            const splatBufferSizeBytes = splatBufferDataOffsetBytes + shDescriptor.BytesPerSplat * maxSplatCount;\n                            directLoadBufferOut = new ArrayBuffer(splatBufferSizeBytes);\n                            SplatBuffer.writeHeaderToBuffer({\n                                versionMajor: SplatBuffer.CurrentMajorVersion,\n                                versionMinor: SplatBuffer.CurrentMinorVersion,\n                                maxSectionCount: sectionCount,\n                                sectionCount: sectionCount,\n                                maxSplatCount: maxSplatCount,\n                                splatCount: 0,\n                                compressionLevel: 0,\n                                sceneCenter: new THREE.Vector3()\n                            }, directLoadBufferOut);\n                        } else {\n                            standardLoadUncompressedSplatArray = new UncompressedSplatArray(outSphericalHarmonicsDegree);\n                        }\n\n                        numBytesStreamed = header.headerSizeBytes;\n                        numBytesParsed = header.headerSizeBytes;\n                        headerLoaded = true;\n                    }\n                } else if (plyFormat === PlyFormat.PlayCanvasCompressed && !readyToLoadSplatData) {\n                    const sizeRequiredForHeaderAndChunks = header.headerSizeBytes + header.chunkElement.storageSizeBytes;\n                    compressedPlyHeaderChunksBuffer = storeChunksInBuffer(chunks, compressedPlyHeaderChunksBuffer);\n                    if (compressedPlyHeaderChunksBuffer.byteLength >= sizeRequiredForHeaderAndChunks) {\n                        PlayCanvasCompressedPlyParser.readElementData(header.chunkElement, compressedPlyHeaderChunksBuffer,\n                                                                      header.headerSizeBytes);\n                        numBytesStreamed = sizeRequiredForHeaderAndChunks;\n                        numBytesParsed = sizeRequiredForHeaderAndChunks;\n                        readyToLoadSplatData = true;\n                    }\n                }\n\n                if (headerLoaded && readyToLoadSplatData && chunks.length > 0) {\n\n                    directLoadBufferIn = storeChunksInBuffer(chunks, directLoadBufferIn);\n\n                    const bytesLoadedSinceLastStreamedSection = numBytesDownloaded - numBytesStreamed;\n                    if (bytesLoadedSinceLastStreamedSection > directLoadSectionSizeBytes ||\n                        (numBytesDownloaded >= endOfBaseSplatDataBytes && !baseSplatDataLoaded) ||\n                        loadComplete) {\n                        const bytesPerSplat = baseSplatDataLoaded ? header.sphericalHarmonicsPerSplat : header.bytesPerSplat;\n                        const endOfBytesToProcess = baseSplatDataLoaded ? numBytesDownloaded :\n                                                    Math.min(endOfBaseSplatDataBytes, numBytesDownloaded);\n                        const numBytesToProcess = endOfBytesToProcess - numBytesParsed;\n                        const addedSplatCount = Math.floor(numBytesToProcess / bytesPerSplat);\n                        const numBytesToParse = addedSplatCount * bytesPerSplat;\n                        const numBytesLeftOver = numBytesDownloaded - numBytesParsed - numBytesToParse;\n                        const parsedDataViewOffset = numBytesParsed - chunks[0].startBytes;\n                        const dataToParse = new DataView(directLoadBufferIn, parsedDataViewOffset, numBytesToParse);\n\n                        if (!baseSplatDataLoaded) {\n                            if (internalLoadType === InternalLoadType.ProgressiveToSplatBuffer) {\n                                const shDesc = SplatBuffer.CompressionLevels[0].SphericalHarmonicsDegrees[outSphericalHarmonicsDegree];\n                                const outOffset = processedBaseSplatCount * shDesc.BytesPerSplat + splatBufferDataOffsetBytes;\n                                if (plyFormat === PlyFormat.PlayCanvasCompressed) {\n                                    PlayCanvasCompressedPlyParser.parseToUncompressedSplatBufferSection(\n                                        header.chunkElement, header.vertexElement, 0, addedSplatCount - 1,\n                                        processedBaseSplatCount, dataToParse, directLoadBufferOut, outOffset\n                                    );\n                                } else {\n                                    INRIAV1PlyParser.parseToUncompressedSplatBufferSection(\n                                        header, 0, addedSplatCount - 1, dataToParse, 0,\n                                        directLoadBufferOut, outOffset, outSphericalHarmonicsDegree\n                                    );\n                                }\n                            } else {\n                                if (plyFormat === PlyFormat.PlayCanvasCompressed) {\n                                    PlayCanvasCompressedPlyParser.parseToUncompressedSplatArraySection(\n                                        header.chunkElement, header.vertexElement, 0, addedSplatCount - 1,\n                                        processedBaseSplatCount, dataToParse, standardLoadUncompressedSplatArray\n                                    );\n                                } else {\n                                    INRIAV1PlyParser.parseToUncompressedSplatArraySection(\n                                        header, 0, addedSplatCount - 1, dataToParse, 0,\n                                        standardLoadUncompressedSplatArray, outSphericalHarmonicsDegree\n                                    );\n                                }\n                            }\n\n                            processedBaseSplatCount += addedSplatCount;\n\n                            if (internalLoadType === InternalLoadType.ProgressiveToSplatBuffer) {\n                                if (!directLoadSplatBuffer) {\n                                    SplatBuffer.writeSectionHeaderToBuffer({\n                                        maxSplatCount: maxSplatCount,\n                                        splatCount: processedBaseSplatCount,\n                                        bucketSize: 0,\n                                        bucketCount: 0,\n                                        bucketBlockSize: 0,\n                                        compressionScaleRange: 0,\n                                        storageSizeBytes: 0,\n                                        fullBucketCount: 0,\n                                        partiallyFilledBucketCount: 0,\n                                        sphericalHarmonicsDegree: outSphericalHarmonicsDegree\n                                    }, 0, directLoadBufferOut, SplatBuffer.HeaderSizeBytes);\n                                    directLoadSplatBuffer = new SplatBuffer(directLoadBufferOut, false);\n                                }\n                                directLoadSplatBuffer.updateLoadedCounts(1, processedBaseSplatCount);\n                            }\n                            if (numBytesDownloaded >= endOfBaseSplatDataBytes) {\n                                baseSplatDataLoaded = true;\n                            }\n                        } else {\n                            if (plyFormat === PlyFormat.PlayCanvasCompressed) {\n                                if (internalLoadType === InternalLoadType.ProgressiveToSplatArray) {\n                                    PlayCanvasCompressedPlyParser.parseSphericalHarmonicsToUncompressedSplatArraySection(\n                                        header.chunkElement, header.shElement, processedSphericalHarmonicsSplatCount,\n                                        processedSphericalHarmonicsSplatCount + addedSplatCount - 1,\n                                        dataToParse, 0, outSphericalHarmonicsDegree, header.sphericalHarmonicsDegree,\n                                        standardLoadUncompressedSplatArray\n                                    );\n                                    processedSphericalHarmonicsSplatCount += addedSplatCount;\n                                }\n                            }\n                        }\n\n                        if (numBytesLeftOver === 0) {\n                            chunks = [];\n                        } else {\n                            let keepChunks = [];\n                            let keepSize = 0;\n                            for (let i = chunks.length - 1; i >= 0; i--) {\n                                const chunk = chunks[i];\n                                keepSize += chunk.sizeBytes;\n                                keepChunks.unshift(chunk);\n                                if (keepSize >= numBytesLeftOver) break;\n                            }\n                            chunks = keepChunks;\n                        }\n\n                        numBytesStreamed += directLoadSectionSizeBytes;\n                        numBytesParsed += numBytesToParse;\n                    }\n                }\n\n                if (onProgressiveLoadSectionProgress && directLoadSplatBuffer) {\n                    onProgressiveLoadSectionProgress(directLoadSplatBuffer, loadComplete);\n                }\n\n                if (loadComplete) {\n                    if (internalLoadType === InternalLoadType.ProgressiveToSplatBuffer) {\n                        loadPromise.resolve(directLoadSplatBuffer);\n                    } else {\n                        loadPromise.resolve(standardLoadUncompressedSplatArray);\n                    }\n                }\n            }\n\n            if (onProgress) onProgress(percent, percentLabel, LoaderStatus.Downloading);\n        };\n\n        if (onProgress) onProgress(0, '0%', LoaderStatus.Downloading);\n        return fetchWithProgress(fileName, localOnProgress, false, headers).then(() => {\n            if (onProgress) onProgress(0, '0%', LoaderStatus.Processing);\n            return loadPromise.promise.then((splatData) => {\n                if (onProgress) onProgress(100, '100%', LoaderStatus.Done);\n                if (internalLoadType === InternalLoadType.DownloadBeforeProcessing) {\n                    const chunkDatas = chunks.map((chunk) => chunk.data);\n                    return new Blob(chunkDatas).arrayBuffer().then((plyFileData) => {\n                        return PlyLoader.loadFromFileData(plyFileData, minimumAlpha, compressionLevel, optimizeSplatData,\n                                                          outSphericalHarmonicsDegree, sectionSize, sceneCenter, blockSize, bucketSize);\n                    });\n                } else if (internalLoadType === InternalLoadType.ProgressiveToSplatBuffer) {\n                    return splatData;\n                } else {\n                    return delayedExecute(() => {\n                        return finalize(splatData, optimizeSplatData, minimumAlpha, compressionLevel,\n                                        sectionSize, sceneCenter, blockSize, bucketSize);\n                    });\n                }\n            });\n        });\n    }\n\n    static loadFromFileData(plyFileData, minimumAlpha, compressionLevel, optimizeSplatData, outSphericalHarmonicsDegree = 0,\n                            sectionSize, sceneCenter, blockSize, bucketSize) {\n        if (optimizeSplatData) {\n            return delayedExecute(() => {\n                return PlyParser.parseToUncompressedSplatArray(plyFileData, outSphericalHarmonicsDegree);\n            })\n            .then((splatArray) => {\n                return finalize(splatArray, optimizeSplatData, minimumAlpha, compressionLevel,\n                                sectionSize, sceneCenter, blockSize, bucketSize);\n            });\n        } else {\n            return delayedExecute(() => {\n                return PlyParser.parseToUncompressedSplatBuffer(plyFileData, outSphericalHarmonicsDegree);\n            });\n        }\n    }\n}\n","const createStream = (data)=> {\n    return new ReadableStream({\n        async start(controller) {\n            controller.enqueue(data);\n            controller.close();\n        },\n    });\n};\n\nexport async function decompressGzipped(data) {\n    try {\n        const stream = createStream(data);\n        if (!stream) throw new Error('Failed to create stream from data');\n\n        return await decompressGzipStream(stream);\n    } catch (error) {\n        console.error('Error decompressing gzipped data:', error);\n        throw error;\n    }\n}\n\nexport async function decompressGzipStream(stream) {\n    const decompressedStream = stream.pipeThrough(new DecompressionStream('gzip'));\n    const response = new Response(decompressedStream);\n    const buffer = await response.arrayBuffer();\n\n    return new Uint8Array(buffer);\n}\n\nexport async function compressGzipped(data) {\n    try {\n        const stream = createStream(data);\n        const compressedStream = stream.pipeThrough(new CompressionStream('gzip'));\n        const response = new Response(compressedStream);\n        const buffer = await response.arrayBuffer();\n\n        return new Uint8Array(buffer);\n    } catch (error) {\n        console.error('Error compressing gzipped data:', error);\n        throw error;\n    }\n}\n","import * as THREE from 'three';\nimport { fetchWithProgress, delayedExecute } from '../../Util.js';\nimport { SplatBuffer } from '../SplatBuffer.js';\nimport { SplatBufferGenerator } from '../SplatBufferGenerator.js';\nimport { LoaderStatus } from '../LoaderStatus.js';\nimport { UncompressedSplatArray } from '../UncompressedSplatArray.js';\nimport { decompressGzipped } from '../Compression.js';\nimport { clamp } from '../../Util.js';\n\nconst SPZ_MAGIC = 1347635022;\nconst FLAG_ANTIALIASED = 1;\nconst COLOR_SCALE = 0.15;\n\nfunction halfToFloat(h) {\n    const sgn = (h >> 15) & 0x1;\n    const exponent = (h >> 10) & 0x1f;\n    const mantissa = h & 0x3ff;\n\n    const signMul = sgn === 1 ? -1.0 : 1.0;\n    if (exponent === 0) {\n        return signMul * Math.pow(2, -14) * mantissa / 1024;\n    }\n\n    if (exponent === 31) {\n        return mantissa !== 0 ? NaN : signMul * Infinity;\n    }\n\n    return signMul * Math.pow(2, exponent - 15) * (1 + mantissa / 1024);\n}\n\nfunction unquantizeSH(x) {\n    return (x - 128.0) / 128.0;\n}\n\nfunction dimForDegree(degree) {\n    switch (degree) {\n        case 0: return 0;\n        case 1: return 3;\n        case 2: return 8;\n        case 3: return 15;\n        default:\n            console.error(`[SPZ: ERROR] Unsupported SH degree: ${degree}`);\n            return 0;\n    }\n}\n\nconst unpackedSplatToUncompressedSplat = function() {\n\n    let rawSplat = [];\n    const tempRotation = new THREE.Quaternion();\n\n    const OFFSET_X = UncompressedSplatArray.OFFSET.X;\n    const OFFSET_Y = UncompressedSplatArray.OFFSET.Y;\n    const OFFSET_Z = UncompressedSplatArray.OFFSET.Z;\n\n    const OFFSET_SCALE0 = UncompressedSplatArray.OFFSET.SCALE0;\n    const OFFSET_SCALE1 = UncompressedSplatArray.OFFSET.SCALE1;\n    const OFFSET_SCALE2 = UncompressedSplatArray.OFFSET.SCALE2;\n\n    const OFFSET_ROTATION0 = UncompressedSplatArray.OFFSET.ROTATION0;\n    const OFFSET_ROTATION1 = UncompressedSplatArray.OFFSET.ROTATION1;\n    const OFFSET_ROTATION2 = UncompressedSplatArray.OFFSET.ROTATION2;\n    const OFFSET_ROTATION3 = UncompressedSplatArray.OFFSET.ROTATION3;\n\n    const OFFSET_FDC0 = UncompressedSplatArray.OFFSET.FDC0;\n    const OFFSET_FDC1 = UncompressedSplatArray.OFFSET.FDC1;\n    const OFFSET_FDC2 = UncompressedSplatArray.OFFSET.FDC2;\n    const OFFSET_OPACITY = UncompressedSplatArray.OFFSET.OPACITY;\n\n    const OFFSET_FRC = [];\n\n    for (let i = 0; i < 45; i++) {\n        OFFSET_FRC[i] = UncompressedSplatArray.OFFSET.FRC0 + i;\n    }\n\n    const shCoeffMap = [dimForDegree(0), dimForDegree(1), dimForDegree(2), dimForDegree(3)];\n\n    const shIndexMap = [\n        0, 1, 2, 9, 10, 11, 12, 13, 24, 25, 26, 27, 28, 29, 30,\n        3, 4, 5, 14, 15, 16, 17, 18, 31, 32, 33, 34, 35, 36, 37,\n        6, 7, 8, 19, 20, 21, 22, 23, 38, 39, 40, 41, 42, 43, 44\n    ];\n\n    return function(unpackedSplat, unpackedSphericalHarmonicsDegree, outSphericalHarmonicsDegree) {\n                    outSphericalHarmonicsDegree = Math.min(unpackedSphericalHarmonicsDegree, outSphericalHarmonicsDegree);\n\n        const newSplat = UncompressedSplatArray.createSplat(outSphericalHarmonicsDegree);\n        if (unpackedSplat.scale[0] !== undefined) {\n            newSplat[OFFSET_SCALE0] = unpackedSplat.scale[0];\n            newSplat[OFFSET_SCALE1] = unpackedSplat.scale[1];\n            newSplat[OFFSET_SCALE2] = unpackedSplat.scale[2];\n        } else {\n            newSplat[OFFSET_SCALE0] = 0.01;\n            newSplat[OFFSET_SCALE1] = 0.01;\n            newSplat[OFFSET_SCALE2] = 0.01;\n        }\n\n        if (unpackedSplat.color[0] !== undefined) {\n            newSplat[OFFSET_FDC0] = unpackedSplat.color[0];\n            newSplat[OFFSET_FDC1] = unpackedSplat.color[1];\n            newSplat[OFFSET_FDC2] = unpackedSplat.color[2];\n        } else if (rawSplat[RED] !== undefined) {\n            newSplat[OFFSET_FDC0] = rawSplat[RED] * 255;\n            newSplat[OFFSET_FDC1] = rawSplat[GREEN] * 255;\n            newSplat[OFFSET_FDC2] = rawSplat[BLUE] * 255;\n        } else {\n            newSplat[OFFSET_FDC0] = 0;\n            newSplat[OFFSET_FDC1] = 0;\n            newSplat[OFFSET_FDC2] = 0;\n        }\n\n        if (unpackedSplat.alpha !== undefined) {\n            newSplat[OFFSET_OPACITY] = unpackedSplat.alpha;\n        }\n\n        newSplat[OFFSET_FDC0] = clamp(Math.floor(newSplat[OFFSET_FDC0]), 0, 255);\n        newSplat[OFFSET_FDC1] = clamp(Math.floor(newSplat[OFFSET_FDC1]), 0, 255);\n        newSplat[OFFSET_FDC2] = clamp(Math.floor(newSplat[OFFSET_FDC2]), 0, 255);\n        newSplat[OFFSET_OPACITY] = clamp(Math.floor(newSplat[OFFSET_OPACITY]), 0, 255);\n\n        let outSHCoeff = shCoeffMap[outSphericalHarmonicsDegree];\n        let readSHCoeff = shCoeffMap[unpackedSphericalHarmonicsDegree];\n        for (let j = 0; j < 3; ++j) {\n            for (let k = 0; k < 15; ++k) {\n                const outIndex = shIndexMap[j * 15 + k];\n                if (k < outSHCoeff && k < readSHCoeff) {\n                    newSplat[UncompressedSplatArray.OFFSET.FRC0 + outIndex] = unpackedSplat.sh[j * readSHCoeff + k];\n                }\n            }\n        }\n\n        tempRotation.set(unpackedSplat.rotation[3], unpackedSplat.rotation[0], unpackedSplat.rotation[1], unpackedSplat.rotation[2]);\n        tempRotation.normalize();\n\n        newSplat[OFFSET_ROTATION0] = tempRotation.x;\n        newSplat[OFFSET_ROTATION1] = tempRotation.y;\n        newSplat[OFFSET_ROTATION2] = tempRotation.z;\n        newSplat[OFFSET_ROTATION3] = tempRotation.w;\n\n        newSplat[OFFSET_X] = unpackedSplat.position[0];\n        newSplat[OFFSET_Y] = unpackedSplat.position[1];\n        newSplat[OFFSET_Z] = unpackedSplat.position[2];\n\n        return newSplat;\n    };\n\n}();\n\n// Helper function to check sizes (matching C++ checkSizes function)\nfunction checkSizes2(packed, numPoints, shDim, usesFloat16) {\n    if (packed.positions.length !== numPoints * 3 * (usesFloat16 ? 2 : 3)) return false;\n    if (packed.scales.length !== numPoints * 3) return false;\n    if (packed.rotations.length !== numPoints * 3) return false;\n    if (packed.alphas.length !== numPoints) return false;\n    if (packed.colors.length !== numPoints * 3) return false;\n    if (packed.sh.length !== numPoints * shDim * 3) return false;\n    return true;\n}\n\nfunction unpackGaussians(packed, outSphericalHarmonicsDegree, directToSplatBuffer, outTarget, outTargetOffset) {\n    outSphericalHarmonicsDegree = Math.min(outSphericalHarmonicsDegree, packed.shDegree);\n    const numPoints = packed.numPoints;\n    const shDim = dimForDegree(packed.shDegree);\n    const usesFloat16 = packed.positions.length === numPoints * 3 * 2;\n\n    // Validate sizes\n    if (!checkSizes2(packed, numPoints, shDim, usesFloat16)) {\n        return null;\n    }\n\n    const splat = {\n        position: [],\n        scale: [],\n        rotation: [],\n        alpha: undefined,\n        color: [],\n        sh: []\n    };\n\n    let halfData;\n    if (usesFloat16) {\n       halfData = new Uint16Array(packed.positions.buffer, packed.positions.byteOffset, numPoints * 3);\n    }\n    const fullPrecisionPositionScale = 1.0 / (1 << packed.fractionalBits);\n    const shCoeffPerChannelPerSplat = dimForDegree(packed.shDegree);\n    const SH_C0 = 0.28209479177387814;\n\n    for (let i = 0; i < numPoints; i++) {\n        // Splat position\n        if (usesFloat16) {\n            // Decode legacy float16 format\n            for (let j = 0; j < 3; j++) {\n                splat.position[j] = halfToFloat(halfData[i * 3 + j]);\n            }\n        } else {\n            // Decode 24-bit fixed point coordinates\n            for (let j = 0; j < 3; j++) {\n                const base = i * 9 + j * 3;\n                let fixed32 = packed.positions[base];\n                fixed32 |= packed.positions[base + 1] << 8;\n                fixed32 |= packed.positions[base + 2] << 16;\n                fixed32 |= (fixed32 & 0x800000) ? 0xff000000 : 0;\n                splat.position[j] = fixed32 * fullPrecisionPositionScale;\n            }\n        }\n\n        // Splat scale\n        for (let j = 0; j < 3; j++) {\n            splat.scale[j] = Math.exp(packed.scales[i * 3 + j] / 16.0 - 10.0);\n        }\n\n        // Splat rotation\n        const r = packed.rotations.subarray(i * 3, i * 3 + 3);\n        const xyz = [\n            r[0] / 127.5 - 1.0,\n            r[1] / 127.5 - 1.0,\n            r[2] / 127.5 - 1.0\n        ];\n        splat.rotation[0] = xyz[0];\n        splat.rotation[1] = xyz[1];\n        splat.rotation[2] = xyz[2];\n        const squaredNorm = xyz[0] * xyz[0] + xyz[1] * xyz[1] + xyz[2] * xyz[2];\n        splat.rotation[3] = Math.sqrt(Math.max(0.0, 1.0 - squaredNorm));\n\n        // Splat alpha\n        // splat.alpha = invSigmoid(packed.alphas[i] / 255.0);\n        splat.alpha = Math.floor(packed.alphas[i]);\n\n        // Splat color\n        for (let j = 0; j < 3; j++) {\n            splat.color[j] = Math.floor(((((packed.colors[i * 3 + j] / 255.0) - 0.5) / COLOR_SCALE) * SH_C0 + 0.5) * 255);\n        }\n\n        // Splat spherical harmonics\n        for (let j = 0; j < 3; j++) {\n            for (let k = 0; k < shCoeffPerChannelPerSplat; k++) {\n                splat.sh[j * shCoeffPerChannelPerSplat + k] = unquantizeSH(packed.sh[shCoeffPerChannelPerSplat * 3 * i + k * 3 + j]);\n            }\n        }\n\n        const uncompressedSplat = unpackedSplatToUncompressedSplat(splat, packed.shDegree, outSphericalHarmonicsDegree);\n        if (directToSplatBuffer) {\n            const outBytesPerSplat = SplatBuffer.CompressionLevels[0].SphericalHarmonicsDegrees[outSphericalHarmonicsDegree].BytesPerSplat;\n            const outBase = i * outBytesPerSplat + outTargetOffset;\n            SplatBuffer.writeSplatDataToSectionBuffer(uncompressedSplat, outTarget, outBase, 0, outSphericalHarmonicsDegree);\n        } else {\n            outTarget.addSplat(uncompressedSplat);\n        }\n    }\n}\n\nconst HEADER_SIZE = 16; // 4 + 4 + 4 + 1 + 1 + 1 + 1 bytes\nconst MAX_POINTS_TO_READ = 10000000;\n\nfunction deserializePackedGaussians(buffer) {\n    const view = new DataView(buffer);\n    let offset = 0;\n\n    // Read and validate header\n    const header = {\n        magic: view.getUint32(offset, true),\n        version: view.getUint32(offset + 4, true),\n        numPoints: view.getUint32(offset + 8, true),\n        shDegree: view.getUint8(offset + 12),\n        fractionalBits: view.getUint8(offset + 13),\n        flags: view.getUint8(offset + 14),\n        reserved: view.getUint8(offset + 15)\n    };\n\n    offset += HEADER_SIZE;\n\n    // Validate header\n    if (header.magic !== SPZ_MAGIC) {\n        console.error('[SPZ ERROR] deserializePackedGaussians: header not found');\n        return null;\n    }\n    if (header.version < 1 || header.version > 2) {\n        console.error(`[SPZ ERROR] deserializePackedGaussians: version not supported: ${header.version}`);\n        return null;\n    }\n    if (header.numPoints > MAX_POINTS_TO_READ) {\n        console.error(`[SPZ ERROR] deserializePackedGaussians: Too many points: ${header.numPoints}`);\n        return null;\n    }\n    if (header.shDegree > 3) {\n        console.error(`[SPZ ERROR] deserializePackedGaussians: Unsupported SH degree: ${header.shDegree}`);\n        return null;\n    }\n\n    const numPoints = header.numPoints;\n    const shDim = dimForDegree(header.shDegree);\n    const usesFloat16 = header.version === 1;\n\n    // Initialize result object\n    const result = {\n        numPoints,\n        shDegree: header.shDegree,\n        fractionalBits: header.fractionalBits,\n        antialiased: (header.flags & FLAG_ANTIALIASED) !== 0,\n        positions: new Uint8Array(numPoints * 3 * (usesFloat16 ? 2 : 3)),\n        scales: new Uint8Array(numPoints * 3),\n        rotations: new Uint8Array(numPoints * 3),\n        alphas: new Uint8Array(numPoints),\n        colors: new Uint8Array(numPoints * 3),\n        sh: new Uint8Array(numPoints * shDim * 3)\n    };\n\n    // Read data sections\n    try {\n        const uint8View = new Uint8Array(buffer);\n        let positionsSize = result.positions.length;\n        let currentOffset = offset;\n\n        result.positions.set(uint8View.slice(currentOffset, currentOffset + positionsSize));\n        currentOffset += positionsSize;\n\n        result.alphas.set(uint8View.slice(currentOffset, currentOffset + result.alphas.length));\n        currentOffset += result.alphas.length;\n\n        result.colors.set(uint8View.slice(currentOffset, currentOffset + result.colors.length));\n        currentOffset += result.colors.length;\n\n        result.scales.set(uint8View.slice(currentOffset, currentOffset + result.scales.length));\n        currentOffset += result.scales.length;\n\n        result.rotations.set(uint8View.slice(currentOffset, currentOffset + result.rotations.length));\n        currentOffset += result.rotations.length;\n\n        result.sh.set(uint8View.slice(currentOffset, currentOffset + result.sh.length));\n\n        // Verify we read the expected amount of data\n        if (currentOffset + result.sh.length !== buffer.byteLength) {\n            console.error('[SPZ ERROR] deserializePackedGaussians: incorrect buffer size');\n            return null;\n        }\n    } catch (error) {\n        console.error('[SPZ ERROR] deserializePackedGaussians: read error', error);\n        return null;\n    }\n\n    return result;\n}\n\nasync function loadSpzPacked(compressedData) {\n    try {\n        const decompressed = await decompressGzipped(compressedData);\n        return deserializePackedGaussians(decompressed.buffer);\n    } catch (error) {\n        console.error('[SPZ ERROR] loadSpzPacked: decompression error', error);\n        return null;\n    }\n}\n\nexport class SpzLoader {\n\n    static loadFromURL(fileName, onProgress, minimumAlpha, compressionLevel, optimizeSplatData = true,\n                       outSphericalHarmonicsDegree = 0, headers, sectionSize, sceneCenter, blockSize, bucketSize) {\n        if (onProgress) onProgress(0, '0%', LoaderStatus.Downloading);\n        return fetchWithProgress(fileName, onProgress, true, headers).then((fileData) => {\n            if (onProgress) onProgress(0, '0%', LoaderStatus.Processing);\n            return SpzLoader.loadFromFileData(fileData, minimumAlpha, compressionLevel, optimizeSplatData,\n                                              outSphericalHarmonicsDegree, sectionSize, sceneCenter, blockSize, bucketSize);\n        });\n    }\n\n    static async loadFromFileData(spzFileData, minimumAlpha, compressionLevel, optimizeSplatData,\n                                  outSphericalHarmonicsDegree = 0, sectionSize, sceneCenter, blockSize, bucketSize) {\n        await delayedExecute();\n        const packed = await loadSpzPacked(spzFileData);\n        outSphericalHarmonicsDegree = Math.min(packed.shDegree, outSphericalHarmonicsDegree);\n\n        const splatArray = new UncompressedSplatArray(outSphericalHarmonicsDegree);\n\n        if (optimizeSplatData) {\n            unpackGaussians(packed, outSphericalHarmonicsDegree, false, splatArray, 0);\n            const splatBufferGenerator = SplatBufferGenerator.getStandardGenerator(minimumAlpha, compressionLevel,\n                                                                                   sectionSize, sceneCenter,\n                                                                                   blockSize, bucketSize);\n            return splatBufferGenerator.generateFromUncompressedSplatArray(splatArray);\n        } else {\n            const {\n                splatBuffer,\n                splatBufferDataOffsetBytes\n              } = SplatBuffer.preallocateUncompressed(packed.numPoints, outSphericalHarmonicsDegree);\n            unpackGaussians(packed, outSphericalHarmonicsDegree, true, splatBuffer.bufferData, splatBufferDataOffsetBytes);\n            return splatBuffer;\n        }\n    }\n\n}\n","import * as THREE from 'three';\nimport { SplatBuffer } from '../SplatBuffer.js';\nimport { UncompressedSplatArray } from '../UncompressedSplatArray.js';\n\nexport class SplatParser {\n\n    static RowSizeBytes = 32;\n    static CenterSizeBytes = 12;\n    static ScaleSizeBytes = 12;\n    static RotationSizeBytes = 4;\n    static ColorSizeBytes = 4;\n\n    static parseToUncompressedSplatBufferSection(fromSplat, toSplat, fromBuffer, fromOffset, toBuffer, toOffset) {\n\n        const outBytesPerCenter = SplatBuffer.CompressionLevels[0].BytesPerCenter;\n        const outBytesPerScale = SplatBuffer.CompressionLevels[0].BytesPerScale;\n        const outBytesPerRotation = SplatBuffer.CompressionLevels[0].BytesPerRotation;\n        const outBytesPerSplat = SplatBuffer.CompressionLevels[0].SphericalHarmonicsDegrees[0].BytesPerSplat;\n\n        for (let i = fromSplat; i <= toSplat; i++) {\n            const inBase = i * SplatParser.RowSizeBytes + fromOffset;\n            const inCenter = new Float32Array(fromBuffer, inBase, 3);\n            const inScale = new Float32Array(fromBuffer, inBase + SplatParser.CenterSizeBytes, 3);\n            const inColor = new Uint8Array(fromBuffer, inBase + SplatParser.CenterSizeBytes + SplatParser.ScaleSizeBytes, 4);\n            const inRotation = new Uint8Array(fromBuffer, inBase + SplatParser.CenterSizeBytes + SplatParser.ScaleSizeBytes +\n                                              SplatParser.RotationSizeBytes, 4);\n\n            const quat = new THREE.Quaternion((inRotation[1] - 128) / 128, (inRotation[2] - 128) / 128,\n                                              (inRotation[3] - 128) / 128, (inRotation[0] - 128) / 128);\n            quat.normalize();\n\n            const outBase = i * outBytesPerSplat + toOffset;\n            const outCenter = new Float32Array(toBuffer, outBase, 3);\n            const outScale = new Float32Array(toBuffer, outBase + outBytesPerCenter, 3);\n            const outRotation = new Float32Array(toBuffer, outBase + outBytesPerCenter + outBytesPerScale, 4);\n            const outColor = new Uint8Array(toBuffer, outBase + outBytesPerCenter + outBytesPerScale + outBytesPerRotation, 4);\n\n            outCenter[0] = inCenter[0];\n            outCenter[1] = inCenter[1];\n            outCenter[2] = inCenter[2];\n\n            outScale[0] = inScale[0];\n            outScale[1] = inScale[1];\n            outScale[2] = inScale[2];\n\n            outRotation[0] = quat.w;\n            outRotation[1] = quat.x;\n            outRotation[2] = quat.y;\n            outRotation[3] = quat.z;\n\n            outColor[0] = inColor[0];\n            outColor[1] = inColor[1];\n            outColor[2] = inColor[2];\n            outColor[3] = inColor[3];\n        }\n    }\n\n    static parseToUncompressedSplatArraySection(fromSplat, toSplat, fromBuffer, fromOffset, splatArray) {\n\n        for (let i = fromSplat; i <= toSplat; i++) {\n            const inBase = i * SplatParser.RowSizeBytes + fromOffset;\n            const inCenter = new Float32Array(fromBuffer, inBase, 3);\n            const inScale = new Float32Array(fromBuffer, inBase + SplatParser.CenterSizeBytes, 3);\n            const inColor = new Uint8Array(fromBuffer, inBase + SplatParser.CenterSizeBytes + SplatParser.ScaleSizeBytes, 4);\n            const inRotation = new Uint8Array(fromBuffer, inBase + SplatParser.CenterSizeBytes + SplatParser.ScaleSizeBytes +\n                                              SplatParser.RotationSizeBytes, 4);\n\n            const quat = new THREE.Quaternion((inRotation[1] - 128) / 128, (inRotation[2] - 128) / 128,\n                                              (inRotation[3] - 128) / 128, (inRotation[0] - 128) / 128);\n            quat.normalize();\n\n            splatArray.addSplatFromComonents(inCenter[0], inCenter[1], inCenter[2], inScale[0], inScale[1], inScale[2],\n                                             quat.w, quat.x, quat.y, quat.z, inColor[0], inColor[1], inColor[2], inColor[3]);\n        }\n    }\n\n    static parseStandardSplatToUncompressedSplatArray(inBuffer) {\n        // Standard .splat row layout:\n        // XYZ - Position (Float32)\n        // XYZ - Scale (Float32)\n        // RGBA - colors (uint8)\n        // IJKL - quaternion/rot (uint8)\n\n        const splatCount = inBuffer.byteLength / SplatParser.RowSizeBytes;\n\n        const splatArray = new UncompressedSplatArray();\n\n        for (let i = 0; i < splatCount; i++) {\n            const inBase = i * SplatParser.RowSizeBytes;\n            const inCenter = new Float32Array(inBuffer, inBase, 3);\n            const inScale = new Float32Array(inBuffer, inBase + SplatParser.CenterSizeBytes, 3);\n            const inColor = new Uint8Array(inBuffer, inBase + SplatParser.CenterSizeBytes + SplatParser.ScaleSizeBytes, 4);\n            const inRotation = new Uint8Array(inBuffer, inBase + SplatParser.CenterSizeBytes +\n                                              SplatParser.ScaleSizeBytes + SplatParser.ColorSizeBytes, 4);\n\n            const quat = new THREE.Quaternion((inRotation[1] - 128) / 128, (inRotation[2] - 128) / 128,\n                                              (inRotation[3] - 128) / 128, (inRotation[0] - 128) / 128);\n            quat.normalize();\n\n            splatArray.addSplatFromComonents(inCenter[0], inCenter[1], inCenter[2], inScale[0], inScale[1], inScale[2],\n                                             quat.w, quat.x, quat.y, quat.z, inColor[0], inColor[1], inColor[2], inColor[3]);\n        }\n\n        return splatArray;\n    }\n\n}\n","import * as THREE from 'three';\nimport { SplatBuffer } from '../SplatBuffer.js';\nimport { SplatBufferGenerator } from '../SplatBufferGenerator.js';\nimport { SplatParser } from './SplatParser.js';\nimport { fetchWithProgress, delayedExecute, nativePromiseWithExtractedComponents } from '../../Util.js';\nimport { UncompressedSplatArray } from '../UncompressedSplatArray.js';\nimport { LoaderStatus } from '../LoaderStatus.js';\nimport { DirectLoadError } from '../DirectLoadError.js';\nimport { Constants } from '../../Constants.js';\nimport { InternalLoadType } from '../InternalLoadType.js';\n\nfunction finalize(splatData, optimizeSplatData, minimumAlpha, compressionLevel, sectionSize, sceneCenter, blockSize, bucketSize) {\n    if (optimizeSplatData) {\n        const splatBufferGenerator = SplatBufferGenerator.getStandardGenerator(minimumAlpha, compressionLevel,\n                                                                               sectionSize, sceneCenter,\n                                                                               blockSize, bucketSize);\n        return splatBufferGenerator.generateFromUncompressedSplatArray(splatData);\n    } else {\n        // TODO: Implement direct-to-SplatBuffer when not optimizing splat data\n        return SplatBuffer.generateFromUncompressedSplatArrays([splatData], minimumAlpha, 0, new THREE.Vector3());\n    }\n}\n\nexport class SplatLoader {\n\n    static loadFromURL(fileName, onProgress, progressiveLoadToSplatBuffer, onProgressiveLoadSectionProgress, minimumAlpha, compressionLevel,\n                       optimizeSplatData = true, headers, sectionSize, sceneCenter, blockSize, bucketSize) {\n\n        let internalLoadType = progressiveLoadToSplatBuffer ? InternalLoadType.ProgressiveToSplatBuffer :\n                                                          InternalLoadType.ProgressiveToSplatArray;\n        if (optimizeSplatData) internalLoadType = InternalLoadType.ProgressiveToSplatArray;\n\n        const splatDataOffsetBytes = SplatBuffer.HeaderSizeBytes + SplatBuffer.SectionHeaderSizeBytes;\n        const directLoadSectionSizeBytes = Constants.ProgressiveLoadSectionSize;\n        const sectionCount = 1;\n\n        let directLoadBufferIn;\n        let directLoadBufferOut;\n        let directLoadSplatBuffer;\n        let maxSplatCount = 0;\n        let splatCount = 0;\n\n        let standardLoadUncompressedSplatArray;\n\n        const loadPromise = nativePromiseWithExtractedComponents();\n\n        let numBytesStreamed = 0;\n        let numBytesLoaded = 0;\n        let chunks = [];\n\n        const localOnProgress = (percent, percentStr, chunk, fileSize) => {\n            const loadComplete = percent >= 100;\n\n            if (chunk) {\n                chunks.push(chunk);\n            }\n\n            if (internalLoadType === InternalLoadType.DownloadBeforeProcessing) {\n                if (loadComplete) {\n                    loadPromise.resolve(chunks);\n                }\n                return;\n            }\n\n            if (!fileSize) {\n                if (progressiveLoadToSplatBuffer) {\n                    throw new DirectLoadError('Cannon directly load .splat because no file size info is available.');\n                } else {\n                    internalLoadType = InternalLoadType.DownloadBeforeProcessing;\n                    return;\n                }\n            }\n\n            if (!directLoadBufferIn) {\n                maxSplatCount = fileSize / SplatParser.RowSizeBytes;\n                directLoadBufferIn = new ArrayBuffer(fileSize);\n                const bytesPerSplat = SplatBuffer.CompressionLevels[0].SphericalHarmonicsDegrees[0].BytesPerSplat;\n                const splatBufferSizeBytes = splatDataOffsetBytes + bytesPerSplat * maxSplatCount;\n\n                if (internalLoadType === InternalLoadType.ProgressiveToSplatBuffer) {\n                    directLoadBufferOut = new ArrayBuffer(splatBufferSizeBytes);\n                    SplatBuffer.writeHeaderToBuffer({\n                        versionMajor: SplatBuffer.CurrentMajorVersion,\n                        versionMinor: SplatBuffer.CurrentMinorVersion,\n                        maxSectionCount: sectionCount,\n                        sectionCount: sectionCount,\n                        maxSplatCount: maxSplatCount,\n                        splatCount: splatCount,\n                        compressionLevel: 0,\n                        sceneCenter: new THREE.Vector3()\n                    }, directLoadBufferOut);\n                } else {\n                    standardLoadUncompressedSplatArray = new UncompressedSplatArray(0);\n                }\n            }\n\n            if (chunk) {\n                new Uint8Array(directLoadBufferIn, numBytesLoaded, chunk.byteLength).set(new Uint8Array(chunk));\n                numBytesLoaded += chunk.byteLength;\n\n                const bytesLoadedSinceLastSection = numBytesLoaded - numBytesStreamed;\n                if (bytesLoadedSinceLastSection > directLoadSectionSizeBytes || loadComplete) {\n                    const bytesToUpdate = loadComplete ? bytesLoadedSinceLastSection : directLoadSectionSizeBytes;\n                    const addedSplatCount = bytesToUpdate / SplatParser.RowSizeBytes;\n                    const newSplatCount = splatCount + addedSplatCount;\n\n                    if (internalLoadType === InternalLoadType.ProgressiveToSplatBuffer) {\n                        SplatParser.parseToUncompressedSplatBufferSection(splatCount, newSplatCount - 1, directLoadBufferIn, 0,\n                                                                            directLoadBufferOut, splatDataOffsetBytes);\n                    } else {\n                        SplatParser.parseToUncompressedSplatArraySection(splatCount, newSplatCount - 1, directLoadBufferIn, 0,\n                                                                            standardLoadUncompressedSplatArray);\n                    }\n\n                    splatCount = newSplatCount;\n\n                    if (internalLoadType === InternalLoadType.ProgressiveToSplatBuffer) {\n                        if (!directLoadSplatBuffer) {\n                            SplatBuffer.writeSectionHeaderToBuffer({\n                                maxSplatCount: maxSplatCount,\n                                splatCount: splatCount,\n                                bucketSize: 0,\n                                bucketCount: 0,\n                                bucketBlockSize: 0,\n                                compressionScaleRange: 0,\n                                storageSizeBytes: 0,\n                                fullBucketCount: 0,\n                                partiallyFilledBucketCount: 0\n                            }, 0, directLoadBufferOut, SplatBuffer.HeaderSizeBytes);\n                            directLoadSplatBuffer = new SplatBuffer(directLoadBufferOut, false);\n                        }\n                        directLoadSplatBuffer.updateLoadedCounts(1, splatCount);\n                        if (onProgressiveLoadSectionProgress) {\n                            onProgressiveLoadSectionProgress(directLoadSplatBuffer, loadComplete);\n                        }\n                    }\n\n                    numBytesStreamed += directLoadSectionSizeBytes;\n                }\n            }\n\n            if (loadComplete) {\n                if (internalLoadType === InternalLoadType.ProgressiveToSplatBuffer) {\n                    loadPromise.resolve(directLoadSplatBuffer);\n                } else {\n                    loadPromise.resolve(standardLoadUncompressedSplatArray);\n                }\n            }\n\n            if (onProgress) onProgress(percent, percentStr, LoaderStatus.Downloading);\n        };\n\n        if (onProgress) onProgress(0, '0%', LoaderStatus.Downloading);\n        return fetchWithProgress(fileName, localOnProgress, false, headers).then(() => {\n            if (onProgress) onProgress(0, '0%', LoaderStatus.Processing);\n            return loadPromise.promise.then((splatData) => {\n                if (onProgress) onProgress(100, '100%', LoaderStatus.Done);\n                if (internalLoadType === InternalLoadType.DownloadBeforeProcessing) {\n                    return new Blob(chunks).arrayBuffer().then((splatData) => {\n                        return SplatLoader.loadFromFileData(splatData, minimumAlpha, compressionLevel, optimizeSplatData,\n                                                            sectionSize, sceneCenter, blockSize, bucketSize);\n                    });\n                } else if (internalLoadType === InternalLoadType.ProgressiveToSplatBuffer) {\n                    return splatData;\n                } else {\n                    return delayedExecute(() => {\n                        return finalize(splatData, optimizeSplatData, minimumAlpha, compressionLevel,\n                                        sectionSize, sceneCenter, blockSize, bucketSize);\n                    });\n                }\n            });\n        });\n    }\n\n    static loadFromFileData(splatFileData, minimumAlpha, compressionLevel, optimizeSplatData,\n                            sectionSize, sceneCenter, blockSize, bucketSize) {\n        return delayedExecute(() => {\n            const splatArray = SplatParser.parseStandardSplatToUncompressedSplatArray(splatFileData);\n            return finalize(splatArray, optimizeSplatData, minimumAlpha, compressionLevel,\n                            sectionSize, sceneCenter, blockSize, bucketSize);\n        });\n    }\n\n}\n","import { SplatBuffer } from '../SplatBuffer.js';\nimport { fetchWithProgress, delayedExecute, nativePromiseWithExtractedComponents } from '../../Util.js';\nimport { LoaderStatus } from '../LoaderStatus.js';\nimport { Constants } from '../../Constants.js';\n\nexport class KSplatLoader {\n\n   static checkVersion(buffer) {\n        const minVersionMajor = SplatBuffer.CurrentMajorVersion;\n        const minVersionMinor = SplatBuffer.CurrentMinorVersion;\n        const header = SplatBuffer.parseHeader(buffer);\n        if (header.versionMajor === minVersionMajor &&\n            header.versionMinor >= minVersionMinor ||\n            header.versionMajor > minVersionMajor) {\n           return true;\n        } else {\n            throw new Error(`KSplat version not supported: v${header.versionMajor}.${header.versionMinor}. ` +\n                            `Minimum required: v${minVersionMajor}.${minVersionMinor}`);\n        }\n    };\n\n    static loadFromURL(fileName, externalOnProgress, progressiveLoadToSplatBuffer, onSectionBuilt, headers) {\n        let directLoadBuffer;\n        let directLoadSplatBuffer;\n\n        let headerBuffer;\n        let header;\n        let headerLoaded = false;\n        let headerLoading = false;\n\n        let sectionHeadersBuffer;\n        let sectionHeaders = [];\n        let sectionHeadersLoaded = false;\n        let sectionHeadersLoading = false;\n\n        let numBytesLoaded = 0;\n        let numBytesProgressivelyLoaded = 0;\n        let totalBytesToDownload = 0;\n\n        let downloadComplete = false;\n        let loadComplete = false;\n        let loadSectionQueued = false;\n\n        let chunks = [];\n\n        const directLoadPromise = nativePromiseWithExtractedComponents();\n\n        const checkAndLoadHeader = () => {\n            if (!headerLoaded && !headerLoading && numBytesLoaded >= SplatBuffer.HeaderSizeBytes) {\n                headerLoading = true;\n                const headerAssemblyPromise = new Blob(chunks).arrayBuffer();\n                headerAssemblyPromise.then((bufferData) => {\n                    headerBuffer = new ArrayBuffer(SplatBuffer.HeaderSizeBytes);\n                    new Uint8Array(headerBuffer).set(new Uint8Array(bufferData, 0, SplatBuffer.HeaderSizeBytes));\n                    KSplatLoader.checkVersion(headerBuffer);\n                    headerLoading = false;\n                    headerLoaded = true;\n                    header = SplatBuffer.parseHeader(headerBuffer);\n                    window.setTimeout(() => {\n                        checkAndLoadSectionHeaders();\n                    }, 1);\n                });\n            }\n        };\n\n        let queuedCheckAndLoadSectionsCount = 0;\n        const queueCheckAndLoadSections = () => {\n            if (queuedCheckAndLoadSectionsCount === 0) {\n                queuedCheckAndLoadSectionsCount++;\n                window.setTimeout(() => {\n                    queuedCheckAndLoadSectionsCount--;\n                    checkAndLoadSections();\n                }, 1);\n            }\n        };\n\n        const checkAndLoadSectionHeaders = () => {\n            const performLoad = () => {\n                sectionHeadersLoading = true;\n                const sectionHeadersAssemblyPromise = new Blob(chunks).arrayBuffer();\n                sectionHeadersAssemblyPromise.then((bufferData) => {\n                    sectionHeadersLoading = false;\n                    sectionHeadersLoaded = true;\n                    sectionHeadersBuffer = new ArrayBuffer(header.maxSectionCount * SplatBuffer.SectionHeaderSizeBytes);\n                    new Uint8Array(sectionHeadersBuffer).set(new Uint8Array(bufferData, SplatBuffer.HeaderSizeBytes,\n                                                                            header.maxSectionCount * SplatBuffer.SectionHeaderSizeBytes));\n                    sectionHeaders = SplatBuffer.parseSectionHeaders(header, sectionHeadersBuffer, 0, false);\n                    let totalSectionStorageStorageByes = 0;\n                    for (let i = 0; i < header.maxSectionCount; i++) {\n                        totalSectionStorageStorageByes += sectionHeaders[i].storageSizeBytes;\n                    }\n                    const totalStorageSizeBytes = SplatBuffer.HeaderSizeBytes + header.maxSectionCount *\n                                                  SplatBuffer.SectionHeaderSizeBytes + totalSectionStorageStorageByes;\n                    if (!directLoadBuffer) {\n                        directLoadBuffer = new ArrayBuffer(totalStorageSizeBytes);\n                        let offset = 0;\n                        for (let i = 0; i < chunks.length; i++) {\n                            const chunk = chunks[i];\n                            new Uint8Array(directLoadBuffer, offset, chunk.byteLength).set(new Uint8Array(chunk));\n                            offset += chunk.byteLength;\n                        }\n                    }\n\n                    totalBytesToDownload = SplatBuffer.HeaderSizeBytes + SplatBuffer.SectionHeaderSizeBytes * header.maxSectionCount;\n                    for (let i = 0; i <= sectionHeaders.length && i < header.maxSectionCount; i++) {\n                        totalBytesToDownload += sectionHeaders[i].storageSizeBytes;\n                    }\n\n                    queueCheckAndLoadSections();\n                });\n            };\n\n            if (!sectionHeadersLoading && !sectionHeadersLoaded && headerLoaded &&\n                numBytesLoaded >= SplatBuffer.HeaderSizeBytes + SplatBuffer.SectionHeaderSizeBytes * header.maxSectionCount) {\n                performLoad();\n            }\n        };\n\n        const checkAndLoadSections = () => {\n            if (loadSectionQueued) return;\n            loadSectionQueued = true;\n            const checkAndLoadFunc = () => {\n                loadSectionQueued = false;\n                if (sectionHeadersLoaded) {\n\n                    if (loadComplete) return;\n\n                    downloadComplete = numBytesLoaded >= totalBytesToDownload;\n\n                    let bytesLoadedSinceLastSection = numBytesLoaded - numBytesProgressivelyLoaded;\n                    if (bytesLoadedSinceLastSection > Constants.ProgressiveLoadSectionSize || downloadComplete) {\n\n                        numBytesProgressivelyLoaded += Constants.ProgressiveLoadSectionSize;\n                        loadComplete = numBytesProgressivelyLoaded >= totalBytesToDownload;\n\n                        if (!directLoadSplatBuffer) directLoadSplatBuffer = new SplatBuffer(directLoadBuffer, false);\n\n                        const baseDataOffset = SplatBuffer.HeaderSizeBytes + SplatBuffer.SectionHeaderSizeBytes * header.maxSectionCount;\n                        let sectionBase = 0;\n                        let reachedSections = 0;\n                        let loadedSplatCount = 0;\n                        for (let i = 0; i < header.maxSectionCount; i++) {\n                            const sectionHeader = sectionHeaders[i];\n                            const bucketsDataOffset = sectionBase + sectionHeader.partiallyFilledBucketCount * 4 +\n                                                    sectionHeader.bucketStorageSizeBytes * sectionHeader.bucketCount;\n                            const bytesRequiredToReachSectionSplatData = baseDataOffset + bucketsDataOffset;\n                            if (numBytesProgressivelyLoaded >= bytesRequiredToReachSectionSplatData) {\n                                reachedSections++;\n                                const bytesPastSSectionSplatDataStart = numBytesProgressivelyLoaded - bytesRequiredToReachSectionSplatData;\n                                const baseDescriptor = SplatBuffer.CompressionLevels[header.compressionLevel];\n                                const shDesc = baseDescriptor.SphericalHarmonicsDegrees[sectionHeader.sphericalHarmonicsDegree];\n                                const bytesPerSplat = shDesc.BytesPerSplat;\n                                let loadedSplatsForSection = Math.floor(bytesPastSSectionSplatDataStart / bytesPerSplat);\n                                loadedSplatsForSection = Math.min(loadedSplatsForSection, sectionHeader.maxSplatCount);\n                                loadedSplatCount += loadedSplatsForSection;\n                                directLoadSplatBuffer.updateLoadedCounts(reachedSections, loadedSplatCount);\n                                directLoadSplatBuffer.updateSectionLoadedCounts(i, loadedSplatsForSection);\n                            } else {\n                                break;\n                            }\n                            sectionBase += sectionHeader.storageSizeBytes;\n                        }\n\n                        onSectionBuilt(directLoadSplatBuffer, loadComplete);\n\n                        const percentComplete = numBytesProgressivelyLoaded / totalBytesToDownload * 100;\n                        const percentLabel = (percentComplete).toFixed(2) + '%';\n\n                        if (externalOnProgress) externalOnProgress(percentComplete, percentLabel, LoaderStatus.Downloading);\n\n                        if (loadComplete) {\n                            directLoadPromise.resolve(directLoadSplatBuffer);\n                        } else {\n                            checkAndLoadSections();\n                        }\n                    }\n                }\n            };\n            window.setTimeout(checkAndLoadFunc, Constants.ProgressiveLoadSectionDelayDuration);\n        };\n\n        const localOnProgress = (percent, percentStr, chunk) => {\n            if (chunk) {\n                chunks.push(chunk);\n                if (directLoadBuffer) {\n                    new Uint8Array(directLoadBuffer, numBytesLoaded, chunk.byteLength).set(new Uint8Array(chunk));\n                }\n                numBytesLoaded += chunk.byteLength;\n            }\n            if (progressiveLoadToSplatBuffer) {\n                checkAndLoadHeader();\n                checkAndLoadSectionHeaders();\n                checkAndLoadSections();\n            } else {\n                if (externalOnProgress) externalOnProgress(percent, percentStr, LoaderStatus.Downloading);\n            }\n        };\n\n        return fetchWithProgress(fileName, localOnProgress, !progressiveLoadToSplatBuffer, headers).then((fullBuffer) => {\n            if (externalOnProgress) externalOnProgress(0, '0%', LoaderStatus.Processing);\n            const loadPromise = progressiveLoadToSplatBuffer ? directLoadPromise.promise : KSplatLoader.loadFromFileData(fullBuffer);\n            return loadPromise.then((splatBuffer) => {\n                if (externalOnProgress) externalOnProgress(100, '100%', LoaderStatus.Done);\n                return splatBuffer;\n            });\n        });\n    }\n\n    static loadFromFileData(fileData) {\n        return delayedExecute(() => {\n            KSplatLoader.checkVersion(fileData);\n            return new SplatBuffer(fileData);\n        });\n    }\n\n    static downloadFile = function() {\n\n        let downLoadLink;\n\n        return function(splatBuffer, fileName) {\n            const blob = new Blob([splatBuffer.bufferData], {\n                type: 'application/octet-stream',\n            });\n\n            if (!downLoadLink) {\n                downLoadLink = document.createElement('a');\n                document.body.appendChild(downLoadLink);\n            }\n            downLoadLink.download = fileName;\n            downLoadLink.href = URL.createObjectURL(blob);\n            downLoadLink.click();\n        };\n\n    }();\n\n}\n","export const SceneFormat = {\n    'Splat': 0,\n    'KSplat': 1,\n    'Ply': 2,\n    'Spz': 3\n};\n","import { SceneFormat } from './SceneFormat.js';\n\nexport const sceneFormatFromPath = (path) => {\n    if (path.endsWith('.ply')) return SceneFormat.Ply;\n    else if (path.endsWith('.splat')) return SceneFormat.Splat;\n    else if (path.endsWith('.ksplat')) return SceneFormat.KSplat;\n    else if (path.endsWith('.spz')) return SceneFormat.Spz;\n    return null;\n};\n","/*\nCopyright © 2010-2024 three.js authors & Mark Kellogg\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n*/\n\nimport {\n    EventDispatcher,\n    MOUSE,\n    Quaternion,\n    Spherical,\n    TOUCH,\n    Vector2,\n    Vector3,\n    Plane,\n    Ray,\n    MathUtils\n} from 'three';\n\n// OrbitControls performs orbiting, dollying (zooming), and panning.\n// Unlike TrackballControls, it maintains the \"up\" direction object.up (+Y by default).\n//\n//    Orbit - left mouse / touch: one-finger move\n//    Zoom - middle mouse, or mousewheel / touch: two-finger spread or squish\n//    Pan - right mouse, or left mouse + ctrl/meta/shiftKey, or arrow keys / touch: two-finger move\n\nconst _changeEvent = { type: 'change' };\nconst _startEvent = { type: 'start' };\nconst _endEvent = { type: 'end' };\nconst _ray = new Ray();\nconst _plane = new Plane();\nconst TILT_LIMIT = Math.cos( 70 * MathUtils.DEG2RAD );\n\nclass OrbitControls extends EventDispatcher {\n\n    constructor( object, domElement ) {\n\n        super();\n\n        this.object = object;\n        this.domElement = domElement;\n        this.domElement.style.touchAction = 'none'; // disable touch scroll\n\n        // Set to false to disable this control\n        this.enabled = true;\n\n        // \"target\" sets the location of focus, where the object orbits around\n        this.target = new Vector3();\n\n        // How far you can dolly in and out ( PerspectiveCamera only )\n        this.minDistance = 0;\n        this.maxDistance = Infinity;\n\n        // How far you can zoom in and out ( OrthographicCamera only )\n        this.minZoom = 0;\n        this.maxZoom = Infinity;\n\n        // How far you can orbit vertically, upper and lower limits.\n        // Range is 0 to Math.PI radians.\n        this.minPolarAngle = 0; // radians\n        this.maxPolarAngle = Math.PI; // radians\n\n        // How far you can orbit horizontally, upper and lower limits.\n        // If set, the interval [min, max] must be a sub-interval of [- 2 PI, 2 PI], with ( max - min < 2 PI )\n        this.minAzimuthAngle = - Infinity; // radians\n        this.maxAzimuthAngle = Infinity; // radians\n\n        // Set to true to enable damping (inertia)\n        // If damping is enabled, you must call controls.update() in your animation loop\n        this.enableDamping = false;\n        this.dampingFactor = 0.05;\n\n        // This option actually enables dollying in and out; left as \"zoom\" for backwards compatibility.\n        // Set to false to disable zooming\n        this.enableZoom = true;\n        this.zoomSpeed = 1.0;\n\n        // Set to false to disable rotating\n        this.enableRotate = true;\n        this.rotateSpeed = 1.0;\n\n        // Set to false to disable panning\n        this.enablePan = true;\n        this.panSpeed = 1.0;\n        this.screenSpacePanning = true; // if false, pan orthogonal to world-space direction camera.up\n        this.keyPanSpeed = 7.0; // pixels moved per arrow key push\n        this.zoomToCursor = false;\n\n        // Set to true to automatically rotate around the target\n        // If auto-rotate is enabled, you must call controls.update() in your animation loop\n        this.autoRotate = false;\n        this.autoRotateSpeed = 2.0; // 30 seconds per orbit when fps is 60\n\n        // The four arrow keys\n        this.keys = { LEFT: 'KeyA', UP: 'KeyW', RIGHT: 'KeyD', BOTTOM: 'KeyS' };\n\n        // Mouse buttons\n        this.mouseButtons = { LEFT: MOUSE.ROTATE, MIDDLE: MOUSE.DOLLY, RIGHT: MOUSE.PAN };\n\n        // Touch fingers\n        this.touches = { ONE: TOUCH.ROTATE, TWO: TOUCH.DOLLY_PAN };\n\n        // for reset\n        this.target0 = this.target.clone();\n        this.position0 = this.object.position.clone();\n        this.zoom0 = this.object.zoom;\n\n        // the target DOM element for key events\n        this._domElementKeyEvents = null;\n\n        //\n        // public methods\n        //\n\n        this.getPolarAngle = function() {\n\n            return spherical.phi;\n\n        };\n\n        this.getAzimuthalAngle = function() {\n\n            return spherical.theta;\n\n        };\n\n        this.getDistance = function() {\n\n            return this.object.position.distanceTo( this.target );\n\n        };\n\n        this.listenToKeyEvents = function( domElement ) {\n\n            domElement.addEventListener( 'keydown', onKeyDown );\n            this._domElementKeyEvents = domElement;\n\n        };\n\n        this.stopListenToKeyEvents = function() {\n\n            this._domElementKeyEvents.removeEventListener( 'keydown', onKeyDown );\n            this._domElementKeyEvents = null;\n\n        };\n\n        this.saveState = function() {\n\n            scope.target0.copy( scope.target );\n            scope.position0.copy( scope.object.position );\n            scope.zoom0 = scope.object.zoom;\n\n        };\n\n        this.reset = function() {\n\n            scope.target.copy( scope.target0 );\n            scope.object.position.copy( scope.position0 );\n            scope.object.zoom = scope.zoom0;\n            this.clearDampedRotation();\n            this.clearDampedPan();\n\n            scope.object.updateProjectionMatrix();\n            scope.dispatchEvent( _changeEvent );\n\n            scope.update();\n\n            state = STATE.NONE;\n\n        };\n\n        this.clearDampedRotation = function() {\n            sphericalDelta.theta = 0.0;\n            sphericalDelta.phi = 0.0;\n        };\n\n        this.clearDampedPan = function() {\n            panOffset.set(0, 0, 0);\n        };\n\n        // this method is exposed, but perhaps it would be better if we can make it private...\n        this.update = function() {\n\n            const offset = new Vector3();\n\n            // so camera.up is the orbit axis\n            const quat = new Quaternion().setFromUnitVectors( object.up, new Vector3( 0, 1, 0 ) );\n            const quatInverse = quat.clone().invert();\n\n            const lastPosition = new Vector3();\n            const lastQuaternion = new Quaternion();\n            const lastTargetPosition = new Vector3();\n\n            const twoPI = 2 * Math.PI;\n\n            return function update() {\n\n                quat.setFromUnitVectors( object.up, new Vector3( 0, 1, 0 ) );\n                quatInverse.copy(quat).invert();\n\n                const position = scope.object.position;\n\n                offset.copy( position ).sub( scope.target );\n\n                // rotate offset to \"y-axis-is-up\" space\n                offset.applyQuaternion( quat );\n\n                // angle from z-axis around y-axis\n                spherical.setFromVector3( offset );\n\n                if ( scope.autoRotate && state === STATE.NONE ) {\n\n                    rotateLeft( getAutoRotationAngle() );\n\n                }\n\n                if ( scope.enableDamping ) {\n\n                    spherical.theta += sphericalDelta.theta * scope.dampingFactor;\n                    spherical.phi += sphericalDelta.phi * scope.dampingFactor;\n\n                } else {\n\n                    spherical.theta += sphericalDelta.theta;\n                    spherical.phi += sphericalDelta.phi;\n\n                }\n\n                // restrict theta to be between desired limits\n\n                let min = scope.minAzimuthAngle;\n                let max = scope.maxAzimuthAngle;\n\n                if ( isFinite( min ) && isFinite( max ) ) {\n\n                    if ( min < - Math.PI ) min += twoPI; else if ( min > Math.PI ) min -= twoPI;\n\n                    if ( max < - Math.PI ) max += twoPI; else if ( max > Math.PI ) max -= twoPI;\n\n                    if ( min <= max ) {\n\n                        spherical.theta = Math.max( min, Math.min( max, spherical.theta ) );\n\n                    } else {\n\n                        spherical.theta = ( spherical.theta > ( min + max ) / 2 ) ?\n                            Math.max( min, spherical.theta ) :\n                            Math.min( max, spherical.theta );\n\n                    }\n\n                }\n\n                // restrict phi to be between desired limits\n                spherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );\n\n                spherical.makeSafe();\n\n\n                // move target to panned location\n\n                if ( scope.enableDamping === true ) {\n\n                    scope.target.addScaledVector( panOffset, scope.dampingFactor );\n\n                } else {\n\n                    scope.target.add( panOffset );\n\n                }\n\n                // adjust the camera position based on zoom only if we're not zooming to the cursor or if it's an ortho camera\n                // we adjust zoom later in these cases\n                if ( scope.zoomToCursor && performCursorZoom || scope.object.isOrthographicCamera ) {\n\n                    spherical.radius = clampDistance( spherical.radius );\n\n                } else {\n\n                    spherical.radius = clampDistance( spherical.radius * scale );\n\n                }\n\n\n                offset.setFromSpherical( spherical );\n\n                // rotate offset back to \"camera-up-vector-is-up\" space\n                offset.applyQuaternion( quatInverse );\n\n                position.copy( scope.target ).add( offset );\n\n                scope.object.lookAt( scope.target );\n\n                if ( scope.enableDamping === true ) {\n\n                    sphericalDelta.theta *= ( 1 - scope.dampingFactor );\n                    sphericalDelta.phi *= ( 1 - scope.dampingFactor );\n\n                    panOffset.multiplyScalar( 1 - scope.dampingFactor );\n\n                } else {\n\n                    sphericalDelta.set( 0, 0, 0 );\n\n                    panOffset.set( 0, 0, 0 );\n\n                }\n\n                // adjust camera position\n                let zoomChanged = false;\n                if ( scope.zoomToCursor && performCursorZoom ) {\n\n                    let newRadius = null;\n                    if ( scope.object.isPerspectiveCamera ) {\n\n                        // move the camera down the pointer ray\n                        // this method avoids floating point error\n                        const prevRadius = offset.length();\n                        newRadius = clampDistance( prevRadius * scale );\n\n                        const radiusDelta = prevRadius - newRadius;\n                        scope.object.position.addScaledVector( dollyDirection, radiusDelta );\n                        scope.object.updateMatrixWorld();\n\n                    } else if ( scope.object.isOrthographicCamera ) {\n\n                        // adjust the ortho camera position based on zoom changes\n                        const mouseBefore = new Vector3( mouse.x, mouse.y, 0 );\n                        mouseBefore.unproject( scope.object );\n\n                        scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / scale ) );\n                        scope.object.updateProjectionMatrix();\n                        zoomChanged = true;\n\n                        const mouseAfter = new Vector3( mouse.x, mouse.y, 0 );\n                        mouseAfter.unproject( scope.object );\n\n                        scope.object.position.sub( mouseAfter ).add( mouseBefore );\n                        scope.object.updateMatrixWorld();\n\n                        newRadius = offset.length();\n\n                    } else {\n\n                        console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - zoom to cursor disabled.' );\n                        scope.zoomToCursor = false;\n\n                    }\n\n                    // handle the placement of the target\n                    if ( newRadius !== null ) {\n\n                        if ( this.screenSpacePanning ) {\n\n                            // position the orbit target in front of the new camera position\n                            scope.target.set( 0, 0, - 1 )\n                                .transformDirection( scope.object.matrix )\n                                .multiplyScalar( newRadius )\n                                .add( scope.object.position );\n\n                        } else {\n\n                            // get the ray and translation plane to compute target\n                            _ray.origin.copy( scope.object.position );\n                            _ray.direction.set( 0, 0, - 1 ).transformDirection( scope.object.matrix );\n\n                            // if the camera is 20 degrees above the horizon then don't adjust the focus target to avoid\n                            // extremely large values\n                            if ( Math.abs( scope.object.up.dot( _ray.direction ) ) < TILT_LIMIT ) {\n\n                                object.lookAt( scope.target );\n\n                            } else {\n\n                                _plane.setFromNormalAndCoplanarPoint( scope.object.up, scope.target );\n                                _ray.intersectPlane( _plane, scope.target );\n\n                            }\n\n                        }\n\n                    }\n\n                } else if ( scope.object.isOrthographicCamera ) {\n\n                    scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / scale ) );\n                    scope.object.updateProjectionMatrix();\n                    zoomChanged = true;\n\n                }\n\n                scale = 1;\n                performCursorZoom = false;\n\n                // update condition is:\n                // min(camera displacement, camera rotation in radians)^2 > EPS\n                // using small-angle approximation cos(x/2) = 1 - x^2 / 8\n\n                if ( zoomChanged ||\n                    lastPosition.distanceToSquared( scope.object.position ) > EPS ||\n                    8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ||\n                    lastTargetPosition.distanceToSquared( scope.target ) > 0 ) {\n\n                    scope.dispatchEvent( _changeEvent );\n\n                    lastPosition.copy( scope.object.position );\n                    lastQuaternion.copy( scope.object.quaternion );\n                    lastTargetPosition.copy( scope.target );\n\n                    zoomChanged = false;\n\n                    return true;\n\n                }\n\n                return false;\n\n            };\n\n        }();\n\n        this.dispose = function() {\n\n            scope.domElement.removeEventListener( 'contextmenu', onContextMenu );\n\n            scope.domElement.removeEventListener( 'pointerdown', onPointerDown );\n            scope.domElement.removeEventListener( 'pointercancel', onPointerUp );\n            scope.domElement.removeEventListener( 'wheel', onMouseWheel );\n\n            scope.domElement.removeEventListener( 'pointermove', onPointerMove );\n            scope.domElement.removeEventListener( 'pointerup', onPointerUp );\n\n\n            if ( scope._domElementKeyEvents !== null ) {\n\n                scope._domElementKeyEvents.removeEventListener( 'keydown', onKeyDown );\n                scope._domElementKeyEvents = null;\n\n            }\n\n        };\n\n        //\n        // internals\n        //\n\n        const scope = this;\n\n        const STATE = {\n            NONE: - 1,\n            ROTATE: 0,\n            DOLLY: 1,\n            PAN: 2,\n            TOUCH_ROTATE: 3,\n            TOUCH_PAN: 4,\n            TOUCH_DOLLY_PAN: 5,\n            TOUCH_DOLLY_ROTATE: 6\n        };\n\n        let state = STATE.NONE;\n\n        const EPS = 0.000001;\n\n        // current position in spherical coordinates\n        const spherical = new Spherical();\n        const sphericalDelta = new Spherical();\n\n        let scale = 1;\n        const panOffset = new Vector3();\n\n        const rotateStart = new Vector2();\n        const rotateEnd = new Vector2();\n        const rotateDelta = new Vector2();\n\n        const panStart = new Vector2();\n        const panEnd = new Vector2();\n        const panDelta = new Vector2();\n\n        const dollyStart = new Vector2();\n        const dollyEnd = new Vector2();\n        const dollyDelta = new Vector2();\n\n        const dollyDirection = new Vector3();\n        const mouse = new Vector2();\n        let performCursorZoom = false;\n\n        const pointers = [];\n        const pointerPositions = {};\n\n        function getAutoRotationAngle() {\n\n            return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;\n\n        }\n\n        function getZoomScale() {\n\n            return Math.pow( 0.95, scope.zoomSpeed );\n\n        }\n\n        function rotateLeft( angle ) {\n\n            sphericalDelta.theta -= angle;\n\n        }\n\n        function rotateUp( angle ) {\n\n            sphericalDelta.phi -= angle;\n\n        }\n\n        const panLeft = function() {\n\n            const v = new Vector3();\n\n            return function panLeft( distance, objectMatrix ) {\n\n                v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix\n                v.multiplyScalar( - distance );\n\n                panOffset.add( v );\n\n            };\n\n        }();\n\n        const panUp = function() {\n\n            const v = new Vector3();\n\n            return function panUp( distance, objectMatrix ) {\n\n                if ( scope.screenSpacePanning === true ) {\n\n                    v.setFromMatrixColumn( objectMatrix, 1 );\n\n                } else {\n\n                    v.setFromMatrixColumn( objectMatrix, 0 );\n                    v.crossVectors( scope.object.up, v );\n\n                }\n\n                v.multiplyScalar( distance );\n\n                panOffset.add( v );\n\n            };\n\n        }();\n\n        // deltaX and deltaY are in pixels; right and down are positive\n        const pan = function() {\n\n            const offset = new Vector3();\n\n            return function pan( deltaX, deltaY ) {\n\n                const element = scope.domElement;\n\n                if ( scope.object.isPerspectiveCamera ) {\n\n                    // perspective\n                    const position = scope.object.position;\n                    offset.copy( position ).sub( scope.target );\n                    let targetDistance = offset.length();\n\n                    // half of the fov is center to top of screen\n                    targetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );\n\n                    // we use only clientHeight here so aspect ratio does not distort speed\n                    panLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );\n                    panUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );\n\n                } else if ( scope.object.isOrthographicCamera ) {\n\n                    // orthographic\n                    panLeft( deltaX * ( scope.object.right - scope.object.left ) /\n                                        scope.object.zoom / element.clientWidth, scope.object.matrix );\n                    panUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom /\n                                      element.clientHeight, scope.object.matrix );\n\n                } else {\n\n                    // camera neither orthographic nor perspective\n                    console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );\n                    scope.enablePan = false;\n\n                }\n\n            };\n\n        }();\n\n        function dollyOut( dollyScale ) {\n\n            if ( scope.object.isPerspectiveCamera || scope.object.isOrthographicCamera ) {\n\n                scale /= dollyScale;\n\n            } else {\n\n                console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n                scope.enableZoom = false;\n\n            }\n\n        }\n\n        function dollyIn( dollyScale ) {\n\n            if ( scope.object.isPerspectiveCamera || scope.object.isOrthographicCamera ) {\n\n                scale *= dollyScale;\n\n            } else {\n\n                console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n                scope.enableZoom = false;\n\n            }\n\n        }\n\n        function updateMouseParameters( event ) {\n\n            if ( ! scope.zoomToCursor ) {\n\n                return;\n\n            }\n\n            performCursorZoom = true;\n\n            const rect = scope.domElement.getBoundingClientRect();\n            const x = event.clientX - rect.left;\n            const y = event.clientY - rect.top;\n            const w = rect.width;\n            const h = rect.height;\n\n            mouse.x = ( x / w ) * 2 - 1;\n            mouse.y = - ( y / h ) * 2 + 1;\n\n            dollyDirection.set( mouse.x, mouse.y, 1 ).unproject( object ).sub( object.position ).normalize();\n\n        }\n\n        function clampDistance( dist ) {\n\n            return Math.max( scope.minDistance, Math.min( scope.maxDistance, dist ) );\n\n        }\n\n        //\n        // event callbacks - update the object state\n        //\n\n        function handleMouseDownRotate( event ) {\n\n            rotateStart.set( event.clientX, event.clientY );\n\n        }\n\n        function handleMouseDownDolly( event ) {\n\n            updateMouseParameters( event );\n            dollyStart.set( event.clientX, event.clientY );\n\n        }\n\n        function handleMouseDownPan( event ) {\n\n            panStart.set( event.clientX, event.clientY );\n\n        }\n\n        function handleMouseMoveRotate( event ) {\n\n            rotateEnd.set( event.clientX, event.clientY );\n\n            rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed );\n\n            const element = scope.domElement;\n\n            rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height\n\n            rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight );\n\n            rotateStart.copy( rotateEnd );\n\n            scope.update();\n\n        }\n\n        function handleMouseMoveDolly( event ) {\n\n            dollyEnd.set( event.clientX, event.clientY );\n\n            dollyDelta.subVectors( dollyEnd, dollyStart );\n\n            if ( dollyDelta.y > 0 ) {\n\n                dollyOut( getZoomScale() );\n\n            } else if ( dollyDelta.y < 0 ) {\n\n                dollyIn( getZoomScale() );\n\n            }\n\n            dollyStart.copy( dollyEnd );\n\n            scope.update();\n\n        }\n\n        function handleMouseMovePan( event ) {\n\n            panEnd.set( event.clientX, event.clientY );\n\n            panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed );\n\n            pan( panDelta.x, panDelta.y );\n\n            panStart.copy( panEnd );\n\n            scope.update();\n\n        }\n\n        function handleMouseWheel( event ) {\n\n            updateMouseParameters( event );\n\n            if ( event.deltaY < 0 ) {\n\n                dollyIn( getZoomScale() );\n\n            } else if ( event.deltaY > 0 ) {\n\n                dollyOut( getZoomScale() );\n\n            }\n\n            scope.update();\n\n        }\n\n        function handleKeyDown( event ) {\n\n            let needsUpdate = false;\n\n            switch ( event.code ) {\n\n                case scope.keys.UP:\n\n                    if ( event.ctrlKey || event.metaKey || event.shiftKey ) {\n\n                        rotateUp( 2 * Math.PI * scope.rotateSpeed / scope.domElement.clientHeight );\n\n                    } else {\n\n                        pan( 0, scope.keyPanSpeed );\n\n                    }\n\n                    needsUpdate = true;\n                    break;\n\n                case scope.keys.BOTTOM:\n\n                    if ( event.ctrlKey || event.metaKey || event.shiftKey ) {\n\n                        rotateUp( - 2 * Math.PI * scope.rotateSpeed / scope.domElement.clientHeight );\n\n                    } else {\n\n                        pan( 0, - scope.keyPanSpeed );\n\n                    }\n\n                    needsUpdate = true;\n                    break;\n\n                case scope.keys.LEFT:\n\n                    if ( event.ctrlKey || event.metaKey || event.shiftKey ) {\n\n                        rotateLeft( 2 * Math.PI * scope.rotateSpeed / scope.domElement.clientHeight );\n\n                    } else {\n\n                        pan( scope.keyPanSpeed, 0 );\n\n                    }\n\n                    needsUpdate = true;\n                    break;\n\n                case scope.keys.RIGHT:\n\n                    if ( event.ctrlKey || event.metaKey || event.shiftKey ) {\n\n                        rotateLeft( - 2 * Math.PI * scope.rotateSpeed / scope.domElement.clientHeight );\n\n                    } else {\n\n                        pan( - scope.keyPanSpeed, 0 );\n\n                    }\n\n                    needsUpdate = true;\n                    break;\n\n            }\n\n            if ( needsUpdate ) {\n\n                // prevent the browser from scrolling on cursor keys\n                event.preventDefault();\n\n                scope.update();\n\n            }\n\n\n        }\n\n        function handleTouchStartRotate() {\n\n            if ( pointers.length === 1 ) {\n\n                rotateStart.set( pointers[0].pageX, pointers[0].pageY );\n\n            } else {\n\n                const x = 0.5 * ( pointers[0].pageX + pointers[1].pageX );\n                const y = 0.5 * ( pointers[0].pageY + pointers[1].pageY );\n\n                rotateStart.set( x, y );\n\n            }\n\n        }\n\n        function handleTouchStartPan() {\n\n            if ( pointers.length === 1 ) {\n\n                panStart.set( pointers[0].pageX, pointers[0].pageY );\n\n            } else {\n\n                const x = 0.5 * ( pointers[0].pageX + pointers[1].pageX );\n                const y = 0.5 * ( pointers[0].pageY + pointers[1].pageY );\n\n                panStart.set( x, y );\n\n            }\n\n        }\n\n        function handleTouchStartDolly() {\n\n            const dx = pointers[0].pageX - pointers[1].pageX;\n            const dy = pointers[0].pageY - pointers[1].pageY;\n\n            const distance = Math.sqrt( dx * dx + dy * dy );\n\n            dollyStart.set( 0, distance );\n\n        }\n\n        function handleTouchStartDollyPan() {\n\n            if ( scope.enableZoom ) handleTouchStartDolly();\n\n            if ( scope.enablePan ) handleTouchStartPan();\n\n        }\n\n        function handleTouchStartDollyRotate() {\n\n            if ( scope.enableZoom ) handleTouchStartDolly();\n\n            if ( scope.enableRotate ) handleTouchStartRotate();\n\n        }\n\n        function handleTouchMoveRotate( event ) {\n\n            if ( pointers.length == 1 ) {\n\n                rotateEnd.set( event.pageX, event.pageY );\n\n            } else {\n\n                const position = getSecondPointerPosition( event );\n\n                const x = 0.5 * ( event.pageX + position.x );\n                const y = 0.5 * ( event.pageY + position.y );\n\n                rotateEnd.set( x, y );\n\n            }\n\n            rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed );\n\n            const element = scope.domElement;\n\n            rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height\n\n            rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight );\n\n            rotateStart.copy( rotateEnd );\n\n        }\n\n        function handleTouchMovePan( event ) {\n\n            if ( pointers.length === 1 ) {\n\n                panEnd.set( event.pageX, event.pageY );\n\n            } else {\n\n                const position = getSecondPointerPosition( event );\n\n                const x = 0.5 * ( event.pageX + position.x );\n                const y = 0.5 * ( event.pageY + position.y );\n\n                panEnd.set( x, y );\n\n            }\n\n            panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed );\n\n            pan( panDelta.x, panDelta.y );\n\n            panStart.copy( panEnd );\n\n        }\n\n        function handleTouchMoveDolly( event ) {\n\n            const position = getSecondPointerPosition( event );\n\n            const dx = event.pageX - position.x;\n            const dy = event.pageY - position.y;\n\n            const distance = Math.sqrt( dx * dx + dy * dy );\n\n            dollyEnd.set( 0, distance );\n\n            dollyDelta.set( 0, Math.pow( dollyEnd.y / dollyStart.y, scope.zoomSpeed ) );\n\n            dollyOut( dollyDelta.y );\n\n            dollyStart.copy( dollyEnd );\n\n        }\n\n        function handleTouchMoveDollyPan( event ) {\n\n            if ( scope.enableZoom ) handleTouchMoveDolly( event );\n\n            if ( scope.enablePan ) handleTouchMovePan( event );\n\n        }\n\n        function handleTouchMoveDollyRotate( event ) {\n\n            if ( scope.enableZoom ) handleTouchMoveDolly( event );\n\n            if ( scope.enableRotate ) handleTouchMoveRotate( event );\n\n        }\n\n        //\n        // event handlers - FSM: listen for events and reset state\n        //\n\n        function onPointerDown( event ) {\n\n            if ( scope.enabled === false ) return;\n\n            if ( pointers.length === 0 ) {\n\n                scope.domElement.setPointerCapture( event.pointerId );\n\n                scope.domElement.addEventListener( 'pointermove', onPointerMove );\n                scope.domElement.addEventListener( 'pointerup', onPointerUp );\n\n            }\n\n            //\n\n            addPointer( event );\n\n            if ( event.pointerType === 'touch' ) {\n\n                onTouchStart( event );\n\n            } else {\n\n                onMouseDown( event );\n\n            }\n\n        }\n\n        function onPointerMove( event ) {\n\n            if ( scope.enabled === false ) return;\n\n            if ( event.pointerType === 'touch' ) {\n\n                onTouchMove( event );\n\n            } else {\n\n                onMouseMove( event );\n\n            }\n\n        }\n\n        function onPointerUp( event ) {\n\n            removePointer( event );\n\n            if ( pointers.length === 0 ) {\n\n                scope.domElement.releasePointerCapture( event.pointerId );\n\n                scope.domElement.removeEventListener( 'pointermove', onPointerMove );\n                scope.domElement.removeEventListener( 'pointerup', onPointerUp );\n\n            }\n\n            scope.dispatchEvent( _endEvent );\n\n            state = STATE.NONE;\n\n        }\n\n        function onMouseDown( event ) {\n\n            let mouseAction;\n\n            switch ( event.button ) {\n\n                case 0:\n\n                    mouseAction = scope.mouseButtons.LEFT;\n                    break;\n\n                case 1:\n\n                    mouseAction = scope.mouseButtons.MIDDLE;\n                    break;\n\n                case 2:\n\n                    mouseAction = scope.mouseButtons.RIGHT;\n                    break;\n\n                default:\n\n                    mouseAction = - 1;\n\n            }\n\n            switch ( mouseAction ) {\n\n                case MOUSE.DOLLY:\n\n                    if ( scope.enableZoom === false ) return;\n\n                    handleMouseDownDolly( event );\n\n                    state = STATE.DOLLY;\n\n                    break;\n\n                case MOUSE.ROTATE:\n\n                    if ( event.ctrlKey || event.metaKey || event.shiftKey ) {\n\n                        if ( scope.enablePan === false ) return;\n\n                        handleMouseDownPan( event );\n\n                        state = STATE.PAN;\n\n                    } else {\n\n                        if ( scope.enableRotate === false ) return;\n\n                        handleMouseDownRotate( event );\n\n                        state = STATE.ROTATE;\n\n                    }\n\n                    break;\n\n                case MOUSE.PAN:\n\n                    if ( event.ctrlKey || event.metaKey || event.shiftKey ) {\n\n                        if ( scope.enableRotate === false ) return;\n\n                        handleMouseDownRotate( event );\n\n                        state = STATE.ROTATE;\n\n                    } else {\n\n                        if ( scope.enablePan === false ) return;\n\n                        handleMouseDownPan( event );\n\n                        state = STATE.PAN;\n\n                    }\n\n                    break;\n\n                default:\n\n                    state = STATE.NONE;\n\n            }\n\n            if ( state !== STATE.NONE ) {\n\n                scope.dispatchEvent( _startEvent );\n\n            }\n\n        }\n\n        function onMouseMove( event ) {\n\n            switch ( state ) {\n\n                case STATE.ROTATE:\n\n                    if ( scope.enableRotate === false ) return;\n\n                    handleMouseMoveRotate( event );\n\n                    break;\n\n                case STATE.DOLLY:\n\n                    if ( scope.enableZoom === false ) return;\n\n                    handleMouseMoveDolly( event );\n\n                    break;\n\n                case STATE.PAN:\n\n                    if ( scope.enablePan === false ) return;\n\n                    handleMouseMovePan( event );\n\n                    break;\n\n            }\n\n        }\n\n        function onMouseWheel( event ) {\n\n            if ( scope.enabled === false || scope.enableZoom === false || state !== STATE.NONE ) return;\n\n            event.preventDefault();\n\n            scope.dispatchEvent( _startEvent );\n\n            handleMouseWheel( event );\n\n            scope.dispatchEvent( _endEvent );\n\n        }\n\n        function onKeyDown( event ) {\n\n            if ( scope.enabled === false || scope.enablePan === false ) return;\n\n            handleKeyDown( event );\n\n        }\n\n        function onTouchStart( event ) {\n\n            trackPointer( event );\n\n            switch ( pointers.length ) {\n\n                case 1:\n\n                    switch ( scope.touches.ONE ) {\n\n                        case TOUCH.ROTATE:\n\n                            if ( scope.enableRotate === false ) return;\n\n                            handleTouchStartRotate();\n\n                            state = STATE.TOUCH_ROTATE;\n\n                            break;\n\n                        case TOUCH.PAN:\n\n                            if ( scope.enablePan === false ) return;\n\n                            handleTouchStartPan();\n\n                            state = STATE.TOUCH_PAN;\n\n                            break;\n\n                        default:\n\n                            state = STATE.NONE;\n\n                    }\n\n                    break;\n\n                case 2:\n\n                    switch ( scope.touches.TWO ) {\n\n                        case TOUCH.DOLLY_PAN:\n\n                            if ( scope.enableZoom === false && scope.enablePan === false ) return;\n\n                            handleTouchStartDollyPan();\n\n                            state = STATE.TOUCH_DOLLY_PAN;\n\n                            break;\n\n                        case TOUCH.DOLLY_ROTATE:\n\n                            if ( scope.enableZoom === false && scope.enableRotate === false ) return;\n\n                            handleTouchStartDollyRotate();\n\n                            state = STATE.TOUCH_DOLLY_ROTATE;\n\n                            break;\n\n                        default:\n\n                            state = STATE.NONE;\n\n                    }\n\n                    break;\n\n                default:\n\n                    state = STATE.NONE;\n\n            }\n\n            if ( state !== STATE.NONE ) {\n\n                scope.dispatchEvent( _startEvent );\n\n            }\n\n        }\n\n        function onTouchMove( event ) {\n\n            trackPointer( event );\n\n            switch ( state ) {\n\n                case STATE.TOUCH_ROTATE:\n\n                    if ( scope.enableRotate === false ) return;\n\n                    handleTouchMoveRotate( event );\n\n                    scope.update();\n\n                    break;\n\n                case STATE.TOUCH_PAN:\n\n                    if ( scope.enablePan === false ) return;\n\n                    handleTouchMovePan( event );\n\n                    scope.update();\n\n                    break;\n\n                case STATE.TOUCH_DOLLY_PAN:\n\n                    if ( scope.enableZoom === false && scope.enablePan === false ) return;\n\n                    handleTouchMoveDollyPan( event );\n\n                    scope.update();\n\n                    break;\n\n                case STATE.TOUCH_DOLLY_ROTATE:\n\n                    if ( scope.enableZoom === false && scope.enableRotate === false ) return;\n\n                    handleTouchMoveDollyRotate( event );\n\n                    scope.update();\n\n                    break;\n\n                default:\n\n                    state = STATE.NONE;\n\n            }\n\n        }\n\n        function onContextMenu( event ) {\n\n            if ( scope.enabled === false ) return;\n\n            event.preventDefault();\n\n        }\n\n        function addPointer( event ) {\n\n            pointers.push( event );\n\n        }\n\n        function removePointer( event ) {\n\n            delete pointerPositions[event.pointerId];\n\n            for ( let i = 0; i < pointers.length; i ++ ) {\n\n                if ( pointers[i].pointerId == event.pointerId ) {\n\n                    pointers.splice( i, 1 );\n                    return;\n\n                }\n\n            }\n\n        }\n\n        function trackPointer( event ) {\n\n            let position = pointerPositions[event.pointerId];\n\n            if ( position === undefined ) {\n\n                position = new Vector2();\n                pointerPositions[event.pointerId] = position;\n\n            }\n\n            position.set( event.pageX, event.pageY );\n\n        }\n\n        function getSecondPointerPosition( event ) {\n\n            const pointer = ( event.pointerId === pointers[0].pointerId ) ? pointers[1] : pointers[0];\n\n            return pointerPositions[pointer.pointerId];\n\n        }\n\n        //\n\n        scope.domElement.addEventListener( 'contextmenu', onContextMenu );\n\n        scope.domElement.addEventListener( 'pointerdown', onPointerDown );\n        scope.domElement.addEventListener( 'pointercancel', onPointerUp );\n        scope.domElement.addEventListener( 'wheel', onMouseWheel, { passive: false } );\n\n        // force an update at start\n\n        this.update();\n\n    }\n\n}\n\nexport { OrbitControls };\n","import { fadeElement } from './Util.js';\n\nconst STANDARD_FADE_DURATION = 500;\n\nexport class LoadingSpinner {\n\n    static elementIDGen = 0;\n\n    constructor(message, container) {\n\n        this.taskIDGen = 0;\n        this.elementID = LoadingSpinner.elementIDGen++;\n\n        this.tasks = [];\n\n        this.message = message || 'Loading...';\n        this.container = container || document.body;\n\n        this.spinnerContainerOuter = document.createElement('div');\n        this.spinnerContainerOuter.className = `spinnerOuterContainer${this.elementID}`;\n        this.spinnerContainerOuter.style.display = 'none';\n\n        this.spinnerContainerPrimary = document.createElement('div');\n        this.spinnerContainerPrimary.className = `spinnerContainerPrimary${this.elementID}`;\n        this.spinnerPrimary = document.createElement('div');\n        this.spinnerPrimary.classList.add(`spinner${this.elementID}`, `spinnerPrimary${this.elementID}`);\n        this.messageContainerPrimary = document.createElement('div');\n        this.messageContainerPrimary.classList.add(`messageContainer${this.elementID}`, `messageContainerPrimary${this.elementID}`);\n        this.messageContainerPrimary.innerHTML = this.message;\n\n        this.spinnerContainerMin = document.createElement('div');\n        this.spinnerContainerMin.className = `spinnerContainerMin${this.elementID}`;\n        this.spinnerMin = document.createElement('div');\n        this.spinnerMin.classList.add(`spinner${this.elementID}`, `spinnerMin${this.elementID}`);\n        this.messageContainerMin = document.createElement('div');\n        this.messageContainerMin.classList.add(`messageContainer${this.elementID}`, `messageContainerMin${this.elementID}`);\n        this.messageContainerMin.innerHTML = this.message;\n\n        this.spinnerContainerPrimary.appendChild(this.spinnerPrimary);\n        this.spinnerContainerPrimary.appendChild(this.messageContainerPrimary);\n        this.spinnerContainerOuter.appendChild(this.spinnerContainerPrimary);\n\n        this.spinnerContainerMin.appendChild(this.spinnerMin);\n        this.spinnerContainerMin.appendChild(this.messageContainerMin);\n        this.spinnerContainerOuter.appendChild(this.spinnerContainerMin);\n\n        const style = document.createElement('style');\n        style.innerHTML = `\n\n            .spinnerOuterContainer${this.elementID} {\n                width: 100%;\n                height: 100%;\n                margin: 0;\n                top: 0;\n                left: 0;\n                position: absolute;\n                pointer-events: none;\n            }\n\n            .messageContainer${this.elementID} {\n                height: 20px;\n                font-family: arial;\n                font-size: 12pt;\n                color: #ffffff;\n                text-align: center;\n                vertical-align: middle;\n            }\n\n            .spinner${this.elementID} {\n                padding: 15px;\n                background: #07e8d6;\n                z-index:99999;\n            \n                aspect-ratio: 1;\n                border-radius: 50%;\n                --_m: \n                    conic-gradient(#0000,#000),\n                    linear-gradient(#000 0 0) content-box;\n                -webkit-mask: var(--_m);\n                    mask: var(--_m);\n                -webkit-mask-composite: source-out;\n                    mask-composite: subtract;\n                box-sizing: border-box;\n                animation: load 1s linear infinite;\n            }\n\n            .spinnerContainerPrimary${this.elementID} {\n                z-index:99999;\n                background-color: rgba(128, 128, 128, 0.75);\n                border: #666666 1px solid;\n                border-radius: 5px;\n                padding-top: 20px;\n                padding-bottom: 10px;\n                margin: 0;\n                position: absolute;\n                top: 50%;\n                left: 50%;\n                transform: translate(-80px, -80px);\n                width: 180px;\n                pointer-events: auto;\n            }\n\n            .spinnerPrimary${this.elementID} {\n                width: 120px;\n                margin-left: 30px;\n            }\n\n            .messageContainerPrimary${this.elementID} {\n                padding-top: 15px;\n            }\n\n            .spinnerContainerMin${this.elementID} {\n                z-index:99999;\n                background-color: rgba(128, 128, 128, 0.75);\n                border: #666666 1px solid;\n                border-radius: 5px;\n                padding-top: 20px;\n                padding-bottom: 15px;\n                margin: 0;\n                position: absolute;\n                bottom: 50px;\n                left: 50%;\n                transform: translate(-50%, 0);\n                display: flex;\n                flex-direction: left;\n                pointer-events: auto;\n                min-width: 250px;\n            }\n\n            .messageContainerMin${this.elementID} {\n                margin-right: 15px;\n            }\n\n            .spinnerMin${this.elementID} {\n                width: 50px;\n                height: 50px;\n                margin-left: 15px;\n                margin-right: 25px;\n            }\n\n            .messageContainerMin${this.elementID} {\n                padding-top: 15px;\n            }\n            \n            @keyframes load {\n                to{transform: rotate(1turn)}\n            }\n\n        `;\n        this.spinnerContainerOuter.appendChild(style);\n        this.container.appendChild(this.spinnerContainerOuter);\n\n        this.setMinimized(false, true);\n\n        this.fadeTransitions = [];\n    }\n\n    addTask(message) {\n        const newTask = {\n            'message': message,\n            'id': this.taskIDGen++\n        };\n        this.tasks.push(newTask);\n        this.update();\n        return newTask.id;\n    }\n\n    removeTask(id) {\n        let index = 0;\n        for (let task of this.tasks) {\n            if (task.id === id) {\n                this.tasks.splice(index, 1);\n                break;\n            }\n            index++;\n        }\n        this.update();\n    }\n\n    removeAllTasks() {\n        this.tasks = [];\n        this.update();\n    }\n\n    setMessageForTask(id, message) {\n        for (let task of this.tasks) {\n            if (task.id === id) {\n                task.message = message;\n                break;\n            }\n        }\n        this.update();\n    }\n\n    update() {\n        if (this.tasks.length > 0) {\n            this.show();\n            this.setMessage(this.tasks[this.tasks.length - 1].message);\n        } else {\n            this.hide();\n        }\n    }\n\n    show() {\n        this.spinnerContainerOuter.style.display = 'block';\n        this.visible = true;\n    }\n\n    hide() {\n        this.spinnerContainerOuter.style.display = 'none';\n        this.visible = false;\n    }\n\n    setContainer(container) {\n        if (this.container && this.spinnerContainerOuter.parentElement === this.container) {\n            this.container.removeChild(this.spinnerContainerOuter);\n        }\n        if (container) {\n            this.container = container;\n            this.container.appendChild(this.spinnerContainerOuter);\n            this.spinnerContainerOuter.style.zIndex = this.container.style.zIndex + 1;\n        }\n    }\n\n    setMinimized(minimized, instant) {\n        const showHideSpinner = (element, show, instant, displayStyle, fadeTransitionsIndex) => {\n            if (instant) {\n                element.style.display = show ? displayStyle : 'none';\n            } else {\n                this.fadeTransitions[fadeTransitionsIndex] = fadeElement(element, !show, displayStyle, STANDARD_FADE_DURATION, () => {\n                    this.fadeTransitions[fadeTransitionsIndex] = null;\n                });\n            }\n        };\n        showHideSpinner(this.spinnerContainerPrimary, !minimized, instant, 'block', 0);\n        showHideSpinner(this.spinnerContainerMin, minimized, instant, 'flex', 1);\n        this.minimized = minimized;\n    }\n\n    setMessage(msg) {\n        this.messageContainerPrimary.innerHTML = msg;\n        this.messageContainerMin.innerHTML = msg;\n    }\n}\n","export const fadeElement = (element, out, displayStyle, duration, onComplete) => {\n    const startTime = performance.now();\n\n    let startOpacity = element.style.display === 'none' ? 0 : parseFloat(element.style.opacity);\n    if (isNaN(startOpacity)) startOpacity = 1;\n\n    const interval = window.setInterval(() => {\n        const currentTime = performance.now();\n        const elapsed = currentTime - startTime;\n\n        let t = Math.min(elapsed / duration, 1.0);\n        if (t > 0.999) t = 1;\n\n        let opacity;\n        if (out) {\n            opacity = (1.0 - t) * startOpacity;\n            if (opacity < 0.0001) opacity = 0;\n        } else {\n            opacity = (1.0 - startOpacity) * t + startOpacity;\n        }\n\n        if (opacity > 0) {\n            element.style.display = displayStyle;\n            element.style.opacity = opacity;\n        } else {\n            element.style.display = 'none';\n        }\n\n        if (t >= 1) {\n            if (onComplete) onComplete();\n            window.clearInterval(interval);\n        }\n    }, 16);\n    return interval;\n};\n\nexport const cancelFade = (interval) => {\n    window.clearInterval(interval);\n};\n","export class LoadingProgressBar {\n\n    constructor(container) {\n\n        this.idGen = 0;\n\n        this.tasks = [];\n\n        this.container = container || document.body;\n\n        this.progressBarContainerOuter = document.createElement('div');\n        this.progressBarContainerOuter.className = 'progressBarOuterContainer';\n        this.progressBarContainerOuter.style.display = 'none';\n\n        this.progressBarBox = document.createElement('div');\n        this.progressBarBox.className = 'progressBarBox';\n\n        this.progressBarBackground = document.createElement('div');\n        this.progressBarBackground.className = 'progressBarBackground';\n\n        this.progressBar = document.createElement('div');\n        this.progressBar.className = 'progressBar';\n\n        this.progressBarBackground.appendChild(this.progressBar);\n        this.progressBarBox.appendChild(this.progressBarBackground);\n        this.progressBarContainerOuter.appendChild(this.progressBarBox);\n\n        const style = document.createElement('style');\n        style.innerHTML = `\n\n            .progressBarOuterContainer {\n                width: 100%;\n                height: 100%;\n                margin: 0;\n                top: 0;\n                left: 0;\n                position: absolute;\n                pointer-events: none;\n            }\n\n            .progressBarBox {\n                z-index:99999;\n                padding: 7px 9px 5px 7px;\n                background-color: rgba(190, 190, 190, 0.75);\n                border: #555555 1px solid;\n                border-radius: 15px;\n                margin: 0;\n                position: absolute;\n                bottom: 50px;\n                left: 50%;\n                transform: translate(-50%, 0);\n                width: 180px;\n                height: 30px;\n                pointer-events: auto;\n            }\n\n            .progressBarBackground {\n                width: 100%;\n                height: 25px;\n                border-radius:10px;\n                background-color: rgba(128, 128, 128, 0.75);\n                border: #444444 1px solid;\n                box-shadow: inset 0 0 10px #333333;\n            }\n\n            .progressBar {\n                height: 25px;\n                width: 0px;\n                border-radius:10px;\n                background-color: rgba(0, 200, 0, 0.75);\n                box-shadow: inset 0 0 10px #003300;\n            }\n\n        `;\n        this.progressBarContainerOuter.appendChild(style);\n        this.container.appendChild(this.progressBarContainerOuter);\n    }\n\n    show() {\n        this.progressBarContainerOuter.style.display = 'block';\n    }\n\n    hide() {\n        this.progressBarContainerOuter.style.display = 'none';\n    }\n\n    setProgress(progress) {\n        this.progressBar.style.width = progress + '%';\n    }\n\n    setContainer(container) {\n        if (this.container && this.progressBarContainerOuter.parentElement === this.container) {\n            this.container.removeChild(this.progressBarContainerOuter);\n        }\n        if (container) {\n            this.container = container;\n            this.container.appendChild(this.progressBarContainerOuter);\n            this.progressBarContainerOuter.style.zIndex = this.container.style.zIndex + 1;\n        }\n    }\n\n}\n","export class InfoPanel {\n\n    constructor(container) {\n\n        this.container = container || document.body;\n\n        this.infoCells = {};\n\n        const layout = [\n            ['Camera position', 'cameraPosition'],\n            ['Camera look-at', 'cameraLookAt'],\n            ['Camera up', 'cameraUp'],\n            ['Camera mode', 'orthographicCamera'],\n            ['Cursor position', 'cursorPosition'],\n            ['FPS', 'fps'],\n            ['Rendering:', 'renderSplatCount'],\n            ['Sort time', 'sortTime'],\n            ['Render window', 'renderWindow'],\n            ['Focal adjustment', 'focalAdjustment'],\n            ['Splat scale', 'splatScale'],\n            ['Point cloud mode', 'pointCloudMode']\n        ];\n\n        this.infoPanelContainer = document.createElement('div');\n        const style = document.createElement('style');\n        style.innerHTML = `\n\n            .infoPanel {\n                width: 430px;\n                padding: 10px;\n                background-color: rgba(50, 50, 50, 0.85);\n                border: #555555 2px solid;\n                color: #dddddd;\n                border-radius: 10px;\n                z-index: 9999;\n                font-family: arial;\n                font-size: 11pt;\n                text-align: left;\n                margin: 0;\n                top: 10px;\n                left:10px;\n                position: absolute;\n                pointer-events: auto;\n            }\n\n            .info-panel-cell {\n                margin-bottom: 5px;\n                padding-bottom: 2px;\n            }\n\n            .label-cell {\n                font-weight: bold;\n                font-size: 12pt;\n                width: 140px;\n            }\n\n        `;\n        this.infoPanelContainer.append(style);\n\n        this.infoPanel = document.createElement('div');\n        this.infoPanel.className = 'infoPanel';\n\n        const infoTable = document.createElement('div');\n        infoTable.style.display = 'table';\n\n        for (let layoutEntry of layout) {\n            const row = document.createElement('div');\n            row.style.display = 'table-row';\n            row.className = 'info-panel-row';\n\n            const labelCell = document.createElement('div');\n            labelCell.style.display = 'table-cell';\n            labelCell.innerHTML = `${layoutEntry[0]}: `;\n            labelCell.classList.add('info-panel-cell', 'label-cell');\n\n            const spacerCell = document.createElement('div');\n            spacerCell.style.display = 'table-cell';\n            spacerCell.style.width = '10px';\n            spacerCell.innerHTML = ' ';\n            spacerCell.className = 'info-panel-cell';\n\n            const infoCell = document.createElement('div');\n            infoCell.style.display = 'table-cell';\n            infoCell.innerHTML = '';\n            infoCell.className = 'info-panel-cell';\n\n            this.infoCells[layoutEntry[1]] = infoCell;\n\n            row.appendChild(labelCell);\n            row.appendChild(spacerCell);\n            row.appendChild(infoCell);\n\n            infoTable.appendChild(row);\n        }\n\n        this.infoPanel.appendChild(infoTable);\n        this.infoPanelContainer.append(this.infoPanel);\n        this.infoPanelContainer.style.display = 'none';\n        this.container.appendChild(this.infoPanelContainer);\n\n        this.visible = false;\n        this.meshCursorPosition = null; \n    }\n\n    update = function(renderDimensions, cameraPosition, cameraLookAtPosition, cameraUp, orthographicCamera,\n                      meshCursorPosition, currentFPS, splatCount, splatRenderCount,\n                      splatRenderCountPct, lastSortTime, focalAdjustment, splatScale, pointCloudMode) {\n        this.meshCursorPosition = meshCursorPosition;\n        const cameraPosString = `${cameraPosition.x.toFixed(2)}, ${cameraPosition.y.toFixed(2)}, ${cameraPosition.z.toFixed(2)}`;\n        if (this.infoCells.cameraPosition.innerHTML !== cameraPosString) {\n            this.infoCells.cameraPosition.innerHTML = cameraPosString;\n        }\n\n        if (cameraLookAtPosition) {\n            const cla = cameraLookAtPosition;\n            const cameraLookAtString = `${cla.x.toFixed(2)}, ${cla.y.toFixed(2)}, ${cla.z.toFixed(2)}`;\n            if (this.infoCells.cameraLookAt.innerHTML !== cameraLookAtString) {\n                this.infoCells.cameraLookAt.innerHTML = cameraLookAtString;\n            }\n        }\n\n        const cameraUpString = `${cameraUp.x.toFixed(2)}, ${cameraUp.y.toFixed(2)}, ${cameraUp.z.toFixed(2)}`;\n        if (this.infoCells.cameraUp.innerHTML !== cameraUpString) {\n            this.infoCells.cameraUp.innerHTML = cameraUpString;\n        }\n\n        this.infoCells.orthographicCamera.innerHTML = orthographicCamera ? 'Orthographic' : 'Perspective';\n\n        if (meshCursorPosition) {\n            const cursPos = meshCursorPosition;\n            const cursorPosString = `${cursPos.x.toFixed(2)}, ${cursPos.y.toFixed(2)}, ${cursPos.z.toFixed(2)}`;\n            this.infoCells.cursorPosition.innerHTML = cursorPosString;\n        } else {\n            this.infoCells.cursorPosition.innerHTML = 'N/A';\n        }\n\n        this.infoCells.fps.innerHTML = currentFPS;\n        this.infoCells.renderWindow.innerHTML = `${renderDimensions.x} x ${renderDimensions.y}`;\n\n        this.infoCells.renderSplatCount.innerHTML =\n            `${splatRenderCount} splats out of ${splatCount} (${splatRenderCountPct.toFixed(2)}%)`;\n\n        this.infoCells.sortTime.innerHTML = `${lastSortTime.toFixed(3)} ms`;\n        this.infoCells.focalAdjustment.innerHTML = `${focalAdjustment.toFixed(3)}`;\n        this.infoCells.splatScale.innerHTML = `${splatScale.toFixed(3)}`;\n        this.infoCells.pointCloudMode.innerHTML = `${pointCloudMode}`;\n    };\n\n    setContainer(container) {\n        if (this.container && this.infoPanelContainer.parentElement === this.container) {\n            this.container.removeChild(this.infoPanelContainer);\n        }\n        if (container) {\n            this.container = container;\n            this.container.appendChild(this.infoPanelContainer);\n            this.infoPanelContainer.style.zIndex = this.container.style.zIndex + 1;\n        }\n    }\n\n    show() {\n        this.infoPanelContainer.style.display = 'block';\n        this.visible = true;\n    }\n\n    hide() {\n        this.infoPanelContainer.style.display = 'none';\n        this.visible = false;\n    }\n\n}\n","import * as THREE from 'three';\n\nconst _axis = new THREE.Vector3();\n\nexport class ArrowHelper extends THREE.Object3D {\n\n    constructor(dir = new THREE.Vector3(0, 0, 1), origin = new THREE.Vector3(0, 0, 0), length = 1,\n                radius = 0.1, color = 0xffff00, headLength = length * 0.2, headRadius = headLength * 0.2) {\n        super();\n\n        this.type = 'ArrowHelper';\n\n        const lineGeometry = new THREE.CylinderGeometry(radius, radius, length, 32);\n        lineGeometry.translate(0, length / 2.0, 0);\n        const coneGeometry = new THREE.CylinderGeometry( 0, headRadius, headLength, 32);\n        coneGeometry.translate(0, length, 0);\n\n        this.position.copy( origin );\n\n        this.line = new THREE.Mesh(lineGeometry, new THREE.MeshBasicMaterial({color: color, toneMapped: false}));\n        this.line.matrixAutoUpdate = false;\n        this.add(this.line);\n\n        this.cone = new THREE.Mesh(coneGeometry, new THREE.MeshBasicMaterial({color: color, toneMapped: false}));\n        this.cone.matrixAutoUpdate = false;\n        this.add(this.cone);\n\n        this.setDirection(dir);\n    }\n\n    setDirection( dir ) {\n        if (dir.y > 0.99999) {\n            this.quaternion.set(0, 0, 0, 1);\n        } else if (dir.y < - 0.99999) {\n            this.quaternion.set(1, 0, 0, 0);\n        } else {\n            _axis.set(dir.z, 0, -dir.x).normalize();\n            const radians = Math.acos(dir.y);\n            this.quaternion.setFromAxisAngle(_axis, radians);\n        }\n    }\n\n    setColor( color ) {\n        this.line.material.color.set(color);\n        this.cone.material.color.set(color);\n    }\n\n    copy(source) {\n        super.copy(source, false);\n        this.line.copy(source.line);\n        this.cone.copy(source.cone);\n        return this;\n    }\n\n    dispose() {\n        this.line.geometry.dispose();\n        this.line.material.dispose();\n        this.cone.geometry.dispose();\n        this.cone.material.dispose();\n    }\n\n}\n","import * as THREE from 'three';\nimport { ArrowHelper } from './ArrowHelper.js';\nimport { disposeAllMeshes } from './Util.js';\n\nexport class SceneHelper {\n\n    constructor(threeScene) {\n        this.threeScene = threeScene;\n        this.splatRenderTarget = null;\n        this.renderTargetCopyQuad = null;\n        this.renderTargetCopyCamera = null;\n        this.meshCursor = null;\n        this.focusMarker = null;\n        this.controlPlane = null;\n        this.debugRoot = null;\n        this.secondaryDebugRoot = null;\n    }\n\n    updateSplatRenderTargetForRenderDimensions(width, height) {\n        this.destroySplatRendertarget();\n        this.splatRenderTarget = new THREE.WebGLRenderTarget(width, height, {\n            format: THREE.RGBAFormat,\n            stencilBuffer: false,\n            depthBuffer: true,\n\n        });\n        this.splatRenderTarget.depthTexture = new THREE.DepthTexture(width, height);\n        this.splatRenderTarget.depthTexture.format = THREE.DepthFormat;\n        this.splatRenderTarget.depthTexture.type = THREE.UnsignedIntType;\n    }\n\n    destroySplatRendertarget() {\n        if (this.splatRenderTarget) {\n            this.splatRenderTarget = null;\n        }\n    }\n\n    setupRenderTargetCopyObjects() {\n        const uniforms = {\n            'sourceColorTexture': {\n                'type': 't',\n                'value': null\n            },\n            'sourceDepthTexture': {\n                'type': 't',\n                'value': null\n            },\n        };\n        const renderTargetCopyMaterial = new THREE.ShaderMaterial({\n            vertexShader: `\n                varying vec2 vUv;\n                void main() {\n                    vUv = uv;\n                    gl_Position = vec4( position.xy, 0.0, 1.0 );    \n                }\n            `,\n            fragmentShader: `\n                #include <common>\n                #include <packing>\n                varying vec2 vUv;\n                uniform sampler2D sourceColorTexture;\n                uniform sampler2D sourceDepthTexture;\n                void main() {\n                    vec4 color = texture2D(sourceColorTexture, vUv);\n                    float fragDepth = texture2D(sourceDepthTexture, vUv).x;\n                    gl_FragDepth = fragDepth;\n                    gl_FragColor = vec4(color.rgb, color.a * 2.0);\n              }\n            `,\n            uniforms: uniforms,\n            depthWrite: false,\n            depthTest: false,\n            transparent: true,\n            blending: THREE.CustomBlending,\n            blendSrc: THREE.SrcAlphaFactor,\n            blendSrcAlpha: THREE.SrcAlphaFactor,\n            blendDst: THREE.OneMinusSrcAlphaFactor,\n            blendDstAlpha: THREE.OneMinusSrcAlphaFactor\n        });\n        renderTargetCopyMaterial.extensions.fragDepth = true;\n        this.renderTargetCopyQuad = new THREE.Mesh(new THREE.PlaneGeometry(2, 2), renderTargetCopyMaterial);\n        this.renderTargetCopyCamera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);\n    }\n\n    destroyRenderTargetCopyObjects() {\n        if (this.renderTargetCopyQuad) {\n            disposeAllMeshes(this.renderTargetCopyQuad);\n            this.renderTargetCopyQuad = null;\n        }\n    }\n\n    setupMeshCursor() {\n        if (!this.meshCursor) {\n            const coneGeometry = new THREE.ConeGeometry(0.5, 1.5, 32);\n            const coneMaterial = new THREE.MeshBasicMaterial({color: 0xFFFFFF});\n\n            const downArrow = new THREE.Mesh(coneGeometry, coneMaterial);\n            downArrow.rotation.set(0, 0, Math.PI);\n            downArrow.position.set(0, 1, 0);\n            const upArrow = new THREE.Mesh(coneGeometry, coneMaterial);\n            upArrow.position.set(0, -1, 0);\n            const leftArrow = new THREE.Mesh(coneGeometry, coneMaterial);\n            leftArrow.rotation.set(0, 0, Math.PI / 2.0);\n            leftArrow.position.set(1, 0, 0);\n            const rightArrow = new THREE.Mesh(coneGeometry, coneMaterial);\n            rightArrow.rotation.set(0, 0, -Math.PI / 2.0);\n            rightArrow.position.set(-1, 0, 0);\n\n            this.meshCursor = new THREE.Object3D();\n            this.meshCursor.add(downArrow);\n            this.meshCursor.add(upArrow);\n            this.meshCursor.add(leftArrow);\n            this.meshCursor.add(rightArrow);\n            this.meshCursor.scale.set(0.1, 0.1, 0.1);\n            this.threeScene.add(this.meshCursor);\n            this.meshCursor.visible = false;\n        }\n    }\n\n    destroyMeshCursor() {\n        if (this.meshCursor) {\n            disposeAllMeshes(this.meshCursor);\n            this.threeScene.remove(this.meshCursor);\n            this.meshCursor = null;\n        }\n    }\n\n    setMeshCursorVisibility(visible) {\n        this.meshCursor.visible = visible;\n    }\n\n    getMeschCursorVisibility() {\n        return this.meshCursor.visible;\n    }\n\n    setMeshCursorPosition(position) {\n        this.meshCursor.position.copy(position);\n    }\n\n    positionAndOrientMeshCursor(position, camera) {\n        this.meshCursor.position.copy(position);\n        this.meshCursor.up.copy(camera.up);\n        this.meshCursor.lookAt(camera.position);\n    }\n\n    setupFocusMarker() {\n        if (!this.focusMarker) {\n            const sphereGeometry = new THREE.SphereGeometry(.5, 32, 32);\n            const focusMarkerMaterial = SceneHelper.buildFocusMarkerMaterial();\n            focusMarkerMaterial.depthTest = false;\n            focusMarkerMaterial.depthWrite = false;\n            focusMarkerMaterial.transparent = true;\n            this.focusMarker = new THREE.Mesh(sphereGeometry, focusMarkerMaterial);\n        }\n    }\n\n    destroyFocusMarker() {\n        if (this.focusMarker) {\n            disposeAllMeshes(this.focusMarker);\n            this.focusMarker = null;\n        }\n    }\n\n    updateFocusMarker = function() {\n\n        const tempPosition = new THREE.Vector3();\n        const tempMatrix = new THREE.Matrix4();\n        const toCamera = new THREE.Vector3();\n\n        return function(position, camera, viewport) {\n            tempMatrix.copy(camera.matrixWorld).invert();\n            tempPosition.copy(position).applyMatrix4(tempMatrix);\n            tempPosition.normalize().multiplyScalar(10);\n            tempPosition.applyMatrix4(camera.matrixWorld);\n            toCamera.copy(camera.position).sub(position);\n            const toCameraDistance = toCamera.length();\n            this.focusMarker.position.copy(position);\n            this.focusMarker.scale.set(toCameraDistance, toCameraDistance, toCameraDistance);\n            this.focusMarker.material.uniforms.realFocusPosition.value.copy(position);\n            this.focusMarker.material.uniforms.viewport.value.copy(viewport);\n            this.focusMarker.material.uniformsNeedUpdate = true;\n        };\n\n    }();\n\n    setFocusMarkerVisibility(visible) {\n        this.focusMarker.visible = visible;\n    }\n\n    setFocusMarkerOpacity(opacity) {\n        this.focusMarker.material.uniforms.opacity.value = opacity;\n        this.focusMarker.material.uniformsNeedUpdate = true;\n    }\n\n    getFocusMarkerOpacity() {\n        return this.focusMarker.material.uniforms.opacity.value;\n    }\n\n    setupControlPlane() {\n        if (!this.controlPlane) {\n            const planeGeometry = new THREE.PlaneGeometry(1, 1);\n            planeGeometry.rotateX(-Math.PI / 2);\n            const planeMaterial = new THREE.MeshBasicMaterial({color: 0xffffff});\n            planeMaterial.transparent = true;\n            planeMaterial.opacity = 0.6;\n            planeMaterial.depthTest = false;\n            planeMaterial.depthWrite = false;\n            planeMaterial.side = THREE.DoubleSide;\n            const planeMesh = new THREE.Mesh(planeGeometry, planeMaterial);\n\n            const arrowDir = new THREE.Vector3(0, 1, 0);\n            arrowDir.normalize();\n            const arrowOrigin = new THREE.Vector3(0, 0, 0);\n            const arrowLength = 0.5;\n            const arrowRadius = 0.01;\n            const arrowColor = 0x00dd00;\n            const arrowHelper = new ArrowHelper(arrowDir, arrowOrigin, arrowLength, arrowRadius, arrowColor, 0.1, 0.03);\n\n            this.controlPlane = new THREE.Object3D();\n            this.controlPlane.add(planeMesh);\n            this.controlPlane.add(arrowHelper);\n        }\n    }\n\n    destroyControlPlane() {\n        if (this.controlPlane) {\n            disposeAllMeshes(this.controlPlane);\n            this.controlPlane = null;\n        }\n    }\n\n    setControlPlaneVisibility(visible) {\n        this.controlPlane.visible = visible;\n    }\n\n    positionAndOrientControlPlane = function() {\n\n        const tempQuaternion = new THREE.Quaternion();\n        const defaultUp = new THREE.Vector3(0, 1, 0);\n\n        return function(position, up) {\n            tempQuaternion.setFromUnitVectors(defaultUp, up);\n            this.controlPlane.position.copy(position);\n            this.controlPlane.quaternion.copy(tempQuaternion);\n        };\n\n    }();\n\n    addDebugMeshes() {\n        this.debugRoot = this.createDebugMeshes();\n        this.secondaryDebugRoot = this.createSecondaryDebugMeshes();\n        this.threeScene.add(this.debugRoot);\n        this.threeScene.add(this.secondaryDebugRoot);\n    }\n\n    destroyDebugMeshes() {\n        for (let debugRoot of [this.debugRoot, this.secondaryDebugRoot]) {\n            if (debugRoot) {\n                disposeAllMeshes(debugRoot);\n                this.threeScene.remove(debugRoot);\n            }\n        }\n        this.debugRoot = null;\n        this.secondaryDebugRoot = null;\n    }\n\n    createDebugMeshes(renderOrder) {\n        const sphereGeometry = new THREE.SphereGeometry(1, 32, 32);\n        const debugMeshRoot = new THREE.Object3D();\n\n        const createMesh = (color, position) => {\n            let sphereMesh = new THREE.Mesh(sphereGeometry, SceneHelper.buildDebugMaterial(color));\n            sphereMesh.renderOrder = renderOrder;\n            debugMeshRoot.add(sphereMesh);\n            sphereMesh.position.fromArray(position);\n        };\n\n        createMesh(0xff0000, [-50, 0, 0]);\n        createMesh(0xff0000, [50, 0, 0]);\n        createMesh(0x00ff00, [0, 0, -50]);\n        createMesh(0x00ff00, [0, 0, 50]);\n        createMesh(0xffaa00, [5, 0, 5]);\n\n        return debugMeshRoot;\n    }\n\n    createSecondaryDebugMeshes(renderOrder) {\n        const boxGeometry = new THREE.BoxGeometry(3, 3, 3);\n        const debugMeshRoot = new THREE.Object3D();\n\n        let boxColor = 0xBBBBBB;\n        const createMesh = (position) => {\n            let boxMesh = new THREE.Mesh(boxGeometry, SceneHelper.buildDebugMaterial(boxColor));\n            boxMesh.renderOrder = renderOrder;\n            debugMeshRoot.add(boxMesh);\n            boxMesh.position.fromArray(position);\n        };\n\n        let separation = 10;\n        createMesh([-separation, 0, -separation]);\n        createMesh([-separation, 0, separation]);\n        createMesh([separation, 0, -separation]);\n        createMesh([separation, 0, separation]);\n\n        return debugMeshRoot;\n    }\n\n    static buildDebugMaterial(color) {\n        const vertexShaderSource = `\n            #include <common>\n            varying float ndcDepth;\n\n            void main() {\n                gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position.xyz, 1.0);\n                ndcDepth = gl_Position.z / gl_Position.w;\n                gl_Position.x = gl_Position.x / gl_Position.w;\n                gl_Position.y = gl_Position.y / gl_Position.w;\n                gl_Position.z = 0.0;\n                gl_Position.w = 1.0;\n    \n            }\n        `;\n\n        const fragmentShaderSource = `\n            #include <common>\n            uniform vec3 color;\n            varying float ndcDepth;\n            void main() {\n                gl_FragDepth = (ndcDepth + 1.0) / 2.0;\n                gl_FragColor = vec4(color.rgb, 0.0);\n            }\n        `;\n\n        const uniforms = {\n            'color': {\n                'type': 'v3',\n                'value': new THREE.Color(color)\n            },\n        };\n\n        const material = new THREE.ShaderMaterial({\n            uniforms: uniforms,\n            vertexShader: vertexShaderSource,\n            fragmentShader: fragmentShaderSource,\n            transparent: false,\n            depthTest: true,\n            depthWrite: true,\n            side: THREE.FrontSide\n        });\n        material.extensions.fragDepth = true;\n\n        return material;\n    }\n\n    static buildFocusMarkerMaterial(color) {\n        const vertexShaderSource = `\n            #include <common>\n\n            uniform vec2 viewport;\n            uniform vec3 realFocusPosition;\n\n            varying vec4 ndcPosition;\n            varying vec4 ndcCenter;\n            varying vec4 ndcFocusPosition;\n\n            void main() {\n                float radius = 0.01;\n\n                vec4 viewPosition = modelViewMatrix * vec4(position.xyz, 1.0);\n                vec4 viewCenter = modelViewMatrix * vec4(0.0, 0.0, 0.0, 1.0);\n\n                vec4 viewFocusPosition = modelViewMatrix * vec4(realFocusPosition, 1.0);\n\n                ndcPosition = projectionMatrix * viewPosition;\n                ndcPosition = ndcPosition * vec4(1.0 / ndcPosition.w);\n                ndcCenter = projectionMatrix * viewCenter;\n                ndcCenter = ndcCenter * vec4(1.0 / ndcCenter.w);\n\n                ndcFocusPosition = projectionMatrix * viewFocusPosition;\n                ndcFocusPosition = ndcFocusPosition * vec4(1.0 / ndcFocusPosition.w);\n\n                gl_Position = projectionMatrix * viewPosition;\n\n            }\n        `;\n\n        const fragmentShaderSource = `\n            #include <common>\n            uniform vec3 color;\n            uniform vec2 viewport;\n            uniform float opacity;\n\n            varying vec4 ndcPosition;\n            varying vec4 ndcCenter;\n            varying vec4 ndcFocusPosition;\n\n            void main() {\n                vec2 screenPosition = vec2(ndcPosition) * viewport;\n                vec2 screenCenter = vec2(ndcCenter) * viewport;\n\n                vec2 screenVec = screenPosition - screenCenter;\n\n                float projectedRadius = length(screenVec);\n\n                float lineWidth = 0.0005 * viewport.y;\n                float aaRange = 0.0025 * viewport.y;\n                float radius = 0.06 * viewport.y;\n                float radDiff = abs(projectedRadius - radius) - lineWidth;\n                float alpha = 1.0 - clamp(radDiff / 5.0, 0.0, 1.0); \n\n                gl_FragColor = vec4(color.rgb, alpha * opacity);\n            }\n        `;\n\n        const uniforms = {\n            'color': {\n                'type': 'v3',\n                'value': new THREE.Color(color)\n            },\n            'realFocusPosition': {\n                'type': 'v3',\n                'value': new THREE.Vector3()\n            },\n            'viewport': {\n                'type': 'v2',\n                'value': new THREE.Vector2()\n            },\n            'opacity': {\n                'value': 0.0\n            }\n        };\n\n        const material = new THREE.ShaderMaterial({\n            uniforms: uniforms,\n            vertexShader: vertexShaderSource,\n            fragmentShader: fragmentShaderSource,\n            transparent: true,\n            depthTest: false,\n            depthWrite: false,\n            side: THREE.FrontSide\n        });\n\n        return material;\n    }\n\n    dispose() {\n        this.destroyMeshCursor();\n        this.destroyFocusMarker();\n        this.destroyDebugMeshes();\n        this.destroyControlPlane();\n        this.destroyRenderTargetCopyObjects();\n        this.destroySplatRendertarget();\n    }\n}\n","import * as THREE from 'three';\n\nconst VectorRight = new THREE.Vector3(1, 0, 0);\nconst VectorUp = new THREE.Vector3(0, 1, 0);\nconst VectorBackward = new THREE.Vector3(0, 0, 1);\n\nexport class Ray {\n\n    constructor(origin = new THREE.Vector3(), direction = new THREE.Vector3()) {\n        this.origin = new THREE.Vector3();\n        this.direction = new THREE.Vector3();\n        this.setParameters(origin, direction);\n    }\n\n    setParameters(origin, direction) {\n        this.origin.copy(origin);\n        this.direction.copy(direction).normalize();\n    }\n\n    boxContainsPoint(box, point, epsilon) {\n        return point.x < box.min.x - epsilon || point.x > box.max.x + epsilon ||\n               point.y < box.min.y - epsilon || point.y > box.max.y + epsilon ||\n               point.z < box.min.z - epsilon || point.z > box.max.z + epsilon ? false : true;\n    }\n\n    intersectBox = function() {\n\n        const planeIntersectionPoint = new THREE.Vector3();\n        const planeIntersectionPointArray = [];\n        const originArray = [];\n        const directionArray = [];\n\n        return function(box, outHit) {\n\n            originArray[0] = this.origin.x;\n            originArray[1] = this.origin.y;\n            originArray[2] = this.origin.z;\n            directionArray[0] = this.direction.x;\n            directionArray[1] = this.direction.y;\n            directionArray[2] = this.direction.z;\n\n            if (this.boxContainsPoint(box, this.origin, 0.0001)) {\n                if (outHit) {\n                    outHit.origin.copy(this.origin);\n                    outHit.normal.set(0, 0, 0);\n                    outHit.distance = -1;\n                }\n                return true;\n            }\n\n            for (let i = 0; i < 3; i++) {\n                if (directionArray[i] == 0.0) continue;\n\n                const hitNormal = i == 0 ? VectorRight : i == 1 ? VectorUp : VectorBackward;\n                const extremeVec = directionArray[i] < 0 ? box.max : box.min;\n                let multiplier = -Math.sign(directionArray[i]);\n                planeIntersectionPointArray[0] = i == 0 ? extremeVec.x : i == 1 ? extremeVec.y : extremeVec.z;\n                let toSide = planeIntersectionPointArray[0] - originArray[i];\n\n                if (toSide * multiplier < 0) {\n                    const idx1 = (i + 1) % 3;\n                    const idx2 = (i + 2) % 3;\n                    planeIntersectionPointArray[2] = directionArray[idx1] / directionArray[i] * toSide + originArray[idx1];\n                    planeIntersectionPointArray[1] = directionArray[idx2] / directionArray[i] * toSide + originArray[idx2];\n                    planeIntersectionPoint.set(planeIntersectionPointArray[i],\n                                               planeIntersectionPointArray[idx2],\n                                               planeIntersectionPointArray[idx1]);\n                    if (this.boxContainsPoint(box, planeIntersectionPoint, 0.0001)) {\n                        if (outHit) {\n                            outHit.origin.copy(planeIntersectionPoint);\n                            outHit.normal.copy(hitNormal).multiplyScalar(multiplier);\n                            outHit.distance = planeIntersectionPoint.sub(this.origin).length();\n                        }\n                        return true;\n                    }\n                }\n            }\n\n            return false;\n        };\n\n    }();\n\n    intersectSphere = function() {\n\n        const toSphereCenterVec = new THREE.Vector3();\n\n        return function(center, radius, outHit) {\n            toSphereCenterVec.copy(center).sub(this.origin);\n            const toClosestApproach = toSphereCenterVec.dot(this.direction);\n            const toClosestApproachSq = toClosestApproach * toClosestApproach;\n            const toSphereCenterSq = toSphereCenterVec.dot(toSphereCenterVec);\n            const diffSq = toSphereCenterSq - toClosestApproachSq;\n            const radiusSq = radius * radius;\n\n            if (diffSq > radiusSq) return false;\n\n            const thc = Math.sqrt(radiusSq - diffSq);\n            const t0 = toClosestApproach - thc;\n            const t1 = toClosestApproach + thc;\n\n            if (t1 < 0) return false;\n            let t = t0 < 0 ? t1 : t0;\n\n            if (outHit) {\n                outHit.origin.copy(this.origin).addScaledVector(this.direction, t);\n                outHit.normal.copy(outHit.origin).sub(center).normalize();\n                outHit.distance = t;\n            }\n            return true;\n        };\n\n    }();\n}\n","import * as THREE from 'three';\n\nexport class Hit {\n\n    constructor() {\n        this.origin = new THREE.Vector3();\n        this.normal = new THREE.Vector3();\n        this.distance = 0;\n        this.splatIndex = 0;\n    }\n\n    set(origin, normal, distance, splatIndex) {\n        this.origin.copy(origin);\n        this.normal.copy(normal);\n        this.distance = distance;\n        this.splatIndex = splatIndex;\n    }\n\n    clone() {\n        const hitClone = new Hit();\n        hitClone.origin.copy(this.origin);\n        hitClone.normal.copy(this.normal);\n        hitClone.distance = this.distance;\n        hitClone.splatIndex = this.splatIndex;\n        return hitClone;\n    }\n\n}\n","export const SplatRenderMode = {\n    ThreeD: 0,\n    TwoD: 1\n};\n","import * as THREE from 'three';\nimport { Ray } from './Ray.js';\nimport { Hit } from './Hit.js';\nimport { SplatRenderMode } from '../SplatRenderMode.js';\n\nexport class Raycaster {\n\n    constructor(origin, direction, raycastAgainstTrueSplatEllipsoid = false) {\n        this.ray = new Ray(origin, direction);\n        this.raycastAgainstTrueSplatEllipsoid = raycastAgainstTrueSplatEllipsoid;\n    }\n\n    setFromCameraAndScreenPosition = function() {\n\n        const ndcCoords = new THREE.Vector2();\n\n        return function(camera, screenPosition, screenDimensions) {\n            ndcCoords.x = screenPosition.x / screenDimensions.x * 2.0 - 1.0;\n            ndcCoords.y = (screenDimensions.y - screenPosition.y) / screenDimensions.y * 2.0 - 1.0;\n            if (camera.isPerspectiveCamera) {\n                this.ray.origin.setFromMatrixPosition(camera.matrixWorld);\n                this.ray.direction.set(ndcCoords.x, ndcCoords.y, 0.5 ).unproject(camera).sub(this.ray.origin).normalize();\n                this.camera = camera;\n            } else if (camera.isOrthographicCamera) {\n                this.ray.origin.set(ndcCoords.x, ndcCoords.y,\n                                   (camera.near + camera.far) / (camera.near - camera.far)).unproject(camera);\n                this.ray.direction.set(0, 0, -1).transformDirection(camera.matrixWorld);\n                this.camera = camera;\n            } else {\n                throw new Error('Raycaster::setFromCameraAndScreenPosition() -> Unsupported camera type');\n            }\n        };\n\n    }();\n\n    intersectSplatMesh = function() {\n\n        const toLocal = new THREE.Matrix4();\n        const fromLocal = new THREE.Matrix4();\n        const sceneTransform = new THREE.Matrix4();\n        const localRay = new Ray();\n        const tempPoint = new THREE.Vector3();\n\n        return function(splatMesh, outHits = []) {\n            const splatTree = splatMesh.getSplatTree();\n\n            if (!splatTree) return;\n\n            for (let s = 0; s < splatTree.subTrees.length; s++) {\n                const subTree = splatTree.subTrees[s];\n\n                fromLocal.copy(splatMesh.matrixWorld);\n                if (splatMesh.dynamicMode) {\n                    splatMesh.getSceneTransform(s, sceneTransform);\n                    fromLocal.multiply(sceneTransform);\n                }\n                toLocal.copy(fromLocal).invert();\n\n                localRay.origin.copy(this.ray.origin).applyMatrix4(toLocal);\n                localRay.direction.copy(this.ray.origin).add(this.ray.direction);\n                localRay.direction.applyMatrix4(toLocal).sub(localRay.origin).normalize();\n\n                const outHitsForSubTree = [];\n                if (subTree.rootNode) {\n                    this.castRayAtSplatTreeNode(localRay, splatTree, subTree.rootNode, outHitsForSubTree);\n                }\n\n                outHitsForSubTree.forEach((hit) => {\n                    hit.origin.applyMatrix4(fromLocal);\n                    hit.normal.applyMatrix4(fromLocal).normalize();\n                    hit.distance = tempPoint.copy(hit.origin).sub(this.ray.origin).length();\n                });\n\n                outHits.push(...outHitsForSubTree);\n            }\n\n            outHits.sort((a, b) => {\n                if (a.distance > b.distance) return 1;\n                else return -1;\n            });\n\n            return outHits;\n        };\n\n    }();\n\n    castRayAtSplatTreeNode = function() {\n\n        const tempColor = new THREE.Vector4();\n        const tempCenter = new THREE.Vector3();\n        const tempScale = new THREE.Vector3();\n        const tempRotation = new THREE.Quaternion();\n        const tempHit = new Hit();\n        const scaleEpsilon = 0.0000001;\n\n        const origin = new THREE.Vector3(0, 0, 0);\n        const uniformScaleMatrix = new THREE.Matrix4();\n        const scaleMatrix = new THREE.Matrix4();\n        const rotationMatrix = new THREE.Matrix4();\n        const toSphereSpace = new THREE.Matrix4();\n        const fromSphereSpace = new THREE.Matrix4();\n        const tempRay = new Ray();\n\n        return function(ray, splatTree, node, outHits = []) {\n            if (!ray.intersectBox(node.boundingBox)) {\n                return;\n            }\n            if (node.data && node.data.indexes && node.data.indexes.length > 0) {\n                for (let i = 0; i < node.data.indexes.length; i++) {\n\n                    const splatGlobalIndex = node.data.indexes[i];\n                    const splatSceneIndex = splatTree.splatMesh.getSceneIndexForSplat(splatGlobalIndex);\n                    const splatScene = splatTree.splatMesh.getScene(splatSceneIndex);\n                    if (!splatScene.visible) continue;\n\n                    splatTree.splatMesh.getSplatColor(splatGlobalIndex, tempColor);\n                    splatTree.splatMesh.getSplatCenter(splatGlobalIndex, tempCenter);\n                    splatTree.splatMesh.getSplatScaleAndRotation(splatGlobalIndex, tempScale, tempRotation);\n\n                    if (tempScale.x <= scaleEpsilon || tempScale.y <= scaleEpsilon ||\n                        splatTree.splatMesh.splatRenderMode === SplatRenderMode.ThreeD && tempScale.z <= scaleEpsilon) {\n                        continue;\n                    }\n\n                    if (!this.raycastAgainstTrueSplatEllipsoid) {\n                        let radius = (tempScale.x + tempScale.y);\n                        let componentCount = 2;\n                        if (splatTree.splatMesh.splatRenderMode === SplatRenderMode.ThreeD) {\n                            radius += tempScale.z;\n                            componentCount = 3;\n                        }\n                        radius = radius / componentCount;\n                        if (ray.intersectSphere(tempCenter, radius, tempHit)) {\n                            const hitClone = tempHit.clone();\n                            hitClone.splatIndex = splatGlobalIndex;\n                            outHits.push(hitClone);\n                        }\n                    } else {\n                        scaleMatrix.makeScale(tempScale.x, tempScale.y, tempScale.z);\n                        rotationMatrix.makeRotationFromQuaternion(tempRotation);\n                        const uniformScale = Math.log10(tempColor.w) * 2.0;\n                        uniformScaleMatrix.makeScale(uniformScale, uniformScale, uniformScale);\n                        fromSphereSpace.copy(uniformScaleMatrix).multiply(rotationMatrix).multiply(scaleMatrix);\n                        toSphereSpace.copy(fromSphereSpace).invert();\n                        tempRay.origin.copy(ray.origin).sub(tempCenter).applyMatrix4(toSphereSpace);\n                        tempRay.direction.copy(ray.origin).add(ray.direction).sub(tempCenter);\n                        tempRay.direction.applyMatrix4(toSphereSpace).sub(tempRay.origin).normalize();\n                        if (tempRay.intersectSphere(origin, 1.0, tempHit)) {\n                            const hitClone = tempHit.clone();\n                            hitClone.splatIndex = splatGlobalIndex;\n                            hitClone.origin.applyMatrix4(fromSphereSpace).add(tempCenter);\n                            outHits.push(hitClone);\n                        }\n                    }\n                }\n             }\n            if (node.children && node.children.length > 0) {\n                for (let child of node.children) {\n                    this.castRayAtSplatTreeNode(ray, splatTree, child, outHits);\n                }\n            }\n            return outHits;\n        };\n\n    }();\n}\n","import * as THREE from 'three';\nimport { Constants } from '../Constants.js';\n\nexport class SplatMaterial {\n\n    static buildVertexShaderBase(dynamicMode = false, enableOptionalEffects = false, maxSphericalHarmonicsDegree = 0, customVars = '') {\n        let vertexShaderSource = `\n        precision highp float;\n        #include <common>\n\n        attribute uint splatIndex;\n        uniform highp usampler2D centersColorsTexture;\n        uniform highp sampler2D sphericalHarmonicsTexture;\n        uniform highp sampler2D sphericalHarmonicsTextureR;\n        uniform highp sampler2D sphericalHarmonicsTextureG;\n        uniform highp sampler2D sphericalHarmonicsTextureB;\n\n        uniform highp usampler2D sceneIndexesTexture;\n        uniform vec2 sceneIndexesTextureSize;\n        uniform int sceneCount;\n    `;\n\n    if (enableOptionalEffects) {\n        vertexShaderSource += `\n            uniform float sceneOpacity[${Constants.MaxScenes}];\n            uniform int sceneVisibility[${Constants.MaxScenes}];\n        `;\n    }\n\n    if (dynamicMode) {\n        vertexShaderSource += `\n            uniform highp mat4 transforms[${Constants.MaxScenes}];\n        `;\n    }\n\n    vertexShaderSource += `\n        ${customVars}\n        uniform vec2 focal;\n        uniform float orthoZoom;\n        uniform int orthographicMode;\n        uniform int pointCloudModeEnabled;\n        uniform float inverseFocalAdjustment;\n        uniform vec2 viewport;\n        uniform vec2 basisViewport;\n        uniform vec2 centersColorsTextureSize;\n        uniform int sphericalHarmonicsDegree;\n        uniform vec2 sphericalHarmonicsTextureSize;\n        uniform int sphericalHarmonics8BitMode;\n        uniform int sphericalHarmonicsMultiTextureMode;\n        uniform float visibleRegionRadius;\n        uniform float visibleRegionFadeStartRadius;\n        uniform float firstRenderTime;\n        uniform float currentTime;\n        uniform int fadeInComplete;\n        uniform vec3 sceneCenter;\n        uniform float splatScale;\n        uniform float sphericalHarmonics8BitCompressionRangeMin[${Constants.MaxScenes}];\n        uniform float sphericalHarmonics8BitCompressionRangeMax[${Constants.MaxScenes}];\n\n        varying vec4 vColor;\n        varying vec2 vUv;\n        varying vec2 vPosition;\n\n        mat3 quaternionToRotationMatrix(float x, float y, float z, float w) {\n            float s = 1.0 / sqrt(w * w + x * x + y * y + z * z);\n        \n            return mat3(\n                1. - 2. * (y * y + z * z),\n                2. * (x * y + w * z),\n                2. * (x * z - w * y),\n                2. * (x * y - w * z),\n                1. - 2. * (x * x + z * z),\n                2. * (y * z + w * x),\n                2. * (x * z + w * y),\n                2. * (y * z - w * x),\n                1. - 2. * (x * x + y * y)\n            );\n        }\n\n        const float sqrt8 = sqrt(8.0);\n        const float minAlpha = 1.0 / 255.0;\n\n        const vec4 encodeNorm4 = vec4(1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0);\n        const uvec4 mask4 = uvec4(uint(0x000000FF), uint(0x0000FF00), uint(0x00FF0000), uint(0xFF000000));\n        const uvec4 shift4 = uvec4(0, 8, 16, 24);\n        vec4 uintToRGBAVec (uint u) {\n           uvec4 urgba = mask4 & u;\n           urgba = urgba >> shift4;\n           vec4 rgba = vec4(urgba) * encodeNorm4;\n           return rgba;\n        }\n\n        vec2 getDataUV(in int stride, in int offset, in vec2 dimensions) {\n            vec2 samplerUV = vec2(0.0, 0.0);\n            float d = float(splatIndex * uint(stride) + uint(offset)) / dimensions.x;\n            samplerUV.y = float(floor(d)) / dimensions.y;\n            samplerUV.x = fract(d);\n            return samplerUV;\n        }\n\n        vec2 getDataUVF(in uint sIndex, in float stride, in uint offset, in vec2 dimensions) {\n            vec2 samplerUV = vec2(0.0, 0.0);\n            float d = float(uint(float(sIndex) * stride) + offset) / dimensions.x;\n            samplerUV.y = float(floor(d)) / dimensions.y;\n            samplerUV.x = fract(d);\n            return samplerUV;\n        }\n\n        const float SH_C1 = 0.4886025119029199f;\n        const float[5] SH_C2 = float[](1.0925484, -1.0925484, 0.3153916, -1.0925484, 0.5462742);\n\n        void main () {\n\n            uint oddOffset = splatIndex & uint(0x00000001);\n            uint doubleOddOffset = oddOffset * uint(2);\n            bool isEven = oddOffset == uint(0);\n            uint nearestEvenIndex = splatIndex - oddOffset;\n            float fOddOffset = float(oddOffset);\n\n            uvec4 sampledCenterColor = texture(centersColorsTexture, getDataUV(1, 0, centersColorsTextureSize));\n            vec3 splatCenter = uintBitsToFloat(uvec3(sampledCenterColor.gba));\n\n            uint sceneIndex = uint(0);\n            if (sceneCount > 1) {\n                sceneIndex = texture(sceneIndexesTexture, getDataUV(1, 0, sceneIndexesTextureSize)).r;\n            }\n            `;\n\n        if (enableOptionalEffects) {\n            vertexShaderSource += `\n                float splatOpacityFromScene = sceneOpacity[sceneIndex];\n                int sceneVisible = sceneVisibility[sceneIndex];\n                if (splatOpacityFromScene <= 0.01 || sceneVisible == 0) {\n                    gl_Position = vec4(0.0, 0.0, 2.0, 1.0);\n                    return;\n                }\n            `;\n        }\n\n        if (dynamicMode) {\n            vertexShaderSource += `\n                mat4 transform = transforms[sceneIndex];\n                mat4 transformModelViewMatrix = viewMatrix * transform;\n            `;\n        } else {\n            vertexShaderSource += `mat4 transformModelViewMatrix = modelViewMatrix;`;\n        }\n\n        vertexShaderSource += `\n            float sh8BitCompressionRangeMinForScene = sphericalHarmonics8BitCompressionRangeMin[sceneIndex];\n            float sh8BitCompressionRangeMaxForScene = sphericalHarmonics8BitCompressionRangeMax[sceneIndex];\n            float sh8BitCompressionRangeForScene = sh8BitCompressionRangeMaxForScene - sh8BitCompressionRangeMinForScene;\n            float sh8BitCompressionHalfRangeForScene = sh8BitCompressionRangeForScene / 2.0;\n            vec3 vec8BitSHShift = vec3(sh8BitCompressionRangeMinForScene);\n\n            vec4 viewCenter = transformModelViewMatrix * vec4(splatCenter, 1.0);\n\n            vec4 clipCenter = projectionMatrix * viewCenter;\n\n            float clip = 1.2 * clipCenter.w;\n            if (clipCenter.z < -clip || clipCenter.x < -clip || clipCenter.x > clip || clipCenter.y < -clip || clipCenter.y > clip) {\n                gl_Position = vec4(0.0, 0.0, 2.0, 1.0);\n                return;\n            }\n\n            vec3 ndcCenter = clipCenter.xyz / clipCenter.w;\n\n            vPosition = position.xy;\n            vColor = uintToRGBAVec(sampledCenterColor.r);\n        `;\n\n        // Proceed to sampling and rendering 1st degree spherical harmonics\n        if (maxSphericalHarmonicsDegree >= 1) {\n\n            vertexShaderSource += `   \n            if (sphericalHarmonicsDegree >= 1) {\n            `;\n\n            if (dynamicMode) {\n                vertexShaderSource += `\n                    vec3 worldViewDir = normalize(splatCenter - vec3(inverse(transform) * vec4(cameraPosition, 1.0)));\n                `;\n            } else {\n                vertexShaderSource += `\n                    vec3 worldViewDir = normalize(splatCenter - cameraPosition);\n                `;\n            }\n\n            vertexShaderSource += `\n                vec3 sh1;\n                vec3 sh2;\n                vec3 sh3;\n            `;\n\n            if (maxSphericalHarmonicsDegree >= 2) {\n                vertexShaderSource += `\n                    vec3 sh4;\n                    vec3 sh5;\n                    vec3 sh6;\n                    vec3 sh7;\n                    vec3 sh8;\n                `;\n            }\n\n            // Determining how to sample spherical harmonics textures to get the coefficients for calculations for a given degree\n            // depends on how many total degrees (maxSphericalHarmonicsDegree) are present in the textures. This is because that\n            // number affects how they are packed in the textures, and therefore the offset & stride required to access them.\n\n            // Sample spherical harmonics textures with 1 degree worth of data for 1st degree calculations, and store in sh1, sh2, and sh3\n            if (maxSphericalHarmonicsDegree === 1) {\n                vertexShaderSource += `\n                    if (sphericalHarmonicsMultiTextureMode == 0) {\n                        vec2 shUV = getDataUVF(nearestEvenIndex, 2.5, doubleOddOffset, sphericalHarmonicsTextureSize);\n                        vec4 sampledSH0123 = texture(sphericalHarmonicsTexture, shUV);\n                        shUV = getDataUVF(nearestEvenIndex, 2.5, doubleOddOffset + uint(1), sphericalHarmonicsTextureSize);\n                        vec4 sampledSH4567 = texture(sphericalHarmonicsTexture, shUV);\n                        shUV = getDataUVF(nearestEvenIndex, 2.5, doubleOddOffset + uint(2), sphericalHarmonicsTextureSize);\n                        vec4 sampledSH891011 = texture(sphericalHarmonicsTexture, shUV);\n                        sh1 = vec3(sampledSH0123.rgb) * (1.0 - fOddOffset) + vec3(sampledSH0123.ba, sampledSH4567.r) * fOddOffset;\n                        sh2 = vec3(sampledSH0123.a, sampledSH4567.rg) * (1.0 - fOddOffset) + vec3(sampledSH4567.gba) * fOddOffset;\n                        sh3 = vec3(sampledSH4567.ba, sampledSH891011.r) * (1.0 - fOddOffset) + vec3(sampledSH891011.rgb) * fOddOffset;\n                    } else {\n                        vec2 sampledSH01R = texture(sphericalHarmonicsTextureR, getDataUV(2, 0, sphericalHarmonicsTextureSize)).rg;\n                        vec2 sampledSH23R = texture(sphericalHarmonicsTextureR, getDataUV(2, 1, sphericalHarmonicsTextureSize)).rg;\n                        vec2 sampledSH01G = texture(sphericalHarmonicsTextureG, getDataUV(2, 0, sphericalHarmonicsTextureSize)).rg;\n                        vec2 sampledSH23G = texture(sphericalHarmonicsTextureG, getDataUV(2, 1, sphericalHarmonicsTextureSize)).rg;\n                        vec2 sampledSH01B = texture(sphericalHarmonicsTextureB, getDataUV(2, 0, sphericalHarmonicsTextureSize)).rg;\n                        vec2 sampledSH23B = texture(sphericalHarmonicsTextureB, getDataUV(2, 1, sphericalHarmonicsTextureSize)).rg;\n                        sh1 = vec3(sampledSH01R.rg, sampledSH23R.r);\n                        sh2 = vec3(sampledSH01G.rg, sampledSH23G.r);\n                        sh3 = vec3(sampledSH01B.rg, sampledSH23B.r);\n                    }\n                `;\n            // Sample spherical harmonics textures with 2 degrees worth of data for 1st degree calculations, and store in sh1, sh2, and sh3\n            } else if (maxSphericalHarmonicsDegree === 2) {\n                vertexShaderSource += `\n                    vec4 sampledSH0123;\n                    vec4 sampledSH4567;\n                    vec4 sampledSH891011;\n\n                    vec4 sampledSH0123R;\n                    vec4 sampledSH0123G;\n                    vec4 sampledSH0123B;\n\n                    if (sphericalHarmonicsMultiTextureMode == 0) {\n                        sampledSH0123 = texture(sphericalHarmonicsTexture, getDataUV(6, 0, sphericalHarmonicsTextureSize));\n                        sampledSH4567 = texture(sphericalHarmonicsTexture, getDataUV(6, 1, sphericalHarmonicsTextureSize));\n                        sampledSH891011 = texture(sphericalHarmonicsTexture, getDataUV(6, 2, sphericalHarmonicsTextureSize));\n                        sh1 = sampledSH0123.rgb;\n                        sh2 = vec3(sampledSH0123.a, sampledSH4567.rg);\n                        sh3 = vec3(sampledSH4567.ba, sampledSH891011.r);\n                    } else {\n                        sampledSH0123R = texture(sphericalHarmonicsTextureR, getDataUV(2, 0, sphericalHarmonicsTextureSize));\n                        sampledSH0123G = texture(sphericalHarmonicsTextureG, getDataUV(2, 0, sphericalHarmonicsTextureSize));\n                        sampledSH0123B = texture(sphericalHarmonicsTextureB, getDataUV(2, 0, sphericalHarmonicsTextureSize));\n                        sh1 = vec3(sampledSH0123R.rgb);\n                        sh2 = vec3(sampledSH0123G.rgb);\n                        sh3 = vec3(sampledSH0123B.rgb);\n                    }\n                `;\n            }\n\n            // Perform 1st degree spherical harmonics calculations\n            vertexShaderSource += `\n                    if (sphericalHarmonics8BitMode == 1) {\n                        sh1 = sh1 * sh8BitCompressionRangeForScene + vec8BitSHShift;\n                        sh2 = sh2 * sh8BitCompressionRangeForScene + vec8BitSHShift;\n                        sh3 = sh3 * sh8BitCompressionRangeForScene + vec8BitSHShift;\n                    }\n                    float x = worldViewDir.x;\n                    float y = worldViewDir.y;\n                    float z = worldViewDir.z;\n                    vColor.rgb += SH_C1 * (-sh1 * y + sh2 * z - sh3 * x);\n            `;\n\n            // Proceed to sampling and rendering 2nd degree spherical harmonics\n            if (maxSphericalHarmonicsDegree >= 2) {\n\n                vertexShaderSource += `\n                    if (sphericalHarmonicsDegree >= 2) {\n                        float xx = x * x;\n                        float yy = y * y;\n                        float zz = z * z;\n                        float xy = x * y;\n                        float yz = y * z;\n                        float xz = x * z;\n                `;\n\n                // Sample spherical harmonics textures with 2 degrees worth of data for 2nd degree calculations,\n                // and store in sh4, sh5, sh6, sh7, and sh8\n                if (maxSphericalHarmonicsDegree === 2) {\n                    vertexShaderSource += `\n                        if (sphericalHarmonicsMultiTextureMode == 0) {\n                            vec4 sampledSH12131415 = texture(sphericalHarmonicsTexture, getDataUV(6, 3, sphericalHarmonicsTextureSize));\n                            vec4 sampledSH16171819 = texture(sphericalHarmonicsTexture, getDataUV(6, 4, sphericalHarmonicsTextureSize));\n                            vec4 sampledSH20212223 = texture(sphericalHarmonicsTexture, getDataUV(6, 5, sphericalHarmonicsTextureSize));\n                            sh4 = sampledSH891011.gba;\n                            sh5 = sampledSH12131415.rgb;\n                            sh6 = vec3(sampledSH12131415.a, sampledSH16171819.rg);\n                            sh7 = vec3(sampledSH16171819.ba, sampledSH20212223.r);\n                            sh8 = sampledSH20212223.gba;\n                        } else {\n                            vec4 sampledSH4567R = texture(sphericalHarmonicsTextureR, getDataUV(2, 1, sphericalHarmonicsTextureSize));\n                            vec4 sampledSH4567G = texture(sphericalHarmonicsTextureG, getDataUV(2, 1, sphericalHarmonicsTextureSize));\n                            vec4 sampledSH4567B = texture(sphericalHarmonicsTextureB, getDataUV(2, 1, sphericalHarmonicsTextureSize));\n                            sh4 = vec3(sampledSH0123R.a, sampledSH4567R.rg);\n                            sh5 = vec3(sampledSH4567R.ba, sampledSH0123G.a);\n                            sh6 = vec3(sampledSH4567G.rgb);\n                            sh7 = vec3(sampledSH4567G.a, sampledSH0123B.a, sampledSH4567B.r);\n                            sh8 = vec3(sampledSH4567B.gba);\n                        }\n                    `;\n                }\n\n                // Perform 2nd degree spherical harmonics calculations\n                vertexShaderSource += `\n                        if (sphericalHarmonics8BitMode == 1) {\n                            sh4 = sh4 * sh8BitCompressionRangeForScene + vec8BitSHShift;\n                            sh5 = sh5 * sh8BitCompressionRangeForScene + vec8BitSHShift;\n                            sh6 = sh6 * sh8BitCompressionRangeForScene + vec8BitSHShift;\n                            sh7 = sh7 * sh8BitCompressionRangeForScene + vec8BitSHShift;\n                            sh8 = sh8 * sh8BitCompressionRangeForScene + vec8BitSHShift;\n                        }\n\n                        vColor.rgb +=\n                            (SH_C2[0] * xy) * sh4 +\n                            (SH_C2[1] * yz) * sh5 +\n                            (SH_C2[2] * (2.0 * zz - xx - yy)) * sh6 +\n                            (SH_C2[3] * xz) * sh7 +\n                            (SH_C2[4] * (xx - yy)) * sh8;\n                    }\n                `;\n            }\n\n            vertexShaderSource += `\n\n                vColor.rgb = clamp(vColor.rgb, vec3(0.), vec3(1.));\n\n            }\n\n            `;\n        }\n\n        return vertexShaderSource;\n    }\n\n    static getVertexShaderFadeIn() {\n        return `\n            if (fadeInComplete == 0) {\n                float opacityAdjust = 1.0;\n                float centerDist = length(splatCenter - sceneCenter);\n                float renderTime = max(currentTime - firstRenderTime, 0.0);\n\n                float fadeDistance = 0.75;\n                float distanceLoadFadeInFactor = step(visibleRegionFadeStartRadius, centerDist);\n                distanceLoadFadeInFactor = (1.0 - distanceLoadFadeInFactor) +\n                                        (1.0 - clamp((centerDist - visibleRegionFadeStartRadius) / fadeDistance, 0.0, 1.0)) *\n                                        distanceLoadFadeInFactor;\n                opacityAdjust *= distanceLoadFadeInFactor;\n                vColor.a *= opacityAdjust;\n            }\n        `;\n    }\n\n    static getUniforms(dynamicMode = false, enableOptionalEffects = false, maxSphericalHarmonicsDegree = 0,\n                       splatScale = 1.0, pointCloudModeEnabled = false) {\n\n        const uniforms = {\n            'sceneCenter': {\n                'type': 'v3',\n                'value': new THREE.Vector3()\n            },\n            'fadeInComplete': {\n                'type': 'i',\n                'value': 0\n            },\n            'orthographicMode': {\n                'type': 'i',\n                'value': 0\n            },\n            'visibleRegionFadeStartRadius': {\n                'type': 'f',\n                'value': 0.0\n            },\n            'visibleRegionRadius': {\n                'type': 'f',\n                'value': 0.0\n            },\n            'currentTime': {\n                'type': 'f',\n                'value': 0.0\n            },\n            'firstRenderTime': {\n                'type': 'f',\n                'value': 0.0\n            },\n            'centersColorsTexture': {\n                'type': 't',\n                'value': null\n            },\n            'sphericalHarmonicsTexture': {\n                'type': 't',\n                'value': null\n            },\n            'sphericalHarmonicsTextureR': {\n                'type': 't',\n                'value': null\n            },\n            'sphericalHarmonicsTextureG': {\n                'type': 't',\n                'value': null\n            },\n            'sphericalHarmonicsTextureB': {\n                'type': 't',\n                'value': null\n            },\n            'sphericalHarmonics8BitCompressionRangeMin': {\n                'type': 'f',\n                'value': []\n            },\n            'sphericalHarmonics8BitCompressionRangeMax': {\n                'type': 'f',\n                'value': []\n            },\n            'focal': {\n                'type': 'v2',\n                'value': new THREE.Vector2()\n            },\n            'orthoZoom': {\n                'type': 'f',\n                'value': 1.0\n            },\n            'inverseFocalAdjustment': {\n                'type': 'f',\n                'value': 1.0\n            },\n            'viewport': {\n                'type': 'v2',\n                'value': new THREE.Vector2()\n            },\n            'basisViewport': {\n                'type': 'v2',\n                'value': new THREE.Vector2()\n            },\n            'debugColor': {\n                'type': 'v3',\n                'value': new THREE.Color()\n            },\n            'centersColorsTextureSize': {\n                'type': 'v2',\n                'value': new THREE.Vector2(1024, 1024)\n            },\n            'sphericalHarmonicsDegree': {\n                'type': 'i',\n                'value': maxSphericalHarmonicsDegree\n            },\n            'sphericalHarmonicsTextureSize': {\n                'type': 'v2',\n                'value': new THREE.Vector2(1024, 1024)\n            },\n            'sphericalHarmonics8BitMode': {\n                'type': 'i',\n                'value': 0\n            },\n            'sphericalHarmonicsMultiTextureMode': {\n                'type': 'i',\n                'value': 0\n            },\n            'splatScale': {\n                'type': 'f',\n                'value': splatScale\n            },\n            'pointCloudModeEnabled': {\n                'type': 'i',\n                'value': pointCloudModeEnabled ? 1 : 0\n            },\n            'sceneIndexesTexture': {\n                'type': 't',\n                'value': null\n            },\n            'sceneIndexesTextureSize': {\n                'type': 'v2',\n                'value': new THREE.Vector2(1024, 1024)\n            },\n            'sceneCount': {\n                'type': 'i',\n                'value': 1\n            }\n        };\n        for (let i = 0; i < Constants.MaxScenes; i++) {\n            uniforms.sphericalHarmonics8BitCompressionRangeMin.value.push(-Constants.SphericalHarmonics8BitCompressionRange / 2.0);\n            uniforms.sphericalHarmonics8BitCompressionRangeMax.value.push(Constants.SphericalHarmonics8BitCompressionRange / 2.0);\n        }\n\n        if (enableOptionalEffects) {\n            const sceneOpacity = [];\n            for (let i = 0; i < Constants.MaxScenes; i++) {\n                sceneOpacity.push(1.0);\n            }\n            uniforms['sceneOpacity'] ={\n                'type': 'f',\n                'value': sceneOpacity\n            };\n\n            const sceneVisibility = [];\n            for (let i = 0; i < Constants.MaxScenes; i++) {\n                sceneVisibility.push(1);\n            }\n            uniforms['sceneVisibility'] ={\n                'type': 'i',\n                'value': sceneVisibility\n            };\n        }\n\n        if (dynamicMode) {\n            const transformMatrices = [];\n            for (let i = 0; i < Constants.MaxScenes; i++) {\n                transformMatrices.push(new THREE.Matrix4());\n            }\n            uniforms['transforms'] = {\n                'type': 'mat4',\n                'value': transformMatrices\n            };\n        }\n\n        return uniforms;\n    }\n\n}\n","import * as THREE from 'three';\nimport { SplatMaterial } from './SplatMaterial.js';\n\nexport class SplatMaterial3D {\n\n    /**\n     * Build the Three.js material that is used to render the splats.\n     * @param {number} dynamicMode If true, it means the scene geometry represented by this splat mesh is not stationary or\n     *                             that the splat count might change\n     * @param {boolean} enableOptionalEffects When true, allows for usage of extra properties and attributes in the shader for effects\n     *                                        such as opacity adjustment. Default is false for performance reasons.\n     * @param {boolean} antialiased If true, calculate compensation factor to deal with gaussians being rendered at a significantly\n     *                              different resolution than that of their training\n     * @param {number} maxScreenSpaceSplatSize The maximum clip space splat size\n     * @param {number} splatScale Value by which all splats are scaled in screen-space (default is 1.0)\n     * @param {number} pointCloudModeEnabled Render all splats as screen-space circles\n     * @param {number} maxSphericalHarmonicsDegree Degree of spherical harmonics to utilize in rendering splats\n     * @return {THREE.ShaderMaterial}\n     */\n    static build(dynamicMode = false, enableOptionalEffects = false, antialiased = false, maxScreenSpaceSplatSize = 2048,\n                 splatScale = 1.0, pointCloudModeEnabled = false, maxSphericalHarmonicsDegree = 0, kernel2DSize = 0.3) {\n\n        const customVertexVars = `\n            uniform vec2 covariancesTextureSize;\n            uniform highp sampler2D covariancesTexture;\n            uniform highp usampler2D covariancesTextureHalfFloat;\n            uniform int covariancesAreHalfFloat;\n\n            void fromCovarianceHalfFloatV4(uvec4 val, out vec4 first, out vec4 second) {\n                vec2 r = unpackHalf2x16(val.r);\n                vec2 g = unpackHalf2x16(val.g);\n                vec2 b = unpackHalf2x16(val.b);\n\n                first = vec4(r.x, r.y, g.x, g.y);\n                second = vec4(b.x, b.y, 0.0, 0.0);\n            }\n        `;\n\n        let vertexShaderSource = SplatMaterial.buildVertexShaderBase(dynamicMode, enableOptionalEffects,\n                                                                     maxSphericalHarmonicsDegree, customVertexVars);\n        vertexShaderSource += SplatMaterial3D.buildVertexShaderProjection(antialiased, enableOptionalEffects,\n                                                                          maxScreenSpaceSplatSize, kernel2DSize);\n        const fragmentShaderSource = SplatMaterial3D.buildFragmentShader();\n\n        const uniforms = SplatMaterial.getUniforms(dynamicMode, enableOptionalEffects,\n                                                   maxSphericalHarmonicsDegree, splatScale, pointCloudModeEnabled);\n\n        uniforms['covariancesTextureSize'] = {\n            'type': 'v2',\n            'value': new THREE.Vector2(1024, 1024)\n        };\n        uniforms['covariancesTexture'] = {\n            'type': 't',\n            'value': null\n        };\n        uniforms['covariancesTextureHalfFloat'] = {\n            'type': 't',\n            'value': null\n        };\n        uniforms['covariancesAreHalfFloat'] = {\n            'type': 'i',\n            'value': 0\n        };\n\n        const material = new THREE.ShaderMaterial({\n            uniforms: uniforms,\n            vertexShader: vertexShaderSource,\n            fragmentShader: fragmentShaderSource,\n            transparent: true,\n            alphaTest: 1.0,\n            blending: THREE.NormalBlending,\n            depthTest: true,\n            depthWrite: false,\n            side: THREE.DoubleSide\n        });\n\n        return material;\n    }\n\n    static buildVertexShaderProjection(antialiased, enableOptionalEffects, maxScreenSpaceSplatSize, kernel2DSize) {\n        let vertexShaderSource = `\n\n            vec4 sampledCovarianceA;\n            vec4 sampledCovarianceB;\n            vec3 cov3D_M11_M12_M13;\n            vec3 cov3D_M22_M23_M33;\n            if (covariancesAreHalfFloat == 0) {\n                sampledCovarianceA = texture(covariancesTexture, getDataUVF(nearestEvenIndex, 1.5, oddOffset,\n                                                                            covariancesTextureSize));\n                sampledCovarianceB = texture(covariancesTexture, getDataUVF(nearestEvenIndex, 1.5, oddOffset + uint(1),\n                                                                            covariancesTextureSize));\n\n                cov3D_M11_M12_M13 = vec3(sampledCovarianceA.rgb) * (1.0 - fOddOffset) +\n                                    vec3(sampledCovarianceA.ba, sampledCovarianceB.r) * fOddOffset;\n                cov3D_M22_M23_M33 = vec3(sampledCovarianceA.a, sampledCovarianceB.rg) * (1.0 - fOddOffset) +\n                                    vec3(sampledCovarianceB.gba) * fOddOffset;\n            } else {\n                uvec4 sampledCovarianceU = texture(covariancesTextureHalfFloat, getDataUV(1, 0, covariancesTextureSize));\n                fromCovarianceHalfFloatV4(sampledCovarianceU, sampledCovarianceA, sampledCovarianceB);\n                cov3D_M11_M12_M13 = sampledCovarianceA.rgb;\n                cov3D_M22_M23_M33 = vec3(sampledCovarianceA.a, sampledCovarianceB.rg);\n            }\n        \n            // Construct the 3D covariance matrix\n            mat3 Vrk = mat3(\n                cov3D_M11_M12_M13.x, cov3D_M11_M12_M13.y, cov3D_M11_M12_M13.z,\n                cov3D_M11_M12_M13.y, cov3D_M22_M23_M33.x, cov3D_M22_M23_M33.y,\n                cov3D_M11_M12_M13.z, cov3D_M22_M23_M33.y, cov3D_M22_M23_M33.z\n            );\n\n            mat3 J;\n            if (orthographicMode == 1) {\n                // Since the projection is linear, we don't need an approximation\n                J = transpose(mat3(orthoZoom, 0.0, 0.0,\n                                0.0, orthoZoom, 0.0,\n                                0.0, 0.0, 0.0));\n            } else {\n                // Construct the Jacobian of the affine approximation of the projection matrix. It will be used to transform the\n                // 3D covariance matrix instead of using the actual projection matrix because that transformation would\n                // require a non-linear component (perspective division) which would yield a non-gaussian result.\n                float s = 1.0 / (viewCenter.z * viewCenter.z);\n                J = mat3(\n                    focal.x / viewCenter.z, 0., -(focal.x * viewCenter.x) * s,\n                    0., focal.y / viewCenter.z, -(focal.y * viewCenter.y) * s,\n                    0., 0., 0.\n                );\n            }\n\n            // Concatenate the projection approximation with the model-view transformation\n            mat3 W = transpose(mat3(transformModelViewMatrix));\n            mat3 T = W * J;\n\n            // Transform the 3D covariance matrix (Vrk) to compute the 2D covariance matrix\n            mat3 cov2Dm = transpose(T) * Vrk * T;\n            `;\n\n        if (antialiased) {\n            vertexShaderSource += `\n                float detOrig = cov2Dm[0][0] * cov2Dm[1][1] - cov2Dm[0][1] * cov2Dm[0][1];\n                cov2Dm[0][0] += ${kernel2DSize};\n                cov2Dm[1][1] += ${kernel2DSize};\n                float detBlur = cov2Dm[0][0] * cov2Dm[1][1] - cov2Dm[0][1] * cov2Dm[0][1];\n                vColor.a *= sqrt(max(detOrig / detBlur, 0.0));\n                if (vColor.a < minAlpha) return;\n            `;\n        } else {\n            vertexShaderSource += `\n                cov2Dm[0][0] += ${kernel2DSize};\n                cov2Dm[1][1] += ${kernel2DSize};\n            `;\n        }\n\n        vertexShaderSource += `\n\n            // We are interested in the upper-left 2x2 portion of the projected 3D covariance matrix because\n            // we only care about the X and Y values. We want the X-diagonal, cov2Dm[0][0],\n            // the Y-diagonal, cov2Dm[1][1], and the correlation between the two cov2Dm[0][1]. We don't\n            // need cov2Dm[1][0] because it is a symetric matrix.\n            vec3 cov2Dv = vec3(cov2Dm[0][0], cov2Dm[0][1], cov2Dm[1][1]);\n\n            // We now need to solve for the eigen-values and eigen vectors of the 2D covariance matrix\n            // so that we can determine the 2D basis for the splat. This is done using the method described\n            // here: https://people.math.harvard.edu/~knill/teaching/math21b2004/exhibits/2dmatrices/index.html\n            // After calculating the eigen-values and eigen-vectors, we calculate the basis for rendering the splat\n            // by normalizing the eigen-vectors and then multiplying them by (sqrt(8) * sqrt(eigen-value)), which is\n            // equal to scaling them by sqrt(8) standard deviations.\n            //\n            // This is a different approach than in the original work at INRIA. In that work they compute the\n            // max extents of the projected splat in screen space to form a screen-space aligned bounding rectangle\n            // which forms the geometry that is actually rasterized. The dimensions of that bounding box are 3.0\n            // times the square root of the maximum eigen-value, or 3 standard deviations. They then use the inverse\n            // 2D covariance matrix (called 'conic') in the CUDA rendering thread to determine fragment opacity by\n            // calculating the full gaussian: exp(-0.5 * (X - mean) * conic * (X - mean)) * splat opacity\n            float a = cov2Dv.x;\n            float d = cov2Dv.z;\n            float b = cov2Dv.y;\n            float D = a * d - b * b;\n            float trace = a + d;\n            float traceOver2 = 0.5 * trace;\n            float term2 = sqrt(max(0.1f, traceOver2 * traceOver2 - D));\n            float eigenValue1 = traceOver2 + term2;\n            float eigenValue2 = traceOver2 - term2;\n\n            if (pointCloudModeEnabled == 1) {\n                eigenValue1 = eigenValue2 = 0.2;\n            }\n\n            if (eigenValue2 <= 0.0) return;\n\n            vec2 eigenVector1 = normalize(vec2(b, eigenValue1 - a));\n            // since the eigen vectors are orthogonal, we derive the second one from the first\n            vec2 eigenVector2 = vec2(eigenVector1.y, -eigenVector1.x);\n\n            // We use sqrt(8) standard deviations instead of 3 to eliminate more of the splat with a very low opacity.\n            vec2 basisVector1 = eigenVector1 * splatScale * min(sqrt8 * sqrt(eigenValue1), ${parseInt(maxScreenSpaceSplatSize)}.0);\n            vec2 basisVector2 = eigenVector2 * splatScale * min(sqrt8 * sqrt(eigenValue2), ${parseInt(maxScreenSpaceSplatSize)}.0);\n            `;\n\n        if (enableOptionalEffects) {\n            vertexShaderSource += `\n                vColor.a *= splatOpacityFromScene;\n            `;\n        }\n\n        vertexShaderSource += `\n            vec2 ndcOffset = vec2(vPosition.x * basisVector1 + vPosition.y * basisVector2) *\n                             basisViewport * 2.0 * inverseFocalAdjustment;\n\n            vec4 quadPos = vec4(ndcCenter.xy + ndcOffset, ndcCenter.z, 1.0);\n            gl_Position = quadPos;\n\n            // Scale the position data we send to the fragment shader\n            vPosition *= sqrt8;\n        `;\n\n        vertexShaderSource += SplatMaterial.getVertexShaderFadeIn();\n        vertexShaderSource += `}`;\n\n        return vertexShaderSource;\n    }\n\n    static buildFragmentShader() {\n        let fragmentShaderSource = `\n            precision highp float;\n            #include <common>\n \n            uniform vec3 debugColor;\n\n            varying vec4 vColor;\n            varying vec2 vUv;\n            varying vec2 vPosition;\n        `;\n\n        fragmentShaderSource += `\n            void main () {\n                // Compute the positional squared distance from the center of the splat to the current fragment.\n                float A = dot(vPosition, vPosition);\n                // Since the positional data in vPosition has been scaled by sqrt(8), the squared result will be\n                // scaled by a factor of 8. If the squared result is larger than 8, it means it is outside the ellipse\n                // defined by the rectangle formed by vPosition. It also means it's farther\n                // away than sqrt(8) standard deviations from the mean.\n                if (A > 8.0) discard;\n                vec3 color = vColor.rgb;\n\n                // Since the rendered splat is scaled by sqrt(8), the inverse covariance matrix that is part of\n                // the gaussian formula becomes the identity matrix. We're then left with (X - mean) * (X - mean),\n                // and since 'mean' is zero, we have X * X, which is the same as A:\n                float opacity = exp(-0.5 * A) * vColor.a;\n\n                gl_FragColor = vec4(color.rgb, opacity);\n            }\n        `;\n\n        return fragmentShaderSource;\n    }\n\n}\n","import * as THREE from 'three';\nimport { SplatMaterial } from './SplatMaterial.js';\n\nexport class SplatMaterial2D {\n\n    /**\n     * Build the Three.js material that is used to render the splats.\n     * @param {number} dynamicMode If true, it means the scene geometry represented by this splat mesh is not stationary or\n     *                             that the splat count might change\n     * @param {boolean} enableOptionalEffects When true, allows for usage of extra properties and attributes in the shader for effects\n     *                                        such as opacity adjustment. Default is false for performance reasons.\n     * @param {number} splatScale Value by which all splats are scaled in screen-space (default is 1.0)\n     * @param {number} pointCloudModeEnabled Render all splats as screen-space circles\n     * @param {number} maxSphericalHarmonicsDegree Degree of spherical harmonics to utilize in rendering splats\n     * @return {THREE.ShaderMaterial}\n     */\n    static build(dynamicMode = false, enableOptionalEffects = false, splatScale = 1.0,\n                 pointCloudModeEnabled = false, maxSphericalHarmonicsDegree = 0) {\n\n        const customVertexVars = `\n            uniform vec2 scaleRotationsTextureSize;\n            uniform highp sampler2D scaleRotationsTexture;\n            varying mat3 vT;\n            varying vec2 vQuadCenter;\n            varying vec2 vFragCoord;\n        `;\n\n        let vertexShaderSource = SplatMaterial.buildVertexShaderBase(dynamicMode, enableOptionalEffects,\n                                                                     maxSphericalHarmonicsDegree, customVertexVars);\n        vertexShaderSource += SplatMaterial2D.buildVertexShaderProjection();\n        const fragmentShaderSource = SplatMaterial2D.buildFragmentShader();\n\n        const uniforms = SplatMaterial.getUniforms(dynamicMode, enableOptionalEffects,\n                                                   maxSphericalHarmonicsDegree, splatScale, pointCloudModeEnabled);\n\n        uniforms['scaleRotationsTexture'] = {\n            'type': 't',\n            'value': null\n        };\n        uniforms['scaleRotationsTextureSize'] = {\n            'type': 'v2',\n            'value': new THREE.Vector2(1024, 1024)\n        };\n\n        const material = new THREE.ShaderMaterial({\n            uniforms: uniforms,\n            vertexShader: vertexShaderSource,\n            fragmentShader: fragmentShaderSource,\n            transparent: true,\n            alphaTest: 1.0,\n            blending: THREE.NormalBlending,\n            depthTest: true,\n            depthWrite: false,\n            side: THREE.DoubleSide\n        });\n\n        return material;\n    }\n\n    static buildVertexShaderProjection() {\n\n        // Original CUDA code for calculating splat-to-screen transformation, for reference\n        /*\n            glm::mat3 R = quat_to_rotmat(rot);\n            glm::mat3 S = scale_to_mat(scale, mod);\n            glm::mat3 L = R * S;\n\n            // center of Gaussians in the camera coordinate\n            glm::mat3x4 splat2world = glm::mat3x4(\n                glm::vec4(L[0], 0.0),\n                glm::vec4(L[1], 0.0),\n                glm::vec4(p_orig.x, p_orig.y, p_orig.z, 1)\n            );\n\n            glm::mat4 world2ndc = glm::mat4(\n                projmatrix[0], projmatrix[4], projmatrix[8], projmatrix[12],\n                projmatrix[1], projmatrix[5], projmatrix[9], projmatrix[13],\n                projmatrix[2], projmatrix[6], projmatrix[10], projmatrix[14],\n                projmatrix[3], projmatrix[7], projmatrix[11], projmatrix[15]\n            );\n\n            glm::mat3x4 ndc2pix = glm::mat3x4(\n                glm::vec4(float(W) / 2.0, 0.0, 0.0, float(W-1) / 2.0),\n                glm::vec4(0.0, float(H) / 2.0, 0.0, float(H-1) / 2.0),\n                glm::vec4(0.0, 0.0, 0.0, 1.0)\n            );\n\n            T = glm::transpose(splat2world) * world2ndc * ndc2pix;\n            normal = transformVec4x3({L[2].x, L[2].y, L[2].z}, viewmatrix);\n        */\n\n        // Compute a 2D-to-2D mapping matrix from a tangent plane into a image plane\n        // given a 2D gaussian parameters. T = WH (from the paper: https://arxiv.org/pdf/2403.17888)\n        let vertexShaderSource = `\n\n            vec4 scaleRotationA = texture(scaleRotationsTexture, getDataUVF(nearestEvenIndex, 1.5,\n                                                                            oddOffset, scaleRotationsTextureSize));\n            vec4 scaleRotationB = texture(scaleRotationsTexture, getDataUVF(nearestEvenIndex, 1.5,\n                                                                            oddOffset + uint(1), scaleRotationsTextureSize));\n\n            vec3 scaleRotation123 = vec3(scaleRotationA.rgb) * (1.0 - fOddOffset) +\n                                    vec3(scaleRotationA.ba, scaleRotationB.r) * fOddOffset;\n            vec3 scaleRotation456 = vec3(scaleRotationA.a, scaleRotationB.rg) * (1.0 - fOddOffset) +\n                                    vec3(scaleRotationB.gba) * fOddOffset;\n\n            float missingW = sqrt(1.0 - scaleRotation456.x * scaleRotation456.x - scaleRotation456.y *\n                                    scaleRotation456.y - scaleRotation456.z * scaleRotation456.z);\n            mat3 R = quaternionToRotationMatrix(scaleRotation456.r, scaleRotation456.g, scaleRotation456.b, missingW);\n            mat3 S = mat3(scaleRotation123.r, 0.0, 0.0,\n                            0.0, scaleRotation123.g, 0.0,\n                            0.0, 0.0, scaleRotation123.b);\n            \n            mat3 L = R * S;\n\n            mat3x4 splat2World = mat3x4(vec4(L[0], 0.0),\n                                        vec4(L[1], 0.0),\n                                        vec4(splatCenter.x, splatCenter.y, splatCenter.z, 1.0));\n\n            mat4 world2ndc = transpose(projectionMatrix * transformModelViewMatrix);\n\n            mat3x4 ndc2pix = mat3x4(vec4(viewport.x / 2.0, 0.0, 0.0, (viewport.x - 1.0) / 2.0),\n                                    vec4(0.0, viewport.y / 2.0, 0.0, (viewport.y - 1.0) / 2.0),\n                                    vec4(0.0, 0.0, 0.0, 1.0));\n\n            mat3 T = transpose(splat2World) * world2ndc * ndc2pix;\n            vec3 normal = vec3(viewMatrix * vec4(L[0][2], L[1][2], L[2][2], 0.0));\n        `;\n\n        // Original CUDA code for projection to 2D, for reference\n        /*\n            float3 T0 = {T[0][0], T[0][1], T[0][2]};\n            float3 T1 = {T[1][0], T[1][1], T[1][2]};\n            float3 T3 = {T[2][0], T[2][1], T[2][2]};\n\n            // Compute AABB\n            float3 temp_point = {1.0f, 1.0f, -1.0f};\n            float distance = sumf3(T3 * T3 * temp_point);\n            float3 f = (1 / distance) * temp_point;\n            if (distance == 0.0) return false;\n\n            point_image = {\n                sumf3(f * T0 * T3),\n                sumf3(f * T1 * T3)\n            };\n\n            float2 temp = {\n                sumf3(f * T0 * T0),\n                sumf3(f * T1 * T1)\n            };\n            float2 half_extend = point_image * point_image - temp;\n            extent = sqrtf2(maxf2(1e-4, half_extend));\n            return true;\n        */\n\n        // Computing the bounding box of the 2D Gaussian and its center\n        // The center of the bounding box is used to create a low pass filter.\n        // This code is based off the reference implementation and creates an AABB aligned\n        // with the screen for the quad to be rendered.\n        const referenceQuadGeneration = `\n            vec3 T0 = vec3(T[0][0], T[0][1], T[0][2]);\n            vec3 T1 = vec3(T[1][0], T[1][1], T[1][2]);\n            vec3 T3 = vec3(T[2][0], T[2][1], T[2][2]);\n\n            vec3 tempPoint = vec3(1.0, 1.0, -1.0);\n            float distance = (T3.x * T3.x * tempPoint.x) + (T3.y * T3.y * tempPoint.y) + (T3.z * T3.z * tempPoint.z);\n            vec3 f = (1.0 / distance) * tempPoint;\n            if (abs(distance) < 0.00001) return;\n\n            float pointImageX = (T0.x * T3.x * f.x) + (T0.y * T3.y * f.y) + (T0.z * T3.z * f.z);\n            float pointImageY = (T1.x * T3.x * f.x) + (T1.y * T3.y * f.y) + (T1.z * T3.z * f.z);\n            vec2 pointImage = vec2(pointImageX, pointImageY);\n\n            float tempX = (T0.x * T0.x * f.x) + (T0.y * T0.y * f.y) + (T0.z * T0.z * f.z);\n            float tempY = (T1.x * T1.x * f.x) + (T1.y * T1.y * f.y) + (T1.z * T1.z * f.z);\n            vec2 temp = vec2(tempX, tempY);\n\n            vec2 halfExtend = pointImage * pointImage - temp;\n            vec2 extent = sqrt(max(vec2(0.0001), halfExtend));\n            float radius = max(extent.x, extent.y);\n\n            vec2 ndcOffset = ((position.xy * radius * 3.0) * basisViewport * 2.0);\n\n            vec4 quadPos = vec4(ndcCenter.xy + ndcOffset, ndcCenter.z, 1.0);\n            gl_Position = quadPos;\n\n            vT = T;\n            vQuadCenter = pointImage;\n            vFragCoord = (quadPos.xy * 0.5 + 0.5) * viewport;\n        `;\n\n        const useRefImplementation = false;\n        if (useRefImplementation) {\n            vertexShaderSource += referenceQuadGeneration;\n        } else {\n            // Create a quad that is aligned with the eigen vectors of the projected gaussian for rendering.\n            // This is a different approach than the reference implementation, similar to how the rendering of\n            // 3D gaussians in this viewer differs from the reference implementation. If the quad is too small\n            // (smaller than a pixel), then revert to the reference implementation.\n            vertexShaderSource += `\n\n                mat4 splat2World4 = mat4(vec4(L[0], 0.0),\n                                        vec4(L[1], 0.0),\n                                        vec4(L[2], 0.0),\n                                        vec4(splatCenter.x, splatCenter.y, splatCenter.z, 1.0));\n\n                mat4 Tt = transpose(transpose(splat2World4) * world2ndc);\n\n                vec4 tempPoint1 = Tt * vec4(1.0, 0.0, 0.0, 1.0);\n                tempPoint1 /= tempPoint1.w;\n\n                vec4 tempPoint2 = Tt * vec4(0.0, 1.0, 0.0, 1.0);\n                tempPoint2 /= tempPoint2.w;\n\n                vec4 center = Tt * vec4(0.0, 0.0, 0.0, 1.0);\n                center /= center.w;\n\n                vec2 basisVector1 = tempPoint1.xy - center.xy;\n                vec2 basisVector2 = tempPoint2.xy - center.xy;\n\n                vec2 basisVector1Screen = basisVector1 * 0.5 * viewport;\n                vec2 basisVector2Screen = basisVector2 * 0.5 * viewport;\n\n                const float minPix = 1.;\n                if (length(basisVector1Screen) < minPix || length(basisVector2Screen) < minPix) {\n                    ${referenceQuadGeneration}\n                } else {\n                    vec2 ndcOffset = vec2(position.x * basisVector1 + position.y * basisVector2) * 3.0 * inverseFocalAdjustment;\n                    vec4 quadPos = vec4(ndcCenter.xy + ndcOffset, ndcCenter.z, 1.0);\n                    gl_Position = quadPos;\n\n                    vT = T;\n                    vQuadCenter = center.xy;\n                    vFragCoord = (quadPos.xy * 0.5 + 0.5) * viewport;\n                }\n            `;\n        }\n\n        vertexShaderSource += SplatMaterial.getVertexShaderFadeIn();\n        vertexShaderSource += `}`;\n\n        return vertexShaderSource;\n    }\n\n    static buildFragmentShader() {\n\n        // Original CUDA code for splat intersection, for reference\n        /*\n            const float2 xy = collected_xy[j];\n            const float3 Tu = collected_Tu[j];\n            const float3 Tv = collected_Tv[j];\n            const float3 Tw = collected_Tw[j];\n            float3 k = pix.x * Tw - Tu;\n            float3 l = pix.y * Tw - Tv;\n            float3 p = cross(k, l);\n            if (p.z == 0.0) continue;\n            float2 s = {p.x / p.z, p.y / p.z};\n            float rho3d = (s.x * s.x + s.y * s.y);\n            float2 d = {xy.x - pixf.x, xy.y - pixf.y};\n            float rho2d = FilterInvSquare * (d.x * d.x + d.y * d.y);\n\n            // compute intersection and depth\n            float rho = min(rho3d, rho2d);\n            float depth = (rho3d <= rho2d) ? (s.x * Tw.x + s.y * Tw.y) + Tw.z : Tw.z;\n            if (depth < near_n) continue;\n            float4 nor_o = collected_normal_opacity[j];\n            float normal[3] = {nor_o.x, nor_o.y, nor_o.z};\n            float opa = nor_o.w;\n\n            float power = -0.5f * rho;\n            if (power > 0.0f)\n                continue;\n\n            // Eq. (2) from 3D Gaussian splatting paper.\n            // Obtain alpha by multiplying with Gaussian opacity\n            // and its exponential falloff from mean.\n            // Avoid numerical instabilities (see paper appendix).\n            float alpha = min(0.99f, opa * exp(power));\n            if (alpha < 1.0f / 255.0f)\n                continue;\n            float test_T = T * (1 - alpha);\n            if (test_T < 0.0001f)\n            {\n                done = true;\n                continue;\n            }\n\n            float w = alpha * T;\n        */\n        let fragmentShaderSource = `\n            precision highp float;\n            #include <common>\n\n            uniform vec3 debugColor;\n\n            varying vec4 vColor;\n            varying vec2 vUv;\n            varying vec2 vPosition;\n            varying mat3 vT;\n            varying vec2 vQuadCenter;\n            varying vec2 vFragCoord;\n\n            void main () {\n\n                const float FilterInvSquare = 2.0;\n                const float near_n = 0.2;\n                const float T = 1.0;\n\n                vec2 xy = vQuadCenter;\n                vec3 Tu = vT[0];\n                vec3 Tv = vT[1];\n                vec3 Tw = vT[2];\n                vec3 k = vFragCoord.x * Tw - Tu;\n                vec3 l = vFragCoord.y * Tw - Tv;\n                vec3 p = cross(k, l);\n                if (p.z == 0.0) discard;\n                vec2 s = vec2(p.x / p.z, p.y / p.z);\n                float rho3d = (s.x * s.x + s.y * s.y); \n                vec2 d = vec2(xy.x - vFragCoord.x, xy.y - vFragCoord.y);\n                float rho2d = FilterInvSquare * (d.x * d.x + d.y * d.y); \n\n                // compute intersection and depth\n                float rho = min(rho3d, rho2d);\n                float depth = (rho3d <= rho2d) ? (s.x * Tw.x + s.y * Tw.y) + Tw.z : Tw.z; \n                if (depth < near_n) discard;\n                //  vec4 nor_o = collected_normal_opacity[j];\n                //  float normal[3] = {nor_o.x, nor_o.y, nor_o.z};\n                float opa = vColor.a;\n\n                float power = -0.5f * rho;\n                if (power > 0.0f) discard;\n\n                // Eq. (2) from 3D Gaussian splatting paper.\n                // Obtain alpha by multiplying with Gaussian opacity\n                // and its exponential falloff from mean.\n                // Avoid numerical instabilities (see paper appendix). \n                float alpha = min(0.99f, opa * exp(power));\n                if (alpha < 1.0f / 255.0f) discard;\n                float test_T = T * (1.0 - alpha);\n                if (test_T < 0.0001)discard;\n\n                float w = alpha * T;\n                gl_FragColor = vec4(vColor.rgb, w);\n            }\n        `;\n\n        return fragmentShaderSource;\n    }\n}\n","import * as THREE from 'three';\n\nexport class SplatGeometry {\n\n    /**\n     * Build the Three.js geometry that will be used to render the splats. The geometry is instanced and is made up of\n     * vertices for a single quad as well as an attribute buffer for the splat indexes.\n     * @param {number} maxSplatCount The maximum number of splats that the geometry will need to accomodate\n     * @return {THREE.InstancedBufferGeometry}\n     */\n    static build(maxSplatCount) {\n\n        const baseGeometry = new THREE.BufferGeometry();\n        baseGeometry.setIndex([0, 1, 2, 0, 2, 3]);\n\n        // Vertices for the instanced quad\n        const positionsArray = new Float32Array(4 * 3);\n        const positions = new THREE.BufferAttribute(positionsArray, 3);\n        baseGeometry.setAttribute('position', positions);\n        positions.setXYZ(0, -1.0, -1.0, 0.0);\n        positions.setXYZ(1, -1.0, 1.0, 0.0);\n        positions.setXYZ(2, 1.0, 1.0, 0.0);\n        positions.setXYZ(3, 1.0, -1.0, 0.0);\n        positions.needsUpdate = true;\n\n        const geometry = new THREE.InstancedBufferGeometry().copy(baseGeometry);\n\n        // Splat index buffer\n        const splatIndexArray = new Uint32Array(maxSplatCount);\n        const splatIndexes = new THREE.InstancedBufferAttribute(splatIndexArray, 1, false);\n        splatIndexes.setUsage(THREE.DynamicDrawUsage);\n        geometry.setAttribute('splatIndex', splatIndexes);\n\n        geometry.instanceCount = 0;\n\n        return geometry;\n    }\n}\n","import * as THREE from 'three';\n\n/**\n * SplatScene: Descriptor for a single splat scene managed by an instance of SplatMesh.\n */\nexport class SplatScene extends THREE.Object3D {\n\n    constructor(splatBuffer, position = new THREE.Vector3(), quaternion = new THREE.Quaternion(),\n                scale = new THREE.Vector3(1, 1, 1), minimumAlpha = 1, opacity = 1.0, visible = true) {\n        super();\n        this.splatBuffer = splatBuffer;\n        this.position.copy(position);\n        this.quaternion.copy(quaternion);\n        this.scale.copy(scale);\n        this.transform = new THREE.Matrix4();\n        this.minimumAlpha = minimumAlpha;\n        this.opacity = opacity;\n        this.visible = visible;\n    }\n\n    copyTransformData(otherScene) {\n        this.position.copy(otherScene.position);\n        this.quaternion.copy(otherScene.quaternion);\n        this.scale.copy(otherScene.scale);\n        this.transform.copy(otherScene.transform);\n    }\n\n    updateTransform(dynamicMode) {\n        if (dynamicMode) {\n            if (this.matrixWorldAutoUpdate) this.updateWorldMatrix(true, false);\n            this.transform.copy(this.matrixWorld);\n        } else {\n            if (this.matrixAutoUpdate) this.updateMatrix();\n            this.transform.copy(this.matrix);\n        }\n    }\n}\n","import * as THREE from 'three';\nimport { delayedExecute } from '../Util.js';\n\nclass SplatTreeNode {\n\n    static idGen = 0;\n\n    constructor(min, max, depth, id) {\n        this.min = new THREE.Vector3().copy(min);\n        this.max = new THREE.Vector3().copy(max);\n        this.boundingBox = new THREE.Box3(this.min, this.max);\n        this.center = new THREE.Vector3().copy(this.max).sub(this.min).multiplyScalar(0.5).add(this.min);\n        this.depth = depth;\n        this.children = [];\n        this.data = null;\n        this.id = id || SplatTreeNode.idGen++;\n    }\n\n}\n\nclass SplatSubTree {\n\n    constructor(maxDepth, maxCentersPerNode) {\n        this.maxDepth = maxDepth;\n        this.maxCentersPerNode = maxCentersPerNode;\n        this.sceneDimensions = new THREE.Vector3();\n        this.sceneMin = new THREE.Vector3();\n        this.sceneMax = new THREE.Vector3();\n        this.rootNode = null;\n        this.nodesWithIndexes = [];\n        this.splatMesh = null;\n    }\n\n    static convertWorkerSubTreeNode(workerSubTreeNode) {\n        const minVector = new THREE.Vector3().fromArray(workerSubTreeNode.min);\n        const maxVector = new THREE.Vector3().fromArray(workerSubTreeNode.max);\n        const convertedNode = new SplatTreeNode(minVector, maxVector, workerSubTreeNode.depth, workerSubTreeNode.id);\n        if (workerSubTreeNode.data.indexes) {\n            convertedNode.data = {\n                'indexes': []\n            };\n            for (let index of workerSubTreeNode.data.indexes) {\n                convertedNode.data.indexes.push(index);\n            }\n        }\n        if (workerSubTreeNode.children) {\n            for (let child of workerSubTreeNode.children) {\n                convertedNode.children.push(SplatSubTree.convertWorkerSubTreeNode(child));\n            }\n        }\n        return convertedNode;\n    }\n\n    static convertWorkerSubTree(workerSubTree, splatMesh) {\n        const convertedSubTree = new SplatSubTree(workerSubTree.maxDepth, workerSubTree.maxCentersPerNode);\n        convertedSubTree.sceneMin = new THREE.Vector3().fromArray(workerSubTree.sceneMin);\n        convertedSubTree.sceneMax = new THREE.Vector3().fromArray(workerSubTree.sceneMax);\n\n        convertedSubTree.splatMesh = splatMesh;\n        convertedSubTree.rootNode = SplatSubTree.convertWorkerSubTreeNode(workerSubTree.rootNode);\n\n\n        const visitLeavesFromNode = (node, visitFunc) => {\n            if (node.children.length === 0) visitFunc(node);\n            for (let child of node.children) {\n                visitLeavesFromNode(child, visitFunc);\n            }\n        };\n\n        convertedSubTree.nodesWithIndexes = [];\n        visitLeavesFromNode(convertedSubTree.rootNode, (node) => {\n            if (node.data && node.data.indexes && node.data.indexes.length > 0) {\n                convertedSubTree.nodesWithIndexes.push(node);\n            }\n        });\n\n        return convertedSubTree;\n    }\n}\n\nfunction createSplatTreeWorker(self) {\n\n    let WorkerSplatTreeNodeIDGen = 0;\n\n    class WorkerBox3 {\n\n        constructor(min, max) {\n            this.min = [min[0], min[1], min[2]];\n            this.max = [max[0], max[1], max[2]];\n        }\n\n        containsPoint(point) {\n            return point[0] >= this.min[0] && point[0] <= this.max[0] &&\n                   point[1] >= this.min[1] && point[1] <= this.max[1] &&\n                   point[2] >= this.min[2] && point[2] <= this.max[2];\n        }\n    }\n\n    class WorkerSplatSubTree {\n\n        constructor(maxDepth, maxCentersPerNode) {\n            this.maxDepth = maxDepth;\n            this.maxCentersPerNode = maxCentersPerNode;\n            this.sceneDimensions = [];\n            this.sceneMin = [];\n            this.sceneMax = [];\n            this.rootNode = null;\n            this.addedIndexes = {};\n            this.nodesWithIndexes = [];\n            this.splatMesh = null;\n            this.disposed = false;\n        }\n\n    }\n\n    class WorkerSplatTreeNode {\n\n        constructor(min, max, depth, id) {\n            this.min = [min[0], min[1], min[2]];\n            this.max = [max[0], max[1], max[2]];\n            this.center = [(max[0] - min[0]) * 0.5 + min[0],\n                           (max[1] - min[1]) * 0.5 + min[1],\n                           (max[2] - min[2]) * 0.5 + min[2]];\n            this.depth = depth;\n            this.children = [];\n            this.data = null;\n            this.id = id || WorkerSplatTreeNodeIDGen++;\n        }\n\n    }\n\n    processSplatTreeNode = function(tree, node, indexToCenter, sceneCenters) {\n        const splatCount = node.data.indexes.length;\n\n        if (splatCount < tree.maxCentersPerNode || node.depth > tree.maxDepth) {\n            const newIndexes = [];\n            for (let i = 0; i < node.data.indexes.length; i++) {\n                if (!tree.addedIndexes[node.data.indexes[i]]) {\n                    newIndexes.push(node.data.indexes[i]);\n                    tree.addedIndexes[node.data.indexes[i]] = true;\n                }\n            }\n            node.data.indexes = newIndexes;\n            node.data.indexes.sort((a, b) => {\n                if (a > b) return 1;\n                else return -1;\n            });\n            tree.nodesWithIndexes.push(node);\n            return;\n        }\n\n        const nodeDimensions = [node.max[0] - node.min[0],\n                                node.max[1] - node.min[1],\n                                node.max[2] - node.min[2]];\n        const halfDimensions = [nodeDimensions[0] * 0.5,\n                                nodeDimensions[1] * 0.5,\n                                nodeDimensions[2] * 0.5];\n        const nodeCenter = [node.min[0] + halfDimensions[0],\n                            node.min[1] + halfDimensions[1],\n                            node.min[2] + halfDimensions[2]];\n\n        const childrenBounds = [\n            // top section, clockwise from upper-left (looking from above, +Y)\n            new WorkerBox3([nodeCenter[0] - halfDimensions[0], nodeCenter[1], nodeCenter[2] - halfDimensions[2]],\n                           [nodeCenter[0], nodeCenter[1] + halfDimensions[1], nodeCenter[2]]),\n            new WorkerBox3([nodeCenter[0], nodeCenter[1], nodeCenter[2] - halfDimensions[2]],\n                           [nodeCenter[0] + halfDimensions[0], nodeCenter[1] + halfDimensions[1], nodeCenter[2]]),\n            new WorkerBox3([nodeCenter[0], nodeCenter[1], nodeCenter[2]],\n                           [nodeCenter[0] + halfDimensions[0], nodeCenter[1] + halfDimensions[1], nodeCenter[2] + halfDimensions[2]]),\n            new WorkerBox3([nodeCenter[0] - halfDimensions[0], nodeCenter[1], nodeCenter[2]],\n                           [nodeCenter[0], nodeCenter[1] + halfDimensions[1], nodeCenter[2] + halfDimensions[2]]),\n\n            // bottom section, clockwise from lower-left (looking from above, +Y)\n            new WorkerBox3([nodeCenter[0] - halfDimensions[0], nodeCenter[1] - halfDimensions[1], nodeCenter[2] - halfDimensions[2]],\n                           [nodeCenter[0], nodeCenter[1], nodeCenter[2]]),\n            new WorkerBox3([nodeCenter[0], nodeCenter[1] - halfDimensions[1], nodeCenter[2] - halfDimensions[2]],\n                           [nodeCenter[0] + halfDimensions[0], nodeCenter[1], nodeCenter[2]]),\n            new WorkerBox3([nodeCenter[0], nodeCenter[1] - halfDimensions[1], nodeCenter[2]],\n                           [nodeCenter[0] + halfDimensions[0], nodeCenter[1], nodeCenter[2] + halfDimensions[2]]),\n            new WorkerBox3([nodeCenter[0] - halfDimensions[0], nodeCenter[1] - halfDimensions[1], nodeCenter[2]],\n                           [nodeCenter[0], nodeCenter[1], nodeCenter[2] + halfDimensions[2]]),\n        ];\n\n        const splatCounts = [];\n        const baseIndexes = [];\n        for (let i = 0; i < childrenBounds.length; i++) {\n            splatCounts[i] = 0;\n            baseIndexes[i] = [];\n        }\n\n        const center = [0, 0, 0];\n        for (let i = 0; i < splatCount; i++) {\n            const splatGlobalIndex = node.data.indexes[i];\n            const centerBase = indexToCenter[splatGlobalIndex];\n            center[0] = sceneCenters[centerBase];\n            center[1] = sceneCenters[centerBase + 1];\n            center[2] = sceneCenters[centerBase + 2];\n            for (let j = 0; j < childrenBounds.length; j++) {\n                if (childrenBounds[j].containsPoint(center)) {\n                    splatCounts[j]++;\n                    baseIndexes[j].push(splatGlobalIndex);\n                }\n            }\n        }\n\n        for (let i = 0; i < childrenBounds.length; i++) {\n            const childNode = new WorkerSplatTreeNode(childrenBounds[i].min, childrenBounds[i].max, node.depth + 1);\n            childNode.data = {\n                'indexes': baseIndexes[i]\n            };\n            node.children.push(childNode);\n        }\n\n        node.data = {};\n        for (let child of node.children) {\n            processSplatTreeNode(tree, child, indexToCenter, sceneCenters);\n        }\n        return;\n    };\n\n    const buildSubTree = (sceneCenters, maxDepth, maxCentersPerNode) => {\n\n        const sceneMin = [0, 0, 0];\n        const sceneMax = [0, 0, 0];\n        const indexes = [];\n        const centerCount = Math.floor(sceneCenters.length / 4);\n        for ( let i = 0; i < centerCount; i ++) {\n            const base = i * 4;\n            const x = sceneCenters[base];\n            const y = sceneCenters[base + 1];\n            const z = sceneCenters[base + 2];\n            const index = Math.round(sceneCenters[base + 3]);\n            if (i === 0 || x < sceneMin[0]) sceneMin[0] = x;\n            if (i === 0 || x > sceneMax[0]) sceneMax[0] = x;\n            if (i === 0 || y < sceneMin[1]) sceneMin[1] = y;\n            if (i === 0 || y > sceneMax[1]) sceneMax[1] = y;\n            if (i === 0 || z < sceneMin[2]) sceneMin[2] = z;\n            if (i === 0 || z > sceneMax[2]) sceneMax[2] = z;\n            indexes.push(index);\n        }\n        const subTree = new WorkerSplatSubTree(maxDepth, maxCentersPerNode);\n        subTree.sceneMin = sceneMin;\n        subTree.sceneMax = sceneMax;\n        subTree.rootNode = new WorkerSplatTreeNode(subTree.sceneMin, subTree.sceneMax, 0);\n        subTree.rootNode.data = {\n            'indexes': indexes\n        };\n\n        return subTree;\n    };\n\n    function createSplatTree(allCenters, maxDepth, maxCentersPerNode) {\n        const indexToCenter = [];\n        for (let sceneCenters of allCenters) {\n            const centerCount = Math.floor(sceneCenters.length / 4);\n            for ( let i = 0; i < centerCount; i ++) {\n                const base = i * 4;\n                const index = Math.round(sceneCenters[base + 3]);\n                indexToCenter[index] = base;\n            }\n        }\n        const subTrees = [];\n        for (let sceneCenters of allCenters) {\n            const subTree = buildSubTree(sceneCenters, maxDepth, maxCentersPerNode);\n            subTrees.push(subTree);\n            processSplatTreeNode(subTree, subTree.rootNode, indexToCenter, sceneCenters);\n        }\n        self.postMessage({\n            'subTrees': subTrees\n        });\n    }\n\n    self.onmessage = (e) => {\n        if (e.data.process) {\n            createSplatTree(e.data.process.centers, e.data.process.maxDepth, e.data.process.maxCentersPerNode);\n        }\n    };\n}\n\nfunction workerProcessCenters(splatTreeWorker, centers, transferBuffers, maxDepth, maxCentersPerNode) {\n    splatTreeWorker.postMessage({\n        'process': {\n            'centers': centers,\n            'maxDepth': maxDepth,\n            'maxCentersPerNode': maxCentersPerNode\n        }\n    }, transferBuffers);\n}\n\nfunction checkAndCreateWorker() {\n    const splatTreeWorker = new Worker(\n        URL.createObjectURL(\n            new Blob(['(', createSplatTreeWorker.toString(), ')(self)'], {\n                type: 'application/javascript',\n            }),\n        ),\n    );\n    return splatTreeWorker;\n}\n\n/**\n * SplatTree: Octree tailored to splat data from a SplatMesh instance\n */\nexport class SplatTree {\n\n    constructor(maxDepth, maxCentersPerNode) {\n        this.maxDepth = maxDepth;\n        this.maxCentersPerNode = maxCentersPerNode;\n        this.subTrees = [];\n        this.splatMesh = null;\n    }\n\n\n    dispose() {\n        this.diposeSplatTreeWorker();\n        this.disposed = true;\n    }\n\n    diposeSplatTreeWorker() {\n        if (this.splatTreeWorker) this.splatTreeWorker.terminate();\n        this.splatTreeWorker = null;\n    };\n\n    /**\n     * Construct this instance of SplatTree from an instance of SplatMesh.\n     *\n     * @param {SplatMesh} splatMesh The instance of SplatMesh from which to construct this splat tree.\n     * @param {function} filterFunc Optional function to filter out unwanted splats.\n     * @param {function} onIndexesUpload Function to be called when the upload of splat centers to the splat tree\n     *                                   builder worker starts and finishes.\n     * @param {function} onSplatTreeConstruction Function to be called when the conversion of the local splat tree from\n     *                                           the format produced by the splat tree builder worker starts and ends.\n     * @return {undefined}\n     */\n    processSplatMesh = function(splatMesh, filterFunc = () => true, onIndexesUpload, onSplatTreeConstruction) {\n        if (!this.splatTreeWorker) this.splatTreeWorker = checkAndCreateWorker();\n\n        this.splatMesh = splatMesh;\n        this.subTrees = [];\n        const center = new THREE.Vector3();\n\n        const addCentersForScene = (splatOffset, splatCount) => {\n            const sceneCenters = new Float32Array(splatCount * 4);\n            let addedCount = 0;\n            for (let i = 0; i < splatCount; i++) {\n                const globalSplatIndex = i + splatOffset;\n                if (filterFunc(globalSplatIndex)) {\n                    splatMesh.getSplatCenter(globalSplatIndex, center);\n                    const addBase = addedCount * 4;\n                    sceneCenters[addBase] = center.x;\n                    sceneCenters[addBase + 1] = center.y;\n                    sceneCenters[addBase + 2] = center.z;\n                    sceneCenters[addBase + 3] = globalSplatIndex;\n                    addedCount++;\n                }\n            }\n            return sceneCenters;\n        };\n\n        return new Promise((resolve) => {\n\n            const checkForEarlyExit = () => {\n                if (this.disposed) {\n                    this.diposeSplatTreeWorker();\n                    resolve();\n                    return true;\n                }\n                return false;\n            };\n\n            if (onIndexesUpload) onIndexesUpload(false);\n\n            delayedExecute(() => {\n\n                if (checkForEarlyExit()) return;\n\n                const allCenters = [];\n                if (splatMesh.dynamicMode) {\n                    let splatOffset = 0;\n                    for (let s = 0; s < splatMesh.scenes.length; s++) {\n                        const scene = splatMesh.getScene(s);\n                        const splatCount = scene.splatBuffer.getSplatCount();\n                        const sceneCenters = addCentersForScene(splatOffset, splatCount);\n                        allCenters.push(sceneCenters);\n                        splatOffset += splatCount;\n                    }\n                } else {\n                    const sceneCenters = addCentersForScene(0, splatMesh.getSplatCount());\n                    allCenters.push(sceneCenters);\n                }\n\n                this.splatTreeWorker.onmessage = (e) => {\n\n                    if (checkForEarlyExit()) return;\n\n                    if (e.data.subTrees) {\n\n                        if (onSplatTreeConstruction) onSplatTreeConstruction(false);\n\n                        delayedExecute(() => {\n\n                            if (checkForEarlyExit()) return;\n\n                            for (let workerSubTree of e.data.subTrees) {\n                                const convertedSubTree = SplatSubTree.convertWorkerSubTree(workerSubTree, splatMesh);\n                                this.subTrees.push(convertedSubTree);\n                            }\n                            this.diposeSplatTreeWorker();\n\n                            if (onSplatTreeConstruction) onSplatTreeConstruction(true);\n\n                            delayedExecute(() => {\n                                resolve();\n                            });\n\n                        });\n                    }\n                };\n\n                delayedExecute(() => {\n                    if (checkForEarlyExit()) return;\n                    if (onIndexesUpload) onIndexesUpload(true);\n                    const transferBuffers = allCenters.map((array) => array.buffer);\n                    workerProcessCenters(this.splatTreeWorker, allCenters, transferBuffers, this.maxDepth, this.maxCentersPerNode);\n                });\n\n            });\n\n        });\n\n    };\n\n    countLeaves() {\n\n        let leafCount = 0;\n        this.visitLeaves(() => {\n            leafCount++;\n        });\n\n        return leafCount;\n    }\n\n    visitLeaves(visitFunc) {\n\n        const visitLeavesFromNode = (node, visitFunc) => {\n            if (node.children.length === 0) visitFunc(node);\n            for (let child of node.children) {\n                visitLeavesFromNode(child, visitFunc);\n            }\n        };\n\n        for (let subTree of this.subTrees) {\n            visitLeavesFromNode(subTree.rootNode, visitFunc);\n        }\n    }\n\n}\n","function WebGLExtensions( gl ) {\n\n    const extensions = {};\n\n    function getExtension( name ) {\n\n        if ( extensions[name] !== undefined ) {\n\n            return extensions[name];\n\n        }\n\n        let extension;\n\n        switch ( name ) {\n\n            case 'WEBGL_depth_texture':\n                extension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) ||\n                            gl.getExtension( 'WEBKIT_WEBGL_depth_texture' );\n                break;\n\n            case 'EXT_texture_filter_anisotropic':\n                extension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) ||\n                            gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) ||\n                            gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );\n                break;\n\n            case 'WEBGL_compressed_texture_s3tc':\n                extension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) ||\n                            gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) ||\n                            gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );\n                break;\n\n            case 'WEBGL_compressed_texture_pvrtc':\n                extension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) ||\n                           gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' );\n                break;\n\n            default:\n                extension = gl.getExtension( name );\n\n        }\n\n        extensions[name] = extension;\n\n        return extension;\n\n    }\n\n    return {\n\n        has: function( name ) {\n\n            return getExtension( name ) !== null;\n\n        },\n\n        init: function( capabilities ) {\n\n            if ( capabilities.isWebGL2 ) {\n\n                getExtension( 'EXT_color_buffer_float' );\n                getExtension( 'WEBGL_clip_cull_distance' );\n\n            } else {\n\n                getExtension( 'WEBGL_depth_texture' );\n                getExtension( 'OES_texture_float' );\n                getExtension( 'OES_texture_half_float' );\n                getExtension( 'OES_texture_half_float_linear' );\n                getExtension( 'OES_standard_derivatives' );\n                getExtension( 'OES_element_index_uint' );\n                getExtension( 'OES_vertex_array_object' );\n                getExtension( 'ANGLE_instanced_arrays' );\n\n            }\n\n            getExtension( 'OES_texture_float_linear' );\n            getExtension( 'EXT_color_buffer_half_float' );\n            getExtension( 'WEBGL_multisampled_render_to_texture' );\n\n        },\n\n        get: function( name ) {\n\n            const extension = getExtension( name );\n\n            if ( extension === null ) {\n\n                console.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' );\n\n            }\n\n            return extension;\n\n        }\n\n    };\n\n}\n\nexport { WebGLExtensions };\n","function WebGLCapabilities( gl, extensions, parameters ) {\n\n    let maxAnisotropy;\n\n    function getMaxAnisotropy() {\n\n        if ( maxAnisotropy !== undefined ) return maxAnisotropy;\n\n        if ( extensions.has( 'EXT_texture_filter_anisotropic' ) === true ) {\n\n            const extension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n            maxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT );\n\n        } else {\n\n            maxAnisotropy = 0;\n\n        }\n\n        return maxAnisotropy;\n\n    }\n\n    function getMaxPrecision( precision ) {\n\n        if ( precision === 'highp' ) {\n\n            if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 &&\n                gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) {\n\n                return 'highp';\n\n            }\n\n            precision = 'mediump';\n\n        }\n\n        if ( precision === 'mediump' ) {\n\n            if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 &&\n                gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) {\n\n                return 'mediump';\n\n            }\n\n        }\n\n        return 'lowp';\n\n    }\n\n    const isWebGL2 = typeof WebGL2RenderingContext !== 'undefined' && gl.constructor.name === 'WebGL2RenderingContext';\n\n    let precision = parameters.precision !== undefined ? parameters.precision : 'highp';\n    const maxPrecision = getMaxPrecision( precision );\n\n    if ( maxPrecision !== precision ) {\n\n        console.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' );\n        precision = maxPrecision;\n\n    }\n\n    const drawBuffers = isWebGL2 || extensions.has( 'WEBGL_draw_buffers' );\n\n    const logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true;\n\n    const maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n    const maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );\n    const maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE );\n    const maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE );\n\n    const maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n    const maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS );\n    const maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS );\n    const maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS );\n\n    const vertexTextures = maxVertexTextures > 0;\n    const floatFragmentTextures = isWebGL2 || extensions.has( 'OES_texture_float' );\n    const floatVertexTextures = vertexTextures && floatFragmentTextures;\n\n    const maxSamples = isWebGL2 ? gl.getParameter( gl.MAX_SAMPLES ) : 0;\n\n    return {\n\n        isWebGL2: isWebGL2,\n\n        drawBuffers: drawBuffers,\n\n        getMaxAnisotropy: getMaxAnisotropy,\n        getMaxPrecision: getMaxPrecision,\n\n        precision: precision,\n        logarithmicDepthBuffer: logarithmicDepthBuffer,\n\n        maxTextures: maxTextures,\n        maxVertexTextures: maxVertexTextures,\n        maxTextureSize: maxTextureSize,\n        maxCubemapSize: maxCubemapSize,\n\n        maxAttributes: maxAttributes,\n        maxVertexUniforms: maxVertexUniforms,\n        maxVaryings: maxVaryings,\n        maxFragmentUniforms: maxFragmentUniforms,\n\n        vertexTextures: vertexTextures,\n        floatFragmentTextures: floatFragmentTextures,\n        floatVertexTextures: floatVertexTextures,\n\n        maxSamples: maxSamples\n\n    };\n\n}\n\n\nexport { WebGLCapabilities };\n","export const SceneRevealMode = {\n    Default: 0,\n    Gradual: 1,\n    Instant: 2\n};\n","export const LogLevel = {\n    None: 0,\n    Error: 1,\n    Warning: 2,\n    Info: 3,\n    Debug: 4\n};\n","import * as THREE from 'three';\nimport { SplatMaterial3D } from './SplatMaterial3D.js';\nimport { SplatMaterial2D } from './SplatMaterial2D.js';\nimport { SplatGeometry } from './SplatGeometry.js';\nimport { SplatScene } from './SplatScene.js';\nimport { SplatTree } from '../splattree/SplatTree.js';\nimport { WebGLExtensions } from '../three-shim/WebGLExtensions.js';\nimport { WebGLCapabilities } from '../three-shim/WebGLCapabilities.js';\nimport { uintEncodedFloat, rgbaArrayToInteger } from '../Util.js';\nimport { Constants } from '../Constants.js';\nimport { SceneRevealMode } from '../SceneRevealMode.js';\nimport { SplatRenderMode } from '../SplatRenderMode.js';\nimport { LogLevel } from '../LogLevel.js';\nimport { clamp, getSphericalHarmonicsComponentCountForDegree } from '../Util.js';\n\nconst dummyGeometry = new THREE.BufferGeometry();\nconst dummyMaterial = new THREE.MeshBasicMaterial();\n\nconst COVARIANCES_ELEMENTS_PER_SPLAT = 6;\nconst CENTER_COLORS_ELEMENTS_PER_SPLAT = 4;\n\nconst COVARIANCES_ELEMENTS_PER_TEXEL_STORED = 4;\nconst COVARIANCES_ELEMENTS_PER_TEXEL_ALLOCATED = 4;\nconst COVARIANCES_ELEMENTS_PER_TEXEL_COMPRESSED_STORED = 6;\nconst COVARIANCES_ELEMENTS_PER_TEXEL_COMPRESSED_ALLOCATED = 8;\nconst SCALES_ROTATIONS_ELEMENTS_PER_TEXEL = 4;\nconst CENTER_COLORS_ELEMENTS_PER_TEXEL = 4;\nconst SCENE_INDEXES_ELEMENTS_PER_TEXEL = 1;\n\nconst SCENE_FADEIN_RATE_FAST = 0.012;\nconst SCENE_FADEIN_RATE_GRADUAL = 0.003;\n\nconst VISIBLE_REGION_EXPANSION_DELTA = 1;\n\n// Based on my own observations across multiple devices, OSes and browsers, using textures that have one dimension\n// greater than 4096 while the other is greater than or equal to 4096 causes issues (Essentially any texture larger\n// than 4096 x 4096 (16777216) texels). Specifically it seems all texture data beyond the 4096 x 4096 texel boundary\n// is corrupted, while data below that boundary is usable. In these cases the texture has been valid in the eyes of\n// both Three.js and WebGL, and the texel format (RG, RGBA, etc.) has not mattered. More investigation will be needed,\n// but for now the work-around is to split the spherical harmonics into three textures (one for each color channel).\nconst MAX_TEXTURE_TEXELS = 16777216;\n\n/**\n * SplatMesh: Container for one or more splat scenes, abstracting them into a single unified container for\n * splat data. Additionally contains data structures and code to make the splat data renderable as a Three.js mesh.\n */\nexport class SplatMesh extends THREE.Mesh {\n\n    constructor(splatRenderMode = SplatRenderMode.ThreeD, dynamicMode = false, enableOptionalEffects = false,\n                halfPrecisionCovariancesOnGPU = false, devicePixelRatio = 1, enableDistancesComputationOnGPU = true,\n                integerBasedDistancesComputation = false, antialiased = false, maxScreenSpaceSplatSize = 1024, logLevel = LogLevel.None,\n                sphericalHarmonicsDegree = 0, sceneFadeInRateMultiplier = 1.0, kernel2DSize = 0.3) {\n        super(dummyGeometry, dummyMaterial);\n\n        // Reference to a Three.js renderer\n        this.renderer = undefined;\n\n        // Determine how the splats are rendered\n        this.splatRenderMode = splatRenderMode;\n\n        // When 'dynamicMode' is true, scenes are assumed to be non-static. Dynamic scenes are handled differently\n        // and certain optimizations cannot be made for them. Additionally, by default, all splat data retrieved from\n        // this splat mesh will not have their scene transform applied to them if the splat mesh is dynamic. That\n        // can be overriden via parameters to the individual functions that are used to retrieve splat data.\n        this.dynamicMode = dynamicMode;\n\n        // When true, allows for usage of extra properties and attributes during rendering for effects such as opacity adjustment.\n        // Default is false for performance reasons. These properties are separate from transform properties (scale, rotation, position)\n        // that are enabled by the 'dynamicScene' parameter.\n        this.enableOptionalEffects = enableOptionalEffects;\n\n        // Use 16-bit floating point values when storing splat covariance data in textures, instead of 32-bit\n        this.halfPrecisionCovariancesOnGPU = halfPrecisionCovariancesOnGPU;\n\n        // Ratio of the resolution in physical pixels to the resolution in CSS pixels for the current display device\n        this.devicePixelRatio = devicePixelRatio;\n\n        // Use a transform feedback to calculate splat distances from the camera\n        this.enableDistancesComputationOnGPU = enableDistancesComputationOnGPU;\n\n        // Use a faster integer-based approach for calculating splat distances from the camera\n        this.integerBasedDistancesComputation = integerBasedDistancesComputation;\n\n        // When true, will perform additional steps during rendering to address artifacts caused by the rendering of gaussians at a\n        // substantially different resolution than that at which they were rendered during training. This will only work correctly\n        // for models that were trained using a process that utilizes this compensation calculation. For more details:\n        // https://github.com/nerfstudio-project/gsplat/pull/117\n        // https://github.com/graphdeco-inria/gaussian-splatting/issues/294#issuecomment-1772688093\n        this.antialiased = antialiased;\n\n        // The size of the 2D kernel used for splat rendering\n        // This will adjust the 2D kernel size after the projection\n        this.kernel2DSize = kernel2DSize;\n\n        // Specify the maximum clip space splat size, can help deal with large splats that get too unwieldy\n        this.maxScreenSpaceSplatSize = maxScreenSpaceSplatSize;\n\n        // The verbosity of console logging\n        this.logLevel = logLevel;\n\n        // Degree 0 means no spherical harmonics\n        this.sphericalHarmonicsDegree = sphericalHarmonicsDegree;\n        this.minSphericalHarmonicsDegree = 0;\n\n        this.sceneFadeInRateMultiplier = sceneFadeInRateMultiplier;\n\n        // The individual splat scenes stored in this splat mesh, each containing their own transform\n        this.scenes = [];\n\n        // Special octree tailored to SplatMesh instances\n        this.splatTree = null;\n        this.baseSplatTree = null;\n\n        // Cache textures and the intermediate data used to populate them\n        this.splatDataTextures = {};\n\n        this.distancesTransformFeedback = {\n            'id': null,\n            'vertexShader': null,\n            'fragmentShader': null,\n            'program': null,\n            'centersBuffer': null,\n            'sceneIndexesBuffer': null,\n            'outDistancesBuffer': null,\n            'centersLoc': -1,\n            'modelViewProjLoc': -1,\n            'sceneIndexesLoc': -1,\n            'transformsLocs': []\n        };\n\n        this.globalSplatIndexToLocalSplatIndexMap = [];\n        this.globalSplatIndexToSceneIndexMap = [];\n\n        this.lastBuildSplatCount = 0;\n        this.lastBuildScenes = [];\n        this.lastBuildMaxSplatCount = 0;\n        this.lastBuildSceneCount = 0;\n        this.firstRenderTime = -1;\n        this.finalBuild = false;\n\n        this.webGLUtils = null;\n\n        this.boundingBox = new THREE.Box3();\n        this.calculatedSceneCenter = new THREE.Vector3();\n        this.maxSplatDistanceFromSceneCenter = 0;\n        this.visibleRegionBufferRadius = 0;\n        this.visibleRegionRadius = 0;\n        this.visibleRegionFadeStartRadius = 0;\n        this.visibleRegionChanging = false;\n\n        this.splatScale = 1.0;\n        this.pointCloudModeEnabled = false;\n\n        this.disposed = false;\n        this.lastRenderer = null;\n        this.visible = false;\n    }\n\n    /**\n     * Build a container for each scene managed by this splat mesh based on an instance of SplatBuffer, along with optional\n     * transform data (position, scale, rotation) passed to the splat mesh during the build process.\n     * @param {Array<THREE.Matrix4>} splatBuffers SplatBuffer instances containing splats for each scene\n     * @param {Array<object>} sceneOptions Array of options objects: {\n     *\n     *         position (Array<number>):   Position of the scene, acts as an offset from its default position, defaults to [0, 0, 0]\n     *\n     *         rotation (Array<number>):   Rotation of the scene represented as a quaternion, defaults to [0, 0, 0, 1]\n     *\n     *         scale (Array<number>):      Scene's scale, defaults to [1, 1, 1]\n     * }\n     * @return {Array<THREE.Matrix4>}\n     */\n    static buildScenes(parentObject, splatBuffers, sceneOptions) {\n        const scenes = [];\n        scenes.length = splatBuffers.length;\n        for (let i = 0; i < splatBuffers.length; i++) {\n            const splatBuffer = splatBuffers[i];\n            const options = sceneOptions[i] || {};\n            let positionArray = options['position'] || [0, 0, 0];\n            let rotationArray = options['rotation'] || [0, 0, 0, 1];\n            let scaleArray = options['scale'] || [1, 1, 1];\n            const position = new THREE.Vector3().fromArray(positionArray);\n            const rotation = new THREE.Quaternion().fromArray(rotationArray);\n            const scale = new THREE.Vector3().fromArray(scaleArray);\n            const scene = SplatMesh.createScene(splatBuffer, position, rotation, scale,\n                                                options.splatAlphaRemovalThreshold || 1, options.opacity, options.visible);\n            parentObject.add(scene);\n            scenes[i] = scene;\n        }\n        return scenes;\n    }\n\n    static createScene(splatBuffer, position, rotation, scale, minimumAlpha, opacity = 1.0, visible = true) {\n        return new SplatScene(splatBuffer, position, rotation, scale, minimumAlpha, opacity, visible);\n    }\n\n    /**\n     * Build data structures that map global splat indexes (based on a unified index across all splat buffers) to\n     * local data within a single scene.\n     * @param {Array<SplatBuffer>} splatBuffers Instances of SplatBuffer off which to build the maps\n     * @return {object}\n     */\n    static buildSplatIndexMaps(splatBuffers) {\n        const localSplatIndexMap = [];\n        const sceneIndexMap = [];\n        let totalSplatCount = 0;\n        for (let s = 0; s < splatBuffers.length; s++) {\n            const splatBuffer = splatBuffers[s];\n            const maxSplatCount = splatBuffer.getMaxSplatCount();\n            for (let i = 0; i < maxSplatCount; i++) {\n                localSplatIndexMap[totalSplatCount] = i;\n                sceneIndexMap[totalSplatCount] = s;\n                totalSplatCount++;\n            }\n        }\n        return {\n            localSplatIndexMap,\n            sceneIndexMap\n        };\n    }\n\n    /**\n     * Build an instance of SplatTree (a specialized octree) for the given splat mesh.\n     * @param {Array<number>} minAlphas Array of minimum splat slphas for each scene\n     * @param {function} onSplatTreeIndexesUpload Function to be called when the upload of splat centers to the splat tree\n     *                                            builder worker starts and finishes.\n     * @param {function} onSplatTreeConstruction Function to be called when the conversion of the local splat tree from\n     *                                           the format produced by the splat tree builder worker starts and ends.\n     * @return {SplatTree}\n     */\n     buildSplatTree = function(minAlphas = [], onSplatTreeIndexesUpload, onSplatTreeConstruction) {\n        return new Promise((resolve) => {\n            this.disposeSplatTree();\n            // TODO: expose SplatTree constructor parameters (maximumDepth and maxCentersPerNode) so that they can\n            // be configured on a per-scene basis\n            this.baseSplatTree = new SplatTree(8, 1000);\n            const buildStartTime = performance.now();\n            const splatColor = new THREE.Vector4();\n            this.baseSplatTree.processSplatMesh(this, (splatIndex) => {\n                this.getSplatColor(splatIndex, splatColor);\n                const sceneIndex = this.getSceneIndexForSplat(splatIndex);\n                const minAlpha = minAlphas[sceneIndex] || 1;\n                return splatColor.w >= minAlpha;\n            }, onSplatTreeIndexesUpload, onSplatTreeConstruction)\n            .then(() => {\n                const buildTime = performance.now() - buildStartTime;\n                if (this.logLevel >= LogLevel.Info) console.log('SplatTree build: ' + buildTime + ' ms');\n                if (this.disposed) {\n                    resolve();\n                } else {\n\n                    this.splatTree = this.baseSplatTree;\n                    this.baseSplatTree = null;\n\n                    let leavesWithVertices = 0;\n                    let avgSplatCount = 0;\n                    let maxSplatCount = 0;\n                    let nodeCount = 0;\n\n                    this.splatTree.visitLeaves((node) => {\n                        const nodeSplatCount = node.data.indexes.length;\n                        if (nodeSplatCount > 0) {\n                            avgSplatCount += nodeSplatCount;\n                            maxSplatCount = Math.max(maxSplatCount, nodeSplatCount);\n                            nodeCount++;\n                            leavesWithVertices++;\n                        }\n                    });\n                    if (this.logLevel >= LogLevel.Info) {\n                        console.log(`SplatTree leaves: ${this.splatTree.countLeaves()}`);\n                        console.log(`SplatTree leaves with splats:${leavesWithVertices}`);\n                        avgSplatCount = avgSplatCount / nodeCount;\n                        console.log(`Avg splat count per node: ${avgSplatCount}`);\n                        console.log(`Total splat count: ${this.getSplatCount()}`);\n                    }\n                    resolve();\n                }\n            });\n        });\n    };\n\n    /**\n     * Construct this instance of SplatMesh.\n     * @param {Array<SplatBuffer>} splatBuffers The base splat data, instances of SplatBuffer\n     * @param {Array<object>} sceneOptions Dynamic options for each scene {\n     *\n     *         splatAlphaRemovalThreshold: Ignore any splats with an alpha less than the specified\n     *                                     value (valid range: 0 - 255), defaults to 1\n     *\n     *         position (Array<number>):   Position of the scene, acts as an offset from its default position, defaults to [0, 0, 0]\n     *\n     *         rotation (Array<number>):   Rotation of the scene represented as a quaternion, defaults to [0, 0, 0, 1]\n     *\n     *         scale (Array<number>):      Scene's scale, defaults to [1, 1, 1]\n     *\n     * }\n     * @param {boolean} keepSceneTransforms For a scene that already exists and is being overwritten, this flag\n     *                                      says to keep the transform from the existing scene.\n     * @param {boolean} finalBuild Will the splat mesh be in its final state after this build?\n     * @param {function} onSplatTreeIndexesUpload Function to be called when the upload of splat centers to the splat tree\n     *                                            builder worker starts and finishes.\n     * @param {function} onSplatTreeConstruction Function to be called when the conversion of the local splat tree from\n     *                                           the format produced by the splat tree builder worker starts and ends.\n     * @return {object} Object containing info about the splats that are updated\n     */\n    build(splatBuffers, sceneOptions, keepSceneTransforms = true, finalBuild = false,\n          onSplatTreeIndexesUpload, onSplatTreeConstruction, preserveVisibleRegion = true) {\n\n        this.sceneOptions = sceneOptions;\n        this.finalBuild = finalBuild;\n\n        const maxSplatCount = SplatMesh.getTotalMaxSplatCountForSplatBuffers(splatBuffers);\n\n        const newScenes = SplatMesh.buildScenes(this, splatBuffers, sceneOptions);\n        if (keepSceneTransforms) {\n            for (let i = 0; i < this.scenes.length && i < newScenes.length; i++) {\n                const newScene = newScenes[i];\n                const existingScene = this.getScene(i);\n                newScene.copyTransformData(existingScene);\n            }\n        }\n        this.scenes = newScenes;\n\n        let minSphericalHarmonicsDegree = 3;\n        for (let splatBuffer of splatBuffers) {\n            const splatBufferSphericalHarmonicsDegree = splatBuffer.getMinSphericalHarmonicsDegree();\n            if (splatBufferSphericalHarmonicsDegree < minSphericalHarmonicsDegree) {\n                minSphericalHarmonicsDegree = splatBufferSphericalHarmonicsDegree;\n            }\n        }\n        this.minSphericalHarmonicsDegree = Math.min(minSphericalHarmonicsDegree, this.sphericalHarmonicsDegree);\n\n        let splatBuffersChanged = false;\n        if (splatBuffers.length !== this.lastBuildScenes.length) {\n            splatBuffersChanged = true;\n        } else {\n            for (let i = 0; i < splatBuffers.length; i++) {\n                const splatBuffer = splatBuffers[i];\n                if (splatBuffer !== this.lastBuildScenes[i].splatBuffer) {\n                    splatBuffersChanged = true;\n                    break;\n                }\n            }\n        }\n\n        let isUpdateBuild = true;\n        if (this.scenes.length !== 1 ||\n            this.lastBuildSceneCount !== this.scenes.length ||\n            this.lastBuildMaxSplatCount !== maxSplatCount ||\n            splatBuffersChanged) {\n                isUpdateBuild = false;\n       }\n\n       if (!isUpdateBuild) {\n            this.boundingBox = new THREE.Box3();\n            if (!preserveVisibleRegion) {\n                this.maxSplatDistanceFromSceneCenter = 0;\n                this.visibleRegionBufferRadius = 0;\n                this.visibleRegionRadius = 0;\n                this.visibleRegionFadeStartRadius = 0;\n                this.firstRenderTime = -1;\n            }\n            this.lastBuildScenes = [];\n            this.lastBuildSplatCount = 0;\n            this.lastBuildMaxSplatCount = 0;\n            this.disposeMeshData();\n            this.geometry = SplatGeometry.build(maxSplatCount);\n            if (this.splatRenderMode === SplatRenderMode.ThreeD) {\n                this.material = SplatMaterial3D.build(this.dynamicMode, this.enableOptionalEffects, this.antialiased,\n                                                      this.maxScreenSpaceSplatSize, this.splatScale, this.pointCloudModeEnabled,\n                                                      this.minSphericalHarmonicsDegree, this.kernel2DSize);\n            } else {\n                this.material = SplatMaterial2D.build(this.dynamicMode, this.enableOptionalEffects,\n                                                      this.splatScale, this.pointCloudModeEnabled, this.minSphericalHarmonicsDegree);\n            }\n\n            const indexMaps = SplatMesh.buildSplatIndexMaps(splatBuffers);\n            this.globalSplatIndexToLocalSplatIndexMap = indexMaps.localSplatIndexMap;\n            this.globalSplatIndexToSceneIndexMap = indexMaps.sceneIndexMap;\n        }\n\n        const splatBufferSplatCount = this.getSplatCount(true);\n        if (this.enableDistancesComputationOnGPU) this.setupDistancesComputationTransformFeedback();\n        const dataUpdateResults = this.refreshGPUDataFromSplatBuffers(isUpdateBuild);\n\n        for (let i = 0; i < this.scenes.length; i++) {\n            this.lastBuildScenes[i] = this.scenes[i];\n        }\n        this.lastBuildSplatCount = splatBufferSplatCount;\n        this.lastBuildMaxSplatCount = this.getMaxSplatCount();\n        this.lastBuildSceneCount = this.scenes.length;\n\n        if (finalBuild && this.scenes.length > 0) {\n            this.buildSplatTree(sceneOptions.map(options => options.splatAlphaRemovalThreshold || 1),\n                                onSplatTreeIndexesUpload, onSplatTreeConstruction)\n            .then(() => {\n                if (this.onSplatTreeReadyCallback) this.onSplatTreeReadyCallback(this.splatTree);\n                this.onSplatTreeReadyCallback = null;\n            });\n        }\n\n        this.visible = (this.scenes.length > 0);\n\n        return dataUpdateResults;\n    }\n\n    freeIntermediateSplatData() {\n\n        const deleteTextureData = (texture) => {\n            delete texture.source.data;\n            delete texture.image;\n            texture.onUpdate = null;\n        };\n\n        delete this.splatDataTextures.baseData.covariances;\n        delete this.splatDataTextures.baseData.centers;\n        delete this.splatDataTextures.baseData.colors;\n        delete this.splatDataTextures.baseData.sphericalHarmonics;\n\n        delete this.splatDataTextures.centerColors.data;\n        delete this.splatDataTextures.covariances.data;\n        if (this.splatDataTextures.sphericalHarmonics) {\n            delete this.splatDataTextures.sphericalHarmonics.data;\n        }\n        if (this.splatDataTextures.sceneIndexes) {\n            delete this.splatDataTextures.sceneIndexes.data;\n        }\n\n        this.splatDataTextures.centerColors.texture.needsUpdate = true;\n        this.splatDataTextures.centerColors.texture.onUpdate = () => {\n            deleteTextureData(this.splatDataTextures.centerColors.texture);\n        };\n\n        this.splatDataTextures.covariances.texture.needsUpdate = true;\n        this.splatDataTextures.covariances.texture.onUpdate = () => {\n            deleteTextureData(this.splatDataTextures.covariances.texture);\n        };\n\n        if (this.splatDataTextures.sphericalHarmonics) {\n            if (this.splatDataTextures.sphericalHarmonics.texture) {\n                this.splatDataTextures.sphericalHarmonics.texture.needsUpdate = true;\n                this.splatDataTextures.sphericalHarmonics.texture.onUpdate = () => {\n                    deleteTextureData(this.splatDataTextures.sphericalHarmonics.texture);\n                };\n            } else {\n                this.splatDataTextures.sphericalHarmonics.textures.forEach((texture) => {\n                    texture.needsUpdate = true;\n                    texture.onUpdate = () => {\n                        deleteTextureData(texture);\n                    };\n                });\n            }\n        }\n        if (this.splatDataTextures.sceneIndexes) {\n            this.splatDataTextures.sceneIndexes.texture.needsUpdate = true;\n            this.splatDataTextures.sceneIndexes.texture.onUpdate = () => {\n                deleteTextureData(this.splatDataTextures.sceneIndexes.texture);\n            };\n        }\n    }\n    /**\n     * Dispose all resources held by the splat mesh\n     */\n    dispose() {\n        this.disposeMeshData();\n        this.disposeTextures();\n        this.disposeSplatTree();\n        if (this.enableDistancesComputationOnGPU) {\n            if (this.computeDistancesOnGPUSyncTimeout) {\n                clearTimeout(this.computeDistancesOnGPUSyncTimeout);\n                this.computeDistancesOnGPUSyncTimeout = null;\n            }\n            this.disposeDistancesComputationGPUResources();\n        }\n        this.scenes = [];\n        this.distancesTransformFeedback = {\n            'id': null,\n            'vertexShader': null,\n            'fragmentShader': null,\n            'program': null,\n            'centersBuffer': null,\n            'sceneIndexesBuffer': null,\n            'outDistancesBuffer': null,\n            'centersLoc': -1,\n            'modelViewProjLoc': -1,\n            'sceneIndexesLoc': -1,\n            'transformsLocs': []\n        };\n        this.renderer = null;\n\n        this.globalSplatIndexToLocalSplatIndexMap = [];\n        this.globalSplatIndexToSceneIndexMap = [];\n\n        this.lastBuildSplatCount = 0;\n        this.lastBuildScenes = [];\n        this.lastBuildMaxSplatCount = 0;\n        this.lastBuildSceneCount = 0;\n        this.firstRenderTime = -1;\n        this.finalBuild = false;\n\n        this.webGLUtils = null;\n\n        this.boundingBox = new THREE.Box3();\n        this.calculatedSceneCenter = new THREE.Vector3();\n        this.maxSplatDistanceFromSceneCenter = 0;\n        this.visibleRegionBufferRadius = 0;\n        this.visibleRegionRadius = 0;\n        this.visibleRegionFadeStartRadius = 0;\n        this.visibleRegionChanging = false;\n\n        this.splatScale = 1.0;\n        this.pointCloudModeEnabled = false;\n\n        this.disposed = true;\n        this.lastRenderer = null;\n        this.visible = false;\n    }\n\n    /**\n     * Dispose of only the Three.js mesh resources (geometry, material, and texture)\n     */\n    disposeMeshData() {\n        if (this.geometry && this.geometry !== dummyGeometry) {\n            this.geometry.dispose();\n            this.geometry = null;\n        }\n        if (this.material) {\n            this.material.dispose();\n            this.material = null;\n        }\n    }\n\n    disposeTextures() {\n        for (let textureKey in this.splatDataTextures) {\n            if (this.splatDataTextures.hasOwnProperty(textureKey)) {\n                const textureContainer = this.splatDataTextures[textureKey];\n                if (textureContainer.texture) {\n                    textureContainer.texture.dispose();\n                    textureContainer.texture = null;\n                }\n            }\n        }\n        this.splatDataTextures = null;\n    }\n\n    disposeSplatTree() {\n        if (this.splatTree) {\n            this.splatTree.dispose();\n            this.splatTree = null;\n        }\n        if (this.baseSplatTree) {\n            this.baseSplatTree.dispose();\n            this.baseSplatTree = null;\n        }\n    }\n\n    getSplatTree() {\n        return this.splatTree;\n    }\n\n    onSplatTreeReady(callback) {\n        this.onSplatTreeReadyCallback = callback;\n    }\n\n    /**\n     * Get copies of data that are necessary for splat distance computation: splat center positions and splat\n     * scene indexes (necessary for applying dynamic scene transformations during distance computation)\n     * @param {*} start The index at which to start copying data\n     * @param {*} end  The index at which to stop copying data\n     * @return {object}\n     */\n    getDataForDistancesComputation(start, end) {\n        const centers = this.integerBasedDistancesComputation ?\n                        this.getIntegerCenters(start, end, true) :\n                        this.getFloatCenters(start, end, true);\n        const sceneIndexes = this.getSceneIndexes(start, end);\n        return {\n            centers,\n            sceneIndexes\n        };\n    }\n\n    /**\n     * Refresh data textures and GPU buffers with splat data from the splat buffers belonging to this mesh.\n     * @param {boolean} sinceLastBuildOnly Specify whether or not to only update for splats that have been added since the last build.\n     * @return {object}\n     */\n    refreshGPUDataFromSplatBuffers(sinceLastBuildOnly) {\n        const splatCount = this.getSplatCount(true);\n        this.refreshDataTexturesFromSplatBuffers(sinceLastBuildOnly);\n        const updateStart = sinceLastBuildOnly ? this.lastBuildSplatCount : 0;\n        const { centers, sceneIndexes } = this.getDataForDistancesComputation(updateStart, splatCount - 1);\n        if (this.enableDistancesComputationOnGPU) {\n            this.refreshGPUBuffersForDistancesComputation(centers, sceneIndexes, sinceLastBuildOnly);\n        }\n        return {\n            'from': updateStart,\n            'to': splatCount - 1,\n            'count': splatCount - updateStart,\n            'centers': centers,\n            'sceneIndexes': sceneIndexes\n        };\n    }\n\n    /**\n     * Update the GPU buffers that are used for computing splat distances on the GPU.\n     * @param {Array<number>} centers Splat center positions\n     * @param {Array<number>} sceneIndexes Indexes of the scene to which each splat belongs\n     * @param {boolean} sinceLastBuildOnly Specify whether or not to only update for splats that have been added since the last build.\n     */\n    refreshGPUBuffersForDistancesComputation(centers, sceneIndexes, sinceLastBuildOnly = false) {\n        const offset = sinceLastBuildOnly ? this.lastBuildSplatCount : 0;\n        this.updateGPUCentersBufferForDistancesComputation(sinceLastBuildOnly, centers, offset);\n        this.updateGPUTransformIndexesBufferForDistancesComputation(sinceLastBuildOnly, sceneIndexes, offset);\n    }\n\n    /**\n     * Refresh data textures with data from the splat buffers for this mesh.\n     * @param {boolean} sinceLastBuildOnly Specify whether or not to only update for splats that have been added since the last build.\n     */\n    refreshDataTexturesFromSplatBuffers(sinceLastBuildOnly) {\n        const splatCount = this.getSplatCount(true);\n        const fromSplat = this.lastBuildSplatCount;\n        const toSplat = splatCount - 1;\n\n        if (!sinceLastBuildOnly) {\n            this.setupDataTextures();\n            this.updateBaseDataFromSplatBuffers();\n        } else {\n            this.updateBaseDataFromSplatBuffers(fromSplat, toSplat);\n        }\n\n        this.updateDataTexturesFromBaseData(fromSplat, toSplat);\n        this.updateVisibleRegion(sinceLastBuildOnly);\n    }\n\n    setupDataTextures() {\n        const maxSplatCount = this.getMaxSplatCount();\n        const splatCount = this.getSplatCount(true);\n\n        this.disposeTextures();\n\n        const computeDataTextureSize = (elementsPerTexel, elementsPerSplat) => {\n            const texSize = new THREE.Vector2(4096, 1024);\n            while (texSize.x * texSize.y * elementsPerTexel < maxSplatCount * elementsPerSplat) texSize.y *= 2;\n            return texSize;\n        };\n\n        const getCovariancesElementsPertexelStored = (compressionLevel) => {\n            return compressionLevel >= 1 ? COVARIANCES_ELEMENTS_PER_TEXEL_COMPRESSED_STORED : COVARIANCES_ELEMENTS_PER_TEXEL_STORED;\n        };\n\n        const getCovariancesInitialTextureSpecs = (compressionLevel) => {\n            const elementsPerTexelStored = getCovariancesElementsPertexelStored(compressionLevel);\n            const texSize = computeDataTextureSize(elementsPerTexelStored, 6);\n            return {elementsPerTexelStored, texSize};\n        };\n\n        let covarianceCompressionLevel = this.getTargetCovarianceCompressionLevel();\n        const scaleRotationCompressionLevel = 0;\n        const shCompressionLevel = this.getTargetSphericalHarmonicsCompressionLevel();\n\n        let covariances;\n        let scales;\n        let rotations;\n        if (this.splatRenderMode === SplatRenderMode.ThreeD) {\n            const initialCovTexSpecs = getCovariancesInitialTextureSpecs(covarianceCompressionLevel);\n            if (initialCovTexSpecs.texSize.x * initialCovTexSpecs.texSize.y > MAX_TEXTURE_TEXELS && covarianceCompressionLevel === 0) {\n                covarianceCompressionLevel = 1;\n            }\n            covariances = new Float32Array(maxSplatCount * COVARIANCES_ELEMENTS_PER_SPLAT);\n        } else {\n            scales = new Float32Array(maxSplatCount * 3);\n            rotations = new Float32Array(maxSplatCount * 4);\n        }\n\n        const centers = new Float32Array(maxSplatCount * 3);\n        const colors = new Uint8Array(maxSplatCount * 4);\n\n        let SphericalHarmonicsArrayType = Float32Array;\n        if (shCompressionLevel === 1) SphericalHarmonicsArrayType = Uint16Array;\n        else if (shCompressionLevel === 2) SphericalHarmonicsArrayType = Uint8Array;\n        const shComponentCount = getSphericalHarmonicsComponentCountForDegree(this.minSphericalHarmonicsDegree);\n        const shData = this.minSphericalHarmonicsDegree ? new SphericalHarmonicsArrayType(maxSplatCount * shComponentCount) : undefined;\n\n        // set up centers/colors data texture\n        const centersColsTexSize = computeDataTextureSize(CENTER_COLORS_ELEMENTS_PER_TEXEL, 4);\n        const paddedCentersCols = new Uint32Array(centersColsTexSize.x * centersColsTexSize.y * CENTER_COLORS_ELEMENTS_PER_TEXEL);\n        SplatMesh.updateCenterColorsPaddedData(0, splatCount - 1, centers, colors, paddedCentersCols);\n\n        const centersColsTex = new THREE.DataTexture(paddedCentersCols, centersColsTexSize.x, centersColsTexSize.y,\n                                                     THREE.RGBAIntegerFormat, THREE.UnsignedIntType);\n        centersColsTex.internalFormat = 'RGBA32UI';\n        centersColsTex.needsUpdate = true;\n        this.material.uniforms.centersColorsTexture.value = centersColsTex;\n        this.material.uniforms.centersColorsTextureSize.value.copy(centersColsTexSize);\n        this.material.uniformsNeedUpdate = true;\n\n        this.splatDataTextures = {\n            'baseData': {\n                'covariances': covariances,\n                'scales': scales,\n                'rotations': rotations,\n                'centers': centers,\n                'colors': colors,\n                'sphericalHarmonics': shData\n            },\n            'centerColors': {\n                'data': paddedCentersCols,\n                'texture': centersColsTex,\n                'size': centersColsTexSize\n            }\n        };\n\n        if (this.splatRenderMode === SplatRenderMode.ThreeD) {\n            // set up covariances data texture\n\n            const covTexSpecs = getCovariancesInitialTextureSpecs(covarianceCompressionLevel);\n            const covariancesElementsPerTexelStored = covTexSpecs.elementsPerTexelStored;\n            const covTexSize = covTexSpecs.texSize;\n\n            let CovariancesDataType = covarianceCompressionLevel >= 1 ? Uint32Array : Float32Array;\n            const covariancesElementsPerTexelAllocated = covarianceCompressionLevel >= 1 ?\n                                                         COVARIANCES_ELEMENTS_PER_TEXEL_COMPRESSED_ALLOCATED :\n                                                         COVARIANCES_ELEMENTS_PER_TEXEL_ALLOCATED;\n            const covariancesTextureData = new CovariancesDataType(covTexSize.x * covTexSize.y * covariancesElementsPerTexelAllocated);\n\n            if (covarianceCompressionLevel === 0) {\n                covariancesTextureData.set(covariances);\n            } else {\n                SplatMesh.updatePaddedCompressedCovariancesTextureData(covariances, covariancesTextureData, 0, 0, covariances.length);\n            }\n\n            let covTex;\n            if (covarianceCompressionLevel >= 1) {\n                covTex = new THREE.DataTexture(covariancesTextureData, covTexSize.x, covTexSize.y,\n                                               THREE.RGBAIntegerFormat, THREE.UnsignedIntType);\n                covTex.internalFormat = 'RGBA32UI';\n                this.material.uniforms.covariancesTextureHalfFloat.value = covTex;\n            } else {\n                covTex = new THREE.DataTexture(covariancesTextureData, covTexSize.x, covTexSize.y, THREE.RGBAFormat, THREE.FloatType);\n                this.material.uniforms.covariancesTexture.value = covTex;\n\n                // For some reason a usampler2D needs to have a valid texture attached or WebGL complains\n                const dummyTex = new THREE.DataTexture(new Uint32Array(32), 2, 2, THREE.RGBAIntegerFormat, THREE.UnsignedIntType);\n                dummyTex.internalFormat = 'RGBA32UI';\n                this.material.uniforms.covariancesTextureHalfFloat.value = dummyTex;\n                dummyTex.needsUpdate = true;\n            }\n            covTex.needsUpdate = true;\n\n            this.material.uniforms.covariancesAreHalfFloat.value = (covarianceCompressionLevel >= 1) ? 1 : 0;\n            this.material.uniforms.covariancesTextureSize.value.copy(covTexSize);\n\n            this.splatDataTextures['covariances'] = {\n                'data': covariancesTextureData,\n                'texture': covTex,\n                'size': covTexSize,\n                'compressionLevel': covarianceCompressionLevel,\n                'elementsPerTexelStored': covariancesElementsPerTexelStored,\n                'elementsPerTexelAllocated': covariancesElementsPerTexelAllocated\n            };\n        } else {\n            // set up scale & rotations data texture\n            const elementsPerSplat = 6;\n            const scaleRotationsTexSize = computeDataTextureSize(SCALES_ROTATIONS_ELEMENTS_PER_TEXEL, elementsPerSplat);\n            let ScaleRotationsDataType = scaleRotationCompressionLevel >= 1 ? Uint16Array : Float32Array;\n            let scaleRotationsTextureType = scaleRotationCompressionLevel >= 1 ? THREE.HalfFloatType : THREE.FloatType;\n            const paddedScaleRotations = new ScaleRotationsDataType(scaleRotationsTexSize.x * scaleRotationsTexSize.y *\n                                                                    SCALES_ROTATIONS_ELEMENTS_PER_TEXEL);\n\n            SplatMesh.updateScaleRotationsPaddedData(0, splatCount - 1, scales, rotations, paddedScaleRotations);\n\n            const scaleRotationsTex = new THREE.DataTexture(paddedScaleRotations, scaleRotationsTexSize.x, scaleRotationsTexSize.y,\n                                                            THREE.RGBAFormat, scaleRotationsTextureType);\n            scaleRotationsTex.needsUpdate = true;\n            this.material.uniforms.scaleRotationsTexture.value = scaleRotationsTex;\n            this.material.uniforms.scaleRotationsTextureSize.value.copy(scaleRotationsTexSize);\n\n            this.splatDataTextures['scaleRotations'] = {\n                'data': paddedScaleRotations,\n                'texture': scaleRotationsTex,\n                'size': scaleRotationsTexSize,\n                'compressionLevel': scaleRotationCompressionLevel\n            };\n        }\n\n        if (shData) {\n            const shTextureType = shCompressionLevel === 2 ? THREE.UnsignedByteType : THREE.HalfFloatType;\n\n            let paddedSHComponentCount = shComponentCount;\n            if (paddedSHComponentCount % 2 !== 0) paddedSHComponentCount++;\n            const shElementsPerTexel = 4;\n            const texelFormat = shElementsPerTexel === 4 ? THREE.RGBAFormat : THREE.RGFormat;\n            let shTexSize = computeDataTextureSize(shElementsPerTexel, paddedSHComponentCount);\n\n            // Use one texture for all spherical harmonics data\n            if (shTexSize.x * shTexSize.y <= MAX_TEXTURE_TEXELS) {\n                const paddedSHArraySize = shTexSize.x * shTexSize.y * shElementsPerTexel;\n                const paddedSHArray = new SphericalHarmonicsArrayType(paddedSHArraySize);\n                for (let c = 0; c < splatCount; c++) {\n                    const srcBase = shComponentCount * c;\n                    const destBase = paddedSHComponentCount * c;\n                    for (let i = 0; i < shComponentCount; i++) {\n                        paddedSHArray[destBase + i] = shData[srcBase + i];\n                    }\n                }\n\n                const shTexture = new THREE.DataTexture(paddedSHArray, shTexSize.x, shTexSize.y, texelFormat, shTextureType);\n                shTexture.needsUpdate = true;\n                this.material.uniforms.sphericalHarmonicsTexture.value = shTexture;\n                this.splatDataTextures['sphericalHarmonics'] = {\n                    'componentCount': shComponentCount,\n                    'paddedComponentCount': paddedSHComponentCount,\n                    'data': paddedSHArray,\n                    'textureCount': 1,\n                    'texture': shTexture,\n                    'size': shTexSize,\n                    'compressionLevel': shCompressionLevel,\n                    'elementsPerTexel': shElementsPerTexel\n                };\n            // Use three textures for spherical harmonics data, one per color channel\n            } else {\n                const shComponentCountPerChannel = shComponentCount / 3;\n                paddedSHComponentCount = shComponentCountPerChannel;\n                if (paddedSHComponentCount % 2 !== 0) paddedSHComponentCount++;\n                shTexSize = computeDataTextureSize(shElementsPerTexel, paddedSHComponentCount);\n\n                const paddedSHArraySize = shTexSize.x * shTexSize.y * shElementsPerTexel;\n                const textureUniforms = [this.material.uniforms.sphericalHarmonicsTextureR,\n                                         this.material.uniforms.sphericalHarmonicsTextureG,\n                                         this.material.uniforms.sphericalHarmonicsTextureB];\n                const paddedSHArrays = [];\n                const shTextures = [];\n                for (let t = 0; t < 3; t++) {\n                    const paddedSHArray = new SphericalHarmonicsArrayType(paddedSHArraySize);\n                    paddedSHArrays.push(paddedSHArray);\n                    for (let c = 0; c < splatCount; c++) {\n                        const srcBase = shComponentCount * c;\n                        const destBase = paddedSHComponentCount * c;\n                        if (shComponentCountPerChannel >= 3) {\n                            for (let i = 0; i < 3; i++) paddedSHArray[destBase + i] = shData[srcBase + t * 3 + i];\n                            if (shComponentCountPerChannel >= 8) {\n                                for (let i = 0; i < 5; i++) paddedSHArray[destBase + 3 + i] = shData[srcBase + 9 + t * 5 + i];\n                            }\n                        }\n                    }\n\n                    const shTexture = new THREE.DataTexture(paddedSHArray, shTexSize.x, shTexSize.y, texelFormat, shTextureType);\n                    shTextures.push(shTexture);\n                    shTexture.needsUpdate = true;\n                    textureUniforms[t].value = shTexture;\n                }\n\n                this.material.uniforms.sphericalHarmonicsMultiTextureMode.value = 1;\n                this.splatDataTextures['sphericalHarmonics'] = {\n                    'componentCount': shComponentCount,\n                    'componentCountPerChannel': shComponentCountPerChannel,\n                    'paddedComponentCount': paddedSHComponentCount,\n                    'data': paddedSHArrays,\n                    'textureCount': 3,\n                    'textures': shTextures,\n                    'size': shTexSize,\n                    'compressionLevel': shCompressionLevel,\n                    'elementsPerTexel': shElementsPerTexel\n                };\n            }\n\n            this.material.uniforms.sphericalHarmonicsTextureSize.value.copy(shTexSize);\n            this.material.uniforms.sphericalHarmonics8BitMode.value = shCompressionLevel === 2 ? 1 : 0;\n            for (let s = 0; s < this.scenes.length; s++) {\n                const splatBuffer = this.scenes[s].splatBuffer;\n                this.material.uniforms.sphericalHarmonics8BitCompressionRangeMin.value[s] =\n                    splatBuffer.minSphericalHarmonicsCoeff;\n                this.material.uniforms.sphericalHarmonics8BitCompressionRangeMax.value[s] =\n                    splatBuffer.maxSphericalHarmonicsCoeff;\n            }\n            this.material.uniformsNeedUpdate = true;\n        }\n\n        const sceneIndexesTexSize = computeDataTextureSize(SCENE_INDEXES_ELEMENTS_PER_TEXEL, 4);\n        const paddedTransformIndexes = new Uint32Array(sceneIndexesTexSize.x *\n                                                       sceneIndexesTexSize.y * SCENE_INDEXES_ELEMENTS_PER_TEXEL);\n        for (let c = 0; c < splatCount; c++) paddedTransformIndexes[c] = this.globalSplatIndexToSceneIndexMap[c];\n        const sceneIndexesTexture = new THREE.DataTexture(paddedTransformIndexes, sceneIndexesTexSize.x, sceneIndexesTexSize.y,\n                                                          THREE.RedIntegerFormat, THREE.UnsignedIntType);\n        sceneIndexesTexture.internalFormat = 'R32UI';\n        sceneIndexesTexture.needsUpdate = true;\n        this.material.uniforms.sceneIndexesTexture.value = sceneIndexesTexture;\n        this.material.uniforms.sceneIndexesTextureSize.value.copy(sceneIndexesTexSize);\n        this.material.uniformsNeedUpdate = true;\n        this.splatDataTextures['sceneIndexes'] = {\n            'data': paddedTransformIndexes,\n            'texture': sceneIndexesTexture,\n            'size': sceneIndexesTexSize\n        };\n        this.material.uniforms.sceneCount.value = this.scenes.length;\n    }\n\n    updateBaseDataFromSplatBuffers(fromSplat, toSplat) {\n        const covarancesTextureDesc = this.splatDataTextures['covariances'];\n        const covarianceCompressionLevel = covarancesTextureDesc ? covarancesTextureDesc.compressionLevel : undefined;\n        const scaleRotationsTextureDesc = this.splatDataTextures['scaleRotations'];\n        const scaleRotationCompressionLevel = scaleRotationsTextureDesc ? scaleRotationsTextureDesc.compressionLevel : undefined;\n        const shITextureDesc = this.splatDataTextures['sphericalHarmonics'];\n        const shCompressionLevel = shITextureDesc ? shITextureDesc.compressionLevel : 0;\n\n        this.fillSplatDataArrays(this.splatDataTextures.baseData.covariances, this.splatDataTextures.baseData.scales,\n                                 this.splatDataTextures.baseData.rotations, this.splatDataTextures.baseData.centers,\n                                 this.splatDataTextures.baseData.colors, this.splatDataTextures.baseData.sphericalHarmonics, undefined,\n                                 covarianceCompressionLevel, scaleRotationCompressionLevel, shCompressionLevel,\n                                 fromSplat, toSplat, fromSplat);\n    }\n\n    updateDataTexturesFromBaseData(fromSplat, toSplat) {\n        const covarancesTextureDesc = this.splatDataTextures['covariances'];\n        const covarianceCompressionLevel = covarancesTextureDesc ? covarancesTextureDesc.compressionLevel : undefined;\n        const scaleRotationsTextureDesc = this.splatDataTextures['scaleRotations'];\n        const scaleRotationCompressionLevel = scaleRotationsTextureDesc ? scaleRotationsTextureDesc.compressionLevel : undefined;\n        const shTextureDesc = this.splatDataTextures['sphericalHarmonics'];\n        const shCompressionLevel = shTextureDesc ? shTextureDesc.compressionLevel : 0;\n\n        // Update center & color data texture\n        const centerColorsTextureDescriptor = this.splatDataTextures['centerColors'];\n        const paddedCenterColors = centerColorsTextureDescriptor.data;\n        const centerColorsTexture = centerColorsTextureDescriptor.texture;\n        SplatMesh.updateCenterColorsPaddedData(fromSplat, toSplat, this.splatDataTextures.baseData.centers,\n                                               this.splatDataTextures.baseData.colors, paddedCenterColors);\n        const centerColorsTextureProps = this.renderer ? this.renderer.properties.get(centerColorsTexture) : null;\n        if (!centerColorsTextureProps || !centerColorsTextureProps.__webglTexture) {\n            centerColorsTexture.needsUpdate = true;\n        } else {\n            this.updateDataTexture(paddedCenterColors, centerColorsTextureDescriptor.texture, centerColorsTextureDescriptor.size,\n                                   centerColorsTextureProps, CENTER_COLORS_ELEMENTS_PER_TEXEL, CENTER_COLORS_ELEMENTS_PER_SPLAT, 4,\n                                   fromSplat, toSplat);\n        }\n\n        // update covariance data texture\n        if (covarancesTextureDesc) {\n            const covariancesTexture = covarancesTextureDesc.texture;\n            const covarancesStartElement = fromSplat * COVARIANCES_ELEMENTS_PER_SPLAT;\n            const covariancesEndElement = toSplat * COVARIANCES_ELEMENTS_PER_SPLAT;\n\n            if (covarianceCompressionLevel === 0) {\n                for (let i = covarancesStartElement; i <= covariancesEndElement; i++) {\n                    const covariance = this.splatDataTextures.baseData.covariances[i];\n                    covarancesTextureDesc.data[i] = covariance;\n                }\n            } else {\n                SplatMesh.updatePaddedCompressedCovariancesTextureData(this.splatDataTextures.baseData.covariances,\n                                                                       covarancesTextureDesc.data,\n                                                                       fromSplat * covarancesTextureDesc.elementsPerTexelAllocated,\n                                                                       covarancesStartElement, covariancesEndElement);\n            }\n\n            const covariancesTextureProps = this.renderer ? this.renderer.properties.get(covariancesTexture) : null;\n            if (!covariancesTextureProps || !covariancesTextureProps.__webglTexture) {\n                covariancesTexture.needsUpdate = true;\n            } else {\n                if (covarianceCompressionLevel === 0) {\n                    this.updateDataTexture(covarancesTextureDesc.data, covarancesTextureDesc.texture, covarancesTextureDesc.size,\n                                           covariancesTextureProps, covarancesTextureDesc.elementsPerTexelStored,\n                                           COVARIANCES_ELEMENTS_PER_SPLAT, 4, fromSplat, toSplat);\n                } else {\n                    this.updateDataTexture(covarancesTextureDesc.data, covarancesTextureDesc.texture, covarancesTextureDesc.size,\n                                           covariancesTextureProps, covarancesTextureDesc.elementsPerTexelAllocated,\n                                           covarancesTextureDesc.elementsPerTexelAllocated, 2, fromSplat, toSplat);\n                }\n            }\n        }\n\n        // update scale and rotation data texture\n        if (scaleRotationsTextureDesc) {\n            const paddedScaleRotations = scaleRotationsTextureDesc.data;\n            const scaleRotationsTexture = scaleRotationsTextureDesc.texture;\n            const elementsPerSplat = 6;\n            const bytesPerElement = scaleRotationCompressionLevel === 0 ? 4 : 2;\n\n            SplatMesh.updateScaleRotationsPaddedData(fromSplat, toSplat, this.splatDataTextures.baseData.scales,\n                                                     this.splatDataTextures.baseData.rotations, paddedScaleRotations);\n            const scaleRotationsTextureProps = this.renderer ? this.renderer.properties.get(scaleRotationsTexture) : null;\n            if (!scaleRotationsTextureProps || !scaleRotationsTextureProps.__webglTexture) {\n                scaleRotationsTexture.needsUpdate = true;\n            } else {\n                this.updateDataTexture(paddedScaleRotations, scaleRotationsTextureDesc.texture, scaleRotationsTextureDesc.size,\n                                       scaleRotationsTextureProps, SCALES_ROTATIONS_ELEMENTS_PER_TEXEL, elementsPerSplat, bytesPerElement,\n                                       fromSplat, toSplat);\n            }\n        }\n\n        // update spherical harmonics data texture\n        const shData = this.splatDataTextures.baseData.sphericalHarmonics;\n        if (shData) {\n            let shBytesPerElement = 4;\n            if (shCompressionLevel === 1) shBytesPerElement = 2;\n            else if (shCompressionLevel === 2) shBytesPerElement = 1;\n\n            const updateTexture = (shTexture, shTextureSize, elementsPerTexel, paddedSHArray, paddedSHComponentCount) => {\n                const shTextureProps = this.renderer ? this.renderer.properties.get(shTexture) : null;\n                if (!shTextureProps || !shTextureProps.__webglTexture) {\n                    shTexture.needsUpdate = true;\n                } else {\n                    this.updateDataTexture(paddedSHArray, shTexture, shTextureSize, shTextureProps, elementsPerTexel,\n                                           paddedSHComponentCount, shBytesPerElement, fromSplat, toSplat);\n                }\n            };\n\n            const shComponentCount = shTextureDesc.componentCount;\n            const paddedSHComponentCount = shTextureDesc.paddedComponentCount;\n\n            // Update for the case of a single texture for all spherical harmonics data\n            if (shTextureDesc.textureCount === 1) {\n                const paddedSHArray = shTextureDesc.data;\n                for (let c = fromSplat; c <= toSplat; c++) {\n                    const srcBase = shComponentCount * c;\n                    const destBase = paddedSHComponentCount * c;\n                    for (let i = 0; i < shComponentCount; i++) {\n                        paddedSHArray[destBase + i] = shData[srcBase + i];\n                    }\n                }\n                updateTexture(shTextureDesc.texture, shTextureDesc.size,\n                              shTextureDesc.elementsPerTexel, paddedSHArray, paddedSHComponentCount);\n            // Update for the case of spherical harmonics data split among three textures, one for each color channel\n            } else {\n                const shComponentCountPerChannel = shTextureDesc.componentCountPerChannel;\n                for (let t = 0; t < 3; t++) {\n                    const paddedSHArray = shTextureDesc.data[t];\n                    for (let c = fromSplat; c <= toSplat; c++) {\n                        const srcBase = shComponentCount * c;\n                        const destBase = paddedSHComponentCount * c;\n                        if (shComponentCountPerChannel >= 3) {\n                            for (let i = 0; i < 3; i++) paddedSHArray[destBase + i] = shData[srcBase + t * 3 + i];\n                            if (shComponentCountPerChannel >= 8) {\n                                for (let i = 0; i < 5; i++) paddedSHArray[destBase + 3 + i] = shData[srcBase + 9 + t * 5 + i];\n                            }\n                        }\n                    }\n                    updateTexture(shTextureDesc.textures[t], shTextureDesc.size,\n                                  shTextureDesc.elementsPerTexel, paddedSHArray, paddedSHComponentCount);\n                }\n            }\n        }\n\n        // update scene index & transform data\n        const sceneIndexesTexDesc = this.splatDataTextures['sceneIndexes'];\n        const paddedSceneIndexes = sceneIndexesTexDesc.data;\n        for (let c = this.lastBuildSplatCount; c <= toSplat; c++) {\n            paddedSceneIndexes[c] = this.globalSplatIndexToSceneIndexMap[c];\n        }\n        const sceneIndexesTexture = sceneIndexesTexDesc.texture;\n        const sceneIndexesTextureProps = this.renderer ? this.renderer.properties.get(sceneIndexesTexture) : null;\n        if (!sceneIndexesTextureProps || !sceneIndexesTextureProps.__webglTexture) {\n            sceneIndexesTexture.needsUpdate = true;\n        } else {\n            this.updateDataTexture(paddedSceneIndexes, sceneIndexesTexDesc.texture, sceneIndexesTexDesc.size,\n                                   sceneIndexesTextureProps, 1, 1, 1, this.lastBuildSplatCount, toSplat);\n        }\n    }\n\n    getTargetCovarianceCompressionLevel() {\n        return this.halfPrecisionCovariancesOnGPU ? 1 : 0;\n    }\n\n    getTargetSphericalHarmonicsCompressionLevel() {\n        return Math.max(1, this.getMaximumSplatBufferCompressionLevel());\n    }\n\n    getMaximumSplatBufferCompressionLevel() {\n        let maxCompressionLevel;\n        for (let i = 0; i < this.scenes.length; i++) {\n            const scene = this.getScene(i);\n            const splatBuffer = scene.splatBuffer;\n            if (i === 0 || splatBuffer.compressionLevel > maxCompressionLevel) {\n                maxCompressionLevel = splatBuffer.compressionLevel;\n            }\n        }\n        return maxCompressionLevel;\n    }\n\n    getMinimumSplatBufferCompressionLevel() {\n        let minCompressionLevel;\n        for (let i = 0; i < this.scenes.length; i++) {\n            const scene = this.getScene(i);\n            const splatBuffer = scene.splatBuffer;\n            if (i === 0 || splatBuffer.compressionLevel < minCompressionLevel) {\n                minCompressionLevel = splatBuffer.compressionLevel;\n            }\n        }\n        return minCompressionLevel;\n    }\n\n    static computeTextureUpdateRegion(startSplat, endSplat, textureWidth, elementsPerTexel, elementsPerSplat) {\n        const texelsPerSplat = elementsPerSplat / elementsPerTexel;\n\n        const startSplatTexels = startSplat * texelsPerSplat;\n        const startRow = Math.floor(startSplatTexels / textureWidth);\n        const startRowElement = startRow * textureWidth * elementsPerTexel;\n\n        const endSplatTexels = endSplat * texelsPerSplat;\n        const endRow = Math.floor(endSplatTexels / textureWidth);\n        const endRowEndElement = endRow * textureWidth * elementsPerTexel + (textureWidth * elementsPerTexel);\n\n        return {\n            'dataStart': startRowElement,\n            'dataEnd': endRowEndElement,\n            'startRow': startRow,\n            'endRow': endRow\n        };\n    }\n\n    updateDataTexture(paddedData, texture, textureSize, textureProps, elementsPerTexel, elementsPerSplat, bytesPerElement, from, to) {\n        const gl = this.renderer.getContext();\n        const updateRegion = SplatMesh.computeTextureUpdateRegion(from, to, textureSize.x, elementsPerTexel, elementsPerSplat);\n        const updateElementCount = updateRegion.dataEnd - updateRegion.dataStart;\n        const updateDataView = new paddedData.constructor(paddedData.buffer,\n                                                          updateRegion.dataStart * bytesPerElement, updateElementCount);\n        const updateHeight = updateRegion.endRow - updateRegion.startRow + 1;\n        const glType = this.webGLUtils.convert(texture.type);\n        const glFormat = this.webGLUtils.convert(texture.format, texture.colorSpace);\n        const currentTexture = gl.getParameter(gl.TEXTURE_BINDING_2D);\n        gl.bindTexture(gl.TEXTURE_2D, textureProps.__webglTexture);\n        gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, updateRegion.startRow,\n                         textureSize.x, updateHeight, glFormat, glType, updateDataView);\n        gl.bindTexture(gl.TEXTURE_2D, currentTexture);\n    }\n\n    static updatePaddedCompressedCovariancesTextureData(sourceData, textureData, textureDataStartIndex, fromElement, toElement) {\n        let textureDataView = new DataView(textureData.buffer);\n        let textureDataIndex = textureDataStartIndex;\n        let sequentialCount = 0;\n        for (let i = fromElement; i <= toElement; i+=2) {\n            textureDataView.setUint16(textureDataIndex * 2, sourceData[i], true);\n            textureDataView.setUint16(textureDataIndex * 2 + 2, sourceData[i + 1], true);\n            textureDataIndex += 2;\n            sequentialCount++;\n            if (sequentialCount >= 3) {\n                textureDataIndex += 2;\n                sequentialCount = 0;\n            }\n        }\n    }\n\n    static updateCenterColorsPaddedData(from, to, centers, colors, paddedCenterColors) {\n        for (let c = from; c <= to; c++) {\n            const colorsBase = c * 4;\n            const centersBase = c * 3;\n            const centerColorsBase = c * 4;\n            paddedCenterColors[centerColorsBase] = rgbaArrayToInteger(colors, colorsBase);\n            paddedCenterColors[centerColorsBase + 1] = uintEncodedFloat(centers[centersBase]);\n            paddedCenterColors[centerColorsBase + 2] = uintEncodedFloat(centers[centersBase + 1]);\n            paddedCenterColors[centerColorsBase + 3] = uintEncodedFloat(centers[centersBase + 2]);\n        }\n    }\n\n    static updateScaleRotationsPaddedData(from, to, scales, rotations, paddedScaleRotations) {\n        const combinedSize = 6;\n        for (let c = from; c <= to; c++) {\n            const scaleBase = c * 3;\n            const rotationBase = c * 4;\n            const scaleRotationsBase = c * combinedSize;\n\n            paddedScaleRotations[scaleRotationsBase] = scales[scaleBase];\n            paddedScaleRotations[scaleRotationsBase + 1] = scales[scaleBase + 1];\n            paddedScaleRotations[scaleRotationsBase + 2] = scales[scaleBase + 2];\n\n            paddedScaleRotations[scaleRotationsBase + 3] = rotations[rotationBase];\n            paddedScaleRotations[scaleRotationsBase + 4] = rotations[rotationBase + 1];\n            paddedScaleRotations[scaleRotationsBase + 5] = rotations[rotationBase + 2];\n        }\n    }\n\n    updateVisibleRegion(sinceLastBuildOnly) {\n        const splatCount = this.getSplatCount(true);\n        const tempCenter = new THREE.Vector3();\n        if (!sinceLastBuildOnly) {\n            const avgCenter = new THREE.Vector3();\n            this.scenes.forEach((scene) => {\n                avgCenter.add(scene.splatBuffer.sceneCenter);\n            });\n            avgCenter.multiplyScalar(1.0 / this.scenes.length);\n            this.calculatedSceneCenter.copy(avgCenter);\n            this.material.uniforms.sceneCenter.value.copy(this.calculatedSceneCenter);\n            this.material.uniformsNeedUpdate = true;\n        }\n\n        const startSplatFormMaxDistanceCalc = sinceLastBuildOnly ? this.lastBuildSplatCount : 0;\n        for (let i = startSplatFormMaxDistanceCalc; i < splatCount; i++) {\n            this.getSplatCenter(i, tempCenter, true);\n            const distFromCSceneCenter = tempCenter.sub(this.calculatedSceneCenter).length();\n            if (distFromCSceneCenter > this.maxSplatDistanceFromSceneCenter) this.maxSplatDistanceFromSceneCenter = distFromCSceneCenter;\n        }\n\n        if (this.maxSplatDistanceFromSceneCenter - this.visibleRegionBufferRadius > VISIBLE_REGION_EXPANSION_DELTA) {\n            this.visibleRegionBufferRadius = this.maxSplatDistanceFromSceneCenter;\n            this.visibleRegionRadius = Math.max(this.visibleRegionBufferRadius - VISIBLE_REGION_EXPANSION_DELTA, 0.0);\n        }\n        if (this.finalBuild) this.visibleRegionRadius = this.visibleRegionBufferRadius = this.maxSplatDistanceFromSceneCenter;\n        this.updateVisibleRegionFadeDistance();\n    }\n\n    updateVisibleRegionFadeDistance(sceneRevealMode = SceneRevealMode.Default) {\n        const fastFadeRate = SCENE_FADEIN_RATE_FAST * this.sceneFadeInRateMultiplier;\n        const gradualFadeRate = SCENE_FADEIN_RATE_GRADUAL * this.sceneFadeInRateMultiplier;\n        const defaultFadeInRate = this.finalBuild ? fastFadeRate : gradualFadeRate;\n        const fadeInRate = sceneRevealMode === SceneRevealMode.Default ? defaultFadeInRate : gradualFadeRate;\n        this.visibleRegionFadeStartRadius = (this.visibleRegionRadius - this.visibleRegionFadeStartRadius) *\n                                             fadeInRate + this.visibleRegionFadeStartRadius;\n        const fadeInPercentage = (this.visibleRegionBufferRadius > 0) ?\n                                 (this.visibleRegionFadeStartRadius / this.visibleRegionBufferRadius) : 0;\n        const fadeInComplete = fadeInPercentage > 0.99;\n        const shaderFadeInComplete = (fadeInComplete || sceneRevealMode === SceneRevealMode.Instant) ? 1 : 0;\n\n        this.material.uniforms.visibleRegionFadeStartRadius.value = this.visibleRegionFadeStartRadius;\n        this.material.uniforms.visibleRegionRadius.value = this.visibleRegionRadius;\n        this.material.uniforms.firstRenderTime.value = this.firstRenderTime;\n        this.material.uniforms.currentTime.value = performance.now();\n        this.material.uniforms.fadeInComplete.value = shaderFadeInComplete;\n        this.material.uniformsNeedUpdate = true;\n        this.visibleRegionChanging = !fadeInComplete;\n    }\n\n    /**\n     * Set the indexes of splats that should be rendered; should be sorted in desired render order.\n     * @param {Uint32Array} globalIndexes Sorted index list of splats to be rendered\n     * @param {number} renderSplatCount Total number of splats to be rendered. Necessary because we may not want to render\n     *                                  every splat.\n     */\n    updateRenderIndexes(globalIndexes, renderSplatCount) {\n        const geometry = this.geometry;\n        geometry.attributes.splatIndex.set(globalIndexes);\n        geometry.attributes.splatIndex.needsUpdate = true;\n        if (renderSplatCount > 0 && this.firstRenderTime === -1) this.firstRenderTime = performance.now();\n        geometry.instanceCount = renderSplatCount;\n        geometry.setDrawRange(0, renderSplatCount);\n    }\n\n    /**\n     * Update the transforms for each scene in this splat mesh from their individual components (position,\n     * quaternion, and scale)\n     */\n    updateTransforms() {\n        for (let i = 0; i < this.scenes.length; i++) {\n            const scene = this.getScene(i);\n            scene.updateTransform(this.dynamicMode);\n        }\n    }\n\n    updateUniforms = function() {\n\n        const viewport = new THREE.Vector2();\n\n        return function(renderDimensions, cameraFocalLengthX, cameraFocalLengthY,\n                        orthographicMode, orthographicZoom, inverseFocalAdjustment) {\n            const splatCount = this.getSplatCount();\n            if (splatCount > 0) {\n                viewport.set(renderDimensions.x * this.devicePixelRatio,\n                             renderDimensions.y * this.devicePixelRatio);\n                this.material.uniforms.viewport.value.copy(viewport);\n                this.material.uniforms.basisViewport.value.set(1.0 / viewport.x, 1.0 / viewport.y);\n                this.material.uniforms.focal.value.set(cameraFocalLengthX, cameraFocalLengthY);\n                this.material.uniforms.orthographicMode.value = orthographicMode ? 1 : 0;\n                this.material.uniforms.orthoZoom.value = orthographicZoom;\n                this.material.uniforms.inverseFocalAdjustment.value = inverseFocalAdjustment;\n                if (this.dynamicMode) {\n                    for (let i = 0; i < this.scenes.length; i++) {\n                        this.material.uniforms.transforms.value[i].copy(this.getScene(i).transform);\n                    }\n                }\n                if (this.enableOptionalEffects) {\n                    for (let i = 0; i < this.scenes.length; i++) {\n                        this.material.uniforms.sceneOpacity.value[i] = clamp(this.getScene(i).opacity, 0.0, 1.0);\n                        this.material.uniforms.sceneVisibility.value[i] = this.getScene(i).visible ? 1 : 0;\n                        this.material.uniformsNeedUpdate = true;\n                    }\n                }\n                this.material.uniformsNeedUpdate = true;\n            }\n        };\n\n    }();\n\n    setSplatScale(splatScale = 1) {\n        this.splatScale = splatScale;\n        this.material.uniforms.splatScale.value = splatScale;\n        this.material.uniformsNeedUpdate = true;\n    }\n\n    getSplatScale() {\n        return this.splatScale;\n    }\n\n    setPointCloudModeEnabled(enabled) {\n        this.pointCloudModeEnabled = enabled;\n        this.material.uniforms.pointCloudModeEnabled.value = enabled ? 1 : 0;\n        this.material.uniformsNeedUpdate = true;\n    }\n\n    getPointCloudModeEnabled() {\n        return this.pointCloudModeEnabled;\n    }\n\n    getSplatDataTextures() {\n        return this.splatDataTextures;\n    }\n\n    getSplatCount(includeSinceLastBuild = false) {\n        if (!includeSinceLastBuild) return this.lastBuildSplatCount;\n        else return SplatMesh.getTotalSplatCountForScenes(this.scenes);\n    }\n\n    static getTotalSplatCountForScenes(scenes) {\n        let totalSplatCount = 0;\n        for (let scene of scenes) {\n            if (scene && scene.splatBuffer) totalSplatCount += scene.splatBuffer.getSplatCount();\n        }\n        return totalSplatCount;\n    }\n\n    static getTotalSplatCountForSplatBuffers(splatBuffers) {\n        let totalSplatCount = 0;\n        for (let splatBuffer of splatBuffers) totalSplatCount += splatBuffer.getSplatCount();\n        return totalSplatCount;\n    }\n\n    getMaxSplatCount() {\n        return SplatMesh.getTotalMaxSplatCountForScenes(this.scenes);\n    }\n\n    static getTotalMaxSplatCountForScenes(scenes) {\n        let totalSplatCount = 0;\n        for (let scene of scenes) {\n            if (scene && scene.splatBuffer) totalSplatCount += scene.splatBuffer.getMaxSplatCount();\n        }\n        return totalSplatCount;\n    }\n\n    static getTotalMaxSplatCountForSplatBuffers(splatBuffers) {\n        let totalSplatCount = 0;\n        for (let splatBuffer of splatBuffers) totalSplatCount += splatBuffer.getMaxSplatCount();\n        return totalSplatCount;\n    }\n\n    disposeDistancesComputationGPUResources() {\n\n        if (!this.renderer) return;\n\n        const gl = this.renderer.getContext();\n\n        if (this.distancesTransformFeedback.vao) {\n            gl.deleteVertexArray(this.distancesTransformFeedback.vao);\n            this.distancesTransformFeedback.vao = null;\n        }\n        if (this.distancesTransformFeedback.program) {\n            gl.deleteProgram(this.distancesTransformFeedback.program);\n            gl.deleteShader(this.distancesTransformFeedback.vertexShader);\n            gl.deleteShader(this.distancesTransformFeedback.fragmentShader);\n            this.distancesTransformFeedback.program = null;\n            this.distancesTransformFeedback.vertexShader = null;\n            this.distancesTransformFeedback.fragmentShader = null;\n        }\n        this.disposeDistancesComputationGPUBufferResources();\n        if (this.distancesTransformFeedback.id) {\n            gl.deleteTransformFeedback(this.distancesTransformFeedback.id);\n            this.distancesTransformFeedback.id = null;\n        }\n    }\n\n    disposeDistancesComputationGPUBufferResources() {\n\n        if (!this.renderer) return;\n\n        const gl = this.renderer.getContext();\n\n        if (this.distancesTransformFeedback.centersBuffer) {\n            this.distancesTransformFeedback.centersBuffer = null;\n            gl.deleteBuffer(this.distancesTransformFeedback.centersBuffer);\n        }\n        if (this.distancesTransformFeedback.outDistancesBuffer) {\n            gl.deleteBuffer(this.distancesTransformFeedback.outDistancesBuffer);\n            this.distancesTransformFeedback.outDistancesBuffer = null;\n        }\n    }\n\n    /**\n     * Set the Three.js renderer used by this splat mesh\n     * @param {THREE.WebGLRenderer} renderer Instance of THREE.WebGLRenderer\n     */\n    setRenderer(renderer) {\n        if (renderer !== this.renderer) {\n            this.renderer = renderer;\n            const gl = this.renderer.getContext();\n            const extensions = new WebGLExtensions(gl);\n            const capabilities = new WebGLCapabilities(gl, extensions, {});\n            extensions.init(capabilities);\n            this.webGLUtils = new THREE.WebGLUtils(gl, extensions, capabilities);\n            if (this.enableDistancesComputationOnGPU && this.getSplatCount() > 0) {\n                this.setupDistancesComputationTransformFeedback();\n                const { centers, sceneIndexes } = this.getDataForDistancesComputation(0, this.getSplatCount() - 1);\n                this.refreshGPUBuffersForDistancesComputation(centers, sceneIndexes);\n            }\n        }\n    }\n\n    setupDistancesComputationTransformFeedback = function() {\n\n        let currentMaxSplatCount;\n\n        return function() {\n            const maxSplatCount = this.getMaxSplatCount();\n\n            if (!this.renderer) return;\n\n            const rebuildGPUObjects = (this.lastRenderer !== this.renderer);\n            const rebuildBuffers = currentMaxSplatCount !== maxSplatCount;\n\n            if (!rebuildGPUObjects && !rebuildBuffers) return;\n\n            if (rebuildGPUObjects) {\n                this.disposeDistancesComputationGPUResources();\n            } else if (rebuildBuffers) {\n                this.disposeDistancesComputationGPUBufferResources();\n            }\n\n            const gl = this.renderer.getContext();\n\n            const createShader = (gl, type, source) => {\n                const shader = gl.createShader(type);\n                if (!shader) {\n                    console.error('Fatal error: gl could not create a shader object.');\n                    return null;\n                }\n\n                gl.shaderSource(shader, source);\n                gl.compileShader(shader);\n\n                const compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);\n                if (!compiled) {\n                    let typeName = 'unknown';\n                    if (type === gl.VERTEX_SHADER) typeName = 'vertex shader';\n                    else if (type === gl.FRAGMENT_SHADER) typeName = 'fragement shader';\n                    const errors = gl.getShaderInfoLog(shader);\n                    console.error('Failed to compile ' + typeName + ' with these errors:' + errors);\n                    gl.deleteShader(shader);\n                    return null;\n                }\n\n                return shader;\n            };\n\n            let vsSource;\n            if (this.integerBasedDistancesComputation) {\n                vsSource =\n                `#version 300 es\n                in ivec4 center;\n                flat out int distance;`;\n                if (this.dynamicMode) {\n                    vsSource += `\n                        in uint sceneIndex;\n                        uniform ivec4 transforms[${Constants.MaxScenes}];\n                        void main(void) {\n                            ivec4 transform = transforms[sceneIndex];\n                            distance = center.x * transform.x + center.y * transform.y + center.z * transform.z + transform.w * center.w;\n                        }\n                    `;\n                } else {\n                    vsSource += `\n                        uniform ivec3 modelViewProj;\n                        void main(void) {\n                            distance = center.x * modelViewProj.x + center.y * modelViewProj.y + center.z * modelViewProj.z;\n                        }\n                    `;\n                }\n            } else {\n                vsSource =\n                `#version 300 es\n                in vec4 center;\n                flat out float distance;`;\n                if (this.dynamicMode) {\n                    vsSource += `\n                        in uint sceneIndex;\n                        uniform mat4 transforms[${Constants.MaxScenes}];\n                        void main(void) {\n                            vec4 transformedCenter = transforms[sceneIndex] * vec4(center.xyz, 1.0);\n                            distance = transformedCenter.z;\n                        }\n                    `;\n                } else {\n                    vsSource += `\n                        uniform vec3 modelViewProj;\n                        void main(void) {\n                            distance = center.x * modelViewProj.x + center.y * modelViewProj.y + center.z * modelViewProj.z;\n                        }\n                    `;\n                }\n            }\n\n            const fsSource =\n            `#version 300 es\n                precision lowp float;\n                out vec4 fragColor;\n                void main(){}\n            `;\n\n            const currentVao = gl.getParameter(gl.VERTEX_ARRAY_BINDING);\n            const currentProgram = gl.getParameter(gl.CURRENT_PROGRAM);\n            const currentProgramDeleted = currentProgram ? gl.getProgramParameter(currentProgram, gl.DELETE_STATUS) : false;\n\n            if (rebuildGPUObjects) {\n                this.distancesTransformFeedback.vao = gl.createVertexArray();\n            }\n\n            gl.bindVertexArray(this.distancesTransformFeedback.vao);\n\n            if (rebuildGPUObjects) {\n                const program = gl.createProgram();\n                const vertexShader = createShader(gl, gl.VERTEX_SHADER, vsSource);\n                const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fsSource);\n                if (!vertexShader || !fragmentShader) {\n                    throw new Error('Could not compile shaders for distances computation on GPU.');\n                }\n                gl.attachShader(program, vertexShader);\n                gl.attachShader(program, fragmentShader);\n                gl.transformFeedbackVaryings(program, ['distance'], gl.SEPARATE_ATTRIBS);\n                gl.linkProgram(program);\n\n                const linked = gl.getProgramParameter(program, gl.LINK_STATUS);\n                if (!linked) {\n                    const error = gl.getProgramInfoLog(program);\n                    console.error('Fatal error: Failed to link program: ' + error);\n                    gl.deleteProgram(program);\n                    gl.deleteShader(fragmentShader);\n                    gl.deleteShader(vertexShader);\n                    throw new Error('Could not link shaders for distances computation on GPU.');\n                }\n\n                this.distancesTransformFeedback.program = program;\n                this.distancesTransformFeedback.vertexShader = vertexShader;\n                this.distancesTransformFeedback.vertexShader = fragmentShader;\n            }\n\n            gl.useProgram(this.distancesTransformFeedback.program);\n\n            this.distancesTransformFeedback.centersLoc =\n                gl.getAttribLocation(this.distancesTransformFeedback.program, 'center');\n            if (this.dynamicMode) {\n                this.distancesTransformFeedback.sceneIndexesLoc =\n                    gl.getAttribLocation(this.distancesTransformFeedback.program, 'sceneIndex');\n                for (let i = 0; i < this.scenes.length; i++) {\n                    this.distancesTransformFeedback.transformsLocs[i] =\n                        gl.getUniformLocation(this.distancesTransformFeedback.program, `transforms[${i}]`);\n                }\n            } else {\n                this.distancesTransformFeedback.modelViewProjLoc =\n                    gl.getUniformLocation(this.distancesTransformFeedback.program, 'modelViewProj');\n            }\n\n            if (rebuildGPUObjects || rebuildBuffers) {\n                this.distancesTransformFeedback.centersBuffer = gl.createBuffer();\n                gl.bindBuffer(gl.ARRAY_BUFFER, this.distancesTransformFeedback.centersBuffer);\n                gl.enableVertexAttribArray(this.distancesTransformFeedback.centersLoc);\n                if (this.integerBasedDistancesComputation) {\n                    gl.vertexAttribIPointer(this.distancesTransformFeedback.centersLoc, 4, gl.INT, 0, 0);\n                } else {\n                    gl.vertexAttribPointer(this.distancesTransformFeedback.centersLoc, 4, gl.FLOAT, false, 0, 0);\n                }\n\n                if (this.dynamicMode) {\n                    this.distancesTransformFeedback.sceneIndexesBuffer = gl.createBuffer();\n                    gl.bindBuffer(gl.ARRAY_BUFFER, this.distancesTransformFeedback.sceneIndexesBuffer);\n                    gl.enableVertexAttribArray(this.distancesTransformFeedback.sceneIndexesLoc);\n                    gl.vertexAttribIPointer(this.distancesTransformFeedback.sceneIndexesLoc, 1, gl.UNSIGNED_INT, 0, 0);\n                }\n            }\n\n            if (rebuildGPUObjects || rebuildBuffers) {\n                this.distancesTransformFeedback.outDistancesBuffer = gl.createBuffer();\n            }\n            gl.bindBuffer(gl.ARRAY_BUFFER, this.distancesTransformFeedback.outDistancesBuffer);\n            gl.bufferData(gl.ARRAY_BUFFER, maxSplatCount * 4, gl.STATIC_READ);\n\n            if (rebuildGPUObjects) {\n                this.distancesTransformFeedback.id = gl.createTransformFeedback();\n            }\n            gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, this.distancesTransformFeedback.id);\n            gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, this.distancesTransformFeedback.outDistancesBuffer);\n\n            if (currentProgram && currentProgramDeleted !== true) gl.useProgram(currentProgram);\n            if (currentVao) gl.bindVertexArray(currentVao);\n\n            this.lastRenderer = this.renderer;\n            currentMaxSplatCount = maxSplatCount;\n        };\n\n    }();\n\n    /**\n     * Refresh GPU buffers used for computing splat distances with centers data from the scenes for this mesh.\n     * @param {boolean} isUpdate Specify whether or not to update the GPU buffer or to initialize & fill\n     * @param {Array<number>} centers The splat centers data\n     * @param {number} offsetSplats Offset in the GPU buffer at which to start updating data, specified in splats\n     */\n    updateGPUCentersBufferForDistancesComputation(isUpdate, centers, offsetSplats) {\n\n        if (!this.renderer) return;\n\n        const gl = this.renderer.getContext();\n\n        const currentVao = gl.getParameter(gl.VERTEX_ARRAY_BINDING);\n        gl.bindVertexArray(this.distancesTransformFeedback.vao);\n\n        const ArrayType = this.integerBasedDistancesComputation ? Uint32Array : Float32Array;\n        const attributeBytesPerCenter = 16;\n        const subBufferOffset = offsetSplats * attributeBytesPerCenter;\n\n        gl.bindBuffer(gl.ARRAY_BUFFER, this.distancesTransformFeedback.centersBuffer);\n\n        if (isUpdate) {\n            gl.bufferSubData(gl.ARRAY_BUFFER, subBufferOffset, centers);\n        } else {\n            const maxArray = new ArrayType(this.getMaxSplatCount() * attributeBytesPerCenter);\n            maxArray.set(centers);\n            gl.bufferData(gl.ARRAY_BUFFER, maxArray, gl.STATIC_DRAW);\n        }\n\n        gl.bindBuffer(gl.ARRAY_BUFFER, null);\n\n        if (currentVao) gl.bindVertexArray(currentVao);\n    }\n\n    /**\n     * Refresh GPU buffers used for pre-computing splat distances with centers data from the scenes for this mesh.\n     * @param {boolean} isUpdate Specify whether or not to update the GPU buffer or to initialize & fill\n     * @param {Array<number>} sceneIndexes The splat scene indexes\n     * @param {number} offsetSplats Offset in the GPU buffer at which to start updating data, specified in splats\n     */\n    updateGPUTransformIndexesBufferForDistancesComputation(isUpdate, sceneIndexes, offsetSplats) {\n\n        if (!this.renderer || !this.dynamicMode) return;\n\n        const gl = this.renderer.getContext();\n\n        const currentVao = gl.getParameter(gl.VERTEX_ARRAY_BINDING);\n        gl.bindVertexArray(this.distancesTransformFeedback.vao);\n\n        const subBufferOffset = offsetSplats * 4;\n\n        gl.bindBuffer(gl.ARRAY_BUFFER, this.distancesTransformFeedback.sceneIndexesBuffer);\n\n        if (isUpdate) {\n            gl.bufferSubData(gl.ARRAY_BUFFER, subBufferOffset, sceneIndexes);\n        } else {\n            const maxArray = new Uint32Array(this.getMaxSplatCount() * 4);\n            maxArray.set(sceneIndexes);\n            gl.bufferData(gl.ARRAY_BUFFER, maxArray, gl.STATIC_DRAW);\n        }\n        gl.bindBuffer(gl.ARRAY_BUFFER, null);\n\n        if (currentVao) gl.bindVertexArray(currentVao);\n    }\n\n    /**\n     * Get a typed array containing a mapping from global splat indexes to their scene index.\n     * @param {number} start Starting splat index to store\n     * @param {number} end Ending splat index to store\n     * @return {Uint32Array}\n     */\n    getSceneIndexes(start, end) {\n\n        let sceneIndexes;\n        const fillCount = end - start + 1;\n        sceneIndexes = new Uint32Array(fillCount);\n        for (let i = start; i <= end; i++) {\n            sceneIndexes[i] = this.globalSplatIndexToSceneIndexMap[i];\n        }\n\n        return sceneIndexes;\n    }\n\n    /**\n     * Fill 'array' with the transforms for each scene in this splat mesh.\n     * @param {Array} array Empty array to be filled with scene transforms. If not empty, contents will be overwritten.\n     */\n    fillTransformsArray = function() {\n\n        const tempArray = [];\n\n        return function(array) {\n            if (tempArray.length !== array.length) tempArray.length = array.length;\n            for (let i = 0; i < this.scenes.length; i++) {\n                const sceneTransform = this.getScene(i).transform;\n                const sceneTransformElements = sceneTransform.elements;\n                for (let j = 0; j < 16; j++) {\n                    tempArray[i * 16 + j] = sceneTransformElements[j];\n                }\n            }\n            array.set(tempArray);\n        };\n\n    }();\n\n    computeDistancesOnGPU = function() {\n\n        const tempMatrix = new THREE.Matrix4();\n\n        return function(modelViewProjMatrix, outComputedDistances) {\n            if (!this.renderer) return;\n\n            // console.time(\"gpu_compute_distances\");\n            const gl = this.renderer.getContext();\n\n            const currentVao = gl.getParameter(gl.VERTEX_ARRAY_BINDING);\n            const currentProgram = gl.getParameter(gl.CURRENT_PROGRAM);\n            const currentProgramDeleted = currentProgram ? gl.getProgramParameter(currentProgram, gl.DELETE_STATUS) : false;\n\n            gl.bindVertexArray(this.distancesTransformFeedback.vao);\n            gl.useProgram(this.distancesTransformFeedback.program);\n\n            gl.enable(gl.RASTERIZER_DISCARD);\n\n            if (this.dynamicMode) {\n                for (let i = 0; i < this.scenes.length; i++) {\n                    tempMatrix.copy(this.getScene(i).transform);\n                    tempMatrix.premultiply(modelViewProjMatrix);\n\n                    if (this.integerBasedDistancesComputation) {\n                        const iTempMatrix = SplatMesh.getIntegerMatrixArray(tempMatrix);\n                        const iTransform = [iTempMatrix[2], iTempMatrix[6], iTempMatrix[10], iTempMatrix[14]];\n                        gl.uniform4i(this.distancesTransformFeedback.transformsLocs[i], iTransform[0], iTransform[1],\n                                                                                        iTransform[2], iTransform[3]);\n                    } else {\n                        gl.uniformMatrix4fv(this.distancesTransformFeedback.transformsLocs[i], false, tempMatrix.elements);\n                    }\n                }\n            } else {\n                if (this.integerBasedDistancesComputation) {\n                    const iViewProjMatrix = SplatMesh.getIntegerMatrixArray(modelViewProjMatrix);\n                    const iViewProj = [iViewProjMatrix[2], iViewProjMatrix[6], iViewProjMatrix[10]];\n                    gl.uniform3i(this.distancesTransformFeedback.modelViewProjLoc, iViewProj[0], iViewProj[1], iViewProj[2]);\n                } else {\n                    const viewProj = [modelViewProjMatrix.elements[2], modelViewProjMatrix.elements[6], modelViewProjMatrix.elements[10]];\n                    gl.uniform3f(this.distancesTransformFeedback.modelViewProjLoc, viewProj[0], viewProj[1], viewProj[2]);\n                }\n            }\n\n            gl.bindBuffer(gl.ARRAY_BUFFER, this.distancesTransformFeedback.centersBuffer);\n            gl.enableVertexAttribArray(this.distancesTransformFeedback.centersLoc);\n            if (this.integerBasedDistancesComputation) {\n                gl.vertexAttribIPointer(this.distancesTransformFeedback.centersLoc, 4, gl.INT, 0, 0);\n            } else {\n                gl.vertexAttribPointer(this.distancesTransformFeedback.centersLoc, 4, gl.FLOAT, false, 0, 0);\n            }\n\n            if (this.dynamicMode) {\n                gl.bindBuffer(gl.ARRAY_BUFFER, this.distancesTransformFeedback.sceneIndexesBuffer);\n                gl.enableVertexAttribArray(this.distancesTransformFeedback.sceneIndexesLoc);\n                gl.vertexAttribIPointer(this.distancesTransformFeedback.sceneIndexesLoc, 1, gl.UNSIGNED_INT, 0, 0);\n            }\n\n            gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, this.distancesTransformFeedback.id);\n            gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, this.distancesTransformFeedback.outDistancesBuffer);\n\n            gl.beginTransformFeedback(gl.POINTS);\n            gl.drawArrays(gl.POINTS, 0, this.getSplatCount());\n            gl.endTransformFeedback();\n\n            gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null);\n            gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);\n\n            gl.disable(gl.RASTERIZER_DISCARD);\n\n            const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);\n            gl.flush();\n\n            const promise = new Promise((resolve) => {\n                const checkSync = () => {\n                    if (this.disposed) {\n                        resolve();\n                    } else {\n                        const timeout = 0;\n                        const bitflags = 0;\n                        const status = gl.clientWaitSync(sync, bitflags, timeout);\n                        switch (status) {\n                            case gl.TIMEOUT_EXPIRED:\n                                this.computeDistancesOnGPUSyncTimeout = setTimeout(checkSync);\n                                return this.computeDistancesOnGPUSyncTimeout;\n                            case gl.WAIT_FAILED:\n                                throw new Error('should never get here');\n                            default:\n                                this.computeDistancesOnGPUSyncTimeout = null;\n                                gl.deleteSync(sync);\n                                const currentVao = gl.getParameter(gl.VERTEX_ARRAY_BINDING);\n                                gl.bindVertexArray(this.distancesTransformFeedback.vao);\n                                gl.bindBuffer(gl.ARRAY_BUFFER, this.distancesTransformFeedback.outDistancesBuffer);\n                                gl.getBufferSubData(gl.ARRAY_BUFFER, 0, outComputedDistances);\n                                gl.bindBuffer(gl.ARRAY_BUFFER, null);\n\n                                if (currentVao) gl.bindVertexArray(currentVao);\n\n                                // console.timeEnd(\"gpu_compute_distances\");\n\n                                resolve();\n                        }\n                    }\n                };\n                this.computeDistancesOnGPUSyncTimeout = setTimeout(checkSync);\n            });\n\n            if (currentProgram && currentProgramDeleted !== true) gl.useProgram(currentProgram);\n            if (currentVao) gl.bindVertexArray(currentVao);\n\n            return promise;\n        };\n\n    }();\n\n    /**\n     * Given a global splat index, return corresponding local data (splat buffer, index of splat in that splat\n     * buffer, and the corresponding transform)\n     * @param {number} globalIndex Global splat index\n     * @param {object} paramsObj Object in which to store local data\n     * @param {boolean} returnSceneTransform By default, the transform of the scene to which the splat at 'globalIndex' belongs will be\n     *                                       returned via the 'sceneTransform' property of 'paramsObj' only if the splat mesh is static.\n     *                                       If 'returnSceneTransform' is true, the 'sceneTransform' property will always contain the scene\n     *                                       transform, and if 'returnSceneTransform' is false, the 'sceneTransform' property will always\n     *                                       be null.\n     */\n    getLocalSplatParameters(globalIndex, paramsObj, returnSceneTransform) {\n        if (returnSceneTransform === undefined || returnSceneTransform === null) {\n            returnSceneTransform = this.dynamicMode ? false : true;\n        }\n        paramsObj.splatBuffer = this.getSplatBufferForSplat(globalIndex);\n        paramsObj.localIndex = this.getSplatLocalIndex(globalIndex);\n        paramsObj.sceneTransform = returnSceneTransform ? this.getSceneTransformForSplat(globalIndex) : null;\n    }\n\n    /**\n     * Fill arrays with splat data and apply transforms if appropriate. Each array is optional.\n     * @param {Float32Array} covariances Target storage for splat covariances\n     * @param {Float32Array} scales Target storage for splat scales\n     * @param {Float32Array} rotations Target storage for splat rotations\n     * @param {Float32Array} centers Target storage for splat centers\n     * @param {Uint8Array} colors Target storage for splat colors\n     * @param {Float32Array} sphericalHarmonics Target storage for spherical harmonics\n     * @param {boolean} applySceneTransform By default, scene transforms are applied to relevant splat data only if the splat mesh is\n     *                                      static. If 'applySceneTransform' is true, scene transforms will always be applied and if\n     *                                      it is false, they will never be applied. If undefined, the default behavior will apply.\n     * @param {number} covarianceCompressionLevel The compression level for covariances in the destination array\n     * @param {number} sphericalHarmonicsCompressionLevel The compression level for spherical harmonics in the destination array\n     * @param {number} srcStart The start location from which to pull source data\n     * @param {number} srcEnd The end location from which to pull source data\n     * @param {number} destStart The start location from which to write data\n     */\n    fillSplatDataArrays(covariances, scales, rotations, centers, colors, sphericalHarmonics, applySceneTransform,\n                        covarianceCompressionLevel = 0, scaleRotationCompressionLevel = 0, sphericalHarmonicsCompressionLevel = 1,\n                        srcStart, srcEnd, destStart = 0, sceneIndex) {\n        const scaleOverride = new THREE.Vector3();\n        scaleOverride.x = undefined;\n        scaleOverride.y = undefined;\n        if (this.splatRenderMode === SplatRenderMode.ThreeD) {\n            scaleOverride.z = undefined;\n        } else {\n            scaleOverride.z = 1;\n        }\n        const tempTransform = new THREE.Matrix4();\n\n        let startSceneIndex = 0;\n        let endSceneIndex = this.scenes.length - 1;\n        if (sceneIndex !== undefined && sceneIndex !== null && sceneIndex >= 0 && sceneIndex <= this.scenes.length) {\n            startSceneIndex = sceneIndex;\n            endSceneIndex = sceneIndex;\n        }\n        for (let i = startSceneIndex; i <= endSceneIndex; i++) {\n            if (applySceneTransform === undefined || applySceneTransform === null) {\n                applySceneTransform = this.dynamicMode ? false : true;\n            }\n\n            const scene = this.getScene(i);\n            const splatBuffer = scene.splatBuffer;\n            let sceneTransform;\n            if (applySceneTransform) {\n                this.getSceneTransform(i, tempTransform);\n                sceneTransform = tempTransform;\n            }\n            if (covariances) {\n                splatBuffer.fillSplatCovarianceArray(covariances, sceneTransform, srcStart, srcEnd, destStart, covarianceCompressionLevel);\n            }\n            if (scales || rotations) {\n                if (!scales || !rotations) {\n                    throw new Error('SplatMesh::fillSplatDataArrays() -> \"scales\" and \"rotations\" must both be valid.');\n                }\n                splatBuffer.fillSplatScaleRotationArray(scales, rotations, sceneTransform,\n                                                        srcStart, srcEnd, destStart, scaleRotationCompressionLevel, scaleOverride);\n            }\n            if (centers) splatBuffer.fillSplatCenterArray(centers, sceneTransform, srcStart, srcEnd, destStart);\n            if (colors) splatBuffer.fillSplatColorArray(colors, scene.minimumAlpha, srcStart, srcEnd, destStart);\n            if (sphericalHarmonics) {\n                splatBuffer.fillSphericalHarmonicsArray(sphericalHarmonics, this.minSphericalHarmonicsDegree,\n                                                        sceneTransform, srcStart, srcEnd, destStart, sphericalHarmonicsCompressionLevel);\n            }\n            destStart += splatBuffer.getSplatCount();\n        }\n    }\n\n    /**\n     * Convert splat centers, which are floating point values, to an array of integers and multiply\n     * each by 1000. Centers will get transformed as appropriate before conversion to integer.\n     * @param {number} start The index at which to start retrieving data\n     * @param {number} end The index at which to stop retrieving data\n     * @param {boolean} padFour Enforce alignment of 4 by inserting a 1 after every 3 values\n     * @return {Int32Array}\n     */\n    getIntegerCenters(start, end, padFour = false) {\n        const splatCount = end - start + 1;\n        const floatCenters = new Float32Array(splatCount * 3);\n        this.fillSplatDataArrays(null, null, null, floatCenters, null, null, undefined, undefined, undefined, undefined, start);\n        let intCenters;\n        let componentCount = padFour ? 4 : 3;\n        intCenters = new Int32Array(splatCount * componentCount);\n        for (let i = 0; i < splatCount; i++) {\n            for (let t = 0; t < 3; t++) {\n                intCenters[i * componentCount + t] = Math.round(floatCenters[i * 3 + t] * 1000.0);\n            }\n            if (padFour) intCenters[i * componentCount + 3] = 1000;\n        }\n        return intCenters;\n    }\n\n    /**\n     * Returns an array of splat centers, transformed as appropriate, optionally padded.\n     * @param {number} start The index at which to start retrieving data\n     * @param {number} end The index at which to stop retrieving data\n     * @param {boolean} padFour Enforce alignment of 4 by inserting a 1 after every 3 values\n     * @return {Float32Array}\n     */\n    getFloatCenters(start, end, padFour = false) {\n        const splatCount = end - start + 1;\n        const floatCenters = new Float32Array(splatCount * 3);\n        this.fillSplatDataArrays(null, null, null, floatCenters, null, null, undefined, undefined, undefined, undefined, start);\n        if (!padFour) return floatCenters;\n        let paddedFloatCenters = new Float32Array(splatCount * 4);\n        for (let i = 0; i < splatCount; i++) {\n            for (let t = 0; t < 3; t++) {\n                paddedFloatCenters[i * 4 + t] = floatCenters[i * 3 + t];\n            }\n            paddedFloatCenters[i * 4 + 3] = 1.0;\n        }\n        return paddedFloatCenters;\n    }\n\n    /**\n     * Get the center for a splat, transformed as appropriate.\n     * @param {number} globalIndex Global index of splat\n     * @param {THREE.Vector3} outCenter THREE.Vector3 instance in which to store splat center\n     * @param {boolean} applySceneTransform By default, if the splat mesh is static, the transform of the scene to which the splat at\n     *                                      'globalIndex' belongs will be applied to the splat center. If 'applySceneTransform' is true,\n     *                                      the scene transform will always be applied and if 'applySceneTransform' is false, the\n     *                                      scene transform will never be applied. If undefined, the default behavior will apply.\n     */\n    getSplatCenter = function() {\n\n        const paramsObj = {};\n\n        return function(globalIndex, outCenter, applySceneTransform) {\n            this.getLocalSplatParameters(globalIndex, paramsObj, applySceneTransform);\n            paramsObj.splatBuffer.getSplatCenter(paramsObj.localIndex, outCenter, paramsObj.sceneTransform);\n        };\n\n    }();\n\n    /**\n     * Get the scale and rotation for a splat, transformed as appropriate.\n     * @param {number} globalIndex Global index of splat\n     * @param {THREE.Vector3} outScale THREE.Vector3 instance in which to store splat scale\n     * @param {THREE.Quaternion} outRotation THREE.Quaternion instance in which to store splat rotation\n     * @param {boolean} applySceneTransform By default, if the splat mesh is static, the transform of the scene to which the splat at\n     *                                      'globalIndex' belongs will be applied to the splat scale and rotation. If\n     *                                      'applySceneTransform' is true, the scene transform will always be applied and if\n     *                                      'applySceneTransform' is false, the scene transform will never be applied. If undefined,\n     *                                      the default behavior will apply.\n     */\n    getSplatScaleAndRotation = function() {\n\n        const paramsObj = {};\n        const scaleOverride = new THREE.Vector3();\n\n        return function(globalIndex, outScale, outRotation, applySceneTransform) {\n            this.getLocalSplatParameters(globalIndex, paramsObj, applySceneTransform);\n            scaleOverride.x = undefined;\n            scaleOverride.y = undefined;\n            scaleOverride.z = undefined;\n            if (this.splatRenderMode === SplatRenderMode.TwoD) scaleOverride.z = 0;\n            paramsObj.splatBuffer.getSplatScaleAndRotation(paramsObj.localIndex, outScale, outRotation,\n                                                           paramsObj.sceneTransform, scaleOverride);\n        };\n\n    }();\n\n    /**\n     * Get the color for a splat.\n     * @param {number} globalIndex Global index of splat\n     * @param {THREE.Vector4} outColor THREE.Vector4 instance in which to store splat color\n     */\n    getSplatColor = function() {\n\n        const paramsObj = {};\n\n        return function(globalIndex, outColor) {\n            this.getLocalSplatParameters(globalIndex, paramsObj);\n            paramsObj.splatBuffer.getSplatColor(paramsObj.localIndex, outColor);\n        };\n\n    }();\n\n    /**\n     * Store the transform of the scene at 'sceneIndex' in 'outTransform'.\n     * @param {number} sceneIndex Index of the desired scene\n     * @param {THREE.Matrix4} outTransform Instance of THREE.Matrix4 in which to store the scene's transform\n     */\n    getSceneTransform(sceneIndex, outTransform) {\n        const scene = this.getScene(sceneIndex);\n        scene.updateTransform(this.dynamicMode);\n        outTransform.copy(scene.transform);\n    }\n\n    /**\n     * Get the scene at 'sceneIndex'.\n     * @param {number} sceneIndex Index of the desired scene\n     * @return {SplatScene}\n     */\n    getScene(sceneIndex) {\n        if (sceneIndex < 0 || sceneIndex >= this.scenes.length) {\n            throw new Error('SplatMesh::getScene() -> Invalid scene index.');\n        }\n        return this.scenes[sceneIndex];\n    }\n\n    getSceneCount() {\n        return this.scenes.length;\n    }\n\n    getSplatBufferForSplat(globalIndex) {\n        return this.getScene(this.globalSplatIndexToSceneIndexMap[globalIndex]).splatBuffer;\n    }\n\n    getSceneIndexForSplat(globalIndex) {\n        return this.globalSplatIndexToSceneIndexMap[globalIndex];\n    }\n\n    getSceneTransformForSplat(globalIndex) {\n        return this.getScene(this.globalSplatIndexToSceneIndexMap[globalIndex]).transform;\n    }\n\n    getSplatLocalIndex(globalIndex) {\n        return this.globalSplatIndexToLocalSplatIndexMap[globalIndex];\n    }\n\n    static getIntegerMatrixArray(matrix) {\n        const matrixElements = matrix.elements;\n        const intMatrixArray = [];\n        for (let i = 0; i < 16; i++) {\n            intMatrixArray[i] = Math.round(matrixElements[i] * 1000.0);\n        }\n        return intMatrixArray;\n    }\n\n    computeBoundingBox(applySceneTransforms = false, sceneIndex) {\n        let splatCount = this.getSplatCount();\n        if (sceneIndex !== undefined && sceneIndex !== null) {\n            if (sceneIndex < 0 || sceneIndex >= this.scenes.length) {\n                throw new Error('SplatMesh::computeBoundingBox() -> Invalid scene index.');\n            }\n            splatCount = this.scenes[sceneIndex].splatBuffer.getSplatCount();\n        }\n\n        const floatCenters = new Float32Array(splatCount * 3);\n        this.fillSplatDataArrays(null, null, null, floatCenters, null, null, applySceneTransforms,\n                                 undefined, undefined, undefined, undefined, sceneIndex);\n\n        const min = new THREE.Vector3();\n        const max = new THREE.Vector3();\n        for (let i = 0; i < splatCount; i++) {\n            const offset = i * 3;\n            const x = floatCenters[offset];\n            const y = floatCenters[offset + 1];\n            const z = floatCenters[offset + 2];\n            if (i === 0 || x < min.x) min.x = x;\n            if (i === 0 || y < min.y) min.y = y;\n            if (i === 0 || z < min.z) min.z = z;\n            if (i === 0 || x > max.x) max.x = x;\n            if (i === 0 || y > max.y) max.y = y;\n            if (i === 0 || z > max.z) max.z = z;\n        }\n\n        return new THREE.Box3(min, max);\n    }\n}\n","\u0000asm\u0001\u0000\u0000\u0000\u0000\u000f\bdylink.0\u0001\u0004\u0000\u0000\u0000\u0000\u0001\u001b\u0003`\u0000\u0000`\u0010\u0000`\u0000\u0001\u0002\u0012\u0001\u0003env\u0006memory\u0002\u0003\u0000��\u0004\u0003\u0004\u0003\u0000\u0001\u0002\u0007T\u0004\u0011__wasm_call_ctors\u0000\u0000\u0018__wasm_apply_data_relocs\u0000\u0000\u000bsortIndexes\u0000\u0001\u0013emscripten_tls_init\u0000\u0002\n�\u0010\u0003\u0003\u0000\u0001\u000b�\u0010\u0004\u0001|\u0003{\u0003\u0003} \u000b \nk!\f\u0002@\u0002@ \u000e\u0004@ \r\u0004@A����\u0007!\nA����x!\r \u000b \fM\r\u0003 \f!\u0001\u0003@ \u0003 \u0001A\u0002t\"\u0005j \u0002 \u0000 \u0005j(\u0002\u0000A\u0002tj(\u0002\u0000\"\u00056\u0002\u0000 \u0005 \n \u0005 \nH\u001b!\n \u0005 \r \u0005 \rJ\u001b!\r \u0001A\u0001j\"\u0001 \u000bG\r\u0000\u000b\f\u0003\u000b \u000f\u0004@ \u000b \fM\r\u0002A!\u000fA����\u0007!\nA����x!\r \f!\u0002\u0003@ \u000f \u0007 \u0000 \u0002A\u0002t\"\u0015j(\u0002\u0000\"\u0016A\u0002tj(\u0002\u0000\"\u0014G\u0004@\u0002 \u0005�\t\u00028 \b \u0014A\u0006tj\"\u000e�\t\u0002\f \u000e*\u0002\u001c� \u0001 \u000e*\u0002,� \u0002 \u000e*\u0002<� \u0003��\u0001 \u0005�\t\u0002( \u000e�\t\u0002\b \u000e*\u0002\u0018� \u0001 \u000e*\u0002(� \u0002 \u000e*\u00028� \u0003��\u0001 \u0005�\t\u0002\b \u000e�\t\u0002\u0000 \u000e*\u0002\u0010� \u0001 \u000e*\u0002 � \u0002 \u000e*\u00020� \u0003��\u0001 \u0005�\t\u0002\u0018 \u000e�\t\u0002\u0004 \u000e*\u0002\u0014� \u0001 \u000e*\u0002$� \u0002 \u000e*\u00024� \u0003��\u0001��\u0001��\u0001��\u0001\"\u0011�_�\f\u0000\u0000\u0000\u0000\u0000@�@\u0000\u0000\u0000\u0000\u0000@�@\"\u0012��\u0001\"\u0013�!\u0001\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b!\u000e\u0002 \u0013�!\u0000\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b�\u0011 \u000e�\u001c\u0001\u0002 \u0011 \u0011�\r\b\t\n\u000b\f\r\u000e\u000f\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000�_ \u0012��\u0001\"\u0011�!\u0000\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b�\u001c\u0002\u0002 \u0011�!\u0001\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b�\u001c\u0003!\u0012 \u0014!\u000f\u000b \u0003 \u0015j \u0001 \u0016A\u0004tj�\u0000\u0000\u0000 \u0012��\u0001\"\u0011�\u001b\u0000 \u0011�\u001b\u0001j \u0011�\u001b\u0002j \u0011�\u001b\u0003j\"\u000e6\u0002\u0000 \u000e \n \n \u000eJ\u001b!\n \u000e \r \r \u000eH\u001b!\r \u0002A\u0001j\"\u0002 \u000bG\r\u0000\u000b\f\u0003\u000b\u0002 \u0005*\u0002\b��\u0014 \u0005*\u0002\u0018��\"\u0001�\f\u0000\u0000\u0000\u0000\u0000@�@\u0000\u0000\u0000\u0000\u0000@�@��\u0001\"\u0011�!\u0001\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b!\u000e\u0002 \u0011�!\u0000\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b!\u0002\u0002 \u0005*\u0002(�D\u0000\u0000\u0000\u0000\u0000@�@�\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b!\u0005A����\u0007!\nA����x!\r \u000b \fM\r\u0002 \u0002�\u0011 \u000e�\u001c\u0001 \u0005�\u001c\u0002!\u0012 \f!\u0005\u0003@ \u0003 \u0005A\u0002t\"\u0002j \u0001 \u0000 \u0002j(\u0002\u0000A\u0004tj�\u0000\u0000\u0000 \u0012��\u0001\"\u0011�\u001b\u0000 \u0011�\u001b\u0001j \u0011�\u001b\u0002j\"\u00026\u0002\u0000 \u0002 \n \u0002 \nH\u001b!\n \u0002 \r \u0002 \rJ\u001b!\r \u0005A\u0001j\"\u0005 \u000bG\r\u0000\u000b\f\u0002\u000b \r\u0004@A����\u0007!\nA����x!\r \u000b \fM\r\u0002 \f!\u0001\u0003@ \u0003 \u0001A\u0002t\"\u0005j\u0002 \u0002 \u0000 \u0005j(\u0002\u0000A\u0002tj*\u0002\u0000�D\u0000\u0000\u0000\u0000\u0000\u0000�@�\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b\"\u000e6\u0002\u0000 \n \u000e \n \u000eH\u001b!\n \r \u000e \r \u000eJ\u001b!\r \u0001A\u0001j\"\u0001 \u000bG\r\u0000\u000b\f\u0002\u000b \u000fE\u0004@ \u000b \fM\r\u0001 \u0005*\u0002(!\u0017 \u0005*\u0002\u0018!\u0018 \u0005*\u0002\b!\u0019A����\u0007!\nA����x!\r \f!\u0005\u0003@\u0002 \u0017 \u0001 \u0000 \u0005A\u0002t\"\u0007j(\u0002\u0000A\u0004tj\"\u0002*\u0002\b� \u0019 \u0002*\u0002\u0000� \u0018 \u0002*\u0002\u0004����D\u0000\u0000\u0000\u0000\u0000\u0000�@�\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b!\u000e \u0003 \u0007j \u000e6\u0002\u0000 \n \u000e \n \u000eH\u001b!\n \r \u000e \r \u000eJ\u001b!\r \u0005A\u0001j\"\u0005 \u000bG\r\u0000\u000b\f\u0002\u000b \u000b \fM\r\u0000A!\u000fA����\u0007!\nA����x!\r \f!\u0002\u0003@ \u000f \u0007 \u0000 \u0002A\u0002t\"\u0014j(\u0002\u0000A\u0002t\"\u0015j(\u0002\u0000\"\u000eG\u0004@ \u0005�\t\u00028 \b \u000eA\u0006tj\"\u000f�\t\u0002\f \u000f*\u0002\u001c� \u0001 \u000f*\u0002,� \u0002 \u000f*\u0002<� \u0003��\u0001 \u0005�\t\u0002( \u000f�\t\u0002\b \u000f*\u0002\u0018� \u0001 \u000f*\u0002(� \u0002 \u000f*\u00028� \u0003��\u0001 \u0005�\t\u0002\b \u000f�\t\u0002\u0000 \u000f*\u0002\u0010� \u0001 \u000f*\u0002 � \u0002 \u000f*\u00020� \u0003��\u0001 \u0005�\t\u0002\u0018 \u000f�\t\u0002\u0004 \u000f*\u0002\u0014� \u0001 \u000f*\u0002$� \u0002 \u000f*\u00024� \u0003��\u0001��\u0001��\u0001��\u0001!\u0011 \u000e!\u000f\u000b \u0003 \u0014j\u0002 \u0011�\u001f\u0003 \u0001 \u0015A\u0002t\"\u000eA\frj*\u0002\u0000� \u0011�\u001f\u0002 \u0001 \u000eA\brj*\u0002\u0000� \u0011�\u001f\u0000 \u0001 \u000ej*\u0002\u0000� \u0011�\u001f\u0001 \u0001 \u000eA\u0004rj*\u0002\u0000�����D\u0000\u0000\u0000\u0000\u0000\u0000�@�\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b\"\u000e6\u0002\u0000 \n \u000e \n \u000eH\u001b!\n \r \u000e \r \u000eJ\u001b!\r \u0002A\u0001j\"\u0002 \u000bG\r\u0000\u000b\f\u0001\u000bA����x!\rA����\u0007!\n\u000b \u000b \fK\u0004@ \tA\u0001k� \r� \n���!\u0017 \f!\r\u0003@\u0002 \u0017 \u0003 \rA\u0002tj\"\u0001(\u0002\u0000 \nk��\"\u0018�C\u0000\u0000\u0000O]\u0004@ \u0018�\f\u0001\u000bA����x\u000b!\u000e \u0001 \u000e6\u0002\u0000 \u0004 \u000eA\u0002tj\"\u0001 \u0001(\u0002\u0000A\u0001j6\u0002\u0000 \rA\u0001j\"\r \u000bG\r\u0000\u000b\u000b \tA\u0002O\u0004@ \u0004(\u0002\u0000!\rA\u0001!\n\u0003@ \u0004 \nA\u0002tj\"\u0001 \u0001(\u0002\u0000 \rj\"\r6\u0002\u0000 \nA\u0001j\"\n \tG\r\u0000\u000b\u000b \fA\u0000J\u0004@ \f!\n\u0003@ \u0006 \nA\u0001k\"\u0001A\u0002t\"\u0002j \u0000 \u0002j(\u0002\u00006\u0002\u0000 \nA\u0001K!\u0002 \u0001!\n \u0002\r\u0000\u000b\u000b \u000b \fJ\u0004@ \u000b!\n\u0003@ \u0006 \u000b \u0004 \u0003 \nA\u0001k\"\nA\u0002t\"\u0001j(\u0002\u0000A\u0002tj\"\u0002(\u0002\u0000\"\u0005kA\u0002tj \u0000 \u0001j(\u0002\u00006\u0002\u0000 \u0002 \u0005A\u0001k6\u0002\u0000 \n \fJ\r\u0000\u000b\u000b\u000b\u0004\u0000A\u0000\u000b","\u0000asm\u0001\u0000\u0000\u0000\u0000\u000f\bdylink.0\u0001\u0004\u0000\u0000\u0000\u0000\u0001\u0017\u0002`\u0000\u0000`\u0010\u0000\u0002\u0012\u0001\u0003env\u0006memory\u0002\u0003\u0000��\u0004\u0003\u0003\u0002\u0000\u0001\u0007>\u0003\u0011__wasm_call_ctors\u0000\u0000\u0018__wasm_apply_data_relocs\u0000\u0000\u000bsortIndexes\u0000\u0001\n�\u000f\u0002\u0002\u0000\u000b�\u000f\u0003\u0001|\u0007}\u0006 \u000b \nk!\f\u0002@\u0002@ \u000e\u0004@ \r\u0004@A����\u0007!\nA����x!\r \u000b \fM\r\u0003 \f!\u0005\u0003@ \u0003 \u0005A\u0002t\"\u0001j \u0002 \u0000 \u0001j(\u0002\u0000A\u0002tj(\u0002\u0000\"\u00016\u0002\u0000 \u0001 \n \u0001 \nH\u001b!\n \u0001 \r \u0001 \rJ\u001b!\r \u0005A\u0001j\"\u0005 \u000bG\r\u0000\u000b\f\u0003\u000b \u000f\u0004@ \u000b \fM\r\u0002A!\u000fA����\u0007!\nA����x!\r \f!\u0002\u0003@ \u000f \u0007 \u0000 \u0002A\u0002t\"\u001aj(\u0002\u0000A\u0002t\"\u001bj(\u0002\u0000\"\u000eG\u0004@\u0002 \u0005*\u00028\"\u0011 \b \u000eA\u0006tj\"\u000f*\u0002<� \u0005*\u0002(\"\u0012 \u000f*\u00028� \u0005*\u0002\b\"\u0013 \u000f*\u00020� \u0005*\u0002\u0018\"\u0014 \u000f*\u00024�����D\u0000\u0000\u0000\u0000\u0000@�@�\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b!\u0018\u0002 \u0011 \u000f*\u0002,� \u0012 \u000f*\u0002(� \u0013 \u000f*\u0002 � \u0014 \u000f*\u0002$�����D\u0000\u0000\u0000\u0000\u0000@�@�\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b!\u0019\u0002 \u0011 \u000f*\u0002\u001c� \u0012 \u000f*\u0002\u0018� \u0013 \u000f*\u0002\u0010� \u0014 \u000f*\u0002\u0014�����D\u0000\u0000\u0000\u0000\u0000@�@�\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b!\u001c\u0002 \u0011 \u000f*\u0002\f� \u0012 \u000f*\u0002\b� \u0013 \u000f*\u0002\u0000� \u0014 \u000f*\u0002\u0004�����D\u0000\u0000\u0000\u0000\u0000@�@�\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b!\u001d \u000e!\u000f\u000b \u0003 \u001aj \u0001 \u001bA\u0002tj\"\u000e(\u0002\u0004 \u001cl \u000e(\u0002\u0000 \u001dlj \u000e(\u0002\b \u0019lj \u000e(\u0002\f \u0018lj\"\u000e6\u0002\u0000 \u000e \n \n \u000eJ\u001b!\n \u000e \r \r \u000eH\u001b!\r \u0002A\u0001j\"\u0002 \u000bG\r\u0000\u000b\f\u0003\u000b\u0002 \u0005*\u0002(�D\u0000\u0000\u0000\u0000\u0000@�@�\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b!\u0002\u0002 \u0005*\u0002\u0018�D\u0000\u0000\u0000\u0000\u0000@�@�\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b!\u0007 \u000b \fM\u0002 \u0005*\u0002\b�D\u0000\u0000\u0000\u0000\u0000@�@�\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b!\u000fA����\u0007!\nA����x!\r\r\u0002 \f!\u0005\u0003@ \u0003 \u0005A\u0002t\"\bj \u0001 \u0000 \bj(\u0002\u0000A\u0004tj\"\b(\u0002\u0004 \u0007l \b(\u0002\u0000 \u000flj \b(\u0002\b \u0002lj\"\b6\u0002\u0000 \b \n \b \nH\u001b!\n \b \r \b \rJ\u001b!\r \u0005A\u0001j\"\u0005 \u000bG\r\u0000\u000b\f\u0002\u000b \r\u0004@A����\u0007!\nA����x!\r \u000b \fM\r\u0002 \f!\u0005\u0003@ \u0003 \u0005A\u0002t\"\u0001j\u0002 \u0002 \u0000 \u0001j(\u0002\u0000A\u0002tj*\u0002\u0000�D\u0000\u0000\u0000\u0000\u0000\u0000�@�\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b\"\u000e6\u0002\u0000 \n \u000e \n \u000eH\u001b!\n \r \u000e \r \u000eJ\u001b!\r \u0005A\u0001j\"\u0005 \u000bG\r\u0000\u000b\f\u0002\u000b \u000fE\u0004@ \u000b \fM\r\u0001 \u0005*\u0002(!\u0011 \u0005*\u0002\u0018!\u0012 \u0005*\u0002\b!\u0013A����\u0007!\nA����x!\r \f!\u0005\u0003@\u0002 \u0011 \u0001 \u0000 \u0005A\u0002t\"\u0007j(\u0002\u0000A\u0004tj\"\u0002*\u0002\b� \u0013 \u0002*\u0002\u0000� \u0012 \u0002*\u0002\u0004����D\u0000\u0000\u0000\u0000\u0000\u0000�@�\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b!\u000e \u0003 \u0007j \u000e6\u0002\u0000 \n \u000e \n \u000eH\u001b!\n \r \u000e \r \u000eJ\u001b!\r \u0005A\u0001j\"\u0005 \u000bG\r\u0000\u000b\f\u0002\u000b \u000b \fM\r\u0000A!\u000fA����\u0007!\nA����x!\r \f!\u0002\u0003@ \u000f \u0007 \u0000 \u0002A\u0002t\"\u0018j(\u0002\u0000A\u0002t\"\u0019j(\u0002\u0000\"\u000eG\u0004@ \u0005*\u00028\"\u0011 \b \u000eA\u0006tj\"\u000f*\u0002<� \u0005*\u0002(\"\u0012 \u000f*\u00028� \u0005*\u0002\b\"\u0013 \u000f*\u00020� \u0005*\u0002\u0018\"\u0014 \u000f*\u00024����!\u0015 \u0011 \u000f*\u0002,� \u0012 \u000f*\u0002(� \u0013 \u000f*\u0002 � \u0014 \u000f*\u0002$����!\u0016 \u0011 \u000f*\u0002\u001c� \u0012 \u000f*\u0002\u0018� \u0013 \u000f*\u0002\u0010� \u0014 \u000f*\u0002\u0014����!\u0017 \u0011 \u000f*\u0002\f� \u0012 \u000f*\u0002\b� \u0013 \u000f*\u0002\u0000� \u0014 \u000f*\u0002\u0004����!\u0011 \u000e!\u000f\u000b \u0003 \u0018j\u0002 \u0015 \u0001 \u0019A\u0002tj\"\u000e*\u0002\f� \u0016 \u000e*\u0002\b� \u0011 \u000e*\u0002\u0000� \u0017 \u000e*\u0002\u0004�����D\u0000\u0000\u0000\u0000\u0000\u0000�@�\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b\"\u000e6\u0002\u0000 \n \u000e \n \u000eH\u001b!\n \r \u000e \r \u000eJ\u001b!\r \u0002A\u0001j\"\u0002 \u000bG\r\u0000\u000b\f\u0001\u000bA����x!\rA����\u0007!\n\u000b \u000b \fK\u0004@ \tA\u0001k� \r� \n���!\u0011 \f!\r\u0003@\u0002 \u0011 \u0003 \rA\u0002tj\"\u0001(\u0002\u0000 \nk��\"\u0012�C\u0000\u0000\u0000O]\u0004@ \u0012�\f\u0001\u000bA����x\u000b!\u000e \u0001 \u000e6\u0002\u0000 \u0004 \u000eA\u0002tj\"\u0001 \u0001(\u0002\u0000A\u0001j6\u0002\u0000 \rA\u0001j\"\r \u000bG\r\u0000\u000b\u000b \tA\u0002O\u0004@ \u0004(\u0002\u0000!\rA\u0001!\n\u0003@ \u0004 \nA\u0002tj\"\u0001 \u0001(\u0002\u0000 \rj\"\r6\u0002\u0000 \nA\u0001j\"\n \tG\r\u0000\u000b\u000b \fA\u0000J\u0004@ \f!\n\u0003@ \u0006 \nA\u0001k\"\u0001A\u0002t\"\u0002j \u0000 \u0002j(\u0002\u00006\u0002\u0000 \nA\u0001K \u0001!\n\r\u0000\u000b\u000b \u000b \fJ\u0004@ \u000b!\n\u0003@ \u0006 \u000b \u0004 \u0003 \nA\u0001k\"\nA\u0002t\"\u0001j(\u0002\u0000A\u0002tj\"\u0002(\u0002\u0000\"\u0005kA\u0002tj \u0000 \u0001j(\u0002\u00006\u0002\u0000 \u0002 \u0005A\u0001k6\u0002\u0000 \n \fJ\r\u0000\u000b\u000b\u000b","import SorterWasm from './sorter.wasm';\nimport SorterWasmNoSIMD from './sorter_no_simd.wasm';\nimport SorterWasmNonShared from './sorter_non_shared.wasm';\nimport SorterWasmNoSIMDNonShared from './sorter_no_simd_non_shared.wasm';\nimport { isIOS, getIOSSemever } from '../Util.js';\nimport { Constants } from '../Constants.js';\n\nfunction sortWorker(self) {\n\n    let wasmInstance;\n    let wasmMemory;\n    let useSharedMemory;\n    let integerBasedSort;\n    let dynamicMode;\n    let splatCount;\n    let indexesToSortOffset;\n    let sortedIndexesOffset;\n    let sceneIndexesOffset;\n    let transformsOffset;\n    let precomputedDistancesOffset;\n    let mappedDistancesOffset;\n    let frequenciesOffset;\n    let centersOffset;\n    let modelViewProjOffset;\n    let countsZero;\n    let sortedIndexesOut;\n    let distanceMapRange;\n    let uploadedSplatCount;\n    let Constants;\n\n    function sort(splatSortCount, splatRenderCount, modelViewProj,\n                  usePrecomputedDistances, copyIndexesToSort, copyPrecomputedDistances, copyTransforms) {\n        const sortStartTime = performance.now();\n\n        if (!useSharedMemory) {\n            const indexesToSort = new Uint32Array(wasmMemory, indexesToSortOffset, copyIndexesToSort.byteLength / Constants.BytesPerInt);\n            indexesToSort.set(copyIndexesToSort);\n            const transforms = new Float32Array(wasmMemory, transformsOffset, copyTransforms.byteLength / Constants.BytesPerFloat);\n            transforms.set(copyTransforms);\n            if (usePrecomputedDistances) {\n                let precomputedDistances;\n                if (integerBasedSort) {\n                    precomputedDistances = new Int32Array(wasmMemory, precomputedDistancesOffset,\n                                                          copyPrecomputedDistances.byteLength / Constants.BytesPerInt);\n                } else {\n                    precomputedDistances = new Float32Array(wasmMemory, precomputedDistancesOffset,\n                                                            copyPrecomputedDistances.byteLength / Constants.BytesPerFloat);\n                }\n                precomputedDistances.set(copyPrecomputedDistances);\n            }\n        }\n\n        if (!countsZero) countsZero = new Uint32Array(distanceMapRange);\n        new Float32Array(wasmMemory, modelViewProjOffset, 16).set(modelViewProj);\n        new Uint32Array(wasmMemory, frequenciesOffset, distanceMapRange).set(countsZero);\n        wasmInstance.exports.sortIndexes(indexesToSortOffset, centersOffset, precomputedDistancesOffset,\n                                         mappedDistancesOffset, frequenciesOffset, modelViewProjOffset,\n                                         sortedIndexesOffset, sceneIndexesOffset, transformsOffset, distanceMapRange,\n                                         splatSortCount, splatRenderCount, splatCount, usePrecomputedDistances, integerBasedSort,\n                                         dynamicMode);\n\n        const sortMessage = {\n            'sortDone': true,\n            'splatSortCount': splatSortCount,\n            'splatRenderCount': splatRenderCount,\n            'sortTime': 0\n        };\n        if (!useSharedMemory) {\n            const sortedIndexes = new Uint32Array(wasmMemory, sortedIndexesOffset, splatRenderCount);\n            if (!sortedIndexesOut || sortedIndexesOut.length < splatRenderCount) {\n                sortedIndexesOut = new Uint32Array(splatRenderCount);\n            }\n            sortedIndexesOut.set(sortedIndexes);\n            sortMessage.sortedIndexes = sortedIndexesOut;\n        }\n        const sortEndTime = performance.now();\n\n        sortMessage.sortTime = sortEndTime - sortStartTime;\n\n        self.postMessage(sortMessage);\n    }\n\n    self.onmessage = (e) => {\n        if (e.data.centers) {\n            centers = e.data.centers;\n            sceneIndexes = e.data.sceneIndexes;\n            if (integerBasedSort) {\n                new Int32Array(wasmMemory, centersOffset + e.data.range.from * Constants.BytesPerInt * 4,\n                               e.data.range.count * 4).set(new Int32Array(centers));\n            } else {\n                new Float32Array(wasmMemory, centersOffset + e.data.range.from * Constants.BytesPerFloat * 4,\n                                 e.data.range.count * 4).set(new Float32Array(centers));\n            }\n            if (dynamicMode) {\n                new Uint32Array(wasmMemory, sceneIndexesOffset + e.data.range.from * 4,\n                                e.data.range.count).set(new Uint32Array(sceneIndexes));\n            }\n            uploadedSplatCount = e.data.range.from + e.data.range.count;\n        } else if (e.data.sort) {\n            const renderCount = Math.min(e.data.sort.splatRenderCount || 0, uploadedSplatCount);\n            const sortCount = Math.min(e.data.sort.splatSortCount || 0, uploadedSplatCount);\n            const usePrecomputedDistances = e.data.sort.usePrecomputedDistances;\n\n            let copyIndexesToSort;\n            let copyPrecomputedDistances;\n            let copyTransforms;\n            if (!useSharedMemory) {\n                copyIndexesToSort = e.data.sort.indexesToSort;\n                copyTransforms = e.data.sort.transforms;\n                if (usePrecomputedDistances) copyPrecomputedDistances = e.data.sort.precomputedDistances;\n            }\n            sort(sortCount, renderCount, e.data.sort.modelViewProj, usePrecomputedDistances,\n                 copyIndexesToSort, copyPrecomputedDistances, copyTransforms);\n        } else if (e.data.init) {\n            // Yep, this is super hacky and gross :(\n            Constants = e.data.init.Constants;\n\n            splatCount = e.data.init.splatCount;\n            useSharedMemory = e.data.init.useSharedMemory;\n            integerBasedSort = e.data.init.integerBasedSort;\n            dynamicMode = e.data.init.dynamicMode;\n            distanceMapRange = e.data.init.distanceMapRange;\n            uploadedSplatCount = 0;\n\n            const CENTERS_BYTES_PER_ENTRY = integerBasedSort ? (Constants.BytesPerInt * 4) : (Constants.BytesPerFloat * 4);\n\n            const sorterWasmBytes = new Uint8Array(e.data.init.sorterWasmBytes);\n\n            const matrixSize = 16 * Constants.BytesPerFloat;\n            const memoryRequiredForIndexesToSort = splatCount * Constants.BytesPerInt;\n            const memoryRequiredForCenters = splatCount * CENTERS_BYTES_PER_ENTRY;\n            const memoryRequiredForModelViewProjectionMatrix = matrixSize;\n            const memoryRequiredForPrecomputedDistances = integerBasedSort ?\n                                                          (splatCount * Constants.BytesPerInt) : (splatCount * Constants.BytesPerFloat);\n            const memoryRequiredForMappedDistances = splatCount * Constants.BytesPerInt;\n            const memoryRequiredForSortedIndexes = splatCount * Constants.BytesPerInt;\n            const memoryRequiredForIntermediateSortBuffers = integerBasedSort ? (distanceMapRange * Constants.BytesPerInt * 2) :\n                                                                                (distanceMapRange * Constants.BytesPerFloat * 2);\n            const memoryRequiredforTransformIndexes = dynamicMode ? (splatCount * Constants.BytesPerInt) : 0;\n            const memoryRequiredforTransforms = dynamicMode ? (Constants.MaxScenes * matrixSize) : 0;\n            const extraMemory = Constants.MemoryPageSize * 32;\n\n            const totalRequiredMemory = memoryRequiredForIndexesToSort +\n                                        memoryRequiredForCenters +\n                                        memoryRequiredForModelViewProjectionMatrix +\n                                        memoryRequiredForPrecomputedDistances +\n                                        memoryRequiredForMappedDistances +\n                                        memoryRequiredForIntermediateSortBuffers +\n                                        memoryRequiredForSortedIndexes +\n                                        memoryRequiredforTransformIndexes +\n                                        memoryRequiredforTransforms +\n                                        extraMemory;\n            const totalPagesRequired = Math.floor(totalRequiredMemory / Constants.MemoryPageSize ) + 1;\n            const sorterWasmImport = {\n                module: {},\n                env: {\n                    memory: new WebAssembly.Memory({\n                        initial: totalPagesRequired,\n                        maximum: totalPagesRequired,\n                        shared: true,\n                    }),\n                }\n            };\n            WebAssembly.compile(sorterWasmBytes)\n            .then((wasmModule) => {\n                return WebAssembly.instantiate(wasmModule, sorterWasmImport);\n            })\n            .then((instance) => {\n                wasmInstance = instance;\n                indexesToSortOffset = 0;\n                centersOffset = indexesToSortOffset + memoryRequiredForIndexesToSort;\n                modelViewProjOffset = centersOffset + memoryRequiredForCenters;\n                precomputedDistancesOffset = modelViewProjOffset + memoryRequiredForModelViewProjectionMatrix;\n                mappedDistancesOffset = precomputedDistancesOffset + memoryRequiredForPrecomputedDistances;\n                frequenciesOffset = mappedDistancesOffset + memoryRequiredForMappedDistances;\n                sortedIndexesOffset = frequenciesOffset + memoryRequiredForIntermediateSortBuffers;\n                sceneIndexesOffset = sortedIndexesOffset + memoryRequiredForSortedIndexes;\n                transformsOffset = sceneIndexesOffset + memoryRequiredforTransformIndexes;\n                wasmMemory = sorterWasmImport.env.memory.buffer;\n                if (useSharedMemory) {\n                    self.postMessage({\n                        'sortSetupPhase1Complete': true,\n                        'indexesToSortBuffer': wasmMemory,\n                        'indexesToSortOffset': indexesToSortOffset,\n                        'sortedIndexesBuffer': wasmMemory,\n                        'sortedIndexesOffset': sortedIndexesOffset,\n                        'precomputedDistancesBuffer': wasmMemory,\n                        'precomputedDistancesOffset': precomputedDistancesOffset,\n                        'transformsBuffer': wasmMemory,\n                        'transformsOffset': transformsOffset\n                    });\n                } else {\n                    self.postMessage({\n                        'sortSetupPhase1Complete': true\n                    });\n                }\n            });\n        }\n    };\n}\n\nexport function createSortWorker(splatCount, useSharedMemory, enableSIMDInSort, integerBasedSort, dynamicMode,\n                                 splatSortDistanceMapPrecision = Constants.DefaultSplatSortDistanceMapPrecision) {\n    const worker = new Worker(\n        URL.createObjectURL(\n            new Blob(['(', sortWorker.toString(), ')(self)'], {\n                type: 'application/javascript',\n            }),\n        ),\n    );\n\n    let sourceWasm = SorterWasm;\n\n    // iOS makes choosing the right WebAssembly configuration tricky :(\n    const iOSSemVer = isIOS() ? getIOSSemever() : null;\n    if (!enableSIMDInSort && !useSharedMemory) {\n        sourceWasm = SorterWasmNoSIMD;\n        // Testing on various devices has shown that even when shared memory is disabled, the WASM module with shared\n        // memory can still be used most of the time -- the exception seems to be iOS devices below 16.4\n        if (iOSSemVer && iOSSemVer.major <= 16 && iOSSemVer.minor < 4) {\n            sourceWasm = SorterWasmNoSIMDNonShared;\n        }\n    } else if (!enableSIMDInSort) {\n        sourceWasm = SorterWasmNoSIMD;\n    } else if (!useSharedMemory) {\n        // Same issue with shared memory as above on iOS devices\n        if (iOSSemVer && iOSSemVer.major <= 16 && iOSSemVer.minor < 4) {\n            sourceWasm = SorterWasmNonShared;\n        }\n    }\n\n    const sorterWasmBinaryString = atob(sourceWasm);\n    const sorterWasmBytes = new Uint8Array(sorterWasmBinaryString.length);\n    for (let i = 0; i < sorterWasmBinaryString.length; i++) {\n        sorterWasmBytes[i] = sorterWasmBinaryString.charCodeAt(i);\n    }\n\n    worker.postMessage({\n        'init': {\n            'sorterWasmBytes': sorterWasmBytes.buffer,\n            'splatCount': splatCount,\n            'useSharedMemory': useSharedMemory,\n            'integerBasedSort': integerBasedSort,\n            'dynamicMode': dynamicMode,\n            'distanceMapRange': 1 << splatSortDistanceMapPrecision,\n            // Super hacky\n            'Constants': {\n                'BytesPerFloat': Constants.BytesPerFloat,\n                'BytesPerInt': Constants.BytesPerInt,\n                'MemoryPageSize': Constants.MemoryPageSize,\n                'MaxScenes': Constants.MaxScenes\n            }\n        }\n    });\n    return worker;\n}\n","export const WebXRMode = {\n    None: 0,\n    VR: 1,\n    AR: 2\n};\n","/*\nCopyright © 2010-2024 three.js authors & Mark Kellogg\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n*/\n\nexport class VRButton {\n\n    static createButton( renderer, sessionInit = {} ) {\n\n        const button = document.createElement( 'button' );\n\n        function showEnterVR( /* device */ ) {\n\n            let currentSession = null;\n\n            async function onSessionStarted( session ) {\n\n                session.addEventListener( 'end', onSessionEnded );\n\n                await renderer.xr.setSession( session );\n                button.textContent = 'EXIT VR';\n\n                currentSession = session;\n\n            }\n\n            function onSessionEnded( /* event */ ) {\n\n                currentSession.removeEventListener( 'end', onSessionEnded );\n\n                button.textContent = 'ENTER VR';\n\n                currentSession = null;\n\n            }\n\n            //\n\n            button.style.display = '';\n\n            button.style.cursor = 'pointer';\n            button.style.left = 'calc(50% - 50px)';\n            button.style.width = '100px';\n\n            button.textContent = 'ENTER VR';\n\n            // WebXR's requestReferenceSpace only works if the corresponding feature\n            // was requested at session creation time. For simplicity, just ask for\n            // the interesting ones as optional features, but be aware that the\n            // requestReferenceSpace call will fail if it turns out to be unavailable.\n            // ('local' is always available for immersive sessions and doesn't need to\n            // be requested separately.)\n\n            const sessionOptions = {\n                ...sessionInit,\n                optionalFeatures: [\n                    'local-floor',\n                    'bounded-floor',\n                    'layers',\n                    ...( sessionInit.optionalFeatures || [] )\n                ],\n            };\n\n            button.onmouseenter = function() {\n\n                button.style.opacity = '1.0';\n\n            };\n\n            button.onmouseleave = function() {\n\n                button.style.opacity = '0.5';\n\n            };\n\n            button.onclick = function() {\n\n                if ( currentSession === null ) {\n\n                    navigator.xr.requestSession( 'immersive-vr', sessionOptions ).then( onSessionStarted );\n\n                } else {\n\n                    currentSession.end();\n\n                    if ( navigator.xr.offerSession !== undefined ) {\n\n                        navigator.xr.offerSession( 'immersive-vr', sessionOptions )\n                            .then( onSessionStarted )\n                            .catch( ( err ) => {\n\n                                console.warn( err );\n\n                            } );\n\n                    }\n\n                }\n\n            };\n\n            if ( navigator.xr.offerSession !== undefined ) {\n\n                navigator.xr.offerSession( 'immersive-vr', sessionOptions )\n                    .then( onSessionStarted )\n                    .catch( ( err ) => {\n\n                        console.warn( err );\n\n                    } );\n\n            }\n\n        }\n\n        function disableButton() {\n\n            button.style.display = '';\n\n            button.style.cursor = 'auto';\n            button.style.left = 'calc(50% - 75px)';\n            button.style.width = '150px';\n\n            button.onmouseenter = null;\n            button.onmouseleave = null;\n\n            button.onclick = null;\n\n        }\n\n        function showWebXRNotFound() {\n\n            disableButton();\n\n            button.textContent = 'VR NOT SUPPORTED';\n\n        }\n\n        function showVRNotAllowed( exception ) {\n\n            disableButton();\n\n            console.warn( 'Exception when trying to call xr.isSessionSupported', exception );\n\n            button.textContent = 'VR NOT ALLOWED';\n\n        }\n\n        function stylizeElement( element ) {\n\n            element.style.position = 'absolute';\n            element.style.bottom = '20px';\n            element.style.padding = '12px 6px';\n            element.style.border = '1px solid #fff';\n            element.style.borderRadius = '4px';\n            element.style.background = 'rgba(0,0,0,0.1)';\n            element.style.color = '#fff';\n            element.style.font = 'normal 13px sans-serif';\n            element.style.textAlign = 'center';\n            element.style.opacity = '0.5';\n            element.style.outline = 'none';\n            element.style.zIndex = '999';\n\n        }\n\n        if ( 'xr' in navigator ) {\n\n            button.id = 'VRButton';\n            button.style.display = 'none';\n\n            stylizeElement( button );\n\n            navigator.xr.isSessionSupported( 'immersive-vr' ).then( function( supported ) {\n\n                supported ? showEnterVR() : showWebXRNotFound();\n\n                if ( supported && VRButton.xrSessionIsGranted ) {\n\n                    button.click();\n\n                }\n\n            } ).catch( showVRNotAllowed );\n\n            return button;\n\n        } else {\n\n            const message = document.createElement( 'a' );\n\n            if ( window.isSecureContext === false ) {\n\n                message.href = document.location.href.replace( /^http:/, 'https:' );\n                message.innerHTML = 'WEBXR NEEDS HTTPS'; // TODO Improve message\n\n            } else {\n\n                message.href = 'https://immersiveweb.dev/';\n                message.innerHTML = 'WEBXR NOT AVAILABLE';\n\n            }\n\n            message.style.left = 'calc(50% - 90px)';\n            message.style.width = '180px';\n            message.style.textDecoration = 'none';\n\n            stylizeElement( message );\n\n            return message;\n\n        }\n\n    }\n\n    static registerSessionGrantedListener() {\n\n        if ( typeof navigator !== 'undefined' && 'xr' in navigator ) {\n\n            // WebXRViewer (based on Firefox) has a bug where addEventListener\n            // throws a silent exception and aborts execution entirely.\n            if ( /WebXRViewer\\//i.test( navigator.userAgent ) ) return;\n\n            navigator.xr.addEventListener( 'sessiongranted', () => {\n\n                VRButton.xrSessionIsGranted = true;\n\n            } );\n\n        }\n\n    }\n\n}\n\nVRButton.xrSessionIsGranted = false;\nVRButton.registerSessionGrantedListener();\n","/*\nCopyright © 2010-2024 three.js authors & Mark Kellogg\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n*/\n\nexport class ARButton {\n\n    static createButton( renderer, sessionInit = {} ) {\n\n        const button = document.createElement( 'button' );\n\n        function showStartAR( /* device */ ) {\n\n            if ( sessionInit.domOverlay === undefined ) {\n\n                const overlay = document.createElement( 'div' );\n                overlay.style.display = 'none';\n                document.body.appendChild( overlay );\n\n                const svg = document.createElementNS( 'http://www.w3.org/2000/svg', 'svg' );\n                svg.setAttribute( 'width', 38 );\n                svg.setAttribute( 'height', 38 );\n                svg.style.position = 'absolute';\n                svg.style.right = '20px';\n                svg.style.top = '20px';\n                svg.addEventListener( 'click', function() {\n\n                    currentSession.end();\n\n                } );\n                overlay.appendChild( svg );\n\n                const path = document.createElementNS( 'http://www.w3.org/2000/svg', 'path' );\n                path.setAttribute( 'd', 'M 12,12 L 28,28 M 28,12 12,28' );\n                path.setAttribute( 'stroke', '#fff' );\n                path.setAttribute( 'stroke-width', 2 );\n                svg.appendChild( path );\n\n                if ( sessionInit.optionalFeatures === undefined ) {\n\n                    sessionInit.optionalFeatures = [];\n\n                }\n\n                sessionInit.optionalFeatures.push( 'dom-overlay' );\n                sessionInit.domOverlay = { root: overlay };\n\n            }\n\n            //\n\n            let currentSession = null;\n\n            async function onSessionStarted( session ) {\n\n                session.addEventListener( 'end', onSessionEnded );\n\n                renderer.xr.setReferenceSpaceType( 'local' );\n\n                await renderer.xr.setSession( session );\n\n                button.textContent = 'STOP AR';\n                sessionInit.domOverlay.root.style.display = '';\n\n                currentSession = session;\n\n            }\n\n            function onSessionEnded( /* event */ ) {\n\n                currentSession.removeEventListener( 'end', onSessionEnded );\n\n                button.textContent = 'START AR';\n                sessionInit.domOverlay.root.style.display = 'none';\n\n                currentSession = null;\n\n            }\n\n            //\n\n            button.style.display = '';\n\n            button.style.cursor = 'pointer';\n            button.style.left = 'calc(50% - 50px)';\n            button.style.width = '100px';\n\n            button.textContent = 'START AR';\n\n            button.onmouseenter = function() {\n\n                button.style.opacity = '1.0';\n\n            };\n\n            button.onmouseleave = function() {\n\n                button.style.opacity = '0.5';\n\n            };\n\n            button.onclick = function() {\n\n                if ( currentSession === null ) {\n\n                    navigator.xr.requestSession( 'immersive-ar', sessionInit ).then( onSessionStarted );\n\n                } else {\n\n                    currentSession.end();\n\n                    if ( navigator.xr.offerSession !== undefined ) {\n\n                        navigator.xr.offerSession( 'immersive-ar', sessionInit )\n                            .then( onSessionStarted )\n                            .catch( ( err ) => {\n\n                                console.warn( err );\n\n                            } );\n\n                    }\n\n                }\n\n            };\n\n            if ( navigator.xr.offerSession !== undefined ) {\n\n                navigator.xr.offerSession( 'immersive-ar', sessionInit )\n                    .then( onSessionStarted )\n                    .catch( ( err ) => {\n\n                        console.warn( err );\n\n                    } );\n\n            }\n\n        }\n\n        function disableButton() {\n\n            button.style.display = '';\n\n            button.style.cursor = 'auto';\n            button.style.left = 'calc(50% - 75px)';\n            button.style.width = '150px';\n\n            button.onmouseenter = null;\n            button.onmouseleave = null;\n\n            button.onclick = null;\n\n        }\n\n        function showARNotSupported() {\n\n            disableButton();\n\n            button.textContent = 'AR NOT SUPPORTED';\n\n        }\n\n        function showARNotAllowed( exception ) {\n\n            disableButton();\n\n            console.warn( 'Exception when trying to call xr.isSessionSupported', exception );\n\n            button.textContent = 'AR NOT ALLOWED';\n\n        }\n\n        function stylizeElement( element ) {\n\n            element.style.position = 'absolute';\n            element.style.bottom = '20px';\n            element.style.padding = '12px 6px';\n            element.style.border = '1px solid #fff';\n            element.style.borderRadius = '4px';\n            element.style.background = 'rgba(0,0,0,0.1)';\n            element.style.color = '#fff';\n            element.style.font = 'normal 13px sans-serif';\n            element.style.textAlign = 'center';\n            element.style.opacity = '0.5';\n            element.style.outline = 'none';\n            element.style.zIndex = '999';\n\n        }\n\n        if ( 'xr' in navigator ) {\n\n            button.id = 'ARButton';\n            button.style.display = 'none';\n\n            stylizeElement( button );\n\n            navigator.xr.isSessionSupported( 'immersive-ar' ).then( function( supported ) {\n\n                supported ? showStartAR() : showARNotSupported();\n\n            } ).catch( showARNotAllowed );\n\n            return button;\n\n        } else {\n\n            const message = document.createElement( 'a' );\n\n            if ( window.isSecureContext === false ) {\n\n                message.href = document.location.href.replace( /^http:/, 'https:' );\n                message.innerHTML = 'WEBXR NEEDS HTTPS'; // TODO Improve message\n\n            } else {\n\n                message.href = 'https://immersiveweb.dev/';\n                message.innerHTML = 'WEBXR NOT AVAILABLE';\n\n            }\n\n            message.style.left = 'calc(50% - 90px)';\n            message.style.width = '180px';\n            message.style.textDecoration = 'none';\n\n            stylizeElement( message );\n\n            return message;\n\n        }\n\n    }\n\n}\n","export const RenderMode = {\n    Always: 0,\n    OnChange: 1,\n    Never: 2\n};\n","import * as THREE from 'three';\nimport { OrbitControls } from './OrbitControls.js';\nimport { PlyLoader } from './loaders/ply/PlyLoader.js';\nimport { SplatLoader } from './loaders/splat/SplatLoader.js';\nimport { KSplatLoader } from './loaders/ksplat/KSplatLoader.js';\nimport { SpzLoader } from './loaders/spz/SpzLoader.js';\nimport { sceneFormatFromPath } from './loaders/Utils.js';\nimport { LoadingSpinner } from './ui/LoadingSpinner.js';\nimport { LoadingProgressBar } from './ui/LoadingProgressBar.js';\nimport { InfoPanel } from './ui/InfoPanel.js';\nimport { SceneHelper } from './SceneHelper.js';\nimport { Raycaster } from './raycaster/Raycaster.js';\nimport { SplatMesh } from './splatmesh/SplatMesh.js';\nimport { createSortWorker } from './worker/SortWorker.js';\nimport { Constants } from './Constants.js';\nimport { getCurrentTime, isIOS, getIOSSemever, clamp } from './Util.js';\nimport { AbortablePromise, AbortedPromiseError } from './AbortablePromise.js';\nimport { SceneFormat } from './loaders/SceneFormat.js';\nimport { WebXRMode } from './webxr/WebXRMode.js';\nimport { VRButton } from './webxr/VRButton.js';\nimport { ARButton } from './webxr/ARButton.js';\nimport { delayedExecute, abortablePromiseWithExtractedComponents } from './Util.js';\nimport { LoaderStatus } from './loaders/LoaderStatus.js';\nimport { DirectLoadError } from './loaders/DirectLoadError.js';\nimport { RenderMode } from './RenderMode.js';\nimport { LogLevel } from './LogLevel.js';\nimport { SceneRevealMode } from './SceneRevealMode.js';\nimport { SplatRenderMode } from './SplatRenderMode.js';\n\n\nconst THREE_CAMERA_FOV = 50;\nconst MINIMUM_DISTANCE_TO_NEW_FOCAL_POINT = .75;\nconst MIN_SPLAT_COUNT_TO_SHOW_SPLAT_TREE_LOADING_SPINNER = 1500000;\nconst FOCUS_MARKER_FADE_IN_SPEED = 10.0;\nconst FOCUS_MARKER_FADE_OUT_SPEED = 2.5;\nconst CONSECUTIVE_RENDERED_FRAMES_FOR_FPS_CALCULATION = 60;\n\n/**\n * Viewer: Manages the rendering of splat scenes. Manages an instance of SplatMesh as well as a web worker\n * that performs the sort for its splats.\n */\nexport class Viewer {\n\n    constructor(options = {}) {\n\n        // The natural 'up' vector for viewing the scene (only has an effect when used with orbit controls and\n        // when the viewer uses its own camera).\n        if (!options.cameraUp) options.cameraUp = [0, 1, 0];\n        this.cameraUp = new THREE.Vector3().fromArray(options.cameraUp);\n\n        // The camera's initial position (only used when the viewer uses its own camera).\n        if (!options.initialCameraPosition) options.initialCameraPosition = [0, 10, 15];\n        this.initialCameraPosition = new THREE.Vector3().fromArray(options.initialCameraPosition);\n\n        // The initial focal point of the camera and center of the camera's orbit (only used when the viewer uses its own camera).\n        if (!options.initialCameraLookAt) options.initialCameraLookAt = [0, 0, 0];\n        this.initialCameraLookAt = new THREE.Vector3().fromArray(options.initialCameraLookAt);\n\n        // 'dropInMode' is a flag that is used internally to support the usage of the viewer as a Three.js scene object\n        this.dropInMode = options.dropInMode || false;\n\n        // If 'selfDrivenMode' is true, the viewer manages its own update/animation loop via requestAnimationFrame()\n        if (options.selfDrivenMode === undefined || options.selfDrivenMode === null) options.selfDrivenMode = true;\n        this.selfDrivenMode = options.selfDrivenMode && !this.dropInMode;\n        this.selfDrivenUpdateFunc = this.selfDrivenUpdate.bind(this);\n\n        // If 'useBuiltInControls' is true, the viewer will create its own instance of OrbitControls and attach to the camera\n        if (options.useBuiltInControls === undefined) options.useBuiltInControls = true;\n        this.useBuiltInControls = options.useBuiltInControls;\n\n        // parent element of the Three.js renderer canvas\n        this.rootElement = options.rootElement;\n\n        // Tells the viewer to pretend the device pixel ratio is 1, which can boost performance on devices where it is larger,\n        // at a small cost to visual quality\n        this.ignoreDevicePixelRatio = options.ignoreDevicePixelRatio || false;\n        this.devicePixelRatio = this.ignoreDevicePixelRatio ? 1 : (window.devicePixelRatio || 1);\n\n        // Tells the viewer to use 16-bit floating point values when storing splat covariance data in textures, instead of 32-bit\n        this.halfPrecisionCovariancesOnGPU = options.halfPrecisionCovariancesOnGPU || false;\n\n        // If 'threeScene' is valid, it will be rendered by the viewer along with the splat mesh\n        this.threeScene = options.threeScene;\n        // Allows for usage of an external Three.js renderer\n        this.renderer = options.renderer;\n        // Allows for usage of an external Three.js camera\n        this.camera = options.camera;\n\n        // If 'gpuAcceleratedSort' is true, a partially GPU-accelerated approach to sorting splats will be used.\n        // Currently this means pre-computing splat distances from the camera on the GPU\n        this.gpuAcceleratedSort = options.gpuAcceleratedSort || false;\n\n        // if 'integerBasedSort' is true, the integer version of splat centers as well as other values used to calculate\n        // splat distances are used instead of the float version. This speeds up computation, but introduces the possibility of\n        // overflow in larger scenes.\n        if (options.integerBasedSort === undefined || options.integerBasedSort === null) {\n            options.integerBasedSort = true;\n        }\n        this.integerBasedSort = options.integerBasedSort;\n\n        // If 'sharedMemoryForWorkers' is true, a SharedArrayBuffer will be used to communicate with web workers. This method\n        // is faster than copying memory to or from web workers, but comes with security implications as outlined here:\n        // https://web.dev/articles/cross-origin-isolation-guide\n        // If enabled, it requires specific CORS headers to be present in the response from the server that is sent when\n        // loading the application. More information is available in the README.\n        if (options.sharedMemoryForWorkers === undefined || options.sharedMemoryForWorkers === null) options.sharedMemoryForWorkers = true;\n        this.sharedMemoryForWorkers = options.sharedMemoryForWorkers;\n\n        // if 'dynamicScene' is true, it tells the viewer to assume scene elements are not stationary or that the number of splats in the\n        // scene may change. This prevents optimizations that depend on a static scene from being made. Additionally, if 'dynamicScene' is\n        // true it tells the splat mesh to not apply scene tranforms to splat data that is returned by functions like\n        // SplatMesh.getSplatCenter() by default.\n        this.dynamicScene = !!options.dynamicScene;\n\n        // When true, will perform additional steps during rendering to address artifacts caused by the rendering of gaussians at a\n        // substantially different resolution than that at which they were rendered during training. This will only work correctly\n        // for models that were trained using a process that utilizes this compensation calculation. For more details:\n        // https://github.com/nerfstudio-project/gsplat/pull/117\n        // https://github.com/graphdeco-inria/gaussian-splatting/issues/294#issuecomment-1772688093\n        this.antialiased = options.antialiased || false;\n\n        // This constant is added to the projected 2D screen-space splat scales\n        this.kernel2DSize = (options.kernel2DSize === undefined) ? 0.3 : options.kernel2DSize;\n\n        this.webXRMode = options.webXRMode || WebXRMode.None;\n        if (this.webXRMode !== WebXRMode.None) {\n            this.gpuAcceleratedSort = false;\n        }\n        this.webXRActive = false;\n\n        this.webXRSessionInit = options.webXRSessionInit || {};\n\n        // if 'renderMode' is RenderMode.Always, then the viewer will rrender the scene on every update. If it is RenderMode.OnChange,\n        // it will only render when something in the scene has changed.\n        this.renderMode = options.renderMode || RenderMode.Always;\n\n        // SceneRevealMode.Default results in a nice, slow fade-in effect for progressively loaded scenes,\n        // and a fast fade-in for non progressively loaded scenes.\n        // SceneRevealMode.Gradual will force a slow fade-in for all scenes.\n        // SceneRevealMode.Instant will force all loaded scene data to be immediately visible.\n        this.sceneRevealMode = options.sceneRevealMode || SceneRevealMode.Default;\n\n        // Hacky, experimental, non-scientific parameter for tweaking focal length related calculations. For scenes with very\n        // small gaussians, small details, and small dimensions -- increasing this value can help improve visual quality.\n        this.focalAdjustment = options.focalAdjustment || 1.0;\n\n        // Specify the maximum screen-space splat size, can help deal with large splats that get too unwieldy\n        this.maxScreenSpaceSplatSize = options.maxScreenSpaceSplatSize || 1024;\n\n        // The verbosity of console logging\n        this.logLevel = options.logLevel || LogLevel.None;\n\n        // Degree of spherical harmonics to utilize in rendering splats (assuming the data is present in the splat scene).\n        // Valid values are 0 - 2. Default value is 0.\n        this.sphericalHarmonicsDegree = options.sphericalHarmonicsDegree || 0;\n\n        // When true, allows for usage of extra properties and attributes during rendering for effects such as opacity adjustment.\n        // Default is false for performance reasons. These properties are separate from transform properties (scale, rotation, position)\n        // that are enabled by the 'dynamicScene' parameter.\n        this.enableOptionalEffects = options.enableOptionalEffects || false;\n\n        // Enable the usage of SIMD WebAssembly instructions for the splat sort\n        if (options.enableSIMDInSort === undefined || options.enableSIMDInSort === null) options.enableSIMDInSort = true;\n        this.enableSIMDInSort = options.enableSIMDInSort;\n\n        // Level to compress non KSPLAT files when loading them for direct rendering\n        if (options.inMemoryCompressionLevel === undefined || options.inMemoryCompressionLevel === null) {\n            options.inMemoryCompressionLevel = 0;\n        }\n        this.inMemoryCompressionLevel = options.inMemoryCompressionLevel;\n\n        // Reorder splat data in memory after loading is complete to optimize cache utilization. Default is true.\n        // Does not apply if splat scene is progressively loaded.\n        if (options.optimizeSplatData === undefined || options.optimizeSplatData === null) {\n            options.optimizeSplatData = true;\n        }\n        this.optimizeSplatData = options.optimizeSplatData;\n\n        // When true, the intermediate splat data that is the result of decompressing splat bufffer(s) and is used to\n        // populate the data textures will be freed. This will reduces memory usage, but if that data needs to be modified\n        // it will need to be re-populated from the splat buffer(s). Default is false.\n        if (options.freeIntermediateSplatData === undefined || options.freeIntermediateSplatData === null) {\n            options.freeIntermediateSplatData = false;\n        }\n        this.freeIntermediateSplatData = options.freeIntermediateSplatData;\n\n        // It appears that for certain iOS versions, special actions need to be taken with the\n        // usage of SIMD instructions and shared memory\n        if (isIOS()) {\n            const semver = getIOSSemever();\n            if (semver.major < 17) {\n                this.enableSIMDInSort = false;\n            }\n            if (semver.major < 16) {\n                this.sharedMemoryForWorkers = false;\n            }\n        }\n\n        // Tell the viewer how to render the splats\n        if (options.splatRenderMode === undefined || options.splatRenderMode === null) {\n            options.splatRenderMode = SplatRenderMode.ThreeD;\n        }\n        this.splatRenderMode = options.splatRenderMode;\n\n        // Customize the speed at which the scene is revealed\n        this.sceneFadeInRateMultiplier = options.sceneFadeInRateMultiplier || 1.0;\n\n        // Set the range for the depth map for the counting sort used to sort the splats\n        this.splatSortDistanceMapPrecision = options.splatSortDistanceMapPrecision || Constants.DefaultSplatSortDistanceMapPrecision;\n        const maxPrecision = this.integerBasedSort ? 20 : 24;\n        this.splatSortDistanceMapPrecision = clamp(this.splatSortDistanceMapPrecision, 10, maxPrecision);\n\n        this.onSplatMeshChangedCallback = null;\n        this.createSplatMesh();\n\n        this.controls = null;\n        this.perspectiveControls = null;\n        this.orthographicControls = null;\n\n        this.orthographicCamera = null;\n        this.perspectiveCamera = null;\n\n        this.showMeshCursor = false;\n        this.showControlPlane = false;\n        this.showInfo = false;\n\n        this.sceneHelper = null;\n\n        this.sortWorker = null;\n        this.sortRunning = false;\n        this.splatRenderCount = 0;\n        this.splatSortCount = 0;\n        this.lastSplatSortCount = 0;\n        this.sortWorkerIndexesToSort = null;\n        this.sortWorkerSortedIndexes = null;\n        this.sortWorkerPrecomputedDistances = null;\n        this.sortWorkerTransforms = null;\n        this.preSortMessages = [];\n        this.runAfterNextSort = [];\n\n        this.selfDrivenModeRunning = false;\n        this.splatRenderReady = false;\n\n        this.raycaster = new Raycaster();\n\n        this.infoPanel = null;\n\n        this.startInOrthographicMode = false;\n\n        this.currentFPS = 0;\n        this.lastSortTime = 0;\n        this.consecutiveRenderFrames = 0;\n\n        this.previousCameraTarget = new THREE.Vector3();\n        this.nextCameraTarget = new THREE.Vector3();\n\n        this.mousePosition = new THREE.Vector2();\n        this.mouseDownPosition = new THREE.Vector2();\n        this.mouseDownTime = null;\n\n        this.resizeObserver = null;\n        this.mouseMoveListener = null;\n        this.mouseDownListener = null;\n        this.mouseUpListener = null;\n        this.keyDownListener = null;\n\n        this.sortPromise = null;\n        this.sortPromiseResolver = null;\n        this.splatSceneDownloadPromises = {};\n        this.splatSceneDownloadAndBuildPromise = null;\n        this.splatSceneRemovalPromise = null;\n\n        this.loadingSpinner = new LoadingSpinner(null, this.rootElement || document.body);\n        this.loadingSpinner.hide();\n        this.loadingProgressBar = new LoadingProgressBar(this.rootElement || document.body);\n        this.loadingProgressBar.hide();\n        this.infoPanel = new InfoPanel(this.rootElement || document.body);\n        this.infoPanel.hide();\n\n        this.usingExternalCamera = (this.dropInMode || this.camera) ? true : false;\n        this.usingExternalRenderer = (this.dropInMode || this.renderer) ? true : false;\n\n        this.initialized = false;\n        this.disposing = false;\n        this.disposed = false;\n        this.disposePromise = null;\n        if (!this.dropInMode) this.init();\n    }\n\n    createSplatMesh() {\n        this.splatMesh = new SplatMesh(this.splatRenderMode, this.dynamicScene, this.enableOptionalEffects,\n                                       this.halfPrecisionCovariancesOnGPU, this.devicePixelRatio, this.gpuAcceleratedSort,\n                                       this.integerBasedSort, this.antialiased, this.maxScreenSpaceSplatSize, this.logLevel,\n                                       this.sphericalHarmonicsDegree, this.sceneFadeInRateMultiplier, this.kernel2DSize);\n        this.splatMesh.frustumCulled = false;\n        if (this.onSplatMeshChangedCallback) this.onSplatMeshChangedCallback();\n    }\n\n    init() {\n\n        if (this.initialized) return;\n\n        if (!this.rootElement) {\n            if (!this.usingExternalRenderer) {\n                this.rootElement = document.createElement('div');\n                this.rootElement.style.width = '100%';\n                this.rootElement.style.height = '100%';\n                this.rootElement.style.position = 'absolute';\n                document.body.appendChild(this.rootElement);\n            } else {\n                this.rootElement = this.renderer.domElement || document.body;\n            }\n        }\n\n        this.setupCamera();\n        this.setupRenderer();\n        this.setupWebXR(this.webXRSessionInit);\n        this.setupControls();\n        this.setupEventHandlers();\n\n        this.threeScene = this.threeScene || new THREE.Scene();\n        this.sceneHelper = new SceneHelper(this.threeScene);\n        this.sceneHelper.setupMeshCursor();\n        this.sceneHelper.setupFocusMarker();\n        this.sceneHelper.setupControlPlane();\n\n        this.loadingProgressBar.setContainer(this.rootElement);\n        this.loadingSpinner.setContainer(this.rootElement);\n        this.infoPanel.setContainer(this.rootElement);\n\n        this.initialized = true;\n    }\n\n    setupCamera() {\n        if (!this.usingExternalCamera) {\n            const renderDimensions = new THREE.Vector2();\n            this.getRenderDimensions(renderDimensions);\n\n            this.perspectiveCamera = new THREE.PerspectiveCamera(THREE_CAMERA_FOV, renderDimensions.x / renderDimensions.y, 0.1, 1000);\n            this.orthographicCamera = new THREE.OrthographicCamera(renderDimensions.x / -2, renderDimensions.x / 2,\n                                                                   renderDimensions.y / 2, renderDimensions.y / -2, 0.1, 1000 );\n            this.camera = this.startInOrthographicMode ? this.orthographicCamera : this.perspectiveCamera;\n            this.camera.position.copy(this.initialCameraPosition);\n            this.camera.up.copy(this.cameraUp).normalize();\n            this.camera.lookAt(this.initialCameraLookAt);\n        }\n    }\n\n    setupRenderer() {\n        if (!this.usingExternalRenderer) {\n            const renderDimensions = new THREE.Vector2();\n            this.getRenderDimensions(renderDimensions);\n\n            this.renderer = new THREE.WebGLRenderer({\n                antialias: false,\n                precision: 'highp'\n            });\n            this.renderer.setPixelRatio(this.devicePixelRatio);\n            this.renderer.autoClear = true;\n            this.renderer.setClearColor(new THREE.Color( 0x000000 ), 0.0);\n            this.renderer.setSize(renderDimensions.x, renderDimensions.y);\n\n            this.resizeObserver = new ResizeObserver(() => {\n                this.getRenderDimensions(renderDimensions);\n                this.renderer.setSize(renderDimensions.x, renderDimensions.y);\n                this.forceRenderNextFrame();\n            });\n            this.resizeObserver.observe(this.rootElement);\n            this.rootElement.appendChild(this.renderer.domElement);\n        }\n\n    }\n\n    setupWebXR(webXRSessionInit) {\n        if (this.webXRMode) {\n            if (this.webXRMode === WebXRMode.VR) {\n                this.rootElement.appendChild(VRButton.createButton(this.renderer, webXRSessionInit));\n            } else if (this.webXRMode === WebXRMode.AR) {\n                this.rootElement.appendChild(ARButton.createButton(this.renderer, webXRSessionInit));\n            }\n            this.renderer.xr.addEventListener('sessionstart', (e) => {\n                this.webXRActive = true;\n            });\n            this.renderer.xr.addEventListener('sessionend', (e) => {\n                this.webXRActive = false;\n            });\n            this.renderer.xr.enabled = true;\n            this.camera.position.copy(this.initialCameraPosition);\n            this.camera.up.copy(this.cameraUp).normalize();\n            this.camera.lookAt(this.initialCameraLookAt);\n        }\n    }\n\n    setupControls() {\n        if (this.useBuiltInControls && this.webXRMode === WebXRMode.None) {\n            if (!this.usingExternalCamera) {\n                this.perspectiveControls = new OrbitControls(this.perspectiveCamera, this.renderer.domElement);\n                this.orthographicControls = new OrbitControls(this.orthographicCamera, this.renderer.domElement);\n            } else {\n                if (this.camera.isOrthographicCamera) {\n                    this.orthographicControls = new OrbitControls(this.camera, this.renderer.domElement);\n                } else {\n                    this.perspectiveControls = new OrbitControls(this.camera, this.renderer.domElement);\n                }\n            }\n            for (let controls of [this.orthographicControls, this.perspectiveControls,]) {\n                if (controls) {\n                    controls.listenToKeyEvents(window);\n                    controls.rotateSpeed = 0.5;\n                    controls.maxPolarAngle = Math.PI * .75;\n                    controls.minPolarAngle = 0.1;\n                    controls.enableDamping = true;\n                    controls.dampingFactor = 0.05;\n                    controls.target.copy(this.initialCameraLookAt);\n                    controls.update();\n                }\n            }\n            this.controls = this.camera.isOrthographicCamera ? this.orthographicControls : this.perspectiveControls;\n            this.controls.update();\n        }\n    }\n\n    setupEventHandlers() {\n        if (this.useBuiltInControls && this.webXRMode === WebXRMode.None) {\n            this.mouseMoveListener = this.onMouseMove.bind(this);\n            this.renderer.domElement.addEventListener('pointermove', this.mouseMoveListener, false);\n            this.mouseDownListener = this.onMouseDown.bind(this);\n            this.renderer.domElement.addEventListener('pointerdown', this.mouseDownListener, false);\n            this.mouseUpListener = this.onMouseUp.bind(this);\n            this.renderer.domElement.addEventListener('pointerup', this.mouseUpListener, false);\n            this.keyDownListener = this.onKeyDown.bind(this);\n            window.addEventListener('keydown', this.keyDownListener, false);\n        }\n    }\n\n    removeEventHandlers() {\n        if (this.useBuiltInControls) {\n            this.renderer.domElement.removeEventListener('pointermove', this.mouseMoveListener);\n            this.mouseMoveListener = null;\n            this.renderer.domElement.removeEventListener('pointerdown', this.mouseDownListener);\n            this.mouseDownListener = null;\n            this.renderer.domElement.removeEventListener('pointerup', this.mouseUpListener);\n            this.mouseUpListener = null;\n            window.removeEventListener('keydown', this.keyDownListener);\n            this.keyDownListener = null;\n        }\n    }\n\n    setRenderMode(renderMode) {\n        this.renderMode = renderMode;\n    }\n\n    setActiveSphericalHarmonicsDegrees(activeSphericalHarmonicsDegrees) {\n        this.splatMesh.material.uniforms.sphericalHarmonicsDegree.value = activeSphericalHarmonicsDegrees;\n        this.splatMesh.material.uniformsNeedUpdate = true;\n    }\n\n    onSplatMeshChanged(callback) {\n        this.onSplatMeshChangedCallback = callback;\n    }\n\n    onKeyDown = function() {\n\n        const forward = new THREE.Vector3();\n        const tempMatrixLeft = new THREE.Matrix4();\n        const tempMatrixRight = new THREE.Matrix4();\n\n        return function(e) {\n            forward.set(0, 0, -1);\n            forward.transformDirection(this.camera.matrixWorld);\n            tempMatrixLeft.makeRotationAxis(forward, Math.PI / 128);\n            tempMatrixRight.makeRotationAxis(forward, -Math.PI / 128);\n            switch (e.code) {\n                case 'KeyG':\n                    this.focalAdjustment += 0.02;\n                    this.forceRenderNextFrame();\n                break;\n                case 'KeyF':\n                    this.focalAdjustment -= 0.02;\n                    this.forceRenderNextFrame();\n                break;\n                case 'ArrowLeft':\n                    this.camera.up.transformDirection(tempMatrixLeft);\n                break;\n                case 'ArrowRight':\n                    this.camera.up.transformDirection(tempMatrixRight);\n                break;\n                case 'KeyC':\n                    this.showMeshCursor = !this.showMeshCursor;\n                break;\n                case 'KeyU':\n                    this.showControlPlane = !this.showControlPlane;\n                break;\n                case 'KeyI':\n                    this.showInfo = !this.showInfo;\n                    if (this.showInfo) {\n                        this.infoPanel.show();\n                    } else {\n                        this.infoPanel.hide();\n                    }\n                break;\n                case 'KeyO':\n                    if (!this.usingExternalCamera) {\n                        this.setOrthographicMode(!this.camera.isOrthographicCamera);\n                    }\n                break;\n                case 'KeyP':\n                    if (!this.usingExternalCamera) {\n                        this.splatMesh.setPointCloudModeEnabled(!this.splatMesh.getPointCloudModeEnabled());\n                    }\n                break;\n                case 'Equal':\n                    if (!this.usingExternalCamera) {\n                        this.splatMesh.setSplatScale(this.splatMesh.getSplatScale() + 0.05);\n                    }\n                break;\n                case 'Minus':\n                    if (!this.usingExternalCamera) {\n                        this.splatMesh.setSplatScale(Math.max(this.splatMesh.getSplatScale() - 0.05, 0.0));\n                    }\n                break;\n            }\n        };\n\n    }();\n\n    onMouseMove(mouse) {\n        this.mousePosition.set(mouse.offsetX, mouse.offsetY);\n    }\n\n    onMouseDown() {\n        this.mouseDownPosition.copy(this.mousePosition);\n        this.mouseDownTime = getCurrentTime();\n    }\n\n    onMouseUp = function() {\n\n        const clickOffset = new THREE.Vector2();\n\n        return function(mouse) {\n            clickOffset.copy(this.mousePosition).sub(this.mouseDownPosition);\n            const mouseUpTime = getCurrentTime();\n            const wasClick = mouseUpTime - this.mouseDownTime < 0.5 && clickOffset.length() < 2;\n            if (wasClick) {\n                this.onMouseClick(mouse);\n            }\n        };\n\n    }();\n\nonMouseClick(mouse) {\n    this.mousePosition.set(mouse.offsetX, mouse.offsetY);\n    this.checkForFocalPointChange();\n\n    if (this.infoPanel && this.infoPanel.meshCursorPosition) {\n        const cursPos = this.infoPanel.meshCursorPosition;\n        const cursorPosString = `${cursPos.x.toFixed(2)}, ${cursPos.y.toFixed(2)}, ${cursPos.z.toFixed(2)}`;\n\n        navigator.clipboard.writeText(cursorPosString)\n            .then(() => {\n                console.log(\"Position copiée :\", cursorPosString);\n            })\n            .catch(err => {\n                console.error(\"Échec de la copie :\", err);\n            });\n    }\n}\n    \n\n    checkForFocalPointChange = function() {\n\n        const renderDimensions = new THREE.Vector2();\n        const toNewFocalPoint = new THREE.Vector3();\n        const outHits = [];\n\n        return function() {\n            if (!this.transitioningCameraTarget) {\n                this.getRenderDimensions(renderDimensions);\n                outHits.length = 0;\n                this.raycaster.setFromCameraAndScreenPosition(this.camera, this.mousePosition, renderDimensions);\n                this.raycaster.intersectSplatMesh(this.splatMesh, outHits);\n                if (outHits.length > 0) {\n                    const hit = outHits[0];\n                    const intersectionPoint = hit.origin;\n                    toNewFocalPoint.copy(intersectionPoint).sub(this.camera.position);\n                    if (toNewFocalPoint.length() > MINIMUM_DISTANCE_TO_NEW_FOCAL_POINT) {\n                        this.previousCameraTarget.copy(this.controls.target);\n                        this.nextCameraTarget.copy(intersectionPoint);\n                        this.transitioningCameraTarget = true;\n                        this.transitioningCameraTargetStartTime = getCurrentTime();\n                    }\n                }\n            }\n        };\n\n    }();\n\n    getRenderDimensions(outDimensions) {\n        if (this.rootElement) {\n            outDimensions.x = this.rootElement.offsetWidth;\n            outDimensions.y = this.rootElement.offsetHeight;\n        } else {\n            this.renderer.getSize(outDimensions);\n        }\n    }\n\n    setOrthographicMode(orthographicMode) {\n        if (orthographicMode === this.camera.isOrthographicCamera) return;\n        const fromCamera = this.camera;\n        const toCamera = orthographicMode ? this.orthographicCamera : this.perspectiveCamera;\n        toCamera.position.copy(fromCamera.position);\n        toCamera.up.copy(fromCamera.up);\n        toCamera.rotation.copy(fromCamera.rotation);\n        toCamera.quaternion.copy(fromCamera.quaternion);\n        toCamera.matrix.copy(fromCamera.matrix);\n        this.camera = toCamera;\n\n        if (this.controls) {\n\n            const resetControls = (controls) => {\n                controls.saveState();\n                controls.reset();\n            };\n\n            const fromControls = this.controls;\n            const toControls = orthographicMode ? this.orthographicControls : this.perspectiveControls;\n\n            resetControls(toControls);\n            resetControls(fromControls);\n\n            toControls.target.copy(fromControls.target);\n            if (orthographicMode) {\n                Viewer.setCameraZoomFromPosition(toCamera, fromCamera, fromControls);\n            } else {\n                Viewer.setCameraPositionFromZoom(toCamera, fromCamera, toControls);\n            }\n            this.controls = toControls;\n            this.camera.lookAt(this.controls.target);\n        }\n    }\n\n    static setCameraPositionFromZoom = function() {\n\n        const tempVector = new THREE.Vector3();\n\n        return function(positionCamera, zoomedCamera, controls) {\n            const toLookAtDistance = 1 / (zoomedCamera.zoom * 0.001);\n            tempVector.copy(controls.target).sub(positionCamera.position).normalize().multiplyScalar(toLookAtDistance).negate();\n            positionCamera.position.copy(controls.target).add(tempVector);\n        };\n\n    }();\n\n\n    static setCameraZoomFromPosition = function() {\n\n        const tempVector = new THREE.Vector3();\n\n        return function(zoomCamera, positionZamera, controls) {\n            const toLookAtDistance = tempVector.copy(controls.target).sub(positionZamera.position).length();\n            zoomCamera.zoom = 1 / (toLookAtDistance * .001);\n        };\n\n    }();\n\n    updateSplatMesh = function() {\n\n        const renderDimensions = new THREE.Vector2();\n\n        return function() {\n            if (!this.splatMesh) return;\n            const splatCount = this.splatMesh.getSplatCount();\n            if (splatCount > 0) {\n                this.splatMesh.updateVisibleRegionFadeDistance(this.sceneRevealMode);\n                this.splatMesh.updateTransforms();\n                this.getRenderDimensions(renderDimensions);\n                const focalLengthX = this.camera.projectionMatrix.elements[0] * 0.5 *\n                                     this.devicePixelRatio * renderDimensions.x;\n                const focalLengthY = this.camera.projectionMatrix.elements[5] * 0.5 *\n                                     this.devicePixelRatio * renderDimensions.y;\n\n                const focalMultiplier = this.camera.isOrthographicCamera ? (1.0 / this.devicePixelRatio) : 1.0;\n                const focalAdjustment = this.focalAdjustment * focalMultiplier;\n                const inverseFocalAdjustment = 1.0 / focalAdjustment;\n\n                this.adjustForWebXRStereo(renderDimensions);\n                this.splatMesh.updateUniforms(renderDimensions, focalLengthX * focalAdjustment, focalLengthY * focalAdjustment,\n                                              this.camera.isOrthographicCamera, this.camera.zoom || 1.0, inverseFocalAdjustment);\n            }\n        };\n\n    }();\n\n    adjustForWebXRStereo(renderDimensions) {\n        // TODO: Figure out a less hacky way to determine if stereo rendering is active\n        if (this.camera && this.webXRActive) {\n            const xrCamera = this.renderer.xr.getCamera();\n            const xrCameraProj00 = xrCamera.projectionMatrix.elements[0];\n            const cameraProj00 = this.camera.projectionMatrix.elements[0];\n            renderDimensions.x *= (cameraProj00 / xrCameraProj00);\n        }\n    }\n\n    isLoadingOrUnloading() {\n        return Object.keys(this.splatSceneDownloadPromises).length > 0 || this.splatSceneDownloadAndBuildPromise !== null ||\n                           this.splatSceneRemovalPromise !== null;\n    }\n\n    isDisposingOrDisposed() {\n        return this.disposing || this.disposed;\n    }\n\n    addSplatSceneDownloadPromise(promise) {\n        this.splatSceneDownloadPromises[promise.id] = promise;\n    }\n\n    removeSplatSceneDownloadPromise(promise) {\n        delete this.splatSceneDownloadPromises[promise.id];\n    }\n\n    setSplatSceneDownloadAndBuildPromise(promise) {\n        this.splatSceneDownloadAndBuildPromise = promise;\n    }\n\n    clearSplatSceneDownloadAndBuildPromise() {\n        this.splatSceneDownloadAndBuildPromise = null;\n    }\n\n    /**\n     * Add a splat scene to the viewer and display any loading UI if appropriate.\n     * @param {string} path Path to splat scene to be loaded\n     * @param {object} options {\n     *\n     *         splatAlphaRemovalThreshold: Ignore any splats with an alpha less than the specified\n     *                                     value (valid range: 0 - 255), defaults to 1\n     *\n     *         showLoadingUI:         Display a loading spinner while the scene is loading, defaults to true\n     *\n     *         position (Array<number>):   Position of the scene, acts as an offset from its default position, defaults to [0, 0, 0]\n     *\n     *         rotation (Array<number>):   Rotation of the scene represented as a quaternion, defaults to [0, 0, 0, 1]\n     *\n     *         scale (Array<number>):      Scene's scale, defaults to [1, 1, 1]\n     *\n     *         onProgress:                 Function to be called as file data are received, or other processing occurs\n     *\n     *         headers:                    Optional HTTP headers to be sent along with splat requests\n     * }\n     * @return {AbortablePromise}\n     */\n    addSplatScene(path, options = {}) {\n\n        if (this.isLoadingOrUnloading()) {\n            throw new Error('Cannot add splat scene while another load or unload is already in progress.');\n        }\n\n        if (this.isDisposingOrDisposed()) {\n            throw new Error('Cannot add splat scene after dispose() is called.');\n        }\n\n        if (options.progressiveLoad && this.splatMesh.scenes && this.splatMesh.scenes.length > 0) {\n            console.log('addSplatScene(): \"progressiveLoad\" option ignore because there are multiple splat scenes');\n            options.progressiveLoad = false;\n        }\n\n        const format = (options.format !== undefined && options.format !== null) ? options.format : sceneFormatFromPath(path);\n        const progressiveLoad = Viewer.isProgressivelyLoadable(format) && options.progressiveLoad;\n        const showLoadingUI = (options.showLoadingUI !== undefined && options.showLoadingUI !== null) ? options.showLoadingUI : true;\n\n        let loadingUITaskId = null;\n        if (showLoadingUI) {\n            this.loadingSpinner.removeAllTasks();\n            loadingUITaskId = this.loadingSpinner.addTask('Downloading...');\n        }\n        const hideLoadingUI = () => {\n            this.loadingProgressBar.hide();\n            this.loadingSpinner.removeAllTasks();\n        };\n\n        const onProgressUIUpdate = (percentComplete, percentCompleteLabel, loaderStatus) => {\n            if (showLoadingUI) {\n                if (loaderStatus === LoaderStatus.Downloading) {\n                    if (percentComplete == 100) {\n                        this.loadingSpinner.setMessageForTask(loadingUITaskId, 'Download complete!');\n                    } else {\n                        if (progressiveLoad) {\n                            this.loadingSpinner.setMessageForTask(loadingUITaskId, 'Downloading splats...');\n                        } else {\n                            const suffix = percentCompleteLabel ? `: ${percentCompleteLabel}` : `...`;\n                            this.loadingSpinner.setMessageForTask(loadingUITaskId, `Downloading${suffix}`);\n                        }\n                    }\n                } else if (loaderStatus === LoaderStatus.Processing) {\n                    this.loadingSpinner.setMessageForTask(loadingUITaskId, 'Processing splats...');\n                }\n            }\n        };\n\n        let downloadDone = false;\n        let downloadedPercentage = 0;\n        const splatBuffersAddedUIUpdate = (firstBuild, finalBuild) => {\n            if (showLoadingUI) {\n                if (firstBuild && progressiveLoad || finalBuild && !progressiveLoad) {\n                    this.loadingSpinner.removeTask(loadingUITaskId);\n                    if (!finalBuild && !downloadDone) this.loadingProgressBar.show();\n                }\n                if (progressiveLoad) {\n                    if (finalBuild) {\n                        downloadDone = true;\n                        this.loadingProgressBar.hide();\n                    } else {\n                        this.loadingProgressBar.setProgress(downloadedPercentage);\n                    }\n                }\n            }\n        };\n\n        const onProgress = (percentComplete, percentCompleteLabel, loaderStatus) => {\n            downloadedPercentage = percentComplete;\n            onProgressUIUpdate(percentComplete, percentCompleteLabel, loaderStatus);\n            if (options.onProgress) options.onProgress(percentComplete, percentCompleteLabel, loaderStatus);\n        };\n\n        const buildSection = (splatBuffer, firstBuild, finalBuild) => {\n            if (!progressiveLoad && options.onProgress) options.onProgress(0, '0%', LoaderStatus.Processing);\n            const addSplatBufferOptions = {\n                'rotation': options.rotation || options.orientation,\n                'position': options.position,\n                'scale': options.scale,\n                'splatAlphaRemovalThreshold': options.splatAlphaRemovalThreshold,\n            };\n            return this.addSplatBuffers([splatBuffer], [addSplatBufferOptions],\n                                         finalBuild, firstBuild && showLoadingUI, showLoadingUI,\n                                         progressiveLoad, progressiveLoad).then(() => {\n                if (!progressiveLoad && options.onProgress) options.onProgress(100, '100%', LoaderStatus.Processing);\n                splatBuffersAddedUIUpdate(firstBuild, finalBuild);\n            });\n        };\n\n        const loadFunc = progressiveLoad ? this.downloadAndBuildSingleSplatSceneProgressiveLoad.bind(this) :\n                                           this.downloadAndBuildSingleSplatSceneStandardLoad.bind(this);\n        return loadFunc(path, format, options.splatAlphaRemovalThreshold, buildSection.bind(this),\n                        onProgress, hideLoadingUI.bind(this), options.headers);\n    }\n\n    /**\n     * Download a single splat scene, convert to splat buffer and then rebuild the viewer's splat mesh\n     * by calling 'buildFunc' -- all before displaying the scene. Also sets/clears relevant instance synchronization objects,\n     * and calls appropriate functions on success or failure.\n     * @param {string} path Path to splat scene to be loaded\n     * @param {SceneFormat} format Format of the splat scene file\n     * @param {number} splatAlphaRemovalThreshold Ignore any splats with an alpha less than the specified value (valid range: 0 - 255)\n     * @param {function} buildFunc Function to build the viewer's splat mesh with the downloaded splat buffer\n     * @param {function} onProgress Function to be called as file data are received, or other processing occurs\n     * @param {function} onException Function to be called when exception occurs\n     * @param {object} headers Optional HTTP headers to pass to use for downloading splat scene\n     * @return {AbortablePromise}\n     */\n    downloadAndBuildSingleSplatSceneStandardLoad(path, format, splatAlphaRemovalThreshold, buildFunc, onProgress, onException, headers) {\n\n        const downloadPromise = this.downloadSplatSceneToSplatBuffer(path, splatAlphaRemovalThreshold, onProgress, false,\n                                                                     undefined, format, headers);\n        const downloadAndBuildPromise = abortablePromiseWithExtractedComponents(downloadPromise.abortHandler);\n\n        downloadPromise.then((splatBuffer) => {\n            this.removeSplatSceneDownloadPromise(downloadPromise);\n            return buildFunc(splatBuffer, true, true).then(() => {\n                downloadAndBuildPromise.resolve();\n                this.clearSplatSceneDownloadAndBuildPromise();\n            });\n        })\n        .catch((e) => {\n            if (onException) onException();\n            this.clearSplatSceneDownloadAndBuildPromise();\n            this.removeSplatSceneDownloadPromise(downloadPromise);\n            downloadAndBuildPromise.reject(this.updateError(e, `Viewer::addSplatScene -> Could not load file ${path}`));\n        });\n\n        this.addSplatSceneDownloadPromise(downloadPromise);\n        this.setSplatSceneDownloadAndBuildPromise(downloadAndBuildPromise.promise);\n\n        return downloadAndBuildPromise.promise;\n    }\n\n    /**\n     * Download a single splat scene and convert to splat buffer in a progressive manner, allowing rendering as the file downloads.\n     * As each section is downloaded, the viewer's splat mesh is rebuilt by calling 'buildFunc'\n     * Also sets/clears relevant instance synchronization objects, and calls appropriate functions on success or failure.\n     * @param {string} path Path to splat scene to be loaded\n     * @param {SceneFormat} format Format of the splat scene file\n     * @param {number} splatAlphaRemovalThreshold Ignore any splats with an alpha less than the specified value (valid range: 0 - 255)\n     * @param {function} buildFunc Function to rebuild the viewer's splat mesh after a new splat buffer section is downloaded\n     * @param {function} onDownloadProgress Function to be called as file data are received\n     * @param {function} onDownloadException Function to be called when exception occurs at any point during the full download\n     * @param {object} headers Optional HTTP headers to pass to use for downloading splat scene\n     * @return {AbortablePromise}\n     */\n    downloadAndBuildSingleSplatSceneProgressiveLoad(path, format, splatAlphaRemovalThreshold, buildFunc,\n                                                    onDownloadProgress, onDownloadException, headers) {\n        let progressiveLoadedSectionBuildCount = 0;\n        let progressiveLoadedSectionBuilding = false;\n        const queuedProgressiveLoadSectionBuilds = [];\n\n        const checkAndBuildProgressiveLoadSections = () => {\n            if (queuedProgressiveLoadSectionBuilds.length > 0 &&\n                !progressiveLoadedSectionBuilding &&\n                !this.isDisposingOrDisposed()) {\n                progressiveLoadedSectionBuilding = true;\n                const queuedBuild = queuedProgressiveLoadSectionBuilds.shift();\n                buildFunc(queuedBuild.splatBuffer, queuedBuild.firstBuild, queuedBuild.finalBuild)\n                .then(() => {\n                    progressiveLoadedSectionBuilding = false;\n                    if (queuedBuild.firstBuild) {\n                        progressiveLoadFirstSectionBuildPromise.resolve();\n                    } else if (queuedBuild.finalBuild) {\n                        splatSceneDownloadAndBuildPromise.resolve();\n                        this.clearSplatSceneDownloadAndBuildPromise();\n                    }\n                    if (queuedProgressiveLoadSectionBuilds.length > 0) {\n                        delayedExecute(() => checkAndBuildProgressiveLoadSections());\n                    }\n                });\n            }\n        };\n\n        const onProgressiveLoadSectionProgress = (splatBuffer, finalBuild) => {\n            if (!this.isDisposingOrDisposed()) {\n                if (finalBuild || queuedProgressiveLoadSectionBuilds.length === 0 ||\n                    splatBuffer.getSplatCount() > queuedProgressiveLoadSectionBuilds[0].splatBuffer.getSplatCount()) {\n                    queuedProgressiveLoadSectionBuilds.push({\n                        splatBuffer,\n                        firstBuild: progressiveLoadedSectionBuildCount === 0,\n                        finalBuild\n                    });\n                    progressiveLoadedSectionBuildCount++;\n                    checkAndBuildProgressiveLoadSections();\n                }\n            }\n        };\n\n        const splatSceneDownloadPromise = this.downloadSplatSceneToSplatBuffer(path, splatAlphaRemovalThreshold, onDownloadProgress, true,\n                                                                               onProgressiveLoadSectionProgress, format, headers);\n\n        const progressiveLoadFirstSectionBuildPromise = abortablePromiseWithExtractedComponents(splatSceneDownloadPromise.abortHandler);\n        const splatSceneDownloadAndBuildPromise = abortablePromiseWithExtractedComponents();\n\n        this.addSplatSceneDownloadPromise(splatSceneDownloadPromise);\n        this.setSplatSceneDownloadAndBuildPromise(splatSceneDownloadAndBuildPromise.promise);\n\n        splatSceneDownloadPromise.then(() => {\n            this.removeSplatSceneDownloadPromise(splatSceneDownloadPromise);\n        })\n        .catch((e) => {\n            this.clearSplatSceneDownloadAndBuildPromise();\n            this.removeSplatSceneDownloadPromise(splatSceneDownloadPromise);\n            const error = this.updateError(e, `Viewer::addSplatScene -> Could not load one or more scenes`);\n            progressiveLoadFirstSectionBuildPromise.reject(error);\n            if (onDownloadException) onDownloadException(error);\n        });\n\n        return progressiveLoadFirstSectionBuildPromise.promise;\n    }\n\n    /**\n     * Add multiple splat scenes to the viewer and display any loading UI if appropriate.\n     * @param {Array<object>} sceneOptions Array of per-scene options: {\n     *\n     *         path: Path to splat scene to be loaded\n     *\n     *         splatAlphaRemovalThreshold: Ignore any splats with an alpha less than the specified\n     *                                     value (valid range: 0 - 255), defaults to 1\n     *\n     *         position (Array<number>):   Position of the scene, acts as an offset from its default position, defaults to [0, 0, 0]\n     *\n     *         rotation (Array<number>):   Rotation of the scene represented as a quaternion, defaults to [0, 0, 0, 1]\n     *\n     *         scale (Array<number>):      Scene's scale, defaults to [1, 1, 1]\n     *\n     *         headers:                    Optional HTTP headers to be sent along with splat requests\n     *\n     *         format (SceneFormat)        Optional, the format of the scene data (.ply, .ksplat, .splat). If not present, the\n     *                                     file extension in 'path' will be used to determine the format (if it is present)\n     * }\n     * @param {boolean} showLoadingUI Display a loading spinner while the scene is loading, defaults to true\n     * @param {function} onProgress Function to be called as file data are received\n     * @return {AbortablePromise}\n     */\n    addSplatScenes(sceneOptions, showLoadingUI = true, onProgress = undefined) {\n\n        if (this.isLoadingOrUnloading()) {\n            throw new Error('Cannot add splat scene while another load or unload is already in progress.');\n        }\n\n        if (this.isDisposingOrDisposed()) {\n            throw new Error('Cannot add splat scene after dispose() is called.');\n        }\n\n        const fileCount = sceneOptions.length;\n        const percentComplete = [];\n\n        let loadingUITaskId;\n        if (showLoadingUI) {\n            this.loadingSpinner.removeAllTasks();\n            loadingUITaskId = this.loadingSpinner.addTask('Downloading...');\n        }\n\n        const onLoadProgress = (fileIndex, percent, percentLabel, loaderStatus) => {\n            percentComplete[fileIndex] = percent;\n            let totalPercent = 0;\n            for (let i = 0; i < fileCount; i++) totalPercent += percentComplete[i] || 0;\n            totalPercent = totalPercent / fileCount;\n            percentLabel = `${totalPercent.toFixed(2)}%`;\n            if (showLoadingUI) {\n                if (loaderStatus === LoaderStatus.Downloading) {\n                    this.loadingSpinner.setMessageForTask(loadingUITaskId, totalPercent == 100 ?\n                                                          `Download complete!` : `Downloading: ${percentLabel}`);\n                }\n            }\n            if (onProgress) onProgress(totalPercent, percentLabel, loaderStatus);\n        };\n\n        const baseDownloadPromises = [];\n        const nativeDownloadPromises = [];\n        for (let i = 0; i < sceneOptions.length; i++) {\n            const options = sceneOptions[i];\n            const format = (options.format !== undefined && options.format !== null) ? options.format : sceneFormatFromPath(options.path);\n            const baseDownloadPromise = this.downloadSplatSceneToSplatBuffer(options.path, options.splatAlphaRemovalThreshold,\n                                                                             onLoadProgress.bind(this, i), false, undefined,\n                                                                             format, options.headers);\n            baseDownloadPromises.push(baseDownloadPromise);\n            nativeDownloadPromises.push(baseDownloadPromise.promise);\n        }\n\n        const downloadAndBuildPromise = new AbortablePromise((resolve, reject) => {\n            Promise.all(nativeDownloadPromises)\n            .then((splatBuffers) => {\n                if (showLoadingUI) this.loadingSpinner.removeTask(loadingUITaskId);\n                if (onProgress) onProgress(0, '0%', LoaderStatus.Processing);\n                this.addSplatBuffers(splatBuffers, sceneOptions, true, showLoadingUI, showLoadingUI, false, false).then(() => {\n                    if (onProgress) onProgress(100, '100%', LoaderStatus.Processing);\n                    this.clearSplatSceneDownloadAndBuildPromise();\n                    resolve();\n                });\n            })\n            .catch((e) => {\n                if (showLoadingUI) this.loadingSpinner.removeTask(loadingUITaskId);\n                this.clearSplatSceneDownloadAndBuildPromise();\n                reject(this.updateError(e, `Viewer::addSplatScenes -> Could not load one or more splat scenes.`));\n            })\n            .finally(() => {\n                this.removeSplatSceneDownloadPromise(downloadAndBuildPromise);\n            });\n        }, (reason) => {\n            for (let baseDownloadPromise of baseDownloadPromises) {\n                baseDownloadPromise.abort(reason);\n            }\n        });\n        this.addSplatSceneDownloadPromise(downloadAndBuildPromise);\n        this.setSplatSceneDownloadAndBuildPromise(downloadAndBuildPromise);\n        return downloadAndBuildPromise;\n    }\n\n    /**\n     * Download a splat scene and convert to SplatBuffer instance.\n     * @param {string} path Path to splat scene to be loaded\n     * @param {number} splatAlphaRemovalThreshold Ignore any splats with an alpha less than the specified\n     *                                            value (valid range: 0 - 255), defaults to 1\n     *\n     * @param {function} onProgress Function to be called as file data are received\n     * @param {boolean} progressiveBuild Construct file sections into splat buffers as they are downloaded\n     * @param {function} onSectionBuilt Function to be called when new section is added to the file\n     * @param {string} format File format of the scene\n     * @param {object} headers Optional HTTP headers to pass to use for downloading splat scene\n     * @return {AbortablePromise}\n     */\n    downloadSplatSceneToSplatBuffer(path, splatAlphaRemovalThreshold = 1, onProgress = undefined,\n                                    progressiveBuild = false, onSectionBuilt = undefined, format, headers) {\n        try {\n            if (format === SceneFormat.Splat || format === SceneFormat.KSplat || format === SceneFormat.Ply) {\n                const optimizeSplatData = progressiveBuild ? false : this.optimizeSplatData;\n                if (format === SceneFormat.Splat) {\n                    return SplatLoader.loadFromURL(path, onProgress, progressiveBuild, onSectionBuilt, splatAlphaRemovalThreshold,\n                                                   this.inMemoryCompressionLevel, optimizeSplatData, headers);\n                } else if (format === SceneFormat.KSplat) {\n                    return KSplatLoader.loadFromURL(path, onProgress, progressiveBuild, onSectionBuilt, headers);\n                } else if (format === SceneFormat.Ply) {\n                    return PlyLoader.loadFromURL(path, onProgress, progressiveBuild, onSectionBuilt, splatAlphaRemovalThreshold,\n                                                 this.inMemoryCompressionLevel, optimizeSplatData, this.sphericalHarmonicsDegree, headers);\n                }\n            } else if (format === SceneFormat.Spz) {\n                return SpzLoader.loadFromURL(path, onProgress, splatAlphaRemovalThreshold, this.inMemoryCompressionLevel,\n                                             this.optimizeSplatData, this.sphericalHarmonicsDegree, headers);\n            }\n        } catch (e) {\n            throw this.updateError(e, null);\n        }\n\n        throw new Error(`Viewer::downloadSplatSceneToSplatBuffer -> File format not supported: ${path}`);\n    }\n\n    static isProgressivelyLoadable(format) {\n        return format === SceneFormat.Splat || format === SceneFormat.KSplat || format === SceneFormat.Ply;\n    }\n\n    /**\n     * Add one or more instances of SplatBuffer to the SplatMesh instance managed by the viewer and set up the sorting web worker.\n     * This function will terminate the existing sort worker (if there is one).\n     */\n    addSplatBuffers = function() {\n\n        return function(splatBuffers, splatBufferOptions = [], finalBuild = true, showLoadingUI = true,\n                        showLoadingUIForSplatTreeBuild = true, replaceExisting = false,\n                        enableRenderBeforeFirstSort = false, preserveVisibleRegion = true) {\n\n            if (this.isDisposingOrDisposed()) return Promise.resolve();\n\n            let splatProcessingTaskId = null;\n            const removeSplatProcessingTask = () => {\n                if (splatProcessingTaskId !== null) {\n                    this.loadingSpinner.removeTask(splatProcessingTaskId);\n                    splatProcessingTaskId = null;\n                }\n            };\n\n            this.splatRenderReady = false;\n            return new Promise((resolve) => {\n                if (showLoadingUI) {\n                    splatProcessingTaskId = this.loadingSpinner.addTask('Processing splats...');\n                }\n                delayedExecute(() => {\n                    if (this.isDisposingOrDisposed()) {\n                        resolve();\n                    } else {\n                        const buildResults = this.addSplatBuffersToMesh(splatBuffers, splatBufferOptions, finalBuild,\n                                                                        showLoadingUIForSplatTreeBuild, replaceExisting,\n                                                                        preserveVisibleRegion);\n\n                        const maxSplatCount = this.splatMesh.getMaxSplatCount();\n                        if (this.sortWorker && this.sortWorker.maxSplatCount !== maxSplatCount) this.disposeSortWorker();\n                        // If we aren't calculating the splat distances from the center on the GPU, the sorting worker needs\n                        // splat centers and transform indexes so that it can calculate those distance values.\n                        if (!this.gpuAcceleratedSort) {\n                            this.preSortMessages.push({\n                                'centers': buildResults.centers.buffer,\n                                'sceneIndexes': buildResults.sceneIndexes.buffer,\n                                'range': {\n                                    'from': buildResults.from,\n                                    'to': buildResults.to,\n                                    'count': buildResults.count\n                                }\n                            });\n                        }\n                        const sortWorkerSetupPromise = (!this.sortWorker && maxSplatCount > 0) ?\n                                                         this.setupSortWorker(this.splatMesh) : Promise.resolve();\n                        sortWorkerSetupPromise.then(() => {\n                            if (this.isDisposingOrDisposed()) return;\n                            this.runSplatSort(true, true).then((sortRunning) => {\n                                if (!this.sortWorker || !sortRunning) {\n                                    this.splatRenderReady = true;\n                                    removeSplatProcessingTask();\n                                    resolve();\n                                } else {\n                                    if (enableRenderBeforeFirstSort) {\n                                        this.splatRenderReady = true;\n                                    } else {\n                                        this.runAfterNextSort.push(() => {\n                                            this.splatRenderReady = true;\n                                        });\n                                    }\n                                    this.runAfterNextSort.push(() => {\n                                        removeSplatProcessingTask();\n                                        resolve();\n                                    });\n                                }\n                            });\n                        });\n                    }\n                }, true);\n            });\n        };\n\n    }();\n\n    /**\n     * Add one or more instances of SplatBuffer to the SplatMesh instance managed by the viewer. By default, this function is additive;\n     * all splat buffers contained by the viewer's splat mesh before calling this function will be preserved. This behavior can be\n     * changed by passing 'true' for 'replaceExisting'.\n     * @param {Array<SplatBuffer>} splatBuffers SplatBuffer instances\n     * @param {Array<object>} splatBufferOptions Array of options objects: {\n     *\n     *         splatAlphaRemovalThreshold: Ignore any splats with an alpha less than the specified\n     *                                     value (valid range: 0 - 255), defaults to 1\n     *\n     *         position (Array<number>):   Position of the scene, acts as an offset from its default position, defaults to [0, 0, 0]\n     *\n     *         rotation (Array<number>):   Rotation of the scene represented as a quaternion, defaults to [0, 0, 0, 1]\n     *\n     *         scale (Array<number>):      Scene's scale, defaults to [1, 1, 1]\n     * }\n     * @param {boolean} finalBuild Will the splat mesh be in its final state after this build?\n     * @param {boolean} showLoadingUIForSplatTreeBuild Whether or not to show the loading spinner during construction of the splat tree.\n     * @return {object} Object containing info about the splats that are updated\n     */\n    addSplatBuffersToMesh = function() {\n\n        let splatOptimizingTaskId;\n\n        return function(splatBuffers, splatBufferOptions, finalBuild = true, showLoadingUIForSplatTreeBuild = false,\n                        replaceExisting = false, preserveVisibleRegion = true) {\n            if (this.isDisposingOrDisposed()) return;\n            let allSplatBuffers = [];\n            let allSplatBufferOptions = [];\n            if (!replaceExisting) {\n                allSplatBuffers = this.splatMesh.scenes.map((scene) => scene.splatBuffer) || [];\n                allSplatBufferOptions = this.splatMesh.sceneOptions ? this.splatMesh.sceneOptions.map((sceneOptions) => sceneOptions) : [];\n            }\n            allSplatBuffers.push(...splatBuffers);\n            allSplatBufferOptions.push(...splatBufferOptions);\n            if (this.renderer) this.splatMesh.setRenderer(this.renderer);\n            const onSplatTreeIndexesUpload = (finished) => {\n                if (this.isDisposingOrDisposed()) return;\n                const splatCount = this.splatMesh.getSplatCount();\n                if (showLoadingUIForSplatTreeBuild && splatCount >= MIN_SPLAT_COUNT_TO_SHOW_SPLAT_TREE_LOADING_SPINNER) {\n                    if (!finished && !splatOptimizingTaskId) {\n                        this.loadingSpinner.setMinimized(true, true);\n                        splatOptimizingTaskId = this.loadingSpinner.addTask('Optimizing data structures...');\n                    }\n                }\n            };\n            const onSplatTreeReady = (finished) => {\n                if (this.isDisposingOrDisposed()) return;\n                if (finished && splatOptimizingTaskId) {\n                    this.loadingSpinner.removeTask(splatOptimizingTaskId);\n                    splatOptimizingTaskId = null;\n                }\n            };\n            const buildResults = this.splatMesh.build(allSplatBuffers, allSplatBufferOptions, true, finalBuild, onSplatTreeIndexesUpload,\n                                                      onSplatTreeReady, preserveVisibleRegion);\n            if (finalBuild && this.freeIntermediateSplatData) this.splatMesh.freeIntermediateSplatData();\n            return buildResults;\n        };\n\n    }();\n\n    /**\n     * Set up the splat sorting web worker.\n     * @param {SplatMesh} splatMesh SplatMesh instance that contains the splats to be sorted\n     * @return {Promise}\n     */\n    setupSortWorker(splatMesh) {\n        if (this.isDisposingOrDisposed()) return;\n        return new Promise((resolve) => {\n            const DistancesArrayType = this.integerBasedSort ? Int32Array : Float32Array;\n            const splatCount = splatMesh.getSplatCount();\n            const maxSplatCount = splatMesh.getMaxSplatCount();\n            this.sortWorker = createSortWorker(maxSplatCount, this.sharedMemoryForWorkers, this.enableSIMDInSort,\n                                               this.integerBasedSort, this.splatMesh.dynamicMode, this.splatSortDistanceMapPrecision);\n            this.sortWorker.onmessage = (e) => {\n                if (e.data.sortDone) {\n                    this.sortRunning = false;\n                    if (this.sharedMemoryForWorkers) {\n                        this.splatMesh.updateRenderIndexes(this.sortWorkerSortedIndexes, e.data.splatRenderCount);\n                    } else {\n                        const sortedIndexes = new Uint32Array(e.data.sortedIndexes.buffer, 0, e.data.splatRenderCount);\n                        this.splatMesh.updateRenderIndexes(sortedIndexes, e.data.splatRenderCount);\n                    }\n\n                    this.lastSplatSortCount = this.splatSortCount;\n\n                    this.lastSortTime = e.data.sortTime;\n                    this.sortPromiseResolver();\n                    this.sortPromiseResolver = null;\n                    this.forceRenderNextFrame();\n                    if (this.runAfterNextSort.length > 0) {\n                        this.runAfterNextSort.forEach((func) => {\n                            func();\n                        });\n                        this.runAfterNextSort.length = 0;\n                    }\n                } else if (e.data.sortCanceled) {\n                    this.sortRunning = false;\n                } else if (e.data.sortSetupPhase1Complete) {\n                    if (this.logLevel >= LogLevel.Info) console.log('Sorting web worker WASM setup complete.');\n                    if (this.sharedMemoryForWorkers) {\n                        this.sortWorkerSortedIndexes = new Uint32Array(e.data.sortedIndexesBuffer,\n                                                                       e.data.sortedIndexesOffset, maxSplatCount);\n                        this.sortWorkerIndexesToSort = new Uint32Array(e.data.indexesToSortBuffer,\n                                                                       e.data.indexesToSortOffset, maxSplatCount);\n                        this.sortWorkerPrecomputedDistances = new DistancesArrayType(e.data.precomputedDistancesBuffer,\n                                                                                     e.data.precomputedDistancesOffset,\n                                                                                     maxSplatCount);\n                         this.sortWorkerTransforms = new Float32Array(e.data.transformsBuffer,\n                                                                      e.data.transformsOffset, Constants.MaxScenes * 16);\n                    } else {\n                        this.sortWorkerIndexesToSort = new Uint32Array(maxSplatCount);\n                        this.sortWorkerPrecomputedDistances = new DistancesArrayType(maxSplatCount);\n                        this.sortWorkerTransforms = new Float32Array(Constants.MaxScenes * 16);\n                    }\n                    for (let i = 0; i < splatCount; i++) this.sortWorkerIndexesToSort[i] = i;\n                    this.sortWorker.maxSplatCount = maxSplatCount;\n\n                    if (this.logLevel >= LogLevel.Info) {\n                        console.log('Sorting web worker ready.');\n                        const splatDataTextures = this.splatMesh.getSplatDataTextures();\n                        const covariancesTextureSize = splatDataTextures.covariances.size;\n                        const centersColorsTextureSize = splatDataTextures.centerColors.size;\n                        console.log('Covariances texture size: ' + covariancesTextureSize.x + ' x ' + covariancesTextureSize.y);\n                        console.log('Centers/colors texture size: ' + centersColorsTextureSize.x + ' x ' + centersColorsTextureSize.y);\n                    }\n\n                    resolve();\n                }\n            };\n        });\n    }\n\n    updateError(error, defaultMessage) {\n        if (error instanceof AbortedPromiseError) return error;\n        if (error instanceof DirectLoadError) {\n            return new Error('File type or server does not support progressive loading.');\n        }\n        return defaultMessage ? new Error(defaultMessage) : error;\n    }\n\n    disposeSortWorker() {\n        if (this.sortWorker) this.sortWorker.terminate();\n        this.sortWorker = null;\n        this.sortPromise = null;\n        if (this.sortPromiseResolver) {\n            this.sortPromiseResolver();\n            this.sortPromiseResolver = null;\n        }\n        this.preSortMessages = [];\n        this.sortRunning = false;\n    }\n\n    removeSplatScene(indexToRemove, showLoadingUI = true) {\n        return this.removeSplatScenes([indexToRemove], showLoadingUI);\n    }\n\n    removeSplatScenes(indexesToRemove, showLoadingUI = true) {\n        if (this.isLoadingOrUnloading()) {\n            throw new Error('Cannot remove splat scene while another load or unload is already in progress.');\n        }\n\n        if (this.isDisposingOrDisposed()) {\n            throw new Error('Cannot remove splat scene after dispose() is called.');\n        }\n\n        let sortPromise;\n\n        this.splatSceneRemovalPromise = new Promise((resolve, reject) => {\n            let revmovalTaskId;\n\n            if (showLoadingUI) {\n                this.loadingSpinner.removeAllTasks();\n                this.loadingSpinner.show();\n                revmovalTaskId = this.loadingSpinner.addTask('Removing splat scene...');\n            }\n\n            const checkAndHideLoadingUI = () => {\n                if (showLoadingUI) {\n                    this.loadingSpinner.hide();\n                    this.loadingSpinner.removeTask(revmovalTaskId);\n                }\n            };\n\n            const onDone = (error) => {\n                checkAndHideLoadingUI();\n                this.splatSceneRemovalPromise = null;\n                if (!error) resolve();\n                else reject(error);\n            };\n\n            const checkForEarlyExit = () => {\n                if (this.isDisposingOrDisposed()) {\n                    onDone();\n                    return true;\n                }\n                return false;\n            };\n\n            sortPromise = this.sortPromise || Promise.resolve();\n            sortPromise.then(() => {\n                if (checkForEarlyExit()) return;\n                const savedSplatBuffers = [];\n                const savedSceneOptions = [];\n                const savedSceneTransformComponents = [];\n                for (let i = 0; i < this.splatMesh.scenes.length; i++) {\n                    let shouldRemove = false;\n                    for (let indexToRemove of indexesToRemove) {\n                        if (indexToRemove === i) {\n                            shouldRemove = true;\n                            break;\n                        }\n                    }\n                    if (!shouldRemove) {\n                        const scene = this.splatMesh.scenes[i];\n                        savedSplatBuffers.push(scene.splatBuffer);\n                        savedSceneOptions.push(this.splatMesh.sceneOptions[i]);\n                        savedSceneTransformComponents.push({\n                            'position': scene.position.clone(),\n                            'quaternion': scene.quaternion.clone(),\n                            'scale': scene.scale.clone()\n                        });\n                    }\n                }\n                this.disposeSortWorker();\n                this.splatMesh.dispose();\n                this.sceneRevealMode = SceneRevealMode.Instant;\n                this.createSplatMesh();\n                this.addSplatBuffers(savedSplatBuffers, savedSceneOptions, true, false, true)\n                .then(() => {\n                    if (checkForEarlyExit()) return;\n                    checkAndHideLoadingUI();\n                    this.splatMesh.scenes.forEach((scene, index) => {\n                        scene.position.copy(savedSceneTransformComponents[index].position);\n                        scene.quaternion.copy(savedSceneTransformComponents[index].quaternion);\n                        scene.scale.copy(savedSceneTransformComponents[index].scale);\n                    });\n                    this.splatMesh.updateTransforms();\n                    this.splatRenderReady = false;\n\n                    this.runSplatSort(true)\n                    .then(() => {\n                        if (checkForEarlyExit()) {\n                            this.splatRenderReady = true;\n                            return;\n                        }\n                        sortPromise = this.sortPromise || Promise.resolve();\n                        sortPromise.then(() => {\n                            this.splatRenderReady = true;\n                            onDone();\n                        });\n                    });\n                })\n                .catch((e) => {\n                    onDone(e);\n                });\n            });\n        });\n\n        return this.splatSceneRemovalPromise;\n    }\n\n    /**\n     * Start self-driven mode\n     */\n    start() {\n        if (this.selfDrivenMode) {\n            if (this.webXRMode) {\n                this.renderer.setAnimationLoop(this.selfDrivenUpdateFunc);\n            } else {\n                this.requestFrameId = requestAnimationFrame(this.selfDrivenUpdateFunc);\n            }\n            this.selfDrivenModeRunning = true;\n        } else {\n            throw new Error('Cannot start viewer unless it is in self driven mode.');\n        }\n    }\n\n    /**\n     * Stop self-driven mode\n     */\n    stop() {\n        if (this.selfDrivenMode && this.selfDrivenModeRunning) {\n            if (this.webXRMode) {\n                this.renderer.setAnimationLoop(null);\n            } else {\n                cancelAnimationFrame(this.requestFrameId);\n            }\n            this.selfDrivenModeRunning = false;\n        }\n    }\n\n    /**\n     * Dispose of all resources held directly and indirectly by this viewer.\n     */\n    async dispose() {\n        if (this.isDisposingOrDisposed()) return this.disposePromise;\n\n        let waitPromises = [];\n        let promisesToAbort = [];\n        for (let promiseKey in this.splatSceneDownloadPromises) {\n            if (this.splatSceneDownloadPromises.hasOwnProperty(promiseKey)) {\n                const downloadPromiseToAbort = this.splatSceneDownloadPromises[promiseKey];\n                promisesToAbort.push(downloadPromiseToAbort);\n                waitPromises.push(downloadPromiseToAbort.promise);\n            }\n        }\n        if (this.sortPromise) {\n            waitPromises.push(this.sortPromise);\n        }\n\n        this.disposing = true;\n        this.disposePromise = Promise.all(waitPromises).finally(() => {\n            this.stop();\n            if (this.orthographicControls) {\n                this.orthographicControls.dispose();\n                this.orthographicControls = null;\n            }\n            if (this.perspectiveControls) {\n                this.perspectiveControls.dispose();\n                this.perspectiveControls = null;\n            }\n            this.controls = null;\n            if (this.splatMesh) {\n                this.splatMesh.dispose();\n                this.splatMesh = null;\n            }\n            if (this.sceneHelper) {\n                this.sceneHelper.dispose();\n                this.sceneHelper = null;\n            }\n            if (this.resizeObserver) {\n                this.resizeObserver.unobserve(this.rootElement);\n                this.resizeObserver = null;\n            }\n            this.disposeSortWorker();\n            this.removeEventHandlers();\n\n            this.loadingSpinner.removeAllTasks();\n            this.loadingSpinner.setContainer(null);\n            this.loadingProgressBar.hide();\n            this.loadingProgressBar.setContainer(null);\n            this.infoPanel.setContainer(null);\n\n            this.camera = null;\n            this.threeScene = null;\n            this.splatRenderReady = false;\n            this.initialized = false;\n            if (this.renderer) {\n                if (!this.usingExternalRenderer) {\n                    this.rootElement.removeChild(this.renderer.domElement);\n                    this.renderer.dispose();\n                }\n                this.renderer = null;\n            }\n\n            if (!this.usingExternalRenderer) {\n                document.body.removeChild(this.rootElement);\n            }\n\n            this.sortWorkerSortedIndexes = null;\n            this.sortWorkerIndexesToSort = null;\n            this.sortWorkerPrecomputedDistances = null;\n            this.sortWorkerTransforms = null;\n            this.disposed = true;\n            this.disposing = false;\n            this.disposePromise = null;\n        });\n        promisesToAbort.forEach((toAbort) => {\n            toAbort.abort('Scene disposed');\n        });\n        return this.disposePromise;\n    }\n\n    selfDrivenUpdate() {\n        if (this.selfDrivenMode && !this.webXRMode) {\n            this.requestFrameId = requestAnimationFrame(this.selfDrivenUpdateFunc);\n        }\n        this.update();\n        if (this.shouldRender()) {\n            this.render();\n            this.consecutiveRenderFrames++;\n        } else {\n            this.consecutiveRenderFrames = 0;\n        }\n        this.renderNextFrame = false;\n    }\n\n    forceRenderNextFrame() {\n        this.renderNextFrame = true;\n    }\n\n    shouldRender = function() {\n\n        let renderCount = 0;\n        const lastCameraPosition = new THREE.Vector3();\n        const lastCameraOrientation = new THREE.Quaternion();\n        const changeEpsilon = 0.0001;\n\n        return function() {\n            if (!this.initialized || !this.splatRenderReady || this.isDisposingOrDisposed()) return false;\n\n            let shouldRender = false;\n            let cameraChanged = false;\n            if (this.camera) {\n                const cp = this.camera.position;\n                const co = this.camera.quaternion;\n                cameraChanged = Math.abs(cp.x - lastCameraPosition.x) > changeEpsilon ||\n                                Math.abs(cp.y - lastCameraPosition.y) > changeEpsilon ||\n                                Math.abs(cp.z - lastCameraPosition.z) > changeEpsilon ||\n                                Math.abs(co.x - lastCameraOrientation.x) > changeEpsilon ||\n                                Math.abs(co.y - lastCameraOrientation.y) > changeEpsilon ||\n                                Math.abs(co.z - lastCameraOrientation.z) > changeEpsilon ||\n                                Math.abs(co.w - lastCameraOrientation.w) > changeEpsilon;\n            }\n\n            shouldRender = this.renderMode !== RenderMode.Never && (renderCount === 0 || this.splatMesh.visibleRegionChanging ||\n                           cameraChanged || this.renderMode === RenderMode.Always || this.dynamicMode === true || this.renderNextFrame);\n\n            if (this.camera) {\n                lastCameraPosition.copy(this.camera.position);\n                lastCameraOrientation.copy(this.camera.quaternion);\n            }\n\n            renderCount++;\n            return shouldRender;\n        };\n\n    }();\n\n    render = function() {\n\n        return function() {\n            if (!this.initialized || !this.splatRenderReady || this.isDisposingOrDisposed()) return;\n\n            const hasRenderables = (threeScene) => {\n                for (let child of threeScene.children) {\n                    if (child.visible) return true;\n                }\n                return false;\n            };\n\n            const savedAuoClear = this.renderer.autoClear;\n            if (hasRenderables(this.threeScene)) {\n                this.renderer.render(this.threeScene, this.camera);\n                this.renderer.autoClear = false;\n            }\n            this.renderer.render(this.splatMesh, this.camera);\n            this.renderer.autoClear = false;\n            if (this.sceneHelper.getFocusMarkerOpacity() > 0.0) this.renderer.render(this.sceneHelper.focusMarker, this.camera);\n            if (this.showControlPlane) this.renderer.render(this.sceneHelper.controlPlane, this.camera);\n            this.renderer.autoClear = savedAuoClear;\n        };\n\n    }();\n\n    update(renderer, camera) {\n        if (this.dropInMode) this.updateForDropInMode(renderer, camera);\n\n        if (!this.initialized || !this.splatRenderReady || this.isDisposingOrDisposed()) return;\n\n        if (this.controls) {\n            this.controls.update();\n            if (this.camera.isOrthographicCamera && !this.usingExternalCamera) {\n                Viewer.setCameraPositionFromZoom(this.camera, this.camera, this.controls);\n            }\n        }\n        this.runSplatSort();\n        this.updateForRendererSizeChanges();\n        this.updateSplatMesh();\n        this.updateMeshCursor();\n        this.updateFPS();\n        this.timingSensitiveUpdates();\n        this.updateInfoPanel();\n        this.updateControlPlane();\n    }\n\n    updateForDropInMode(renderer, camera) {\n        this.renderer = renderer;\n        if (this.splatMesh) this.splatMesh.setRenderer(this.renderer);\n        this.camera = camera;\n        if (this.controls) this.controls.object = camera;\n        this.init();\n    }\n\n    updateFPS = function() {\n\n        let lastCalcTime = getCurrentTime();\n        let frameCount = 0;\n\n        return function() {\n            if (this.consecutiveRenderFrames > CONSECUTIVE_RENDERED_FRAMES_FOR_FPS_CALCULATION) {\n                const currentTime = getCurrentTime();\n                const calcDelta = currentTime - lastCalcTime;\n                if (calcDelta >= 1.0) {\n                    this.currentFPS = frameCount;\n                    frameCount = 0;\n                    lastCalcTime = currentTime;\n                } else {\n                    frameCount++;\n                }\n            } else {\n                this.currentFPS = null;\n            }\n        };\n\n    }();\n\n    updateForRendererSizeChanges = function() {\n\n        const lastRendererSize = new THREE.Vector2();\n        const currentRendererSize = new THREE.Vector2();\n        let lastCameraOrthographic;\n\n        return function() {\n            if (!this.usingExternalCamera) {\n                this.renderer.getSize(currentRendererSize);\n                if (lastCameraOrthographic === undefined || lastCameraOrthographic !== this.camera.isOrthographicCamera ||\n                    currentRendererSize.x !== lastRendererSize.x || currentRendererSize.y !== lastRendererSize.y) {\n                    if (this.camera.isOrthographicCamera) {\n                        this.camera.left = -currentRendererSize.x / 2.0;\n                        this.camera.right = currentRendererSize.x / 2.0;\n                        this.camera.top = currentRendererSize.y / 2.0;\n                        this.camera.bottom = -currentRendererSize.y / 2.0;\n                    } else {\n                        this.camera.aspect = currentRendererSize.x / currentRendererSize.y;\n                    }\n                    this.camera.updateProjectionMatrix();\n                    lastRendererSize.copy(currentRendererSize);\n                    lastCameraOrthographic = this.camera.isOrthographicCamera;\n                }\n            }\n        };\n\n    }();\n\n    timingSensitiveUpdates = function() {\n\n        let lastUpdateTime;\n\n        return function() {\n            const currentTime = getCurrentTime();\n            if (!lastUpdateTime) lastUpdateTime = currentTime;\n            const timeDelta = currentTime - lastUpdateTime;\n\n            this.updateCameraTransition(currentTime);\n            this.updateFocusMarker(timeDelta);\n\n            lastUpdateTime = currentTime;\n        };\n\n    }();\n\n    updateCameraTransition = function() {\n\n        let tempCameraTarget = new THREE.Vector3();\n        let toPreviousTarget = new THREE.Vector3();\n        let toNextTarget = new THREE.Vector3();\n\n        return function(currentTime) {\n            if (this.transitioningCameraTarget) {\n                toPreviousTarget.copy(this.previousCameraTarget).sub(this.camera.position).normalize();\n                toNextTarget.copy(this.nextCameraTarget).sub(this.camera.position).normalize();\n                const rotationAngle = Math.acos(toPreviousTarget.dot(toNextTarget));\n                const rotationSpeed = rotationAngle / (Math.PI / 3) * .65 + .3;\n                const t = (rotationSpeed / rotationAngle * (currentTime - this.transitioningCameraTargetStartTime));\n                tempCameraTarget.copy(this.previousCameraTarget).lerp(this.nextCameraTarget, t);\n                this.camera.lookAt(tempCameraTarget);\n                this.controls.target.copy(tempCameraTarget);\n                if (t >= 1.0) {\n                    this.transitioningCameraTarget = false;\n                }\n            }\n        };\n\n    }();\n\n    updateFocusMarker = function() {\n\n        const renderDimensions = new THREE.Vector2();\n        let wasTransitioning = false;\n\n        return function(timeDelta) {\n            this.getRenderDimensions(renderDimensions);\n            if (this.transitioningCameraTarget) {\n                this.sceneHelper.setFocusMarkerVisibility(true);\n                const currentFocusMarkerOpacity = Math.max(this.sceneHelper.getFocusMarkerOpacity(), 0.0);\n                let newFocusMarkerOpacity = Math.min(currentFocusMarkerOpacity + FOCUS_MARKER_FADE_IN_SPEED * timeDelta, 1.0);\n                this.sceneHelper.setFocusMarkerOpacity(newFocusMarkerOpacity);\n                this.sceneHelper.updateFocusMarker(this.nextCameraTarget, this.camera, renderDimensions);\n                wasTransitioning = true;\n                this.forceRenderNextFrame();\n            } else {\n                let currentFocusMarkerOpacity;\n                if (wasTransitioning) currentFocusMarkerOpacity = 1.0;\n                else currentFocusMarkerOpacity = Math.min(this.sceneHelper.getFocusMarkerOpacity(), 1.0);\n                if (currentFocusMarkerOpacity > 0) {\n                    this.sceneHelper.updateFocusMarker(this.nextCameraTarget, this.camera, renderDimensions);\n                    let newFocusMarkerOpacity = Math.max(currentFocusMarkerOpacity - FOCUS_MARKER_FADE_OUT_SPEED * timeDelta, 0.0);\n                    this.sceneHelper.setFocusMarkerOpacity(newFocusMarkerOpacity);\n                    if (newFocusMarkerOpacity === 0.0) this.sceneHelper.setFocusMarkerVisibility(false);\n                }\n                if (currentFocusMarkerOpacity > 0.0) this.forceRenderNextFrame();\n                wasTransitioning = false;\n            }\n        };\n\n    }();\n\n    updateMeshCursor = function() {\n\n        const outHits = [];\n        const renderDimensions = new THREE.Vector2();\n\n        return function() {\n            if (this.showMeshCursor) {\n                this.forceRenderNextFrame();\n                this.getRenderDimensions(renderDimensions);\n                outHits.length = 0;\n                this.raycaster.setFromCameraAndScreenPosition(this.camera, this.mousePosition, renderDimensions);\n                this.raycaster.intersectSplatMesh(this.splatMesh, outHits);\n                if (outHits.length > 0) {\n                    this.sceneHelper.setMeshCursorVisibility(true);\n                    this.sceneHelper.positionAndOrientMeshCursor(outHits[0].origin, this.camera);\n                } else {\n                    this.sceneHelper.setMeshCursorVisibility(false);\n                }\n            } else {\n                if (this.sceneHelper.getMeschCursorVisibility()) this.forceRenderNextFrame();\n                this.sceneHelper.setMeshCursorVisibility(false);\n            }\n        };\n\n    }();\n\n    updateInfoPanel = function() {\n\n        const renderDimensions = new THREE.Vector2();\n\n        return function() {\n            if (!this.showInfo) return;\n            const splatCount = this.splatMesh.getSplatCount();\n            this.getRenderDimensions(renderDimensions);\n            const cameraLookAtPosition = this.controls ? this.controls.target : null;\n            const meshCursorPosition = this.showMeshCursor ? this.sceneHelper.meshCursor.position : null;\n            const splatRenderCountPct = splatCount > 0 ? this.splatRenderCount / splatCount * 100 : 0;\n            this.infoPanel.update(renderDimensions, this.camera.position, cameraLookAtPosition,\n                                  this.camera.up, this.camera.isOrthographicCamera, meshCursorPosition,\n                                  this.currentFPS || 'N/A', splatCount, this.splatRenderCount, splatRenderCountPct,\n                                  this.lastSortTime, this.focalAdjustment, this.splatMesh.getSplatScale(),\n                                  this.splatMesh.getPointCloudModeEnabled());\n        };\n\n    }();\n\n    updateControlPlane() {\n        if (this.showControlPlane) {\n            this.sceneHelper.setControlPlaneVisibility(true);\n            this.sceneHelper.positionAndOrientControlPlane(this.controls.target, this.camera.up);\n        } else {\n            this.sceneHelper.setControlPlaneVisibility(false);\n        }\n    }\n\n    runSplatSort = function() {\n\n        const mvpMatrix = new THREE.Matrix4();\n        const cameraPositionArray = [];\n        const lastSortViewDir = new THREE.Vector3(0, 0, -1);\n        const sortViewDir = new THREE.Vector3(0, 0, -1);\n        const lastSortViewPos = new THREE.Vector3();\n        const sortViewOffset = new THREE.Vector3();\n        const queuedSorts = [];\n\n        const partialSorts = [\n            {\n                'angleThreshold': 0.55,\n                'sortFractions': [0.125, 0.33333, 0.75]\n            },\n            {\n                'angleThreshold': 0.65,\n                'sortFractions': [0.33333, 0.66667]\n            },\n            {\n                'angleThreshold': 0.8,\n                'sortFractions': [0.5]\n            }\n        ];\n\n        return function(force = false, forceSortAll = false) {\n            if (!this.initialized) return Promise.resolve(false);\n            if (this.sortRunning) return Promise.resolve(true);\n            if (this.splatMesh.getSplatCount() <= 0) {\n                this.splatRenderCount = 0;\n                return Promise.resolve(false);\n            }\n\n            let angleDiff = 0;\n            let positionDiff = 0;\n            let needsRefreshForRotation = false;\n            let needsRefreshForPosition = false;\n\n            sortViewDir.set(0, 0, -1).applyQuaternion(this.camera.quaternion);\n            angleDiff = sortViewDir.dot(lastSortViewDir);\n            positionDiff = sortViewOffset.copy(this.camera.position).sub(lastSortViewPos).length();\n\n            if (!force) {\n                if (!this.splatMesh.dynamicMode && queuedSorts.length === 0) {\n                    if (angleDiff <= 0.99) needsRefreshForRotation = true;\n                    if (positionDiff >= 1.0) needsRefreshForPosition = true;\n                    if (!needsRefreshForRotation && !needsRefreshForPosition) return Promise.resolve(false);\n                }\n            }\n\n            this.sortRunning = true;\n            let { splatRenderCount, shouldSortAll } = this.gatherSceneNodesForSort();\n            shouldSortAll = shouldSortAll || forceSortAll;\n            this.splatRenderCount = splatRenderCount;\n\n            mvpMatrix.copy(this.camera.matrixWorld).invert();\n            const mvpCamera = this.perspectiveCamera || this.camera;\n            mvpMatrix.premultiply(mvpCamera.projectionMatrix);\n            if (!this.splatMesh.dynamicMode) mvpMatrix.multiply(this.splatMesh.matrixWorld);\n\n            let gpuAcceleratedSortPromise = Promise.resolve(true);\n            if (this.gpuAcceleratedSort && (queuedSorts.length <= 1 || queuedSorts.length % 2 === 0)) {\n                gpuAcceleratedSortPromise = this.splatMesh.computeDistancesOnGPU(mvpMatrix, this.sortWorkerPrecomputedDistances);\n            }\n\n            gpuAcceleratedSortPromise.then(() => {\n                if (queuedSorts.length === 0) {\n                    if (this.splatMesh.dynamicMode || shouldSortAll) {\n                        queuedSorts.push(this.splatRenderCount);\n                    } else {\n                            for (let partialSort of partialSorts) {\n                            if (angleDiff < partialSort.angleThreshold) {\n                                for (let sortFraction of partialSort.sortFractions) {\n                                    queuedSorts.push(Math.floor(this.splatRenderCount * sortFraction));\n                                }\n                                break;\n                            }\n                        }\n                        queuedSorts.push(this.splatRenderCount);\n                    }\n                }\n                let sortCount = Math.min(queuedSorts.shift(), this.splatRenderCount);\n                this.splatSortCount = sortCount;\n\n                cameraPositionArray[0] = this.camera.position.x;\n                cameraPositionArray[1] = this.camera.position.y;\n                cameraPositionArray[2] = this.camera.position.z;\n\n                const sortMessage = {\n                    'modelViewProj': mvpMatrix.elements,\n                    'cameraPosition': cameraPositionArray,\n                    'splatRenderCount': this.splatRenderCount,\n                    'splatSortCount': sortCount,\n                    'usePrecomputedDistances': this.gpuAcceleratedSort\n                };\n                if (this.splatMesh.dynamicMode) {\n                    this.splatMesh.fillTransformsArray(this.sortWorkerTransforms);\n                }\n                if (!this.sharedMemoryForWorkers) {\n                    sortMessage.indexesToSort = this.sortWorkerIndexesToSort;\n                    sortMessage.transforms = this.sortWorkerTransforms;\n                    if (this.gpuAcceleratedSort) {\n                        sortMessage.precomputedDistances = this.sortWorkerPrecomputedDistances;\n                    }\n                }\n\n                this.sortPromise = new Promise((resolve) => {\n                    this.sortPromiseResolver = resolve;\n                });\n\n                if (this.preSortMessages.length > 0) {\n                    this.preSortMessages.forEach((message) => {\n                        this.sortWorker.postMessage(message);\n                    });\n                    this.preSortMessages = [];\n                }\n                this.sortWorker.postMessage({\n                    'sort': sortMessage\n                });\n\n                if (queuedSorts.length === 0) {\n                    lastSortViewPos.copy(this.camera.position);\n                    lastSortViewDir.copy(sortViewDir);\n                }\n\n                return true;\n            });\n\n            return gpuAcceleratedSortPromise;\n        };\n\n    }();\n\n    /**\n     * Determine which splats to render by checking which are inside or close to the view frustum\n     */\n    gatherSceneNodesForSort = function() {\n\n        const nodeRenderList = [];\n        let allSplatsSortBuffer = null;\n        const tempVectorYZ = new THREE.Vector3();\n        const tempVectorXZ = new THREE.Vector3();\n        const tempVector = new THREE.Vector3();\n        const modelView = new THREE.Matrix4();\n        const baseModelView = new THREE.Matrix4();\n        const sceneTransform = new THREE.Matrix4();\n        const renderDimensions = new THREE.Vector3();\n        const forward = new THREE.Vector3(0, 0, -1);\n\n        const tempMax = new THREE.Vector3();\n        const nodeSize = (node) => {\n            return tempMax.copy(node.max).sub(node.min).length();\n        };\n\n        return function(gatherAllNodes = false) {\n\n            this.getRenderDimensions(renderDimensions);\n            const cameraFocalLength = (renderDimensions.y / 2.0) / Math.tan(this.camera.fov / 2.0 * THREE.MathUtils.DEG2RAD);\n            const fovXOver2 = Math.atan(renderDimensions.x / 2.0 / cameraFocalLength);\n            const fovYOver2 = Math.atan(renderDimensions.y / 2.0 / cameraFocalLength);\n            const cosFovXOver2 = Math.cos(fovXOver2);\n            const cosFovYOver2 = Math.cos(fovYOver2);\n\n            const splatTree = this.splatMesh.getSplatTree();\n\n            if (splatTree) {\n                baseModelView.copy(this.camera.matrixWorld).invert();\n                if (!this.splatMesh.dynamicMode) baseModelView.multiply(this.splatMesh.matrixWorld);\n\n                let nodeRenderCount = 0;\n                let splatRenderCount = 0;\n\n                for (let s = 0; s < splatTree.subTrees.length; s++) {\n                    const subTree = splatTree.subTrees[s];\n                    modelView.copy(baseModelView);\n                    if (this.splatMesh.dynamicMode) {\n                        this.splatMesh.getSceneTransform(s, sceneTransform);\n                        modelView.multiply(sceneTransform);\n                    }\n                    const nodeCount = subTree.nodesWithIndexes.length;\n                    for (let i = 0; i < nodeCount; i++) {\n                        const node = subTree.nodesWithIndexes[i];\n                        if (!node.data || !node.data.indexes || node.data.indexes.length === 0) continue;\n                        tempVector.copy(node.center).applyMatrix4(modelView);\n\n                        const distanceToNode = tempVector.length();\n                        tempVector.normalize();\n\n                        tempVectorYZ.copy(tempVector).setX(0).normalize();\n                        tempVectorXZ.copy(tempVector).setY(0).normalize();\n\n                        const cameraAngleXZDot = forward.dot(tempVectorXZ);\n                        const cameraAngleYZDot = forward.dot(tempVectorYZ);\n\n                        const ns = nodeSize(node);\n                        const outOfFovY = cameraAngleYZDot < (cosFovYOver2 - .6);\n                        const outOfFovX = cameraAngleXZDot < (cosFovXOver2 - .6);\n                        if (!gatherAllNodes && ((outOfFovX || outOfFovY) && distanceToNode > ns)) {\n                            continue;\n                        }\n                        splatRenderCount += node.data.indexes.length;\n                        nodeRenderList[nodeRenderCount] = node;\n                        node.data.distanceToNode = distanceToNode;\n                        nodeRenderCount++;\n                    }\n                }\n\n                nodeRenderList.length = nodeRenderCount;\n                nodeRenderList.sort((a, b) => {\n                    if (a.data.distanceToNode < b.data.distanceToNode) return -1;\n                    else return 1;\n                });\n\n                let currentByteOffset = splatRenderCount * Constants.BytesPerInt;\n                for (let i = 0; i < nodeRenderCount; i++) {\n                    const node = nodeRenderList[i];\n                    const windowSizeInts = node.data.indexes.length;\n                    const windowSizeBytes = windowSizeInts * Constants.BytesPerInt;\n                    let destView = new Uint32Array(this.sortWorkerIndexesToSort.buffer,\n                                                   currentByteOffset - windowSizeBytes, windowSizeInts);\n                    destView.set(node.data.indexes);\n                    currentByteOffset -= windowSizeBytes;\n                }\n\n                return {\n                    'splatRenderCount': splatRenderCount,\n                    'shouldSortAll': false\n                };\n            } else {\n                const totalSplatCount = this.splatMesh.getSplatCount();\n                if (!allSplatsSortBuffer || allSplatsSortBuffer.length !== totalSplatCount) {\n                    allSplatsSortBuffer = new Uint32Array(totalSplatCount);\n                    for (let i = 0; i < totalSplatCount; i++) {\n                        allSplatsSortBuffer[i] = i;\n                    }\n                }\n                this.sortWorkerIndexesToSort.set(allSplatsSortBuffer);\n                return {\n                    'splatRenderCount': totalSplatCount,\n                    'shouldSortAll': true\n                };\n            }\n        };\n\n    }();\n\n    getSplatMesh() {\n        return this.splatMesh;\n    }\n\n    /**\n     * Get a reference to a splat scene.\n     * @param {number} sceneIndex The index of the scene to which the reference will be returned\n     * @return {SplatScene}\n     */\n    getSplatScene(sceneIndex) {\n        return this.splatMesh.getScene(sceneIndex);\n    }\n\n    getSceneCount() {\n        return this.splatMesh.getSceneCount();\n    }\n\n    isMobile() {\n        return navigator.userAgent.includes('Mobi');\n    }\n}\n","\u0000asm\u0001\u0000\u0000\u0000\u0000\u000f\bdylink.0\u0001\u0004\u0000\u0000\u0000\u0000\u0001\u0017\u0002`\u0000\u0000`\u0010\u0000\u0002\u000f\u0001\u0003env\u0006memory\u0002\u0000\u0000\u0003\u0003\u0002\u0000\u0001\u0007>\u0003\u0011__wasm_call_ctors\u0000\u0000\u0018__wasm_apply_data_relocs\u0000\u0000\u000bsortIndexes\u0000\u0001\n�\u000f\u0002\u0002\u0000\u000b�\u000f\u0004\u0001|\u0003{\u0007}\u0003 \u000b \nk!\f\u0002@\u0002@ \u000e\u0004@ \r\u0004@A����\u0007!\nA����x!\r \u000b \fM\r\u0003 \f!\u0005\u0003@ \u0003 \u0005A\u0002t\"\u0001j \u0002 \u0000 \u0001j(\u0002\u0000A\u0002tj(\u0002\u0000\"\u00016\u0002\u0000 \u0001 \n \u0001 \nH\u001b!\n \u0001 \r \u0001 \rJ\u001b!\r \u0005A\u0001j\"\u0005 \u000bG\r\u0000\u000b\f\u0003\u000b \u000f\u0004@ \u000b \fM\r\u0002A!\u000fA����\u0007!\nA����x!\r \f!\u0002\u0003@ \u000f \u0007 \u0000 \u0002A\u0002t\"\u001cj(\u0002\u0000\"\u001dA\u0002tj(\u0002\u0000\"\u001bG\u0004@\u0002 \u0005�\t\u00028 \b \u001bA\u0006tj\"\u000e�\t\u0002\f \u000e*\u0002\u001c� \u0001 \u000e*\u0002,� \u0002 \u000e*\u0002<� \u0003��\u0001 \u0005�\t\u0002( \u000e�\t\u0002\b \u000e*\u0002\u0018� \u0001 \u000e*\u0002(� \u0002 \u000e*\u00028� \u0003��\u0001 \u0005�\t\u0002\b \u000e�\t\u0002\u0000 \u000e*\u0002\u0010� \u0001 \u000e*\u0002 � \u0002 \u000e*\u00020� \u0003��\u0001 \u0005�\t\u0002\u0018 \u000e�\t\u0002\u0004 \u000e*\u0002\u0014� \u0001 \u000e*\u0002$� \u0002 \u000e*\u00024� \u0003��\u0001��\u0001��\u0001��\u0001\"\u0011�_�\f\u0000\u0000\u0000\u0000\u0000@�@\u0000\u0000\u0000\u0000\u0000@�@\"\u0012��\u0001\"\u0013�!\u0001\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b!\u000e\u0002 \u0013�!\u0000\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b�\u0011 \u000e�\u001c\u0001\u0002 \u0011 \u0011�\r\b\t\n\u000b\f\r\u000e\u000f\u0000\u0001\u0002\u0003\u0000\u0001\u0002\u0003�_ \u0012��\u0001\"\u0011�!\u0000\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b�\u001c\u0002\u0002 \u0011�!\u0001\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b�\u001c\u0003!\u0012 \u001b!\u000f\u000b \u0003 \u001cj \u0001 \u001dA\u0004tj�\u0000\u0000\u0000 \u0012��\u0001\"\u0011�\u001b\u0000 \u0011�\u001b\u0001j \u0011�\u001b\u0002j \u0011�\u001b\u0003j\"\u000e6\u0002\u0000 \u000e \n \n \u000eJ\u001b!\n \u000e \r \r \u000eH\u001b!\r \u0002A\u0001j\"\u0002 \u000bG\r\u0000\u000b\f\u0003\u000b\u0002 \u0005*\u0002\b��\u0014 \u0005*\u0002\u0018��\"\u0001�\f\u0000\u0000\u0000\u0000\u0000@�@\u0000\u0000\u0000\u0000\u0000@�@��\u0001\"\u0011�!\u0001\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b!\u000e\u0002 \u0011�!\u0000\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b\u0002 \u0005*\u0002(�D\u0000\u0000\u0000\u0000\u0000@�@�\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b!\u0005A����\u0007!\nA����x!\r \u000b \fM\r\u0002�\u0011 \u000e�\u001c\u0001 \u0005�\u001c\u0002!\u0012 \f!\u0005\u0003@ \u0003 \u0005A\u0002t\"\u0002j \u0001 \u0000 \u0002j(\u0002\u0000A\u0004tj�\u0000\u0000\u0000 \u0012��\u0001\"\u0011�\u001b\u0000 \u0011�\u001b\u0001j \u0011�\u001b\u0002j\"\u00026\u0002\u0000 \u0002 \n \u0002 \nH\u001b!\n \u0002 \r \u0002 \rJ\u001b!\r \u0005A\u0001j\"\u0005 \u000bG\r\u0000\u000b\f\u0002\u000b \r\u0004@A����\u0007!\nA����x!\r \u000b \fM\r\u0002 \f!\u0005\u0003@ \u0003 \u0005A\u0002t\"\u0001j\u0002 \u0002 \u0000 \u0001j(\u0002\u0000A\u0002tj*\u0002\u0000�D\u0000\u0000\u0000\u0000\u0000\u0000�@�\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b\"\u000e6\u0002\u0000 \n \u000e \n \u000eH\u001b!\n \r \u000e \r \u000eJ\u001b!\r \u0005A\u0001j\"\u0005 \u000bG\r\u0000\u000b\f\u0002\u000b \u000fE\u0004@ \u000b \fM\r\u0001 \u0005*\u0002(!\u0014 \u0005*\u0002\u0018!\u0015 \u0005*\u0002\b!\u0016A����\u0007!\nA����x!\r \f!\u0005\u0003@\u0002 \u0014 \u0001 \u0000 \u0005A\u0002t\"\u0007j(\u0002\u0000A\u0004tj\"\u0002*\u0002\b� \u0016 \u0002*\u0002\u0000� \u0015 \u0002*\u0002\u0004����D\u0000\u0000\u0000\u0000\u0000\u0000�@�\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b!\u000e \u0003 \u0007j \u000e6\u0002\u0000 \n \u000e \n \u000eH\u001b!\n \r \u000e \r \u000eJ\u001b!\r \u0005A\u0001j\"\u0005 \u000bG\r\u0000\u000b\f\u0002\u000b \u000b \fM\r\u0000A!\u000fA����\u0007!\nA����x!\r \f!\u0002\u0003@ \u000f \u0007 \u0000 \u0002A\u0002t\"\u001bj(\u0002\u0000A\u0002t\"\u001cj(\u0002\u0000\"\u000eG\u0004@ \u0005*\u00028\"\u0014 \b \u000eA\u0006tj\"\u000f*\u0002<� \u0005*\u0002(\"\u0015 \u000f*\u00028� \u0005*\u0002\b\"\u0016 \u000f*\u00020� \u0005*\u0002\u0018\"\u0017 \u000f*\u00024����!\u0018 \u0014 \u000f*\u0002,� \u0015 \u000f*\u0002(� \u0016 \u000f*\u0002 � \u0017 \u000f*\u0002$����!\u0019 \u0014 \u000f*\u0002\u001c� \u0015 \u000f*\u0002\u0018� \u0016 \u000f*\u0002\u0010� \u0017 \u000f*\u0002\u0014����!\u001a \u0014 \u000f*\u0002\f� \u0015 \u000f*\u0002\b� \u0016 \u000f*\u0002\u0000� \u0017 \u000f*\u0002\u0004����!\u0014 \u000e!\u000f\u000b \u0003 \u001bj\u0002 \u0018 \u0001 \u001cA\u0002tj\"\u000e*\u0002\f� \u0019 \u000e*\u0002\b� \u0014 \u000e*\u0002\u0000� \u001a \u000e*\u0002\u0004�����D\u0000\u0000\u0000\u0000\u0000\u0000�@�\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b\"\u000e6\u0002\u0000 \n \u000e \n \u000eH\u001b!\n \r \u000e \r \u000eJ\u001b!\r \u0002A\u0001j\"\u0002 \u000bG\r\u0000\u000b\f\u0001\u000bA����x!\rA����\u0007!\n\u000b \u000b \fK\u0004@ \tA\u0001k� \r� \n���!\u0014 \f!\r\u0003@\u0002 \u0014 \u0003 \rA\u0002tj\"\u0001(\u0002\u0000 \nk��\"\u0015�C\u0000\u0000\u0000O]\u0004@ \u0015�\f\u0001\u000bA����x\u000b!\u000e \u0001 \u000e6\u0002\u0000 \u0004 \u000eA\u0002tj\"\u0001 \u0001(\u0002\u0000A\u0001j6\u0002\u0000 \rA\u0001j\"\r \u000bG\r\u0000\u000b\u000b \tA\u0002O\u0004@ \u0004(\u0002\u0000!\rA\u0001!\n\u0003@ \u0004 \nA\u0002tj\"\u0001 \u0001(\u0002\u0000 \rj\"\r6\u0002\u0000 \nA\u0001j\"\n \tG\r\u0000\u000b\u000b \fA\u0000J\u0004@ \f!\n\u0003@ \u0006 \nA\u0001k\"\u0001A\u0002t\"\u0002j \u0000 \u0002j(\u0002\u00006\u0002\u0000 \nA\u0001K \u0001!\n\r\u0000\u000b\u000b \u000b \fJ\u0004@ \u000b!\n\u0003@ \u0006 \u000b \u0004 \u0003 \nA\u0001k\"\nA\u0002t\"\u0001j(\u0002\u0000A\u0002tj\"\u0002(\u0002\u0000\"\u0005kA\u0002tj \u0000 \u0001j(\u0002\u00006\u0002\u0000 \u0002 \u0005A\u0001k6\u0002\u0000 \n \fJ\r\u0000\u000b\u000b\u000b","\u0000asm\u0001\u0000\u0000\u0000\u0000\u000f\bdylink.0\u0001\u0004\u0000\u0000\u0000\u0000\u0001\u0017\u0002`\u0000\u0000`\u0010\u0000\u0002\u000f\u0001\u0003env\u0006memory\u0002\u0000\u0000\u0003\u0003\u0002\u0000\u0001\u0007>\u0003\u0011__wasm_call_ctors\u0000\u0000\u0018__wasm_apply_data_relocs\u0000\u0000\u000bsortIndexes\u0000\u0001\n�\u000f\u0002\u0002\u0000\u000b�\u000f\u0003\u0001|\u0007}\u0006 \u000b \nk!\f\u0002@\u0002@ \u000e\u0004@ \r\u0004@A����\u0007!\nA����x!\r \u000b \fM\r\u0003 \f!\u0005\u0003@ \u0003 \u0005A\u0002t\"\u0001j \u0002 \u0000 \u0001j(\u0002\u0000A\u0002tj(\u0002\u0000\"\u00016\u0002\u0000 \u0001 \n \u0001 \nH\u001b!\n \u0001 \r \u0001 \rJ\u001b!\r \u0005A\u0001j\"\u0005 \u000bG\r\u0000\u000b\f\u0003\u000b \u000f\u0004@ \u000b \fM\r\u0002A!\u000fA����\u0007!\nA����x!\r \f!\u0002\u0003@ \u000f \u0007 \u0000 \u0002A\u0002t\"\u001aj(\u0002\u0000A\u0002t\"\u001bj(\u0002\u0000\"\u000eG\u0004@\u0002 \u0005*\u00028\"\u0011 \b \u000eA\u0006tj\"\u000f*\u0002<� \u0005*\u0002(\"\u0012 \u000f*\u00028� \u0005*\u0002\b\"\u0013 \u000f*\u00020� \u0005*\u0002\u0018\"\u0014 \u000f*\u00024�����D\u0000\u0000\u0000\u0000\u0000@�@�\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b!\u0018\u0002 \u0011 \u000f*\u0002,� \u0012 \u000f*\u0002(� \u0013 \u000f*\u0002 � \u0014 \u000f*\u0002$�����D\u0000\u0000\u0000\u0000\u0000@�@�\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b!\u0019\u0002 \u0011 \u000f*\u0002\u001c� \u0012 \u000f*\u0002\u0018� \u0013 \u000f*\u0002\u0010� \u0014 \u000f*\u0002\u0014�����D\u0000\u0000\u0000\u0000\u0000@�@�\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b!\u001c\u0002 \u0011 \u000f*\u0002\f� \u0012 \u000f*\u0002\b� \u0013 \u000f*\u0002\u0000� \u0014 \u000f*\u0002\u0004�����D\u0000\u0000\u0000\u0000\u0000@�@�\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b!\u001d \u000e!\u000f\u000b \u0003 \u001aj \u0001 \u001bA\u0002tj\"\u000e(\u0002\u0004 \u001cl \u000e(\u0002\u0000 \u001dlj \u000e(\u0002\b \u0019lj \u000e(\u0002\f \u0018lj\"\u000e6\u0002\u0000 \u000e \n \n \u000eJ\u001b!\n \u000e \r \r \u000eH\u001b!\r \u0002A\u0001j\"\u0002 \u000bG\r\u0000\u000b\f\u0003\u000b\u0002 \u0005*\u0002(�D\u0000\u0000\u0000\u0000\u0000@�@�\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b!\u0002\u0002 \u0005*\u0002\u0018�D\u0000\u0000\u0000\u0000\u0000@�@�\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b!\u0007 \u000b \fM\u0002 \u0005*\u0002\b�D\u0000\u0000\u0000\u0000\u0000@�@�\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b!\u000fA����\u0007!\nA����x!\r\r\u0002 \f!\u0005\u0003@ \u0003 \u0005A\u0002t\"\bj \u0001 \u0000 \bj(\u0002\u0000A\u0004tj\"\b(\u0002\u0004 \u0007l \b(\u0002\u0000 \u000flj \b(\u0002\b \u0002lj\"\b6\u0002\u0000 \b \n \b \nH\u001b!\n \b \r \b \rJ\u001b!\r \u0005A\u0001j\"\u0005 \u000bG\r\u0000\u000b\f\u0002\u000b \r\u0004@A����\u0007!\nA����x!\r \u000b \fM\r\u0002 \f!\u0005\u0003@ \u0003 \u0005A\u0002t\"\u0001j\u0002 \u0002 \u0000 \u0001j(\u0002\u0000A\u0002tj*\u0002\u0000�D\u0000\u0000\u0000\u0000\u0000\u0000�@�\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b\"\u000e6\u0002\u0000 \n \u000e \n \u000eH\u001b!\n \r \u000e \r \u000eJ\u001b!\r \u0005A\u0001j\"\u0005 \u000bG\r\u0000\u000b\f\u0002\u000b \u000fE\u0004@ \u000b \fM\r\u0001 \u0005*\u0002(!\u0011 \u0005*\u0002\u0018!\u0012 \u0005*\u0002\b!\u0013A����\u0007!\nA����x!\r \f!\u0005\u0003@\u0002 \u0011 \u0001 \u0000 \u0005A\u0002t\"\u0007j(\u0002\u0000A\u0004tj\"\u0002*\u0002\b� \u0013 \u0002*\u0002\u0000� \u0012 \u0002*\u0002\u0004����D\u0000\u0000\u0000\u0000\u0000\u0000�@�\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b!\u000e \u0003 \u0007j \u000e6\u0002\u0000 \n \u000e \n \u000eH\u001b!\n \r \u000e \r \u000eJ\u001b!\r \u0005A\u0001j\"\u0005 \u000bG\r\u0000\u000b\f\u0002\u000b \u000b \fM\r\u0000A!\u000fA����\u0007!\nA����x!\r \f!\u0002\u0003@ \u000f \u0007 \u0000 \u0002A\u0002t\"\u0018j(\u0002\u0000A\u0002t\"\u0019j(\u0002\u0000\"\u000eG\u0004@ \u0005*\u00028\"\u0011 \b \u000eA\u0006tj\"\u000f*\u0002<� \u0005*\u0002(\"\u0012 \u000f*\u00028� \u0005*\u0002\b\"\u0013 \u000f*\u00020� \u0005*\u0002\u0018\"\u0014 \u000f*\u00024����!\u0015 \u0011 \u000f*\u0002,� \u0012 \u000f*\u0002(� \u0013 \u000f*\u0002 � \u0014 \u000f*\u0002$����!\u0016 \u0011 \u000f*\u0002\u001c� \u0012 \u000f*\u0002\u0018� \u0013 \u000f*\u0002\u0010� \u0014 \u000f*\u0002\u0014����!\u0017 \u0011 \u000f*\u0002\f� \u0012 \u000f*\u0002\b� \u0013 \u000f*\u0002\u0000� \u0014 \u000f*\u0002\u0004����!\u0011 \u000e!\u000f\u000b \u0003 \u0018j\u0002 \u0015 \u0001 \u0019A\u0002tj\"\u000e*\u0002\f� \u0016 \u000e*\u0002\b� \u0011 \u000e*\u0002\u0000� \u0017 \u000e*\u0002\u0004�����D\u0000\u0000\u0000\u0000\u0000\u0000�@�\"\u0010�D\u0000\u0000\u0000\u0000\u0000\u0000�Ac\u0004@ \u0010�\f\u0001\u000bA����x\u000b\"\u000e6\u0002\u0000 \n \u000e \n \u000eH\u001b!\n \r \u000e \r \u000eJ\u001b!\r \u0002A\u0001j\"\u0002 \u000bG\r\u0000\u000b\f\u0001\u000bA����x!\rA����\u0007!\n\u000b \u000b \fK\u0004@ \tA\u0001k� \r� \n���!\u0011 \f!\r\u0003@\u0002 \u0011 \u0003 \rA\u0002tj\"\u0001(\u0002\u0000 \nk��\"\u0012�C\u0000\u0000\u0000O]\u0004@ \u0012�\f\u0001\u000bA����x\u000b!\u000e \u0001 \u000e6\u0002\u0000 \u0004 \u000eA\u0002tj\"\u0001 \u0001(\u0002\u0000A\u0001j6\u0002\u0000 \rA\u0001j\"\r \u000bG\r\u0000\u000b\u000b \tA\u0002O\u0004@ \u0004(\u0002\u0000!\rA\u0001!\n\u0003@ \u0004 \nA\u0002tj\"\u0001 \u0001(\u0002\u0000 \rj\"\r6\u0002\u0000 \nA\u0001j\"\n \tG\r\u0000\u000b\u000b \fA\u0000J\u0004@ \f!\n\u0003@ \u0006 \nA\u0001k\"\u0001A\u0002t\"\u0002j \u0000 \u0002j(\u0002\u00006\u0002\u0000 \nA\u0001K \u0001!\n\r\u0000\u000b\u000b \u000b \fJ\u0004@ \u000b!\n\u0003@ \u0006 \u000b \u0004 \u0003 \nA\u0001k\"\nA\u0002t\"\u0001j(\u0002\u0000A\u0002tj\"\u0002(\u0002\u0000\"\u0005kA\u0002tj \u0000 \u0001j(\u0002\u00006\u0002\u0000 \u0002 \u0005A\u0001k6\u0002\u0000 \n \fJ\r\u0000\u000b\u000b\u000b","import * as THREE from 'three';\nimport { Viewer } from './Viewer.js';\n\n/**\n * DropInViewer: Wrapper for a Viewer instance that enables it to be added to a Three.js scene like\n * any other Three.js scene object (Mesh, Object3D, etc.)\n */\nexport class DropInViewer extends THREE.Group {\n\n    constructor(options = {}) {\n        super();\n\n        options.selfDrivenMode = false;\n        options.useBuiltInControls = false;\n        options.rootElement = null;\n        options.dropInMode = true;\n        options.camera = undefined;\n        options.renderer = undefined;\n\n        this.viewer = new Viewer(options);\n        this.splatMesh = null;\n        this.updateSplatMesh();\n\n        this.callbackMesh = DropInViewer.createCallbackMesh();\n        this.add(this.callbackMesh);\n        this.callbackMesh.onBeforeRender = DropInViewer.onBeforeRender.bind(this, this.viewer);\n\n        this.viewer.onSplatMeshChanged(() => {\n            this.updateSplatMesh();\n        });\n\n    }\n\n    updateSplatMesh() {\n        if (this.splatMesh !== this.viewer.splatMesh) {\n            if (this.splatMesh) {\n                this.remove(this.splatMesh);\n            }\n            this.splatMesh = this.viewer.splatMesh;\n            this.add(this.viewer.splatMesh);\n        }\n    }\n\n    /**\n     * Add a single splat scene to the viewer.\n     * @param {string} path Path to splat scene to be loaded\n     * @param {object} options {\n     *\n     *         splatAlphaRemovalThreshold: Ignore any splats with an alpha less than the specified\n     *                                     value (valid range: 0 - 255), defaults to 1\n     *\n     *         showLoadingUI:         Display a loading spinner while the scene is loading, defaults to true\n     *\n     *         position (Array<number>):   Position of the scene, acts as an offset from its default position, defaults to [0, 0, 0]\n     *\n     *         rotation (Array<number>):   Rotation of the scene represented as a quaternion, defaults to [0, 0, 0, 1]\n     *\n     *         scale (Array<number>):      Scene's scale, defaults to [1, 1, 1]\n     *\n     *         onProgress:                 Function to be called as file data are received\n     *\n     * }\n     * @return {AbortablePromise}\n     */\n    addSplatScene(path, options = {}) {\n        if (options.showLoadingUI !== false) options.showLoadingUI = true;\n        return this.viewer.addSplatScene(path, options);\n    }\n\n    /**\n     * Add multiple splat scenes to the viewer.\n     * @param {Array<object>} sceneOptions Array of per-scene options: {\n     *\n     *         path: Path to splat scene to be loaded\n     *\n     *         splatAlphaRemovalThreshold: Ignore any splats with an alpha less than the specified\n     *                                     value (valid range: 0 - 255), defaults to 1\n     *\n     *         position (Array<number>):   Position of the scene, acts as an offset from its default position, defaults to [0, 0, 0]\n     *\n     *         rotation (Array<number>):   Rotation of the scene represented as a quaternion, defaults to [0, 0, 0, 1]\n     *\n     *         scale (Array<number>):      Scene's scale, defaults to [1, 1, 1]\n     * }\n     * @param {boolean} showLoadingUI Display a loading spinner while the scene is loading, defaults to true\n     * @return {AbortablePromise}\n     */\n    addSplatScenes(sceneOptions, showLoadingUI) {\n        if (showLoadingUI !== false) showLoadingUI = true;\n        return this.viewer.addSplatScenes(sceneOptions, showLoadingUI);\n    }\n\n    /**\n     * Get a reference to a splat scene.\n     * @param {number} sceneIndex The index of the scene to which the reference will be returned\n     * @return {SplatScene}\n     */\n    getSplatScene(sceneIndex) {\n        return this.viewer.getSplatScene(sceneIndex);\n    }\n\n    removeSplatScene(index, showLoadingUI = true) {\n        return this.viewer.removeSplatScene(index, showLoadingUI);\n    }\n\n    removeSplatScenes(indexes, showLoadingUI = true) {\n        return this.viewer.removeSplatScenes(indexes, showLoadingUI);\n    }\n\n    getSceneCount() {\n        return this.viewer.getSceneCount();\n    }\n\n    setActiveSphericalHarmonicsDegrees(activeSphericalHarmonicsDegrees) {\n        this.viewer.setActiveSphericalHarmonicsDegrees(activeSphericalHarmonicsDegrees);\n    }\n\n    async dispose() {\n        return await this.viewer.dispose();\n    }\n\n    static onBeforeRender(viewer, renderer, threeScene, camera) {\n        viewer.update(renderer, camera);\n    }\n\n    static createCallbackMesh() {\n        const geometry = new THREE.SphereGeometry(1, 8, 8);\n        const material = new THREE.MeshBasicMaterial();\n        material.colorWrite = false;\n        material.depthWrite = false;\n        const mesh = new THREE.Mesh(geometry, material);\n        mesh.frustumCulled = false;\n        return mesh;\n    }\n\n}\n"],"names":["AbortablePromise","static","constructor","promiseFunc","abortHandler","resolver","rejecter","this","promise","Promise","resolve","reject","promiseResolve","bind","promiseReject","args","error","id","idGen","then","onResolve","onResolveResult","args2","catch","onFail","abort","reason","AbortedPromiseError","Error","msg","super","floatView","Float32Array","int32View","Int32Array","buffer","uintEncodedFloat","f","fetchWithProgress","path","onProgress","saveChunks","headers","abortController","AbortController","signal","aborted","onProgressCalledAtComplete","localOnProgress","percent","percentLabel","chunk","fileSize","fetchOptions","fetch","async","data","ok","errorText","text","status","statusText","reader","body","getReader","bytesDownloaded","_fileSize","get","parseInt","undefined","chunks","value","done","read","Blob","arrayBuffer","length","toFixed","push","clamp","val","min","max","Math","getCurrentTime","performance","now","disposeAllMeshes","object3D","geometry","dispose","material","children","child","delayedExecute","func","fast","window","setTimeout","getSphericalHarmonicsComponentCountForDegree","sphericalHarmonicsDegree","shCoeffPerSplat","nativePromiseWithExtractedComponents","abortablePromiseWithExtractedComponents","Semver","major","minor","patch","toString","isIOS","ua","navigator","userAgent","indexOf","getIOSSemever","extract","match","UncompressedSplatArray","X","Y","Z","SCALE0","SCALE1","SCALE2","ROTATION0","ROTATION1","ROTATION2","ROTATION3","FDC0","FDC1","FDC2","OPACITY","FRC0","FRC1","FRC2","FRC3","FRC4","FRC5","FRC6","FRC7","FRC8","FRC9","FRC10","FRC11","FRC12","FRC13","FRC14","FRC15","FRC16","FRC17","FRC18","FRC19","FRC20","FRC21","FRC22","FRC23","sphericalHarmonicsCount","componentCount","defaultSphericalHarmonics","Array","fill","splats","splatCount","createSplat","baseSplat","shEntries","i","addSplat","splat","getSplat","index","addDefaultSplat","newSplat","addSplatFromComonents","x","y","z","scale0","scale1","scale2","rot0","rot1","rot2","rot3","r","g","b","opacity","rest","addSplatFromArray","src","srcIndex","srcSplat","Constants","DefaultSphericalHarmonics8BitCompressionHalfRange","SphericalHarmonics8BitCompressionRange","toHalfFloat","THREE","DataUtils","fromHalfFloat","toUncompressedFloat","compressionLevel","isSH","range8BitMin","range8BitMax","fromUint8","toUint8","v","rangeMin","rangeMax","range","floor","fromHalfFloatToUint8","fromUint8ToHalfFloat","dataViewFloatForCompressionLevel","dataView","floatIndex","getFloat32","getUint16","getUint8","convertBetweenCompressionLevels","noop","fromLevel","toLevel","outputConversionFunc","copyBetweenBuffers","srcBuffer","srcOffset","destBuffer","destOffset","byteCount","Uint8Array","dest","SplatBuffer","BytesPerCenter","BytesPerScale","BytesPerRotation","BytesPerColor","ScaleOffsetBytes","RotationffsetBytes","ColorOffsetBytes","SphericalHarmonicsOffsetBytes","ScaleRange","BytesPerSphericalHarmonicsComponent","SphericalHarmonicsOffsetFloat","SphericalHarmonicsDegrees","BytesPerSplat","bufferData","secLoadedCountsToMax","constructFromBuffer","getSplatCount","getMaxSplatCount","maxSplatCount","getMinSphericalHarmonicsDegree","minSphericalHarmonicsDegree","sections","section","getBucketIndex","localSplatIndex","bucketIndex","maxSplatIndexInFullBuckets","fullBucketCount","bucketSize","bucketSplatIndex","partiallyFullBucketIndex","currentPartiallyFilledBucketSize","partiallyFilledBucketLengths","getSplatCenter","globalSplatIndex","outCenter","transform","sectionIndex","globalSplatIndexToSectionMap","splatCountOffset","srcSplatCentersBase","bytesPerSplat","DataView","dataBase","bucketBase","BucketStorageSizeFloats","sf","compressionScaleFactor","sr","compressionScaleRange","bucketArray","applyMatrix4","getSplatScaleAndRotation","scaleMatrix","Matrix4","rotationMatrix","tempMatrix","tempPosition","Vector3","scale","rotation","Quaternion","outScale","outRotation","scaleOverride","srcSplatScalesBase","CompressionLevels","set","makeScale","makeRotationFromQuaternion","copy","multiply","decompose","getSplatColor","outColor","srcSplatColorsBase","splatColorsArray","fillSplatCenterArray","outCenterArray","srcFrom","srcTo","destFrom","center","centerDestBase","CenterComponentCount","fillSplatScaleRotationArray","ensurePositiveW","quaternion","flip","w","outScaleArray","outRotationArray","desiredOutputCompressionLevel","outputConversion","srcCompressionLevel","scaleDestBase","ScaleComponentCount","rotationDestBase","RotationComponentCount","srcScaleX","srcScaleY","srcScaleZ","srcRotationW","srcRotationX","srcRotationY","srcRotationZ","normalize","identity","premultiply","tempMatrix4","Matrix3","covarianceMatrix","transformedCovariance","transform3x3","transform3x3Transpose","outCovariance","outOffset","setFromMatrix4","transpose","elements","fillSplatCovarianceArray","covarianceArray","covarianceDestBase","CovarianceComponentCount","computeCovariance","fillSplatColorArray","outColorArray","minimumAlpha","colorDestBase","ColorComponentCount","alpha","fillSphericalHarmonicsArray","sphericalHarmonicVectors","tempMatrix3","tempTranslation","tempScale","tempRotation","sh11","sh12","sh13","sh21","sh22","sh23","sh24","sh25","shIn1","shIn2","shIn3","shIn4","shIn5","shOut1","shOut2","shOut3","shOut4","shOut5","set3","array","val1","val2","val3","set3FromArray","srcDestView","stride","srcBase","copy3","srcArray","destArray","setOutput3","destBase","conversionFunc","toUncompressedFloatArray3","outSphericalHarmonicsArray","outSphericalHarmonicsDegree","localFromHalfFloatToUint8","minSphericalHarmonicsCoeff","maxSphericalHarmonicsCoeff","localToUint8","outSphericalHarmonicsComponentsCount","srcSplatSHBase","shDestBase","compressionLevelForOutputConversion","minShCoeff","maxShCoeff","rotateSphericalHarmonics3","rotateSphericalHarmonics5","v1","v2","v3","transformRow","outArray","t0","t1","t2","addInto3","v4","v5","t3","t4","in1","in2","in3","tsh11","tsh12","tsh13","out1","out2","out3","dot3","in4","in5","tsh21","tsh22","tsh23","tsh24","tsh25","out4","out5","kSqrt0104","sqrt","kSqrt0304","kSqrt0103","kSqrt0403","kSqrt0112","dot5","parseHeader","headerArrayUint8","HeaderSizeBytes","headerArrayUint16","Uint16Array","headerArrayUint32","Uint32Array","headerArrayFloat32","versionMajor","versionMinor","maxSectionCount","sectionCount","sceneCenter","writeHeaderCountsToBuffer","writeHeaderToBuffer","header","parseSectionHeaders","offset","sectionHeaderArrayUint16","SectionHeaderSizeBytes","sectionHeaderArrayUint32","sectionHeaderArrayFloat32","sectionHeaders","sectionHeaderBase","sectionHeaderBaseUint16","sectionHeaderBaseUint32","sectionBase","bucketCount","bucketBlockSize","halfBucketBlockSize","bucketStorageSizeBytes","partiallyFilledBucketCount","bucketsMetaDataSizeBytes","bucketsStorageSizeBytes","calculateComponentStorage","splatDataStorageSizeBytes","storageSizeBytes","sectionHeader","base","bucketsBase","writeSectionHeaderToBuffer","sectionHeadeArrayUint16","sectionHeadeArrayUint32","sectionHeadeArrayFloat32","BucketStorageSizeBytes","writeSectionHeaderSplatCountToBuffer","globalSplatIndexToLocalSplatIndexMap","linkBufferArrays","buildMaps","bytesPerCenter","bytesPerScale","bytesPerRotation","bytesPerColor","sphericalHarmonicsComponentsPerSplat","sphericalHarmonicsBytesPerSplat","cumulativeSplatCount","j","updateLoadedCounts","newSectionCount","newSplatCount","updateSectionLoadedCounts","sectionHeaderOffset","tempCenterBuffer","ArrayBuffer","tempScaleBuffer","tempRotationBuffer","tempColorBuffer","tempSHBuffer","tempRot","bucketCenterDelta","OFFSET_X","OFFSET_Y","OFFSET_Z","OFFSET_SCALE0","OFFSET_SCALE1","OFFSET_SCALE2","OFFSET_ROT0","OFFSET_ROT1","OFFSET_ROT2","OFFSET_ROT3","OFFSET_FDC0","OFFSET_FDC1","OFFSET_FDC2","OFFSET_OPACITY","OFFSET_FRC0","OFFSET_FRC9","OFFSET","compressPositionOffset","doubleCompressionScaleRange","round","targetSplat","sectionBuffer","bufferOffset","bucketCenter","centerBase","scaleBase","rotationBase","colorBase","sphericalHarmonicsBase","rot","shOut","s","sub","bytesPerSHComponent","srcVal","degree1ByteCount","rgba","Uint8ClampedArray","generateFromUncompressedSplatArrays","splatArrays","blockSize","options","shDegree","sa","splatArray","sc","sectionBuffers","sectionHeaderBuffers","totalSplatCount","validSplats","sectionOptions","sectionBlockSize","blockSizeFactor","BucketBlockSize","sectionBucketSize","ceil","bucketSizeFactor","BucketSize","bucketInfo","computeBucketsForUncompressedSplatArray","fullBuckets","partiallyFullBucketLengths","partiallyFullBuckets","map","bucket","buckets","sectionDataSizeBytes","bucketMetaDataSizeBytes","bucketDataBytes","sectionSizeBytes","outSplatCount","fromArray","row","writeSplatDataToSectionBuffer","bucketMetaDataArray","pfb","sectionHeaderBuffer","sectionsCumulativeSizeBytes","byteLength","unifiedBufferSize","unifiedBuffer","currentUnifiedBase","halfBlockSize","dimensions","yBlocks","zBlocks","blockCenter","xBlock","yBlock","zBlock","bucketId","toArray","partiallyFullBucketArray","hasOwnProperty","preallocateUncompressed","sphericalHarmonicsDegrees","shDescriptor","splatBufferDataOffsetBytes","splatBufferSizeBytes","outBuffer","CurrentMajorVersion","CurrentMinorVersion","splatBuffer","HeaderMagicBytes","HeaderEndTokenBytes","HeaderEndToken","DataTypeMap","Map","Int8Array","Int16Array","Float64Array","unpackUnorm","bits","t","unpack111011","result","lerp","a","getElementPropStorage","element","name","properties","find","p","storage","PlayCanvasCompressedPlyParser","decodeHeaderText","headerText","chunkElement","vertexElement","shElement","headerLines","split","filter","line","startsWith","words","count","has","StorageType","storageSizeByes","BYTES_PER_ELEMENT","type","byteSize","sphericalHarmonicsPerSplat","headerSizeBytes","decodeHeader","plyBuffer","endHeaderTokenOffset","buf","search","endIndex","TextDecoder","decode","slice","readElementData","readBuffer","readOffset","fromIndex","toIndex","propertyFilter","e","property","requiredStorageSizeBytes","getInt8","getInt16","getInt32","getUint32","getFloat64","readPly","readIndex","getElementStorageArrays","storageArrays","minR","minG","minB","maxR","maxG","maxB","minX","minY","minZ","maxX","maxY","maxZ","minScaleX","minScaleY","minScaleZ","maxScaleX","maxScaleY","maxScaleZ","position","color","shStorageArrays","fRestKey","fRest","c","Vector4","chunkSplatIndexOffset","positionArray","positionExtremes","scaleArray","scaleExtremes","rotationArray","colorExtremes","colorArray","outSplat","chunkIndex","norm","m","unpackRot","exp","shCoeffMap","shIndexMap","shArray","readSphericalHarmonicsDegree","outSHCoeff","readSHCoeff","k","outIndex","parseToUncompressedSplatBufferSection","vertexDataBuffer","outBytesPerSplat","tempSplat","decompressBaseSplat","outBase","parseToUncompressedSplatArraySection","parseSphericalHarmonicsToUncompressedSplatArraySection","vertexReadOffset","sh","shArrays","Object","values","decompressSphericalHarmonics","parseToUncompressedSplatArray","parseToUncompressedSplatBuffer","PlyFormat","FieldSizeIdDouble","FieldSizeIdInt","FieldSizeIdUInt","FieldSizeIdFloat","FieldSizeIdShort","FieldSizeIdUShort","FieldSizeIdUChar","FieldSizeStringMap","double","int","uint","float","short","ushort","uchar","FieldSize","PlyParserUtils","decodeSectionHeader","fieldNameIdMap","headerStartLine","extractedLines","processingSection","headerEndLine","vertexCount","endOfHeader","sectionName","fieldIds","fieldTypes","allFieldNames","usedFieldNames","fieldTypesByName","trim","lineComponents","validComponents","lineComponent","trimmedComponent","fieldMatch","fieldTypeStr","fieldName","fieldId","fieldType","fieldOffsets","bytesPerVertex","sphericalHarmonics","decodeSphericalHarmonicsFromSectionHeader","dataSizeBytes","degree","sphericalHarmonicsCoefficientsPerChannel","coefficientsPerChannel","sphericalHarmonicsDegree1Fields","degree1Fields","sphericalHarmonicsDegree2Fields","degree2Fields","fieldNames","sphericalHarmonicsFieldCount","rgb","getHeaderSectionNames","sectionNames","headerLine","checkTextForEndHeader","endHeaderTestText","includes","checkBufferForEndHeader","searchOfset","chunkSize","decoder","endHeaderTestChunk","extractHeaderFromBufferToText","headerOffset","readChunkSize","headerChunk","readHeaderFromBuffer","convertHeaderTextToLines","prunedLines","determineHeaderFormatFromHeaderText","headertText","format","determineHeaderFormatFromPlyBuffer","readVertex","vertexData","dataOffset","fieldsToRead","rawVertex","BaseFieldNamesToRead","BaseFieldsToReadIndexes","SCALE_0","SCALE_1","SCALE_2","ROT_0","ROT_1","ROT_2","ROT_3","F_DC_0","F_DC_1","F_DC_2","RED","GREEN","BLUE","F_REST_0","INRIAV1PlyParser","decodeHeaderLines","shLineCount","forEach","shFieldsToReadCount","shRemainingFieldNamesToRead","from","fieldNamesToRead","fieldsToReadIndexes","reduce","acc","decodeHeaderFromBuffer","findSplatData","fromSplat","toSplat","splatData","splatDataOffset","toBuffer","toOffset","parsedSplat","parseToUncompressedSplat","decodeSectionSplatData","sectionSplatData","toSplatArray","rawSplat","OFFSET_ROTATION0","OFFSET_ROTATION1","OFFSET_ROTATION2","OFFSET_ROTATION3","OFFSET_FRC","readSplat","SH_C0","separatePlyHeaderAndData","CodeBookEntryNamesToRead","CodeBookEntriesToReadIndexes","CB_FEATURES_DC","CB_FEATURES_REST_0","CB_FEATURES_REST_3","CB_OPACITY","CB_SCALING","CB_ROTATION_RE","CB_ROTATION_IM","FieldNamesToRead","FieldsToReadIndexes","PLY_SCALE_0","PLY_SCALE_1","PLY_SCALE_2","PLY_ROT_0","PLY_ROT_1","PLY_ROT_2","PLY_ROT_3","PLY_X","PLY_Y","PLY_Z","PLY_F_DC_0","PLY_F_DC_1","PLY_F_DC_2","PLY_OPACITY","PLY_RED","PLY_GREEN","PLY_BLUE","hf","NaN","pow","INRIAV2PlyParser","decodeSectionHeadersFromHeaderLines","codeBookEntriesToReadIdMap","codeBookSectionIndex","currentStartLine","lastSectionFound","decodeSectionHeadersFromHeaderText","getSplatCountFromSectionHeaders","decodeHeaderFromHeaderText","findVertexData","targetSection","byteOffset","decodeCodeBook","codeBookData","codeBook","codeBookElementOffset","codeBookPage","page","baseValue","unified","PlyParser","plyFormat","SplatPartitioner","sectionFilters","groupingParameters","partitionGenerator","partitionUncompressedSplatArray","results","newArrays","sectionSplats","sectionFilter","parameters","getStandardPartitioner","partitionSize","clampDistance","point","centerDist","lengthSq","sort","patitionCount","currentStartSplat","startSplat","splatIndex","blocksSize","SplatBufferGenerator","splatPartitioner","alphaRemovalThreshold","sectionSize","generateFromUncompressedSplatArray","partitionResults","getStandardGenerator","LoaderStatus","DirectLoadError","InternalLoadType","storeChunksInBuffer","inBytes","sizeBytes","finalize","optimizeSplatData","PlyLoader","loadFromURL","fileName","progressiveLoadToSplatBuffer","onProgressiveLoadSectionProgress","internalLoadType","directLoadSectionSizeBytes","ProgressiveLoadSectionSize","directLoadBufferIn","directLoadBufferOut","directLoadSplatBuffer","compressedPlyHeaderChunksBuffer","processedBaseSplatCount","processedSphericalHarmonicsSplatCount","headerLoaded","readyToLoadSplatData","baseSplatDataLoaded","loadPromise","standardLoadUncompressedSplatArray","numBytesStreamed","numBytesParsed","numBytesDownloaded","endOfBaseSplatDataBytes","textDecoder","chunkData","loadComplete","startBytes","endBytes","sizeRequiredForHeaderAndChunks","numBytesToProcess","addedSplatCount","numBytesToParse","numBytesLeftOver","parsedDataViewOffset","dataToParse","shDesc","keepChunks","keepSize","unshift","chunkDatas","plyFileData","loadFromFileData","createStream","ReadableStream","start","controller","enqueue","close","decompressGzipped","stream","decompressedStream","pipeThrough","DecompressionStream","response","Response","decompressGzipStream","console","SPZ_MAGIC","FLAG_ANTIALIASED","halfToFloat","h","exponent","mantissa","signMul","Infinity","dimForDegree","unpackedSplatToUncompressedSplat","unpackedSplat","unpackedSphericalHarmonicsDegree","unpackGaussians","packed","directToSplatBuffer","outTarget","outTargetOffset","numPoints","shDim","usesFloat16","positions","scales","rotations","alphas","colors","checkSizes2","halfData","fullPrecisionPositionScale","fractionalBits","shCoeffPerChannelPerSplat","fixed32","subarray","xyz","squaredNorm","uncompressedSplat","HEADER_SIZE","MAX_POINTS_TO_READ","loadSpzPacked","compressedData","view","magic","version","flags","reserved","antialiased","uint8View","positionsSize","currentOffset","deserializePackedGaussians","SpzLoader","fileData","spzFileData","SplatParser","fromBuffer","fromOffset","outBytesPerCenter","outBytesPerScale","outBytesPerRotation","inBase","RowSizeBytes","inCenter","inScale","CenterSizeBytes","inColor","ScaleSizeBytes","inRotation","RotationSizeBytes","quat","parseStandardSplatToUncompressedSplatArray","inBuffer","ColorSizeBytes","SplatLoader","splatDataOffsetBytes","numBytesLoaded","percentStr","bytesLoadedSinceLastSection","splatFileData","KSplatLoader","checkVersion","minVersionMajor","minVersionMinor","externalOnProgress","onSectionBuilt","directLoadBuffer","headerBuffer","sectionHeadersBuffer","headerLoading","sectionHeadersLoaded","sectionHeadersLoading","numBytesProgressivelyLoaded","totalBytesToDownload","downloadComplete","loadSectionQueued","directLoadPromise","queuedCheckAndLoadSectionsCount","checkAndLoadSectionHeaders","performLoad","totalSectionStorageStorageByes","totalStorageSizeBytes","checkAndLoadSections","baseDataOffset","reachedSections","loadedSplatCount","bytesRequiredToReachSectionSplatData","bytesPastSSectionSplatDataStart","loadedSplatsForSection","percentComplete","ProgressiveLoadSectionDelayDuration","fullBuffer","downLoadLink","blob","document","createElement","appendChild","download","href","URL","createObjectURL","click","SceneFormat","Splat","KSplat","Ply","Spz","sceneFormatFromPath","endsWith","_changeEvent","_startEvent","_endEvent","_ray","Ray","_plane","Plane","TILT_LIMIT","cos","MathUtils","DEG2RAD","OrbitControls","EventDispatcher","object","domElement","style","touchAction","enabled","target","minDistance","maxDistance","minZoom","maxZoom","minPolarAngle","maxPolarAngle","PI","minAzimuthAngle","maxAzimuthAngle","enableDamping","dampingFactor","enableZoom","zoomSpeed","enableRotate","rotateSpeed","enablePan","panSpeed","screenSpacePanning","keyPanSpeed","zoomToCursor","autoRotate","autoRotateSpeed","keys","LEFT","UP","RIGHT","BOTTOM","mouseButtons","MOUSE","ROTATE","MIDDLE","DOLLY","PAN","touches","ONE","TOUCH","TWO","DOLLY_PAN","target0","clone","position0","zoom0","zoom","_domElementKeyEvents","getPolarAngle","spherical","phi","getAzimuthalAngle","theta","getDistance","distanceTo","listenToKeyEvents","addEventListener","onKeyDown","stopListenToKeyEvents","removeEventListener","saveState","scope","reset","clearDampedRotation","clearDampedPan","updateProjectionMatrix","dispatchEvent","update","state","STATE","NONE","sphericalDelta","panOffset","setFromUnitVectors","up","quatInverse","invert","lastPosition","lastQuaternion","lastTargetPosition","twoPI","applyQuaternion","setFromVector3","rotateLeft","isFinite","makeSafe","addScaledVector","add","performCursorZoom","isOrthographicCamera","radius","setFromSpherical","lookAt","multiplyScalar","zoomChanged","newRadius","isPerspectiveCamera","prevRadius","radiusDelta","dollyDirection","updateMatrixWorld","mouseBefore","mouse","unproject","mouseAfter","warn","transformDirection","matrix","origin","direction","abs","dot","setFromNormalAndCoplanarPoint","intersectPlane","distanceToSquared","EPS","onContextMenu","onPointerDown","onPointerUp","onMouseWheel","onPointerMove","TOUCH_ROTATE","TOUCH_PAN","TOUCH_DOLLY_PAN","TOUCH_DOLLY_ROTATE","Spherical","rotateStart","Vector2","rotateEnd","rotateDelta","panStart","panEnd","panDelta","dollyStart","dollyEnd","dollyDelta","pointers","pointerPositions","getZoomScale","angle","rotateUp","panLeft","distance","objectMatrix","setFromMatrixColumn","panUp","crossVectors","pan","deltaX","deltaY","targetDistance","tan","fov","clientHeight","right","left","clientWidth","top","bottom","dollyOut","dollyScale","dollyIn","updateMouseParameters","event","rect","getBoundingClientRect","clientX","clientY","width","height","dist","handleMouseDownRotate","handleMouseDownPan","handleTouchStartRotate","pageX","pageY","handleTouchStartPan","handleTouchStartDolly","dx","dy","handleTouchMoveRotate","getSecondPointerPosition","subVectors","handleTouchMovePan","handleTouchMoveDolly","setPointerCapture","pointerId","addPointer","pointerType","trackPointer","DOLLY_ROTATE","onTouchStart","mouseAction","button","handleMouseDownDolly","ctrlKey","metaKey","shiftKey","onMouseDown","handleTouchMoveDollyPan","handleTouchMoveDollyRotate","onTouchMove","handleMouseMoveRotate","handleMouseMoveDolly","handleMouseMovePan","onMouseMove","splice","removePointer","releasePointerCapture","preventDefault","handleMouseWheel","needsUpdate","code","handleKeyDown","pointer","passive","LoadingSpinner","message","container","taskIDGen","elementID","elementIDGen","tasks","spinnerContainerOuter","className","display","spinnerContainerPrimary","spinnerPrimary","classList","messageContainerPrimary","innerHTML","spinnerContainerMin","spinnerMin","messageContainerMin","setMinimized","fadeTransitions","addTask","newTask","removeTask","task","removeAllTasks","setMessageForTask","show","setMessage","hide","visible","setContainer","parentElement","removeChild","zIndex","minimized","instant","showHideSpinner","displayStyle","fadeTransitionsIndex","out","duration","onComplete","startTime","startOpacity","parseFloat","isNaN","interval","setInterval","elapsed","clearInterval","fadeElement","LoadingProgressBar","progressBarContainerOuter","progressBarBox","progressBarBackground","progressBar","setProgress","progress","InfoPanel","infoCells","layout","infoPanelContainer","append","infoPanel","infoTable","layoutEntry","labelCell","spacerCell","infoCell","meshCursorPosition","renderDimensions","cameraPosition","cameraLookAtPosition","cameraUp","orthographicCamera","currentFPS","splatRenderCount","splatRenderCountPct","lastSortTime","focalAdjustment","splatScale","pointCloudMode","cameraPosString","cla","cameraLookAtString","cameraLookAt","cameraUpString","cursPos","cursorPosString","cursorPosition","fps","renderWindow","renderSplatCount","sortTime","_axis","ArrowHelper","Object3D","dir","headLength","headRadius","lineGeometry","CylinderGeometry","translate","coneGeometry","Mesh","MeshBasicMaterial","toneMapped","matrixAutoUpdate","cone","setDirection","radians","acos","setFromAxisAngle","setColor","source","SceneHelper","threeScene","splatRenderTarget","renderTargetCopyQuad","renderTargetCopyCamera","meshCursor","focusMarker","controlPlane","debugRoot","secondaryDebugRoot","updateSplatRenderTargetForRenderDimensions","destroySplatRendertarget","WebGLRenderTarget","RGBAFormat","stencilBuffer","depthBuffer","depthTexture","DepthTexture","DepthFormat","UnsignedIntType","setupRenderTargetCopyObjects","renderTargetCopyMaterial","ShaderMaterial","vertexShader","fragmentShader","uniforms","sourceColorTexture","sourceDepthTexture","depthWrite","depthTest","transparent","blending","CustomBlending","blendSrc","SrcAlphaFactor","blendSrcAlpha","blendDst","OneMinusSrcAlphaFactor","blendDstAlpha","extensions","fragDepth","PlaneGeometry","OrthographicCamera","destroyRenderTargetCopyObjects","setupMeshCursor","ConeGeometry","coneMaterial","downArrow","upArrow","leftArrow","rightArrow","destroyMeshCursor","remove","setMeshCursorVisibility","getMeschCursorVisibility","setMeshCursorPosition","positionAndOrientMeshCursor","camera","setupFocusMarker","sphereGeometry","SphereGeometry","focusMarkerMaterial","buildFocusMarkerMaterial","destroyFocusMarker","updateFocusMarker","toCamera","viewport","matrixWorld","toCameraDistance","realFocusPosition","uniformsNeedUpdate","setFocusMarkerVisibility","setFocusMarkerOpacity","getFocusMarkerOpacity","setupControlPlane","planeGeometry","rotateX","planeMaterial","side","DoubleSide","planeMesh","arrowDir","arrowOrigin","arrowHelper","destroyControlPlane","setControlPlaneVisibility","positionAndOrientControlPlane","tempQuaternion","defaultUp","addDebugMeshes","createDebugMeshes","createSecondaryDebugMeshes","destroyDebugMeshes","renderOrder","debugMeshRoot","createMesh","sphereMesh","buildDebugMaterial","boxGeometry","BoxGeometry","boxMesh","separation","Color","FrontSide","VectorRight","VectorUp","VectorBackward","setParameters","boxContainsPoint","box","epsilon","intersectBox","planeIntersectionPoint","planeIntersectionPointArray","originArray","directionArray","outHit","normal","hitNormal","extremeVec","multiplier","sign","toSide","idx1","idx2","intersectSphere","toSphereCenterVec","toClosestApproach","toClosestApproachSq","diffSq","radiusSq","thc","Hit","hitClone","SplatRenderMode","ThreeD","TwoD","Raycaster","raycastAgainstTrueSplatEllipsoid","ray","setFromCameraAndScreenPosition","ndcCoords","screenPosition","screenDimensions","setFromMatrixPosition","near","far","intersectSplatMesh","toLocal","fromLocal","sceneTransform","localRay","tempPoint","splatMesh","outHits","splatTree","getSplatTree","subTrees","subTree","dynamicMode","getSceneTransform","outHitsForSubTree","rootNode","castRayAtSplatTreeNode","hit","tempColor","tempCenter","tempHit","scaleEpsilon","uniformScaleMatrix","toSphereSpace","fromSphereSpace","tempRay","node","boundingBox","indexes","splatGlobalIndex","splatSceneIndex","getSceneIndexForSplat","getScene","splatRenderMode","uniformScale","log10","SplatMaterial","buildVertexShaderBase","enableOptionalEffects","maxSphericalHarmonicsDegree","customVars","vertexShaderSource","MaxScenes","getVertexShaderFadeIn","getUniforms","pointCloudModeEnabled","fadeInComplete","orthographicMode","visibleRegionFadeStartRadius","visibleRegionRadius","currentTime","firstRenderTime","centersColorsTexture","sphericalHarmonicsTexture","sphericalHarmonicsTextureR","sphericalHarmonicsTextureG","sphericalHarmonicsTextureB","sphericalHarmonics8BitCompressionRangeMin","sphericalHarmonics8BitCompressionRangeMax","focal","orthoZoom","inverseFocalAdjustment","basisViewport","debugColor","centersColorsTextureSize","sphericalHarmonicsTextureSize","sphericalHarmonics8BitMode","sphericalHarmonicsMultiTextureMode","sceneIndexesTexture","sceneIndexesTextureSize","sceneCount","sceneOpacity","sceneVisibility","transformMatrices","SplatMaterial3D","build","maxScreenSpaceSplatSize","kernel2DSize","buildVertexShaderProjection","fragmentShaderSource","buildFragmentShader","alphaTest","NormalBlending","SplatMaterial2D","referenceQuadGeneration","SplatGeometry","baseGeometry","BufferGeometry","setIndex","positionsArray","BufferAttribute","setAttribute","setXYZ","InstancedBufferGeometry","splatIndexArray","splatIndexes","InstancedBufferAttribute","setUsage","DynamicDrawUsage","instanceCount","SplatScene","copyTransformData","otherScene","updateTransform","matrixWorldAutoUpdate","updateWorldMatrix","updateMatrix","SplatTreeNode","depth","Box3","SplatSubTree","maxDepth","maxCentersPerNode","sceneDimensions","sceneMin","sceneMax","nodesWithIndexes","convertWorkerSubTreeNode","workerSubTreeNode","minVector","maxVector","convertedNode","convertWorkerSubTree","workerSubTree","convertedSubTree","visitLeavesFromNode","visitFunc","createSplatTreeWorker","self","WorkerSplatTreeNodeIDGen","WorkerBox3","containsPoint","WorkerSplatSubTree","addedIndexes","disposed","WorkerSplatTreeNode","processSplatTreeNode","tree","indexToCenter","sceneCenters","newIndexes","nodeDimensions","halfDimensions","nodeCenter","childrenBounds","splatCounts","baseIndexes","childNode","buildSubTree","centerCount","onmessage","process","allCenters","postMessage","createSplatTree","centers","SplatTree","diposeSplatTreeWorker","splatTreeWorker","terminate","processSplatMesh","filterFunc","onIndexesUpload","onSplatTreeConstruction","Worker","addCentersForScene","splatOffset","addedCount","addBase","checkForEarlyExit","scenes","transferBuffers","workerProcessCenters","countLeaves","leafCount","visitLeaves","WebGLExtensions","gl","getExtension","extension","init","capabilities","isWebGL2","WebGLCapabilities","maxAnisotropy","getMaxPrecision","precision","getShaderPrecisionFormat","VERTEX_SHADER","HIGH_FLOAT","FRAGMENT_SHADER","MEDIUM_FLOAT","WebGL2RenderingContext","maxPrecision","drawBuffers","logarithmicDepthBuffer","maxTextures","getParameter","MAX_TEXTURE_IMAGE_UNITS","maxVertexTextures","MAX_VERTEX_TEXTURE_IMAGE_UNITS","maxTextureSize","MAX_TEXTURE_SIZE","maxCubemapSize","MAX_CUBE_MAP_TEXTURE_SIZE","maxAttributes","MAX_VERTEX_ATTRIBS","maxVertexUniforms","MAX_VERTEX_UNIFORM_VECTORS","maxVaryings","MAX_VARYING_VECTORS","maxFragmentUniforms","MAX_FRAGMENT_UNIFORM_VECTORS","vertexTextures","floatFragmentTextures","getMaxAnisotropy","MAX_TEXTURE_MAX_ANISOTROPY_EXT","floatVertexTextures","maxSamples","MAX_SAMPLES","SceneRevealMode","Default","Gradual","Instant","LogLevel","None","Warning","Info","Debug","dummyGeometry","dummyMaterial","MAX_TEXTURE_TEXELS","SplatMesh","halfPrecisionCovariancesOnGPU","devicePixelRatio","enableDistancesComputationOnGPU","integerBasedDistancesComputation","logLevel","sceneFadeInRateMultiplier","renderer","baseSplatTree","splatDataTextures","distancesTransformFeedback","program","centersBuffer","sceneIndexesBuffer","outDistancesBuffer","centersLoc","modelViewProjLoc","sceneIndexesLoc","transformsLocs","globalSplatIndexToSceneIndexMap","lastBuildSplatCount","lastBuildScenes","lastBuildMaxSplatCount","lastBuildSceneCount","finalBuild","webGLUtils","calculatedSceneCenter","maxSplatDistanceFromSceneCenter","visibleRegionBufferRadius","visibleRegionChanging","lastRenderer","buildScenes","parentObject","splatBuffers","sceneOptions","scene","createScene","splatAlphaRemovalThreshold","buildSplatIndexMaps","localSplatIndexMap","sceneIndexMap","buildSplatTree","minAlphas","onSplatTreeIndexesUpload","disposeSplatTree","buildStartTime","splatColor","sceneIndex","minAlpha","buildTime","log","leavesWithVertices","avgSplatCount","nodeCount","nodeSplatCount","keepSceneTransforms","preserveVisibleRegion","getTotalMaxSplatCountForSplatBuffers","newScenes","newScene","existingScene","splatBufferSphericalHarmonicsDegree","splatBuffersChanged","isUpdateBuild","disposeMeshData","indexMaps","splatBufferSplatCount","setupDistancesComputationTransformFeedback","dataUpdateResults","refreshGPUDataFromSplatBuffers","onSplatTreeReadyCallback","freeIntermediateSplatData","deleteTextureData","texture","image","onUpdate","baseData","covariances","centerColors","sceneIndexes","textures","disposeTextures","computeDistancesOnGPUSyncTimeout","clearTimeout","disposeDistancesComputationGPUResources","textureKey","textureContainer","onSplatTreeReady","callback","getDataForDistancesComputation","end","getIntegerCenters","getFloatCenters","getSceneIndexes","sinceLastBuildOnly","refreshDataTexturesFromSplatBuffers","updateStart","refreshGPUBuffersForDistancesComputation","to","updateGPUCentersBufferForDistancesComputation","updateGPUTransformIndexesBufferForDistancesComputation","updateBaseDataFromSplatBuffers","setupDataTextures","updateDataTexturesFromBaseData","updateVisibleRegion","computeDataTextureSize","elementsPerTexel","elementsPerSplat","texSize","getCovariancesInitialTextureSpecs","elementsPerTexelStored","getCovariancesElementsPertexelStored","covarianceCompressionLevel","getTargetCovarianceCompressionLevel","shCompressionLevel","getTargetSphericalHarmonicsCompressionLevel","initialCovTexSpecs","SphericalHarmonicsArrayType","shComponentCount","shData","centersColsTexSize","paddedCentersCols","updateCenterColorsPaddedData","centersColsTex","DataTexture","RGBAIntegerFormat","internalFormat","size","covTexSpecs","covariancesElementsPerTexelStored","covTexSize","covariancesElementsPerTexelAllocated","covariancesTextureData","covTex","updatePaddedCompressedCovariancesTextureData","covariancesTextureHalfFloat","FloatType","covariancesTexture","dummyTex","covariancesAreHalfFloat","covariancesTextureSize","elementsPerTexelAllocated","scaleRotationsTexSize","ScaleRotationsDataType","scaleRotationsTextureType","paddedScaleRotations","updateScaleRotationsPaddedData","scaleRotationsTex","scaleRotationsTexture","scaleRotationsTextureSize","shTextureType","UnsignedByteType","HalfFloatType","paddedSHComponentCount","shElementsPerTexel","texelFormat","RGFormat","shTexSize","paddedSHArray","shTexture","paddedComponentCount","textureCount","shComponentCountPerChannel","paddedSHArraySize","textureUniforms","paddedSHArrays","shTextures","componentCountPerChannel","sceneIndexesTexSize","paddedTransformIndexes","RedIntegerFormat","covarancesTextureDesc","scaleRotationsTextureDesc","scaleRotationCompressionLevel","shITextureDesc","fillSplatDataArrays","shTextureDesc","centerColorsTextureDescriptor","paddedCenterColors","centerColorsTexture","centerColorsTextureProps","__webglTexture","updateDataTexture","covarancesStartElement","covariancesEndElement","covariance","covariancesTextureProps","bytesPerElement","scaleRotationsTextureProps","shBytesPerElement","updateTexture","shTextureSize","shTextureProps","sceneIndexesTexDesc","paddedSceneIndexes","sceneIndexesTextureProps","getMaximumSplatBufferCompressionLevel","maxCompressionLevel","getMinimumSplatBufferCompressionLevel","minCompressionLevel","computeTextureUpdateRegion","endSplat","textureWidth","texelsPerSplat","startSplatTexels","startRow","startRowElement","endSplatTexels","endRow","dataStart","dataEnd","paddedData","textureSize","textureProps","getContext","updateRegion","updateElementCount","updateDataView","updateHeight","glType","convert","glFormat","colorSpace","currentTexture","TEXTURE_BINDING_2D","bindTexture","TEXTURE_2D","texSubImage2D","sourceData","textureData","textureDataStartIndex","fromElement","toElement","textureDataView","textureDataIndex","sequentialCount","setUint16","colorsBase","centersBase","centerColorsBase","arr","scaleRotationsBase","avgCenter","distFromCSceneCenter","updateVisibleRegionFadeDistance","sceneRevealMode","fastFadeRate","gradualFadeRate","defaultFadeInRate","fadeInRate","shaderFadeInComplete","updateRenderIndexes","globalIndexes","attributes","setDrawRange","updateTransforms","updateUniforms","cameraFocalLengthX","cameraFocalLengthY","orthographicZoom","transforms","setSplatScale","getSplatScale","setPointCloudModeEnabled","getPointCloudModeEnabled","getSplatDataTextures","includeSinceLastBuild","getTotalSplatCountForScenes","getTotalSplatCountForSplatBuffers","getTotalMaxSplatCountForScenes","vao","deleteVertexArray","deleteProgram","deleteShader","disposeDistancesComputationGPUBufferResources","deleteTransformFeedback","deleteBuffer","setRenderer","WebGLUtils","currentMaxSplatCount","rebuildGPUObjects","rebuildBuffers","createShader","shader","shaderSource","compileShader","getShaderParameter","COMPILE_STATUS","typeName","errors","getShaderInfoLog","vsSource","currentVao","VERTEX_ARRAY_BINDING","currentProgram","CURRENT_PROGRAM","currentProgramDeleted","getProgramParameter","DELETE_STATUS","createVertexArray","bindVertexArray","createProgram","attachShader","transformFeedbackVaryings","SEPARATE_ATTRIBS","linkProgram","LINK_STATUS","getProgramInfoLog","useProgram","getAttribLocation","getUniformLocation","createBuffer","bindBuffer","ARRAY_BUFFER","enableVertexAttribArray","vertexAttribIPointer","INT","vertexAttribPointer","FLOAT","UNSIGNED_INT","STATIC_READ","createTransformFeedback","bindTransformFeedback","TRANSFORM_FEEDBACK","bindBufferBase","TRANSFORM_FEEDBACK_BUFFER","isUpdate","offsetSplats","ArrayType","subBufferOffset","bufferSubData","maxArray","STATIC_DRAW","fillTransformsArray","tempArray","sceneTransformElements","computeDistancesOnGPU","modelViewProjMatrix","outComputedDistances","enable","RASTERIZER_DISCARD","iTempMatrix","getIntegerMatrixArray","iTransform","uniform4i","uniformMatrix4fv","iViewProjMatrix","iViewProj","uniform3i","viewProj","uniform3f","beginTransformFeedback","POINTS","drawArrays","endTransformFeedback","disable","sync","fenceSync","SYNC_GPU_COMMANDS_COMPLETE","flush","checkSync","timeout","bitflags","clientWaitSync","TIMEOUT_EXPIRED","WAIT_FAILED","deleteSync","getBufferSubData","getLocalSplatParameters","globalIndex","paramsObj","returnSceneTransform","getSplatBufferForSplat","localIndex","getSplatLocalIndex","getSceneTransformForSplat","applySceneTransform","sphericalHarmonicsCompressionLevel","srcStart","srcEnd","destStart","tempTransform","startSceneIndex","endSceneIndex","padFour","floatCenters","intCenters","paddedFloatCenters","outTransform","getSceneCount","matrixElements","intMatrixArray","computeBoundingBox","applySceneTransforms","SorterWasmNoSIMD","sortWorker","wasmInstance","wasmMemory","useSharedMemory","integerBasedSort","indexesToSortOffset","sortedIndexesOffset","sceneIndexesOffset","transformsOffset","precomputedDistancesOffset","mappedDistancesOffset","frequenciesOffset","centersOffset","modelViewProjOffset","countsZero","sortedIndexesOut","distanceMapRange","uploadedSplatCount","BytesPerInt","BytesPerFloat","renderCount","sortCount","splatSortCount","usePrecomputedDistances","copyIndexesToSort","copyPrecomputedDistances","copyTransforms","indexesToSort","precomputedDistances","modelViewProj","sortStartTime","exports","sortIndexes","sortMessage","sortDone","sortedIndexes","sortEndTime","CENTERS_BYTES_PER_ENTRY","sorterWasmBytes","matrixSize","memoryRequiredForIndexesToSort","memoryRequiredForCenters","memoryRequiredForModelViewProjectionMatrix","memoryRequiredForPrecomputedDistances","memoryRequiredForMappedDistances","memoryRequiredForSortedIndexes","memoryRequiredForIntermediateSortBuffers","memoryRequiredforTransformIndexes","memoryRequiredforTransforms","extraMemory","MemoryPageSize","totalRequiredMemory","totalPagesRequired","sorterWasmImport","module","env","memory","WebAssembly","Memory","initial","maximum","shared","compile","wasmModule","instantiate","instance","sortSetupPhase1Complete","indexesToSortBuffer","sortedIndexesBuffer","precomputedDistancesBuffer","transformsBuffer","WebXRMode","VR","AR","VRButton","createButton","sessionInit","disableButton","cursor","onmouseenter","onmouseleave","onclick","stylizeElement","padding","border","borderRadius","background","font","textAlign","outline","xr","isSessionSupported","supported","currentSession","onSessionStarted","session","onSessionEnded","setSession","textContent","sessionOptions","optionalFeatures","requestSession","offerSession","err","showEnterVR","xrSessionIsGranted","exception","isSecureContext","location","replace","textDecoration","registerSessionGrantedListener","test","ARButton","domOverlay","overlay","svg","createElementNS","root","setReferenceSpaceType","showStartAR","RenderMode","Always","OnChange","Never","Viewer","initialCameraPosition","initialCameraLookAt","dropInMode","selfDrivenMode","selfDrivenUpdateFunc","selfDrivenUpdate","useBuiltInControls","rootElement","ignoreDevicePixelRatio","gpuAcceleratedSort","sharedMemoryForWorkers","dynamicScene","webXRMode","webXRActive","webXRSessionInit","renderMode","enableSIMDInSort","inMemoryCompressionLevel","semver","splatSortDistanceMapPrecision","DefaultSplatSortDistanceMapPrecision","onSplatMeshChangedCallback","createSplatMesh","controls","perspectiveControls","orthographicControls","perspectiveCamera","showMeshCursor","showControlPlane","showInfo","sceneHelper","sortRunning","lastSplatSortCount","sortWorkerIndexesToSort","sortWorkerSortedIndexes","sortWorkerPrecomputedDistances","sortWorkerTransforms","preSortMessages","runAfterNextSort","selfDrivenModeRunning","splatRenderReady","raycaster","startInOrthographicMode","consecutiveRenderFrames","previousCameraTarget","nextCameraTarget","mousePosition","mouseDownPosition","mouseDownTime","resizeObserver","mouseMoveListener","mouseDownListener","mouseUpListener","keyDownListener","sortPromise","sortPromiseResolver","splatSceneDownloadPromises","splatSceneDownloadAndBuildPromise","splatSceneRemovalPromise","loadingSpinner","loadingProgressBar","usingExternalCamera","usingExternalRenderer","initialized","disposing","disposePromise","frustumCulled","setupCamera","setupRenderer","setupWebXR","setupControls","setupEventHandlers","Scene","getRenderDimensions","PerspectiveCamera","WebGLRenderer","antialias","setPixelRatio","autoClear","setClearColor","setSize","ResizeObserver","forceRenderNextFrame","observe","onMouseUp","removeEventHandlers","setRenderMode","setActiveSphericalHarmonicsDegrees","activeSphericalHarmonicsDegrees","onSplatMeshChanged","forward","tempMatrixLeft","tempMatrixRight","makeRotationAxis","setOrthographicMode","offsetX","offsetY","clickOffset","onMouseClick","checkForFocalPointChange","clipboard","writeText","toNewFocalPoint","transitioningCameraTarget","intersectionPoint","transitioningCameraTargetStartTime","outDimensions","offsetWidth","offsetHeight","getSize","fromCamera","resetControls","fromControls","toControls","setCameraZoomFromPosition","setCameraPositionFromZoom","tempVector","positionCamera","zoomedCamera","toLookAtDistance","negate","zoomCamera","positionZamera","updateSplatMesh","focalLengthX","projectionMatrix","focalLengthY","focalMultiplier","adjustForWebXRStereo","xrCameraProj00","getCamera","cameraProj00","isLoadingOrUnloading","isDisposingOrDisposed","addSplatSceneDownloadPromise","removeSplatSceneDownloadPromise","setSplatSceneDownloadAndBuildPromise","clearSplatSceneDownloadAndBuildPromise","addSplatScene","progressiveLoad","isProgressivelyLoadable","showLoadingUI","loadingUITaskId","onProgressUIUpdate","percentCompleteLabel","loaderStatus","suffix","downloadDone","downloadedPercentage","splatBuffersAddedUIUpdate","firstBuild","downloadAndBuildSingleSplatSceneProgressiveLoad","downloadAndBuildSingleSplatSceneStandardLoad","addSplatBufferOptions","orientation","addSplatBuffers","buildFunc","onException","downloadPromise","downloadSplatSceneToSplatBuffer","downloadAndBuildPromise","updateError","onDownloadProgress","onDownloadException","progressiveLoadedSectionBuildCount","progressiveLoadedSectionBuilding","queuedProgressiveLoadSectionBuilds","checkAndBuildProgressiveLoadSections","queuedBuild","shift","progressiveLoadFirstSectionBuildPromise","splatSceneDownloadPromise","addSplatScenes","fileCount","onLoadProgress","fileIndex","totalPercent","baseDownloadPromises","nativeDownloadPromises","baseDownloadPromise","all","finally","progressiveBuild","splatBufferOptions","showLoadingUIForSplatTreeBuild","replaceExisting","enableRenderBeforeFirstSort","splatProcessingTaskId","removeSplatProcessingTask","buildResults","addSplatBuffersToMesh","disposeSortWorker","setupSortWorker","runSplatSort","splatOptimizingTaskId","allSplatBuffers","allSplatBufferOptions","finished","DistancesArrayType","worker","sourceWasm","iOSSemVer","sorterWasmBinaryString","atob","charCodeAt","createSortWorker","sortCanceled","defaultMessage","removeSplatScene","indexToRemove","removeSplatScenes","indexesToRemove","revmovalTaskId","checkAndHideLoadingUI","onDone","savedSplatBuffers","savedSceneOptions","savedSceneTransformComponents","shouldRemove","setAnimationLoop","requestFrameId","requestAnimationFrame","stop","cancelAnimationFrame","waitPromises","promisesToAbort","promiseKey","downloadPromiseToAbort","unobserve","toAbort","shouldRender","render","renderNextFrame","lastCameraPosition","lastCameraOrientation","changeEpsilon","cameraChanged","cp","co","savedAuoClear","hasRenderables","updateForDropInMode","updateForRendererSizeChanges","updateMeshCursor","updateFPS","timingSensitiveUpdates","updateInfoPanel","updateControlPlane","lastCalcTime","frameCount","lastRendererSize","currentRendererSize","lastCameraOrthographic","aspect","lastUpdateTime","timeDelta","updateCameraTransition","tempCameraTarget","toPreviousTarget","toNextTarget","rotationAngle","wasTransitioning","currentFocusMarkerOpacity","newFocusMarkerOpacity","mvpMatrix","cameraPositionArray","lastSortViewDir","sortViewDir","lastSortViewPos","sortViewOffset","queuedSorts","partialSorts","angleThreshold","sortFractions","force","forceSortAll","angleDiff","positionDiff","needsRefreshForRotation","needsRefreshForPosition","shouldSortAll","gatherSceneNodesForSort","mvpCamera","gpuAcceleratedSortPromise","partialSort","sortFraction","nodeRenderList","allSplatsSortBuffer","tempVectorYZ","tempVectorXZ","modelView","baseModelView","tempMax","nodeSize","gatherAllNodes","cameraFocalLength","fovXOver2","atan","fovYOver2","cosFovXOver2","cosFovYOver2","nodeRenderCount","distanceToNode","setX","setY","cameraAngleXZDot","cameraAngleYZDot","ns","currentByteOffset","windowSizeInts","windowSizeBytes","getSplatMesh","getSplatScene","isMobile","DropInViewer","Group","viewer","callbackMesh","createCallbackMesh","onBeforeRender","colorWrite","mesh"],"mappings":"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"}