@onerjs/core 8.54.4 → 8.54.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/Engines/WebGPU/Extensions/engine.cubeTexture.pure.js +1 -1
  2. package/Engines/WebGPU/Extensions/engine.cubeTexture.pure.js.map +1 -1
  3. package/Engines/WebGPU/Extensions/engine.rawTexture.pure.js +2 -2
  4. package/Engines/WebGPU/Extensions/engine.rawTexture.pure.js.map +1 -1
  5. package/Engines/WebGPU/webgpuCacheRenderPipeline.d.ts +1 -0
  6. package/Engines/WebGPU/webgpuCacheRenderPipeline.js +18 -4
  7. package/Engines/WebGPU/webgpuCacheRenderPipeline.js.map +1 -1
  8. package/Engines/WebGPU/webgpuCacheTextureView.d.ts +13 -0
  9. package/Engines/WebGPU/webgpuCacheTextureView.js +32 -0
  10. package/Engines/WebGPU/webgpuCacheTextureView.js.map +1 -0
  11. package/Engines/WebGPU/webgpuRenderTargetWrapper.d.ts +10 -0
  12. package/Engines/WebGPU/webgpuRenderTargetWrapper.js +10 -0
  13. package/Engines/WebGPU/webgpuRenderTargetWrapper.js.map +1 -1
  14. package/Engines/WebGPU/webgpuShaderProcessorsWGSL.pure.js +57 -4
  15. package/Engines/WebGPU/webgpuShaderProcessorsWGSL.pure.js.map +1 -1
  16. package/Engines/WebGPU/webgpuTextureManager.d.ts +1 -1
  17. package/Engines/WebGPU/webgpuTextureManager.js +4 -2
  18. package/Engines/WebGPU/webgpuTextureManager.js.map +1 -1
  19. package/Engines/abstractEngine.pure.js +2 -2
  20. package/Engines/abstractEngine.pure.js.map +1 -1
  21. package/Engines/thinNativeEngine.pure.d.ts +5 -0
  22. package/Engines/thinNativeEngine.pure.js +29 -6
  23. package/Engines/thinNativeEngine.pure.js.map +1 -1
  24. package/Engines/webgpuEngine.pure.d.ts +1 -0
  25. package/Engines/webgpuEngine.pure.js +21 -8
  26. package/Engines/webgpuEngine.pure.js.map +1 -1
  27. package/FlowGraph/Blocks/Data/Math/flowGraphMathBlocks.pure.d.ts +95 -1
  28. package/FlowGraph/Blocks/Data/Math/flowGraphMathBlocks.pure.js +169 -4
  29. package/FlowGraph/Blocks/Data/Math/flowGraphMathBlocks.pure.js.map +1 -1
  30. package/FlowGraph/Blocks/Data/Math/flowGraphMathCombineExtractBlocks.pure.d.ts +21 -6
  31. package/FlowGraph/Blocks/Data/Math/flowGraphMathCombineExtractBlocks.pure.js +28 -26
  32. package/FlowGraph/Blocks/Data/Math/flowGraphMathCombineExtractBlocks.pure.js.map +1 -1
  33. package/FlowGraph/Blocks/Data/Math/flowGraphMatrixMathBlocks.pure.d.ts +30 -2
  34. package/FlowGraph/Blocks/Data/Math/flowGraphMatrixMathBlocks.pure.js +111 -29
  35. package/FlowGraph/Blocks/Data/Math/flowGraphMatrixMathBlocks.pure.js.map +1 -1
  36. package/FlowGraph/Blocks/Data/Math/flowGraphVectorMathBlocks.pure.d.ts +56 -2
  37. package/FlowGraph/Blocks/Data/Math/flowGraphVectorMathBlocks.pure.js +99 -14
  38. package/FlowGraph/Blocks/Data/Math/flowGraphVectorMathBlocks.pure.js.map +1 -1
  39. package/FlowGraph/Blocks/Data/Transformers/flowGraphJsonPointerParserBlock.pure.js +10 -2
  40. package/FlowGraph/Blocks/Data/Transformers/flowGraphJsonPointerParserBlock.pure.js.map +1 -1
  41. package/FlowGraph/Blocks/Data/Utils/flowGraphArrayIndexBlock.pure.js +21 -1
  42. package/FlowGraph/Blocks/Data/Utils/flowGraphArrayIndexBlock.pure.js.map +1 -1
  43. package/FlowGraph/Blocks/Data/flowGraphCachedOperationBlock.d.ts +18 -0
  44. package/FlowGraph/Blocks/Data/flowGraphCachedOperationBlock.js +29 -2
  45. package/FlowGraph/Blocks/Data/flowGraphCachedOperationBlock.js.map +1 -1
  46. package/FlowGraph/Blocks/Event/flowGraphReceiveCustomEventBlock.pure.d.ts +15 -0
  47. package/FlowGraph/Blocks/Event/flowGraphReceiveCustomEventBlock.pure.js +44 -7
  48. package/FlowGraph/Blocks/Event/flowGraphReceiveCustomEventBlock.pure.js.map +1 -1
  49. package/FlowGraph/Blocks/Event/flowGraphSceneReadyEventBlock.pure.d.ts +9 -0
  50. package/FlowGraph/Blocks/Event/flowGraphSceneReadyEventBlock.pure.js +9 -1
  51. package/FlowGraph/Blocks/Event/flowGraphSceneReadyEventBlock.pure.js.map +1 -1
  52. package/FlowGraph/Blocks/Event/flowGraphSceneTickEventBlock.pure.d.ts +7 -0
  53. package/FlowGraph/Blocks/Event/flowGraphSceneTickEventBlock.pure.js +8 -1
  54. package/FlowGraph/Blocks/Event/flowGraphSceneTickEventBlock.pure.js.map +1 -1
  55. package/FlowGraph/Blocks/Event/flowGraphStopEventPropagationBlock.d.ts +5 -0
  56. package/FlowGraph/Blocks/Event/flowGraphStopEventPropagationBlock.js +8 -0
  57. package/FlowGraph/Blocks/Event/flowGraphStopEventPropagationBlock.js.map +1 -0
  58. package/FlowGraph/Blocks/Event/flowGraphStopEventPropagationBlock.pure.d.ts +37 -0
  59. package/FlowGraph/Blocks/Event/flowGraphStopEventPropagationBlock.pure.js +44 -0
  60. package/FlowGraph/Blocks/Event/flowGraphStopEventPropagationBlock.pure.js.map +1 -0
  61. package/FlowGraph/Blocks/Event/index.d.ts +1 -0
  62. package/FlowGraph/Blocks/Event/index.js +1 -0
  63. package/FlowGraph/Blocks/Event/index.js.map +1 -1
  64. package/FlowGraph/Blocks/Event/pure.d.ts +1 -0
  65. package/FlowGraph/Blocks/Event/pure.js +1 -0
  66. package/FlowGraph/Blocks/Event/pure.js.map +1 -1
  67. package/FlowGraph/Blocks/Execution/Animation/flowGraphBezierCurveEasingBlock.pure.d.ts +4 -1
  68. package/FlowGraph/Blocks/Execution/Animation/flowGraphBezierCurveEasingBlock.pure.js +67 -2
  69. package/FlowGraph/Blocks/Execution/Animation/flowGraphBezierCurveEasingBlock.pure.js.map +1 -1
  70. package/FlowGraph/Blocks/Execution/Animation/flowGraphPlayAnimationBlock.pure.d.ts +13 -0
  71. package/FlowGraph/Blocks/Execution/Animation/flowGraphPlayAnimationBlock.pure.js +102 -7
  72. package/FlowGraph/Blocks/Execution/Animation/flowGraphPlayAnimationBlock.pure.js.map +1 -1
  73. package/FlowGraph/Blocks/Execution/Animation/flowGraphStopAnimationBlock.pure.js +5 -1
  74. package/FlowGraph/Blocks/Execution/Animation/flowGraphStopAnimationBlock.pure.js.map +1 -1
  75. package/FlowGraph/Blocks/Execution/ControlFlow/flowGraphCancelDelayBlock.pure.js +5 -1
  76. package/FlowGraph/Blocks/Execution/ControlFlow/flowGraphCancelDelayBlock.pure.js.map +1 -1
  77. package/FlowGraph/Blocks/Execution/ControlFlow/flowGraphForLoopBlock.pure.d.ts +11 -2
  78. package/FlowGraph/Blocks/Execution/ControlFlow/flowGraphForLoopBlock.pure.js +21 -3
  79. package/FlowGraph/Blocks/Execution/ControlFlow/flowGraphForLoopBlock.pure.js.map +1 -1
  80. package/FlowGraph/Blocks/Execution/ControlFlow/flowGraphSetDelayBlock.pure.js +25 -4
  81. package/FlowGraph/Blocks/Execution/ControlFlow/flowGraphSetDelayBlock.pure.js.map +1 -1
  82. package/FlowGraph/Blocks/flowGraphBlockFactory.js +18 -0
  83. package/FlowGraph/Blocks/flowGraphBlockFactory.js.map +1 -1
  84. package/FlowGraph/Blocks/flowGraphBlockNames.d.ts +9 -0
  85. package/FlowGraph/Blocks/flowGraphBlockNames.js +9 -0
  86. package/FlowGraph/Blocks/flowGraphBlockNames.js.map +1 -1
  87. package/FlowGraph/CustomTypes/flowGraphMatrix.d.ts +17 -3
  88. package/FlowGraph/CustomTypes/flowGraphMatrix.js +27 -21
  89. package/FlowGraph/CustomTypes/flowGraphMatrix.js.map +1 -1
  90. package/FlowGraph/flowGraphContext.d.ts +23 -0
  91. package/FlowGraph/flowGraphContext.js +29 -0
  92. package/FlowGraph/flowGraphContext.js.map +1 -1
  93. package/FlowGraph/flowGraphCoordinator.d.ts +58 -1
  94. package/FlowGraph/flowGraphCoordinator.js +72 -0
  95. package/FlowGraph/flowGraphCoordinator.js.map +1 -1
  96. package/FlowGraph/flowGraphDelayRegistry.d.ts +31 -0
  97. package/FlowGraph/flowGraphDelayRegistry.js +50 -0
  98. package/FlowGraph/flowGraphDelayRegistry.js.map +1 -0
  99. package/FlowGraph/flowGraphHostResolver.d.ts +69 -0
  100. package/FlowGraph/flowGraphHostResolver.js +25 -0
  101. package/FlowGraph/flowGraphHostResolver.js.map +1 -0
  102. package/FlowGraph/flowGraphMath.d.ts +48 -1
  103. package/FlowGraph/flowGraphMath.js +169 -4
  104. package/FlowGraph/flowGraphMath.js.map +1 -1
  105. package/FlowGraph/flowGraphPathConverterComponent.d.ts +14 -3
  106. package/FlowGraph/flowGraphPathConverterComponent.js +110 -18
  107. package/FlowGraph/flowGraphPathConverterComponent.js.map +1 -1
  108. package/FlowGraph/flowGraphSignalConnection.pure.js +7 -1
  109. package/FlowGraph/flowGraphSignalConnection.pure.js.map +1 -1
  110. package/FlowGraph/index.d.ts +2 -0
  111. package/FlowGraph/index.js +2 -0
  112. package/FlowGraph/index.js.map +1 -1
  113. package/FlowGraph/pure.d.ts +2 -0
  114. package/FlowGraph/pure.js +2 -0
  115. package/FlowGraph/pure.js.map +1 -1
  116. package/Maths/math.vector.pure.d.ts +10 -0
  117. package/Maths/math.vector.pure.js +13 -0
  118. package/Maths/math.vector.pure.js.map +1 -1
  119. package/Meshes/GaussianSplatting/gaussianSplattingMesh.pure.d.ts +216 -1
  120. package/Meshes/GaussianSplatting/gaussianSplattingMesh.pure.js +714 -67
  121. package/Meshes/GaussianSplatting/gaussianSplattingMesh.pure.js.map +1 -1
  122. package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.d.ts +81 -4
  123. package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.js +466 -52
  124. package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.js.map +1 -1
  125. package/Meshes/GaussianSplatting/gaussianSplattingPartProxyMesh.pure.d.ts +19 -0
  126. package/Meshes/GaussianSplatting/gaussianSplattingPartProxyMesh.pure.js +24 -0
  127. package/Meshes/GaussianSplatting/gaussianSplattingPartProxyMesh.pure.js.map +1 -1
  128. package/Meshes/GaussianSplatting/gaussianSplattingSortWorker.js +31 -6
  129. package/Meshes/GaussianSplatting/gaussianSplattingSortWorker.js.map +1 -1
  130. package/Meshes/GreasedLine/greasedLineRibbonMesh.pure.js +5 -1
  131. package/Meshes/GreasedLine/greasedLineRibbonMesh.pure.js.map +1 -1
  132. package/Misc/greasedLineTools.js +1 -1
  133. package/Misc/greasedLineTools.js.map +1 -1
  134. package/Misc/tools.pure.js +14 -2
  135. package/Misc/tools.pure.js.map +1 -1
  136. package/Particles/gpuParticleSystem.pure.d.ts +66 -1
  137. package/Particles/gpuParticleSystem.pure.js +189 -49
  138. package/Particles/gpuParticleSystem.pure.js.map +1 -1
  139. package/Physics/v2/characterController.js +69 -17
  140. package/Physics/v2/characterController.js.map +1 -1
  141. package/XR/features/Layers/WebXRWebGPUCompositionLayer.d.ts +3 -9
  142. package/XR/features/Layers/WebXRWebGPUCompositionLayer.js +4 -11
  143. package/XR/features/Layers/WebXRWebGPUCompositionLayer.js.map +1 -1
  144. package/XR/features/WebXRAbstractFeature.d.ts +9 -0
  145. package/XR/features/WebXRAbstractFeature.js +16 -0
  146. package/XR/features/WebXRAbstractFeature.js.map +1 -1
  147. package/XR/features/WebXRDepthSensing.pure.d.ts +7 -0
  148. package/XR/features/WebXRDepthSensing.pure.js +350 -39
  149. package/XR/features/WebXRDepthSensing.pure.js.map +1 -1
  150. package/XR/features/WebXRImageTracking.pure.js.map +1 -1
  151. package/XR/features/WebXRLayers.pure.d.ts +6 -5
  152. package/XR/features/WebXRLayers.pure.js +65 -8
  153. package/XR/features/WebXRLayers.pure.js.map +1 -1
  154. package/XR/features/WebXRRawCameraAccess.pure.js +9 -2
  155. package/XR/features/WebXRRawCameraAccess.pure.js.map +1 -1
  156. package/XR/features/WebXRSpaceWarp.pure.d.ts +0 -1
  157. package/XR/features/WebXRSpaceWarp.pure.js +13 -4
  158. package/XR/features/WebXRSpaceWarp.pure.js.map +1 -1
  159. package/XR/features/WebXRWalkingLocomotion.pure.js.map +1 -1
  160. package/XR/webXRCamera.js +27 -0
  161. package/XR/webXRCamera.js.map +1 -1
  162. package/XR/webXRFeatureWarningRegistry.d.ts +14 -0
  163. package/XR/webXRFeatureWarningRegistry.js +19 -0
  164. package/XR/webXRFeatureWarningRegistry.js.map +1 -0
  165. package/XR/webXRFeaturesManager.d.ts +5 -0
  166. package/XR/webXRFeaturesManager.js +23 -4
  167. package/XR/webXRFeaturesManager.js.map +1 -1
  168. package/XR/webXRGraphicsBinding.d.ts +17 -10
  169. package/XR/webXRGraphicsBinding.js +8 -5
  170. package/XR/webXRGraphicsBinding.js.map +1 -1
  171. package/XR/webXRSessionManager.d.ts +3 -5
  172. package/XR/webXRSessionManager.js +1 -3
  173. package/XR/webXRSessionManager.js.map +1 -1
  174. package/XR/webXRWebGPURenderTargetTextureProvider.d.ts +21 -5
  175. package/XR/webXRWebGPURenderTargetTextureProvider.js +38 -10
  176. package/XR/webXRWebGPURenderTargetTextureProvider.js.map +1 -1
  177. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"gaussianSplattingMesh.pure.js","sourceRoot":"","sources":["../../../../../dev/core/src/Meshes/GaussianSplatting/gaussianSplattingMesh.pure.ts"],"names":[],"mappings":"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","sourcesContent":["/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"core/types\";\r\nimport { type Scene } from \"core/scene.pure\";\r\nimport { Matrix, Quaternion, Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { type Vector2 } from \"core/Maths/math.vector\";\r\nimport { type Effect } from \"core/Materials/effect.pure\";\r\nimport { GetGaussianSplattingMaxPartCount } from \"core/Materials/GaussianSplatting/gaussianSplattingMaterial.pure\";\r\nimport { GaussianSplattingMeshBase, AllocateShBuffers } from \"./gaussianSplattingMeshBase.pure\";\r\nimport { GaussianSplattingSortWorkerCommand } from \"./gaussianSplattingSortWorker\";\r\nimport { RawTexture } from \"core/Materials/Textures/rawTexture\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { DecodeBase64ToBinary, EncodeArrayBufferToBase64 } from \"core/Misc/stringTools\";\r\nimport { Mesh } from \"core/Meshes/mesh.pure\";\r\nimport { GaussianSplattingPartProxyMesh } from \"./gaussianSplattingPartProxyMesh.pure\";\r\nimport { BoundingInfo } from \"../../Culling/boundingInfo\";\r\nimport { type BaseTexture } from \"../../Materials/Textures/baseTexture.pure\";\r\nimport { type AbstractMesh } from \"core/Meshes/abstractMesh.pure\";\r\n\r\nconst _GaussianSplattingBytesPerSplat = 32;\r\nconst _GaussianSplattingBytesPerShTexel = 16;\r\n\r\ninterface IGaussianSplattingPartSource {\r\n name: string;\r\n _vertexCount: number;\r\n _splatsData: Nullable<ArrayBuffer | ArrayBufferView>;\r\n _shData: Nullable<Uint8Array[]>;\r\n _shDegree: number;\r\n isCompound: boolean;\r\n getWorldMatrix(): Matrix;\r\n getBoundingInfo(): BoundingInfo;\r\n dispose(): void;\r\n}\r\n\r\n/**\r\n * Run-Length Encoding (RLE) compression for serialization\r\n * Compressed Uint32Array can be parsed using {@link ParsePartIndices}\r\n * Some notes for devs: We do not expect Uint8Array larger than 4GB,\r\n * so it should be safe to use Uint32Array.\r\n * @param partIndices A view of partIndices from GaussianSplattingMesh\r\n * @returns A compressed Uint32Array of [count, value, ...]\r\n */\r\nfunction CompressPartIndices(partIndices: Uint8Array): Uint32Array {\r\n const runs: number[] = [];\r\n const length = partIndices.length;\r\n let i = 0;\r\n while (i < length) {\r\n const value = partIndices[i];\r\n let count = 1;\r\n while (i + count < length && partIndices[i + count] === value) {\r\n count++;\r\n }\r\n runs.push(count, value);\r\n i += count;\r\n }\r\n return new Uint32Array(runs);\r\n}\r\n\r\n/**\r\n * Parse partIndices compressed by {@link CompressPartIndices} to runtime array\r\n * @param compressed The compressed partIndices of [count, value, ...]\r\n * @returns runtime Uint8Array for GaussianSplattingMesh\r\n */\r\nfunction ParsePartIndices(compressed: Uint32Array | number[]): Uint8Array {\r\n let totalCount = 0;\r\n const length = compressed.length;\r\n for (let i = 0; i < length; i += 2) {\r\n totalCount += compressed[i];\r\n }\r\n\r\n const partIndices = new Uint8Array(totalCount);\r\n let offset = 0;\r\n for (let i = 0; i < length; i += 2) {\r\n const count = compressed[i];\r\n const value = compressed[i + 1];\r\n partIndices.fill(value, offset, offset + count);\r\n offset += count;\r\n }\r\n\r\n return partIndices;\r\n}\r\n\r\n/**\r\n * Class used to render a Gaussian Splatting mesh. Supports both single-cloud and compound\r\n * (multi-part) rendering. In compound mode, multiple Gaussian Splatting source meshes are\r\n * merged into one draw call while retaining per-part world-matrix control via\r\n * addPart/addParts and removePart.\r\n */\r\nexport class GaussianSplattingMesh extends GaussianSplattingMeshBase {\r\n /**\r\n * Proxy meshes indexed by part index. Maintained in sync with _partMatrices.\r\n */\r\n private _partProxies: GaussianSplattingPartProxyMesh[] = [];\r\n\r\n /** Part 0 local-space AABB when owned directly (not proxied). Set on first addPart, cleared on dispose/reset. */\r\n private _part0LocalMin: Nullable<Vector3> = null;\r\n private _part0LocalMax: Nullable<Vector3> = null;\r\n\r\n /**\r\n * World matrices for each part, indexed by part index.\r\n */\r\n protected _partMatrices: Matrix[] = [];\r\n\r\n /** When true, suppresses the sort trigger inside setWorldMatrixForPart during batch rebuilds. */\r\n private _rebuilding: boolean = false;\r\n\r\n /**\r\n * Visibility values for each part (0.0 to 1.0), indexed by part index.\r\n */\r\n protected _partVisibility: number[] = [];\r\n\r\n private _partIndicesTexture: Nullable<BaseTexture> = null;\r\n private _partIndices: Nullable<Uint8Array> = null;\r\n\r\n /** Gets the part indices texture used for compound rendering */\r\n public get partIndicesTexture() {\r\n return this._partIndicesTexture;\r\n }\r\n\r\n /**\r\n * Creates a new GaussianSplattingMesh\r\n * @param name the name of the mesh\r\n * @param url optional URL to load a Gaussian Splatting file from\r\n * @param scene the hosting scene\r\n * @param keepInRam whether to keep the raw splat data in RAM after uploading to GPU\r\n * @param needsRotationScaleTextures generate rotation and scale matrix textures required for voxel-based IBL shadows\r\n */\r\n constructor(name: string, url: Nullable<string> = null, scene: Nullable<Scene> = null, keepInRam: boolean = false, needsRotationScaleTextures: boolean = false) {\r\n super(name, url, scene, keepInRam);\r\n // Ensure _splatsData is retained once compound mode is entered — addPart/addParts need\r\n // the source data for full-texture rebuilds. Set after super() so it is visible to\r\n // _updateData when the async load completes.\r\n this._alwaysRetainSplatsData = true;\r\n this._needsRotationScaleTextures = needsRotationScaleTextures;\r\n }\r\n\r\n /**\r\n * Returns the class name\r\n * @returns \"GaussianSplattingMesh\"\r\n */\r\n public override getClassName(): string {\r\n return \"GaussianSplattingMesh\";\r\n }\r\n\r\n /**\r\n * Is this node ready to be used/rendered.\r\n * Force-syncs every part proxy's world matrix into `_partMatrices` BEFORE delegating to\r\n * the base readiness check. This guarantees that any pending proxy transform changes\r\n * (for example a user-set `proxy.position`) are reflected in the next sort post, so the\r\n * base `isReady` will only return true once `sortAppliedId === sortRequestId` for that\r\n * up-to-date state. Without this, the proxy's `onAfterWorldMatrixUpdateObservable` would\r\n * fire during the first render and queue a fresh sort AFTER readiness was reported,\r\n * leaving the rendered frame with stale splat order on `renderCount=1` runs.\r\n * @param completeCheck defines if a complete check (including materials and lights) has to be done (false by default)\r\n * @returns true when ready\r\n */\r\n public override isReady(completeCheck = false): boolean {\r\n for (const proxy of this._partProxies) {\r\n if (proxy) {\r\n proxy.computeWorldMatrix(true);\r\n }\r\n }\r\n return super.isReady(completeCheck);\r\n }\r\n\r\n /**\r\n * Recomputes compound local-space bounds from part 0's stored AABB (if unproxied) plus all\r\n * proxy world AABBs inverse-transformed to compound-local space. All 8 corners of each proxy\r\n * AABB are transformed so the result is correct under non-identity compound rotation/scale.\r\n */\r\n private _updateBoundingInfoFromProxies(): void {\r\n const compoundWorld = this.getWorldMatrix();\r\n const invCompoundWorld = Matrix.Invert(compoundWorld);\r\n\r\n const localMin = this._part0LocalMin ? this._part0LocalMin.clone() : new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n const localMax = this._part0LocalMax ? this._part0LocalMax.clone() : new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\r\n\r\n const corner = new Vector3();\r\n for (const proxy of this._partProxies) {\r\n if (!proxy) {\r\n continue;\r\n }\r\n // Proxies have no geometry — getHierarchyBoundingVectors returns sentinels. Use boundingBox directly.\r\n proxy.computeWorldMatrix(false);\r\n const bb = proxy.getBoundingInfo().boundingBox;\r\n const wMin = bb.minimumWorld;\r\n const wMax = bb.maximumWorld;\r\n for (let b = 0; b < 8; b++) {\r\n corner.set(b & 1 ? wMax.x : wMin.x, b & 2 ? wMax.y : wMin.y, b & 4 ? wMax.z : wMin.z);\r\n Vector3.TransformCoordinatesToRef(corner, invCompoundWorld, corner);\r\n localMin.minimizeInPlace(corner);\r\n localMax.maximizeInPlace(corner);\r\n }\r\n }\r\n\r\n if (localMin.x <= localMax.x) {\r\n // Direct access avoids getBoundingInfo() → _updateBoundingInfo() recursion.\r\n if (this._boundingInfo) {\r\n this._boundingInfo.reConstruct(localMin, localMax, compoundWorld);\r\n } else {\r\n this._boundingInfo = new BoundingInfo(localMin, localMax, compoundWorld);\r\n }\r\n this._cachedBoundingMin = localMin.clone();\r\n this._cachedBoundingMax = localMax.clone();\r\n }\r\n }\r\n\r\n /**\r\n * Override for compound meshes: recomputes bounds from proxy world extents instead of\r\n * local bounds × world matrix, which is wrong for proxied parts with independent transforms.\r\n * @returns this mesh\r\n */\r\n public override _updateBoundingInfo(): AbstractMesh {\r\n if (this.isCompound) {\r\n this._updateBoundingInfoFromProxies();\r\n this._updateSubMeshesBoundingInfo(this.worldMatrixFromCache);\r\n return this;\r\n }\r\n return super._updateBoundingInfo();\r\n }\r\n\r\n /**\r\n * Replaces the base hierarchy bounds computation for compound meshes: computes world bounds\r\n * from scratch by iterating part 0's local AABB and all proxy meshes, rather than delegating\r\n * to the base _children traversal which never reaches proxies (they are not parented to the\r\n * compound). Visibility per-part is respected; invisible parts are excluded.\r\n * @param includeDescendants when true, includes descendants (default: true)\r\n * @param predicate optional filter predicate\r\n * @returns world-space min/max of the hierarchy bounding box\r\n */\r\n public override getHierarchyBoundingVectors(\r\n includeDescendants: boolean = true,\r\n predicate: Nullable<(abstractMesh: AbstractMesh) => boolean> = null\r\n ): { min: Vector3; max: Vector3 } {\r\n if (!this.isCompound) {\r\n return super.getHierarchyBoundingVectors(includeDescendants, predicate);\r\n }\r\n // For compound meshes, compute visible-only world bounds from scratch so that\r\n // invisible parts don't inflate the result (e.g. for voxelization scene bounds).\r\n const min = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n const max = new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\r\n // Unproxied part 0: the compound mesh owns this geometry directly (no proxy node).\r\n // Transform its local AABB to world space if visible.\r\n if (this._part0LocalMin && (this._partVisibility[0] ?? 1.0) > 0) {\r\n const wm = this.getWorldMatrix();\r\n const lMin = this._part0LocalMin;\r\n const lMax = this._part0LocalMax!;\r\n const corner = new Vector3();\r\n for (let b = 0; b < 8; b++) {\r\n corner.set(b & 1 ? lMax.x : lMin.x, b & 2 ? lMax.y : lMin.y, b & 4 ? lMax.z : lMin.z);\r\n Vector3.TransformCoordinatesToRef(corner, wm, corner);\r\n min.minimizeInPlace(corner);\r\n max.maximizeInPlace(corner);\r\n }\r\n }\r\n for (let i = 0; i < this._partProxies.length; i++) {\r\n const proxy = this._partProxies[i];\r\n if (!proxy || (this._partVisibility[i] ?? 1.0) === 0) {\r\n continue;\r\n }\r\n proxy.computeWorldMatrix(false);\r\n const bb = proxy.getBoundingInfo().boundingBox;\r\n min.minimizeInPlace(bb.minimumWorld);\r\n max.maximizeInPlace(bb.maximumWorld);\r\n }\r\n return { min, max };\r\n }\r\n\r\n /**\r\n * Disposes proxy meshes and clears part data in addition to the base class GPU resources.\r\n * @param doNotRecurse Set to true to not recurse into each children\r\n */\r\n public override dispose(doNotRecurse?: boolean): void {\r\n for (const proxy of this._partProxies) {\r\n proxy.dispose();\r\n }\r\n this._partIndicesTexture?.dispose();\r\n this._partProxies = [];\r\n this._partMatrices = [];\r\n this._partVisibility = [];\r\n this._partIndicesTexture = null;\r\n this._part0LocalMin = null;\r\n this._part0LocalMax = null;\r\n super.dispose(doNotRecurse);\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Worker and material hooks\r\n // ---------------------------------------------------------------------------\r\n\r\n /**\r\n * Posts the initial per-part data to the sort worker after it has been created.\r\n * Sends the current part matrices and group index array so the worker can correctly\r\n * weight depth values per part.\r\n * @param worker the newly created sort worker\r\n */\r\n protected override _onWorkerCreated(worker: Worker): void {\r\n worker.postMessage({ command: GaussianSplattingSortWorkerCommand.PART_MATRICES, partMatrices: this._partMatrices.map((matrix) => new Float32Array(matrix.m)) });\r\n worker.postMessage({ command: GaussianSplattingSortWorkerCommand.PART_INDICES, partIndices: this._partIndices ? new Uint8Array(this._partIndices) : null });\r\n }\r\n\r\n /**\r\n * Stores the raw part index array, padded to texture length, so the worker and GPU texture\r\n * creation step have access to it.\r\n * @param partIndices - the raw part indices array received during a data load\r\n * @param textureLength - the padded texture length to allocate into\r\n */\r\n protected override _onIndexDataReceived(partIndices: Uint8Array, textureLength: number): void {\r\n this._partIndices = new Uint8Array(textureLength);\r\n this._partIndices.set(partIndices);\r\n }\r\n\r\n /**\r\n * Returns `true` when at least one part has been added to this compound mesh.\r\n * Returns `false` before any parts are added, so the mesh renders in normal\r\n * (non-compound) mode until the first addPart/addParts call. This matches the\r\n * old base-class behavior of `this._partMatrices.length > 0` and avoids\r\n * binding unset partWorld uniforms (which would cause division-by-zero in the\r\n * Gaussian projection Jacobian and produce huge distorted splats).\r\n * @internal\r\n */\r\n public override get isCompound(): boolean {\r\n return this._partMatrices.length > 0;\r\n }\r\n\r\n /**\r\n * During a removePart rebuild, keep the existing sort worker alive rather than\r\n * tearing it down and spinning up a new one. This avoids startup latency and the\r\n * transient state window where a stale sort could fire against an incomplete\r\n * partMatrices array.\r\n * Outside of a rebuild the base-class behaviour is used unchanged.\r\n */\r\n protected override _instantiateWorker(): void {\r\n if (this._rebuilding && this._worker) {\r\n // Worker already exists and is kept alive; just resize the splat-index buffer.\r\n this._updateSplatIndexBuffer(this._vertexCount);\r\n return;\r\n }\r\n super._instantiateWorker();\r\n }\r\n\r\n /**\r\n * Ensures the part-index GPU texture exists at the start of an incremental update.\r\n * Called before the sub-texture upload so the correct texture is available for the first batch.\r\n * @param textureSize - current texture dimensions\r\n */\r\n protected override _onIncrementalUpdateStart(textureSize: Vector2): void {\r\n this._ensurePartIndicesTexture(textureSize, this._partIndices ?? undefined);\r\n }\r\n\r\n /**\r\n * Posts positions (via super) and then additionally posts the current part-index array\r\n * to the sort worker so it can associate each splat with its part.\r\n */\r\n protected override _notifyWorkerNewData(): void {\r\n super._notifyWorkerNewData();\r\n if (this._worker) {\r\n this._worker.postMessage({ command: GaussianSplattingSortWorkerCommand.PART_INDICES, partIndices: this._partIndices ?? null });\r\n }\r\n }\r\n\r\n /**\r\n * Binds all compound-specific shader uniforms: the group index texture, per-part world\r\n * matrices, and per-part visibility values.\r\n * @param effect the shader effect that is being bound\r\n * @internal\r\n */\r\n public override bindExtraEffectUniforms(effect: Effect): void {\r\n if (!this._partIndicesTexture) {\r\n return;\r\n }\r\n effect.setTexture(\"partIndicesTexture\", this._partIndicesTexture);\r\n const partWorldData = new Float32Array(this.partCount * 16);\r\n for (let i = 0; i < this.partCount; i++) {\r\n this._partMatrices[i].toArray(partWorldData, i * 16);\r\n }\r\n effect.setMatrices(\"partWorld\", partWorldData);\r\n const partVisibilityData: number[] = [];\r\n for (let i = 0; i < this.partCount; i++) {\r\n partVisibilityData.push(this._partVisibility[i] ?? 1.0);\r\n }\r\n effect.setArray(\"partVisibility\", partVisibilityData);\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Part matrix / visibility management\r\n // ---------------------------------------------------------------------------\r\n\r\n /**\r\n * Gets the number of parts in the compound.\r\n */\r\n public get partCount(): number {\r\n return this._partMatrices.length;\r\n }\r\n\r\n /**\r\n * Gets the part visibility array.\r\n */\r\n public get partVisibility(): number[] {\r\n return this._partVisibility;\r\n }\r\n\r\n /**\r\n * Sets the world matrix for a specific part of the compound.\r\n * This will trigger a re-sort of the mesh.\r\n * The `_partMatrices` array is automatically extended when `partIndex >= partCount`.\r\n * @param partIndex index of the part\r\n * @param worldMatrix the world matrix to set\r\n */\r\n public setWorldMatrixForPart(partIndex: number, worldMatrix: Matrix): void {\r\n if (this._partMatrices.length <= partIndex) {\r\n this.computeWorldMatrix(true);\r\n const defaultMatrix = this.getWorldMatrix();\r\n while (this._partMatrices.length <= partIndex) {\r\n this._partMatrices.push(defaultMatrix.clone());\r\n this._partVisibility.push(1.0);\r\n }\r\n }\r\n // Skip the post / sort if the matrix is unchanged. Babylon recomputes the proxy mesh's world matrix every frame\r\n // and fires onAfterWorldMatrixUpdateObservable, so without this guard a stable scene would queue a forced sort\r\n // every frame and `isReady()` would never settle (sortRequestId would keep advancing past sortAppliedId).\r\n if (this._partMatrices[partIndex].equals(worldMatrix)) {\r\n return;\r\n }\r\n this._partMatrices[partIndex].copyFrom(worldMatrix);\r\n // During a batch rebuild suppress intermediate posts — the final correct set is posted\r\n // once the full rebuild completes (at the end of removePart).\r\n if (!this._rebuilding) {\r\n if (this._worker) {\r\n this._worker.postMessage({\r\n command: GaussianSplattingSortWorkerCommand.PART_MATRICES,\r\n partMatrices: this._partMatrices.map((matrix) => new Float32Array(matrix.m)),\r\n });\r\n }\r\n this._postToWorker(true);\r\n }\r\n }\r\n\r\n /**\r\n * Gets the world matrix for a specific part of the compound.\r\n * @param partIndex index of the part, that must be between 0 and partCount - 1\r\n * @returns the world matrix for the part, or the current world matrix of the mesh if the part is not found\r\n */\r\n public getWorldMatrixForPart(partIndex: number): Matrix {\r\n return this._partMatrices[partIndex] ?? this.getWorldMatrix();\r\n }\r\n\r\n /**\r\n * Gets the visibility for a specific part of the compound.\r\n * @param partIndex index of the part, that must be between 0 and partCount - 1\r\n * @returns the visibility value (0.0 to 1.0) for the part\r\n */\r\n public getPartVisibility(partIndex: number): number {\r\n return this._partVisibility[partIndex] ?? 1.0;\r\n }\r\n\r\n /**\r\n * Sets the visibility for a specific part of the compound.\r\n * @param partIndex index of the part, that must be between 0 and partCount - 1\r\n * @param value the visibility value (0.0 to 1.0) to set\r\n */\r\n public setPartVisibility(partIndex: number, value: number): void {\r\n this._partVisibility[partIndex] = Math.max(0.0, Math.min(1.0, value));\r\n }\r\n\r\n protected override _copyTextures(source: GaussianSplattingMeshBase): void {\r\n super._copyTextures(source);\r\n this._partIndicesTexture = (source as GaussianSplattingMesh)._partIndicesTexture?.clone()!;\r\n }\r\n\r\n protected override _onUpdateTextures(textureSize: Vector2) {\r\n const createTextureFromDataU8 = (data: Uint8Array, width: number, height: number, format: number) => {\r\n return new RawTexture(data, width, height, format, this._scene, false, false, Constants.TEXTURE_BILINEAR_SAMPLINGMODE, Constants.TEXTURETYPE_UNSIGNED_BYTE);\r\n };\r\n\r\n // Keep the part indices texture in sync with _partIndices whenever textures are rebuilt.\r\n // The old \"only create if absent\" logic left the texture stale after a second addPart/addParts\r\n // call that doesn't change the texture dimensions: all new splats kept reading partIndex=0\r\n // (the first part), causing wrong positions, broken GPU picking, and shared movement.\r\n if (this._partIndices) {\r\n const buffer = new Uint8Array(this._partIndices);\r\n if (!this._partIndicesTexture) {\r\n this._partIndicesTexture = createTextureFromDataU8(buffer, textureSize.x, textureSize.y, Constants.TEXTUREFORMAT_RED);\r\n this._partIndicesTexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n this._partIndicesTexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n } else {\r\n const existingSize = this._partIndicesTexture.getSize();\r\n if (existingSize.width !== textureSize.x || existingSize.height !== textureSize.y) {\r\n // Dimensions changed — dispose and recreate at the new size.\r\n this._partIndicesTexture.dispose();\r\n this._partIndicesTexture = createTextureFromDataU8(buffer, textureSize.x, textureSize.y, Constants.TEXTUREFORMAT_RED);\r\n this._partIndicesTexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n this._partIndicesTexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n } else {\r\n // Same size — update data in-place (e.g. second addParts fitting in existing dims).\r\n this._updateTextureFromData(this._partIndicesTexture, buffer, textureSize.x, 0, textureSize.y);\r\n }\r\n }\r\n }\r\n }\r\n\r\n protected override _updateSubTextures(\r\n splatPositions: Float32Array,\r\n covA: Uint16Array,\r\n covB: Uint16Array,\r\n colorArray: Uint8Array,\r\n lineStart: number,\r\n lineCount: number,\r\n sh?: Uint8Array[],\r\n partIndices?: Uint8Array\r\n ): void {\r\n super._updateSubTextures(splatPositions, covA, covB, colorArray, lineStart, lineCount, sh);\r\n if (partIndices && this._partIndicesTexture) {\r\n const textureSize = this._getTextureSize(this._vertexCount);\r\n const texelStart = lineStart * textureSize.x;\r\n const texelCount = lineCount * textureSize.x;\r\n const partIndicesView = new Uint8Array(partIndices.buffer, texelStart, texelCount);\r\n this._updateTextureFromData(this._partIndicesTexture, partIndicesView, textureSize.x, lineStart, lineCount);\r\n\r\n if (this._worker) {\r\n this._worker.postMessage({ command: GaussianSplattingSortWorkerCommand.PART_INDICES, partIndices: partIndices });\r\n }\r\n }\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Private helpers\r\n // ---------------------------------------------------------------------------\r\n\r\n /**\r\n * Creates the part indices GPU texture the first time an incremental addPart introduces\r\n * compound data. Has no effect if the texture already exists or no partIndices are provided.\r\n * @param textureSize - Current texture dimensions\r\n * @param partIndices - Part index data; if undefined the method is a no-op\r\n */\r\n protected _ensurePartIndicesTexture(textureSize: Vector2, partIndices: Uint8Array | undefined): void {\r\n if (!partIndices || this._partIndicesTexture) {\r\n return;\r\n }\r\n const buffer = new Uint8Array(this._partIndices!);\r\n this._partIndicesTexture = new RawTexture(\r\n buffer,\r\n textureSize.x,\r\n textureSize.y,\r\n Constants.TEXTUREFORMAT_RED,\r\n this._scene,\r\n false,\r\n false,\r\n Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\r\n Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n );\r\n this._partIndicesTexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n this._partIndicesTexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n if (this._worker) {\r\n this._worker.postMessage({ command: GaussianSplattingSortWorkerCommand.PART_INDICES, partIndices: partIndices ?? null });\r\n }\r\n }\r\n\r\n private _appendPartSourceToArrays(\r\n source: IGaussianSplattingPartSource,\r\n dstOffset: number,\r\n covA: Uint16Array,\r\n covB: Uint16Array,\r\n colorArray: Uint8Array,\r\n sh: Uint8Array[] | undefined,\r\n minimum: Vector3,\r\n maximum: Vector3\r\n ): void {\r\n this._appendSourceToArrays(source as unknown as GaussianSplattingMeshBase, dstOffset, covA, covB, colorArray, sh, minimum, maximum);\r\n }\r\n\r\n private _createRetainedPartSource(proxy: GaussianSplattingPartProxyMesh): Nullable<IGaussianSplattingPartSource> {\r\n if (!this._splatsData || (this._shDegree > 0 && !this._shData)) {\r\n return null;\r\n }\r\n\r\n const splatByteOffset = proxy._splatsDataOffset * _GaussianSplattingBytesPerSplat;\r\n const splatByteLength = proxy._vertexCount * _GaussianSplattingBytesPerSplat;\r\n const shByteOffset = proxy._shDataOffset * _GaussianSplattingBytesPerShTexel;\r\n const shByteLength = proxy._vertexCount * _GaussianSplattingBytesPerShTexel;\r\n const splatBytes = GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData);\r\n\r\n return {\r\n name: proxy.name,\r\n _vertexCount: proxy._vertexCount,\r\n _splatsData: splatBytes.subarray(splatByteOffset, splatByteOffset + splatByteLength),\r\n _shData: this._shData?.map((texture) => texture.subarray(shByteOffset, shByteOffset + shByteLength)) ?? null,\r\n _shDegree: this._shData ? this._shDegree : 0,\r\n isCompound: false,\r\n getWorldMatrix: () => proxy.getWorldMatrix(),\r\n getBoundingInfo: () => proxy.getBoundingInfo(),\r\n dispose: () => {},\r\n };\r\n }\r\n\r\n private _retainMergedPartData(existingVertexCount: number, totalCount: number, others: IGaussianSplattingPartSource[], shDegree: number): void {\r\n if (!this._keepInRam && !this._alwaysRetainSplatsData) {\r\n this._splatsData = null;\r\n this._shData = null;\r\n return;\r\n }\r\n\r\n const mergedSplatsData = new Uint8Array(totalCount * _GaussianSplattingBytesPerSplat);\r\n let splatByteOffset = 0;\r\n\r\n if (this._splatsData && existingVertexCount > 0) {\r\n mergedSplatsData.set(\r\n GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData).subarray(0, existingVertexCount * _GaussianSplattingBytesPerSplat),\r\n splatByteOffset\r\n );\r\n splatByteOffset += existingVertexCount * _GaussianSplattingBytesPerSplat;\r\n }\r\n\r\n for (const other of others) {\r\n if (!other._splatsData) {\r\n continue;\r\n }\r\n\r\n const splatByteLength = other._vertexCount * _GaussianSplattingBytesPerSplat;\r\n mergedSplatsData.set(GaussianSplattingMeshBase._GetSplatDataBytes(other._splatsData).subarray(0, splatByteLength), splatByteOffset);\r\n splatByteOffset += splatByteLength;\r\n }\r\n\r\n this._splatsData = mergedSplatsData.buffer;\r\n\r\n if (shDegree <= 0) {\r\n this._shData = null;\r\n return;\r\n }\r\n\r\n // Each SH texture holds one texel per splat; each texel is _GaussianSplattingBytesPerShTexel\r\n // bytes with one byte per scalar, so it carries that many scalars. Degree d has\r\n // ((d+1)^2 - 1) higher-order coefficients × 3 RGB = total scalars per splat; divide by texel capacity.\r\n const shTextureCount = Math.ceil((((shDegree + 1) * (shDegree + 1) - 1) * 3) / _GaussianSplattingBytesPerShTexel);\r\n const mergedShData = AllocateShBuffers(shTextureCount, totalCount * _GaussianSplattingBytesPerShTexel);\r\n\r\n let shByteOffset = 0;\r\n if (this._shData && existingVertexCount > 0) {\r\n const existingShByteLength = existingVertexCount * _GaussianSplattingBytesPerShTexel;\r\n for (let textureIndex = 0; textureIndex < mergedShData.length; textureIndex++) {\r\n if (textureIndex < this._shData.length) {\r\n mergedShData[textureIndex].set(this._shData[textureIndex].subarray(0, existingShByteLength), shByteOffset);\r\n }\r\n }\r\n shByteOffset += existingShByteLength;\r\n }\r\n\r\n for (const other of others) {\r\n const otherShByteLength = other._vertexCount * _GaussianSplattingBytesPerShTexel;\r\n if (other._shData) {\r\n for (let textureIndex = 0; textureIndex < mergedShData.length; textureIndex++) {\r\n if (textureIndex < other._shData.length) {\r\n mergedShData[textureIndex].set(other._shData[textureIndex].subarray(0, otherShByteLength), shByteOffset);\r\n }\r\n }\r\n }\r\n shByteOffset += otherShByteLength;\r\n }\r\n\r\n this._shData = mergedShData;\r\n }\r\n\r\n /**\r\n * Core implementation for adding one or more source parts as new\r\n * parts. Writes directly into texture-sized CPU arrays, updates the retained merged source\r\n * buffers, and uploads in one pass.\r\n *\r\n * @param others - Source meshes to append (must each be non-compound and fully loaded)\r\n * @param disposeOthers - Dispose source meshes after appending\r\n * @returns Proxy meshes and their assigned part indices\r\n */\r\n protected _addPartsInternal(others: IGaussianSplattingPartSource[], disposeOthers: boolean): { proxyMeshes: GaussianSplattingPartProxyMesh[]; assignedPartIndices: number[] } {\r\n if (others.length === 0) {\r\n return { proxyMeshes: [], assignedPartIndices: [] };\r\n }\r\n\r\n // Validate\r\n for (const other of others) {\r\n if (!other._splatsData) {\r\n throw new Error(`To call addPart()/addParts(), each source mesh must be fully loaded`);\r\n }\r\n if (other.isCompound) {\r\n throw new Error(`To call addPart()/addParts(), each source mesh must not be a compound`);\r\n }\r\n }\r\n\r\n const splatCountA = this._vertexCount;\r\n const totalOtherCount = others.reduce((s, o) => s + o._vertexCount, 0);\r\n const totalCount = splatCountA + totalOtherCount;\r\n\r\n const textureSize = this._getTextureSize(totalCount);\r\n const textureLength = textureSize.x * textureSize.y;\r\n const covBSItemSize = this._useRGBACovariants ? 4 : 2;\r\n\r\n // Allocate destination arrays for the full new texture\r\n const covA = new Uint16Array(textureLength * 4);\r\n const covB = new Uint16Array(covBSItemSize * textureLength);\r\n const colorArray = new Uint8Array(textureLength * 4);\r\n\r\n // Determine merged SH degree.\r\n // hasSH is true when the merged result will carry SH:\r\n // - Existing compound already has SH (_shDegree>0): preserve it even if new parts\r\n // have no SH — their texel region is pre-filled with 128 (neutral) by AllocateShBuffers.\r\n // - At least one new part carries SH: enable SH for the whole compound; existing\r\n // parts that had no SH also get neutral fill.\r\n // Deliberately excludes the case where the existing compound has no SH and no new part\r\n // has SH either (shDegreeNew stays 0, no SH textures allocated).\r\n const hasSH = this._shDegree > 0 || others.some((o) => o._shData !== null);\r\n const shDegreeNew = hasSH ? Math.max(this._shDegree, ...others.map((o) => o._shDegree)) : 0;\r\n let sh: Uint8Array[] | undefined = undefined;\r\n if (hasSH && shDegreeNew > 0) {\r\n // Each SH texture holds one texel per splat; each texel is _GaussianSplattingBytesPerShTexel\r\n // bytes with one byte per scalar, so it carries that many scalars. Degree d has\r\n // ((d+1)^2 - 1) higher-order coefficients × 3 RGB = total scalars per splat; divide by texel capacity.\r\n const shTextureCount = Math.ceil((((shDegreeNew + 1) * (shDegreeNew + 1) - 1) * 3) / _GaussianSplattingBytesPerShTexel);\r\n sh = AllocateShBuffers(shTextureCount, textureLength * _GaussianSplattingBytesPerShTexel);\r\n }\r\n\r\n // --- Incremental path: can we reuse the already-committed GPU region? ---\r\n const incremental = this._canReuseCachedData(splatCountA, totalCount);\r\n const firstNewLine = incremental ? Math.floor(splatCountA / textureSize.x) : 0;\r\n\r\n const minimum = incremental ? this._cachedBoundingMin!.clone() : new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n const maximum = incremental ? this._cachedBoundingMax!.clone() : new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\r\n\r\n // Preserve existing processed positions in the new array\r\n const oldPositions = this._splatPositions;\r\n this._splatPositions = new Float32Array(4 * textureLength);\r\n if (incremental && oldPositions) {\r\n this._splatPositions.set(oldPositions.subarray(0, splatCountA * 4));\r\n }\r\n\r\n // --- Build part indices ---\r\n let nextPartIndex = this.partCount;\r\n let partIndicesA = this._partIndices;\r\n if (!partIndicesA) {\r\n // First addPart on a plain mesh: assign its splats to part 0\r\n partIndicesA = new Uint8Array(splatCountA);\r\n nextPartIndex = splatCountA > 0 ? 1 : 0;\r\n }\r\n\r\n this._partIndices = new Uint8Array(textureLength);\r\n this._partIndices.set(partIndicesA.subarray(0, splatCountA));\r\n\r\n const assignedPartIndices: number[] = [];\r\n const assignedSplatsDataOffsets: number[] = [];\r\n let dstOffset = splatCountA;\r\n const maxPartCount = GetGaussianSplattingMaxPartCount(this._scene.getEngine());\r\n for (const other of others) {\r\n if (nextPartIndex >= maxPartCount) {\r\n throw new Error(`Cannot add part, as the maximum part count (${maxPartCount}) has been reached`);\r\n }\r\n const newPartIndex = nextPartIndex++;\r\n assignedPartIndices.push(newPartIndex);\r\n assignedSplatsDataOffsets.push(dstOffset);\r\n this._partIndices.fill(newPartIndex, dstOffset, dstOffset + other._vertexCount);\r\n dstOffset += other._vertexCount;\r\n }\r\n\r\n // --- Process source data ---\r\n if (!incremental) {\r\n // Full rebuild path — only reached when the GPU texture must be reallocated\r\n // (either the texture height needs to grow to fit the new total, or this is\r\n // the very first addPart onto a mesh with no GPU textures yet). In the common\r\n // case where the texture height is unchanged, `incremental` is true and this\r\n // entire block is skipped. The `splatCountA > 0` guard avoids redundant work\r\n // on the first-ever addPart when the compound mesh starts empty.\r\n if (splatCountA > 0) {\r\n if (this._partProxies.length > 0) {\r\n // Already compound: rebuild every existing part from its stored source data.\r\n //\r\n // DESIGN NOTE: The intended use of GaussianSplattingMesh / GaussianSplattingCompoundMesh\r\n // in compound mode is to start EMPTY and compose parts exclusively via addPart/addParts.\r\n // In a future major version this will be the only supported path and the \"own data\"\r\n // legacy branch below will be removed.\r\n //\r\n // Until then, two layouts are possible:\r\n // A) LEGACY — compound loaded its own splat data (via URL or updateData) before\r\n // any addPart call. _partProxies[0] is undefined; the mesh's own splat data\r\n // is treated as an implicit \"part 0\" in this._splatsData. Proxied parts occupy\r\n // indices 1+. This layout will be deprecated in the next major version.\r\n // B) PREFERRED — compound started empty; first addPart assigned partIndex=0.\r\n // _partProxies[0] is set; this._splatsData is null; all parts are proxied.\r\n let rebuildOffset = 0;\r\n\r\n // Rebuild the compound's legacy \"own\" data at part 0 (scenario A only).\r\n // Skipped in the preferred empty-composer path (scenario B).\r\n if (!this._partProxies[0] && this._splatsData) {\r\n const proxyVertexCount = this._partProxies.reduce((sum, proxy) => sum + (proxy ? proxy._vertexCount : 0), 0);\r\n const part0Count = splatCountA - proxyVertexCount;\r\n if (part0Count > 0) {\r\n const uBufA = GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData);\r\n const fBufA = GaussianSplattingMeshBase._GetSplatDataFloats(this._splatsData);\r\n for (let i = 0; i < part0Count; i++) {\r\n this._makeSplat(i, fBufA, uBufA, covA, covB, colorArray, minimum, maximum, false);\r\n }\r\n if (sh && this._shData) {\r\n for (let texIdx = 0; texIdx < sh.length; texIdx++) {\r\n if (texIdx < this._shData.length) {\r\n sh[texIdx].set(this._shData[texIdx].subarray(0, part0Count * _GaussianSplattingBytesPerShTexel), 0);\r\n }\r\n }\r\n }\r\n rebuildOffset += part0Count;\r\n }\r\n }\r\n\r\n // Rebuild all proxied parts. Loop from index 0 because in the preferred\r\n // scenario B, part 0 is itself a proxied part with no implicit \"own\" data.\r\n for (let partIndex = 0; partIndex < this._partProxies.length; partIndex++) {\r\n const proxy = this._partProxies[partIndex];\r\n if (!proxy) {\r\n continue;\r\n }\r\n const source = this._createRetainedPartSource(proxy);\r\n if (!source) {\r\n throw new Error(`Cannot rebuild compound part \"${proxy.name}\": the retained compound source data is not available.`);\r\n }\r\n this._appendPartSourceToArrays(source, rebuildOffset, covA, covB, colorArray, sh, minimum, maximum);\r\n rebuildOffset += source._vertexCount;\r\n }\r\n } else {\r\n // No proxies yet: this is the very first addPart call on a mesh that loaded\r\n // its own splat data (scenario A legacy path). Re-process that own data so\r\n // it occupies the start of the new texture before the incoming part is appended.\r\n // In the preferred scenario B (empty composer) splatCountA is 0 and this\r\n // entire branch is skipped by the outer `if (splatCountA > 0)` guard.\r\n if (this._splatsData) {\r\n const uBufA = GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData);\r\n const fBufA = GaussianSplattingMeshBase._GetSplatDataFloats(this._splatsData);\r\n for (let i = 0; i < splatCountA; i++) {\r\n this._makeSplat(i, fBufA, uBufA, covA, covB, colorArray, minimum, maximum, false);\r\n }\r\n if (sh && this._shData) {\r\n for (let texIdx = 0; texIdx < sh.length; texIdx++) {\r\n if (texIdx < this._shData.length) {\r\n sh[texIdx].set(this._shData[texIdx].subarray(0, splatCountA * _GaussianSplattingBytesPerShTexel), 0);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Incremental path: rebuild the partial first row (indices firstNewTexel to splatCountA-1)\r\n // so _updateSubTextures does not upload stale zeros over those already-committed texels.\r\n // The base-class _updateData always re-processes from firstNewTexel for the same reason;\r\n // the compound path must do the same.\r\n // Boundary-row SH is restored after _retainMergedPartData (see below), where _shData is ready.\r\n if (incremental) {\r\n const firstNewTexel = firstNewLine * textureSize.x;\r\n if (firstNewTexel < splatCountA) {\r\n if (this._partProxies.length === 0) {\r\n // No proxies: the mesh loaded its own splat data and this is the first\r\n // addPart call (scenario A legacy path). Re-process the partial boundary\r\n // row so it is not clobbered by stale zeros during the sub-texture upload.\r\n if (this._splatsData) {\r\n const uBufA = GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData);\r\n const fBufA = GaussianSplattingMeshBase._GetSplatDataFloats(this._splatsData);\r\n for (let i = firstNewTexel; i < splatCountA; i++) {\r\n this._makeSplat(i, fBufA, uBufA, covA, covB, colorArray, minimum, maximum, false, i);\r\n }\r\n }\r\n } else {\r\n // Already compound: build a per-partIndex source lookup so each splat in the\r\n // partial boundary row can be re-processed from its original source buffer.\r\n //\r\n // Handles both layouts (see full-rebuild comment above):\r\n // A) LEGACY: _partProxies[0] absent → seed lookup[0] with this._splatsData\r\n // B) PREFERRED: _partProxies[0] present → all entries filled from proxies\r\n const proxyTotal = this._partProxies.reduce((s, p) => s + (p ? p._vertexCount : 0), 0);\r\n const part0Count = splatCountA - proxyTotal; // > 0 only in legacy scenario A\r\n const srcUBufs: (Uint8Array | null)[] = new Array(this._partProxies.length).fill(null);\r\n const srcFBufs: (Float32Array | null)[] = new Array(this._partProxies.length).fill(null);\r\n const partStarts: number[] = new Array(this._partProxies.length).fill(0);\r\n // Legacy scenario A: part 0 is the mesh's own loaded data.\r\n if (!this._partProxies[0] && this._splatsData && part0Count > 0) {\r\n srcUBufs[0] = GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData);\r\n srcFBufs[0] = GaussianSplattingMeshBase._GetSplatDataFloats(this._splatsData);\r\n partStarts[0] = 0;\r\n }\r\n // All proxied parts — start from pi=0 to cover preferred scenario B.\r\n let cumOffset = part0Count;\r\n for (let pi = 0; pi < this._partProxies.length; pi++) {\r\n const proxy = this._partProxies[pi];\r\n if (!proxy) {\r\n continue;\r\n }\r\n const source = this._createRetainedPartSource(proxy);\r\n if (!source || !source._splatsData) {\r\n throw new Error(`Cannot rebuild compound part \"${proxy.name}\": the retained compound source data is not available.`);\r\n }\r\n srcUBufs[pi] = GaussianSplattingMeshBase._GetSplatDataBytes(source._splatsData);\r\n srcFBufs[pi] = GaussianSplattingMeshBase._GetSplatDataFloats(source._splatsData);\r\n partStarts[pi] = cumOffset;\r\n cumOffset += source._vertexCount;\r\n }\r\n for (let splatIdx = firstNewTexel; splatIdx < splatCountA; splatIdx++) {\r\n const partIdx = this._partIndices ? this._partIndices[splatIdx] : 0;\r\n const uBuf = partIdx < srcUBufs.length ? srcUBufs[partIdx] : null;\r\n const fBuf = partIdx < srcFBufs.length ? srcFBufs[partIdx] : null;\r\n if (uBuf && fBuf) {\r\n this._makeSplat(splatIdx, fBuf, uBuf, covA, covB, colorArray, minimum, maximum, false, splatIdx - (partStarts[partIdx] ?? 0));\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Append each new source\r\n dstOffset = splatCountA;\r\n for (const other of others) {\r\n this._appendPartSourceToArrays(other, dstOffset, covA, covB, colorArray, sh, minimum, maximum);\r\n dstOffset += other._vertexCount;\r\n }\r\n\r\n // Pad empty splats to texture boundary\r\n const paddedEnd = (totalCount + 15) & ~0xf;\r\n for (let i = totalCount; i < paddedEnd; i++) {\r\n this._makeEmptySplat(i, covA, covB, colorArray);\r\n }\r\n\r\n // --- Update vertex count / index buffer ---\r\n if (totalCount !== this._vertexCount) {\r\n this._updateSplatIndexBuffer(totalCount);\r\n }\r\n this._retainMergedPartData(splatCountA, totalCount, others, shDegreeNew);\r\n this._vertexCount = totalCount;\r\n this._shDegree = shDegreeNew;\r\n\r\n // Gate the sort worker for the duration of this operation. _updateTextures (below) may create the worker and fire an\r\n // immediate sort via _postToWorker. At that point partMatrices has not yet been updated for the incoming parts, so the\r\n // worker would compute depthCoeffs for fewer parts than partIndices references — crashing with\r\n // \"Cannot read properties of undefined (reading '0')\".\r\n // When called from removePart, _rebuilding is already true and _canPostToWorker is already false, so the gate is a\r\n // no-op — removePart handles the final post+sort.\r\n const needsWorkerGate = !this._rebuilding;\r\n if (needsWorkerGate) {\r\n this._canPostToWorker = false;\r\n this._rebuilding = true;\r\n }\r\n\r\n try {\r\n // --- Upload to GPU ---\r\n if (incremental) {\r\n // Create missing SH GPU textures: either the compound just gained SH for the first\r\n // time (_shTextures===null) or the degree increased (sh.length > _shTextures.length).\r\n // Use _shData when available (contains correct merged values for all rows);\r\n // fall back to sh[idx] (pre-filled with 128) when _shData is absent (keepInRam=false).\r\n // _updateSubTextures will re-upload from firstNewLine, which is redundant but harmless.\r\n if (sh && (!this._shTextures || sh.length > this._shTextures.length)) {\r\n if (!this._shTextures) {\r\n this._shTextures = [];\r\n }\r\n while (this._shTextures.length < sh.length) {\r\n const idx = this._shTextures.length;\r\n const shTexture = new RawTexture(\r\n null,\r\n textureSize.x,\r\n textureSize.y,\r\n Constants.TEXTUREFORMAT_RGBA_INTEGER,\r\n this._scene,\r\n false,\r\n false,\r\n Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n Constants.TEXTURETYPE_UNSIGNED_INTEGER\r\n );\r\n shTexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n shTexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n this._shTextures.push(shTexture);\r\n const src = this._shData && idx < this._shData.length ? this._shData[idx] : sh[idx];\r\n this._updateShTextureData(shTexture, src, textureSize.x, 0, textureSize.y);\r\n }\r\n }\r\n\r\n // Restore boundary-row SH: sh is freshly filled with 128, and _updateSubTextures\r\n // starts at firstNewLine — existing splats on that row need their values from _shData.\r\n if (sh && this._shData) {\r\n const firstNewTexel = firstNewLine * textureSize.x;\r\n if (firstNewTexel < splatCountA) {\r\n const byteStart = firstNewTexel * _GaussianSplattingBytesPerShTexel;\r\n const byteEnd = splatCountA * _GaussianSplattingBytesPerShTexel;\r\n for (let texIdx = 0; texIdx < sh.length; texIdx++) {\r\n if (texIdx < this._shData.length) {\r\n sh[texIdx].set(this._shData[texIdx].subarray(byteStart, byteEnd), byteStart);\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Update the part-indices texture (handles both create and update-in-place).\r\n // _ensurePartIndicesTexture is a no-op when the texture already exists, so on the\r\n // second+ addPart the partIndices would be stale without this call.\r\n this._onUpdateTextures(textureSize);\r\n this._updateSubTextures(this._splatPositions, covA, covB, colorArray, firstNewLine, textureSize.y - firstNewLine, sh);\r\n } else {\r\n this._updateTextures(covA, covB, colorArray, sh);\r\n }\r\n\r\n this.setEnabled(true);\r\n this._notifyWorkerNewData();\r\n\r\n // Bounding info is updated via _updateBoundingInfoFromProxies (called below, after proxy\r\n // world matrices are known), which needs part 0's local-space AABB as an input:\r\n // • For unproxied part 0 (legacy layout A: compound loaded its own splat data before\r\n // any addPart call, so no _partProxies[0]), capture the local-space AABB from the\r\n // compound mesh's existing _boundingInfo — set when the mesh loaded its own data via\r\n // URL/updateData — so _updateBoundingInfoFromProxies can include part 0's geometry.\r\n // • For proxied part 0, skip — its bounds are already on the proxy's getBoundingInfo()\r\n // and _updateBoundingInfoFromProxies picks it up there.\r\n // Guard splatCountA > 0 avoids reading a stale bounding box on a fresh empty mesh.\r\n // Guard !this._part0LocalMin ensures we only store once; subsequent addPart calls must\r\n // not overwrite it, because by then _boundingInfo reflects the full merged dataset.\r\n if (!this._partProxies[0] && splatCountA > 0 && !this._part0LocalMin) {\r\n this._part0LocalMin = this.getBoundingInfo().minimum.clone();\r\n this._part0LocalMax = this.getBoundingInfo().maximum.clone();\r\n }\r\n\r\n // --- Create proxy meshes ---\r\n const proxyMeshes: GaussianSplattingPartProxyMesh[] = [];\r\n for (let i = 0; i < others.length; i++) {\r\n const other = others[i];\r\n const newPartIndex = assignedPartIndices[i];\r\n\r\n const partWorldMatrix = other.getWorldMatrix();\r\n this.setWorldMatrixForPart(newPartIndex, partWorldMatrix);\r\n\r\n const proxyMesh = new GaussianSplattingPartProxyMesh(\r\n other.name,\r\n this.getScene(),\r\n this,\r\n newPartIndex,\r\n other.getBoundingInfo(),\r\n other._vertexCount,\r\n assignedSplatsDataOffsets[i],\r\n assignedSplatsDataOffsets[i]\r\n );\r\n\r\n if (disposeOthers) {\r\n other.dispose();\r\n }\r\n\r\n const quaternion = new Quaternion();\r\n partWorldMatrix.decompose(proxyMesh.scaling, quaternion, proxyMesh.position);\r\n proxyMesh.rotationQuaternion = quaternion;\r\n proxyMesh.computeWorldMatrix(true);\r\n\r\n this._partProxies[newPartIndex] = proxyMesh;\r\n proxyMeshes.push(proxyMesh);\r\n }\r\n\r\n // Update compound bounds now that all proxy world matrices are known.\r\n this._updateBoundingInfoFromProxies();\r\n\r\n // Restore the rebuild gate and post the now-complete partMatrices in one message, then trigger a single sort pass.\r\n // This ensures the worker sees a consistent partMatrices array that matches the partIndices for every splat.\r\n if (needsWorkerGate) {\r\n this._rebuilding = false;\r\n if (this._worker) {\r\n this._worker.postMessage({\r\n command: GaussianSplattingSortWorkerCommand.PART_MATRICES,\r\n partMatrices: this._partMatrices.map((matrix) => new Float32Array(matrix.m)),\r\n });\r\n }\r\n this._canPostToWorker = true;\r\n this._postToWorker(true);\r\n }\r\n\r\n this.onPartCountChangedObservable.notifyObservers(this.partCount);\r\n return { proxyMeshes, assignedPartIndices };\r\n } catch (e) {\r\n // Ensure the gates are always restored so sorting is not permanently frozen.\r\n if (needsWorkerGate) {\r\n this._rebuilding = false;\r\n this._canPostToWorker = true;\r\n }\r\n throw e;\r\n }\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Public compound API\r\n // ---------------------------------------------------------------------------\r\n\r\n /**\r\n * Add another mesh to this mesh, as a new part. This makes the current mesh a compound, if not already.\r\n * The source mesh's splat data is read directly and copied into the compound's retained source buffers.\r\n * @param other - The other mesh to add. Must be fully loaded before calling this method.\r\n * @param disposeOther - Whether to dispose the other mesh after adding it to the current mesh.\r\n * @returns a placeholder mesh that can be used to manipulate the part transform\r\n * @deprecated Use {@link GaussianSplattingCompoundMesh.addPart} instead.\r\n */\r\n public addPart(other: GaussianSplattingMesh, disposeOther: boolean = true): GaussianSplattingPartProxyMesh {\r\n const { proxyMeshes } = this._addPartsInternal([other], disposeOther);\r\n return proxyMeshes[0];\r\n }\r\n\r\n /**\r\n * Remove a part from this compound mesh.\r\n * The remaining parts are rebuilt directly from the compound mesh's retained source buffers.\r\n * The current mesh is reset to a plain (single-part) state and then each remaining source is\r\n * re-added via addParts.\r\n * @param index - The index of the part to remove\r\n * @deprecated Use {@link GaussianSplattingCompoundMesh.removePart} instead.\r\n */\r\n public removePart(index: number): void {\r\n if (index < 0 || index >= this.partCount) {\r\n throw new Error(`Part index ${index} is out of range [0, ${this.partCount})`);\r\n }\r\n\r\n // Collect surviving proxy objects (sorted by current part index so part 0 is added first)\r\n const survivors: Array<{ proxyMesh: GaussianSplattingPartProxyMesh; source: IGaussianSplattingPartSource; oldIndex: number; worldMatrix: Matrix; visibility: number }> = [];\r\n for (let proxyIndex = 0; proxyIndex < this._partProxies.length; proxyIndex++) {\r\n const proxy = this._partProxies[proxyIndex];\r\n if (!proxy || proxyIndex === index) {\r\n continue;\r\n }\r\n const source = this._createRetainedPartSource(proxy);\r\n if (!source) {\r\n throw new Error(`Cannot remove part: the retained compound source data is not available for part \"${proxy.name}\".`);\r\n }\r\n survivors.push({ proxyMesh: proxy, source, oldIndex: proxyIndex, worldMatrix: proxy.getWorldMatrix().clone(), visibility: this._partVisibility[proxyIndex] ?? 1.0 });\r\n }\r\n survivors.sort((a, b) => a.oldIndex - b.oldIndex);\r\n\r\n // Validate every survivor still has its source data. If even one is missing we cannot rebuild.\r\n for (const { proxyMesh, source } of survivors) {\r\n if (!source._splatsData) {\r\n throw new Error(`Cannot remove part: the source data for part \"${proxyMesh.name}\" is not available.`);\r\n }\r\n if (source._shDegree > 0 && !source._shData) {\r\n throw new Error(`Cannot remove part: the SH data for part \"${proxyMesh.name}\" is not available.`);\r\n }\r\n }\r\n\r\n // Notify listeners before mutation so they can record state keyed on the original index.\r\n this.onPartRemovedObservable.notifyObservers(index);\r\n\r\n // --- Reset this mesh to an empty state ---\r\n // Terminate the sort worker before zeroing _vertexCount. The worker's onmessage handler\r\n // compares depthMix.length against (_vertexCount + 15) & ~0xf; with _vertexCount = 0 that\r\n // becomes 16, which causes a forced re-sort loop on stale data and resets _canPostToWorker\r\n // to true, defeating the gate below. The worker will be re-instantiated naturally after\r\n // the rebuild via the first _postToWorker call.\r\n if (this._worker) {\r\n this._worker.terminate();\r\n this._worker = null;\r\n }\r\n // Dispose and null GPU textures so _updateTextures sees firstTime=true and creates\r\n // fresh GPU textures.\r\n this._covariancesATexture?.dispose();\r\n this._covariancesBTexture?.dispose();\r\n this._centersTexture?.dispose();\r\n this._colorsTexture?.dispose();\r\n this._rotationsATexture?.dispose();\r\n this._rotationsBTexture?.dispose();\r\n this._rotationScaleTexture?.dispose();\r\n this._covariancesATexture = null;\r\n this._covariancesBTexture = null;\r\n this._centersTexture = null;\r\n this._colorsTexture = null;\r\n this._rotationsATexture = null;\r\n this._rotationsBTexture = null;\r\n this._rotationScaleTexture = null;\r\n if (this._shTextures) {\r\n for (const t of this._shTextures) {\r\n t.dispose();\r\n }\r\n this._shTextures = null;\r\n }\r\n if (this._partIndicesTexture) {\r\n this._partIndicesTexture.dispose();\r\n this._partIndicesTexture = null;\r\n }\r\n this._vertexCount = 0;\r\n this._splatPositions = null;\r\n this._partIndices = null;\r\n this._partMatrices = [];\r\n this._partVisibility = [];\r\n this._cachedBoundingMin = null;\r\n this._cachedBoundingMax = null;\r\n this._part0LocalMin = null;\r\n this._part0LocalMax = null;\r\n this._splatsData = null;\r\n this._shData = null;\r\n this._shDegree = 0;\r\n\r\n // Remove the proxy for the removed part and dispose it\r\n const proxyToRemove = this._partProxies[index];\r\n if (proxyToRemove) {\r\n proxyToRemove.dispose();\r\n }\r\n this._partProxies = [];\r\n\r\n // Rebuild from surviving sources. _addPartsInternal assigns part indices in order 0, 1, 2, …\r\n // so the new index for each survivor is simply its position in the survivors array.\r\n if (survivors.length === 0) {\r\n // Nothing left — leave the mesh empty.\r\n this.setEnabled(false);\r\n this.onPartCountChangedObservable.notifyObservers(0);\r\n return;\r\n }\r\n\r\n // Gate the sort worker: suppress any sort request until the full rebuild is committed.\r\n this._rebuilding = true;\r\n this._canPostToWorker = false;\r\n try {\r\n const sources = survivors.map((s) => s.source);\r\n const { proxyMeshes: newProxies } = this._addPartsInternal(sources, false);\r\n\r\n // Restore world matrices and re-map proxies\r\n for (let i = 0; i < survivors.length; i++) {\r\n const oldProxy = survivors[i].proxyMesh;\r\n const newProxy = newProxies[i];\r\n const newPartIndex = newProxy.partIndex;\r\n\r\n // Restore the world matrix and visibility the user had set on the old proxy\r\n this.setWorldMatrixForPart(newPartIndex, survivors[i].worldMatrix);\r\n this.setPartVisibility(newPartIndex, survivors[i].visibility);\r\n const quaternion = new Quaternion();\r\n survivors[i].worldMatrix.decompose(newProxy.scaling, quaternion, newProxy.position);\r\n newProxy.rotationQuaternion = quaternion;\r\n newProxy.computeWorldMatrix(true);\r\n\r\n // Update the old proxy's index and metadata so existing user references still work.\r\n oldProxy.updatePartIndex(newPartIndex);\r\n oldProxy.updatePartMetadata(newProxy._vertexCount, newProxy._splatsDataOffset, newProxy._shDataOffset);\r\n this._partProxies[newPartIndex] = oldProxy;\r\n\r\n // newProxy is redundant — it was created inside _addPartsInternal; dispose it\r\n newProxy.dispose();\r\n }\r\n\r\n // Rebuild is complete: all partMatrices are now set correctly.\r\n // Post the final complete set and fire one sort.\r\n this._rebuilding = false;\r\n // Break TypeScript's flow narrowing — _addPartsInternal may have reinstantiated _worker.\r\n const workerAfterRebuild = this._worker as Worker | null;\r\n workerAfterRebuild?.postMessage({\r\n command: GaussianSplattingSortWorkerCommand.PART_MATRICES,\r\n partMatrices: this._partMatrices.map((matrix) => new Float32Array(matrix.m)),\r\n });\r\n this._canPostToWorker = true;\r\n this._postToWorker(true);\r\n } catch (e) {\r\n // Ensure the gates are always restored so sorting is not permanently frozen.\r\n this._rebuilding = false;\r\n this._canPostToWorker = true;\r\n throw e;\r\n }\r\n }\r\n\r\n /**\r\n * Serialize current GaussianSplattingMesh\r\n * @param serializationObject defines the object which will receive the serialization data\r\n * @param encoding the encoding of binary data, defaults to base64 for json serialize,\r\n * kept for future internal use like cloning where base64 encoding wastes cycles and memory\r\n * @returns the serialized object\r\n */\r\n public override serialize(serializationObject: any = {}, encoding: string = \"base64\"): any {\r\n serializationObject = super.serialize(serializationObject);\r\n serializationObject.subMeshes = [];\r\n serializationObject.geometryUniqueId = undefined;\r\n serializationObject.geometryId = undefined;\r\n serializationObject.materialUniqueId = undefined;\r\n serializationObject.materialId = undefined;\r\n serializationObject.instances = [];\r\n serializationObject.actions = undefined;\r\n serializationObject.type = this.getClassName();\r\n serializationObject.keepInRam = this._keepInRam;\r\n serializationObject.disableDepthSort = this._disableDepthSort;\r\n serializationObject.viewUpdateThreshold = this.viewUpdateThreshold;\r\n serializationObject._flipY = this._flipY;\r\n\r\n if (this._splatsData) {\r\n serializationObject.splatsData = encoding === \"base64\" ? EncodeArrayBufferToBase64(this._splatsData) : this._splatsData;\r\n }\r\n if (this._shData) {\r\n serializationObject.shData = encoding === \"base64\" ? this._shData.map(EncodeArrayBufferToBase64) : this._shData;\r\n serializationObject.shDegree = this._shDegree;\r\n }\r\n if (this._partIndices) {\r\n const compressedIndices = CompressPartIndices(this._partIndices.subarray(0, this._vertexCount));\r\n serializationObject.partIndices = encoding === \"base64\" ? EncodeArrayBufferToBase64(compressedIndices) : compressedIndices;\r\n }\r\n if (this._partProxies.length) {\r\n serializationObject.partProxies = this._partProxies.filter((proxy) => !!proxy).map((proxy) => proxy.serialize());\r\n }\r\n\r\n return serializationObject;\r\n }\r\n\r\n /**\r\n * Internal helper to parses a serialized GaussianSplattingMesh or GaussianSplattingCompoundMesh\r\n * @param parsedMesh the serialized mesh\r\n * @param scene the scene to create the GaussianSplattingMesh or GaussianSplattingCompoundMesh in\r\n * @param ctor the constructor of the mesh to create\r\n * @returns the created GaussianSplattingMesh\r\n * @internal\r\n */\r\n public static _ParseInternal<T extends GaussianSplattingMesh>(\r\n parsedMesh: any,\r\n scene: Scene,\r\n ctor: new (name: string, url: Nullable<string>, scene: Nullable<Scene>, keepInRam: boolean) => T\r\n ): T {\r\n const mesh = new ctor(parsedMesh.name, null, scene, parsedMesh.keepInRam);\r\n\r\n mesh.disableDepthSort = parsedMesh.disableDepthSort ?? false;\r\n mesh.viewUpdateThreshold = parsedMesh.viewUpdateThreshold ?? GaussianSplattingMeshBase._DefaultViewUpdateThreshold;\r\n\r\n let splatsData: ArrayBuffer | string | undefined = parsedMesh.splatsData;\r\n if (typeof splatsData === \"string\") {\r\n splatsData = DecodeBase64ToBinary(splatsData);\r\n }\r\n\r\n const shData: string[] | Uint8Array[] | undefined = parsedMesh.shData;\r\n let parsedShData: Uint8Array[] | undefined;\r\n if (Array.isArray(shData) && shData.length) {\r\n const newData: Uint8Array[] = [];\r\n for (let i = 0, length = shData.length; i < length; i++) {\r\n const data = shData[i];\r\n if (typeof data === \"string\") {\r\n newData[i] = new Uint8Array(DecodeBase64ToBinary(data));\r\n } else {\r\n newData[i] = data;\r\n }\r\n }\r\n parsedShData = newData;\r\n }\r\n\r\n let partIndices: string | Uint32Array | number[] | undefined = parsedMesh.partIndices;\r\n let parsedPartIndices: Uint8Array | undefined;\r\n if (typeof partIndices === \"string\") {\r\n partIndices = new Uint32Array(DecodeBase64ToBinary(partIndices));\r\n }\r\n if (partIndices) {\r\n parsedPartIndices = ParsePartIndices(partIndices);\r\n }\r\n\r\n if (splatsData) {\r\n const flipY = parsedMesh._flipY ?? false;\r\n mesh.updateData(splatsData, parsedShData, { flipY }, parsedPartIndices, parsedMesh.shDegree);\r\n }\r\n\r\n if (parsedMesh.partProxies) {\r\n for (const serializedPart of parsedMesh.partProxies) {\r\n const part = Object.assign({}, serializedPart);\r\n part.compoundSplatMesh = mesh;\r\n const proxyMesh = Mesh.Parse(part, scene, \"\") as GaussianSplattingPartProxyMesh;\r\n const newPartIndex = proxyMesh.partIndex;\r\n mesh._partProxies[newPartIndex] = proxyMesh;\r\n mesh.setWorldMatrixForPart(newPartIndex, proxyMesh.getWorldMatrix());\r\n mesh.setPartVisibility(newPartIndex, proxyMesh.visibility);\r\n }\r\n }\r\n\r\n return mesh;\r\n }\r\n\r\n /**\r\n * Parses a serialized GaussianSplattingMesh\r\n * @param parsedMesh the serialized mesh\r\n * @param scene the scene to create the GaussianSplattingMesh in\r\n * @returns the created GaussianSplattingMesh\r\n */\r\n public static override Parse(parsedMesh: any, scene: Scene): GaussianSplattingMesh {\r\n return GaussianSplattingMesh._ParseInternal(parsedMesh, scene, GaussianSplattingMesh);\r\n }\r\n}\r\n\r\n/**\r\n * True when `className` (from `AbstractMesh.getClassName()`) identifies a Gaussian Splatting mesh whose\r\n * `position.z` vertex attribute encodes a splat index rather than world-space Z: `\"GaussianSplattingMesh\"`\r\n * (also returned by {@link GaussianSplattingCompoundMesh}, which deliberately does not override\r\n * `getClassName()`) and `\"GaussianSplattingStream\"` (which does override it, to remain distinguishable for\r\n * other purposes). Rendering-pipeline code that must treat any Gaussian Splatting mesh differently from an\r\n * ordinary mesh (geometry buffer, depth pre-pass, GPU picking, IBL voxelization, snapshot rendering, ...)\r\n * should use this instead of a literal string comparison, so a future splat mesh subclass only needs to be\r\n * added here once.\r\n * @param className the mesh class name to test, e.g. from `AbstractMesh.getClassName()`\r\n * @returns true if the class name identifies a Gaussian Splatting mesh\r\n */\r\nexport function IsGaussianSplattingClassName(className: string): boolean {\r\n return className === \"GaussianSplattingMesh\" || className === \"GaussianSplattingStream\";\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for gaussianSplattingMesh.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGaussianSplattingMesh(): void {\r\n if (_Registered) {\r\n return;\r\n }\r\n _Registered = true;\r\n\r\n Mesh._GaussianSplattingMeshParser = GaussianSplattingMesh.Parse;\r\n}\r\n"]}
1
+ {"version":3,"file":"gaussianSplattingMesh.pure.js","sourceRoot":"","sources":["../../../../../dev/core/src/Meshes/GaussianSplatting/gaussianSplattingMesh.pure.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAI7D,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAG1E,OAAO,EAAE,gCAAgC,EAAE,MAAM,iEAAiE,CAAC;AACnH,OAAO,EAAE,yBAAyB,EAAE,iBAAiB,EAAqC,MAAM,kCAAkC,CAAC;AACnI,OAAO,EAAE,kCAAkC,EAAE,MAAM,+BAA+B,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAEhE,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACxF,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAE,8BAA8B,EAAE,MAAM,uCAAuC,CAAC;AACvF,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAI1D,MAAM,+BAA+B,GAAG,EAAE,CAAC;AAC3C,MAAM,iCAAiC,GAAG,EAAE,CAAC;AAqB7C;;;;;;;GAOG;AACH,SAAS,mBAAmB,CAAC,WAAuB;IAChD,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;IAClC,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,GAAG,MAAM,EAAE,CAAC;QAChB,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;QAC7B,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,OAAO,CAAC,GAAG,KAAK,GAAG,MAAM,IAAI,WAAW,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,KAAK,EAAE,CAAC;YAC5D,KAAK,EAAE,CAAC;QACZ,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACxB,CAAC,IAAI,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC;AAED;;;;GAIG;AACH,SAAS,gBAAgB,CAAC,UAAkC;IACxD,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;IACjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACjC,UAAU,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;IAChC,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC;IAC/C,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;QAC5B,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAChC,WAAW,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC;IACpB,CAAC;IAED,OAAO,WAAW,CAAC;AACvB,CAAC;AAiID;;;;;GAKG;AACH,MAAM,OAAO,qBAAsB,SAAQ,yBAAyB;IAwDhE,gEAAgE;IAChE,IAAW,kBAAkB;QACzB,OAAO,IAAI,CAAC,mBAAmB,CAAC;IACpC,CAAC;IAED;;;;;;;OAOG;IACH,YAAY,IAAY,EAAE,MAAwB,IAAI,EAAE,QAAyB,IAAI,EAAE,YAAqB,KAAK,EAAE,6BAAsC,KAAK;QAC1J,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QArEvC;;WAEG;QACK,iBAAY,GAAqC,EAAE,CAAC;QAE5D,iHAAiH;QACzG,mBAAc,GAAsB,IAAI,CAAC;QACzC,mBAAc,GAAsB,IAAI,CAAC;QAEjD;;WAEG;QACO,kBAAa,GAAa,EAAE,CAAC;QAEvC,iGAAiG;QACzF,gBAAW,GAAY,KAAK,CAAC;QAErC;;WAEG;QACO,oBAAe,GAAa,EAAE,CAAC;QAEzC;;;;;;WAMG;QACK,qBAAgB,GAA+C,EAAE,CAAC;QAE1E;;;;;WAKG;QACO,sBAAiB,GAAG,KAAK,CAAC;QAEpC,yGAAyG;QACjG,qBAAgB,GAA0B,EAAE,CAAC;QAErD;;;;WAIG;QACK,uBAAkB,GAAG,CAAC,CAAC;QAE/B,+HAA+H;QACvH,2BAAsB,GAAG,IAAI,GAAG,EAAU,CAAC;QAE3C,wBAAmB,GAA0B,IAAI,CAAC;QAClD,iBAAY,GAAyB,IAAI,CAAC;QAiB9C,uFAAuF;QACvF,mFAAmF;QACnF,6CAA6C;QAC7C,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC;QACpC,IAAI,CAAC,2BAA2B,GAAG,0BAA0B,CAAC;IAClE,CAAC;IAED;;;OAGG;IACa,YAAY;QACxB,OAAO,uBAAuB,CAAC;IACnC,CAAC;IAED;;;;;;;;;;;OAWG;IACa,OAAO,CAAC,aAAa,GAAG,KAAK;QACzC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACpC,IAAI,KAAK,EAAE,CAAC;gBACR,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;YACnC,CAAC;QACL,CAAC;QACD,OAAO,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IACxC,CAAC;IAED;;;;OAIG;IACK,8BAA8B;QAClC,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QAC5C,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QAEtD,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;QACvI,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAE1I,MAAM,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC7B,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACpC,sGAAsG;YACtG,sGAAsG;YACtG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC7D,SAAS;YACb,CAAC;YACD,sGAAsG;YACtG,KAAK,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;YAChC,MAAM,EAAE,GAAG,KAAK,CAAC,eAAe,EAAE,CAAC,WAAW,CAAC;YAC/C,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC;YAC7B,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC;YAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBACzB,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBACtF,OAAO,CAAC,yBAAyB,CAAC,MAAM,EAAE,gBAAgB,EAAE,MAAM,CAAC,CAAC;gBACpE,QAAQ,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;gBACjC,QAAQ,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;YACrC,CAAC;QACL,CAAC;QAED,IAAI,QAAQ,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,EAAE,CAAC;YAC3B,4EAA4E;YAC5E,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;gBACrB,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;YACtE,CAAC;iBAAM,CAAC;gBACJ,IAAI,CAAC,aAAa,GAAG,IAAI,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;YAC7E,CAAC;YACD,IAAI,CAAC,kBAAkB,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC;YAC3C,IAAI,CAAC,kBAAkB,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC;QAC/C,CAAC;IACL,CAAC;IAED;;;;OAIG;IACa,mBAAmB;QAC/B,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAClB,IAAI,CAAC,8BAA8B,EAAE,CAAC;YACtC,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;YAC7D,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,OAAO,KAAK,CAAC,mBAAmB,EAAE,CAAC;IACvC,CAAC;IAED;;;;;;;;OAQG;IACa,2BAA2B,CACvC,qBAA8B,IAAI,EAClC,YAA+D,IAAI;QAEnE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACnB,OAAO,KAAK,CAAC,2BAA2B,CAAC,kBAAkB,EAAE,SAAS,CAAC,CAAC;QAC5E,CAAC;QACD,8EAA8E;QAC9E,iFAAiF;QACjF,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;QAC9E,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACjF,mFAAmF;QACnF,sDAAsD;QACtD,IAAI,IAAI,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9D,MAAM,EAAE,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YACjC,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC;YACjC,MAAM,IAAI,GAAG,IAAI,CAAC,cAAe,CAAC;YAClC,MAAM,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBACzB,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBACtF,OAAO,CAAC,yBAAyB,CAAC,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;gBACtD,GAAG,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;gBAC5B,GAAG,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;YAChC,CAAC;QACL,CAAC;QACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAChD,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACnC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBACnD,SAAS;YACb,CAAC;YACD,KAAK,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;YAChC,MAAM,EAAE,GAAG,KAAK,CAAC,eAAe,EAAE,CAAC,WAAW,CAAC;YAC/C,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC;YACrC,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC;QACzC,CAAC;QACD,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IACxB,CAAC;IAED;;;OAGG;IACa,OAAO,CAAC,YAAsB;QAC1C,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACpC,KAAK,CAAC,OAAO,EAAE,CAAC;QACpB,CAAC;QACD,IAAI,CAAC,mBAAmB,EAAE,OAAO,EAAE,CAAC;QACpC,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;QACxB,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;QAC1B,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;QAChC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAChC,CAAC;IAED,8EAA8E;IAC9E,4BAA4B;IAC5B,8EAA8E;IAE9E;;;;;OAKG;IACgB,gBAAgB,CAAC,MAAc;QAC9C,MAAM,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,kCAAkC,CAAC,aAAa,EAAE,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAChK,MAAM,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,kCAAkC,CAAC,YAAY,EAAE,WAAW,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAChK,CAAC;IAED;;;;;OAKG;IACgB,oBAAoB,CAAC,WAAuB,EAAE,aAAqB;QAClF,IAAI,CAAC,YAAY,GAAG,IAAI,UAAU,CAAC,aAAa,CAAC,CAAC;QAClD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACvC,CAAC;IAED;;;;;;;;OAQG;IACH,IAAoB,UAAU;QAC1B,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC;IACzC,CAAC;IAED;;;;;;OAMG;IACgB,kBAAkB;QACjC,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACnC,+EAA+E;YAC/E,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAChD,OAAO;QACX,CAAC;QACD,KAAK,CAAC,kBAAkB,EAAE,CAAC;IAC/B,CAAC;IAED;;;;OAIG;IACgB,yBAAyB,CAAC,WAAoB;QAC7D,IAAI,CAAC,yBAAyB,CAAC,WAAW,EAAE,IAAI,CAAC,YAAY,IAAI,SAAS,CAAC,CAAC;IAChF,CAAC;IAED;;;OAGG;IACgB,oBAAoB;QACnC,KAAK,CAAC,oBAAoB,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,kCAAkC,CAAC,YAAY,EAAE,WAAW,EAAE,IAAI,CAAC,YAAY,IAAI,IAAI,EAAE,CAAC,CAAC;QACnI,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACa,uBAAuB,CAAC,MAAc;QAClD,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC5B,OAAO;QACX,CAAC;QACD,MAAM,CAAC,UAAU,CAAC,oBAAoB,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAClE,MAAM,aAAa,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC;QAC5D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,CAAC,WAAW,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;QAC/C,MAAM,kBAAkB,GAAa,EAAE,CAAC;QACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;QAC5D,CAAC;QACD,MAAM,CAAC,QAAQ,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,CAAC;IAC1D,CAAC;IAED,8EAA8E;IAC9E,sCAAsC;IACtC,8EAA8E;IAE9E;;OAEG;IACH,IAAW,SAAS;QAChB,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;IACrC,CAAC;IAED;;OAEG;IACH,IAAW,cAAc;QACrB,OAAO,IAAI,CAAC,eAAe,CAAC;IAChC,CAAC;IAED;;;;;;OAMG;IACI,qBAAqB,CAAC,SAAiB,EAAE,WAAmB;QAC/D,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC;YACzC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;YAC9B,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YAC5C,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC;gBAC5C,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC,CAAC;gBAC/C,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACnC,CAAC;QACL,CAAC;QACD,gHAAgH;QAChH,+GAA+G;QAC/G,0GAA0G;QAC1G,IAAI,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;YACpD,OAAO;QACX,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QACpD,uFAAuF;QACvF,8DAA8D;QAC9D,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACpB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACf,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;oBACrB,OAAO,EAAE,kCAAkC,CAAC,aAAa;oBACzD,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;iBAC/E,CAAC,CAAC;YACP,CAAC;YACD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;IACL,CAAC;IAED;;;;OAIG;IACI,qBAAqB,CAAC,SAAiB;QAC1C,OAAO,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;IAClE,CAAC;IAED;;;;OAIG;IACI,iBAAiB,CAAC,SAAiB;QACtC,OAAO,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC;IAClD,CAAC;IAED;;;;OAIG;IACI,iBAAiB,CAAC,SAAiB,EAAE,KAAa;QACrD,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;IAC1E,CAAC;IAED;;;;;;;;;;;;OAYG;IACI,kBAAkB,CAAC,SAAiB,EAAE,MAAyD;QAClG,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;YAChB,OAAO;QACX,CAAC;QACD,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC7G,IAAI,CAAC,sBAAsB,EAAE,CAAC;IAClC,CAAC;IAED;;;;;OAKG;IACK,sBAAsB;QAC1B,IAAI,WAAW,GAAG,KAAK,CAAC;QACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACpD,IAAI,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC3B,WAAW,GAAG,IAAI,CAAC;gBACnB,MAAM;YACV,CAAC;QACL,CAAC;QACD,IAAI,CAAC,WAAW,EAAE,CAAC;YACf,0EAA0E;YAC1E,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;YAC/B,OAAO;QACX,CAAC;QAED,MAAM,SAAS,GAAmC,EAAE,CAAC;QACrD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QACjC,KAAK,IAAI,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,SAAS,EAAE,SAAS,EAAE,EAAE,CAAC;YACzD,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;YAClD,IAAI,QAAQ,EAAE,CAAC;gBACX,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;oBAC3B,IAAI,KAAK,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;wBAClB,SAAS,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;oBACjE,CAAC;gBACL,CAAC;gBACD,SAAS;YACb,CAAC;YACD,sEAAsE;YACtE,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;YAC3C,IAAI,KAAK,IAAI,KAAK,CAAC,YAAY,GAAG,CAAC,EAAE,CAAC;gBAClC,SAAS,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,iBAAiB,EAAE,KAAK,EAAE,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC;YACnF,CAAC;QACL,CAAC;QAED,IAAI,CAAC,mBAAmB,CAAC,qBAAqB,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC,CAAC;IACpF,CAAC;IAED;;;;;OAKG;IACK,MAAM,CAAC,oBAAoB,CAAC,MAAsC;QACtE,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YACrB,OAAO,MAAM,CAAC;QAClB,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;QAClE,MAAM,MAAM,GAAmC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QACtG,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACvC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YACxB,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC;YACzC,IAAI,KAAK,CAAC,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;gBAC1D,IAAI,CAAC,KAAK,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;YACnC,CAAC;iBAAM,CAAC;gBACJ,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;YAC9D,CAAC;QACL,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IAEkB,aAAa,CAAC,MAAiC;QAC9D,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC5B,IAAI,CAAC,mBAAmB,GAAI,MAAgC,CAAC,mBAAmB,EAAE,KAAK,EAAG,CAAC;IAC/F,CAAC;IAEkB,iBAAiB,CAAC,WAAoB;QACrD,MAAM,uBAAuB,GAAG,CAAC,IAAgB,EAAE,KAAa,EAAE,MAAc,EAAE,MAAc,EAAE,EAAE;YAChG,OAAO,IAAI,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,6BAA6B,EAAE,SAAS,CAAC,yBAAyB,CAAC,CAAC;QAChK,CAAC,CAAC;QAEF,yFAAyF;QACzF,+FAA+F;QAC/F,2FAA2F;QAC3F,sFAAsF;QACtF,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACjD,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC5B,IAAI,CAAC,mBAAmB,GAAG,uBAAuB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,EAAE,SAAS,CAAC,iBAAiB,CAAC,CAAC;gBACtH,IAAI,CAAC,mBAAmB,CAAC,KAAK,GAAG,SAAS,CAAC,yBAAyB,CAAC;gBACrE,IAAI,CAAC,mBAAmB,CAAC,KAAK,GAAG,SAAS,CAAC,yBAAyB,CAAC;YACzE,CAAC;iBAAM,CAAC;gBACJ,MAAM,YAAY,GAAG,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,CAAC;gBACxD,IAAI,YAAY,CAAC,KAAK,KAAK,WAAW,CAAC,CAAC,IAAI,YAAY,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,EAAE,CAAC;oBAChF,6DAA6D;oBAC7D,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,CAAC;oBACnC,IAAI,CAAC,mBAAmB,GAAG,uBAAuB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,EAAE,SAAS,CAAC,iBAAiB,CAAC,CAAC;oBACtH,IAAI,CAAC,mBAAmB,CAAC,KAAK,GAAG,SAAS,CAAC,yBAAyB,CAAC;oBACrE,IAAI,CAAC,mBAAmB,CAAC,KAAK,GAAG,SAAS,CAAC,yBAAyB,CAAC;gBACzE,CAAC;qBAAM,CAAC;oBACJ,oFAAoF;oBACpF,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,mBAAmB,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;gBACnG,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;IAEkB,kBAAkB,CACjC,cAA4B,EAC5B,IAAiB,EACjB,IAAiB,EACjB,UAAsB,EACtB,SAAiB,EACjB,SAAiB,EACjB,EAAiB,EACjB,WAAwB;QAExB,KAAK,CAAC,kBAAkB,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAC3F,IAAI,WAAW,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC1C,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC5D,MAAM,UAAU,GAAG,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC;YAC7C,MAAM,UAAU,GAAG,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC;YAC7C,MAAM,eAAe,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;YACnF,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,mBAAmB,EAAE,eAAe,EAAE,WAAW,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;YAE5G,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACf,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,kCAAkC,CAAC,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,CAAC;YACrH,CAAC;QACL,CAAC;IACL,CAAC;IAED,8EAA8E;IAC9E,kBAAkB;IAClB,8EAA8E;IAE9E;;;;;OAKG;IACO,yBAAyB,CAAC,WAAoB,EAAE,WAAmC;QACzF,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC3C,OAAO;QACX,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,YAAa,CAAC,CAAC;QAClD,IAAI,CAAC,mBAAmB,GAAG,IAAI,UAAU,CACrC,MAAM,EACN,WAAW,CAAC,CAAC,EACb,WAAW,CAAC,CAAC,EACb,SAAS,CAAC,iBAAiB,EAC3B,IAAI,CAAC,MAAM,EACX,KAAK,EACL,KAAK,EACL,SAAS,CAAC,6BAA6B,EACvC,SAAS,CAAC,yBAAyB,CACtC,CAAC;QACF,IAAI,CAAC,mBAAmB,CAAC,KAAK,GAAG,SAAS,CAAC,yBAAyB,CAAC;QACrE,IAAI,CAAC,mBAAmB,CAAC,KAAK,GAAG,SAAS,CAAC,yBAAyB,CAAC;QACrE,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,kCAAkC,CAAC,YAAY,EAAE,WAAW,EAAE,WAAW,IAAI,IAAI,EAAE,CAAC,CAAC;QAC7H,CAAC;IACL,CAAC;IAEO,yBAAyB,CAC7B,MAAoC,EACpC,SAAiB,EACjB,IAAiB,EACjB,IAAiB,EACjB,UAAsB,EACtB,EAA4B,EAC5B,OAAgB,EAChB,OAAgB;QAEhB,IAAI,CAAC,qBAAqB,CAAC,MAA8C,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACxI,CAAC;IAEO,yBAAyB,CAAC,KAAqC;QACnE,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7D,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,MAAM,eAAe,GAAG,KAAK,CAAC,iBAAiB,GAAG,+BAA+B,CAAC;QAClF,MAAM,eAAe,GAAG,KAAK,CAAC,YAAY,GAAG,+BAA+B,CAAC;QAC7E,MAAM,YAAY,GAAG,KAAK,CAAC,aAAa,GAAG,iCAAiC,CAAC;QAC7E,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,GAAG,iCAAiC,CAAC;QAC5E,MAAM,UAAU,GAAG,yBAAyB,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAElF,OAAO;YACH,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,WAAW,EAAE,UAAU,CAAC,QAAQ,CAAC,eAAe,EAAE,eAAe,GAAG,eAAe,CAAC;YACpF,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,EAAE,YAAY,GAAG,YAAY,CAAC,CAAC,IAAI,IAAI;YAC5G,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;YAC5C,UAAU,EAAE,KAAK;YACjB,cAAc,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,cAAc,EAAE;YAC5C,eAAe,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,eAAe,EAAE;YAC9C,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC;SACpB,CAAC;IACN,CAAC;IAEO,qBAAqB,CAAC,mBAA2B,EAAE,UAAkB,EAAE,MAAsC,EAAE,QAAgB;QACnI,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,uBAAuB,EAAE,CAAC;YACpD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YACxB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,OAAO;QACX,CAAC;QAED,MAAM,gBAAgB,GAAG,IAAI,UAAU,CAAC,UAAU,GAAG,+BAA+B,CAAC,CAAC;QACtF,IAAI,eAAe,GAAG,CAAC,CAAC;QAExB,IAAI,IAAI,CAAC,WAAW,IAAI,mBAAmB,GAAG,CAAC,EAAE,CAAC;YAC9C,gBAAgB,CAAC,GAAG,CAChB,yBAAyB,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,mBAAmB,GAAG,+BAA+B,CAAC,EACjI,eAAe,CAClB,CAAC;YACF,eAAe,IAAI,mBAAmB,GAAG,+BAA+B,CAAC;QAC7E,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YACzB,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;gBACrB,SAAS;YACb,CAAC;YAED,MAAM,eAAe,GAAG,KAAK,CAAC,YAAY,GAAG,+BAA+B,CAAC;YAC7E,gBAAgB,CAAC,GAAG,CAAC,yBAAyB,CAAC,kBAAkB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,eAAe,CAAC,EAAE,eAAe,CAAC,CAAC;YACpI,eAAe,IAAI,eAAe,CAAC;QACvC,CAAC;QAED,IAAI,CAAC,WAAW,GAAG,gBAAgB,CAAC,MAAM,CAAC;QAE3C,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;YAChB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,OAAO;QACX,CAAC;QAED,6FAA6F;QAC7F,gFAAgF;QAChF,uGAAuG;QACvG,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,iCAAiC,CAAC,CAAC;QAClH,MAAM,YAAY,GAAG,iBAAiB,CAAC,cAAc,EAAE,UAAU,GAAG,iCAAiC,CAAC,CAAC;QAEvG,IAAI,YAAY,GAAG,CAAC,CAAC;QACrB,IAAI,IAAI,CAAC,OAAO,IAAI,mBAAmB,GAAG,CAAC,EAAE,CAAC;YAC1C,MAAM,oBAAoB,GAAG,mBAAmB,GAAG,iCAAiC,CAAC;YACrF,KAAK,IAAI,YAAY,GAAG,CAAC,EAAE,YAAY,GAAG,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,EAAE,CAAC;gBAC5E,IAAI,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;oBACrC,YAAY,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,oBAAoB,CAAC,EAAE,YAAY,CAAC,CAAC;gBAC/G,CAAC;YACL,CAAC;YACD,YAAY,IAAI,oBAAoB,CAAC;QACzC,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YACzB,MAAM,iBAAiB,GAAG,KAAK,CAAC,YAAY,GAAG,iCAAiC,CAAC;YACjF,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBAChB,KAAK,IAAI,YAAY,GAAG,CAAC,EAAE,YAAY,GAAG,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,EAAE,CAAC;oBAC5E,IAAI,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;wBACtC,YAAY,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,iBAAiB,CAAC,EAAE,YAAY,CAAC,CAAC;oBAC7G,CAAC;gBACL,CAAC;YACL,CAAC;YACD,YAAY,IAAI,iBAAiB,CAAC;QACtC,CAAC;QAED,IAAI,CAAC,OAAO,GAAG,YAAY,CAAC;IAChC,CAAC;IAED;;;;;;;;OAQG;IACO,iBAAiB,CAAC,MAAsC,EAAE,aAAsB;QACtF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,mBAAmB,EAAE,EAAE,EAAE,CAAC;QACxD,CAAC;QAED,WAAW;QACX,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YACzB,yFAAyF;YACzF,6FAA6F;YAC7F,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE,CAAC;gBAChD,MAAM,IAAI,KAAK,CAAC,qEAAqE,CAAC,CAAC;YAC3F,CAAC;YACD,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;gBACnB,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAC;YAC7F,CAAC;QACL,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC;QACtC,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;QACvE,MAAM,UAAU,GAAG,WAAW,GAAG,eAAe,CAAC;QAEjD,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;QACrD,MAAM,aAAa,GAAG,WAAW,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC;QACpD,MAAM,aAAa,GAAG,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAEtD,uDAAuD;QACvD,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,aAAa,GAAG,aAAa,CAAC,CAAC;QAC5D,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC;QAErD,6GAA6G;QAC7G,iHAAiH;QACjH,6GAA6G;QAC7G,0EAA0E;QAC1E,MAAM,iBAAiB,GAAG,IAAI,CAAC,kBAAkB,CAAC;QAClD,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,GAAG,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC;QACjF,MAAM,KAAK,GAAG,WAAW,IAAI,iBAAiB,GAAG,CAAC,CAAC;QACnD,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/G,IAAI,EAAE,GAA6B,SAAS,CAAC;QAC7C,6GAA6G;QAC7G,4GAA4G;QAC5G,yBAAyB;QACzB,IAAI,KAAK,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;YAC3B,6FAA6F;YAC7F,gFAAgF;YAChF,uGAAuG;YACvG,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,GAAG,CAAC,WAAW,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,iCAAiC,CAAC,CAAC;YACxH,EAAE,GAAG,iBAAiB,CAAC,cAAc,EAAE,aAAa,GAAG,iCAAiC,CAAC,CAAC;QAC9F,CAAC;QAED,2EAA2E;QAC3E,MAAM,WAAW,GAAG,IAAI,CAAC,mBAAmB,CAAC,WAAW,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC;QACvF,MAAM,YAAY,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAE/E,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAmB,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;QACnI,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAmB,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAEtI,yDAAyD;QACzD,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,CAAC;QAC1C,IAAI,CAAC,eAAe,GAAG,IAAI,YAAY,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC;QAC3D,IAAI,WAAW,IAAI,YAAY,EAAE,CAAC;YAC9B,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,EAAE,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC;QACxE,CAAC;QAED,6BAA6B;QAC7B,IAAI,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC;QACnC,IAAI,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;QACrC,IAAI,CAAC,YAAY,EAAE,CAAC;YAChB,6DAA6D;YAC7D,YAAY,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,CAAC;YAC3C,aAAa,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5C,CAAC;QAED,IAAI,CAAC,YAAY,GAAG,IAAI,UAAU,CAAC,aAAa,CAAC,CAAC;QAClD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC;QAE7D,MAAM,mBAAmB,GAAa,EAAE,CAAC;QACzC,MAAM,yBAAyB,GAAa,EAAE,CAAC;QAC/C,IAAI,SAAS,GAAG,WAAW,CAAC;QAC5B,MAAM,YAAY,GAAG,gCAAgC,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;QAC/E,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YACzB,IAAI,aAAa,IAAI,YAAY,EAAE,CAAC;gBAChC,MAAM,IAAI,KAAK,CAAC,+CAA+C,YAAY,oBAAoB,CAAC,CAAC;YACrG,CAAC;YACD,MAAM,YAAY,GAAG,aAAa,EAAE,CAAC;YACrC,mBAAmB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACvC,yBAAyB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC1C,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,EAAE,SAAS,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC;YAChF,SAAS,IAAI,KAAK,CAAC,YAAY,CAAC;QACpC,CAAC;QAED,8BAA8B;QAC9B,IAAI,CAAC,WAAW,EAAE,CAAC;YACf,4EAA4E;YAC5E,4EAA4E;YAC5E,8EAA8E;YAC9E,6EAA6E;YAC7E,6EAA6E;YAC7E,iEAAiE;YACjE,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;gBAClB,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC/B,6EAA6E;oBAC7E,EAAE;oBACF,yFAAyF;oBACzF,yFAAyF;oBACzF,oFAAoF;oBACpF,uCAAuC;oBACvC,EAAE;oBACF,wCAAwC;oBACxC,kFAAkF;oBAClF,iFAAiF;oBACjF,oFAAoF;oBACpF,6EAA6E;oBAC7E,+EAA+E;oBAC/E,gFAAgF;oBAChF,IAAI,aAAa,GAAG,CAAC,CAAC;oBAEtB,wEAAwE;oBACxE,6DAA6D;oBAC7D,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;wBAC5C,MAAM,gBAAgB,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;wBAC7G,MAAM,UAAU,GAAG,WAAW,GAAG,gBAAgB,CAAC;wBAClD,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;4BACjB,MAAM,KAAK,GAAG,yBAAyB,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;4BAC7E,MAAM,KAAK,GAAG,yBAAyB,CAAC,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;4BAC9E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;gCAClC,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;4BACtF,CAAC;4BACD,IAAI,EAAE,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gCACrB,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;oCAChD,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;wCAC/B,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,UAAU,GAAG,iCAAiC,CAAC,EAAE,CAAC,CAAC,CAAC;oCACxG,CAAC;gCACL,CAAC;4BACL,CAAC;4BACD,aAAa,IAAI,UAAU,CAAC;wBAChC,CAAC;oBACL,CAAC;oBAED,wEAAwE;oBACxE,2EAA2E;oBAC3E,KAAK,IAAI,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC;wBACxE,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;wBAC3C,IAAI,CAAC,KAAK,EAAE,CAAC;4BACT,SAAS;wBACb,CAAC;wBACD,iFAAiF;wBACjF,8FAA8F;wBAC9F,8FAA8F;wBAC9F,0FAA0F;wBAC1F,4FAA4F;wBAC5F,gGAAgG;wBAChG,IAAI,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,EAAE,CAAC;4BACvD,aAAa,IAAI,KAAK,CAAC,YAAY,CAAC;4BACpC,SAAS;wBACb,CAAC;wBACD,MAAM,MAAM,GAAG,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAC;wBACrD,IAAI,CAAC,MAAM,EAAE,CAAC;4BACV,MAAM,IAAI,KAAK,CAAC,iCAAiC,KAAK,CAAC,IAAI,wDAAwD,CAAC,CAAC;wBACzH,CAAC;wBACD,IAAI,CAAC,yBAAyB,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;wBACpG,aAAa,IAAI,MAAM,CAAC,YAAY,CAAC;oBACzC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACJ,4EAA4E;oBAC5E,2EAA2E;oBAC3E,iFAAiF;oBACjF,yEAAyE;oBACzE,sEAAsE;oBACtE,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;wBACnB,MAAM,KAAK,GAAG,yBAAyB,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;wBAC7E,MAAM,KAAK,GAAG,yBAAyB,CAAC,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;wBAC9E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;4BACnC,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;wBACtF,CAAC;wBACD,IAAI,EAAE,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;4BACrB,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;gCAChD,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;oCAC/B,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,WAAW,GAAG,iCAAiC,CAAC,EAAE,CAAC,CAAC,CAAC;gCACzG,CAAC;4BACL,CAAC;wBACL,CAAC;oBACL,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC;QAED,2FAA2F;QAC3F,yFAAyF;QACzF,yFAAyF;QACzF,sCAAsC;QACtC,+FAA+F;QAC/F,IAAI,WAAW,EAAE,CAAC;YACd,MAAM,aAAa,GAAG,YAAY,GAAG,WAAW,CAAC,CAAC,CAAC;YACnD,IAAI,aAAa,GAAG,WAAW,EAAE,CAAC;gBAC9B,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACjC,uEAAuE;oBACvE,yEAAyE;oBACzE,2EAA2E;oBAC3E,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;wBACnB,MAAM,KAAK,GAAG,yBAAyB,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;wBAC7E,MAAM,KAAK,GAAG,yBAAyB,CAAC,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;wBAC9E,KAAK,IAAI,CAAC,GAAG,aAAa,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;4BAC/C,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;wBACzF,CAAC;oBACL,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACJ,6EAA6E;oBAC7E,4EAA4E;oBAC5E,EAAE;oBACF,yDAAyD;oBACzD,6EAA6E;oBAC7E,4EAA4E;oBAC5E,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;oBACvF,MAAM,UAAU,GAAG,WAAW,GAAG,UAAU,CAAC,CAAC,gCAAgC;oBAC7E,MAAM,QAAQ,GAA0B,IAAI,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACvF,MAAM,QAAQ,GAA4B,IAAI,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACzF,MAAM,UAAU,GAAa,IAAI,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBACzE,2DAA2D;oBAC3D,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,WAAW,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;wBAC9D,QAAQ,CAAC,CAAC,CAAC,GAAG,yBAAyB,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;wBAC7E,QAAQ,CAAC,CAAC,CAAC,GAAG,yBAAyB,CAAC,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;wBAC9E,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;oBACtB,CAAC;oBACD,qEAAqE;oBACrE,IAAI,SAAS,GAAG,UAAU,CAAC;oBAC3B,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC;wBACnD,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;wBACpC,IAAI,CAAC,KAAK,EAAE,CAAC;4BACT,SAAS;wBACb,CAAC;wBACD,8FAA8F;wBAC9F,8FAA8F;wBAC9F,+FAA+F;wBAC/F,IAAI,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,EAAE,CAAC;4BACvD,UAAU,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC;4BAC3B,SAAS,IAAI,KAAK,CAAC,YAAY,CAAC;4BAChC,SAAS;wBACb,CAAC;wBACD,MAAM,MAAM,GAAG,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAC;wBACrD,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;4BACjC,MAAM,IAAI,KAAK,CAAC,iCAAiC,KAAK,CAAC,IAAI,wDAAwD,CAAC,CAAC;wBACzH,CAAC;wBACD,QAAQ,CAAC,EAAE,CAAC,GAAG,yBAAyB,CAAC,kBAAkB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;wBAChF,QAAQ,CAAC,EAAE,CAAC,GAAG,yBAAyB,CAAC,mBAAmB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;wBACjF,UAAU,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC;wBAC3B,SAAS,IAAI,MAAM,CAAC,YAAY,CAAC;oBACrC,CAAC;oBACD,KAAK,IAAI,QAAQ,GAAG,aAAa,EAAE,QAAQ,GAAG,WAAW,EAAE,QAAQ,EAAE,EAAE,CAAC;wBACpE,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;wBACpE,MAAM,IAAI,GAAG,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;wBAClE,MAAM,IAAI,GAAG,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;wBAClE,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;4BACf,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;wBAClI,CAAC;oBACL,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC;QAED,yBAAyB;QACzB,SAAS,GAAG,WAAW,CAAC;QACxB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YACzB,IAAI,CAAC,yBAAyB,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YAC/F,SAAS,IAAI,KAAK,CAAC,YAAY,CAAC;QACpC,CAAC;QAED,uCAAuC;QACvC,MAAM,SAAS,GAAG,CAAC,UAAU,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC;QAC3C,KAAK,IAAI,CAAC,GAAG,UAAU,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;YAC1C,IAAI,CAAC,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;QACpD,CAAC;QAED,6CAA6C;QAC7C,IAAI,UAAU,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC;YACnC,IAAI,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;QAC7C,CAAC;QACD,4GAA4G;QAC5G,4GAA4G;QAC5G,IAAI,CAAC,qBAAqB,CAAC,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3F,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC;QAC/B,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC;QAC7B,2GAA2G;QAC3G,iGAAiG;QACjG,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC;QAEhC,qHAAqH;QACrH,uHAAuH;QACvH,+FAA+F;QAC/F,uDAAuD;QACvD,mHAAmH;QACnH,kDAAkD;QAClD,MAAM,eAAe,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC;QAC1C,IAAI,eAAe,EAAE,CAAC;YAClB,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;YAC9B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAC5B,CAAC;QAED,IAAI,CAAC;YACD,wBAAwB;YACxB,IAAI,WAAW,EAAE,CAAC;gBACd,mFAAmF;gBACnF,sFAAsF;gBACtF,4EAA4E;gBAC5E,uFAAuF;gBACvF,wFAAwF;gBACxF,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;oBACnE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;wBACpB,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;oBAC1B,CAAC;oBACD,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC;wBACzC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;wBACpC,MAAM,SAAS,GAAG,IAAI,UAAU,CAC5B,IAAI,EACJ,WAAW,CAAC,CAAC,EACb,WAAW,CAAC,CAAC,EACb,SAAS,CAAC,0BAA0B,EACpC,IAAI,CAAC,MAAM,EACX,KAAK,EACL,KAAK,EACL,SAAS,CAAC,4BAA4B,EACtC,SAAS,CAAC,4BAA4B,CACzC,CAAC;wBACF,SAAS,CAAC,KAAK,GAAG,SAAS,CAAC,yBAAyB,CAAC;wBACtD,SAAS,CAAC,KAAK,GAAG,SAAS,CAAC,yBAAyB,CAAC;wBACtD,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;wBACjC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;wBACpF,IAAI,CAAC,oBAAoB,CAAC,SAAS,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;oBAC/E,CAAC;gBACL,CAAC;gBAED,iFAAiF;gBACjF,uFAAuF;gBACvF,IAAI,EAAE,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;oBACrB,MAAM,aAAa,GAAG,YAAY,GAAG,WAAW,CAAC,CAAC,CAAC;oBACnD,IAAI,aAAa,GAAG,WAAW,EAAE,CAAC;wBAC9B,MAAM,SAAS,GAAG,aAAa,GAAG,iCAAiC,CAAC;wBACpE,MAAM,OAAO,GAAG,WAAW,GAAG,iCAAiC,CAAC;wBAChE,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;4BAChD,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;gCAC/B,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,SAAS,CAAC,CAAC;4BACjF,CAAC;wBACL,CAAC;oBACL,CAAC;gBACL,CAAC;gBAED,6EAA6E;gBAC7E,kFAAkF;gBAClF,oEAAoE;gBACpE,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;gBACpC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,eAAe,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC,GAAG,YAAY,EAAE,EAAE,CAAC,CAAC;YAC1H,CAAC;iBAAM,CAAC;gBACJ,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;YACrD,CAAC;YAED,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACtB,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAE5B,yFAAyF;YACzF,gFAAgF;YAChF,uFAAuF;YACvF,sFAAsF;YACtF,yFAAyF;YACzF,wFAAwF;YACxF,yFAAyF;YACzF,4DAA4D;YAC5D,mFAAmF;YACnF,uFAAuF;YACvF,oFAAoF;YACpF,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,WAAW,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;gBACnE,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;gBAC7D,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACjE,CAAC;YAED,8BAA8B;YAC9B,MAAM,WAAW,GAAqC,EAAE,CAAC;YACzD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACrC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;gBACxB,MAAM,YAAY,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC;gBAE5C,MAAM,eAAe,GAAG,KAAK,CAAC,cAAc,EAAE,CAAC;gBAC/C,IAAI,CAAC,qBAAqB,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC;gBAE1D,MAAM,SAAS,GAAG,IAAI,8BAA8B,CAChD,KAAK,CAAC,IAAI,EACV,IAAI,CAAC,QAAQ,EAAE,EACf,IAAI,EACJ,YAAY,EACZ,KAAK,CAAC,eAAe,EAAE,EACvB,KAAK,CAAC,YAAY,EAClB,yBAAyB,CAAC,CAAC,CAAC,EAC5B,yBAAyB,CAAC,CAAC,CAAC,CAC/B,CAAC;gBAEF,IAAI,aAAa,EAAE,CAAC;oBAChB,KAAK,CAAC,OAAO,EAAE,CAAC;gBACpB,CAAC;gBAED,MAAM,UAAU,GAAG,IAAI,UAAU,EAAE,CAAC;gBACpC,eAAe,CAAC,SAAS,CAAC,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC;gBAC7E,SAAS,CAAC,kBAAkB,GAAG,UAAU,CAAC;gBAC1C,SAAS,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;gBAEnC,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC;gBAC5C,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAChC,CAAC;YAED,sEAAsE;YACtE,IAAI,CAAC,8BAA8B,EAAE,CAAC;YAEtC,mHAAmH;YACnH,6GAA6G;YAC7G,IAAI,eAAe,EAAE,CAAC;gBAClB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;gBACzB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;oBACf,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;wBACrB,OAAO,EAAE,kCAAkC,CAAC,aAAa;wBACzD,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;qBAC/E,CAAC,CAAC;gBACP,CAAC;gBACD,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;gBAC7B,+FAA+F;gBAC/F,8FAA8F;gBAC9F,8FAA8F;gBAC9F,iGAAiG;gBACjG,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;oBACzB,IAAI,CAAC,sBAAsB,EAAE,CAAC;gBAClC,CAAC;gBACD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YAC7B,CAAC;YAED,IAAI,CAAC,4BAA4B,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAClE,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,CAAC;QAChD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,6EAA6E;YAC7E,IAAI,eAAe,EAAE,CAAC;gBAClB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;gBACzB,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;YACjC,CAAC;YACD,MAAM,CAAC,CAAC;QACZ,CAAC;IACL,CAAC;IAED,8EAA8E;IAC9E,sBAAsB;IACtB,8EAA8E;IAE9E;;;;;;;OAOG;IACI,OAAO,CAAC,KAA4B,EAAE,eAAwB,IAAI;QACrE,uGAAuG;QACvG,wGAAwG;QACxG,4FAA4F;QAC5F,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,KAAK,CAAC,EAAE,YAAY,CAAC,CAAC;QACtE,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IAED;;;;;OAKG;IACK,wBAAwB;QAC5B,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxC,IAAI,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;gBACnD,SAAS;YACb,CAAC;YACD,IAAI,KAAK,CAAC,cAAc,GAAG,KAAK,EAAE,CAAC;gBAC/B,KAAK,GAAG,KAAK,CAAC,cAAc,CAAC;YACjC,CAAC;YACD,IAAI,KAAK,CAAC,QAAQ,GAAG,MAAM,EAAE,CAAC;gBAC1B,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC;YAC5B,CAAC;YACD,IAAI,KAAK,CAAC,kBAAkB,EAAE,CAAC;gBAC3B,QAAQ,GAAG,IAAI,CAAC;YACpB,CAAC;QACL,CAAC;QACD,IAAI,CAAC,uBAAuB,GAAG,KAAK,CAAC;QACrC,IAAI,CAAC,cAAc,GAAG,KAAK,GAAG,CAAC,CAAC;QAChC,IAAI,CAAC,kBAAkB,GAAG,MAAM,CAAC;QACjC,0HAA0H;QAC1H,iHAAiH;QACjH,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC;IACpC,CAAC;IAED;;;;;;;;;OASG;IACK,cAAc,CAAC,KAAa;QAChC,4GAA4G;QAC5G,iGAAiG;QACjG,IAAI,CAAC,uBAAuB,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QACpD,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QACvC,IAAI,KAAK,EAAE,CAAC;YACR,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACxB,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC;QACzB,CAAC;QACD,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAChC,6GAA6G;QAC7G,kDAAkD;QAClD,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,KAAK,CAAC,CAAC;QAC9E,IAAI,YAAY,EAAE,CAAC;YACf,YAAY,CAAC,OAAO,GAAG,IAAI,CAAC;QAChC,CAAC;QACD,uGAAuG;QACvG,wFAAwF;QACxF,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QAClC,iGAAiG;QACjG,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACvC,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAC9B,IAAI,CAAC,8BAA8B,EAAE,CAAC;IAC1C,CAAC;IAED;;;;;OAKG;IACO,gBAAgB;QACtB,iGAAiG;QACjG,uGAAuG;QACvG,qGAAqG;QACrG,gFAAgF;QAChF,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;YACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACxB,CAAC;QACD,sGAAsG;QACtG,yGAAyG;QACzG,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;YACzB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YACtB,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC9G,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,oBAAoB,EAAE,OAAO,EAAE,CAAC;YACrC,IAAI,CAAC,oBAAoB,EAAE,OAAO,EAAE,CAAC;YACrC,IAAI,CAAC,eAAe,EAAE,OAAO,EAAE,CAAC;YAChC,IAAI,CAAC,cAAc,EAAE,OAAO,EAAE,CAAC;YAC/B,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;YACjC,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;YACjC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;YAC5B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC/B,CAAC;QACD,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,kGAAkG;YAClG,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;YAC5B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAC7B,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,kBAAkB,EAAE,OAAO,EAAE,CAAC;YACnC,IAAI,CAAC,kBAAkB,EAAE,OAAO,EAAE,CAAC;YACnC,IAAI,CAAC,qBAAqB,EAAE,OAAO,EAAE,CAAC;QAC1C,CAAC;QACD,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;QAC/B,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;QAC/B,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;QAClC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACnB,mGAAmG;YACnG,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjC,GAAG,CAAC,OAAO,EAAE,CAAC;YAClB,CAAC;YACD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YACxB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAC5B,CAAC;aAAM,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAC1B,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBAC/B,CAAC,CAAC,OAAO,EAAE,CAAC;YAChB,CAAC;YACD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAC5B,CAAC;QACD,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC3B,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,CAAC;YACnC,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;QACpC,CAAC;QACD,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QACtB,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC5B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;QACxB,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;QAC1B,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;QAC/B,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;QAC/B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;QACnB,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;QACvB,uGAAuG;QACvG,yGAAyG;QACzG,oDAAoD;QACpD,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;IAC/B,CAAC;IAED;;;;;;;;;;;OAWG;IACI,YAAY;QACf,IAAI,IAAI,CAAC,sBAAsB,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACzC,OAAO;QACX,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAc7C,MAAM,KAAK,GAAmB,EAAE,CAAC;QACjC,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAChD,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACnC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC/C,SAAS;YACb,CAAC;YACD,MAAM,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,IAAI,IAAI,CAAC;YAC3E,MAAM,WAAW,GAAG,KAAK,CAAC,cAAc,EAAE,CAAC,KAAK,EAAE,CAAC;YACnD,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;YAClD,IAAI,KAAK,EAAE,CAAC;gBACR,kGAAkG;gBAClG,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC,GAAG,UAAU,CAAC;gBACnE,MAAM,QAAQ,GAAG,WAAW,GAAG,SAAS,CAAC;gBACzC,MAAM,YAAY,GAAG,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;gBAC/C,MAAM,MAAM,GAAiC;oBACzC,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,YAAY,EAAE,YAAY;oBAC1B,WAAW,EAAE,IAAI;oBACjB,OAAO,EAAE,IAAI;oBACb,SAAS,EAAE,CAAC;oBACZ,UAAU,EAAE,KAAK;oBACjB,cAAc,EAAE,GAAG,EAAE,CAAC,WAAW;oBACjC,eAAe,EAAE,GAAG,EAAE,CAAC,IAAI,YAAY,CAAC,OAAO,CAAC,YAAY,EAAE,OAAO,CAAC,YAAY,CAAC;oBACnF,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC;oBACjB,gBAAgB,EAAE,IAAI;iBACzB,CAAC;gBACF,KAAK,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,CAAC;gBACxG,SAAS,IAAI,YAAY,CAAC;YAC9B,CAAC;iBAAM,CAAC;gBACJ,MAAM,MAAM,GAAG,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAC;gBACrD,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;oBACjC,MAAM,IAAI,KAAK,CAAC,2DAA2D,KAAK,CAAC,IAAI,qBAAqB,CAAC,CAAC;gBAChH,CAAC;gBACD,KAAK,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;gBACvG,SAAS,IAAI,MAAM,CAAC,YAAY,CAAC;YACrC,CAAC;QACL,CAAC;QAED,uGAAuG;QACvG,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,IAAI,CAAC,+BAA+B,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACzE,CAAC;QAED,+FAA+F;QAC/F,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,sBAAsB,EAAE,CAAC;YAC1C,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;QACpC,CAAC;QAED,+FAA+F;QAC/F,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAExB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrB,qGAAqG;YACrG,mGAAmG;YACnG,uGAAuG;YACvG,2FAA2F;YAC3F,IAAI,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC;YACjC,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;YAC/B,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,CAAC;YACpC,IAAI,CAAC,wBAAwB,EAAE,CAAC;YAChC,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;YAC1B,wGAAwG;YACxG,sGAAsG;YACtG,IAAI,CAAC,kBAAkB,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC,OAAO,KAAK,GAAG,CAAC;YACzF,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACvB,IAAI,CAAC,4BAA4B,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;YACrD,OAAO;QACX,CAAC;QAED,0GAA0G;QAC1G,0GAA0G;QAC1G,4GAA4G;QAC5G,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAEhC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;QAC9B,IAAI,CAAC;YACD,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,iBAAiB,CACtD,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAC1B,KAAK,CACR,CAAC;YAEF,4FAA4F;YAC5F,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACpC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBACtB,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;gBAC/B,MAAM,YAAY,GAAG,QAAQ,CAAC,SAAS,CAAC;gBAExC,IAAI,CAAC,qBAAqB,CAAC,YAAY,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;gBAC3D,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;gBACtD,MAAM,UAAU,GAAG,IAAI,UAAU,EAAE,CAAC;gBACpC,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBAC5E,QAAQ,CAAC,kBAAkB,GAAG,UAAU,CAAC;gBACzC,QAAQ,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;gBAElC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;gBAC5C,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,iBAAiB,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC;gBAC5G,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;gBAChD,QAAQ,CAAC,OAAO,EAAE,CAAC;gBAEnB,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;oBACb,yFAAyF;oBACzF,uEAAuE;oBACvE,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,YAAY,CAAC;oBACpC,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,QAAQ,CAAC,iBAAiB,GAAG,IAAI,CAAC,QAAQ,CAAC;oBAC7D,iGAAiG;oBACjG,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW;wBACxD,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,KAAM,CAAC,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;wBAC9F,CAAC,CAAC,IAAI,CAAC;gBACf,CAAC;qBAAM,CAAC;oBACJ,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,CAAC,4BAA4B;gBAC5E,CAAC;YACL,CAAC;YAED,kGAAkG;YAClG,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACjB,IAAI,CAAC,8BAA8B,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACxE,CAAC;YAED,2EAA2E;YAC3E,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAM,CAAC,CAAC;YAC1E,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC;YAC1D,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,CAAC;YAEpC,uGAAuG;YACvG,sGAAsG;YACtG,iGAAiG;YACjG,IAAI,CAAC,8BAA8B,EAAE,CAAC;YAEtC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;YACzB,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;YAC7B,qGAAqG;YACrG,uGAAuG;YACvG,uGAAuG;YACvG,uGAAuG;YACvG,IAAI,CAAC,sBAAsB,EAAE,CAAC;YAC9B,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC5B,MAAM,kBAAkB,GAAG,IAAI,CAAC,OAAwB,CAAC;YACzD,kBAAkB,EAAE,WAAW,CAAC;gBAC5B,OAAO,EAAE,kCAAkC,CAAC,aAAa;gBACzD,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;aAC/E,CAAC,CAAC;YACH,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YACzB,IAAI,CAAC,4BAA4B,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACtE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;YACzB,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;YAC7B,MAAM,CAAC,CAAC;QACZ,CAAC;IACL,CAAC;IAED;;;;;;;;OAQG;IACI,UAAU,CAAC,KAAa;QAC3B,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACvC,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,wBAAwB,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;QAClF,CAAC;QAED,mGAAmG;QACnG,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACzB,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;YAC3B,OAAO;QACX,CAAC;QAED,0FAA0F;QAC1F,MAAM,SAAS,GAA0J,EAAE,CAAC;QAC5K,KAAK,IAAI,UAAU,GAAG,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,CAAC;YAC3E,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;YAC5C,IAAI,CAAC,KAAK,IAAI,UAAU,KAAK,KAAK,EAAE,CAAC;gBACjC,SAAS;YACb,CAAC;YACD,MAAM,MAAM,GAAG,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAC;YACrD,IAAI,CAAC,MAAM,EAAE,CAAC;gBACV,MAAM,IAAI,KAAK,CAAC,oFAAoF,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC;YACxH,CAAC;YACD,SAAS,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,KAAK,CAAC,cAAc,EAAE,CAAC,KAAK,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;QACzK,CAAC;QACD,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;QAElD,+FAA+F;QAC/F,KAAK,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;YAC5C,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;gBACtB,MAAM,IAAI,KAAK,CAAC,iDAAiD,SAAS,CAAC,IAAI,qBAAqB,CAAC,CAAC;YAC1G,CAAC;YACD,IAAI,MAAM,CAAC,SAAS,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBAC1C,MAAM,IAAI,KAAK,CAAC,6CAA6C,SAAS,CAAC,IAAI,qBAAqB,CAAC,CAAC;YACtG,CAAC;QACL,CAAC;QAED,yFAAyF;QACzF,IAAI,CAAC,uBAAuB,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAEpD,uGAAuG;QACvG,6CAA6C;QAC7C,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;QACpC,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAExB,6FAA6F;QAC7F,oFAAoF;QACpF,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,uCAAuC;YACvC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACvB,IAAI,CAAC,4BAA4B,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;YACrD,OAAO;QACX,CAAC;QAED,uFAAuF;QACvF,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;QAC9B,IAAI,CAAC;YACD,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAC/C,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAE3E,4CAA4C;YAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACxC,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBACxC,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;gBAC/B,MAAM,YAAY,GAAG,QAAQ,CAAC,SAAS,CAAC;gBAExC,4EAA4E;gBAC5E,IAAI,CAAC,qBAAqB,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;gBACnE,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;gBAC9D,MAAM,UAAU,GAAG,IAAI,UAAU,EAAE,CAAC;gBACpC,SAAS,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBACpF,QAAQ,CAAC,kBAAkB,GAAG,UAAU,CAAC;gBACzC,QAAQ,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;gBAElC,oFAAoF;gBACpF,QAAQ,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;gBACvC,QAAQ,CAAC,kBAAkB,CAAC,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,iBAAiB,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC;gBACvG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,GAAG,QAAQ,CAAC;gBAE3C,8EAA8E;gBAC9E,QAAQ,CAAC,OAAO,EAAE,CAAC;YACvB,CAAC;YAED,+DAA+D;YAC/D,iDAAiD;YACjD,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;YACzB,yFAAyF;YACzF,MAAM,kBAAkB,GAAG,IAAI,CAAC,OAAwB,CAAC;YACzD,kBAAkB,EAAE,WAAW,CAAC;gBAC5B,OAAO,EAAE,kCAAkC,CAAC,aAAa;gBACzD,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;aAC/E,CAAC,CAAC;YACH,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;YAC7B,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,6EAA6E;YAC7E,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;YACzB,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;YAC7B,MAAM,CAAC,CAAC;QACZ,CAAC;IACL,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;OAqBG;IACI,oBAAoB,CACvB,QAAgB,EAChB,cAAsB,MAAM,CAAC,QAAQ,EAAE,EACvC,OAAe,IAAI,CAAC,IAAI,GAAG,gBAAgB,EAC3C,iBAAyB,CAAC,EAC1B,WAAmB,CAAC,EACpB,qBAA8B,KAAK;QAEnC,yGAAyG;QACzG,4GAA4G;QAC5G,iDAAiD;QACjD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;YAClD,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;QACjF,CAAC;QAED,0GAA0G;QAC1G,wGAAwG;QACxG,uGAAuG;QACvG,MAAM,oBAAoB,GAAG,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,IAAI,QAAQ,GAAG,oBAAoB,EAAE,CAAC;YACrF,MAAM,IAAI,KAAK,CAAC,4DAA4D,oBAAoB,GAAG,CAAC,CAAC;QACzG,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,cAAc,CAAC,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;YAC9D,MAAM,IAAI,KAAK,CAAC,qEAAqE,CAAC,CAAC;QAC3F,CAAC;QACD,IAAI,QAAQ,GAAG,CAAC,KAAK,cAAc,GAAG,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,mGAAmG,CAAC,CAAC;QACzH,CAAC;QACD,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;YACf,MAAM,sBAAsB,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,iCAAiC,CAAC,CAAC;YAC1H,IAAI,cAAc,KAAK,sBAAsB,EAAE,CAAC;gBAC5C,MAAM,IAAI,KAAK,CAAC,wCAAwC,cAAc,4BAA4B,QAAQ,cAAc,sBAAsB,GAAG,CAAC,CAAC;YACvJ,CAAC;QACL,CAAC;QAED,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,CAAC,cAAc,CAAC;QACxE,MAAM,WAAW,GAAG,cAAc,GAAG,cAAc,CAAC;QAEpD,qGAAqG;QACrG,mFAAmF;QACnF,gGAAgG;QAChG,6FAA6F;QAC7F,uGAAuG;QACvG,yEAAyE;QACzE,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7C,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,+CAA+C;QACtF,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC,GAAG,UAAU,CAAC;QACrE,MAAM,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAC,CAAC,iDAAiD;QAC7F,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,UAAU,CAAC,GAAG,UAAU,CAAC;QACtE,MAAM,YAAY,GAAG,QAAQ,GAAG,eAAe,CAAC;QAEhD,8GAA8G;QAC9G,wGAAwG;QACxG,yGAAyG;QACzG,gFAAgF;QAChF,MAAM,eAAe,GAAG,WAAW,GAAG,YAAY,CAAC;QACnD,IAAI,eAAe,GAAG,CAAC,GAAG,WAAW,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CACX,kCAAkC,QAAQ,4BAA4B,eAAe,mEAAmE,WAAW,EAAE,CACxK,CAAC;QACN,CAAC;QAED,qGAAqG;QACrG,uGAAuG;QACvG,2FAA2F;QAC3F,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;QAE/B,4GAA4G;QAC5G,yGAAyG;QACzG,4GAA4G;QAC5G,IAAI,cAAc,GAAG,CAAC,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;YAC3B,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,uBAAuB,EAAE,cAAc,CAAC,CAAC;YACtF,uGAAuG;YACvG,mGAAmG;YACnG,sDAAsD;YACtD,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,EAAE,QAAQ,CAAC,CAAC;QAC1E,CAAC;QAED,0GAA0G;QAC1G,8GAA8G;QAC9G,4FAA4F;QAC5F,IAAI,kBAAkB,EAAE,CAAC;YACrB,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;YAC5B,IAAI,CAAC,2BAA2B,GAAG,IAAI,CAAC;QAC5C,CAAC;QAED,6FAA6F;QAC7F,MAAM,SAAS,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;QACpF,MAAM,SAAS,GAAG,IAAI,OAAO,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAEvF,mGAAmG;QACnG,iGAAiG;QACjG,yFAAyF;QACzF,MAAM,cAAc,GAAiC;YACjD,IAAI;YACJ,YAAY,EAAE,YAAY;YAC1B,WAAW,EAAE,IAAI;YACjB,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,CAAC;YACZ,UAAU,EAAE,KAAK;YACjB,cAAc,EAAE,GAAG,EAAE,CAAC,WAAW;YACjC,eAAe,EAAE,GAAG,EAAE,CAAC,IAAI,YAAY,CAAC,OAAO,CAAC,YAAY,EAAE,OAAO,CAAC,YAAY,CAAC;YACnF,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC;YACjB,gBAAgB,EAAE,IAAI;SACzB,CAAC;QAEF,MAAM,EAAE,WAAW,EAAE,mBAAmB,EAAE,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,cAAc,CAAC,EAAE,KAAK,CAAC,CAAC;QAC7F,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;QAC7B,wGAAwG;QACxG,wGAAwG;QACxG,wGAAwG;QACxG,yGAAyG;QACzG,MAAM,KAAK,GAAwB;YAC/B,KAAK;YACL,IAAI,EAAE,WAAW;YACjB,SAAS,EAAE,mBAAmB,CAAC,CAAC,CAAC;YACjC,QAAQ,EAAE,eAAe;YACzB,SAAS;YACT,SAAS;YACT,WAAW,EAAE,IAAI;YACjB,cAAc,EAAE,cAAc,GAAG,CAAC,IAAI,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;YACvE,QAAQ,EAAE,cAAc,GAAG,CAAC,IAAI,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAC3D,kBAAkB;YAClB,OAAO,EAAE,KAAK;SACjB,CAAC;QACF,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClC,QAAQ,GAAG,eAAe,CAAC;QAE3B,gGAAgG;QAChG,qEAAqE;QACrE,4DAA4D;QAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC;QACtB,MAAM,WAAW,GAAG,GAAG,EAAE;YACrB,IAAI,SAAS,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,EAAE,CAAC;gBAC7B,KAAK,CAAC,eAAe,CAAC,IAAI,YAAY,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;gBAC9E,QAAQ,CAAC,8BAA8B,EAAE,CAAC;YAC9C,CAAC;QACL,CAAC,CAAC;QACF,2GAA2G;QAC3G,kEAAkE;QAClE,MAAM,UAAU,GAAG,CAAC,MAAc,EAAE,EAAE;YAClC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBAChB,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,wCAAwC,CAAC,CAAC;YACvE,CAAC;QACL,CAAC,CAAC;QACF,uGAAuG;QACvG,wFAAwF;QACxF,MAAM,gBAAgB,GAAG,CAAC,MAAc,EAAE,MAAc,EAAE,KAAa,EAAE,EAAE;YACvE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,MAAM,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACtH,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,kBAAkB,MAAM,KAAK,MAAM,GAAG,KAAK,wCAAwC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC;YACnI,CAAC;QACL,CAAC,CAAC;QAEF,MAAM,MAAM,GAAoC;YAC5C,KAAK;YACL,QAAQ;YACR,IAAI,SAAS;gBACT,OAAO,KAAK,CAAC,SAAS,CAAC;YAC3B,CAAC;YACD,IAAI,IAAI;gBACJ,OAAO,KAAK,CAAC,IAAI,CAAC;YACtB,CAAC;YACD,IAAI,cAAc;gBACd,OAAO,QAAQ,CAAC,cAAc,CAAC;YACnC,CAAC;YACD,IAAI,mBAAmB;gBACnB,OAAO,QAAQ,CAAC,mBAAmB,CAAC;YACxC,CAAC;YACD,IAAI,mBAAmB;gBACnB,OAAO,QAAQ,CAAC,mBAAmB,CAAC;YACxC,CAAC;YACD,IAAI,aAAa;gBACb,OAAO,QAAQ,CAAC,aAAa,CAAC;YAClC,CAAC;YACD,IAAI,cAAc;gBACd,OAAO,QAAQ,CAAC,eAAe,CAAC;YACpC,CAAC;YACD,IAAI,QAAQ;gBACR,OAAO,QAAQ,CAAC,SAAS,CAAC;YAC9B,CAAC;YACD,IAAI,UAAU;gBACV,OAAO,QAAQ,CAAC,WAAW,CAAC;YAChC,CAAC;YACD,IAAI,WAAW;gBACX,OAAO,QAAQ,CAAC,YAAY,CAAC;YACjC,CAAC;YACD,IAAI,UAAU;gBACV,OAAO,QAAQ,CAAC,eAAe,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC7D,CAAC;YACD,IAAI,kBAAkB;gBAClB,OAAO,QAAQ,CAAC,mBAAmB,CAAC;YACxC,CAAC;YACD,eAAe,EAAE,CAAC,WAAW,EAAE,EAAE;gBAC7B,UAAU,CAAC,iBAAiB,CAAC,CAAC;gBAC9B,6FAA6F;gBAC7F,IAAI,WAAW,EAAE,CAAC;oBACd,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;wBAC1B,gBAAgB,CAAC,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;oBAC3D,CAAC;gBACL,CAAC;gBACD,uFAAuF;gBACvF,KAAK,CAAC,WAAW,GAAG,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;gBACxG,MAAM,YAAY,GAAG,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;gBACtH,QAAQ,CAAC,kBAAkB,CAAC,KAAK,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;YAC/D,CAAC;YACD,WAAW,EAAE,CAAC,WAAW,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE;gBAC5C,UAAU,CAAC,aAAa,CAAC,CAAC;gBAC1B,8FAA8F;gBAC9F,gBAAgB,CAAC,aAAa,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;gBACpD,QAAQ,CAAC,qBAAqB,CAAC,KAAK,CAAC,IAAI,GAAG,WAAW,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;gBAClG,WAAW,EAAE,CAAC;YAClB,CAAC;YACD,kBAAkB,EAAE,CAAC,WAAW,EAAE,KAAK,EAAE,EAAE;gBACvC,UAAU,CAAC,oBAAoB,CAAC,CAAC;gBACjC,gBAAgB,CAAC,oBAAoB,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;gBAC3D,QAAQ,CAAC,yBAAyB,CAAC,KAAK,CAAC,IAAI,GAAG,WAAW,EAAE,KAAK,CAAC,CAAC;YACxE,CAAC;YACD,YAAY,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;gBACvB,UAAU,CAAC,cAAc,CAAC,CAAC;gBAC3B,SAAS,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;gBAC/B,SAAS,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;gBAC/B,WAAW,EAAE,CAAC;YAClB,CAAC;YACD,iBAAiB,EAAE,GAAG,EAAE;gBACpB,UAAU,CAAC,mBAAmB,CAAC,CAAC;gBAChC,QAAQ,CAAC,oBAAoB,EAAE,CAAC;YACpC,CAAC;YACD,oBAAoB,EAAE,CAAC,QAAQ,EAAE,EAAE;gBAC/B,MAAM,QAAQ,GAAG,QAAQ,CAAC,+BAA+B,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;gBACxE,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC3E,CAAC;YACD,mBAAmB,EAAE,CAAC,QAAQ,EAAE,EAAE;gBAC9B,MAAM,QAAQ,GAAG,QAAQ,CAAC,8BAA8B,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;gBACvE,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC1E,CAAC;SACJ,CAAC;QACF,mGAAmG;QACnG,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC9B,OAAO,MAAM,CAAC;IAClB,CAAC;IAED;;;;;;OAMG;IACa,SAAS,CAAC,sBAA2B,EAAE,EAAE,WAAmB,QAAQ;QAChF,mBAAmB,GAAG,KAAK,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QAC3D,mBAAmB,CAAC,SAAS,GAAG,EAAE,CAAC;QACnC,mBAAmB,CAAC,gBAAgB,GAAG,SAAS,CAAC;QACjD,mBAAmB,CAAC,UAAU,GAAG,SAAS,CAAC;QAC3C,mBAAmB,CAAC,gBAAgB,GAAG,SAAS,CAAC;QACjD,mBAAmB,CAAC,UAAU,GAAG,SAAS,CAAC;QAC3C,mBAAmB,CAAC,SAAS,GAAG,EAAE,CAAC;QACnC,mBAAmB,CAAC,OAAO,GAAG,SAAS,CAAC;QACxC,mBAAmB,CAAC,IAAI,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAC/C,mBAAmB,CAAC,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC;QAChD,mBAAmB,CAAC,gBAAgB,GAAG,IAAI,CAAC,iBAAiB,CAAC;QAC9D,mBAAmB,CAAC,mBAAmB,GAAG,IAAI,CAAC,mBAAmB,CAAC;QACnE,mBAAmB,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAEzC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACnB,mBAAmB,CAAC,UAAU,GAAG,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,yBAAyB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC;QAC5H,CAAC;QACD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,mBAAmB,CAAC,MAAM,GAAG,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC;YAChH,mBAAmB,CAAC,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC;QAClD,CAAC;QACD,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,MAAM,iBAAiB,GAAG,mBAAmB,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;YAChG,mBAAmB,CAAC,WAAW,GAAG,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,yBAAyB,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC;QAC/H,CAAC;QACD,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;YAC3B,mBAAmB,CAAC,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;QACrH,CAAC;QAED,OAAO,mBAAmB,CAAC;IAC/B,CAAC;IAED;;;;;;;OAOG;IACI,MAAM,CAAC,cAAc,CACxB,UAAe,EACf,KAAY,EACZ,IAAgG;QAEhG,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC;QAE1E,IAAI,CAAC,gBAAgB,GAAG,UAAU,CAAC,gBAAgB,IAAI,KAAK,CAAC;QAC7D,IAAI,CAAC,mBAAmB,GAAG,UAAU,CAAC,mBAAmB,IAAI,yBAAyB,CAAC,2BAA2B,CAAC;QAEnH,IAAI,UAAU,GAAqC,UAAU,CAAC,UAAU,CAAC;QACzE,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;YACjC,UAAU,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC;QAClD,CAAC;QAED,MAAM,MAAM,GAAwC,UAAU,CAAC,MAAM,CAAC;QACtE,IAAI,YAAsC,CAAC;QAC3C,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YACzC,MAAM,OAAO,GAAiB,EAAE,CAAC;YACjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACtD,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;gBACvB,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAC3B,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,UAAU,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC5D,CAAC;qBAAM,CAAC;oBACJ,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;gBACtB,CAAC;YACL,CAAC;YACD,YAAY,GAAG,OAAO,CAAC;QAC3B,CAAC;QAED,IAAI,WAAW,GAAgD,UAAU,CAAC,WAAW,CAAC;QACtF,IAAI,iBAAyC,CAAC;QAC9C,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;YAClC,WAAW,GAAG,IAAI,WAAW,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC,CAAC;QACrE,CAAC;QACD,IAAI,WAAW,EAAE,CAAC;YACd,iBAAiB,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;QACtD,CAAC;QAED,IAAI,UAAU,EAAE,CAAC;YACb,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,IAAI,KAAK,CAAC;YACzC,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,iBAAiB,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC;QACjG,CAAC;QAED,IAAI,UAAU,CAAC,WAAW,EAAE,CAAC;YACzB,KAAK,MAAM,cAAc,IAAI,UAAU,CAAC,WAAW,EAAE,CAAC;gBAClD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC;gBAC/C,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;gBAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAmC,CAAC;gBAChF,MAAM,YAAY,GAAG,SAAS,CAAC,SAAS,CAAC;gBACzC,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC;gBAC5C,IAAI,CAAC,qBAAqB,CAAC,YAAY,EAAE,SAAS,CAAC,cAAc,EAAE,CAAC,CAAC;gBACrE,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;YAC/D,CAAC;QACL,CAAC;QAED,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAU,KAAK,CAAC,UAAe,EAAE,KAAY;QACtD,OAAO,qBAAqB,CAAC,cAAc,CAAC,UAAU,EAAE,KAAK,EAAE,qBAAqB,CAAC,CAAC;IAC1F,CAAC;CACJ;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,4BAA4B,CAAC,SAAiB;IAC1D,OAAO,SAAS,KAAK,uBAAuB,IAAI,SAAS,KAAK,yBAAyB,CAAC;AAC5F,CAAC;AAED,IAAI,WAAW,GAAG,KAAK,CAAC;AACxB;;;GAGG;AACH,MAAM,UAAU,6BAA6B;IACzC,IAAI,WAAW,EAAE,CAAC;QACd,OAAO;IACX,CAAC;IACD,WAAW,GAAG,IAAI,CAAC;IAEnB,IAAI,CAAC,4BAA4B,GAAG,qBAAqB,CAAC,KAAK,CAAC;AACpE,CAAC","sourcesContent":["/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"core/types\";\r\nimport { type Scene } from \"core/scene.pure\";\r\nimport { Matrix, Quaternion, Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { type Vector2 } from \"core/Maths/math.vector\";\r\nimport { type Effect } from \"core/Materials/effect.pure\";\r\nimport { GetGaussianSplattingMaxPartCount } from \"core/Materials/GaussianSplatting/gaussianSplattingMaterial.pure\";\r\nimport { GaussianSplattingMeshBase, AllocateShBuffers, type IGaussianSplattingSplatRange } from \"./gaussianSplattingMeshBase.pure\";\r\nimport { GaussianSplattingSortWorkerCommand } from \"./gaussianSplattingSortWorker\";\r\nimport { RawTexture } from \"core/Materials/Textures/rawTexture\";\r\nimport { type MultiRenderTarget } from \"core/Materials/Textures/multiRenderTarget.pure\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { DecodeBase64ToBinary, EncodeArrayBufferToBase64 } from \"core/Misc/stringTools\";\r\nimport { Mesh } from \"core/Meshes/mesh.pure\";\r\nimport { GaussianSplattingPartProxyMesh } from \"./gaussianSplattingPartProxyMesh.pure\";\r\nimport { BoundingInfo } from \"../../Culling/boundingInfo\";\r\nimport { type BaseTexture } from \"../../Materials/Textures/baseTexture.pure\";\r\nimport { type AbstractMesh } from \"core/Meshes/abstractMesh.pure\";\r\n\r\nconst _GaussianSplattingBytesPerSplat = 32;\r\nconst _GaussianSplattingBytesPerShTexel = 16;\r\n\r\ninterface IGaussianSplattingPartSource {\r\n name: string;\r\n _vertexCount: number;\r\n _splatsData: Nullable<ArrayBuffer | ArrayBufferView>;\r\n _shData: Nullable<Uint8Array[]>;\r\n _shDegree: number;\r\n isCompound: boolean;\r\n getWorldMatrix(): Matrix;\r\n getBoundingInfo(): BoundingInfo;\r\n dispose(): void;\r\n /**\r\n * When true this is a placeholder that reserves `_vertexCount` empty (invisible) splats in the\r\n * atlas instead of copying real data. Used by {@link GaussianSplattingMesh.reserveStreamingPart}\r\n * so a streaming engine can later GPU-decode into the reserved region. Sources flagged this way\r\n * are allowed to have a null `_splatsData`; their atlas region is left zeroed (invisible padding).\r\n */\r\n _isReservedEmpty?: boolean;\r\n}\r\n\r\n/**\r\n * Run-Length Encoding (RLE) compression for serialization\r\n * Compressed Uint32Array can be parsed using {@link ParsePartIndices}\r\n * Some notes for devs: We do not expect Uint8Array larger than 4GB,\r\n * so it should be safe to use Uint32Array.\r\n * @param partIndices A view of partIndices from GaussianSplattingMesh\r\n * @returns A compressed Uint32Array of [count, value, ...]\r\n */\r\nfunction CompressPartIndices(partIndices: Uint8Array): Uint32Array {\r\n const runs: number[] = [];\r\n const length = partIndices.length;\r\n let i = 0;\r\n while (i < length) {\r\n const value = partIndices[i];\r\n let count = 1;\r\n while (i + count < length && partIndices[i + count] === value) {\r\n count++;\r\n }\r\n runs.push(count, value);\r\n i += count;\r\n }\r\n return new Uint32Array(runs);\r\n}\r\n\r\n/**\r\n * Parse partIndices compressed by {@link CompressPartIndices} to runtime array\r\n * @param compressed The compressed partIndices of [count, value, ...]\r\n * @returns runtime Uint8Array for GaussianSplattingMesh\r\n */\r\nfunction ParsePartIndices(compressed: Uint32Array | number[]): Uint8Array {\r\n let totalCount = 0;\r\n const length = compressed.length;\r\n for (let i = 0; i < length; i += 2) {\r\n totalCount += compressed[i];\r\n }\r\n\r\n const partIndices = new Uint8Array(totalCount);\r\n let offset = 0;\r\n for (let i = 0; i < length; i += 2) {\r\n const count = compressed[i];\r\n const value = compressed[i + 1];\r\n partIndices.fill(value, offset, offset + count);\r\n offset += count;\r\n }\r\n\r\n return partIndices;\r\n}\r\n\r\n/**\r\n * Handle to a region of a compound Gaussian Splatting mesh reserved for dynamic (streamed) content by\r\n * {@link GaussianSplattingMesh.reserveStreamingPart}. It lets a streaming engine populate the region's\r\n * splats over time and drive which of them are sorted/rendered, while the compound keeps depth-sorting\r\n * and drawing every part (static + streamed) together in one pass.\r\n *\r\n * Ranges/offsets passed to this handle are LOCAL to the part (0-based within `[0, capacity)`); the handle\r\n * translates them to the compound's global atlas coordinates.\r\n */\r\nexport interface IGaussianSplattingStreamingPart {\r\n /** The proxy mesh controlling this part's world transform and visibility. */\r\n readonly proxy: GaussianSplattingPartProxyMesh;\r\n /** The part index assigned to this streaming region in the compound. */\r\n readonly partIndex: number;\r\n /** First atlas splat index of the reserved region. */\r\n readonly base: number;\r\n /** Number of splats reserved for the region. */\r\n readonly capacity: number;\r\n /** The compound's shared centers texture (the region occupies `[base, base+capacity)` within it). */\r\n readonly centersTexture: Nullable<BaseTexture>;\r\n /** The compound's shared covariance A texture. */\r\n readonly covariancesATexture: Nullable<BaseTexture>;\r\n /** The compound's shared covariance B texture. */\r\n readonly covariancesBTexture: Nullable<BaseTexture>;\r\n /** The compound's shared colors texture. */\r\n readonly colorsTexture: Nullable<BaseTexture>;\r\n /** The compound's shared CPU centers buffer consumed by the sort worker. */\r\n readonly splatPositions: Nullable<Float32Array>;\r\n /** The compound's shared render-target atlas a streaming engine decodes into, or null on a non-GPU backend. */\r\n readonly mrtAtlas: Nullable<MultiRenderTarget>;\r\n /**\r\n * The compound's shared higher-order SH render-target atlas (one single-attachment integer MRT per packed-u32\r\n * SH texture) a streaming engine bakes SH into, or null when SH decode was not requested for this part.\r\n */\r\n readonly shMrtAtlas: Nullable<MultiRenderTarget[]>;\r\n /**\r\n * The compound's shared rotation/scale render-target atlas (one 3-attachment half-float MRT) a streaming engine\r\n * decodes rotation/scale into for voxel-IBL shadows, or null when rotation decode was not requested for this part.\r\n */\r\n readonly rotMrtAtlas: Nullable<MultiRenderTarget>;\r\n /** Width (in texels) of the atlas, used to address decode/readback over the wide layout. */\r\n readonly atlasWidth: number;\r\n /** Whether the compound's shared depth sort is settled (a streaming engine polls this to detect readiness). */\r\n readonly isDepthSortSettled: boolean;\r\n /**\r\n * Restricts which of this part's splats are sorted/rendered, in LOCAL coordinates. `null` renders the\r\n * whole reserved region. The compound merges this with every other part's ranges into the single sort.\r\n * @param localRanges active local ranges, or `null` for the full region\r\n */\r\n setActiveRanges(localRanges: Nullable<readonly IGaussianSplattingSplatRange[]>): void;\r\n /**\r\n * CPU-decodes raw `.splat` bytes into the region at `localOffset`, uploading only those texels and\r\n * patching the sort worker. Grows the part's bounding info to include the written centers. This is the\r\n * CPU population path (used to seed the region or as a fallback when GPU decode is unavailable).\r\n * @param localOffset first local splat index to write\r\n * @param count number of splats to write\r\n * @param splatsData raw `.splat` bytes for `count` splats (stride 32)\r\n */\r\n writeSplats(localOffset: number, count: number, splatsData: ArrayBuffer | ArrayBufferView): void;\r\n /**\r\n * Patches only `[localOffset, localOffset+count)` of the worker's position buffer (for the GPU path,\r\n * where texel data is written directly to the atlas and only the CPU centers are pushed to the worker).\r\n * @param localOffset first local splat index\r\n * @param count number of splats\r\n */\r\n postPositionsRange(localOffset: number, count: number): void;\r\n /**\r\n * Grows the part's (and compound's) bounding info to include the given local-space centers extent.\r\n * @param min minimum corner\r\n * @param max maximum corner\r\n */\r\n expandBounds(min: Vector3, max: Vector3): void;\r\n /**\r\n * Re-posts the full merged position + part-index set to the compound's sort worker. Only needed after a\r\n * relayout moved the region's data wholesale; per-decode updates use {@link postPositionsRange} instead.\r\n */\r\n notifyDataChanged(): void;\r\n /**\r\n * Subscribes to the \"about to recreate the shared atlas to grow it\" event (e.g. another part is being added).\r\n * The callback receives the OLD atlas and should back up this region's GPU-only data before it is disposed.\r\n * @param callback invoked with the old atlas MRT\r\n * @returns an unsubscribe function (call it on dispose)\r\n */\r\n onBeforeAtlasRebuild(callback: (oldAtlas: MultiRenderTarget) => void): () => void;\r\n /**\r\n * Subscribes to the \"shared atlas has been recreated\" event. The callback receives the NEW atlas and should\r\n * rebind to it and restore this region's backed-up data.\r\n * @param callback invoked with the new atlas MRT\r\n * @returns an unsubscribe function (call it on dispose)\r\n */\r\n onAfterAtlasRebuild(callback: (newAtlas: MultiRenderTarget) => void): () => void;\r\n}\r\n\r\n/**\r\n * Internal mutable bookkeeping for one reserved streaming region. The handle's `base`/`partIndex` getters and\r\n * the compaction re-post read from this object, so {@link GaussianSplattingMesh.compactAtlas} can RELOCATE a\r\n * region (assign it a new base/partIndex) in place without invalidating the streaming engine's handle.\r\n */\r\ninterface IStreamingPartState {\r\n /** The proxy mesh for this region (stable identity across a relocation). */\r\n proxy: GaussianSplattingPartProxyMesh;\r\n /** First usable atlas splat index of the region (row-aligned). Updated when the region is relocated. */\r\n base: number;\r\n /** The region's current part index. Updated when parts before it are removed. */\r\n partIndex: number;\r\n /** Usable capacity (row-aligned), fixed for the region's lifetime. */\r\n capacity: number;\r\n /** Running local-space bounds of the region's written centers (shared with the handle's closures). */\r\n boundsMin: Vector3;\r\n boundsMax: Vector3;\r\n /** The region's last active LOD ranges in LOCAL coordinates, so a relocation can re-post them at the new base. */\r\n localRanges: Nullable<readonly IGaussianSplattingSplatRange[]>;\r\n /** Number of packed-u32 SH textures this streaming part bakes into the shared SH atlas (0 = no SH). Used to\r\n * recompute the compound's SH-atlas state from the SURVIVING parts when a part is removed (so removing the last\r\n * SH part turns the SH atlas off instead of leaving stale render-target degree/count behind). */\r\n shTextureCount: number;\r\n /** SH degree of this streaming part's baked SH (0 = no SH). Feeds the compound's max-degree recompute. */\r\n shDegree: number;\r\n /** Whether this streaming part decodes rotation/scale into the shared rotation atlas (for voxel-IBL shadows).\r\n * Used to recompute the compound's rotation-atlas state from the SURVIVING parts when a part is removed. */\r\n needsRotationScale: boolean;\r\n /** Set once the part is removed (tombstoned). The handle returned by {@link GaussianSplattingMesh.reserveStreamingPart}\r\n * checks this so a caller that retained a removed handle can't mutate a surviving part that later inherited this\r\n * region's part index/base. */\r\n removed: boolean;\r\n}\r\n\r\n/**\r\n * Class used to render a Gaussian Splatting mesh. Supports both single-cloud and compound\r\n * (multi-part) rendering. In compound mode, multiple Gaussian Splatting source meshes are\r\n * merged into one draw call while retaining per-part world-matrix control via\r\n * addPart/addParts and removePart.\r\n */\r\nexport class GaussianSplattingMesh extends GaussianSplattingMeshBase {\r\n /**\r\n * Proxy meshes indexed by part index. Maintained in sync with _partMatrices.\r\n */\r\n private _partProxies: GaussianSplattingPartProxyMesh[] = [];\r\n\r\n /** Part 0 local-space AABB when owned directly (not proxied). Set on first addPart, cleared on dispose/reset. */\r\n private _part0LocalMin: Nullable<Vector3> = null;\r\n private _part0LocalMax: Nullable<Vector3> = null;\r\n\r\n /**\r\n * World matrices for each part, indexed by part index.\r\n */\r\n protected _partMatrices: Matrix[] = [];\r\n\r\n /** When true, suppresses the sort trigger inside setWorldMatrixForPart during batch rebuilds. */\r\n private _rebuilding: boolean = false;\r\n\r\n /**\r\n * Visibility values for each part (0.0 to 1.0), indexed by part index.\r\n */\r\n protected _partVisibility: number[] = [];\r\n\r\n /**\r\n * Per-part active source-splat range overrides, indexed by part index, in GLOBAL source-splat\r\n * coordinates (offsets into the merged atlas). A part with no entry (undefined) renders its full\r\n * range; a part with an entry renders only those ranges. Used by streaming parts to render just\r\n * their currently-active LOD splats while static parts render fully. No overrides at all means no\r\n * filter (the base renders every splat, preserving the non-streaming fast path).\r\n */\r\n private _partSplatRanges: Nullable<IGaussianSplattingSplatRange[]>[] = [];\r\n\r\n /**\r\n * True once a streaming part has been reserved. A streamed region's data lives only on the GPU (no retained CPU\r\n * source), so atlas rebuilds and part add/remove take the streaming-aware paths that back up and restore each\r\n * region rather than regenerating it from a CPU source.\r\n * @internal\r\n */\r\n protected _hasStreamingPart = false;\r\n\r\n /** Mutable bookkeeping for each reserved streaming region, so {@link compactAtlas} can relocate them. */\r\n private _streamingStates: IStreamingPartState[] = [];\r\n\r\n /**\r\n * Max SH degree contributed by the live (non-tombstoned) streaming parts. Recomputed by\r\n * {@link _refreshStreamingShState} whenever parts change, so removing the last SH stream turns the shared SH\r\n * atlas off instead of leaving SH_DEGREE high over texels nothing refills.\r\n */\r\n private _streamingShDegree = 0;\r\n\r\n /** Part indices tombstoned by {@link removePart} while streaming — excluded from render, reclaimed by {@link compactAtlas}. */\r\n private _tombstonedPartIndices = new Set<number>();\r\n\r\n private _partIndicesTexture: Nullable<BaseTexture> = null;\r\n private _partIndices: Nullable<Uint8Array> = null;\r\n\r\n /** Gets the part indices texture used for compound rendering */\r\n public get partIndicesTexture() {\r\n return this._partIndicesTexture;\r\n }\r\n\r\n /**\r\n * Creates a new GaussianSplattingMesh\r\n * @param name the name of the mesh\r\n * @param url optional URL to load a Gaussian Splatting file from\r\n * @param scene the hosting scene\r\n * @param keepInRam whether to keep the raw splat data in RAM after uploading to GPU\r\n * @param needsRotationScaleTextures generate rotation and scale matrix textures required for voxel-based IBL shadows\r\n */\r\n constructor(name: string, url: Nullable<string> = null, scene: Nullable<Scene> = null, keepInRam: boolean = false, needsRotationScaleTextures: boolean = false) {\r\n super(name, url, scene, keepInRam);\r\n // Ensure _splatsData is retained once compound mode is entered — addPart/addParts need\r\n // the source data for full-texture rebuilds. Set after super() so it is visible to\r\n // _updateData when the async load completes.\r\n this._alwaysRetainSplatsData = true;\r\n this._needsRotationScaleTextures = needsRotationScaleTextures;\r\n }\r\n\r\n /**\r\n * Returns the class name\r\n * @returns \"GaussianSplattingMesh\"\r\n */\r\n public override getClassName(): string {\r\n return \"GaussianSplattingMesh\";\r\n }\r\n\r\n /**\r\n * Is this node ready to be used/rendered.\r\n * Force-syncs every part proxy's world matrix into `_partMatrices` BEFORE delegating to\r\n * the base readiness check. This guarantees that any pending proxy transform changes\r\n * (for example a user-set `proxy.position`) are reflected in the next sort post, so the\r\n * base `isReady` will only return true once `sortAppliedId === sortRequestId` for that\r\n * up-to-date state. Without this, the proxy's `onAfterWorldMatrixUpdateObservable` would\r\n * fire during the first render and queue a fresh sort AFTER readiness was reported,\r\n * leaving the rendered frame with stale splat order on `renderCount=1` runs.\r\n * @param completeCheck defines if a complete check (including materials and lights) has to be done (false by default)\r\n * @returns true when ready\r\n */\r\n public override isReady(completeCheck = false): boolean {\r\n for (const proxy of this._partProxies) {\r\n if (proxy) {\r\n proxy.computeWorldMatrix(true);\r\n }\r\n }\r\n return super.isReady(completeCheck);\r\n }\r\n\r\n /**\r\n * Recomputes compound local-space bounds from part 0's stored AABB (if unproxied) plus all\r\n * proxy world AABBs inverse-transformed to compound-local space. All 8 corners of each proxy\r\n * AABB are transformed so the result is correct under non-identity compound rotation/scale.\r\n */\r\n private _updateBoundingInfoFromProxies(): void {\r\n const compoundWorld = this.getWorldMatrix();\r\n const invCompoundWorld = Matrix.Invert(compoundWorld);\r\n\r\n const localMin = this._part0LocalMin ? this._part0LocalMin.clone() : new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n const localMax = this._part0LocalMax ? this._part0LocalMax.clone() : new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\r\n\r\n const corner = new Vector3();\r\n for (const proxy of this._partProxies) {\r\n // Skip removed parts: a tombstoned proxy is kept (for compaction) but renders nothing, so it must not\r\n // inflate the compound's bounds (and thus its frustum culling) until its rows are actually reclaimed.\r\n if (!proxy || this._tombstonedPartIndices.has(proxy.partIndex)) {\r\n continue;\r\n }\r\n // Proxies have no geometry — getHierarchyBoundingVectors returns sentinels. Use boundingBox directly.\r\n proxy.computeWorldMatrix(false);\r\n const bb = proxy.getBoundingInfo().boundingBox;\r\n const wMin = bb.minimumWorld;\r\n const wMax = bb.maximumWorld;\r\n for (let b = 0; b < 8; b++) {\r\n corner.set(b & 1 ? wMax.x : wMin.x, b & 2 ? wMax.y : wMin.y, b & 4 ? wMax.z : wMin.z);\r\n Vector3.TransformCoordinatesToRef(corner, invCompoundWorld, corner);\r\n localMin.minimizeInPlace(corner);\r\n localMax.maximizeInPlace(corner);\r\n }\r\n }\r\n\r\n if (localMin.x <= localMax.x) {\r\n // Direct access avoids getBoundingInfo() → _updateBoundingInfo() recursion.\r\n if (this._boundingInfo) {\r\n this._boundingInfo.reConstruct(localMin, localMax, compoundWorld);\r\n } else {\r\n this._boundingInfo = new BoundingInfo(localMin, localMax, compoundWorld);\r\n }\r\n this._cachedBoundingMin = localMin.clone();\r\n this._cachedBoundingMax = localMax.clone();\r\n }\r\n }\r\n\r\n /**\r\n * Override for compound meshes: recomputes bounds from proxy world extents instead of\r\n * local bounds × world matrix, which is wrong for proxied parts with independent transforms.\r\n * @returns this mesh\r\n */\r\n public override _updateBoundingInfo(): AbstractMesh {\r\n if (this.isCompound) {\r\n this._updateBoundingInfoFromProxies();\r\n this._updateSubMeshesBoundingInfo(this.worldMatrixFromCache);\r\n return this;\r\n }\r\n return super._updateBoundingInfo();\r\n }\r\n\r\n /**\r\n * Replaces the base hierarchy bounds computation for compound meshes: computes world bounds\r\n * from scratch by iterating part 0's local AABB and all proxy meshes, rather than delegating\r\n * to the base _children traversal which never reaches proxies (they are not parented to the\r\n * compound). Visibility per-part is respected; invisible parts are excluded.\r\n * @param includeDescendants when true, includes descendants (default: true)\r\n * @param predicate optional filter predicate\r\n * @returns world-space min/max of the hierarchy bounding box\r\n */\r\n public override getHierarchyBoundingVectors(\r\n includeDescendants: boolean = true,\r\n predicate: Nullable<(abstractMesh: AbstractMesh) => boolean> = null\r\n ): { min: Vector3; max: Vector3 } {\r\n if (!this.isCompound) {\r\n return super.getHierarchyBoundingVectors(includeDescendants, predicate);\r\n }\r\n // For compound meshes, compute visible-only world bounds from scratch so that\r\n // invisible parts don't inflate the result (e.g. for voxelization scene bounds).\r\n const min = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n const max = new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\r\n // Unproxied part 0: the compound mesh owns this geometry directly (no proxy node).\r\n // Transform its local AABB to world space if visible.\r\n if (this._part0LocalMin && (this._partVisibility[0] ?? 1.0) > 0) {\r\n const wm = this.getWorldMatrix();\r\n const lMin = this._part0LocalMin;\r\n const lMax = this._part0LocalMax!;\r\n const corner = new Vector3();\r\n for (let b = 0; b < 8; b++) {\r\n corner.set(b & 1 ? lMax.x : lMin.x, b & 2 ? lMax.y : lMin.y, b & 4 ? lMax.z : lMin.z);\r\n Vector3.TransformCoordinatesToRef(corner, wm, corner);\r\n min.minimizeInPlace(corner);\r\n max.maximizeInPlace(corner);\r\n }\r\n }\r\n for (let i = 0; i < this._partProxies.length; i++) {\r\n const proxy = this._partProxies[i];\r\n if (!proxy || (this._partVisibility[i] ?? 1.0) === 0) {\r\n continue;\r\n }\r\n proxy.computeWorldMatrix(false);\r\n const bb = proxy.getBoundingInfo().boundingBox;\r\n min.minimizeInPlace(bb.minimumWorld);\r\n max.maximizeInPlace(bb.maximumWorld);\r\n }\r\n return { min, max };\r\n }\r\n\r\n /**\r\n * Disposes proxy meshes and clears part data in addition to the base class GPU resources.\r\n * @param doNotRecurse Set to true to not recurse into each children\r\n */\r\n public override dispose(doNotRecurse?: boolean): void {\r\n for (const proxy of this._partProxies) {\r\n proxy.dispose();\r\n }\r\n this._partIndicesTexture?.dispose();\r\n this._partProxies = [];\r\n this._partMatrices = [];\r\n this._partVisibility = [];\r\n this._partIndicesTexture = null;\r\n this._part0LocalMin = null;\r\n this._part0LocalMax = null;\r\n super.dispose(doNotRecurse);\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Worker and material hooks\r\n // ---------------------------------------------------------------------------\r\n\r\n /**\r\n * Posts the initial per-part data to the sort worker after it has been created.\r\n * Sends the current part matrices and group index array so the worker can correctly\r\n * weight depth values per part.\r\n * @param worker the newly created sort worker\r\n */\r\n protected override _onWorkerCreated(worker: Worker): void {\r\n worker.postMessage({ command: GaussianSplattingSortWorkerCommand.PART_MATRICES, partMatrices: this._partMatrices.map((matrix) => new Float32Array(matrix.m)) });\r\n worker.postMessage({ command: GaussianSplattingSortWorkerCommand.PART_INDICES, partIndices: this._partIndices ? new Uint8Array(this._partIndices) : null });\r\n }\r\n\r\n /**\r\n * Stores the raw part index array, padded to texture length, so the worker and GPU texture\r\n * creation step have access to it.\r\n * @param partIndices - the raw part indices array received during a data load\r\n * @param textureLength - the padded texture length to allocate into\r\n */\r\n protected override _onIndexDataReceived(partIndices: Uint8Array, textureLength: number): void {\r\n this._partIndices = new Uint8Array(textureLength);\r\n this._partIndices.set(partIndices);\r\n }\r\n\r\n /**\r\n * Returns `true` when at least one part has been added to this compound mesh.\r\n * Returns `false` before any parts are added, so the mesh renders in normal\r\n * (non-compound) mode until the first addPart/addParts call. This matches the\r\n * old base-class behavior of `this._partMatrices.length > 0` and avoids\r\n * binding unset partWorld uniforms (which would cause division-by-zero in the\r\n * Gaussian projection Jacobian and produce huge distorted splats).\r\n * @internal\r\n */\r\n public override get isCompound(): boolean {\r\n return this._partMatrices.length > 0;\r\n }\r\n\r\n /**\r\n * During a removePart rebuild, keep the existing sort worker alive rather than\r\n * tearing it down and spinning up a new one. This avoids startup latency and the\r\n * transient state window where a stale sort could fire against an incomplete\r\n * partMatrices array.\r\n * Outside of a rebuild the base-class behaviour is used unchanged.\r\n */\r\n protected override _instantiateWorker(): void {\r\n if (this._rebuilding && this._worker) {\r\n // Worker already exists and is kept alive; just resize the splat-index buffer.\r\n this._updateSplatIndexBuffer(this._vertexCount);\r\n return;\r\n }\r\n super._instantiateWorker();\r\n }\r\n\r\n /**\r\n * Ensures the part-index GPU texture exists at the start of an incremental update.\r\n * Called before the sub-texture upload so the correct texture is available for the first batch.\r\n * @param textureSize - current texture dimensions\r\n */\r\n protected override _onIncrementalUpdateStart(textureSize: Vector2): void {\r\n this._ensurePartIndicesTexture(textureSize, this._partIndices ?? undefined);\r\n }\r\n\r\n /**\r\n * Posts positions (via super) and then additionally posts the current part-index array\r\n * to the sort worker so it can associate each splat with its part.\r\n */\r\n protected override _notifyWorkerNewData(): void {\r\n super._notifyWorkerNewData();\r\n if (this._worker) {\r\n this._worker.postMessage({ command: GaussianSplattingSortWorkerCommand.PART_INDICES, partIndices: this._partIndices ?? null });\r\n }\r\n }\r\n\r\n /**\r\n * Binds all compound-specific shader uniforms: the group index texture, per-part world\r\n * matrices, and per-part visibility values.\r\n * @param effect the shader effect that is being bound\r\n * @internal\r\n */\r\n public override bindExtraEffectUniforms(effect: Effect): void {\r\n if (!this._partIndicesTexture) {\r\n return;\r\n }\r\n effect.setTexture(\"partIndicesTexture\", this._partIndicesTexture);\r\n const partWorldData = new Float32Array(this.partCount * 16);\r\n for (let i = 0; i < this.partCount; i++) {\r\n this._partMatrices[i].toArray(partWorldData, i * 16);\r\n }\r\n effect.setMatrices(\"partWorld\", partWorldData);\r\n const partVisibilityData: number[] = [];\r\n for (let i = 0; i < this.partCount; i++) {\r\n partVisibilityData.push(this._partVisibility[i] ?? 1.0);\r\n }\r\n effect.setArray(\"partVisibility\", partVisibilityData);\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Part matrix / visibility management\r\n // ---------------------------------------------------------------------------\r\n\r\n /**\r\n * Gets the number of parts in the compound.\r\n */\r\n public get partCount(): number {\r\n return this._partMatrices.length;\r\n }\r\n\r\n /**\r\n * Gets the part visibility array.\r\n */\r\n public get partVisibility(): number[] {\r\n return this._partVisibility;\r\n }\r\n\r\n /**\r\n * Sets the world matrix for a specific part of the compound.\r\n * This will trigger a re-sort of the mesh.\r\n * The `_partMatrices` array is automatically extended when `partIndex >= partCount`.\r\n * @param partIndex index of the part\r\n * @param worldMatrix the world matrix to set\r\n */\r\n public setWorldMatrixForPart(partIndex: number, worldMatrix: Matrix): void {\r\n if (this._partMatrices.length <= partIndex) {\r\n this.computeWorldMatrix(true);\r\n const defaultMatrix = this.getWorldMatrix();\r\n while (this._partMatrices.length <= partIndex) {\r\n this._partMatrices.push(defaultMatrix.clone());\r\n this._partVisibility.push(1.0);\r\n }\r\n }\r\n // Skip the post / sort if the matrix is unchanged. Babylon recomputes the proxy mesh's world matrix every frame\r\n // and fires onAfterWorldMatrixUpdateObservable, so without this guard a stable scene would queue a forced sort\r\n // every frame and `isReady()` would never settle (sortRequestId would keep advancing past sortAppliedId).\r\n if (this._partMatrices[partIndex].equals(worldMatrix)) {\r\n return;\r\n }\r\n this._partMatrices[partIndex].copyFrom(worldMatrix);\r\n // During a batch rebuild suppress intermediate posts — the final correct set is posted\r\n // once the full rebuild completes (at the end of removePart).\r\n if (!this._rebuilding) {\r\n if (this._worker) {\r\n this._worker.postMessage({\r\n command: GaussianSplattingSortWorkerCommand.PART_MATRICES,\r\n partMatrices: this._partMatrices.map((matrix) => new Float32Array(matrix.m)),\r\n });\r\n }\r\n this._postToWorker(true);\r\n }\r\n }\r\n\r\n /**\r\n * Gets the world matrix for a specific part of the compound.\r\n * @param partIndex index of the part, that must be between 0 and partCount - 1\r\n * @returns the world matrix for the part, or the current world matrix of the mesh if the part is not found\r\n */\r\n public getWorldMatrixForPart(partIndex: number): Matrix {\r\n return this._partMatrices[partIndex] ?? this.getWorldMatrix();\r\n }\r\n\r\n /**\r\n * Gets the visibility for a specific part of the compound.\r\n * @param partIndex index of the part, that must be between 0 and partCount - 1\r\n * @returns the visibility value (0.0 to 1.0) for the part\r\n */\r\n public getPartVisibility(partIndex: number): number {\r\n return this._partVisibility[partIndex] ?? 1.0;\r\n }\r\n\r\n /**\r\n * Sets the visibility for a specific part of the compound.\r\n * @param partIndex index of the part, that must be between 0 and partCount - 1\r\n * @param value the visibility value (0.0 to 1.0) to set\r\n */\r\n public setPartVisibility(partIndex: number, value: number): void {\r\n this._partVisibility[partIndex] = Math.max(0.0, Math.min(1.0, value));\r\n }\r\n\r\n /**\r\n * Restricts which source splats of a single part are sorted and rendered, in GLOBAL source-splat\r\n * coordinates (offsets into the merged atlas). Static parts render fully by default; a streaming\r\n * part uses this to render only its currently-active LOD splats. The compound recomputes the union\r\n * of every part's active ranges and drives the single shared depth sort / draw with it, so all\r\n * parts still sort together in one pass.\r\n *\r\n * Passing `null` clears the override for that part (it reverts to rendering its full range). When no\r\n * part has an override, the compound clears the range filter entirely (renders every splat), which\r\n * preserves the non-streaming fast path.\r\n * @param partIndex index of the part to constrain\r\n * @param ranges active global source-splat ranges for the part, or `null` to render the whole part\r\n */\r\n public setPartSplatRanges(partIndex: number, ranges: Nullable<readonly IGaussianSplattingSplatRange[]>): void {\r\n if (partIndex < 0) {\r\n return;\r\n }\r\n this._partSplatRanges[partIndex] = ranges ? ranges.map((r) => ({ offset: r.offset, count: r.count })) : null;\r\n this._refreshPartRangeUnion();\r\n }\r\n\r\n /**\r\n * Recomputes the global active-range union across all parts and pushes it to the shared sort/draw\r\n * via the base {@link setSplatIndexRanges}. When no part carries an override the filter is cleared\r\n * (render everything). A part without an override contributes its full `[offset, count)` derived\r\n * from its proxy; a part with an override contributes exactly those ranges.\r\n */\r\n private _refreshPartRangeUnion(): void {\r\n let hasOverride = false;\r\n for (let i = 0; i < this._partSplatRanges.length; i++) {\r\n if (this._partSplatRanges[i]) {\r\n hasOverride = true;\r\n break;\r\n }\r\n }\r\n if (!hasOverride) {\r\n // No part constrains its splats: render the whole atlas (base fast path).\r\n this.setSplatIndexRanges(null);\r\n return;\r\n }\r\n\r\n const collected: IGaussianSplattingSplatRange[] = [];\r\n const partCount = this.partCount;\r\n for (let partIndex = 0; partIndex < partCount; partIndex++) {\r\n const override = this._partSplatRanges[partIndex];\r\n if (override) {\r\n for (const range of override) {\r\n if (range.count > 0) {\r\n collected.push({ offset: range.offset, count: range.count });\r\n }\r\n }\r\n continue;\r\n }\r\n // No override: render the part's full extent, derived from its proxy.\r\n const proxy = this._partProxies[partIndex];\r\n if (proxy && proxy._vertexCount > 0) {\r\n collected.push({ offset: proxy._splatsDataOffset, count: proxy._vertexCount });\r\n }\r\n }\r\n\r\n this.setSplatIndexRanges(GaussianSplattingMesh._CoalesceSplatRanges(collected));\r\n }\r\n\r\n /**\r\n * Sorts and merges adjacent/overlapping source-splat ranges so the interval list handed to the sort\r\n * worker stays compact (parts occupy disjoint regions, so this mainly coalesces contiguous parts).\r\n * @param ranges raw ranges\r\n * @returns coalesced ranges sorted by offset\r\n */\r\n private static _CoalesceSplatRanges(ranges: IGaussianSplattingSplatRange[]): IGaussianSplattingSplatRange[] {\r\n if (ranges.length <= 1) {\r\n return ranges;\r\n }\r\n const sorted = ranges.slice().sort((a, b) => a.offset - b.offset);\r\n const merged: IGaussianSplattingSplatRange[] = [{ offset: sorted[0].offset, count: sorted[0].count }];\r\n for (let i = 1; i < sorted.length; i++) {\r\n const last = merged[merged.length - 1];\r\n const range = sorted[i];\r\n const lastEnd = last.offset + last.count;\r\n if (range.offset <= lastEnd) {\r\n const end = Math.max(lastEnd, range.offset + range.count);\r\n last.count = end - last.offset;\r\n } else {\r\n merged.push({ offset: range.offset, count: range.count });\r\n }\r\n }\r\n return merged;\r\n }\r\n\r\n protected override _copyTextures(source: GaussianSplattingMeshBase): void {\r\n super._copyTextures(source);\r\n this._partIndicesTexture = (source as GaussianSplattingMesh)._partIndicesTexture?.clone()!;\r\n }\r\n\r\n protected override _onUpdateTextures(textureSize: Vector2) {\r\n const createTextureFromDataU8 = (data: Uint8Array, width: number, height: number, format: number) => {\r\n return new RawTexture(data, width, height, format, this._scene, false, false, Constants.TEXTURE_BILINEAR_SAMPLINGMODE, Constants.TEXTURETYPE_UNSIGNED_BYTE);\r\n };\r\n\r\n // Keep the part indices texture in sync with _partIndices whenever textures are rebuilt.\r\n // The old \"only create if absent\" logic left the texture stale after a second addPart/addParts\r\n // call that doesn't change the texture dimensions: all new splats kept reading partIndex=0\r\n // (the first part), causing wrong positions, broken GPU picking, and shared movement.\r\n if (this._partIndices) {\r\n const buffer = new Uint8Array(this._partIndices);\r\n if (!this._partIndicesTexture) {\r\n this._partIndicesTexture = createTextureFromDataU8(buffer, textureSize.x, textureSize.y, Constants.TEXTUREFORMAT_RED);\r\n this._partIndicesTexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n this._partIndicesTexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n } else {\r\n const existingSize = this._partIndicesTexture.getSize();\r\n if (existingSize.width !== textureSize.x || existingSize.height !== textureSize.y) {\r\n // Dimensions changed — dispose and recreate at the new size.\r\n this._partIndicesTexture.dispose();\r\n this._partIndicesTexture = createTextureFromDataU8(buffer, textureSize.x, textureSize.y, Constants.TEXTUREFORMAT_RED);\r\n this._partIndicesTexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n this._partIndicesTexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n } else {\r\n // Same size — update data in-place (e.g. second addParts fitting in existing dims).\r\n this._updateTextureFromData(this._partIndicesTexture, buffer, textureSize.x, 0, textureSize.y);\r\n }\r\n }\r\n }\r\n }\r\n\r\n protected override _updateSubTextures(\r\n splatPositions: Float32Array,\r\n covA: Uint16Array,\r\n covB: Uint16Array,\r\n colorArray: Uint8Array,\r\n lineStart: number,\r\n lineCount: number,\r\n sh?: Uint8Array[],\r\n partIndices?: Uint8Array\r\n ): void {\r\n super._updateSubTextures(splatPositions, covA, covB, colorArray, lineStart, lineCount, sh);\r\n if (partIndices && this._partIndicesTexture) {\r\n const textureSize = this._getTextureSize(this._vertexCount);\r\n const texelStart = lineStart * textureSize.x;\r\n const texelCount = lineCount * textureSize.x;\r\n const partIndicesView = new Uint8Array(partIndices.buffer, texelStart, texelCount);\r\n this._updateTextureFromData(this._partIndicesTexture, partIndicesView, textureSize.x, lineStart, lineCount);\r\n\r\n if (this._worker) {\r\n this._worker.postMessage({ command: GaussianSplattingSortWorkerCommand.PART_INDICES, partIndices: partIndices });\r\n }\r\n }\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Private helpers\r\n // ---------------------------------------------------------------------------\r\n\r\n /**\r\n * Creates the part indices GPU texture the first time an incremental addPart introduces\r\n * compound data. Has no effect if the texture already exists or no partIndices are provided.\r\n * @param textureSize - Current texture dimensions\r\n * @param partIndices - Part index data; if undefined the method is a no-op\r\n */\r\n protected _ensurePartIndicesTexture(textureSize: Vector2, partIndices: Uint8Array | undefined): void {\r\n if (!partIndices || this._partIndicesTexture) {\r\n return;\r\n }\r\n const buffer = new Uint8Array(this._partIndices!);\r\n this._partIndicesTexture = new RawTexture(\r\n buffer,\r\n textureSize.x,\r\n textureSize.y,\r\n Constants.TEXTUREFORMAT_RED,\r\n this._scene,\r\n false,\r\n false,\r\n Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\r\n Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n );\r\n this._partIndicesTexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n this._partIndicesTexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n if (this._worker) {\r\n this._worker.postMessage({ command: GaussianSplattingSortWorkerCommand.PART_INDICES, partIndices: partIndices ?? null });\r\n }\r\n }\r\n\r\n private _appendPartSourceToArrays(\r\n source: IGaussianSplattingPartSource,\r\n dstOffset: number,\r\n covA: Uint16Array,\r\n covB: Uint16Array,\r\n colorArray: Uint8Array,\r\n sh: Uint8Array[] | undefined,\r\n minimum: Vector3,\r\n maximum: Vector3\r\n ): void {\r\n this._appendSourceToArrays(source as unknown as GaussianSplattingMeshBase, dstOffset, covA, covB, colorArray, sh, minimum, maximum);\r\n }\r\n\r\n private _createRetainedPartSource(proxy: GaussianSplattingPartProxyMesh): Nullable<IGaussianSplattingPartSource> {\r\n if (!this._splatsData || (this._shDegree > 0 && !this._shData)) {\r\n return null;\r\n }\r\n\r\n const splatByteOffset = proxy._splatsDataOffset * _GaussianSplattingBytesPerSplat;\r\n const splatByteLength = proxy._vertexCount * _GaussianSplattingBytesPerSplat;\r\n const shByteOffset = proxy._shDataOffset * _GaussianSplattingBytesPerShTexel;\r\n const shByteLength = proxy._vertexCount * _GaussianSplattingBytesPerShTexel;\r\n const splatBytes = GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData);\r\n\r\n return {\r\n name: proxy.name,\r\n _vertexCount: proxy._vertexCount,\r\n _splatsData: splatBytes.subarray(splatByteOffset, splatByteOffset + splatByteLength),\r\n _shData: this._shData?.map((texture) => texture.subarray(shByteOffset, shByteOffset + shByteLength)) ?? null,\r\n _shDegree: this._shData ? this._shDegree : 0,\r\n isCompound: false,\r\n getWorldMatrix: () => proxy.getWorldMatrix(),\r\n getBoundingInfo: () => proxy.getBoundingInfo(),\r\n dispose: () => {},\r\n };\r\n }\r\n\r\n private _retainMergedPartData(existingVertexCount: number, totalCount: number, others: IGaussianSplattingPartSource[], shDegree: number): void {\r\n if (!this._keepInRam && !this._alwaysRetainSplatsData) {\r\n this._splatsData = null;\r\n this._shData = null;\r\n return;\r\n }\r\n\r\n const mergedSplatsData = new Uint8Array(totalCount * _GaussianSplattingBytesPerSplat);\r\n let splatByteOffset = 0;\r\n\r\n if (this._splatsData && existingVertexCount > 0) {\r\n mergedSplatsData.set(\r\n GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData).subarray(0, existingVertexCount * _GaussianSplattingBytesPerSplat),\r\n splatByteOffset\r\n );\r\n splatByteOffset += existingVertexCount * _GaussianSplattingBytesPerSplat;\r\n }\r\n\r\n for (const other of others) {\r\n if (!other._splatsData) {\r\n continue;\r\n }\r\n\r\n const splatByteLength = other._vertexCount * _GaussianSplattingBytesPerSplat;\r\n mergedSplatsData.set(GaussianSplattingMeshBase._GetSplatDataBytes(other._splatsData).subarray(0, splatByteLength), splatByteOffset);\r\n splatByteOffset += splatByteLength;\r\n }\r\n\r\n this._splatsData = mergedSplatsData.buffer;\r\n\r\n if (shDegree <= 0) {\r\n this._shData = null;\r\n return;\r\n }\r\n\r\n // Each SH texture holds one texel per splat; each texel is _GaussianSplattingBytesPerShTexel\r\n // bytes with one byte per scalar, so it carries that many scalars. Degree d has\r\n // ((d+1)^2 - 1) higher-order coefficients × 3 RGB = total scalars per splat; divide by texel capacity.\r\n const shTextureCount = Math.ceil((((shDegree + 1) * (shDegree + 1) - 1) * 3) / _GaussianSplattingBytesPerShTexel);\r\n const mergedShData = AllocateShBuffers(shTextureCount, totalCount * _GaussianSplattingBytesPerShTexel);\r\n\r\n let shByteOffset = 0;\r\n if (this._shData && existingVertexCount > 0) {\r\n const existingShByteLength = existingVertexCount * _GaussianSplattingBytesPerShTexel;\r\n for (let textureIndex = 0; textureIndex < mergedShData.length; textureIndex++) {\r\n if (textureIndex < this._shData.length) {\r\n mergedShData[textureIndex].set(this._shData[textureIndex].subarray(0, existingShByteLength), shByteOffset);\r\n }\r\n }\r\n shByteOffset += existingShByteLength;\r\n }\r\n\r\n for (const other of others) {\r\n const otherShByteLength = other._vertexCount * _GaussianSplattingBytesPerShTexel;\r\n if (other._shData) {\r\n for (let textureIndex = 0; textureIndex < mergedShData.length; textureIndex++) {\r\n if (textureIndex < other._shData.length) {\r\n mergedShData[textureIndex].set(other._shData[textureIndex].subarray(0, otherShByteLength), shByteOffset);\r\n }\r\n }\r\n }\r\n shByteOffset += otherShByteLength;\r\n }\r\n\r\n this._shData = mergedShData;\r\n }\r\n\r\n /**\r\n * Core implementation for adding one or more source parts as new\r\n * parts. Writes directly into texture-sized CPU arrays, updates the retained merged source\r\n * buffers, and uploads in one pass.\r\n *\r\n * @param others - Source meshes to append (must each be non-compound and fully loaded)\r\n * @param disposeOthers - Dispose source meshes after appending\r\n * @returns Proxy meshes and their assigned part indices\r\n */\r\n protected _addPartsInternal(others: IGaussianSplattingPartSource[], disposeOthers: boolean): { proxyMeshes: GaussianSplattingPartProxyMesh[]; assignedPartIndices: number[] } {\r\n if (others.length === 0) {\r\n return { proxyMeshes: [], assignedPartIndices: [] };\r\n }\r\n\r\n // Validate\r\n for (const other of others) {\r\n // Reserved-empty placeholders (reserveStreamingPart) intentionally carry no splat data —\r\n // their atlas region is left zeroed (invisible) for a streaming engine to decode into later.\r\n if (!other._splatsData && !other._isReservedEmpty) {\r\n throw new Error(`To call addPart()/addParts(), each source mesh must be fully loaded`);\r\n }\r\n if (other.isCompound) {\r\n throw new Error(`To call addPart()/addParts(), each source mesh must not be a compound`);\r\n }\r\n }\r\n\r\n const splatCountA = this._vertexCount;\r\n const totalOtherCount = others.reduce((s, o) => s + o._vertexCount, 0);\r\n const totalCount = splatCountA + totalOtherCount;\r\n\r\n const textureSize = this._getTextureSize(totalCount);\r\n const textureLength = textureSize.x * textureSize.y;\r\n const covBSItemSize = this._useRGBACovariants ? 4 : 2;\r\n\r\n // Allocate destination arrays for the full new texture\r\n const covA = new Uint16Array(textureLength * 4);\r\n const covB = new Uint16Array(covBSItemSize * textureLength);\r\n const colorArray = new Uint8Array(textureLength * 4);\r\n\r\n // Merged SH degree. The compound carries SH if any existing or new part has it, or a hosted stream bakes it.\r\n // Parts without SH get neutral (128) fill. `_streamingShDegree` is the degree of the live SH streams (recomputed\r\n // from surviving parts, so it shrinks when one is removed); folding it in keeps `_shDegree` correct across a\r\n // rebuild (which resets it) and drops it to 0 when no SH stream survives.\r\n const streamingShDegree = this._streamingShDegree;\r\n const staticHasSH = this._shDegree > 0 || others.some((o) => o._shData !== null);\r\n const hasSH = staticHasSH || streamingShDegree > 0;\r\n const shDegreeNew = hasSH ? Math.max(this._shDegree, streamingShDegree, ...others.map((o) => o._shDegree)) : 0;\r\n let sh: Uint8Array[] | undefined = undefined;\r\n // Allocate the neutral (128 == 0 after decode) CPU SH base whenever the atlas carries SH, and upload it over\r\n // the whole atlas before any SH stream restores its region, so non-SH regions read neutral instead of raw 0\r\n // (which decodes to -1).\r\n if (hasSH && shDegreeNew > 0) {\r\n // Each SH texture holds one texel per splat; each texel is _GaussianSplattingBytesPerShTexel\r\n // bytes with one byte per scalar, so it carries that many scalars. Degree d has\r\n // ((d+1)^2 - 1) higher-order coefficients × 3 RGB = total scalars per splat; divide by texel capacity.\r\n const shTextureCount = Math.ceil((((shDegreeNew + 1) * (shDegreeNew + 1) - 1) * 3) / _GaussianSplattingBytesPerShTexel);\r\n sh = AllocateShBuffers(shTextureCount, textureLength * _GaussianSplattingBytesPerShTexel);\r\n }\r\n\r\n // --- Incremental path: can we reuse the already-committed GPU region? ---\r\n const incremental = this._canReuseCachedData(splatCountA, totalCount, sh?.length ?? 0);\r\n const firstNewLine = incremental ? Math.floor(splatCountA / textureSize.x) : 0;\r\n\r\n const minimum = incremental ? this._cachedBoundingMin!.clone() : new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n const maximum = incremental ? this._cachedBoundingMax!.clone() : new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\r\n\r\n // Preserve existing processed positions in the new array\r\n const oldPositions = this._splatPositions;\r\n this._splatPositions = new Float32Array(4 * textureLength);\r\n if (incremental && oldPositions) {\r\n this._splatPositions.set(oldPositions.subarray(0, splatCountA * 4));\r\n }\r\n\r\n // --- Build part indices ---\r\n let nextPartIndex = this.partCount;\r\n let partIndicesA = this._partIndices;\r\n if (!partIndicesA) {\r\n // First addPart on a plain mesh: assign its splats to part 0\r\n partIndicesA = new Uint8Array(splatCountA);\r\n nextPartIndex = splatCountA > 0 ? 1 : 0;\r\n }\r\n\r\n this._partIndices = new Uint8Array(textureLength);\r\n this._partIndices.set(partIndicesA.subarray(0, splatCountA));\r\n\r\n const assignedPartIndices: number[] = [];\r\n const assignedSplatsDataOffsets: number[] = [];\r\n let dstOffset = splatCountA;\r\n const maxPartCount = GetGaussianSplattingMaxPartCount(this._scene.getEngine());\r\n for (const other of others) {\r\n if (nextPartIndex >= maxPartCount) {\r\n throw new Error(`Cannot add part, as the maximum part count (${maxPartCount}) has been reached`);\r\n }\r\n const newPartIndex = nextPartIndex++;\r\n assignedPartIndices.push(newPartIndex);\r\n assignedSplatsDataOffsets.push(dstOffset);\r\n this._partIndices.fill(newPartIndex, dstOffset, dstOffset + other._vertexCount);\r\n dstOffset += other._vertexCount;\r\n }\r\n\r\n // --- Process source data ---\r\n if (!incremental) {\r\n // Full rebuild path — only reached when the GPU texture must be reallocated\r\n // (either the texture height needs to grow to fit the new total, or this is\r\n // the very first addPart onto a mesh with no GPU textures yet). In the common\r\n // case where the texture height is unchanged, `incremental` is true and this\r\n // entire block is skipped. The `splatCountA > 0` guard avoids redundant work\r\n // on the first-ever addPart when the compound mesh starts empty.\r\n if (splatCountA > 0) {\r\n if (this._partProxies.length > 0) {\r\n // Already compound: rebuild every existing part from its stored source data.\r\n //\r\n // DESIGN NOTE: The intended use of GaussianSplattingMesh / GaussianSplattingCompoundMesh\r\n // in compound mode is to start EMPTY and compose parts exclusively via addPart/addParts.\r\n // In a future major version this will be the only supported path and the \"own data\"\r\n // legacy branch below will be removed.\r\n //\r\n // Until then, two layouts are possible:\r\n // A) LEGACY — compound loaded its own splat data (via URL or updateData) before\r\n // any addPart call. _partProxies[0] is undefined; the mesh's own splat data\r\n // is treated as an implicit \"part 0\" in this._splatsData. Proxied parts occupy\r\n // indices 1+. This layout will be deprecated in the next major version.\r\n // B) PREFERRED — compound started empty; first addPart assigned partIndex=0.\r\n // _partProxies[0] is set; this._splatsData is null; all parts are proxied.\r\n let rebuildOffset = 0;\r\n\r\n // Rebuild the compound's legacy \"own\" data at part 0 (scenario A only).\r\n // Skipped in the preferred empty-composer path (scenario B).\r\n if (!this._partProxies[0] && this._splatsData) {\r\n const proxyVertexCount = this._partProxies.reduce((sum, proxy) => sum + (proxy ? proxy._vertexCount : 0), 0);\r\n const part0Count = splatCountA - proxyVertexCount;\r\n if (part0Count > 0) {\r\n const uBufA = GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData);\r\n const fBufA = GaussianSplattingMeshBase._GetSplatDataFloats(this._splatsData);\r\n for (let i = 0; i < part0Count; i++) {\r\n this._makeSplat(i, fBufA, uBufA, covA, covB, colorArray, minimum, maximum, false);\r\n }\r\n if (sh && this._shData) {\r\n for (let texIdx = 0; texIdx < sh.length; texIdx++) {\r\n if (texIdx < this._shData.length) {\r\n sh[texIdx].set(this._shData[texIdx].subarray(0, part0Count * _GaussianSplattingBytesPerShTexel), 0);\r\n }\r\n }\r\n }\r\n rebuildOffset += part0Count;\r\n }\r\n }\r\n\r\n // Rebuild all proxied parts. Loop from index 0 because in the preferred\r\n // scenario B, part 0 is itself a proxied part with no implicit \"own\" data.\r\n for (let partIndex = 0; partIndex < this._partProxies.length; partIndex++) {\r\n const proxy = this._partProxies[partIndex];\r\n if (!proxy) {\r\n continue;\r\n }\r\n // Streaming parts have no retained CPU source — their atlas rows (core + SH) are\r\n // GPU-authoritative and preserved across the rebuild by the backup/restore hooks. Leave their\r\n // rows at the fresh-array defaults (zero core, neutral SH) for the restore to overwrite; just\r\n // advance the offset. (With a static part present _splatsData is non-null and these would\r\n // otherwise reconstruct as a harmless zeros-slice; with only streaming parts it is null and\r\n // _createRetainedPartSource returns null — so this skip is required, not just an optimization.)\r\n if (this._streamingStates.some((s) => s.proxy === proxy)) {\r\n rebuildOffset += proxy._vertexCount;\r\n continue;\r\n }\r\n const source = this._createRetainedPartSource(proxy);\r\n if (!source) {\r\n throw new Error(`Cannot rebuild compound part \"${proxy.name}\": the retained compound source data is not available.`);\r\n }\r\n this._appendPartSourceToArrays(source, rebuildOffset, covA, covB, colorArray, sh, minimum, maximum);\r\n rebuildOffset += source._vertexCount;\r\n }\r\n } else {\r\n // No proxies yet: this is the very first addPart call on a mesh that loaded\r\n // its own splat data (scenario A legacy path). Re-process that own data so\r\n // it occupies the start of the new texture before the incoming part is appended.\r\n // In the preferred scenario B (empty composer) splatCountA is 0 and this\r\n // entire branch is skipped by the outer `if (splatCountA > 0)` guard.\r\n if (this._splatsData) {\r\n const uBufA = GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData);\r\n const fBufA = GaussianSplattingMeshBase._GetSplatDataFloats(this._splatsData);\r\n for (let i = 0; i < splatCountA; i++) {\r\n this._makeSplat(i, fBufA, uBufA, covA, covB, colorArray, minimum, maximum, false);\r\n }\r\n if (sh && this._shData) {\r\n for (let texIdx = 0; texIdx < sh.length; texIdx++) {\r\n if (texIdx < this._shData.length) {\r\n sh[texIdx].set(this._shData[texIdx].subarray(0, splatCountA * _GaussianSplattingBytesPerShTexel), 0);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Incremental path: rebuild the partial first row (indices firstNewTexel to splatCountA-1)\r\n // so _updateSubTextures does not upload stale zeros over those already-committed texels.\r\n // The base-class _updateData always re-processes from firstNewTexel for the same reason;\r\n // the compound path must do the same.\r\n // Boundary-row SH is restored after _retainMergedPartData (see below), where _shData is ready.\r\n if (incremental) {\r\n const firstNewTexel = firstNewLine * textureSize.x;\r\n if (firstNewTexel < splatCountA) {\r\n if (this._partProxies.length === 0) {\r\n // No proxies: the mesh loaded its own splat data and this is the first\r\n // addPart call (scenario A legacy path). Re-process the partial boundary\r\n // row so it is not clobbered by stale zeros during the sub-texture upload.\r\n if (this._splatsData) {\r\n const uBufA = GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData);\r\n const fBufA = GaussianSplattingMeshBase._GetSplatDataFloats(this._splatsData);\r\n for (let i = firstNewTexel; i < splatCountA; i++) {\r\n this._makeSplat(i, fBufA, uBufA, covA, covB, colorArray, minimum, maximum, false, i);\r\n }\r\n }\r\n } else {\r\n // Already compound: build a per-partIndex source lookup so each splat in the\r\n // partial boundary row can be re-processed from its original source buffer.\r\n //\r\n // Handles both layouts (see full-rebuild comment above):\r\n // A) LEGACY: _partProxies[0] absent → seed lookup[0] with this._splatsData\r\n // B) PREFERRED: _partProxies[0] present → all entries filled from proxies\r\n const proxyTotal = this._partProxies.reduce((s, p) => s + (p ? p._vertexCount : 0), 0);\r\n const part0Count = splatCountA - proxyTotal; // > 0 only in legacy scenario A\r\n const srcUBufs: (Uint8Array | null)[] = new Array(this._partProxies.length).fill(null);\r\n const srcFBufs: (Float32Array | null)[] = new Array(this._partProxies.length).fill(null);\r\n const partStarts: number[] = new Array(this._partProxies.length).fill(0);\r\n // Legacy scenario A: part 0 is the mesh's own loaded data.\r\n if (!this._partProxies[0] && this._splatsData && part0Count > 0) {\r\n srcUBufs[0] = GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData);\r\n srcFBufs[0] = GaussianSplattingMeshBase._GetSplatDataFloats(this._splatsData);\r\n partStarts[0] = 0;\r\n }\r\n // All proxied parts — start from pi=0 to cover preferred scenario B.\r\n let cumOffset = part0Count;\r\n for (let pi = 0; pi < this._partProxies.length; pi++) {\r\n const proxy = this._partProxies[pi];\r\n if (!proxy) {\r\n continue;\r\n }\r\n // Streaming parts are GPU-authoritative (no CPU source) — skip reconstruction (their rows are\r\n // restored via the atlas hooks). Row-aligned regions mean a streamed part's splats never fall\r\n // in the partial boundary row anyway; leave its source buffers null and just track the offset.\r\n if (this._streamingStates.some((s) => s.proxy === proxy)) {\r\n partStarts[pi] = cumOffset;\r\n cumOffset += proxy._vertexCount;\r\n continue;\r\n }\r\n const source = this._createRetainedPartSource(proxy);\r\n if (!source || !source._splatsData) {\r\n throw new Error(`Cannot rebuild compound part \"${proxy.name}\": the retained compound source data is not available.`);\r\n }\r\n srcUBufs[pi] = GaussianSplattingMeshBase._GetSplatDataBytes(source._splatsData);\r\n srcFBufs[pi] = GaussianSplattingMeshBase._GetSplatDataFloats(source._splatsData);\r\n partStarts[pi] = cumOffset;\r\n cumOffset += source._vertexCount;\r\n }\r\n for (let splatIdx = firstNewTexel; splatIdx < splatCountA; splatIdx++) {\r\n const partIdx = this._partIndices ? this._partIndices[splatIdx] : 0;\r\n const uBuf = partIdx < srcUBufs.length ? srcUBufs[partIdx] : null;\r\n const fBuf = partIdx < srcFBufs.length ? srcFBufs[partIdx] : null;\r\n if (uBuf && fBuf) {\r\n this._makeSplat(splatIdx, fBuf, uBuf, covA, covB, colorArray, minimum, maximum, false, splatIdx - (partStarts[partIdx] ?? 0));\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Append each new source\r\n dstOffset = splatCountA;\r\n for (const other of others) {\r\n this._appendPartSourceToArrays(other, dstOffset, covA, covB, colorArray, sh, minimum, maximum);\r\n dstOffset += other._vertexCount;\r\n }\r\n\r\n // Pad empty splats to texture boundary\r\n const paddedEnd = (totalCount + 15) & ~0xf;\r\n for (let i = totalCount; i < paddedEnd; i++) {\r\n this._makeEmptySplat(i, covA, covB, colorArray);\r\n }\r\n\r\n // --- Update vertex count / index buffer ---\r\n if (totalCount !== this._vertexCount) {\r\n this._updateSplatIndexBuffer(totalCount);\r\n }\r\n // Retain CPU SH only for the STATIC contribution — a stream-only SH atlas has no CPU SH to reconstruct on a\r\n // later compaction (the stream re-decodes/backup-restores its own region), so don't retain neutral buffers.\r\n this._retainMergedPartData(splatCountA, totalCount, others, staticHasSH ? shDegreeNew : 0);\r\n this._vertexCount = totalCount;\r\n this._shDegree = shDegreeNew;\r\n // Keep the max in sync so the public `shDegree` setter's clamp tracks the current data (and shrinks when a\r\n // higher-degree part is removed). The compound's SH degree is fully described by the live parts.\r\n this._maxShDegree = shDegreeNew;\r\n\r\n // Gate the sort worker for the duration of this operation. _updateTextures (below) may create the worker and fire an\r\n // immediate sort via _postToWorker. At that point partMatrices has not yet been updated for the incoming parts, so the\r\n // worker would compute depthCoeffs for fewer parts than partIndices references — crashing with\r\n // \"Cannot read properties of undefined (reading '0')\".\r\n // When called from removePart, _rebuilding is already true and _canPostToWorker is already false, so the gate is a\r\n // no-op — removePart handles the final post+sort.\r\n const needsWorkerGate = !this._rebuilding;\r\n if (needsWorkerGate) {\r\n this._canPostToWorker = false;\r\n this._rebuilding = true;\r\n }\r\n\r\n try {\r\n // --- Upload to GPU ---\r\n if (incremental) {\r\n // Create missing SH GPU textures: either the compound just gained SH for the first\r\n // time (_shTextures===null) or the degree increased (sh.length > _shTextures.length).\r\n // Use _shData when available (contains correct merged values for all rows);\r\n // fall back to sh[idx] (pre-filled with 128) when _shData is absent (keepInRam=false).\r\n // _updateSubTextures will re-upload from firstNewLine, which is redundant but harmless.\r\n if (sh && (!this._shTextures || sh.length > this._shTextures.length)) {\r\n if (!this._shTextures) {\r\n this._shTextures = [];\r\n }\r\n while (this._shTextures.length < sh.length) {\r\n const idx = this._shTextures.length;\r\n const shTexture = new RawTexture(\r\n null,\r\n textureSize.x,\r\n textureSize.y,\r\n Constants.TEXTUREFORMAT_RGBA_INTEGER,\r\n this._scene,\r\n false,\r\n false,\r\n Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n Constants.TEXTURETYPE_UNSIGNED_INTEGER\r\n );\r\n shTexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n shTexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n this._shTextures.push(shTexture);\r\n const src = this._shData && idx < this._shData.length ? this._shData[idx] : sh[idx];\r\n this._updateShTextureData(shTexture, src, textureSize.x, 0, textureSize.y);\r\n }\r\n }\r\n\r\n // Restore boundary-row SH: sh is freshly filled with 128, and _updateSubTextures\r\n // starts at firstNewLine — existing splats on that row need their values from _shData.\r\n if (sh && this._shData) {\r\n const firstNewTexel = firstNewLine * textureSize.x;\r\n if (firstNewTexel < splatCountA) {\r\n const byteStart = firstNewTexel * _GaussianSplattingBytesPerShTexel;\r\n const byteEnd = splatCountA * _GaussianSplattingBytesPerShTexel;\r\n for (let texIdx = 0; texIdx < sh.length; texIdx++) {\r\n if (texIdx < this._shData.length) {\r\n sh[texIdx].set(this._shData[texIdx].subarray(byteStart, byteEnd), byteStart);\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Update the part-indices texture (handles both create and update-in-place).\r\n // _ensurePartIndicesTexture is a no-op when the texture already exists, so on the\r\n // second+ addPart the partIndices would be stale without this call.\r\n this._onUpdateTextures(textureSize);\r\n this._updateSubTextures(this._splatPositions, covA, covB, colorArray, firstNewLine, textureSize.y - firstNewLine, sh);\r\n } else {\r\n this._updateTextures(covA, covB, colorArray, sh);\r\n }\r\n\r\n this.setEnabled(true);\r\n this._notifyWorkerNewData();\r\n\r\n // Bounding info is updated via _updateBoundingInfoFromProxies (called below, after proxy\r\n // world matrices are known), which needs part 0's local-space AABB as an input:\r\n // • For unproxied part 0 (legacy layout A: compound loaded its own splat data before\r\n // any addPart call, so no _partProxies[0]), capture the local-space AABB from the\r\n // compound mesh's existing _boundingInfo — set when the mesh loaded its own data via\r\n // URL/updateData — so _updateBoundingInfoFromProxies can include part 0's geometry.\r\n // • For proxied part 0, skip — its bounds are already on the proxy's getBoundingInfo()\r\n // and _updateBoundingInfoFromProxies picks it up there.\r\n // Guard splatCountA > 0 avoids reading a stale bounding box on a fresh empty mesh.\r\n // Guard !this._part0LocalMin ensures we only store once; subsequent addPart calls must\r\n // not overwrite it, because by then _boundingInfo reflects the full merged dataset.\r\n if (!this._partProxies[0] && splatCountA > 0 && !this._part0LocalMin) {\r\n this._part0LocalMin = this.getBoundingInfo().minimum.clone();\r\n this._part0LocalMax = this.getBoundingInfo().maximum.clone();\r\n }\r\n\r\n // --- Create proxy meshes ---\r\n const proxyMeshes: GaussianSplattingPartProxyMesh[] = [];\r\n for (let i = 0; i < others.length; i++) {\r\n const other = others[i];\r\n const newPartIndex = assignedPartIndices[i];\r\n\r\n const partWorldMatrix = other.getWorldMatrix();\r\n this.setWorldMatrixForPart(newPartIndex, partWorldMatrix);\r\n\r\n const proxyMesh = new GaussianSplattingPartProxyMesh(\r\n other.name,\r\n this.getScene(),\r\n this,\r\n newPartIndex,\r\n other.getBoundingInfo(),\r\n other._vertexCount,\r\n assignedSplatsDataOffsets[i],\r\n assignedSplatsDataOffsets[i]\r\n );\r\n\r\n if (disposeOthers) {\r\n other.dispose();\r\n }\r\n\r\n const quaternion = new Quaternion();\r\n partWorldMatrix.decompose(proxyMesh.scaling, quaternion, proxyMesh.position);\r\n proxyMesh.rotationQuaternion = quaternion;\r\n proxyMesh.computeWorldMatrix(true);\r\n\r\n this._partProxies[newPartIndex] = proxyMesh;\r\n proxyMeshes.push(proxyMesh);\r\n }\r\n\r\n // Update compound bounds now that all proxy world matrices are known.\r\n this._updateBoundingInfoFromProxies();\r\n\r\n // Restore the rebuild gate and post the now-complete partMatrices in one message, then trigger a single sort pass.\r\n // This ensures the worker sees a consistent partMatrices array that matches the partIndices for every splat.\r\n if (needsWorkerGate) {\r\n this._rebuilding = false;\r\n if (this._worker) {\r\n this._worker.postMessage({\r\n command: GaussianSplattingSortWorkerCommand.PART_MATRICES,\r\n partMatrices: this._partMatrices.map((matrix) => new Float32Array(matrix.m)),\r\n });\r\n }\r\n this._canPostToWorker = true;\r\n // A streaming compound renders the active-range UNION (a part carries an override), so a newly\r\n // added static part must be folded into that union now — otherwise it stays out of the sorted\r\n // set and isn't drawn until the stream's next LOD re-evaluation happens to refresh the union.\r\n // (No-op for non-streaming compounds: with no override the union clears to the render-all path.)\r\n if (this._hasStreamingPart) {\r\n this._refreshPartRangeUnion();\r\n }\r\n this._postToWorker(true);\r\n }\r\n\r\n this.onPartCountChangedObservable.notifyObservers(this.partCount);\r\n return { proxyMeshes, assignedPartIndices };\r\n } catch (e) {\r\n // Ensure the gates are always restored so sorting is not permanently frozen.\r\n if (needsWorkerGate) {\r\n this._rebuilding = false;\r\n this._canPostToWorker = true;\r\n }\r\n throw e;\r\n }\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Public compound API\r\n // ---------------------------------------------------------------------------\r\n\r\n /**\r\n * Add another mesh to this mesh, as a new part. This makes the current mesh a compound, if not already.\r\n * The source mesh's splat data is read directly and copied into the compound's retained source buffers.\r\n * @param other - The other mesh to add. Must be fully loaded before calling this method.\r\n * @param disposeOther - Whether to dispose the other mesh after adding it to the current mesh.\r\n * @returns a placeholder mesh that can be used to manipulate the part transform\r\n * @deprecated Use {@link GaussianSplattingCompoundMesh.addPart} instead.\r\n */\r\n public addPart(other: GaussianSplattingMesh, disposeOther: boolean = true): GaussianSplattingPartProxyMesh {\r\n // Adding parts while a streaming part exists is supported: the grow rebuild preserves streamed regions\r\n // (their GPU data is backed up/restored around the atlas recreation). Only removal is still restricted,\r\n // because it shifts existing part offsets (which streamed regions' work buffers depend on).\r\n const { proxyMeshes } = this._addPartsInternal([other], disposeOther);\r\n return proxyMeshes[0];\r\n }\r\n\r\n /**\r\n * Recomputes the shared SH-atlas state ({@link _useShMrtAtlas}, {@link _shMrtAtlasTextureCount},\r\n * {@link _streamingShDegree}) from the currently-live (non-tombstoned) streaming parts. Call before an atlas\r\n * rebuild that follows a removal so a stale SH degree/count from a removed part can't keep the SH atlas active\r\n * (and SH_DEGREE high) with nothing refilling the SH texels.\r\n */\r\n private _refreshStreamingShState(): void {\r\n let count = 0;\r\n let degree = 0;\r\n let needsRot = false;\r\n for (const state of this._streamingStates) {\r\n if (this._tombstonedPartIndices.has(state.partIndex)) {\r\n continue;\r\n }\r\n if (state.shTextureCount > count) {\r\n count = state.shTextureCount;\r\n }\r\n if (state.shDegree > degree) {\r\n degree = state.shDegree;\r\n }\r\n if (state.needsRotationScale) {\r\n needsRot = true;\r\n }\r\n }\r\n this._shMrtAtlasTextureCount = count;\r\n this._useShMrtAtlas = count > 0;\r\n this._streamingShDegree = degree;\r\n // Render-backed rotation atlas is active iff a live streaming part decodes rotation/scale. (`_needsRotationScaleTextures`\r\n // is left as-is — removing a stream doesn't disable IBL for surviving static parts, which keep CPU RawTextures.)\r\n this._useRotMrtAtlas = needsRot;\r\n }\r\n\r\n /**\r\n * Tombstones a part of a streaming compound: excludes it from the render union permanently and hides its\r\n * proxy, leaving its atlas rows idle. Used instead of the compacting {@link removePart} rebuild whenever a\r\n * streaming part is reserved — a streamed region has no retained CPU source and decodes at a FIXED base\r\n * offset, so the rebuild can neither reconstruct it nor shift any part without desynchronizing the streaming\r\n * engine. Every other part keeps its exact offset (no shift), so resident streams keep decoding at their base.\r\n * The empty `[]` override survives future add-driven rebuilds, so the region stays invisible even though its\r\n * texels get rebuilt; memory is only reclaimed by disposing/recreating the whole compound.\r\n * @param index the part index to tombstone\r\n */\r\n private _tombstonePart(index: number): void {\r\n // Fire before mutation so the stream driving this part (which subscribes to this observable at reservation)\r\n // can dispose itself: stop its LOD loop, free its work buffer, and drop its atlas-rebuild hooks.\r\n this.onPartRemovedObservable.notifyObservers(index);\r\n const proxy = this._partProxies[index];\r\n if (proxy) {\r\n proxy.setEnabled(false);\r\n proxy.visibility = 0;\r\n }\r\n this._partVisibility[index] = 0;\r\n // Invalidate this region's streaming handle so a caller that retained it can't later mutate a surviving part\r\n // that inherits this index/base after compaction.\r\n const removedState = this._streamingStates.find((s) => s.partIndex === index);\r\n if (removedState) {\r\n removedState.removed = true;\r\n }\r\n // Empty (non-null) override = \"this part contributes no splats\"; keeps the union filter engaged so the\r\n // idle region is never rendered, even after another part's addition rebuilds the atlas.\r\n this._partSplatRanges[index] = [];\r\n // Record the tombstone so compactAtlas() can drop this part's atlas rows and reclaim the memory.\r\n this._tombstonedPartIndices.add(index);\r\n this._refreshPartRangeUnion();\r\n this._updateBoundingInfoFromProxies();\r\n }\r\n\r\n /**\r\n * Tears the compound down to an empty state so a subsequent {@link _addPartsInternal} recreates fresh GPU\r\n * textures. Shared by {@link removePart} (compacting rebuild) and {@link compactAtlas}. Does NOT dispose the\r\n * part proxies — callers dispose only the proxies being removed and reuse the survivors' proxy objects.\r\n * @internal\r\n */\r\n protected _resetForRebuild(): void {\r\n // Terminate the sort worker before zeroing _vertexCount. The worker's onmessage handler compares\r\n // depthMix.length against (_vertexCount + 15) & ~0xf; with _vertexCount = 0 that becomes 16, forcing a\r\n // re-sort loop on stale data and resetting _canPostToWorker to true, defeating the rebuild gate. The\r\n // worker is re-instantiated after the rebuild via the first _postToWorker call.\r\n if (this._worker) {\r\n this._worker.terminate();\r\n this._worker = null;\r\n }\r\n // Dispose GPU textures and null them so _updateTextures sees firstTime=true and allocates fresh ones.\r\n // For a streaming atlas the four data textures are attachments of _mrtAtlas — dispose the MRT, not each.\r\n if (this._mrtAtlas) {\r\n this._mrtAtlas.dispose();\r\n this._mrtAtlas = null;\r\n this._covariancesATexture = this._covariancesBTexture = this._centersTexture = this._colorsTexture = null;\r\n } else {\r\n this._covariancesATexture?.dispose();\r\n this._covariancesBTexture?.dispose();\r\n this._centersTexture?.dispose();\r\n this._colorsTexture?.dispose();\r\n this._covariancesATexture = null;\r\n this._covariancesBTexture = null;\r\n this._centersTexture = null;\r\n this._colorsTexture = null;\r\n }\r\n if (this._rotMrtAtlas) {\r\n // The three rotation textures are attachments of this MRT — dispose the MRT, not each attachment.\r\n this._rotMrtAtlas.dispose();\r\n this._rotMrtAtlas = null;\r\n } else {\r\n this._rotationsATexture?.dispose();\r\n this._rotationsBTexture?.dispose();\r\n this._rotationScaleTexture?.dispose();\r\n }\r\n this._rotationsATexture = null;\r\n this._rotationsBTexture = null;\r\n this._rotationScaleTexture = null;\r\n if (this._shMrtAtlas) {\r\n // SH attachments belong to these MRTs — dispose the MRTs, not each attachment (mirrors _mrtAtlas).\r\n for (const mrt of this._shMrtAtlas) {\r\n mrt.dispose();\r\n }\r\n this._shMrtAtlas = null;\r\n this._shTextures = null;\r\n } else if (this._shTextures) {\r\n for (const t of this._shTextures) {\r\n t.dispose();\r\n }\r\n this._shTextures = null;\r\n }\r\n if (this._partIndicesTexture) {\r\n this._partIndicesTexture.dispose();\r\n this._partIndicesTexture = null;\r\n }\r\n this._vertexCount = 0;\r\n this._splatPositions = null;\r\n this._partIndices = null;\r\n this._partMatrices = [];\r\n this._partVisibility = [];\r\n this._cachedBoundingMin = null;\r\n this._cachedBoundingMax = null;\r\n this._part0LocalMin = null;\r\n this._part0LocalMax = null;\r\n this._splatsData = null;\r\n this._shData = null;\r\n this._shDegree = 0;\r\n this._partProxies = [];\r\n // Drop per-part range overrides too: a rebuild reassigns part indices from 0, so a leftover entry at a\r\n // now-unused high index would otherwise be inherited by a later-added part (rendering it wrong/nothing).\r\n // The rebuild re-sets the surviving parts' entries.\r\n this._partSplatRanges = [];\r\n }\r\n\r\n /**\r\n * Reclaims the atlas rows of parts removed (tombstoned) while a streaming part was resident. `removePart`\r\n * on a streaming compound only tombstones — it excludes the part from the render union and hides its proxy,\r\n * but leaves its rows allocated, since compacting them would relocate the still-resident streaming regions.\r\n * This method performs that compaction: it rebuilds the shared atlas from the LIVE parts at new, contiguous\r\n * (row-aligned for streaming) offsets, physically relocating each surviving streaming region's GPU texels,\r\n * CPU sort positions, and decode/render base offset, and drops the tombstoned rows — shrinking the atlas.\r\n *\r\n * Call it after removing one or more models to actually free the GPU/CPU memory (e.g. on idle, or once a\r\n * batch of removals settles). No-op when nothing is tombstoned. Safe while streams are actively decoding:\r\n * each surviving region is backed up before the old atlas is disposed and restored at its new base after.\r\n */\r\n public compactAtlas(): void {\r\n if (this._tombstonedPartIndices.size === 0) {\r\n return;\r\n }\r\n\r\n const atlasWidth = this._getTextureSize(1).x;\r\n\r\n // Build the compacted layout of the LIVE parts (skip tombstoned ones), in current part-index order.\r\n // Static parts pack tightly from their retained CPU source; streaming regions are re-reserved as\r\n // row-aligned empty sources (front-padded to the next row) and relocated via the atlas-rebuild hooks.\r\n type LivePartSpec = {\r\n oldProxy: GaussianSplattingPartProxyMesh;\r\n source: IGaussianSplattingPartSource;\r\n worldMatrix: Matrix;\r\n visibility: number;\r\n state: Nullable<IStreamingPartState>;\r\n newBase: number; // streaming only: the region's usable base after compaction\r\n frontPad: number; // streaming only\r\n };\r\n const specs: LivePartSpec[] = [];\r\n let cumOffset = 0;\r\n for (let i = 0; i < this._partProxies.length; i++) {\r\n const proxy = this._partProxies[i];\r\n if (!proxy || this._tombstonedPartIndices.has(i)) {\r\n continue;\r\n }\r\n const state = this._streamingStates.find((s) => s.proxy === proxy) ?? null;\r\n const worldMatrix = proxy.getWorldMatrix().clone();\r\n const visibility = this._partVisibility[i] ?? 1.0;\r\n if (state) {\r\n // Streaming: reserve an empty, row-aligned region (front pad + capacity) at the compacted offset.\r\n const alignedBase = Math.ceil(cumOffset / atlasWidth) * atlasWidth;\r\n const frontPad = alignedBase - cumOffset;\r\n const regionSplats = frontPad + state.capacity;\r\n const source: IGaussianSplattingPartSource = {\r\n name: proxy.name,\r\n _vertexCount: regionSplats,\r\n _splatsData: null,\r\n _shData: null,\r\n _shDegree: 0,\r\n isCompound: false,\r\n getWorldMatrix: () => worldMatrix,\r\n getBoundingInfo: () => new BoundingInfo(Vector3.ZeroReadOnly, Vector3.ZeroReadOnly),\r\n dispose: () => {},\r\n _isReservedEmpty: true,\r\n };\r\n specs.push({ oldProxy: proxy, source, worldMatrix, visibility, state, newBase: alignedBase, frontPad });\r\n cumOffset += regionSplats;\r\n } else {\r\n const source = this._createRetainedPartSource(proxy);\r\n if (!source || !source._splatsData) {\r\n throw new Error(`compactAtlas: the retained source data for static part \"${proxy.name}\" is not available.`);\r\n }\r\n specs.push({ oldProxy: proxy, source, worldMatrix, visibility, state: null, newBase: 0, frontPad: 0 });\r\n cumOffset += source._vertexCount;\r\n }\r\n }\r\n\r\n // Back up every surviving streaming region's GPU texels + CPU positions before the atlas is torn down.\r\n if (this._mrtAtlas) {\r\n this._onBeforeAtlasRebuildObservable.notifyObservers(this._mrtAtlas);\r\n }\r\n\r\n // Dispose the tombstoned parts' proxies (their streams were already disposed when tombstoned).\r\n for (const i of this._tombstonedPartIndices) {\r\n this._partProxies[i]?.dispose();\r\n }\r\n\r\n // Tear the compound down to empty so _addPartsInternal recreates fresh (smaller) GPU textures.\r\n this._resetForRebuild();\r\n\r\n if (specs.length === 0) {\r\n // Everything was tombstoned — nothing to rebuild. Clear the streaming/atlas capability flags so that\r\n // reusing this now-empty compound for plain (non-streaming) content doesn't recreate render-target\r\n // atlases or restore a stale SH/rotation configuration. _refreshStreamingShState turns off SH/rotation\r\n // from the (empty) live states; the render-backed core atlas + RGBA covariants reset here.\r\n this._streamingStates.length = 0;\r\n this._hasStreamingPart = false;\r\n this._tombstonedPartIndices.clear();\r\n this._refreshStreamingShState();\r\n this._useMrtAtlas = false;\r\n // Restore the engine-derived default rather than a hardcoded `false`: WebGL 1 (no WebGPU) cannot render\r\n // the RG half-float covariance-B path and requires RGBA, so a reused compound must keep that default.\r\n this._useRGBACovariants = !this.getEngine().isWebGPU && this.getEngine().version === 1.0;\r\n this.setEnabled(false);\r\n this.onPartCountChangedObservable.notifyObservers(0);\r\n return;\r\n }\r\n\r\n // Recompute the SH-atlas state from the SURVIVING streaming parts BEFORE the rebuild: if the removed part\r\n // was the only SH stream, this turns the SH atlas off (degree 0) so the rebuild neither recreates a stale\r\n // SH atlas nor keeps SH_DEGREE high over now-unfilled (raw-0) texels; a lower surviving degree shrinks too.\r\n this._refreshStreamingShState();\r\n\r\n this._rebuilding = true;\r\n this._canPostToWorker = false;\r\n try {\r\n const { proxyMeshes: newProxies } = this._addPartsInternal(\r\n specs.map((s) => s.source),\r\n false\r\n );\r\n\r\n // Re-map the surviving proxies onto their new indices/offsets and relocate streaming state.\r\n for (let i = 0; i < specs.length; i++) {\r\n const spec = specs[i];\r\n const newProxy = newProxies[i];\r\n const newPartIndex = newProxy.partIndex;\r\n\r\n this.setWorldMatrixForPart(newPartIndex, spec.worldMatrix);\r\n this.setPartVisibility(newPartIndex, spec.visibility);\r\n const quaternion = new Quaternion();\r\n spec.worldMatrix.decompose(newProxy.scaling, quaternion, newProxy.position);\r\n newProxy.rotationQuaternion = quaternion;\r\n newProxy.computeWorldMatrix(true);\r\n\r\n spec.oldProxy.updatePartIndex(newPartIndex);\r\n spec.oldProxy.updatePartMetadata(newProxy._vertexCount, newProxy._splatsDataOffset, newProxy._shDataOffset);\r\n this._partProxies[newPartIndex] = spec.oldProxy;\r\n newProxy.dispose();\r\n\r\n if (spec.state) {\r\n // Relocate: the usable base is the (aligned) source start + front pad. Update BEFORE the\r\n // onAfter hook fires so the stream reads the new base from the handle.\r\n spec.state.partIndex = newPartIndex;\r\n spec.state.base = newProxy._splatsDataOffset + spec.frontPad;\r\n // Re-post the region's active ranges at the new base so the union stays correct with no flicker.\r\n this._partSplatRanges[newPartIndex] = spec.state.localRanges\r\n ? spec.state.localRanges.map((r) => ({ offset: spec.state!.base + r.offset, count: r.count }))\r\n : null;\r\n } else {\r\n this._partSplatRanges[newPartIndex] = null; // static parts render fully\r\n }\r\n }\r\n\r\n // Rebind + restore every surviving streaming region into the new (smaller) atlas at its new base.\r\n if (this._mrtAtlas) {\r\n this._onAfterAtlasRebuildObservable.notifyObservers(this._mrtAtlas);\r\n }\r\n\r\n // Drop the states of tombstoned streaming parts; keep only surviving ones.\r\n this._streamingStates = specs.filter((s) => s.state).map((s) => s.state!);\r\n this._hasStreamingPart = this._streamingStates.length > 0;\r\n this._tombstonedPartIndices.clear();\r\n\r\n // Recompute bounds from the restored proxies (_addPartsInternal above used the zero-box placeholders),\r\n // else a static-transform compound keeps stale bounds and isInFrustum can cull it. Must run after the\r\n // tombstone set is cleared so a survivor reusing a tombstoned index isn't skipped by the filter.\r\n this._updateBoundingInfoFromProxies();\r\n\r\n this._rebuilding = false;\r\n this._canPostToWorker = true;\r\n // The streaming regions' CPU positions were restored into _splatPositions by the onAfter hook (after\r\n // _addPartsInternal had already posted the rebuild's zeros), so re-post the full merged set: positions\r\n // + part indices via _notifyWorkerNewData, then the per-part matrices (suppressed during _rebuilding),\r\n // refresh the union, and fire one sort — so the worker's positions/partIndices/partMatrices all agree.\r\n this._refreshPartRangeUnion();\r\n this._notifyWorkerNewData();\r\n const workerAfterRebuild = this._worker as Worker | null;\r\n workerAfterRebuild?.postMessage({\r\n command: GaussianSplattingSortWorkerCommand.PART_MATRICES,\r\n partMatrices: this._partMatrices.map((matrix) => new Float32Array(matrix.m)),\r\n });\r\n this._postToWorker(true);\r\n this.onPartCountChangedObservable.notifyObservers(this.partCount);\r\n } catch (e) {\r\n this._rebuilding = false;\r\n this._canPostToWorker = true;\r\n throw e;\r\n }\r\n }\r\n\r\n /**\r\n * Remove a part from this compound mesh.\r\n * The remaining parts are rebuilt directly from the compound mesh's retained source buffers.\r\n * The current mesh is reset to a plain (single-part) state and then each remaining source is\r\n * re-added via addParts.\r\n * When a streaming part is reserved the part is tombstoned instead of compacted (see {@link _tombstonePart}).\r\n * @param index - The index of the part to remove\r\n * @deprecated Use {@link GaussianSplattingCompoundMesh.removePart} instead.\r\n */\r\n public removePart(index: number): void {\r\n if (index < 0 || index >= this.partCount) {\r\n throw new Error(`Part index ${index} is out of range [0, ${this.partCount})`);\r\n }\r\n\r\n // Streaming compounds can't compact (a reserved region has no CPU source and a fixed base offset).\r\n if (this._hasStreamingPart) {\r\n this._tombstonePart(index);\r\n return;\r\n }\r\n\r\n // Collect surviving proxy objects (sorted by current part index so part 0 is added first)\r\n const survivors: Array<{ proxyMesh: GaussianSplattingPartProxyMesh; source: IGaussianSplattingPartSource; oldIndex: number; worldMatrix: Matrix; visibility: number }> = [];\r\n for (let proxyIndex = 0; proxyIndex < this._partProxies.length; proxyIndex++) {\r\n const proxy = this._partProxies[proxyIndex];\r\n if (!proxy || proxyIndex === index) {\r\n continue;\r\n }\r\n const source = this._createRetainedPartSource(proxy);\r\n if (!source) {\r\n throw new Error(`Cannot remove part: the retained compound source data is not available for part \"${proxy.name}\".`);\r\n }\r\n survivors.push({ proxyMesh: proxy, source, oldIndex: proxyIndex, worldMatrix: proxy.getWorldMatrix().clone(), visibility: this._partVisibility[proxyIndex] ?? 1.0 });\r\n }\r\n survivors.sort((a, b) => a.oldIndex - b.oldIndex);\r\n\r\n // Validate every survivor still has its source data. If even one is missing we cannot rebuild.\r\n for (const { proxyMesh, source } of survivors) {\r\n if (!source._splatsData) {\r\n throw new Error(`Cannot remove part: the source data for part \"${proxyMesh.name}\" is not available.`);\r\n }\r\n if (source._shDegree > 0 && !source._shData) {\r\n throw new Error(`Cannot remove part: the SH data for part \"${proxyMesh.name}\" is not available.`);\r\n }\r\n }\r\n\r\n // Notify listeners before mutation so they can record state keyed on the original index.\r\n this.onPartRemovedObservable.notifyObservers(index);\r\n\r\n // Dispose the removed part's proxy, then reset to an empty state (survivors' proxy objects are held in\r\n // `survivors` and reused after the rebuild).\r\n this._partProxies[index]?.dispose();\r\n this._resetForRebuild();\r\n\r\n // Rebuild from surviving sources. _addPartsInternal assigns part indices in order 0, 1, 2, …\r\n // so the new index for each survivor is simply its position in the survivors array.\r\n if (survivors.length === 0) {\r\n // Nothing left — leave the mesh empty.\r\n this.setEnabled(false);\r\n this.onPartCountChangedObservable.notifyObservers(0);\r\n return;\r\n }\r\n\r\n // Gate the sort worker: suppress any sort request until the full rebuild is committed.\r\n this._rebuilding = true;\r\n this._canPostToWorker = false;\r\n try {\r\n const sources = survivors.map((s) => s.source);\r\n const { proxyMeshes: newProxies } = this._addPartsInternal(sources, false);\r\n\r\n // Restore world matrices and re-map proxies\r\n for (let i = 0; i < survivors.length; i++) {\r\n const oldProxy = survivors[i].proxyMesh;\r\n const newProxy = newProxies[i];\r\n const newPartIndex = newProxy.partIndex;\r\n\r\n // Restore the world matrix and visibility the user had set on the old proxy\r\n this.setWorldMatrixForPart(newPartIndex, survivors[i].worldMatrix);\r\n this.setPartVisibility(newPartIndex, survivors[i].visibility);\r\n const quaternion = new Quaternion();\r\n survivors[i].worldMatrix.decompose(newProxy.scaling, quaternion, newProxy.position);\r\n newProxy.rotationQuaternion = quaternion;\r\n newProxy.computeWorldMatrix(true);\r\n\r\n // Update the old proxy's index and metadata so existing user references still work.\r\n oldProxy.updatePartIndex(newPartIndex);\r\n oldProxy.updatePartMetadata(newProxy._vertexCount, newProxy._splatsDataOffset, newProxy._shDataOffset);\r\n this._partProxies[newPartIndex] = oldProxy;\r\n\r\n // newProxy is redundant — it was created inside _addPartsInternal; dispose it\r\n newProxy.dispose();\r\n }\r\n\r\n // Rebuild is complete: all partMatrices are now set correctly.\r\n // Post the final complete set and fire one sort.\r\n this._rebuilding = false;\r\n // Break TypeScript's flow narrowing — _addPartsInternal may have reinstantiated _worker.\r\n const workerAfterRebuild = this._worker as Worker | null;\r\n workerAfterRebuild?.postMessage({\r\n command: GaussianSplattingSortWorkerCommand.PART_MATRICES,\r\n partMatrices: this._partMatrices.map((matrix) => new Float32Array(matrix.m)),\r\n });\r\n this._canPostToWorker = true;\r\n this._postToWorker(true);\r\n } catch (e) {\r\n // Ensure the gates are always restored so sorting is not permanently frozen.\r\n this._rebuilding = false;\r\n this._canPostToWorker = true;\r\n throw e;\r\n }\r\n }\r\n\r\n /**\r\n * Reserves a contiguous region of `capacity` splats in the compound as a new part for dynamic (streamed)\r\n * content. Unlike {@link addPart}, no source data is copied: the region is created as invisible padding\r\n * (zeroed) for a streaming engine to populate over time via the returned handle. The reserved part\r\n * participates in the compound's single shared depth sort and draw exactly like a static part — it has a\r\n * `partIndex`, a per-part world matrix (via its proxy), and a per-part visibility — so streamed splats are\r\n * sorted and rendered together in one pass with the static parts.\r\n *\r\n * Add the streaming part LAST (after all static parts). The returned handle drives which of the region's\r\n * splats render (LOD) and writes their data.\r\n * @param capacity number of splats to reserve\r\n * @param worldMatrix initial world matrix for the region's proxy (e.g. carrying a source's up-axis\r\n * convention); defaults to identity\r\n * @param name name for the region's proxy mesh\r\n * @param shTextureCount number of packed-u32 higher-order SH textures to allocate as a shared render-target SH\r\n * atlas the streaming engine bakes into (`ceil(coeffs*3/16)` for the stream's max SH degree); 0 = no SH\r\n * @param shDegree SH degree of the streamed content (drives the compound's `SH_DEGREE`); ignored when\r\n * `shTextureCount` is 0. The compound keeps the MAX SH degree across its parts.\r\n * @param needsRotationScale when true, converts the compound's rotation/scale textures to a shared render-target\r\n * half-float atlas the streaming engine decodes into, so the streamed splats participate in voxel-IBL shadows.\r\n * @returns a handle used to populate and control the reserved region\r\n */\r\n public reserveStreamingPart(\r\n capacity: number,\r\n worldMatrix: Matrix = Matrix.Identity(),\r\n name: string = this.name + \"_streamingPart\",\r\n shTextureCount: number = 0,\r\n shDegree: number = 0,\r\n needsRotationScale: boolean = false\r\n ): IGaussianSplattingStreamingPart {\r\n // Require a positive integer (reject e.g. 0.5, which would floor to a 0-capacity region), and cap at the\r\n // largest atlas the backend can allocate (a square texture at the max width) so an absurd value can't drive\r\n // an out-of-memory typed-array / MRT allocation.\r\n if (!Number.isSafeInteger(capacity) || capacity < 1) {\r\n throw new Error(\"reserveStreamingPart: capacity must be a positive integer\");\r\n }\r\n\r\n // Validate the SH sizing parameters — they drive the SH_DEGREE define and the SH texture allocation, so a\r\n // fractional/negative/huge value would give an invalid layout or an unbounded allocation. The draw path\r\n // supports degree 0..4 (shTexture0..4); SH is all-or-nothing; the texture count must match the degree.\r\n const maxSupportedShDegree = 4;\r\n if (!Number.isSafeInteger(shDegree) || shDegree < 0 || shDegree > maxSupportedShDegree) {\r\n throw new Error(`reserveStreamingPart: shDegree must be an integer in [0, ${maxSupportedShDegree}]`);\r\n }\r\n if (!Number.isSafeInteger(shTextureCount) || shTextureCount < 0) {\r\n throw new Error(\"reserveStreamingPart: shTextureCount must be a non-negative integer\");\r\n }\r\n if (shDegree > 0 !== shTextureCount > 0) {\r\n throw new Error(\"reserveStreamingPart: shDegree and shTextureCount must both be positive (SH) or both zero (no SH)\");\r\n }\r\n if (shDegree > 0) {\r\n const expectedShTextureCount = Math.ceil((((shDegree + 1) * (shDegree + 1) - 1) * 3) / _GaussianSplattingBytesPerShTexel);\r\n if (shTextureCount !== expectedShTextureCount) {\r\n throw new Error(`reserveStreamingPart: shTextureCount ${shTextureCount} does not match shDegree ${shDegree} (expected ${expectedShTextureCount})`);\r\n }\r\n }\r\n\r\n const maxTextureSize = this._scene.getEngine().getCaps().maxTextureSize;\r\n const maxCapacity = maxTextureSize * maxTextureSize;\r\n\r\n // Row-align the region so a later GPU relayout (defrag under a memory budget) can be scoped to whole\r\n // atlas rows via scissor without ever touching a preceding part that shares a row.\r\n // - Front alignment: start the usable region on the next row boundary. This only consumes the\r\n // preceding parts' already-allocated last-row tail padding, so it costs no extra memory.\r\n // - Capacity alignment: pad the region up to a whole number of rows so its end is a row boundary too\r\n // (needed when another part follows, e.g. multiple streaming parts).\r\n const atlasWidth = this._getTextureSize(1).x;\r\n const startOffset = this._vertexCount; // first atlas index the reserved part occupies\r\n const alignedBase = Math.ceil(startOffset / atlasWidth) * atlasWidth;\r\n const frontPad = alignedBase - startOffset; // invisible padding that fills the preceding row\r\n const alignedCapacity = Math.ceil(capacity / atlasWidth) * atlasWidth;\r\n const regionSplats = frontPad + alignedCapacity;\r\n\r\n // Validate the RESULTING atlas, not just `capacity`: existing splats, row-alignment padding, and the trailing\r\n // empty sentinel slot (`+ 1`, see _getTextureSize) all count against the device's square-texture limit.\r\n // _getTextureSize would silently clamp and drop the sentinel past the limit, so reject here — before any\r\n // state is mutated below, so a rejected reservation leaves the compound intact.\r\n const projectedSplats = startOffset + regionSplats;\r\n if (projectedSplats + 1 > maxCapacity) {\r\n throw new Error(\r\n `reserveStreamingPart: capacity ${capacity} would grow the atlas to ${projectedSplats} splats (plus a sentinel), exceeding the maximum atlas capacity ${maxCapacity}`\r\n );\r\n }\r\n\r\n // Back the atlas with a render-targetable MRT so a streaming engine can GPU-decode into the reserved\r\n // region. Must be set before _addPartsInternal so the (forced) full rebuild builds MRT attachments and\r\n // allocates covariance B as RGBA. Harmless/no-op if a streaming part was already reserved.\r\n this._useMrtAtlas = true;\r\n this._useRGBACovariants = true;\r\n\r\n // Higher-order SH: convert the SH textures to render-targetable integer MRTs so the stream can bake SH into\r\n // its region, and set the compound's SH degree so the draw path lights the decoded splats. Sized for the\r\n // MAX SH texture count across parts (a later higher-degree part grows it; lower-degree parts neutral-fill).\r\n if (shTextureCount > 0 && shDegree > 0) {\r\n this._useShMrtAtlas = true;\r\n this._shMrtAtlasTextureCount = Math.max(this._shMrtAtlasTextureCount, shTextureCount);\r\n // Streaming SH degree is tracked separately from _maxShDegree (which folds in static parts too) and is\r\n // recomputed from the surviving states on removal — so it shrinks correctly. The _addPartsInternal\r\n // rebuild below folds it into _shDegree/_maxShDegree.\r\n this._streamingShDegree = Math.max(this._streamingShDegree, shDegree);\r\n }\r\n\r\n // Rotation/scale: convert the rotation textures to a render-targetable half-float atlas so the stream can\r\n // decode rotation/scale into its region for voxel-IBL shadows. `_needsRotationScaleTextures` makes _makeSplat\r\n // fill static parts' rotation data (CPU-uploaded into the shared atlas by the rebuild) too.\r\n if (needsRotationScale) {\r\n this._useRotMrtAtlas = true;\r\n this._needsRotationScaleTextures = true;\r\n }\r\n\r\n // Running local-space bounds of the region's written centers; grown as splats are populated.\r\n const boundsMin = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n const boundsMax = new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\r\n\r\n // Synthetic placeholder source: no data, so _addPartsInternal leaves the region zeroed (invisible)\r\n // while still assigning a part index, filling _partIndices, growing the atlas + _splatPositions,\r\n // creating the proxy, and posting the (larger) position/interval set to the sort worker.\r\n const reservedSource: IGaussianSplattingPartSource = {\r\n name,\r\n _vertexCount: regionSplats,\r\n _splatsData: null,\r\n _shData: null,\r\n _shDegree: 0,\r\n isCompound: false,\r\n getWorldMatrix: () => worldMatrix,\r\n getBoundingInfo: () => new BoundingInfo(Vector3.ZeroReadOnly, Vector3.ZeroReadOnly),\r\n dispose: () => {},\r\n _isReservedEmpty: true,\r\n };\r\n\r\n const { proxyMeshes, assignedPartIndices } = this._addPartsInternal([reservedSource], false);\r\n const proxy = proxyMeshes[0];\r\n // Usable region starts at the row-aligned base (past the front padding) and spans the aligned capacity.\r\n // (proxy._splatsDataOffset === startOffset; the usable base is startOffset + frontPad === alignedBase.)\r\n // `base`/`partIndex` live in mutable state so compactAtlas can RELOCATE this region (new base/index) in\r\n // place; the handle's getters and closures read the state, so the streaming engine's handle stays valid.\r\n const state: IStreamingPartState = {\r\n proxy,\r\n base: alignedBase,\r\n partIndex: assignedPartIndices[0],\r\n capacity: alignedCapacity,\r\n boundsMin,\r\n boundsMax,\r\n localRanges: null,\r\n shTextureCount: shTextureCount > 0 && shDegree > 0 ? shTextureCount : 0,\r\n shDegree: shTextureCount > 0 && shDegree > 0 ? shDegree : 0,\r\n needsRotationScale,\r\n removed: false,\r\n };\r\n this._streamingStates.push(state);\r\n capacity = alignedCapacity;\r\n\r\n // The handle's live getters need a stable reference to this compound (its atlas textures can be\r\n // recreated on a later rebuild), so alias it for the closures below.\r\n // eslint-disable-next-line @typescript-eslint/no-this-alias\r\n const compound = this;\r\n const applyBounds = () => {\r\n if (boundsMin.x <= boundsMax.x) {\r\n proxy.setBoundingInfo(new BoundingInfo(boundsMin.clone(), boundsMax.clone()));\r\n compound._updateBoundingInfoFromProxies();\r\n }\r\n };\r\n // Rejects any mutating call after the part was removed, so a retained stale handle can't touch a surviving\r\n // part that inherited this region's (now-reused) part index/base.\r\n const assertLive = (method: string) => {\r\n if (state.removed) {\r\n throw new Error(`${method}: this streaming part has been removed`);\r\n }\r\n };\r\n // Enforces the documented local part boundary [0, capacity) so a handle call can never address another\r\n // part's atlas region (the region base is added to these local coordinates before use).\r\n const assertLocalRange = (method: string, offset: number, count: number) => {\r\n if (!Number.isInteger(offset) || !Number.isInteger(count) || offset < 0 || count < 0 || offset + count > state.capacity) {\r\n throw new Error(`${method}: local range [${offset}, ${offset + count}) is outside the reserved region [0, ${state.capacity})`);\r\n }\r\n };\r\n\r\n const handle: IGaussianSplattingStreamingPart = {\r\n proxy,\r\n capacity,\r\n get partIndex() {\r\n return state.partIndex;\r\n },\r\n get base() {\r\n return state.base;\r\n },\r\n get centersTexture() {\r\n return compound.centersTexture;\r\n },\r\n get covariancesATexture() {\r\n return compound.covariancesATexture;\r\n },\r\n get covariancesBTexture() {\r\n return compound.covariancesBTexture;\r\n },\r\n get colorsTexture() {\r\n return compound.colorsTexture;\r\n },\r\n get splatPositions() {\r\n return compound._splatPositions;\r\n },\r\n get mrtAtlas() {\r\n return compound._mrtAtlas;\r\n },\r\n get shMrtAtlas() {\r\n return compound._shMrtAtlas;\r\n },\r\n get rotMrtAtlas() {\r\n return compound._rotMrtAtlas;\r\n },\r\n get atlasWidth() {\r\n return compound._getTextureSize(compound._vertexCount).x;\r\n },\r\n get isDepthSortSettled() {\r\n return compound._isDepthSortSettled;\r\n },\r\n setActiveRanges: (localRanges) => {\r\n assertLive(\"setActiveRanges\");\r\n // Keep every range inside this part's region so it can never activate another part's splats.\r\n if (localRanges) {\r\n for (const r of localRanges) {\r\n assertLocalRange(\"setActiveRanges\", r.offset, r.count);\r\n }\r\n }\r\n // Remember the LOCAL ranges so compactAtlas can re-post them at the region's new base.\r\n state.localRanges = localRanges ? localRanges.map((r) => ({ offset: r.offset, count: r.count })) : null;\r\n const globalRanges = localRanges ? localRanges.map((r) => ({ offset: state.base + r.offset, count: r.count })) : null;\r\n compound.setPartSplatRanges(state.partIndex, globalRanges);\r\n },\r\n writeSplats: (localOffset, count, splatsData) => {\r\n assertLive(\"writeSplats\");\r\n // Keep the write inside this part's region so it can never touch another part's atlas texels.\r\n assertLocalRange(\"writeSplats\", localOffset, count);\r\n compound._writeStreamingSplats(state.base + localOffset, count, splatsData, boundsMin, boundsMax);\r\n applyBounds();\r\n },\r\n postPositionsRange: (localOffset, count) => {\r\n assertLive(\"postPositionsRange\");\r\n assertLocalRange(\"postPositionsRange\", localOffset, count);\r\n compound._postWorkerPositionsRange(state.base + localOffset, count);\r\n },\r\n expandBounds: (min, max) => {\r\n assertLive(\"expandBounds\");\r\n boundsMin.minimizeInPlace(min);\r\n boundsMax.maximizeInPlace(max);\r\n applyBounds();\r\n },\r\n notifyDataChanged: () => {\r\n assertLive(\"notifyDataChanged\");\r\n compound._notifyWorkerNewData();\r\n },\r\n onBeforeAtlasRebuild: (callback) => {\r\n const observer = compound._onBeforeAtlasRebuildObservable.add(callback);\r\n return () => compound._onBeforeAtlasRebuildObservable.remove(observer);\r\n },\r\n onAfterAtlasRebuild: (callback) => {\r\n const observer = compound._onAfterAtlasRebuildObservable.add(callback);\r\n return () => compound._onAfterAtlasRebuildObservable.remove(observer);\r\n },\r\n };\r\n // Mark AFTER the successful internal _addPartsInternal so its own call isn't blocked by the guard.\r\n this._hasStreamingPart = true;\r\n return handle;\r\n }\r\n\r\n /**\r\n * Serialize current GaussianSplattingMesh\r\n * @param serializationObject defines the object which will receive the serialization data\r\n * @param encoding the encoding of binary data, defaults to base64 for json serialize,\r\n * kept for future internal use like cloning where base64 encoding wastes cycles and memory\r\n * @returns the serialized object\r\n */\r\n public override serialize(serializationObject: any = {}, encoding: string = \"base64\"): any {\r\n serializationObject = super.serialize(serializationObject);\r\n serializationObject.subMeshes = [];\r\n serializationObject.geometryUniqueId = undefined;\r\n serializationObject.geometryId = undefined;\r\n serializationObject.materialUniqueId = undefined;\r\n serializationObject.materialId = undefined;\r\n serializationObject.instances = [];\r\n serializationObject.actions = undefined;\r\n serializationObject.type = this.getClassName();\r\n serializationObject.keepInRam = this._keepInRam;\r\n serializationObject.disableDepthSort = this._disableDepthSort;\r\n serializationObject.viewUpdateThreshold = this.viewUpdateThreshold;\r\n serializationObject._flipY = this._flipY;\r\n\r\n if (this._splatsData) {\r\n serializationObject.splatsData = encoding === \"base64\" ? EncodeArrayBufferToBase64(this._splatsData) : this._splatsData;\r\n }\r\n if (this._shData) {\r\n serializationObject.shData = encoding === \"base64\" ? this._shData.map(EncodeArrayBufferToBase64) : this._shData;\r\n serializationObject.shDegree = this._shDegree;\r\n }\r\n if (this._partIndices) {\r\n const compressedIndices = CompressPartIndices(this._partIndices.subarray(0, this._vertexCount));\r\n serializationObject.partIndices = encoding === \"base64\" ? EncodeArrayBufferToBase64(compressedIndices) : compressedIndices;\r\n }\r\n if (this._partProxies.length) {\r\n serializationObject.partProxies = this._partProxies.filter((proxy) => !!proxy).map((proxy) => proxy.serialize());\r\n }\r\n\r\n return serializationObject;\r\n }\r\n\r\n /**\r\n * Internal helper to parses a serialized GaussianSplattingMesh or GaussianSplattingCompoundMesh\r\n * @param parsedMesh the serialized mesh\r\n * @param scene the scene to create the GaussianSplattingMesh or GaussianSplattingCompoundMesh in\r\n * @param ctor the constructor of the mesh to create\r\n * @returns the created GaussianSplattingMesh\r\n * @internal\r\n */\r\n public static _ParseInternal<T extends GaussianSplattingMesh>(\r\n parsedMesh: any,\r\n scene: Scene,\r\n ctor: new (name: string, url: Nullable<string>, scene: Nullable<Scene>, keepInRam: boolean) => T\r\n ): T {\r\n const mesh = new ctor(parsedMesh.name, null, scene, parsedMesh.keepInRam);\r\n\r\n mesh.disableDepthSort = parsedMesh.disableDepthSort ?? false;\r\n mesh.viewUpdateThreshold = parsedMesh.viewUpdateThreshold ?? GaussianSplattingMeshBase._DefaultViewUpdateThreshold;\r\n\r\n let splatsData: ArrayBuffer | string | undefined = parsedMesh.splatsData;\r\n if (typeof splatsData === \"string\") {\r\n splatsData = DecodeBase64ToBinary(splatsData);\r\n }\r\n\r\n const shData: string[] | Uint8Array[] | undefined = parsedMesh.shData;\r\n let parsedShData: Uint8Array[] | undefined;\r\n if (Array.isArray(shData) && shData.length) {\r\n const newData: Uint8Array[] = [];\r\n for (let i = 0, length = shData.length; i < length; i++) {\r\n const data = shData[i];\r\n if (typeof data === \"string\") {\r\n newData[i] = new Uint8Array(DecodeBase64ToBinary(data));\r\n } else {\r\n newData[i] = data;\r\n }\r\n }\r\n parsedShData = newData;\r\n }\r\n\r\n let partIndices: string | Uint32Array | number[] | undefined = parsedMesh.partIndices;\r\n let parsedPartIndices: Uint8Array | undefined;\r\n if (typeof partIndices === \"string\") {\r\n partIndices = new Uint32Array(DecodeBase64ToBinary(partIndices));\r\n }\r\n if (partIndices) {\r\n parsedPartIndices = ParsePartIndices(partIndices);\r\n }\r\n\r\n if (splatsData) {\r\n const flipY = parsedMesh._flipY ?? false;\r\n mesh.updateData(splatsData, parsedShData, { flipY }, parsedPartIndices, parsedMesh.shDegree);\r\n }\r\n\r\n if (parsedMesh.partProxies) {\r\n for (const serializedPart of parsedMesh.partProxies) {\r\n const part = Object.assign({}, serializedPart);\r\n part.compoundSplatMesh = mesh;\r\n const proxyMesh = Mesh.Parse(part, scene, \"\") as GaussianSplattingPartProxyMesh;\r\n const newPartIndex = proxyMesh.partIndex;\r\n mesh._partProxies[newPartIndex] = proxyMesh;\r\n mesh.setWorldMatrixForPart(newPartIndex, proxyMesh.getWorldMatrix());\r\n mesh.setPartVisibility(newPartIndex, proxyMesh.visibility);\r\n }\r\n }\r\n\r\n return mesh;\r\n }\r\n\r\n /**\r\n * Parses a serialized GaussianSplattingMesh\r\n * @param parsedMesh the serialized mesh\r\n * @param scene the scene to create the GaussianSplattingMesh in\r\n * @returns the created GaussianSplattingMesh\r\n */\r\n public static override Parse(parsedMesh: any, scene: Scene): GaussianSplattingMesh {\r\n return GaussianSplattingMesh._ParseInternal(parsedMesh, scene, GaussianSplattingMesh);\r\n }\r\n}\r\n\r\n/**\r\n * True when `className` (from `AbstractMesh.getClassName()`) identifies a Gaussian Splatting mesh whose\r\n * `position.z` vertex attribute encodes a splat index rather than world-space Z: `\"GaussianSplattingMesh\"`\r\n * (also returned by {@link GaussianSplattingCompoundMesh}, which deliberately does not override\r\n * `getClassName()`) and `\"GaussianSplattingStream\"` (which does override it, to remain distinguishable for\r\n * other purposes). Rendering-pipeline code that must treat any Gaussian Splatting mesh differently from an\r\n * ordinary mesh (geometry buffer, depth pre-pass, GPU picking, IBL voxelization, snapshot rendering, ...)\r\n * should use this instead of a literal string comparison, so a future splat mesh subclass only needs to be\r\n * added here once.\r\n * @param className the mesh class name to test, e.g. from `AbstractMesh.getClassName()`\r\n * @returns true if the class name identifies a Gaussian Splatting mesh\r\n */\r\nexport function IsGaussianSplattingClassName(className: string): boolean {\r\n return className === \"GaussianSplattingMesh\" || className === \"GaussianSplattingStream\";\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for gaussianSplattingMesh.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGaussianSplattingMesh(): void {\r\n if (_Registered) {\r\n return;\r\n }\r\n _Registered = true;\r\n\r\n Mesh._GaussianSplattingMeshParser = GaussianSplattingMesh.Parse;\r\n}\r\n"]}