@thinkersteps_labs/3d-viewer-core 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.map +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +46 -46
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/converter/errors.ts","../src/converter/normalize.ts","../src/converter/loaders.ts","../src/events/index.ts","../src/converter/fetch.ts","../src/converter/source-resolver.ts","../src/converter/index.ts","../src/parts/keywords.ts","../src/parts/index.ts","../src/materials/presets.ts","../src/materials/gem-geometry.ts","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/Constants.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/utils/ArrayBoxUtilities.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/utils/nodeBufferUtils.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/build/computeBoundsUtils.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/build/splitUtils.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/BVHNode.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/build/sortUtils.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/build/buildUtils.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/build/buildTree.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/utils/PrimitivePool.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/utils/BufferStack.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/cast/shapecast.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/cast/bvhcast.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/BVHTraversalHelper.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/BVH.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/utils/BufferUtils.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/build/geometryUtils.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/GeometryBVH.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/math/SeparatingAxisBounds.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/math/MathUtilities.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/math/ExtendedTriangle.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/math/OrientedBox.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/utils/ExtendedTrianglePool.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/cast/closestPointToPoint.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/utils/ThreeRayIntersectUtilities.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/utils/TriangleUtilities.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/utils/iterationUtils.generated.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/cast/refit.generated.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/utils/intersectUtils.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/utils/iterationUtils_indirect.generated.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/cast/raycast.generated.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/cast/raycastFirst.generated.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/cast/intersectsGeometry.generated.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/cast/closestPointToGeometry.generated.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/cast/refit_indirect.generated.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/cast/raycast_indirect.generated.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/cast/raycastFirst_indirect.generated.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/cast/intersectsGeometry_indirect.generated.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/cast/closestPointToGeometry_indirect.generated.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/utils/GeometryRayIntersectUtilities.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/MeshBVH.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/webgl/VertexAttributeTexture.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/webgl/MeshBVHUniformStruct.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/webgl/glsl/common_functions.glsl.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/webgl/glsl/bvh_ray_functions.glsl.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/webgl/glsl/bvh_struct_definitions.glsl.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/index.js","../src/materials/diamond-shaders.ts","../src/materials/diamond-baker.ts","../src/materials/diamond-material.ts","../src/materials/environment.ts","../src/materials/diamond-bvh.ts","../src/materials/format-loaders.ts","../src/materials/diamond-reference-shaders.ts","../src/materials/diamond-reference-material.ts","../src/materials/index.ts","../src/viewer/renderer.ts","../src/viewer/scene.ts","../src/viewer/controls.ts","../src/viewer/interaction.ts","../src/viewer/state.ts","../src/viewer/shadow.ts","../src/viewer/index.ts","../src/index.ts"],"sourcesContent":["export class UnsupportedFormatError extends Error {\n readonly format: string\n\n constructor(format: string) {\n super(`Unsupported format: \"${format}\"`)\n this.name = 'UnsupportedFormatError'\n this.format = format\n Object.setPrototypeOf(this, UnsupportedFormatError.prototype)\n }\n}\n\nexport class CorruptFileError extends Error {\n override readonly cause?: unknown\n\n constructor(message: string, cause?: unknown) {\n super(message)\n this.name = 'CorruptFileError'\n this.cause = cause\n Object.setPrototypeOf(this, CorruptFileError.prototype)\n }\n}\n\nexport class NetworkError extends Error {\n readonly status?: number\n readonly url?: string\n\n constructor(message: string, status?: number, url?: string) {\n super(message)\n this.name = 'NetworkError'\n this.status = status\n this.url = url\n Object.setPrototypeOf(this, NetworkError.prototype)\n }\n}\n","import * as THREE from 'three'\n\n/**\n * Mutates the scene in place:\n * 1. Centers the bounding box at the world origin.\n * 2. Scales uniformly so the longest axis = 1.0 unit.\n */\nexport function normalizeScene(scene: THREE.Group): void {\n scene.position.set(0, 0, 0)\n scene.scale.set(1, 1, 1)\n scene.updateMatrixWorld(true)\n\n const box = new THREE.Box3().setFromObject(scene)\n const center = box.getCenter(new THREE.Vector3())\n const size = box.getSize(new THREE.Vector3())\n\n const maxDim = Math.max(size.x, size.y, size.z)\n const scale = maxDim > 0 ? 1 / maxDim : 1\n\n // Scale\n scene.scale.setScalar(scale)\n // Center\n scene.position.sub(center.multiplyScalar(scale))\n // Re-center after scale\n scene.updateMatrixWorld(true)\n}\n","import * as THREE from 'three'\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'\nimport { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'\nimport { STLLoader } from 'three/examples/jsm/loaders/STLLoader.js'\nimport { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js'\nimport { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader.js'\nimport { GLTFExporter } from 'three/examples/jsm/exporters/GLTFExporter.js'\n\nexport const DEFAULT_DRACO_DECODER_PATH = 'https://www.gstatic.com/draco/versioned/decoders/1.5.6/'\nimport { CorruptFileError } from './errors'\nimport type { FetchedSource } from './fetch'\nimport { normalizeScene } from './normalize'\n\n// Polyfill FileReader for Node environments (e.g. Vitest / Node runtime) if not present\nif (typeof globalThis.FileReader === 'undefined') {\n class NodeFileReader {\n result: ArrayBuffer | string | null = null\n onloadend: (() => void) | null = null\n onload: (() => void) | null = null\n onerror: ((err: unknown) => void) | null = null\n\n readAsArrayBuffer(blob: Blob) {\n blob.arrayBuffer().then(\n (buf) => {\n this.result = buf\n this.onload?.()\n this.onloadend?.()\n },\n (err) => {\n this.onerror?.(err)\n this.onloadend?.()\n },\n )\n }\n\n readAsDataURL(blob: Blob) {\n blob.arrayBuffer().then(\n (buf) => {\n const nodeBuffer = (globalThis as unknown as { Buffer?: { from: (b: ArrayBuffer) => { toString: (e: string) => string } } }).Buffer\n const base64 = nodeBuffer ? nodeBuffer.from(buf).toString('base64') : ''\n this.result = `data:${blob.type};base64,${base64}`\n this.onload?.()\n this.onloadend?.()\n },\n (err) => {\n this.onerror?.(err)\n this.onloadend?.()\n },\n )\n }\n }\n ;(globalThis as unknown as { FileReader: typeof NodeFileReader }).FileReader = NodeFileReader\n}\n\nconst SIZE_WARN_BYTES = 50 * 1024 * 1024 // 50 MB\n\nexport interface ParseResult {\n scene: THREE.Group\n warnings: string[]\n}\n\nexport async function parseToScene(\n fetched: FetchedSource,\n dracoDecoderPath?: string,\n): Promise<ParseResult> {\n const warnings: string[] = []\n\n if (fetched.data.byteLength > SIZE_WARN_BYTES) {\n warnings.push('File exceeds 50 MB; performance may be affected')\n }\n\n switch (fetched.format) {\n case 'glb':\n case 'gltf':\n return parseGltf(fetched, warnings, dracoDecoderPath)\n case 'stl':\n return parseStl(fetched, warnings)\n case 'obj':\n return parseObj(fetched, warnings)\n }\n}\n\nasync function parseGltf(\n fetched: FetchedSource,\n warnings: string[],\n dracoDecoderPath?: string,\n): Promise<ParseResult> {\n const loader = new GLTFLoader()\n const dracoLoader = new DRACOLoader()\n dracoLoader.setDecoderPath(dracoDecoderPath ?? DEFAULT_DRACO_DECODER_PATH)\n loader.setDRACOLoader(dracoLoader)\n\n try {\n const gltf = await new Promise<{ scene: THREE.Group }>((resolve, reject) => {\n loader.parse(\n fetched.data,\n '',\n resolve,\n reject,\n )\n })\n dracoLoader.dispose()\n normalizeScene(gltf.scene)\n return { scene: gltf.scene, warnings }\n } catch (err) {\n dracoLoader.dispose()\n throw new CorruptFileError('Failed to parse GLTF/GLB', err)\n }\n}\n\nfunction parseStl(fetched: FetchedSource, warnings: string[]): ParseResult {\n const loader = new STLLoader()\n let geometry: THREE.BufferGeometry\n try {\n geometry = loader.parse(fetched.data)\n } catch (err) {\n throw new CorruptFileError('Failed to parse STL', err)\n }\n // Spec §4.3: metal uses MeshPhysicalMaterial with metalness ~1.0\n const material = new THREE.MeshPhysicalMaterial({\n name: 'metal',\n color: 0xc0c0c0,\n metalness: 1.0,\n roughness: 0.10,\n envMapIntensity: 1.0,\n })\n const mesh = new THREE.Mesh(geometry, material)\n mesh.name = 'metal'\n const scene = new THREE.Group()\n scene.add(mesh)\n normalizeScene(scene)\n return { scene, warnings }\n}\n\nasync function parseObj(fetched: FetchedSource, warnings: string[]): Promise<ParseResult> {\n if (!fetched.mtlData) {\n warnings.push('No material file provided; default material applied')\n }\n\n let materials: MTLLoader.MaterialCreator | undefined\n\n if (fetched.mtlData) {\n const mtlLoader = new MTLLoader()\n const mtlText = new TextDecoder().decode(fetched.mtlData)\n try {\n materials = mtlLoader.parse(mtlText, '')\n materials.preload()\n } catch {\n warnings.push('Failed to parse MTL file; default material applied')\n materials = undefined\n }\n }\n\n const objLoader = new OBJLoader()\n if (materials) {\n objLoader.setMaterials(materials)\n }\n\n let scene: THREE.Group\n try {\n const text = new TextDecoder().decode(fetched.data)\n scene = objLoader.parse(text) as THREE.Group\n } catch (err) {\n throw new CorruptFileError('Failed to parse OBJ', err)\n }\n\n normalizeScene(scene)\n return { scene, warnings }\n}\n\nexport async function exportToGlb(scene: THREE.Group): Promise<ArrayBuffer> {\n const exporter = new GLTFExporter()\n return new Promise<ArrayBuffer>((resolve, reject) => {\n exporter.parse(\n scene,\n (result) => {\n if (result instanceof ArrayBuffer) {\n resolve(result)\n } else {\n // JSON result — encode to binary\n const text = JSON.stringify(result)\n const bytes = new TextEncoder().encode(text)\n resolve(bytes.buffer)\n }\n },\n reject,\n { binary: true },\n )\n })\n}\n","type Listener<T> = (data: T) => void\n\nexport class TypedEmitter<Events extends object> {\n private readonly _listeners = new Map<\n keyof Events,\n Set<Listener<unknown>>\n >()\n\n on<K extends keyof Events>(\n event: K,\n cb: Listener<Events[K]>,\n ): () => void {\n if (!this._listeners.has(event)) {\n this._listeners.set(event, new Set())\n }\n this._listeners.get(event)!.add(cb as Listener<unknown>)\n return () => this.off(event, cb)\n }\n\n off<K extends keyof Events>(event: K, cb: Listener<Events[K]>): void {\n this._listeners.get(event)?.delete(cb as Listener<unknown>)\n }\n\n emit<K extends keyof Events>(event: K, data: Events[K]): void {\n this._listeners.get(event)?.forEach((cb) => {\n try {\n cb(data)\n } catch (err) {\n console.error(`[3d-viewer] uncaught listener error on \"${String(event)}\":`, err)\n }\n })\n }\n\n clear(): void {\n this._listeners.clear()\n }\n}\n","import { UnsupportedFormatError, NetworkError } from './errors'\nimport type { ModelSource, SupportedFormat } from '../types'\n\nconst EXT_TO_FORMAT: Record<string, SupportedFormat> = {\n '.stl': 'stl',\n '.obj': 'obj',\n '.glb': 'glb',\n '.gltf': 'gltf',\n}\n\nconst MIME_TO_FORMAT: Record<string, SupportedFormat> = {\n 'model/gltf-binary': 'glb',\n 'model/gltf+json': 'gltf',\n}\n\nexport function inferFormatFromUrl(url: string): SupportedFormat | null {\n try {\n const pathname = new URL(url, 'http://dummy').pathname\n const dot = pathname.lastIndexOf('.')\n if (dot === -1) return null\n const ext = pathname.slice(dot).toLowerCase()\n return EXT_TO_FORMAT[ext] ?? null\n } catch {\n return null\n }\n}\n\nexport function inferFormatFromMime(mime: string): SupportedFormat | null {\n const base = mime.split(';')[0].trim().toLowerCase()\n return MIME_TO_FORMAT[base] ?? null\n}\n\nexport function inferFormatFromBuffer(buffer: ArrayBuffer): SupportedFormat | null {\n if (buffer.byteLength < 4) return null\n const bytes = new Uint8Array(buffer, 0, Math.min(buffer.byteLength, 80))\n // GLB magic number: 0x46546C67 ('glTF' in little endian: 0x67, 0x6c, 0x54, 0x46)\n if (bytes[0] === 0x67 && bytes[1] === 0x6c && bytes[2] === 0x54 && bytes[3] === 0x46) {\n return 'glb'\n }\n // Check for JSON gltf: starts with '{'\n if (bytes[0] === 0x7b) {\n return 'gltf'\n }\n // Check for ASCII STL: starts with 'solid'\n const header = String.fromCharCode(...bytes.slice(0, 5)).toLowerCase()\n if (header === 'solid') {\n return 'stl'\n }\n return null\n}\n\nexport async function decompressIfGzip(buffer: ArrayBuffer): Promise<ArrayBuffer> {\n const bytes = new Uint8Array(buffer)\n if (bytes.length >= 2 && bytes[0] === 0x1f && bytes[1] === 0x8b) {\n if (typeof DecompressionStream !== 'undefined') {\n try {\n const ds = new DecompressionStream('gzip')\n const stream = new Blob([buffer]).stream().pipeThrough(ds)\n const decompressed = await new Response(stream).arrayBuffer()\n if (decompressed.byteLength > 0) {\n return decompressed\n }\n } catch (err) {\n console.warn('[fetchSource] Decompression failed, proceeding with original buffer:', err)\n }\n }\n }\n return buffer\n}\n\nexport interface FetchedSource {\n data: ArrayBuffer\n mtlData?: ArrayBuffer\n format: SupportedFormat\n}\n\nexport async function fetchSource(\n source: ModelSource,\n signal?: AbortSignal,\n): Promise<FetchedSource> {\n // data variant — no network call\n if ('data' in source) {\n let data =\n source.data instanceof Blob ? await source.data.arrayBuffer() : source.data\n data = await decompressIfGzip(data)\n const mtlData =\n source.mtlData instanceof Blob\n ? await source.mtlData.arrayBuffer()\n : source.mtlData\n const format = source.format || inferFormatFromBuffer(data) || 'glb'\n return { data, mtlData, format }\n }\n\n // URL variant\n let format: SupportedFormat | null | undefined = source.format ?? inferFormatFromUrl(source.url)\n\n const response = await fetch(source.url, {\n headers: source.headers,\n signal,\n }).catch((err: unknown) => {\n if ((err as Error).name === 'AbortError') throw err\n throw new NetworkError(\n `Fetch failed: ${(err as Error).message}`,\n undefined,\n source.url,\n )\n })\n\n if (!response.ok) {\n throw new NetworkError(`HTTP ${response.status}`, response.status, source.url)\n }\n\n if (!format) {\n const ct = response.headers.get('content-type') ?? ''\n format = inferFormatFromMime(ct)\n }\n\n let data = await response.arrayBuffer()\n data = await decompressIfGzip(data)\n\n if (!format) {\n format = inferFormatFromBuffer(data)\n }\n\n if (!format) {\n throw new UnsupportedFormatError('unknown')\n }\n\n let mtlData: ArrayBuffer | undefined\n if (source.mtlUrl) {\n const mtlRes = await fetch(source.mtlUrl, {\n headers: source.headers,\n signal,\n })\n if (mtlRes.ok) {\n mtlData = await mtlRes.arrayBuffer()\n }\n }\n\n return { data, mtlData, format }\n}\n","import type { ModelSource, SupportedFormat, ViewerSourceInput } from '../types'\n\nconst SUPPORTED_FORMATS: readonly SupportedFormat[] = ['glb', 'gltf', 'obj', 'stl'] as const\n\n/**\n * Infer format from a file URL or path string.\n * Defaults to 'glb' if not recognised or absent.\n */\nexport function inferFormatFromUrl(url: string): SupportedFormat {\n const cleanUrl = url.split('?')[0].split('#')[0]\n const ext = cleanUrl.split('.').pop()?.toLowerCase()\n if (ext && (SUPPORTED_FORMATS as readonly string[]).includes(ext)) {\n return ext as SupportedFormat\n }\n return 'glb'\n}\n\n/**\n * Normalizes any supported source input (string URL, ModelSource object, or null/undefined)\n * into a canonical ModelSource object or null.\n */\nexport function normalizeModelSource(source: ViewerSourceInput): ModelSource | null {\n if (!source) return null\n\n if (typeof source === 'string') {\n const trimmed = source.trim()\n if (!trimmed) return null\n return {\n url: trimmed,\n format: inferFormatFromUrl(trimmed),\n }\n }\n\n // Already a ModelSource (url object or binary data object)\n return source\n}\n","import { fetchSource } from './fetch'\nimport { parseToScene, exportToGlb } from './loaders'\nimport type { ModelSource, ConvertedModel } from '../types'\nexport { UnsupportedFormatError, CorruptFileError, NetworkError } from './errors'\nexport { normalizeScene } from './normalize'\nexport { normalizeModelSource, inferFormatFromUrl } from './source-resolver'\n\nexport async function convert(\n source: ModelSource,\n signal?: AbortSignal,\n onProgress?: (progress: number) => void,\n options?: { dracoDecoderPath?: string },\n): Promise<ConvertedModel> {\n onProgress?.(0)\n\n const fetched = await fetchSource(source, signal)\n\n onProgress?.(0.3)\n\n const { scene, warnings } = await parseToScene(fetched, options?.dracoDecoderPath)\n\n onProgress?.(0.7)\n\n const glb = fetched.format === 'glb' ? fetched.data : await exportToGlb(scene)\n\n onProgress?.(1.0)\n\n // Count meshes\n let meshCount = 0\n scene.traverse((obj) => {\n if ((obj as { isMesh?: boolean }).isMesh) meshCount++\n })\n\n return {\n glb,\n sourceFormat: fetched.format,\n meshCount,\n warnings,\n }\n}\n","export const STONE_KEYWORDS = ['stone', 'diamond', 'gem', 'jewel', 'crystal']\nexport const METAL_KEYWORDS = ['metal', 'gold', 'silver', 'platinum', 'band', 'ring', 'prong', 'shank']\n","import * as THREE from 'three'\nimport { STONE_KEYWORDS, METAL_KEYWORDS } from './keywords'\nimport type { PartInfo, PartType, MeshMaterialSlot, MaterialSlotInfo } from '../types'\n\nfunction hasKeyword(text: string, keywords: string[]): boolean {\n const lower = text.toLowerCase()\n return keywords.some((kw) => lower.includes(kw))\n}\n\nfunction sanitizeName(name: string): string {\n return name.trim().replace(/[^a-zA-Z0-9_-]/g, '_')\n}\n\nexport function getStablePartId(\n mesh: THREE.Mesh,\n scene: THREE.Group,\n usedIds: Set<string>,\n): string {\n // 1. Author-defined metadata in CAD / GLTF extras\n if (typeof mesh.userData?.partId === 'string' && mesh.userData.partId.trim()) {\n const id = mesh.userData.partId.trim()\n usedIds.add(id)\n return id\n }\n if (typeof mesh.userData?.id === 'string' && mesh.userData.id.trim()) {\n const id = mesh.userData.id.trim()\n usedIds.add(id)\n return id\n }\n\n // 2. Clean, unique mesh name\n if (mesh.name && mesh.name.trim()) {\n const clean = mesh.name.trim()\n if (!usedIds.has(clean)) {\n usedIds.add(clean)\n return clean\n }\n }\n\n // 3. Hierarchical path fallback\n let path = mesh.name ? mesh.name.trim() : 'mesh'\n let curr: THREE.Object3D | null = mesh.parent\n while (curr && curr !== scene) {\n if (curr.name && curr.name.trim()) {\n path = `${curr.name.trim()}/${path}`\n }\n curr = curr.parent\n }\n\n let uniquePath = path\n let counter = 1\n while (usedIds.has(uniquePath)) {\n uniquePath = `${path}_${counter++}`\n }\n usedIds.add(uniquePath)\n return uniquePath\n}\n\nexport function getMeshMaterialSlots(mesh: THREE.Mesh): MeshMaterialSlot[] {\n if (Array.isArray(mesh.userData?.originalSlots) && mesh.userData.originalSlots.length > 0) {\n return mesh.userData.originalSlots\n }\n\n if (Array.isArray(mesh.material)) {\n return mesh.material.map((mat, idx) => {\n const name = mat?.name?.trim() || `Material_${idx}`\n const slotId =\n (typeof mat?.userData?.slotId === 'string' && mat.userData.slotId) ||\n `slot_${idx}_${sanitizeName(name)}`\n return {\n slotId,\n materialName: name,\n index: idx,\n }\n })\n }\n\n const mat = mesh.material as THREE.Material | null\n const name = mat?.name?.trim() || (mesh.name ? `${mesh.name}_mat` : 'default')\n const slotId =\n (typeof mat?.userData?.slotId === 'string' && mat.userData.slotId) ||\n `slot_0_${sanitizeName(name)}`\n\n return [\n {\n slotId,\n materialName: name,\n index: 0,\n },\n ]\n}\n\nfunction classifyByName(name: string, materialName: string): PartType {\n const combined = `${name} ${materialName}`\n const isStone = hasKeyword(combined, STONE_KEYWORDS)\n const isMetal = hasKeyword(combined, METAL_KEYWORDS)\n\n if (isStone) return 'stone' // stone wins when both match\n if (isMetal) return 'metal'\n return 'metal' // default\n}\n\nexport function classifyParts(\n scene: THREE.Group,\n overrides: Record<string, PartType>,\n): PartInfo[] {\n const parts: PartInfo[] = []\n const usedIds = new Set<string>()\n\n scene.traverse((obj) => {\n if (!(obj instanceof THREE.Mesh)) return\n\n const mesh = obj as THREE.Mesh\n const partId = getStablePartId(mesh, scene, usedIds)\n mesh.userData.partId = partId\n\n const slots = getMeshMaterialSlots(mesh)\n mesh.userData.originalSlots = slots\n\n const primaryMaterialName = slots[0]?.materialName ?? ''\n mesh.userData.originalMaterialName = primaryMaterialName\n\n const allMaterialNames = slots.map((s) => s.materialName).join(' ')\n\n // Support override by runtime mesh UUID or stable partId\n const isOverridden = mesh.uuid in overrides || partId in overrides\n const overriddenType = overrides[partId] ?? overrides[mesh.uuid]\n\n if (isOverridden && overriddenType) {\n parts.push({\n meshId: mesh.uuid,\n partId,\n meshName: mesh.name,\n materialName: primaryMaterialName,\n slots,\n type: overriddenType,\n overridden: true,\n })\n } else {\n parts.push({\n meshId: mesh.uuid,\n partId,\n meshName: mesh.name,\n materialName: primaryMaterialName,\n slots,\n type: classifyByName(mesh.name, allMaterialNames),\n overridden: false,\n })\n }\n })\n\n return parts\n}\n\nexport function extractMaterialSlots(parts: PartInfo[]): MaterialSlotInfo[] {\n const map = new Map<string, MaterialSlotInfo>()\n\n for (const part of parts) {\n for (const slot of part.slots) {\n const existing = map.get(slot.slotId)\n if (existing) {\n if (!existing.partIds.includes(part.partId)) {\n existing.partIds.push(part.partId)\n }\n if (!existing.meshIds.includes(part.meshId)) {\n existing.meshIds.push(part.meshId)\n }\n // Conflict rule: stone wins over metal\n if (existing.type !== 'stone' && part.type === 'stone') {\n existing.type = 'stone'\n }\n } else {\n map.set(slot.slotId, {\n slotId: slot.slotId,\n name: slot.materialName,\n type: part.type,\n partIds: [part.partId],\n meshIds: [part.meshId],\n })\n }\n }\n }\n\n return Array.from(map.values())\n}\n","// ─── Interfaces ──────────────────────────────────────────────────────────────\n\nexport interface MetalPreset {\n // Required\n id: string\n label: string\n hex: string\n metalness: number\n roughness: number\n // Optional\n category?: 'gold' | 'platinum-silver' | 'alternative'\n thumbnail?: string\n specularColor?: string\n ior?: number\n density?: number\n source?: string\n}\n\nexport interface StonePreset {\n // Required\n id: string\n label: string\n hex: string\n ior: number\n transmission: number\n roughness: number\n // Optional\n category?: 'diamond' | 'gemstone'\n thumbnail?: string\n dispersion?: number // Cauchy half-spread Delta: IOR_blue = n+Delta, IOR_red = n-Delta\n absorptionFactor?: number // Beer-Lambert coefficient in radius-normalised units\n boostFactors?: [number, number, number] // RGB radiance gain [r, g, b]\n envMapIntensity?: number // Per-stone environment intensity multiplier\n squashFactor?: number // Y-axis squash for sphere intersect (default 0.98)\n geometryFactor?: number // Geometry scale for sphere intersect (default 0.5)\n gammaFactor?: number // Pre-colorspace gamma correction (default 1.0)\n ambientFloor?: number // Ambient light floor (0.0 = pure black extinction, 0.05 = soft luminous graphite)\n attenuationColor?: string\n attenuationDistance?: number\n specularColor?: string\n grade?: string\n source?: string\n}\n\n// ─── Unified Metal Presets ────────────────────────────────────────────────────\n// Single collection containing all precious metals (physically-based, RMJ, and legacy).\n\nexport const METAL_PRESETS: MetalPreset[] = [\n // ── Physically-Based Precious Metals (physicallybased.info) ──\n { id: 'yellow-gold-18k', label: '18K Yellow Gold', hex: '#ffd566', metalness: 1.0, roughness: 0.04, category: 'gold', specularColor: '#fffdbf', density: 15500, thumbnail: '/thumbnails/yellow-gold-18k.svg' },\n { id: 'yellow-gold-14k', label: '14K Yellow Gold', hex: '#fed882', metalness: 1.0, roughness: 0.05, category: 'gold', specularColor: '#fffec9', density: 13500, thumbnail: '/thumbnails/yellow-gold-14k.svg' },\n { id: 'pure-gold-24k', label: '24K Pure Gold', hex: '#ffe496', metalness: 1.0, roughness: 0.03, category: 'gold', specularColor: '#fffdbf', density: 19320, source: 'physicallybased.info/gold', thumbnail: '/thumbnails/pure-gold-24k.svg' },\n { id: 'rose-gold-18k', label: '18K Rose Gold', hex: '#e8927c', metalness: 1.0, roughness: 0.04, category: 'gold', specularColor: '#ffd7cb', density: 15400, thumbnail: '/thumbnails/rose-gold-18k.svg' },\n { id: 'rose-gold-14k', label: '14K Rose Gold', hex: '#f1a998', metalness: 1.0, roughness: 0.05, category: 'gold', specularColor: '#ffe4db', density: 13300, thumbnail: '/thumbnails/rose-gold-14k.svg' },\n { id: 'white-gold-18k', label: '18K White Gold', hex: '#f5f6f8', metalness: 1.0, roughness: 0.03, category: 'gold', specularColor: '#ffffff', density: 15600, thumbnail: '/thumbnails/white-gold-18k.svg' },\n { id: 'platinum-950', label: 'Platinum 950', hex: '#e3ded7', metalness: 1.0, roughness: 0.04, category: 'platinum-silver', specularColor: '#edebe6', density: 21450, source: 'physicallybased.info/platinum', thumbnail: '/thumbnails/platinum-950.svg' },\n { id: 'silver-925', label: 'Sterling Silver 925', hex: '#fefdfc', metalness: 1.0, roughness: 0.05, category: 'platinum-silver', specularColor: '#ffffff', density: 10360, source: 'physicallybased.info/silver', thumbnail: '/thumbnails/silver-925.svg' },\n { id: 'titanium', label: 'Titanium', hex: '#b1aaa2', metalness: 1.0, roughness: 0.10, category: 'alternative', specularColor: '#c8c3bd', density: 4506, source: 'physicallybased.info/titanium', thumbnail: '/thumbnails/titanium.svg' },\n { id: 'black-ruthenium', label: 'Black Ruthenium', hex: '#28282c', metalness: 0.95, roughness: 0.06, category: 'alternative', specularColor: '#444448', density: 12450, thumbnail: '/thumbnails/black-ruthenium.svg' },\n\n // ── RenderMyJewelry Metals (app.rendermyjewelry.com) ──\n { id: 'rmj-custom-yellow-gold', label: 'RMJ Custom Yellow Gold', hex: '#ffc766', metalness: 1.0, roughness: 0.00, category: 'gold', specularColor: '#ffffff', ior: 1.5, source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-custom-yellow-gold.svg' },\n { id: 'rmj-custom-rose-gold', label: 'RMJ Custom Rose Gold', hex: '#ffb6a3', metalness: 1.0, roughness: 0.00, category: 'gold', specularColor: '#ffffff', ior: 1.5, source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-custom-rose-gold.svg' },\n { id: 'rmj-white-gold-polished', label: 'RMJ White Gold Polished', hex: '#c2c2c3', metalness: 1.0, roughness: 0.00, category: 'gold', specularColor: '#ffffff', ior: 1.5, source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-white-gold-polished.svg' },\n { id: 'rmj-gold-polished', label: 'RMJ Gold Polished (18K)', hex: '#e5b377', metalness: 1.0, roughness: 0.00, category: 'gold', specularColor: '#ffffff', ior: 1.5, source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-gold-polished.svg' },\n { id: 'rmj-rose-gold-polished', label: 'RMJ Rose Gold Polished', hex: '#f2af83', metalness: 1.0, roughness: 0.00, category: 'gold', specularColor: '#ffffff', ior: 1.5, source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-rose-gold-polished.svg' },\n { id: 'rmj-gold-22k', label: 'RMJ Gold 22K', hex: '#eaa958', metalness: 1.0, roughness: 0.00, category: 'gold', specularColor: '#ffffff', ior: 1.5, source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-gold-22k.svg' },\n { id: 'rmj-gold-14k', label: 'RMJ Gold 14K', hex: '#d6af80', metalness: 1.0, roughness: 0.00, category: 'gold', specularColor: '#ffffff', ior: 1.5, source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-gold-14k.svg' },\n { id: 'rmj-gold-09k', label: 'RMJ Gold 9K', hex: '#d4b38c', metalness: 1.0, roughness: 0.00, category: 'gold', specularColor: '#ffffff', ior: 1.5, source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-gold-09k.svg' },\n { id: 'rmj-silver-polished', label: 'RMJ Silver Polished', hex: '#dedede', metalness: 1.0, roughness: 0.10, category: 'platinum-silver', specularColor: '#ffffff', ior: 1.5, source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-silver-polished.svg' },\n { id: 'rmj-platinum-polished', label: 'RMJ Platinum Polished', hex: '#b9bbbc', metalness: 1.0, roughness: 0.00, category: 'platinum-silver', specularColor: '#ffffff', ior: 1.5, source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-platinum-polished.svg' },\n\n // ── Legacy Basic Metals ──\n { id: 'yellow-gold', label: 'Yellow Gold', hex: '#ffc766', metalness: 1.0, roughness: 0.06, thumbnail: '/thumbnails/yellow-gold.svg' },\n { id: 'rose-gold', label: 'Rose Gold', hex: '#ffb6a3', metalness: 1.0, roughness: 0.06, thumbnail: '/thumbnails/rose-gold.svg' },\n { id: 'white-gold', label: 'White Gold', hex: '#f0f0f0', metalness: 1.0, roughness: 0.05, thumbnail: '/thumbnails/white-gold.svg' },\n { id: 'platinum', label: 'Platinum', hex: '#e5e5e5', metalness: 1.0, roughness: 0.05, thumbnail: '/thumbnails/platinum.svg' },\n { id: 'silver', label: 'Silver', hex: '#dcdcdc', metalness: 1.0, roughness: 0.08, thumbnail: '/thumbnails/silver.svg' },\n]\n\n// ─── Unified Stone Presets ────────────────────────────────────────────────────\n// Single collection containing all stones & diamonds (physical, gemstones, RMJ, and legacy).\n\nexport const STONE_PRESETS: StonePreset[] = [\n // ── Diamonds (GIA & Fancy Color Spectrum, IOR 2.417) ──\n { id: 'diamond-d', label: 'White Diamond', hex: '#ffffff', ior: 2.417, transmission: 0.98, roughness: 0.0, category: 'diamond', grade: 'D-F Colorless', dispersion: 0.024, absorptionFactor: 0.00, ambientFloor: 0.05, source: 'physicallybased.info/diamond', thumbnail: '/thumbnails/diamond-d.svg' },\n { id: 'diamond-gh', label: 'Near Colorless Diamond', hex: '#fbf9f5', ior: 2.417, transmission: 0.97, roughness: 0.0, category: 'diamond', grade: 'G-H Near Colorless', dispersion: 0.012, absorptionFactor: 0.00, ambientFloor: 0.05, thumbnail: '/thumbnails/diamond-gh.svg' },\n { id: 'diamond-fancy-yellow', label: 'Yellow Diamond', hex: '#fdd835', ior: 2.417, transmission: 0.95, roughness: 0.0, category: 'diamond', grade: 'Fancy Yellow', dispersion: 0.010, absorptionFactor: 0.11, thumbnail: '/thumbnails/diamond-fancy-yellow.svg' },\n { id: 'diamond-fancy-pink', label: 'Pink Diamond', hex: '#f472b6', ior: 2.417, transmission: 0.94, roughness: 0.0, category: 'diamond', grade: 'Fancy Pink', dispersion: 0.010, absorptionFactor: 0.14, thumbnail: '/thumbnails/diamond-fancy-pink.svg' },\n { id: 'diamond-fancy-blue', label: 'Blue Diamond', hex: '#38bdf8', ior: 2.417, transmission: 0.94, roughness: 0.0, category: 'diamond', grade: 'Fancy Blue', dispersion: 0.010, absorptionFactor: 0.14, thumbnail: '/thumbnails/diamond-fancy-blue.svg' },\n { id: 'diamond-fancy-green', label: 'Green Diamond', hex: '#34d399', ior: 2.417, transmission: 0.94, roughness: 0.0, category: 'diamond', grade: 'Fancy Green', dispersion: 0.010, absorptionFactor: 0.14, thumbnail: '/thumbnails/diamond-fancy-green.svg' },\n { id: 'diamond-fancy-champagne', label: 'Champagne Diamond', hex: '#c28b51', ior: 2.417, transmission: 0.93, roughness: 0.0, category: 'diamond', grade: 'Fancy Champagne', dispersion: 0.010, absorptionFactor: 0.18, thumbnail: '/thumbnails/diamond-fancy-champagne.svg' },\n { id: 'diamond-fancy-black', label: 'Black Diamond', hex: '#151515', ior: 2.417, transmission: 0.00, roughness: 0.05, category: 'diamond', grade: 'Fancy Black', dispersion: 0.000, absorptionFactor: 0.00, thumbnail: '/thumbnails/diamond-fancy-black.svg' },\n\n // ── Colored Gemstones ──\n { id: 'ruby', label: 'Ruby', hex: '#e14276', ior: 1.770, transmission: 0.88, roughness: 0.03, category: 'gemstone', dispersion: 0.000, absorptionFactor: 0.50, thumbnail: '/thumbnails/ruby.svg' },\n { id: 'sapphire', label: 'Sapphire', hex: '#1a4fb4', ior: 1.770, transmission: 0.88, roughness: 0.03, category: 'gemstone', dispersion: 0.000, absorptionFactor: 0.45, source: 'physicallybased.info/sapphire', thumbnail: '/thumbnails/sapphire.svg' },\n { id: 'emerald', label: 'Emerald', hex: '#20cc95', ior: 1.580, transmission: 0.90, roughness: 0.04, category: 'gemstone', dispersion: 0.000, absorptionFactor: 0.40, thumbnail: '/thumbnails/emerald.svg' },\n { id: 'aquamarine', label: 'Aquamarine', hex: '#5eead4', ior: 1.577, transmission: 0.94, roughness: 0.00, category: 'gemstone', dispersion: 0.000, absorptionFactor: 0.10, thumbnail: '/thumbnails/aquamarine.svg' },\n { id: 'amethyst', label: 'Amethyst', hex: '#9333ea', ior: 1.544, transmission: 0.91, roughness: 0.00, category: 'gemstone', dispersion: 0.000, absorptionFactor: 0.35, source: 'physicallybased.info/quartz', thumbnail: '/thumbnails/amethyst.svg' },\n { id: 'tanzanite', label: 'Tanzanite', hex: '#6366f1', ior: 1.691, transmission: 0.90, roughness: 0.00, category: 'gemstone', dispersion: 0.000, absorptionFactor: 0.42, thumbnail: '/thumbnails/tanzanite.svg' },\n\n // ── RenderMyJewelry Gems (app.rendermyjewelry.com) ──\n { id: 'rmj-diamond-d-colorless', label: 'RMJ Diamond D Colorless', hex: '#ececec', ior: 2.400, transmission: 0.98, roughness: 0.0, category: 'diamond', dispersion: 0.004, absorptionFactor: 1.0, boostFactors: [2.0, 2.0, 2.0], source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-diamond-d-colorless.svg' },\n { id: 'rmj-ruby-1', label: 'RMJ Ruby 1', hex: '#e14276', ior: 1.770, transmission: 0.88, roughness: 0.0, category: 'gemstone', dispersion: 0.000, absorptionFactor: 1.6, boostFactors: [1.3, 0.16, 0.9], source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-ruby-1.svg' },\n { id: 'rmj-emerald-1', label: 'RMJ Emerald 1', hex: '#20cc95', ior: 1.577, transmission: 0.90, roughness: 0.0, category: 'gemstone', dispersion: 0.012, absorptionFactor: 1.0, boostFactors: [0.892, 0.892, 0.986], source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-emerald-1.svg' },\n { id: 'rmj-sapphire-cabachon-2', label: 'RMJ Sapphire Cabochon 2', hex: '#45b1e1', ior: 1.660, transmission: 0.88, roughness: 0.0, category: 'gemstone', dispersion: 0.000, absorptionFactor: 2.51, boostFactors: [1.0, 1.0, 1.0], source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-sapphire-cabachon-2.svg' },\n { id: 'rmj-diamond-pink-2', label: 'RMJ Diamond Pink 2', hex: '#f1bcd5', ior: 2.600, transmission: 0.94, roughness: 0.0, category: 'diamond', dispersion: 0.012, absorptionFactor: 1.0, boostFactors: [1.3, 1.0, 1.0], source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-diamond-pink-2.svg' },\n { id: 'rmj-diamond-yellow-2', label: 'RMJ Diamond Yellow 2', hex: '#fce88c', ior: 2.600, transmission: 0.94, roughness: 0.0, category: 'diamond', dispersion: 0.012, absorptionFactor: 1.3, boostFactors: [1.0, 1.0, 1.0], source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-diamond-yellow-2.svg' },\n { id: 'rmj-diamond-blue-2', label: 'RMJ Diamond Blue 2', hex: '#80c9fc', ior: 2.600, transmission: 0.94, roughness: 0.0, category: 'diamond', dispersion: 0.013, absorptionFactor: 1.0, boostFactors: [0.9, 1.0, 1.0], source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-diamond-blue-2.svg' },\n\n // ── Legacy Aliases ──\n { id: 'diamond', label: 'White Diamond', hex: '#ffffff', ior: 2.417, transmission: 0.95, roughness: 0.02, dispersion: 0.012, absorptionFactor: 0.00, ambientFloor: 0.05, thumbnail: '/thumbnails/diamond-d.svg' },\n { id: 'yellow-diamond', label: 'Yellow Diamond', hex: '#fcd34d', ior: 2.420, transmission: 0.94, roughness: 0.02, dispersion: 0.010, absorptionFactor: 0.11, thumbnail: '/thumbnails/diamond-fancy-yellow.svg' },\n { id: 'pink-diamond', label: 'Pink Diamond', hex: '#f472b6', ior: 2.420, transmission: 0.94, roughness: 0.02, dispersion: 0.010, absorptionFactor: 0.14, thumbnail: '/thumbnails/diamond-fancy-pink.svg' },\n { id: 'blue-diamond', label: 'Blue Diamond', hex: '#60a5fa', ior: 2.420, transmission: 0.94, roughness: 0.02, dispersion: 0.010, absorptionFactor: 0.14, thumbnail: '/thumbnails/diamond-fancy-blue.svg' },\n { id: 'black-diamond', label: 'Black Diamond', hex: '#1a1a1a', ior: 2.420, transmission: 0.00, roughness: 0.05, dispersion: 0.000, absorptionFactor: 0.00, thumbnail: '/thumbnails/diamond-fancy-black.svg' },\n]\n\n// ─── Convenience Subsets & Aliases ────────────────────────────────────────────\n// Derived views from the master single arrays for backwards compatibility.\n\nexport const ALL_METAL_PRESETS: MetalPreset[] = METAL_PRESETS\nexport const ALL_STONE_PRESETS: StonePreset[] = STONE_PRESETS\n\nexport const PHYSICALLY_BASED_METAL_PRESETS: MetalPreset[] = METAL_PRESETS.filter(\n (m) => m.category !== undefined && !m.id.startsWith('rmj-')\n)\nexport const RENDERMYJEWELRY_METALS: MetalPreset[] = METAL_PRESETS.filter(\n (m) => m.id.startsWith('rmj-')\n)\n\nexport const DIAMOND_PRESETS: StonePreset[] = STONE_PRESETS.filter(\n (s) => s.category === 'diamond' && !s.id.startsWith('rmj-') && s.id.startsWith('diamond-')\n)\nexport const GEMSTONE_PRESETS: StonePreset[] = STONE_PRESETS.filter(\n (s) => s.category === 'gemstone' && !s.id.startsWith('rmj-')\n)\nexport const RENDERMYJEWELRY_GEMS: StonePreset[] = STONE_PRESETS.filter(\n (s) => s.id.startsWith('rmj-')\n)\n\n// ─── Canonical Presets (No Legacy Duplicates) ─────────────────────────────────\nconst LEGACY_METAL_ALIAS_IDS = new Set(['yellow-gold', 'rose-gold', 'white-gold', 'platinum', 'silver'])\nconst LEGACY_STONE_ALIAS_IDS = new Set(['diamond', 'yellow-diamond', 'pink-diamond', 'blue-diamond', 'black-diamond'])\n\nexport const CANONICAL_METAL_PRESETS: MetalPreset[] = METAL_PRESETS.filter(\n (m) => !LEGACY_METAL_ALIAS_IDS.has(m.id)\n)\n\nexport const CANONICAL_STONE_PRESETS: StonePreset[] = STONE_PRESETS.filter(\n (s) => !LEGACY_STONE_ALIAS_IDS.has(s.id)\n)\n\n// ─── Autocomplete-Friendly Types ──────────────────────────────────────────────\nexport type StandardMetalId =\n | 'yellow-gold-18k'\n | 'yellow-gold-14k'\n | 'pure-gold-24k'\n | 'rose-gold-18k'\n | 'rose-gold-14k'\n | 'white-gold-18k'\n | 'platinum-950'\n | 'silver-925'\n | 'titanium'\n | 'black-ruthenium'\n | 'rmj-custom-yellow-gold'\n | 'rmj-custom-rose-gold'\n | 'rmj-white-gold-polished'\n | 'rmj-gold-polished'\n | 'rmj-rose-gold-polished'\n | 'rmj-gold-22k'\n | 'rmj-gold-14k'\n | 'rmj-gold-09k'\n | 'rmj-silver-polished'\n | 'rmj-platinum-polished'\n | 'yellow-gold'\n | 'rose-gold'\n | 'white-gold'\n | 'platinum'\n | 'silver'\n\nexport type StandardStoneId =\n | 'diamond-d'\n | 'diamond-gh'\n | 'diamond-fancy-yellow'\n | 'diamond-fancy-pink'\n | 'diamond-fancy-blue'\n | 'diamond-fancy-green'\n | 'diamond-fancy-champagne'\n | 'diamond-fancy-black'\n | 'ruby'\n | 'sapphire'\n | 'emerald'\n | 'aquamarine'\n | 'amethyst'\n | 'tanzanite'\n | 'rmj-diamond-d-colorless'\n | 'rmj-ruby-1'\n | 'rmj-emerald-1'\n | 'rmj-sapphire-cabachon-2'\n | 'rmj-diamond-pink-2'\n | 'rmj-diamond-yellow-2'\n | 'rmj-diamond-blue-2'\n | 'diamond'\n | 'yellow-diamond'\n | 'pink-diamond'\n | 'blue-diamond'\n | 'black-diamond'\n\n/**\n * Autocomplete-friendly metal color type. Suggests canonical preset IDs while allowing arbitrary hex codes.\n */\nexport type MetalColorProp = StandardMetalId | (string & {})\n\n/**\n * Autocomplete-friendly stone color type. Suggests canonical preset IDs while allowing arbitrary hex codes.\n */\nexport type StoneColorProp = StandardStoneId | (string & {})\n\n// ─── Lookup Helpers ───────────────────────────────────────────────────────────\nexport function getMetalPreset(idOrHex: string): MetalPreset | undefined {\n if (!idOrHex) return undefined\n const query = idOrHex.toLowerCase().trim()\n return METAL_PRESETS.find((m) => m.id.toLowerCase() === query || m.hex.toLowerCase() === query)\n}\n\nexport function getStonePreset(idOrHex: string): StonePreset | undefined {\n if (!idOrHex) return undefined\n const query = idOrHex.toLowerCase().trim()\n return STONE_PRESETS.find((s) => s.id.toLowerCase() === query || s.hex.toLowerCase() === query)\n}\n","import * as THREE from 'three'\n\nexport interface GemAnalysis {\n centroid: THREE.Vector3\n radius: number\n triangleCount: number\n starConvexFailureArea: number\n isBakeable: boolean\n flippedWinding: boolean\n}\n\nexport interface BakeHandle {\n key: string\n texture: THREE.CubeTexture\n centroid: THREE.Vector3\n radius: number\n encoding: 'signed' | 'unorm'\n bvh?: any\n}\n\nconst hashMap = new WeakMap<THREE.BufferGeometry, string>()\n\nexport function analyzeGeometry(g: THREE.BufferGeometry): GemAnalysis {\n if (!g.boundingSphere) {\n g.computeBoundingSphere()\n }\n const centroid = g.boundingSphere?.center ? g.boundingSphere.center.clone() : new THREE.Vector3()\n const rawRadius = g.boundingSphere?.radius ?? 1.0\n const radius = Math.max(rawRadius, 0.01)\n\n const posAttr = g.getAttribute('position')\n if (!posAttr || posAttr.count === 0) {\n return {\n centroid,\n radius,\n triangleCount: 0,\n starConvexFailureArea: 1.0,\n isBakeable: false,\n flippedWinding: false,\n }\n }\n\n const index = g.getIndex()\n const triangleCount = index ? index.count / 3 : posAttr.count / 3\n\n let totalArea = 0\n let failureArea = 0\n let signedVolume = 0\n\n const p0 = new THREE.Vector3()\n const p1 = new THREE.Vector3()\n const p2 = new THREE.Vector3()\n const e1 = new THREE.Vector3()\n const e2 = new THREE.Vector3()\n const normal = new THREE.Vector3()\n const crossP1P2 = new THREE.Vector3()\n\n for (let i = 0; i < triangleCount; i++) {\n const i0 = index ? index.getX(i * 3) : i * 3\n const i1 = index ? index.getX(i * 3 + 1) : i * 3 + 1\n const i2 = index ? index.getX(i * 3 + 2) : i * 3 + 2\n\n p0.fromBufferAttribute(posAttr, i0).sub(centroid).divideScalar(radius)\n p1.fromBufferAttribute(posAttr, i1).sub(centroid).divideScalar(radius)\n p2.fromBufferAttribute(posAttr, i2).sub(centroid).divideScalar(radius)\n\n e1.subVectors(p1, p0)\n e2.subVectors(p2, p0)\n normal.crossVectors(e1, e2)\n const doubleArea = normal.length()\n if (doubleArea < 1e-12) continue\n\n const area = doubleArea * 0.5\n totalArea += area\n\n normal.divideScalar(doubleArea)\n const D = p0.dot(normal)\n\n // Signed volume contribution: dot(p0, cross(p1, p2)) / 6\n crossP1P2.crossVectors(p1, p2)\n signedVolume += p0.dot(crossP1P2) / 6.0\n\n if (D <= 1e-4) {\n failureArea += area\n }\n }\n\n const starConvexFailureArea = totalArea > 0 ? failureArea / totalArea : 1.0\n const flippedWinding = signedVolume < 0\n\n return {\n centroid,\n radius,\n triangleCount,\n starConvexFailureArea,\n isBakeable: starConvexFailureArea <= 0.005 && !isNaN(totalArea) && totalArea > 0,\n flippedWinding,\n }\n}\n\nexport function buildFacetAttribute(g: THREE.BufferGeometry, a: GemAnalysis): Float32Array {\n const nonIndexed = g.getIndex() ? g.toNonIndexed() : g.clone()\n const posAttr = nonIndexed.getAttribute('position')\n const vertexCount = posAttr.count\n const facetData = new Float32Array(vertexCount * 4)\n\n const p0 = new THREE.Vector3()\n const p1 = new THREE.Vector3()\n const p2 = new THREE.Vector3()\n const e1 = new THREE.Vector3()\n const e2 = new THREE.Vector3()\n const normal = new THREE.Vector3()\n\n const windingSign = a.flippedWinding ? -1 : 1\n\n for (let i = 0; i < vertexCount; i += 3) {\n p0.fromBufferAttribute(posAttr, i).sub(a.centroid).divideScalar(a.radius)\n p1.fromBufferAttribute(posAttr, i + 1).sub(a.centroid).divideScalar(a.radius)\n p2.fromBufferAttribute(posAttr, i + 2).sub(a.centroid).divideScalar(a.radius)\n\n e1.subVectors(p1, p0)\n e2.subVectors(p2, p0)\n normal.crossVectors(e1, e2).multiplyScalar(windingSign)\n\n const len = normal.length()\n if (len > 1e-12) {\n normal.divideScalar(len)\n } else {\n normal.set(0, 1, 0)\n }\n\n const D = p0.dot(normal)\n\n for (let v = 0; v < 3; v++) {\n const idx = (i + v) * 4\n facetData[idx] = normal.x\n facetData[idx + 1] = normal.y\n facetData[idx + 2] = normal.z\n facetData[idx + 3] = D\n }\n }\n\n return facetData\n}\n\nexport function hashGeometry(g: THREE.BufferGeometry, a: GemAnalysis): string {\n const cached = hashMap.get(g)\n if (cached) return cached\n\n const posAttr = g.getAttribute('position')\n const index = g.getIndex()\n let hash = 0x811c9dc5 // FNV-1a 32-bit offset basis\n\n const fnv1a = (val: number) => {\n hash ^= val & 0xff\n hash = Math.imul(hash, 0x01000193)\n hash ^= (val >> 8) & 0xff\n hash = Math.imul(hash, 0x01000193)\n hash ^= (val >> 16) & 0xff\n hash = Math.imul(hash, 0x01000193)\n hash ^= (val >> 24) & 0xff\n hash = Math.imul(hash, 0x01000193)\n }\n\n fnv1a(a.triangleCount)\n if (index) {\n for (let i = 0; i < index.count; i++) {\n fnv1a(index.getX(i))\n }\n }\n\n const p = new THREE.Vector3()\n for (let i = 0; i < posAttr.count; i++) {\n p.fromBufferAttribute(posAttr, i).sub(a.centroid).divideScalar(a.radius)\n fnv1a(Math.round(p.x * 10000))\n fnv1a(Math.round(p.y * 10000))\n fnv1a(Math.round(p.z * 10000))\n }\n\n const result = (hash >>> 0).toString(16)\n hashMap.set(g, result)\n return result\n}\n","// Split strategy constants\n\n/**\n * Option for splitting each BVH node down the center of the longest axis of the bounds.\n *\n * This is the fastest construction option and will yield a good, performant bounds.\n * @type {number}\n */\nexport const CENTER = 0;\n\n/**\n * Option for splitting each BVH node at the average point along the longest axis for\n * all triangle centroids in the bounds.\n *\n * This strategy may be better than `CENTER` with some geometry.\n * @type {number}\n */\nexport const AVERAGE = 1;\n\n/**\n * Option to use a Surface Area Heuristic to split the bounds more optimally. This SAH\n * implementation tests 32 discrete splits in each node along each axis to determine\n * which split is the lowest cost.\n *\n * This is the slowest construction option but will yield the best bounds of the three\n * options and use the least memory.\n * @type {number}\n */\nexport const SAH = 2;\n\n// Traversal constants\n\n/**\n * Indicates the shape did not intersect the given bounding box.\n * @type {number}\n */\nexport const NOT_INTERSECTED = 0;\n\n/**\n * Indicates the shape did intersect the given bounding box.\n * @type {number}\n */\nexport const INTERSECTED = 1;\n\n/**\n * Indicate the shape entirely contains the given bounding box.\n * @type {number}\n */\nexport const CONTAINED = 2;\n\n// SAH cost constants\n// TODO: hone these costs more. The relative difference between them should be the\n// difference in measured time to perform a primitive intersection vs traversing\n// bounds.\n// TODO: could be tuned per primitive type (triangles vs lines vs points)\nexport const PRIMITIVE_INTERSECT_COST = 1.25;\nexport const TRAVERSAL_COST = 1;\n\n\n// Build constants\nexport const BYTES_PER_NODE = 6 * 4 + 4 + 4;\nexport const UINT32_PER_NODE = BYTES_PER_NODE / 4;\nexport const IS_LEAFNODE_FLAG = 0xFFFF;\n\n// Bit masks for 32 bit node data\nexport const LEAFNODE_MASK_32 = IS_LEAFNODE_FLAG << 16;\n\n// EPSILON for computing floating point error during build\n// https://en.wikipedia.org/wiki/Machine_epsilon#Values_for_standard_hardware_floating_point_arithmetics\nexport const FLOAT32_EPSILON = Math.pow( 2, - 24 );\n\nexport const SKIP_GENERATION = Symbol( 'SKIP_GENERATION' );\n\nexport const DEFAULT_OPTIONS = {\n\tstrategy: CENTER,\n\tmaxDepth: 40,\n\ttargetLeafSize: 10,\n\tuseSharedArrayBuffer: false,\n\tsetBoundingBox: true,\n\tonProgress: null,\n\tindirect: false,\n\tverbose: true,\n\trange: null,\n\t[ SKIP_GENERATION ]: false,\n};\n\n","export function arrayToBox( nodeIndex32, array, target ) {\n\n\ttarget.min.x = array[ nodeIndex32 ];\n\ttarget.min.y = array[ nodeIndex32 + 1 ];\n\ttarget.min.z = array[ nodeIndex32 + 2 ];\n\n\ttarget.max.x = array[ nodeIndex32 + 3 ];\n\ttarget.max.y = array[ nodeIndex32 + 4 ];\n\ttarget.max.z = array[ nodeIndex32 + 5 ];\n\n\treturn target;\n\n}\n\nexport function makeEmptyBounds( target ) {\n\n\ttarget[ 0 ] = target[ 1 ] = target[ 2 ] = Infinity;\n\ttarget[ 3 ] = target[ 4 ] = target[ 5 ] = - Infinity;\n\n}\n\nexport function getLongestEdgeIndex( bounds ) {\n\n\tlet splitDimIdx = - 1;\n\tlet splitDist = - Infinity;\n\n\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\tconst dist = bounds[ i + 3 ] - bounds[ i ];\n\t\tif ( dist > splitDist ) {\n\n\t\t\tsplitDist = dist;\n\t\t\tsplitDimIdx = i;\n\n\t\t}\n\n\t}\n\n\treturn splitDimIdx;\n\n}\n\n// copies bounds a into bounds b\nexport function copyBounds( source, target ) {\n\n\ttarget.set( source );\n\n}\n\n// sets bounds target to the union of bounds a and b\nexport function unionBounds( a, b, target ) {\n\n\tlet aVal, bVal;\n\tfor ( let d = 0; d < 3; d ++ ) {\n\n\t\tconst d3 = d + 3;\n\n\t\t// set the minimum values\n\t\taVal = a[ d ];\n\t\tbVal = b[ d ];\n\t\ttarget[ d ] = aVal < bVal ? aVal : bVal;\n\n\t\t// set the max values\n\t\taVal = a[ d3 ];\n\t\tbVal = b[ d3 ];\n\t\ttarget[ d3 ] = aVal > bVal ? aVal : bVal;\n\n\t}\n\n}\n\n// expands the given bounds by the provided primitive bounds\nexport function expandByPrimitiveBounds( startIndex, primitiveBounds, bounds ) {\n\n\tfor ( let d = 0; d < 3; d ++ ) {\n\n\t\tconst tCenter = primitiveBounds[ startIndex + 2 * d ];\n\t\tconst tHalf = primitiveBounds[ startIndex + 2 * d + 1 ];\n\n\t\tconst tMin = tCenter - tHalf;\n\t\tconst tMax = tCenter + tHalf;\n\n\t\tif ( tMin < bounds[ d ] ) {\n\n\t\t\tbounds[ d ] = tMin;\n\n\t\t}\n\n\t\tif ( tMax > bounds[ d + 3 ] ) {\n\n\t\t\tbounds[ d + 3 ] = tMax;\n\n\t\t}\n\n\t}\n\n}\n\n// compute bounds surface area\nexport function computeSurfaceArea( bounds ) {\n\n\tconst d0 = bounds[ 3 ] - bounds[ 0 ];\n\tconst d1 = bounds[ 4 ] - bounds[ 1 ];\n\tconst d2 = bounds[ 5 ] - bounds[ 2 ];\n\n\treturn 2 * ( d0 * d1 + d1 * d2 + d2 * d0 );\n\n}\n","import { IS_LEAFNODE_FLAG, UINT32_PER_NODE } from '../Constants.js';\n\nexport function IS_LEAF( n16, uint16Array ) {\n\n\treturn uint16Array[ n16 + 15 ] === IS_LEAFNODE_FLAG;\n\n}\n\nexport function OFFSET( n32, uint32Array ) {\n\n\treturn uint32Array[ n32 + 6 ];\n\n}\n\nexport function COUNT( n16, uint16Array ) {\n\n\treturn uint16Array[ n16 + 14 ];\n\n}\n\n// Returns the uint32-aligned offset of the left child node for performance\nexport function LEFT_NODE( n32 ) {\n\n\treturn n32 + UINT32_PER_NODE;\n\n}\n\n// Returns the uint32-aligned offset of the right child node for performance\nexport function RIGHT_NODE( n32, uint32Array ) {\n\n\t// stored value is relative offset from parent, convert to absolute uint32 index\n\tconst relativeOffset = uint32Array[ n32 + 6 ];\n\treturn n32 + relativeOffset * UINT32_PER_NODE;\n\n}\n\nexport function SPLIT_AXIS( n32, uint32Array ) {\n\n\treturn uint32Array[ n32 + 7 ];\n\n}\n\nexport function BOUNDING_DATA_INDEX( n32 ) {\n\n\treturn n32;\n\n}\n","// computes the union of the bounds of all of the given primitives and puts the resulting box in \"target\".\n// A bounding box is computed for the centroids of the primitives, as well, and placed in \"centroidTarget\".\n// These are computed together to avoid redundant accesses to bounds array.\nexport function getBounds( primitiveBounds, offset, count, target, centroidTarget ) {\n\n\tlet minx = Infinity;\n\tlet miny = Infinity;\n\tlet minz = Infinity;\n\tlet maxx = - Infinity;\n\tlet maxy = - Infinity;\n\tlet maxz = - Infinity;\n\n\tlet cminx = Infinity;\n\tlet cminy = Infinity;\n\tlet cminz = Infinity;\n\tlet cmaxx = - Infinity;\n\tlet cmaxy = - Infinity;\n\tlet cmaxz = - Infinity;\n\n\tconst boundsOffset = primitiveBounds.offset || 0;\n\tfor ( let i = ( offset - boundsOffset ) * 6, end = ( offset + count - boundsOffset ) * 6; i < end; i += 6 ) {\n\n\t\tconst cx = primitiveBounds[ i + 0 ];\n\t\tconst hx = primitiveBounds[ i + 1 ];\n\t\tconst lx = cx - hx;\n\t\tconst rx = cx + hx;\n\t\tif ( lx < minx ) minx = lx;\n\t\tif ( rx > maxx ) maxx = rx;\n\t\tif ( cx < cminx ) cminx = cx;\n\t\tif ( cx > cmaxx ) cmaxx = cx;\n\n\t\tconst cy = primitiveBounds[ i + 2 ];\n\t\tconst hy = primitiveBounds[ i + 3 ];\n\t\tconst ly = cy - hy;\n\t\tconst ry = cy + hy;\n\t\tif ( ly < miny ) miny = ly;\n\t\tif ( ry > maxy ) maxy = ry;\n\t\tif ( cy < cminy ) cminy = cy;\n\t\tif ( cy > cmaxy ) cmaxy = cy;\n\n\t\tconst cz = primitiveBounds[ i + 4 ];\n\t\tconst hz = primitiveBounds[ i + 5 ];\n\t\tconst lz = cz - hz;\n\t\tconst rz = cz + hz;\n\t\tif ( lz < minz ) minz = lz;\n\t\tif ( rz > maxz ) maxz = rz;\n\t\tif ( cz < cminz ) cminz = cz;\n\t\tif ( cz > cmaxz ) cmaxz = cz;\n\n\t}\n\n\ttarget[ 0 ] = minx;\n\ttarget[ 1 ] = miny;\n\ttarget[ 2 ] = minz;\n\n\ttarget[ 3 ] = maxx;\n\ttarget[ 4 ] = maxy;\n\ttarget[ 5 ] = maxz;\n\n\tcentroidTarget[ 0 ] = cminx;\n\tcentroidTarget[ 1 ] = cminy;\n\tcentroidTarget[ 2 ] = cminz;\n\n\tcentroidTarget[ 3 ] = cmaxx;\n\tcentroidTarget[ 4 ] = cmaxy;\n\tcentroidTarget[ 5 ] = cmaxz;\n\n}\n","import { getLongestEdgeIndex, computeSurfaceArea, copyBounds, unionBounds, expandByPrimitiveBounds } from '../../utils/ArrayBoxUtilities.js';\nimport { CENTER, AVERAGE, SAH, PRIMITIVE_INTERSECT_COST, TRAVERSAL_COST } from '../Constants.js';\n\nconst BIN_COUNT = 32;\nconst binsSort = ( a, b ) => a.candidate - b.candidate;\nconst sahBins = /* @__PURE__ */ new Array( BIN_COUNT ).fill().map( () => {\n\n\treturn {\n\n\t\tcount: 0,\n\t\tbounds: new Float32Array( 6 ),\n\t\trightCacheBounds: new Float32Array( 6 ),\n\t\tleftCacheBounds: new Float32Array( 6 ),\n\t\tcandidate: 0,\n\n\t};\n\n} );\nconst leftBounds = /* @__PURE__ */ new Float32Array( 6 );\n\nexport function getOptimalSplit( nodeBoundingData, centroidBoundingData, primitiveBounds, offset, count, strategy ) {\n\n\tlet axis = - 1;\n\tlet pos = 0;\n\n\t// Center\n\tif ( strategy === CENTER ) {\n\n\t\taxis = getLongestEdgeIndex( centroidBoundingData );\n\t\tif ( axis !== - 1 ) {\n\n\t\t\tpos = ( centroidBoundingData[ axis ] + centroidBoundingData[ axis + 3 ] ) / 2;\n\n\t\t}\n\n\t} else if ( strategy === AVERAGE ) {\n\n\t\taxis = getLongestEdgeIndex( nodeBoundingData );\n\t\tif ( axis !== - 1 ) {\n\n\t\t\tpos = getAverage( primitiveBounds, offset, count, axis );\n\n\t\t}\n\n\t} else if ( strategy === SAH ) {\n\n\t\tconst rootSurfaceArea = computeSurfaceArea( nodeBoundingData );\n\t\tlet bestCost = PRIMITIVE_INTERSECT_COST * count;\n\n\t\t// iterate over all axes\n\t\tconst boundsOffset = primitiveBounds.offset || 0;\n\t\tconst cStart = ( offset - boundsOffset ) * 6;\n\t\tconst cEnd = ( offset + count - boundsOffset ) * 6;\n\t\tfor ( let a = 0; a < 3; a ++ ) {\n\n\t\t\tconst axisLeft = centroidBoundingData[ a ];\n\t\t\tconst axisRight = centroidBoundingData[ a + 3 ];\n\t\t\tconst axisLength = axisRight - axisLeft;\n\t\t\tconst binWidth = axisLength / BIN_COUNT;\n\n\t\t\t// If we have fewer primitives than we're planning to split then just check all\n\t\t\t// the primitive positions because it will be faster.\n\t\t\tif ( count < BIN_COUNT / 4 ) {\n\n\t\t\t\t// initialize the bin candidates\n\t\t\t\tconst truncatedBins = [ ...sahBins ];\n\t\t\t\ttruncatedBins.length = count;\n\n\t\t\t\t// set the candidates\n\t\t\t\tlet b = 0;\n\t\t\t\tfor ( let c = cStart; c < cEnd; c += 6, b ++ ) {\n\n\t\t\t\t\tconst bin = truncatedBins[ b ];\n\t\t\t\t\tbin.candidate = primitiveBounds[ c + 2 * a ];\n\t\t\t\t\tbin.count = 0;\n\n\t\t\t\t\tconst {\n\t\t\t\t\t\tbounds,\n\t\t\t\t\t\tleftCacheBounds,\n\t\t\t\t\t\trightCacheBounds,\n\t\t\t\t\t} = bin;\n\t\t\t\t\tfor ( let d = 0; d < 3; d ++ ) {\n\n\t\t\t\t\t\trightCacheBounds[ d ] = Infinity;\n\t\t\t\t\t\trightCacheBounds[ d + 3 ] = - Infinity;\n\n\t\t\t\t\t\tleftCacheBounds[ d ] = Infinity;\n\t\t\t\t\t\tleftCacheBounds[ d + 3 ] = - Infinity;\n\n\t\t\t\t\t\tbounds[ d ] = Infinity;\n\t\t\t\t\t\tbounds[ d + 3 ] = - Infinity;\n\n\t\t\t\t\t}\n\n\t\t\t\t\texpandByPrimitiveBounds( c, primitiveBounds, bounds );\n\n\t\t\t\t}\n\n\t\t\t\ttruncatedBins.sort( binsSort );\n\n\t\t\t\t// remove redundant splits\n\t\t\t\tlet splitCount = count;\n\t\t\t\tfor ( let bi = 0; bi < splitCount; bi ++ ) {\n\n\t\t\t\t\tconst bin = truncatedBins[ bi ];\n\t\t\t\t\twhile ( bi + 1 < splitCount && truncatedBins[ bi + 1 ].candidate === bin.candidate ) {\n\n\t\t\t\t\t\ttruncatedBins.splice( bi + 1, 1 );\n\t\t\t\t\t\tsplitCount --;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// find the appropriate bin for each primitive and expand the bounds.\n\t\t\t\tfor ( let c = cStart; c < cEnd; c += 6 ) {\n\n\t\t\t\t\tconst center = primitiveBounds[ c + 2 * a ];\n\t\t\t\t\tfor ( let bi = 0; bi < splitCount; bi ++ ) {\n\n\t\t\t\t\t\tconst bin = truncatedBins[ bi ];\n\t\t\t\t\t\tif ( center >= bin.candidate ) {\n\n\t\t\t\t\t\t\texpandByPrimitiveBounds( c, primitiveBounds, bin.rightCacheBounds );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\texpandByPrimitiveBounds( c, primitiveBounds, bin.leftCacheBounds );\n\t\t\t\t\t\t\tbin.count ++;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// expand all the bounds\n\t\t\t\tfor ( let bi = 0; bi < splitCount; bi ++ ) {\n\n\t\t\t\t\tconst bin = truncatedBins[ bi ];\n\t\t\t\t\tconst leftCount = bin.count;\n\t\t\t\t\tconst rightCount = count - bin.count;\n\n\t\t\t\t\t// check the cost of this split\n\t\t\t\t\tconst leftBounds = bin.leftCacheBounds;\n\t\t\t\t\tconst rightBounds = bin.rightCacheBounds;\n\n\t\t\t\t\tlet leftProb = 0;\n\t\t\t\t\tif ( leftCount !== 0 ) {\n\n\t\t\t\t\t\tleftProb = computeSurfaceArea( leftBounds ) / rootSurfaceArea;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tlet rightProb = 0;\n\t\t\t\t\tif ( rightCount !== 0 ) {\n\n\t\t\t\t\t\trightProb = computeSurfaceArea( rightBounds ) / rootSurfaceArea;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tconst cost = TRAVERSAL_COST + PRIMITIVE_INTERSECT_COST * (\n\t\t\t\t\t\tleftProb * leftCount + rightProb * rightCount\n\t\t\t\t\t);\n\n\t\t\t\t\tif ( cost < bestCost ) {\n\n\t\t\t\t\t\taxis = a;\n\t\t\t\t\t\tbestCost = cost;\n\t\t\t\t\t\tpos = bin.candidate;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// reset the bins\n\t\t\t\tfor ( let i = 0; i < BIN_COUNT; i ++ ) {\n\n\t\t\t\t\tconst bin = sahBins[ i ];\n\t\t\t\t\tbin.count = 0;\n\t\t\t\t\tbin.candidate = axisLeft + binWidth + i * binWidth;\n\n\t\t\t\t\tconst bounds = bin.bounds;\n\t\t\t\t\tfor ( let d = 0; d < 3; d ++ ) {\n\n\t\t\t\t\t\tbounds[ d ] = Infinity;\n\t\t\t\t\t\tbounds[ d + 3 ] = - Infinity;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// iterate over all center positions\n\t\t\t\tfor ( let c = cStart; c < cEnd; c += 6 ) {\n\n\t\t\t\t\tconst triCenter = primitiveBounds[ c + 2 * a ];\n\t\t\t\t\tconst relativeCenter = triCenter - axisLeft;\n\n\t\t\t\t\t// in the partition function if the centroid lies on the split plane then it is\n\t\t\t\t\t// considered to be on the right side of the split\n\t\t\t\t\tlet binIndex = ~ ~ ( relativeCenter / binWidth );\n\t\t\t\t\tif ( binIndex >= BIN_COUNT ) binIndex = BIN_COUNT - 1;\n\n\t\t\t\t\tconst bin = sahBins[ binIndex ];\n\t\t\t\t\tbin.count ++;\n\n\t\t\t\t\texpandByPrimitiveBounds( c, primitiveBounds, bin.bounds );\n\n\t\t\t\t}\n\n\t\t\t\t// cache the unioned bounds from right to left so we don't have to regenerate them each time\n\t\t\t\tconst lastBin = sahBins[ BIN_COUNT - 1 ];\n\t\t\t\tcopyBounds( lastBin.bounds, lastBin.rightCacheBounds );\n\t\t\t\tfor ( let i = BIN_COUNT - 2; i >= 0; i -- ) {\n\n\t\t\t\t\tconst bin = sahBins[ i ];\n\t\t\t\t\tconst nextBin = sahBins[ i + 1 ];\n\t\t\t\t\tunionBounds( bin.bounds, nextBin.rightCacheBounds, bin.rightCacheBounds );\n\n\t\t\t\t}\n\n\t\t\t\tlet leftCount = 0;\n\t\t\t\tfor ( let i = 0; i < BIN_COUNT - 1; i ++ ) {\n\n\t\t\t\t\tconst bin = sahBins[ i ];\n\t\t\t\t\tconst binCount = bin.count;\n\t\t\t\t\tconst bounds = bin.bounds;\n\n\t\t\t\t\tconst nextBin = sahBins[ i + 1 ];\n\t\t\t\t\tconst rightBounds = nextBin.rightCacheBounds;\n\n\t\t\t\t\t// don't do anything with the bounds if the new bounds have no primitives\n\t\t\t\t\tif ( binCount !== 0 ) {\n\n\t\t\t\t\t\tif ( leftCount === 0 ) {\n\n\t\t\t\t\t\t\tcopyBounds( bounds, leftBounds );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tunionBounds( bounds, leftBounds, leftBounds );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tleftCount += binCount;\n\n\t\t\t\t\t// check the cost of this split\n\t\t\t\t\tlet leftProb = 0;\n\t\t\t\t\tlet rightProb = 0;\n\n\t\t\t\t\tif ( leftCount !== 0 ) {\n\n\t\t\t\t\t\tleftProb = computeSurfaceArea( leftBounds ) / rootSurfaceArea;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tconst rightCount = count - leftCount;\n\t\t\t\t\tif ( rightCount !== 0 ) {\n\n\t\t\t\t\t\trightProb = computeSurfaceArea( rightBounds ) / rootSurfaceArea;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tconst cost = TRAVERSAL_COST + PRIMITIVE_INTERSECT_COST * (\n\t\t\t\t\t\tleftProb * leftCount + rightProb * rightCount\n\t\t\t\t\t);\n\n\t\t\t\t\tif ( cost < bestCost ) {\n\n\t\t\t\t\t\taxis = a;\n\t\t\t\t\t\tbestCost = cost;\n\t\t\t\t\t\tpos = bin.candidate;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t} else {\n\n\t\tconsole.warn( `BVH: Invalid build strategy value ${ strategy } used.` );\n\n\t}\n\n\treturn { axis, pos };\n\n}\n\n// returns the average coordinate on the specified axis of all the provided primitives\nfunction getAverage( primitiveBounds, offset, count, axis ) {\n\n\tlet avg = 0;\n\tconst boundsOffset = primitiveBounds.offset;\n\tfor ( let i = offset, end = offset + count; i < end; i ++ ) {\n\n\t\tavg += primitiveBounds[ ( i - boundsOffset ) * 6 + axis * 2 ];\n\n\t}\n\n\treturn avg / count;\n\n}\n","export class BVHNode {\n\n\tconstructor() {\n\n\t\t// internal nodes have boundingData, left, right, and splitAxis\n\t\t// leaf nodes have offset and count (referring to primitives in the mesh geometry)\n\n\t\tthis.boundingData = new Float32Array( 6 );\n\n\t}\n\n}\n","// reorders the partition buffer such that for `count` elements after `offset`, elements on the left side of the split\n// will be on the left and elements on the right side of the split will be on the right. returns the index\n// of the first element on the right side, or offset + count if there are no elements on the right side.\nexport function partition( buffer, stride, primitiveBounds, offset, count, split ) {\n\n\tlet left = offset;\n\tlet right = offset + count - 1;\n\tconst pos = split.pos;\n\tconst axisOffset = split.axis * 2;\n\tconst boundsOffset = primitiveBounds.offset || 0;\n\n\t// hoare partitioning, see e.g. https://en.wikipedia.org/wiki/Quicksort#Hoare_partition_scheme\n\twhile ( true ) {\n\n\t\twhile ( left <= right && primitiveBounds[ ( left - boundsOffset ) * 6 + axisOffset ] < pos ) {\n\n\t\t\tleft ++;\n\n\t\t}\n\n\t\t// if a primitive center lies on the partition plane it is considered to be on the right side\n\t\twhile ( left <= right && primitiveBounds[ ( right - boundsOffset ) * 6 + axisOffset ] >= pos ) {\n\n\t\t\tright --;\n\n\t\t}\n\n\t\tif ( left < right ) {\n\n\t\t\t// we need to swap all of the information associated with the primitives at index\n\t\t\t// left and right; that's the elements in the partition buffer and the bounds\n\t\t\tfor ( let i = 0; i < stride; i ++ ) {\n\n\t\t\t\tlet t0 = buffer[ left * stride + i ];\n\t\t\t\tbuffer[ left * stride + i ] = buffer[ right * stride + i ];\n\t\t\t\tbuffer[ right * stride + i ] = t0;\n\n\t\t\t}\n\n\t\t\t// swap bounds\n\t\t\tfor ( let i = 0; i < 6; i ++ ) {\n\n\t\t\t\tconst l = left - boundsOffset;\n\t\t\t\tconst r = right - boundsOffset;\n\t\t\t\tconst tb = primitiveBounds[ l * 6 + i ];\n\t\t\t\tprimitiveBounds[ l * 6 + i ] = primitiveBounds[ r * 6 + i ];\n\t\t\t\tprimitiveBounds[ r * 6 + i ] = tb;\n\n\t\t\t}\n\n\t\t\tleft ++;\n\t\t\tright --;\n\n\t\t} else {\n\n\t\t\treturn left;\n\n\t\t}\n\n\t}\n\n}\n","import { BYTES_PER_NODE, IS_LEAFNODE_FLAG } from '../Constants.js';\n\nlet float32Array, uint32Array, uint16Array, uint8Array;\nconst MAX_POINTER = Math.pow( 2, 32 );\n\nexport function countNodes( node ) {\n\n\tif ( 'count' in node ) {\n\n\t\treturn 1;\n\n\t} else {\n\n\t\treturn 1 + countNodes( node.left ) + countNodes( node.right );\n\n\t}\n\n}\n\nexport function populateBuffer( byteOffset, node, buffer ) {\n\n\tfloat32Array = new Float32Array( buffer );\n\tuint32Array = new Uint32Array( buffer );\n\tuint16Array = new Uint16Array( buffer );\n\tuint8Array = new Uint8Array( buffer );\n\n\treturn _populateBuffer( byteOffset, node );\n\n}\n\n// pack structure\n// boundingData \t\t\t\t: 6 float32\n// right / offset \t\t\t\t: 1 uint32\n// splitAxis / isLeaf + count \t: 1 uint32 / 2 uint16\nfunction _populateBuffer( byteOffset, node ) {\n\n\tconst node32Index = byteOffset / 4;\n\tconst node16Index = byteOffset / 2;\n\tconst isLeaf = 'count' in node;\n\tconst boundingData = node.boundingData;\n\tfor ( let i = 0; i < 6; i ++ ) {\n\n\t\tfloat32Array[ node32Index + i ] = boundingData[ i ];\n\n\t}\n\n\tif ( isLeaf ) {\n\n\t\tif ( node.buffer ) {\n\n\t\t\tuint8Array.set( new Uint8Array( node.buffer ), byteOffset );\n\t\t\treturn byteOffset + node.buffer.byteLength;\n\n\t\t} else {\n\n\t\t\tuint32Array[ node32Index + 6 ] = node.offset;\n\t\t\tuint16Array[ node16Index + 14 ] = node.count;\n\t\t\tuint16Array[ node16Index + 15 ] = IS_LEAFNODE_FLAG;\n\t\t\treturn byteOffset + BYTES_PER_NODE;\n\n\t\t}\n\n\t} else {\n\n\t\tconst { left, right, splitAxis } = node;\n\n\t\t// fill in the left node contents\n\t\tconst leftByteOffset = byteOffset + BYTES_PER_NODE;\n\t\tlet rightByteOffset = _populateBuffer( leftByteOffset, left );\n\n\t\t// calculate relative offset from parent to right child\n\t\tconst currentNodeIndex = byteOffset / BYTES_PER_NODE;\n\t\tconst rightNodeIndex = rightByteOffset / BYTES_PER_NODE;\n\t\tconst relativeRightIndex = rightNodeIndex - currentNodeIndex;\n\n\t\t// check if the relative offset is too high\n\t\tif ( relativeRightIndex > MAX_POINTER ) {\n\n\t\t\tthrow new Error( 'MeshBVH: Cannot store relative child node offset greater than 32 bits.' );\n\n\t\t}\n\n\t\t// fill in the right node contents (store as relative offset)\n\t\tuint32Array[ node32Index + 6 ] = relativeRightIndex;\n\t\tuint32Array[ node32Index + 7 ] = splitAxis;\n\n\t\t// return the next available buffer pointer\n\t\treturn _populateBuffer( rightByteOffset, right );\n\n\t}\n\n}\n","import { getBounds } from './computeBoundsUtils.js';\nimport { getOptimalSplit } from './splitUtils.js';\nimport { getLongestEdgeIndex } from '../../utils/ArrayBoxUtilities.js';\nimport { BVHNode } from '../BVHNode.js';\nimport { BYTES_PER_NODE } from '../Constants.js';\n\nimport { partition } from './sortUtils.js';\nimport { countNodes, populateBuffer } from './buildUtils.js';\n\nexport function buildTree( bvh, primitiveBounds, offset, count, options, loadRange ) {\n\n\t// expand variables\n\tconst {\n\t\tmaxDepth,\n\t\tverbose,\n\t\ttargetLeafSize,\n\t\t_strictLeafSize = Infinity,\n\t\tstrategy,\n\t\tonProgress,\n\t} = options;\n\n\tconst partitionBuffer = bvh.primitiveBuffer;\n\tconst partitionStride = bvh.primitiveBufferStride;\n\n\t// generate intermediate variables\n\tconst cacheCentroidBoundingData = new Float32Array( 6 );\n\tlet reachedMaxDepth = false;\n\n\tconst root = new BVHNode();\n\tgetBounds( primitiveBounds, offset, count, root.boundingData, cacheCentroidBoundingData );\n\tsplitNode( root, offset, count, cacheCentroidBoundingData );\n\treturn root;\n\n\tfunction triggerProgress( primitivesProcessed ) {\n\n\t\tif ( onProgress ) {\n\n\t\t\tonProgress( ( primitivesProcessed - loadRange.offset ) / loadRange.count );\n\n\t\t}\n\n\t}\n\n\t// either recursively splits the given node, creating left and right subtrees for it, or makes it a leaf node,\n\t// recording the offset and count of its primitives and writing them into the reordered geometry index.\n\tfunction splitNode( node, offset, count, centroidBoundingData = null, depth = 0 ) {\n\n\t\tif ( ! reachedMaxDepth && depth >= maxDepth ) {\n\n\t\t\treachedMaxDepth = true;\n\t\t\tif ( verbose ) {\n\n\t\t\t\tconsole.warn( `BVH: Max depth of ${ maxDepth } reached when generating BVH. Consider increasing maxDepth.` );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// A hard guarantee that no leaf exceeds \"_strictLeafSize\" primitives. When this node is over\n\t\t// that limit it must keep splitting regardless of the heuristic.\n\t\tconst mustSplit = count > _strictLeafSize;\n\n\t\t// early out if we've met our capacity - unless the strict guarantee still requires a split\n\t\tif ( ( count <= targetLeafSize && ! mustSplit ) || depth >= maxDepth ) {\n\n\t\t\ttriggerProgress( offset + count );\n\t\t\tnode.offset = offset;\n\t\t\tnode.count = count;\n\t\t\treturn node;\n\n\t\t}\n\n\t\t// Find where to split the volume\n\t\tconst split = getOptimalSplit( node.boundingData, centroidBoundingData, primitiveBounds, offset, count, strategy );\n\t\tlet splitOffset = split.axis === - 1 ? - 1 : partition( partitionBuffer, partitionStride, primitiveBounds, offset, count, split );\n\n\t\t// If the heuristic can't produce a usable split then make a leaf unless the strict guarantee requires the split -\n\t\t// in which case force an arbitrary median split. The axis comes from the node bounds so parallel and serial\n\t\t// builds produce identical trees.\n\t\tif ( split.axis === - 1 || splitOffset === offset || splitOffset === offset + count ) {\n\n\t\t\tif ( ! mustSplit ) {\n\n\t\t\t\ttriggerProgress( offset + count );\n\t\t\t\tnode.offset = offset;\n\t\t\t\tnode.count = count;\n\t\t\t\treturn node;\n\n\t\t\t}\n\n\t\t\tsplit.axis = Math.max( 0, getLongestEdgeIndex( node.boundingData ) );\n\t\t\tsplitOffset = offset + Math.max( 1, Math.floor( count / 2 ) );\n\n\t\t}\n\n\t\t// create the two new child nodes\n\t\tnode.splitAxis = split.axis;\n\n\t\t// create the left child and compute its bounding box\n\t\tconst left = new BVHNode();\n\t\tconst lstart = offset;\n\t\tconst lcount = splitOffset - offset;\n\t\tnode.left = left;\n\n\t\tgetBounds( primitiveBounds, lstart, lcount, left.boundingData, cacheCentroidBoundingData );\n\t\tsplitNode( left, lstart, lcount, cacheCentroidBoundingData, depth + 1 );\n\n\t\t// repeat for right\n\t\tconst right = new BVHNode();\n\t\tconst rstart = splitOffset;\n\t\tconst rcount = count - lcount;\n\t\tnode.right = right;\n\n\t\tgetBounds( primitiveBounds, rstart, rcount, right.boundingData, cacheCentroidBoundingData );\n\t\tsplitNode( right, rstart, rcount, cacheCentroidBoundingData, depth + 1 );\n\n\t\treturn node;\n\n\t}\n\n}\n\nexport function buildPackedTree( bvh, options ) {\n\n\tconst BufferConstructor = options.useSharedArrayBuffer ? SharedArrayBuffer : ArrayBuffer;\n\n\t// get the range of buffer data to construct / arrange\n\tconst rootRanges = bvh.getRootRanges( options.range );\n\tconst firstRange = rootRanges[ 0 ];\n\tconst lastRange = rootRanges[ rootRanges.length - 1 ];\n\tconst fullRange = {\n\t\toffset: firstRange.offset,\n\t\tcount: lastRange.offset + lastRange.count - firstRange.offset,\n\t};\n\n\t// construct the primitive bounds for sorting\n\tconst primitiveBounds = new Float32Array( 6 * fullRange.count );\n\tprimitiveBounds.offset = fullRange.offset;\n\tbvh.computePrimitiveBounds( fullRange.offset, fullRange.count, primitiveBounds );\n\n\t// Build BVH roots\n\tbvh._roots = rootRanges.map( range => {\n\n\t\tconst root = buildTree( bvh, primitiveBounds, range.offset, range.count, options, fullRange );\n\t\tconst nodeCount = countNodes( root );\n\t\tconst buffer = new BufferConstructor( BYTES_PER_NODE * nodeCount );\n\t\tpopulateBuffer( 0, root, buffer );\n\t\treturn buffer;\n\n\t} );\n\n}\n","export class PrimitivePool {\n\n\tconstructor( getNewPrimitive ) {\n\n\t\tthis._getNewPrimitive = getNewPrimitive;\n\t\tthis._primitives = [];\n\n\t}\n\n\tgetPrimitive() {\n\n\t\tconst primitives = this._primitives;\n\t\tif ( primitives.length === 0 ) {\n\n\t\t\treturn this._getNewPrimitive();\n\n\t\t} else {\n\n\t\t\treturn primitives.pop();\n\n\t\t}\n\n\t}\n\n\treleasePrimitive( primitive ) {\n\n\t\tthis._primitives.push( primitive );\n\n\t}\n\n}\n","class _BufferStack {\n\n\tconstructor() {\n\n\t\tthis.float32Array = null;\n\t\tthis.uint16Array = null;\n\t\tthis.uint32Array = null;\n\n\t\tconst stack = [];\n\t\tlet prevBuffer = null;\n\t\tthis.setBuffer = buffer => {\n\n\t\t\tif ( prevBuffer ) {\n\n\t\t\t\tstack.push( prevBuffer );\n\n\t\t\t}\n\n\t\t\tprevBuffer = buffer;\n\t\t\tthis.float32Array = new Float32Array( buffer );\n\t\t\tthis.uint16Array = new Uint16Array( buffer );\n\t\t\tthis.uint32Array = new Uint32Array( buffer );\n\n\t\t};\n\n\t\tthis.clearBuffer = () => {\n\n\t\t\tprevBuffer = null;\n\t\t\tthis.float32Array = null;\n\t\t\tthis.uint16Array = null;\n\t\t\tthis.uint32Array = null;\n\n\t\t\tif ( stack.length !== 0 ) {\n\n\t\t\t\tthis.setBuffer( stack.pop() );\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n}\n\nexport const BufferStack = /* @__PURE__ */ new _BufferStack();\n","import { Box3 } from 'three';\nimport { CONTAINED, UINT32_PER_NODE } from '../Constants.js';\nimport { arrayToBox } from '../../utils/ArrayBoxUtilities.js';\nimport { PrimitivePool } from '../../utils/PrimitivePool.js';\nimport { COUNT, OFFSET, LEFT_NODE, RIGHT_NODE, IS_LEAF, BOUNDING_DATA_INDEX } from '../utils/nodeBufferUtils.js';\nimport { BufferStack } from '../utils/BufferStack.js';\n\nlet _box1, _box2;\nconst boxStack = [];\nconst boxPool = /* @__PURE__ */ new PrimitivePool( () => new Box3() );\n\nexport function shapecast( bvh, root, intersectsBounds, intersectsRange, boundsTraverseOrder, nodeOffset ) {\n\n\t// setup\n\t_box1 = boxPool.getPrimitive();\n\t_box2 = boxPool.getPrimitive();\n\tboxStack.push( _box1, _box2 );\n\tBufferStack.setBuffer( bvh._roots[ root ] );\n\n\tconst result = shapecastTraverse( 0, bvh.geometry, intersectsBounds, intersectsRange, boundsTraverseOrder, nodeOffset );\n\n\t// cleanup\n\tBufferStack.clearBuffer();\n\tboxPool.releasePrimitive( _box1 );\n\tboxPool.releasePrimitive( _box2 );\n\tboxStack.pop();\n\tboxStack.pop();\n\n\tconst length = boxStack.length;\n\tif ( length > 0 ) {\n\n\t\t_box2 = boxStack[ length - 1 ];\n\t\t_box1 = boxStack[ length - 2 ];\n\n\t}\n\n\treturn result;\n\n}\n\nfunction shapecastTraverse(\n\tnodeIndex32,\n\tgeometry,\n\tintersectsBoundsFunc,\n\tintersectsRangeFunc,\n\tnodeScoreFunc = null,\n\tnodeIndexOffset = 0, // offset for unique node identifier\n\tdepth = 0\n) {\n\n\tconst { float32Array, uint16Array, uint32Array } = BufferStack;\n\tlet nodeIndex16 = nodeIndex32 * 2;\n\n\tconst isLeaf = IS_LEAF( nodeIndex16, uint16Array );\n\tif ( isLeaf ) {\n\n\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\t\tarrayToBox( BOUNDING_DATA_INDEX( nodeIndex32 ), float32Array, _box1 );\n\t\treturn intersectsRangeFunc( offset, count, false, depth, nodeIndexOffset + nodeIndex32 / UINT32_PER_NODE, _box1 );\n\n\t} else {\n\n\t\tconst left = LEFT_NODE( nodeIndex32 );\n\t\tconst right = RIGHT_NODE( nodeIndex32, uint32Array );\n\t\tlet c1 = left;\n\t\tlet c2 = right;\n\n\t\tlet score1, score2;\n\t\tlet box1, box2;\n\t\tif ( nodeScoreFunc ) {\n\n\t\t\tbox1 = _box1;\n\t\t\tbox2 = _box2;\n\n\t\t\t// bounding data is not offset\n\t\t\tarrayToBox( BOUNDING_DATA_INDEX( c1 ), float32Array, box1 );\n\t\t\tarrayToBox( BOUNDING_DATA_INDEX( c2 ), float32Array, box2 );\n\n\t\t\tscore1 = nodeScoreFunc( box1 );\n\t\t\tscore2 = nodeScoreFunc( box2 );\n\n\t\t\tif ( score2 < score1 ) {\n\n\t\t\t\tc1 = right;\n\t\t\t\tc2 = left;\n\n\t\t\t\tconst temp = score1;\n\t\t\t\tscore1 = score2;\n\t\t\t\tscore2 = temp;\n\n\t\t\t\tbox1 = box2;\n\t\t\t\t// box2 is always set before use below\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Check box 1 intersection\n\t\tif ( ! box1 ) {\n\n\t\t\tbox1 = _box1;\n\t\t\tarrayToBox( BOUNDING_DATA_INDEX( c1 ), float32Array, box1 );\n\n\t\t}\n\n\t\tconst isC1Leaf = IS_LEAF( c1 * 2, uint16Array );\n\t\tconst c1Intersection = intersectsBoundsFunc( box1, isC1Leaf, score1, depth + 1, nodeIndexOffset + c1 / UINT32_PER_NODE );\n\n\t\tlet c1StopTraversal;\n\t\tif ( c1Intersection === CONTAINED ) {\n\n\t\t\tconst offset = getLeftOffset( c1 );\n\t\t\tconst end = getRightEndOffset( c1 );\n\t\t\tconst count = end - offset;\n\n\t\t\tc1StopTraversal = intersectsRangeFunc( offset, count, true, depth + 1, nodeIndexOffset + c1 / UINT32_PER_NODE, box1 );\n\n\t\t} else {\n\n\t\t\tc1StopTraversal =\n\t\t\t\tc1Intersection &&\n\t\t\t\tshapecastTraverse(\n\t\t\t\t\tc1,\n\t\t\t\t\tgeometry,\n\t\t\t\t\tintersectsBoundsFunc,\n\t\t\t\t\tintersectsRangeFunc,\n\t\t\t\t\tnodeScoreFunc,\n\t\t\t\t\tnodeIndexOffset,\n\t\t\t\t\tdepth + 1\n\t\t\t\t);\n\n\t\t}\n\n\t\tif ( c1StopTraversal ) return true;\n\n\t\t// Check box 2 intersection\n\t\t// cached box2 will have been overwritten by previous traversal\n\t\tbox2 = _box2;\n\t\tarrayToBox( BOUNDING_DATA_INDEX( c2 ), float32Array, box2 );\n\n\t\tconst isC2Leaf = IS_LEAF( c2 * 2, uint16Array );\n\t\tconst c2Intersection = intersectsBoundsFunc( box2, isC2Leaf, score2, depth + 1, nodeIndexOffset + c2 / UINT32_PER_NODE );\n\n\t\tlet c2StopTraversal;\n\t\tif ( c2Intersection === CONTAINED ) {\n\n\t\t\tconst offset = getLeftOffset( c2 );\n\t\t\tconst end = getRightEndOffset( c2 );\n\t\t\tconst count = end - offset;\n\n\t\t\tc2StopTraversal = intersectsRangeFunc( offset, count, true, depth + 1, nodeIndexOffset + c2 / UINT32_PER_NODE, box2 );\n\n\t\t} else {\n\n\t\t\tc2StopTraversal =\n\t\t\t\tc2Intersection &&\n\t\t\t\tshapecastTraverse(\n\t\t\t\t\tc2,\n\t\t\t\t\tgeometry,\n\t\t\t\t\tintersectsBoundsFunc,\n\t\t\t\t\tintersectsRangeFunc,\n\t\t\t\t\tnodeScoreFunc,\n\t\t\t\t\tnodeIndexOffset,\n\t\t\t\t\tdepth + 1\n\t\t\t\t);\n\n\t\t}\n\n\t\tif ( c2StopTraversal ) return true;\n\n\t\treturn false;\n\n\t\t// Define these inside the function so it has access to the local variables needed\n\t\t// when converting to the buffer equivalents\n\t\tfunction getLeftOffset( nodeIndex32 ) {\n\n\t\t\tconst { uint16Array, uint32Array } = BufferStack;\n\t\t\tlet nodeIndex16 = nodeIndex32 * 2;\n\n\t\t\t// traverse until we find a leaf\n\t\t\twhile ( ! IS_LEAF( nodeIndex16, uint16Array ) ) {\n\n\t\t\t\tnodeIndex32 = LEFT_NODE( nodeIndex32 );\n\t\t\t\tnodeIndex16 = nodeIndex32 * 2;\n\n\t\t\t}\n\n\t\t\treturn OFFSET( nodeIndex32, uint32Array );\n\n\t\t}\n\n\t\tfunction getRightEndOffset( nodeIndex32 ) {\n\n\t\t\tconst { uint16Array, uint32Array } = BufferStack;\n\t\t\tlet nodeIndex16 = nodeIndex32 * 2;\n\n\t\t\t// traverse until we find a leaf\n\t\t\twhile ( ! IS_LEAF( nodeIndex16, uint16Array ) ) {\n\n\t\t\t\t// adjust offset to point to the right node\n\t\t\t\tnodeIndex32 = RIGHT_NODE( nodeIndex32, uint32Array );\n\t\t\t\tnodeIndex16 = nodeIndex32 * 2;\n\n\t\t\t}\n\n\t\t\t// return the end offset of the triangle range\n\t\t\treturn OFFSET( nodeIndex32, uint32Array ) + COUNT( nodeIndex16, uint16Array );\n\n\t\t}\n\n\t}\n\n}\n","import { Box3, Matrix4 } from 'three';\nimport { BufferStack } from '../utils/BufferStack.js';\nimport { BOUNDING_DATA_INDEX, COUNT, IS_LEAF, LEFT_NODE, OFFSET, RIGHT_NODE } from '../utils/nodeBufferUtils.js';\nimport { arrayToBox } from '../../utils/ArrayBoxUtilities.js';\nimport { PrimitivePool } from '../../utils/PrimitivePool.js';\nimport { BYTES_PER_NODE, UINT32_PER_NODE } from '../Constants.js';\n\nconst _bufferStack1 = /* @__PURE__ */ new BufferStack.constructor();\nconst _bufferStack2 = /* @__PURE__ */ new BufferStack.constructor();\nconst _boxPool = /* @__PURE__ */ new PrimitivePool( () => new Box3() );\nconst _leftBox1 = /* @__PURE__ */ new Box3();\nconst _rightBox1 = /* @__PURE__ */ new Box3();\n\nconst _leftBox2 = /* @__PURE__ */ new Box3();\nconst _rightBox2 = /* @__PURE__ */ new Box3();\n\nlet _active = false;\n\nexport function bvhcast( bvh, otherBvh, matrixToLocal, intersectsRanges ) {\n\n\tif ( _active ) {\n\n\t\tthrow new Error( 'MeshBVH: Recursive calls to bvhcast not supported.' );\n\n\t}\n\n\t_active = true;\n\n\tconst roots = bvh._roots;\n\tconst otherRoots = otherBvh._roots;\n\tlet result;\n\tlet nodeOffset1 = 0;\n\tlet nodeOffset2 = 0;\n\tconst invMat = new Matrix4().copy( matrixToLocal ).invert();\n\n\t// iterate over the first set of roots\n\tfor ( let i = 0, il = roots.length; i < il; i ++ ) {\n\n\t\t_bufferStack1.setBuffer( roots[ i ] );\n\t\tnodeOffset2 = 0;\n\n\t\t// prep the initial root box\n\t\tconst localBox = _boxPool.getPrimitive();\n\t\tarrayToBox( BOUNDING_DATA_INDEX( 0 ), _bufferStack1.float32Array, localBox );\n\t\tlocalBox.applyMatrix4( invMat );\n\n\t\t// iterate over the second set of roots\n\t\tfor ( let j = 0, jl = otherRoots.length; j < jl; j ++ ) {\n\n\t\t\t_bufferStack2.setBuffer( otherRoots[ j ] );\n\n\t\t\tresult = _traverse(\n\t\t\t\t0, 0, matrixToLocal, invMat, intersectsRanges,\n\t\t\t\tnodeOffset1, nodeOffset2, 0, 0,\n\t\t\t\tlocalBox,\n\t\t\t);\n\n\t\t\t_bufferStack2.clearBuffer();\n\t\t\tnodeOffset2 += otherRoots[ j ].byteLength / BYTES_PER_NODE;\n\n\t\t\tif ( result ) {\n\n\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// release stack info\n\t\t_boxPool.releasePrimitive( localBox );\n\t\t_bufferStack1.clearBuffer();\n\t\tnodeOffset1 += roots[ i ].byteLength / BYTES_PER_NODE;\n\n\t\tif ( result ) {\n\n\t\t\tbreak;\n\n\t\t}\n\n\t}\n\n\t_active = false;\n\treturn result;\n\n}\n\nfunction _traverse(\n\tnode1Index32,\n\tnode2Index32,\n\tmatrix2to1,\n\tmatrix1to2,\n\tintersectsRangesFunc,\n\n\t// offsets for ids\n\tnode1IndexOffset = 0,\n\tnode2IndexOffset = 0,\n\n\t// tree depth\n\tdepth1 = 0,\n\tdepth2 = 0,\n\n\tcurrBox = null,\n\treversed = false,\n\n) {\n\n\t// get the buffer stacks associated with the current indices\n\tlet bufferStack1, bufferStack2;\n\tif ( reversed ) {\n\n\t\tbufferStack1 = _bufferStack2;\n\t\tbufferStack2 = _bufferStack1;\n\n\t} else {\n\n\t\tbufferStack1 = _bufferStack1;\n\t\tbufferStack2 = _bufferStack2;\n\n\t}\n\n\t// get the local instances of the typed buffers\n\tconst\n\t\tfloat32Array1 = bufferStack1.float32Array,\n\t\tuint32Array1 = bufferStack1.uint32Array,\n\t\tuint16Array1 = bufferStack1.uint16Array,\n\t\tfloat32Array2 = bufferStack2.float32Array,\n\t\tuint32Array2 = bufferStack2.uint32Array,\n\t\tuint16Array2 = bufferStack2.uint16Array;\n\n\tconst node1Index16 = node1Index32 * 2;\n\tconst node2Index16 = node2Index32 * 2;\n\tconst isLeaf1 = IS_LEAF( node1Index16, uint16Array1 );\n\tconst isLeaf2 = IS_LEAF( node2Index16, uint16Array2 );\n\tlet result = false;\n\tif ( isLeaf2 && isLeaf1 ) {\n\n\t\t// if both bounds are leaf nodes then fire the callback if the boxes intersect\n\t\t// Note the \"nodeIndex\" values are just intended to be used as unique identifiers in the tree and\n\t\t// not used for accessing data\n\t\tif ( reversed ) {\n\n\t\t\tresult = intersectsRangesFunc(\n\t\t\t\tOFFSET( node2Index32, uint32Array2 ), COUNT( node2Index32 * 2, uint16Array2 ),\n\t\t\t\tOFFSET( node1Index32, uint32Array1 ), COUNT( node1Index32 * 2, uint16Array1 ),\n\t\t\t\tdepth2, node2IndexOffset + node2Index32 / UINT32_PER_NODE,\n\t\t\t\tdepth1, node1IndexOffset + node1Index32 / UINT32_PER_NODE,\n\t\t\t);\n\n\t\t} else {\n\n\t\t\tresult = intersectsRangesFunc(\n\t\t\t\tOFFSET( node1Index32, uint32Array1 ), COUNT( node1Index32 * 2, uint16Array1 ),\n\t\t\t\tOFFSET( node2Index32, uint32Array2 ), COUNT( node2Index32 * 2, uint16Array2 ),\n\t\t\t\tdepth1, node1IndexOffset + node1Index32 / UINT32_PER_NODE,\n\t\t\t\tdepth2, node2IndexOffset + node2Index32 / UINT32_PER_NODE,\n\t\t\t);\n\n\t\t}\n\n\t} else if ( isLeaf2 ) {\n\n\t\t// SWAP\n\t\t// If we've traversed to the leaf node on the other bvh then we need to swap over\n\t\t// to traverse down the first one\n\n\t\t// get the new box to use\n\t\tconst newBox = _boxPool.getPrimitive();\n\t\tarrayToBox( BOUNDING_DATA_INDEX( node2Index32 ), float32Array2, newBox );\n\t\tnewBox.applyMatrix4( matrix2to1 );\n\n\t\t// get the child bounds to check before traversal\n\t\tconst cl1 = LEFT_NODE( node1Index32 );\n\t\tconst cr1 = RIGHT_NODE( node1Index32, uint32Array1 );\n\t\tarrayToBox( BOUNDING_DATA_INDEX( cl1 ), float32Array1, _leftBox1 );\n\t\tarrayToBox( BOUNDING_DATA_INDEX( cr1 ), float32Array1, _rightBox1 );\n\n\t\t// precompute the intersections otherwise the global boxes will be modified during traversal\n\t\tconst intersectCl1 = newBox.intersectsBox( _leftBox1 );\n\t\tconst intersectCr1 = newBox.intersectsBox( _rightBox1 );\n\t\tresult = (\n\t\t\tintersectCl1 && _traverse(\n\t\t\t\tnode2Index32, cl1, matrix1to2, matrix2to1, intersectsRangesFunc,\n\t\t\t\tnode2IndexOffset, node1IndexOffset, depth2, depth1 + 1,\n\t\t\t\tnewBox, ! reversed,\n\t\t\t)\n\t\t) || (\n\t\t\tintersectCr1 && _traverse(\n\t\t\t\tnode2Index32, cr1, matrix1to2, matrix2to1, intersectsRangesFunc,\n\t\t\t\tnode2IndexOffset, node1IndexOffset, depth2, depth1 + 1,\n\t\t\t\tnewBox, ! reversed,\n\t\t\t)\n\t\t);\n\n\t\t_boxPool.releasePrimitive( newBox );\n\n\t} else {\n\n\t\t// if neither are leaves then we should swap if one of the children does not\n\t\t// intersect with the current bounds\n\n\t\t// get the child bounds to check\n\t\tconst cl2 = LEFT_NODE( node2Index32 );\n\t\tconst cr2 = RIGHT_NODE( node2Index32, uint32Array2 );\n\t\tarrayToBox( BOUNDING_DATA_INDEX( cl2 ), float32Array2, _leftBox2 );\n\t\tarrayToBox( BOUNDING_DATA_INDEX( cr2 ), float32Array2, _rightBox2 );\n\n\t\tconst leftIntersects = currBox.intersectsBox( _leftBox2 );\n\t\tconst rightIntersects = currBox.intersectsBox( _rightBox2 );\n\t\tif ( leftIntersects && rightIntersects ) {\n\n\t\t\t// continue to traverse both children if they both intersect\n\t\t\tresult = _traverse(\n\t\t\t\tnode1Index32, cl2, matrix2to1, matrix1to2, intersectsRangesFunc,\n\t\t\t\tnode1IndexOffset, node2IndexOffset, depth1, depth2 + 1,\n\t\t\t\tcurrBox, reversed,\n\t\t\t) || _traverse(\n\t\t\t\tnode1Index32, cr2, matrix2to1, matrix1to2, intersectsRangesFunc,\n\t\t\t\tnode1IndexOffset, node2IndexOffset, depth1, depth2 + 1,\n\t\t\t\tcurrBox, reversed,\n\t\t\t);\n\n\t\t} else if ( leftIntersects ) {\n\n\t\t\tif ( isLeaf1 ) {\n\n\t\t\t\t// if the current box is a leaf then just continue\n\t\t\t\tresult = _traverse(\n\t\t\t\t\tnode1Index32, cl2, matrix2to1, matrix1to2, intersectsRangesFunc,\n\t\t\t\t\tnode1IndexOffset, node2IndexOffset, depth1, depth2 + 1,\n\t\t\t\t\tcurrBox, reversed,\n\t\t\t\t);\n\n\t\t\t} else {\n\n\t\t\t\t// SWAP\n\t\t\t\t// if only one box intersects then we have to swap to the other bvh to continue\n\t\t\t\tconst newBox = _boxPool.getPrimitive();\n\t\t\t\tnewBox.copy( _leftBox2 ).applyMatrix4( matrix2to1 );\n\n\t\t\t\tconst cl1 = LEFT_NODE( node1Index32 );\n\t\t\t\tconst cr1 = RIGHT_NODE( node1Index32, uint32Array1 );\n\t\t\t\tarrayToBox( BOUNDING_DATA_INDEX( cl1 ), float32Array1, _leftBox1 );\n\t\t\t\tarrayToBox( BOUNDING_DATA_INDEX( cr1 ), float32Array1, _rightBox1 );\n\n\t\t\t\t// precompute the intersections otherwise the global boxes will be modified during traversal\n\t\t\t\tconst intersectCl1 = newBox.intersectsBox( _leftBox1 );\n\t\t\t\tconst intersectCr1 = newBox.intersectsBox( _rightBox1 );\n\t\t\t\tresult = (\n\t\t\t\t\tintersectCl1 && _traverse(\n\t\t\t\t\t\tcl2, cl1, matrix1to2, matrix2to1, intersectsRangesFunc,\n\t\t\t\t\t\tnode2IndexOffset, node1IndexOffset, depth2, depth1 + 1,\n\t\t\t\t\t\tnewBox, ! reversed,\n\t\t\t\t\t)\n\t\t\t\t) || (\n\t\t\t\t\tintersectCr1 && _traverse(\n\t\t\t\t\t\tcl2, cr1, matrix1to2, matrix2to1, intersectsRangesFunc,\n\t\t\t\t\t\tnode2IndexOffset, node1IndexOffset, depth2, depth1 + 1,\n\t\t\t\t\t\tnewBox, ! reversed,\n\t\t\t\t\t)\n\t\t\t\t);\n\n\t\t\t\t_boxPool.releasePrimitive( newBox );\n\n\t\t\t}\n\n\t\t} else if ( rightIntersects ) {\n\n\t\t\tif ( isLeaf1 ) {\n\n\t\t\t\t// if the current box is a leaf then just continue\n\t\t\t\tresult = _traverse(\n\t\t\t\t\tnode1Index32, cr2, matrix2to1, matrix1to2, intersectsRangesFunc,\n\t\t\t\t\tnode1IndexOffset, node2IndexOffset, depth1, depth2 + 1,\n\t\t\t\t\tcurrBox, reversed,\n\t\t\t\t);\n\n\t\t\t} else {\n\n\t\t\t\t// SWAP\n\t\t\t\t// if only one box intersects then we have to swap to the other bvh to continue\n\t\t\t\tconst newBox = _boxPool.getPrimitive();\n\t\t\t\tnewBox.copy( _rightBox2 ).applyMatrix4( matrix2to1 );\n\n\t\t\t\tconst cl1 = LEFT_NODE( node1Index32 );\n\t\t\t\tconst cr1 = RIGHT_NODE( node1Index32, uint32Array1 );\n\t\t\t\tarrayToBox( BOUNDING_DATA_INDEX( cl1 ), float32Array1, _leftBox1 );\n\t\t\t\tarrayToBox( BOUNDING_DATA_INDEX( cr1 ), float32Array1, _rightBox1 );\n\n\t\t\t\t// precompute the intersections otherwise the global boxes will be modified during traversal\n\t\t\t\tconst intersectCl1 = newBox.intersectsBox( _leftBox1 );\n\t\t\t\tconst intersectCr1 = newBox.intersectsBox( _rightBox1 );\n\t\t\t\tresult = (\n\t\t\t\t\tintersectCl1 && _traverse(\n\t\t\t\t\t\tcr2, cl1, matrix1to2, matrix2to1, intersectsRangesFunc,\n\t\t\t\t\t\tnode2IndexOffset, node1IndexOffset, depth2, depth1 + 1,\n\t\t\t\t\t\tnewBox, ! reversed,\n\t\t\t\t\t)\n\t\t\t\t) || (\n\t\t\t\t\tintersectCr1 && _traverse(\n\t\t\t\t\t\tcr2, cr1, matrix1to2, matrix2to1, intersectsRangesFunc,\n\t\t\t\t\t\tnode2IndexOffset, node1IndexOffset, depth2, depth1 + 1,\n\t\t\t\t\t\tnewBox, ! reversed,\n\t\t\t\t\t)\n\t\t\t\t);\n\n\t\t\t\t_boxPool.releasePrimitive( newBox );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\treturn result;\n\n}\n\n","import { COUNT, IS_LEAF, LEFT_NODE, OFFSET, RIGHT_NODE, SPLIT_AXIS } from './utils/nodeBufferUtils.js';\n\nexport const BVHTraversalHelper = new ( class {\n\n\tconstructor() {\n\n\t\tlet buffer = null;\n\t\tlet uint32Array = null;\n\t\tlet uint16Array = null;\n\t\tlet traversing = false;\n\n\t\tthis.root = null;\n\t\tthis.buffer = null;\n\t\tthis.uint32Array = null;\n\t\tthis.uint16Array = null;\n\n\t\tthis.setBVH = ( bvh, root ) => {\n\n\t\t\tif ( traversing ) {\n\n\t\t\t\tthrow new Error( 'BVHTraversalHelper: cannot call setBVH during an active traversal.' );\n\n\t\t\t}\n\n\t\t\tthis.root = root;\n\t\t\tthis.buffer = buffer = bvh._roots[ root ];\n\t\t\tthis.uint16Array = uint16Array = new Uint16Array( buffer );\n\t\t\tthis.uint32Array = uint32Array = new Uint32Array( buffer );\n\n\t\t};\n\n\t\tthis.reset = () => {\n\n\t\t\tthis.root = null;\n\t\t\tthis.buffer = buffer = null;\n\t\t\tthis.uint16Array = uint16Array = null;\n\t\t\tthis.uint32Array = uint32Array = null;\n\n\t\t};\n\n\t\tthis.getRangeStart = node32Index => {\n\n\t\t\tlet node16Index = node32Index * 2;\n\t\t\twhile ( ! IS_LEAF( node16Index, uint16Array ) ) {\n\n\t\t\t\tnode32Index = LEFT_NODE( node32Index );\n\t\t\t\tnode16Index = node32Index * 2;\n\n\t\t\t}\n\n\t\t\treturn OFFSET( node32Index, uint32Array );\n\n\t\t};\n\n\t\tthis.getRangeEnd = node32Index => {\n\n\t\t\tlet node16Index = node32Index * 2;\n\t\t\twhile ( ! IS_LEAF( node16Index, uint16Array ) ) {\n\n\t\t\t\tnode32Index = RIGHT_NODE( node32Index, uint32Array );\n\t\t\t\tnode16Index = node32Index * 2;\n\n\t\t\t}\n\n\t\t\treturn OFFSET( node32Index, uint32Array ) + COUNT( node16Index, uint16Array );\n\n\t\t};\n\n\t\t// internal recursive walk - the public \"traverseBuffer\" wraps this with the re-entrancy guard\n\t\tconst walk = ( callback, node32Index, depth ) => {\n\n\t\t\tconst node16Index = node32Index * 2;\n\t\t\tconst isLeaf = IS_LEAF( node16Index, uint16Array );\n\t\t\tconst stopTraversal = callback( depth, isLeaf, node32Index );\n\t\t\tif ( ! stopTraversal && ! isLeaf ) {\n\n\t\t\t\tconst left = LEFT_NODE( node32Index );\n\t\t\t\tconst right = RIGHT_NODE( node32Index, uint32Array );\n\t\t\t\twalk( callback, left, depth + 1 );\n\t\t\t\twalk( callback, right, depth + 1 );\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.traverseBuffer = callback => {\n\n\t\t\tif ( traversing ) {\n\n\t\t\t\tthrow new Error( 'BVHTraversalHelper: cannot start a traversal during an active traversal.' );\n\n\t\t\t}\n\n\t\t\ttraversing = true;\n\t\t\ttry {\n\n\t\t\t\twalk( callback, 0, 0 );\n\n\t\t\t} finally {\n\n\t\t\t\ttraversing = false;\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.traverse = callback => {\n\n\t\t\tthis.traverseBuffer( ( depth, isLeaf, node32Index ) => {\n\n\t\t\t\tif ( isLeaf ) {\n\n\t\t\t\t\tconst node16Index = node32Index * 2;\n\t\t\t\t\tconst offset = uint32Array[ node32Index + 6 ];\n\t\t\t\t\tconst count = uint16Array[ node16Index + 14 ];\n\t\t\t\t\treturn callback( depth, isLeaf, new Float32Array( buffer, node32Index * 4, 6 ), offset, count );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconst splitAxis = SPLIT_AXIS( node32Index, uint32Array );\n\t\t\t\t\treturn callback( depth, isLeaf, new Float32Array( buffer, node32Index * 4, 6 ), splitAxis );\n\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t};\n\n\t}\n\n} )();\n","/** @import { Matrix4 } from 'three' */\nimport { Box3 } from 'three';\nimport { BYTES_PER_NODE, UINT32_PER_NODE, DEFAULT_OPTIONS, FLOAT32_EPSILON } from './Constants.js';\nimport { arrayToBox } from '../utils/ArrayBoxUtilities.js';\nimport { IS_LEAF, LEFT_NODE, RIGHT_NODE, COUNT, OFFSET } from './utils/nodeBufferUtils.js';\nimport { buildPackedTree } from './build/buildTree.js';\nimport { shapecast as shapecastFunc } from './cast/shapecast.js';\nimport { bvhcast } from './cast/bvhcast.js';\nimport { BVHTraversalHelper } from './BVHTraversalHelper.js';\n\nconst _tempBox = /* @__PURE__ */ new Box3();\nconst _tempBuffer = /* @__PURE__ */ new Float32Array( 6 );\n\n/**\n * @callback BoundsTraverseOrderCallback\n * @param {Box3} box\n * @returns {number}\n */\n\n/**\n * @callback IntersectsBoundsCallback\n * @param {Box3} box\n * @param {boolean} isLeaf\n * @param {number|undefined} score\n * @param {number} depth\n * @param {number} nodeIndex\n * @returns {number}\n */\n\n/**\n * @callback IntersectsRangeCallback\n * @param {number} offset\n * @param {number} count\n * @param {boolean} contained\n * @param {number} depth\n * @param {number} nodeIndex\n * @param {Box3} box\n * @returns {boolean}\n */\n\n/**\n * @callback IntersectsRangesCallback\n * @param {number} offset1\n * @param {number} count1\n * @param {number} offset2\n * @param {number} count2\n * @param {number} depth1\n * @param {number} nodeIndex1\n * @param {number} depth2\n * @param {number} nodeIndex2\n * @returns {boolean}\n */\n\n/**\n * Abstract base class for BVH implementations. Provides core tree traversal and spatial query\n * methods. Subclasses implement primitive-specific logic by overriding `writePrimitiveBounds`\n * and related internal methods.\n */\nexport class BVH {\n\n\tconstructor() {\n\n\t\tthis._roots = null;\n\t\tthis.primitiveBuffer = null;\n\t\tthis.primitiveBufferStride = null;\n\n\t}\n\n\tinit( options ) {\n\n\t\toptions = {\n\t\t\t...DEFAULT_OPTIONS,\n\t\t\t...options,\n\t\t};\n\n\t\tif ( 'maxLeafSize' in options ) {\n\n\t\t\tconsole.warn( 'BVH: \"maxLeafSize\" option has been deprecated. Use \"targetLeafSize\", instead.' );\n\t\t\toptions = {\n\t\t\t\t...options,\n\t\t\t\ttargetLeafSize: options.maxLeafSize,\n\t\t\t};\n\n\t\t}\n\n\t\tbuildPackedTree( this, options );\n\n\t}\n\n\tgetRootRanges( /* range */ ) {\n\n\t\t// TODO: can we avoid passing range in here?\n\t\tthrow new Error( 'BVH: getRootRanges() not implemented' );\n\n\t}\n\n\t// write the i-th primitive bounds in a 6-value min / max format to the buffer\n\t// starting at the given \"writeOffset\"\n\twritePrimitiveBounds( /* i, buffer, writeOffset */ ) {\n\n\t\tthrow new Error( 'BVH: writePrimitiveBounds() not implemented' );\n\n\t}\n\n\t// writes the union bounds of all primitives in the given range in a min / max format\n\t// to the buffer\n\twritePrimitiveRangeBounds( offset, count, targetBuffer, baseIndex ) {\n\n\t\t// Initialize bounds\n\t\tlet minX = Infinity;\n\t\tlet minY = Infinity;\n\t\tlet minZ = Infinity;\n\t\tlet maxX = - Infinity;\n\t\tlet maxY = - Infinity;\n\t\tlet maxZ = - Infinity;\n\n\t\t// compute union of all bounds\n\t\tfor ( let i = offset, end = offset + count; i < end; i ++ ) {\n\n\t\t\tthis.writePrimitiveBounds( i, _tempBuffer, 0 );\n\n\t\t\t// compute union\n\t\t\tconst [ lx, ly, lz, rx, ry, rz ] = _tempBuffer;\n\t\t\tif ( lx < minX ) minX = lx;\n\t\t\tif ( rx > maxX ) maxX = rx;\n\t\t\tif ( ly < minY ) minY = ly;\n\t\t\tif ( ry > maxY ) maxY = ry;\n\t\t\tif ( lz < minZ ) minZ = lz;\n\t\t\tif ( rz > maxZ ) maxZ = rz;\n\n\t\t}\n\n\t\t// write bounds\n\t\ttargetBuffer[ baseIndex + 0 ] = minX;\n\t\ttargetBuffer[ baseIndex + 1 ] = minY;\n\t\ttargetBuffer[ baseIndex + 2 ] = minZ;\n\t\ttargetBuffer[ baseIndex + 3 ] = maxX;\n\t\ttargetBuffer[ baseIndex + 4 ] = maxY;\n\t\ttargetBuffer[ baseIndex + 5 ] = maxZ;\n\n\t\treturn targetBuffer;\n\n\t}\n\n\tcomputePrimitiveBounds( offset, count, targetBuffer ) {\n\n\t\tconst boundsOffset = targetBuffer.offset || 0;\n\t\tfor ( let i = offset, end = offset + count; i < end; i ++ ) {\n\n\t\t\tthis.writePrimitiveBounds( i, _tempBuffer, 0 );\n\n\t\t\t// construction primitive bounds requires a center + half extents format\n\t\t\tconst [ lx, ly, lz, rx, ry, rz ] = _tempBuffer;\n\n\t\t\tconst cx = ( lx + rx ) / 2;\n\t\t\tconst cy = ( ly + ry ) / 2;\n\t\t\tconst cz = ( lz + rz ) / 2;\n\n\t\t\tconst hx = ( rx - lx ) / 2;\n\t\t\tconst hy = ( ry - ly ) / 2;\n\t\t\tconst hz = ( rz - lz ) / 2;\n\n\t\t\tconst baseIndex = ( i - boundsOffset ) * 6;\n\t\t\ttargetBuffer[ baseIndex + 0 ] = cx;\n\t\t\ttargetBuffer[ baseIndex + 1 ] = hx + ( Math.abs( cx ) + hx ) * FLOAT32_EPSILON;\n\t\t\ttargetBuffer[ baseIndex + 2 ] = cy;\n\t\t\ttargetBuffer[ baseIndex + 3 ] = hy + ( Math.abs( cy ) + hy ) * FLOAT32_EPSILON;\n\t\t\ttargetBuffer[ baseIndex + 4 ] = cz;\n\t\t\ttargetBuffer[ baseIndex + 5 ] = hz + ( Math.abs( cz ) + hz ) * FLOAT32_EPSILON;\n\n\t\t}\n\n\t\treturn targetBuffer;\n\n\t}\n\n\t/**\n\t * Adjusts all primitive offsets stored in the BVH leaf nodes by the given value. Useful when\n\t * geometry buffers have been shifted or compacted (e.g. when merging geometries).\n\t * @param {number} offset\n\t */\n\tshiftPrimitiveOffsets( offset ) {\n\n\t\tconst indirectBuffer = this._indirectBuffer;\n\t\tif ( indirectBuffer ) {\n\n\t\t\t// the offsets are embedded in the indirect buffer\n\t\t\tfor ( let i = 0, l = indirectBuffer.length; i < l; i ++ ) {\n\n\t\t\t\tindirectBuffer[ i ] += offset;\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// offsets are embedded in the leaf nodes\n\t\t\tconst roots = this._roots;\n\t\t\tfor ( let rootIndex = 0; rootIndex < roots.length; rootIndex ++ ) {\n\n\t\t\t\tconst root = roots[ rootIndex ];\n\t\t\t\tconst uint32Array = new Uint32Array( root );\n\t\t\t\tconst uint16Array = new Uint16Array( root );\n\t\t\t\tconst totalNodes = root.byteLength / BYTES_PER_NODE;\n\t\t\t\tfor ( let node = 0; node < totalNodes; node ++ ) {\n\n\t\t\t\t\tconst node32Index = UINT32_PER_NODE * node;\n\t\t\t\t\tconst node16Index = 2 * node32Index;\n\t\t\t\t\tif ( IS_LEAF( node16Index, uint16Array ) ) {\n\n\t\t\t\t\t\t// offset value\n\t\t\t\t\t\tuint32Array[ node32Index + 6 ] += offset;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Traverses all nodes of the BVH, invoking a callback for each node.\n\t *\n\t * For leaf nodes the callback receives `( depth, isLeaf, boundingData, offset, count )`.\n\t * For internal nodes it receives `( depth, isLeaf, boundingData, splitAxis )` and may\n\t * return `true` to stop descending into that node's children.\n\t *\n\t * @param {Function} callback\n\t * @param {number} [rootIndex=0]\n\t */\n\ttraverse( callback, rootIndex = 0 ) {\n\n\t\tBVHTraversalHelper.setBVH( this, rootIndex );\n\t\tBVHTraversalHelper.traverse( callback );\n\t\tBVHTraversalHelper.reset();\n\n\t}\n\n\t/**\n\t * Refits all BVH node bounds to reflect the current primitive positions. Faster than\n\t * rebuilding the BVH but produces a less optimal tree after large vertex deformations.\n\t */\n\trefit( /* nodeIndices = null */ ) {\n\n\t\t// TODO: add support for \"nodeIndices\"\n\t\t// if ( nodeIndices && Array.isArray( nodeIndices ) ) {\n\n\t\t// \tnodeIndices = new Set( nodeIndices );\n\n\t\t// }\n\n\t\tconst roots = this._roots;\n\t\tfor ( let rootIndex = 0, rootCount = roots.length; rootIndex < rootCount; rootIndex ++ ) {\n\n\t\t\tconst buffer = roots[ rootIndex ];\n\t\t\tconst uint32Array = new Uint32Array( buffer );\n\t\t\tconst uint16Array = new Uint16Array( buffer );\n\t\t\tconst float32Array = new Float32Array( buffer );\n\t\t\tconst totalNodes = buffer.byteLength / BYTES_PER_NODE;\n\n\t\t\t// Traverse nodes from right to left so children are updated before parents\n\t\t\tfor ( let nodeIndex = totalNodes - 1; nodeIndex >= 0; nodeIndex -- ) {\n\n\t\t\t\tconst nodeIndex32 = nodeIndex * UINT32_PER_NODE;\n\t\t\t\tconst nodeIndex16 = nodeIndex32 * 2;\n\t\t\t\tconst isLeaf = IS_LEAF( nodeIndex16, uint16Array );\n\n\t\t\t\tif ( isLeaf ) {\n\n\t\t\t\t\t// get the bounds\n\t\t\t\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\t\t\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\t\t\t\t\tthis.writePrimitiveRangeBounds( offset, count, _tempBuffer, 0 );\n\n\t\t\t\t\t// write directly to node bounds (already in min/max format)\n\t\t\t\t\tfloat32Array.set( _tempBuffer, nodeIndex32 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconst left = LEFT_NODE( nodeIndex32 );\n\t\t\t\t\tconst right = RIGHT_NODE( nodeIndex32, uint32Array );\n\n\t\t\t\t\t// Union the bounds of left and right children\n\t\t\t\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\tconst leftMin = float32Array[ left + i ];\n\t\t\t\t\t\tconst leftMax = float32Array[ left + i + 3 ];\n\t\t\t\t\t\tconst rightMin = float32Array[ right + i ];\n\t\t\t\t\t\tconst rightMax = float32Array[ right + i + 3 ];\n\n\t\t\t\t\t\tfloat32Array[ nodeIndex32 + i ] = leftMin < rightMin ? leftMin : rightMin;\n\t\t\t\t\t\tfloat32Array[ nodeIndex32 + i + 3 ] = leftMax > rightMax ? leftMax : rightMax;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Computes the axis-aligned bounding box of all primitives in the BVH.\n\t * @param {Box3} target - Target box to write the result into.\n\t * @returns {Box3}\n\t */\n\tgetBoundingBox( target ) {\n\n\t\ttarget.makeEmpty();\n\n\t\tconst roots = this._roots;\n\t\troots.forEach( buffer => {\n\n\t\t\tarrayToBox( 0, new Float32Array( buffer ), _tempBox );\n\t\t\ttarget.union( _tempBox );\n\n\t\t} );\n\n\t\treturn target;\n\n\t}\n\n\t/**\n\t * A generalized traversal function for performing spatial queries against the BVH. Returns\n\t * `true` as soon as a primitive has been reported as intersected. The tree is traversed\n\t * depth-first; `boundsTraverseOrder` controls which child is visited first. Returning\n\t * `CONTAINED` from `intersectsBounds` skips further child traversal and intersects all\n\t * primitives in that subtree immediately.\n\t *\n\t * @param {Object} callbacks\n\t * @param {IntersectsBoundsCallback} callbacks.intersectsBounds\n\t * @param {IntersectsRangeCallback} [callbacks.intersectsRange]\n\t * @param {BoundsTraverseOrderCallback} [callbacks.boundsTraverseOrder]\n\t * @returns {boolean}\n\t */\n\t// TODO: see if we can get rid of \"iterateFunc\" here as well as the primitive so the function\n\t// API aligns with the \"shapecast\" implementation\n\tshapecast( callbacks ) {\n\n\t\t// TODO: can we get rid of \"scratchPrimitive\" and / or \"iterate\"? Or merge them somehow\n\t\tlet {\n\t\t\tboundsTraverseOrder,\n\t\t\tintersectsBounds,\n\t\t\tintersectsRange,\n\t\t\tintersectsPrimitive,\n\t\t\tscratchPrimitive,\n\t\t\titerate,\n\t\t} = callbacks;\n\n\t\t// wrap the intersectsRange function\n\t\tif ( intersectsRange && intersectsPrimitive ) {\n\n\t\t\tconst originalIntersectsRange = intersectsRange;\n\t\t\tintersectsRange = ( offset, count, contained, depth, nodeIndex ) => {\n\n\t\t\t\tif ( ! originalIntersectsRange( offset, count, contained, depth, nodeIndex ) ) {\n\n\t\t\t\t\treturn iterate( offset, count, this, intersectsPrimitive, contained, depth, scratchPrimitive );\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t};\n\n\t\t} else if ( ! intersectsRange ) {\n\n\t\t\tif ( intersectsPrimitive ) {\n\n\t\t\t\tintersectsRange = ( offset, count, contained, depth ) => {\n\n\t\t\t\t\treturn iterate( offset, count, this, intersectsPrimitive, contained, depth, scratchPrimitive );\n\n\t\t\t\t};\n\n\t\t\t} else {\n\n\t\t\t\tintersectsRange = ( offset, count, contained ) => {\n\n\t\t\t\t\treturn contained;\n\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t}\n\n\t\t// run shapecast\n\t\tlet result = false;\n\t\tlet nodeOffset = 0;\n\t\tconst roots = this._roots;\n\t\tfor ( let i = 0, l = roots.length; i < l; i ++ ) {\n\n\t\t\tconst root = roots[ i ];\n\t\t\tresult = shapecastFunc( this, i, intersectsBounds, intersectsRange, boundsTraverseOrder, nodeOffset );\n\n\t\t\tif ( result ) {\n\n\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tnodeOffset += root.byteLength / BYTES_PER_NODE;\n\n\t\t}\n\n\t\treturn result;\n\n\t}\n\n\t/**\n\t * Simultaneously traverses two BVH structures to find intersecting primitive pairs. Returns\n\t * `true` as soon as any intersection is reported. Both trees are traversed depth-first with\n\t * alternating descent. `matrixToLocal` transforms `otherBvh` into the local space of this BVH.\n\t *\n\t * @param {BVH} otherBvh\n\t * @param {Matrix4} matrixToLocal\n\t * @param {Object} callbacks\n\t * @param {IntersectsRangesCallback} callbacks.intersectsRanges\n\t * @returns {boolean}\n\t */\n\tbvhcast( otherBvh, matrixToLocal, callbacks ) {\n\n\t\tlet { intersectsRanges } = callbacks;\n\t\treturn bvhcast( this, otherBvh, matrixToLocal, intersectsRanges );\n\n\n\t}\n\n}\n","export function isSharedArrayBufferSupported() {\n\n\treturn typeof SharedArrayBuffer !== 'undefined';\n\n}\n\nexport function convertToBufferType( array, BufferConstructor ) {\n\n\tif ( array === null ) {\n\n\t\treturn array;\n\n\t} else if ( array.buffer ) {\n\n\t\tconst buffer = array.buffer;\n\t\tif ( buffer.constructor === BufferConstructor ) {\n\n\t\t\treturn array;\n\n\t\t}\n\n\t\tconst ArrayConstructor = array.constructor;\n\t\tconst result = new ArrayConstructor( new BufferConstructor( buffer.byteLength ) );\n\t\tresult.set( array );\n\t\treturn result;\n\n\t} else {\n\n\t\tif ( array.constructor === BufferConstructor ) {\n\n\t\t\treturn array;\n\n\t\t}\n\n\t\tconst result = new BufferConstructor( array.byteLength );\n\t\tnew Uint8Array( result ).set( new Uint8Array( array ) );\n\t\treturn result;\n\n\t}\n\n}\n","import { BufferAttribute } from 'three';\n\nexport function getVertexCount( geo ) {\n\n\treturn geo.index ? geo.index.count : geo.attributes.position.count;\n\n}\n\nexport function getTriCount( geo ) {\n\n\treturn getVertexCount( geo ) / 3;\n\n}\n\nexport function getIndexArray( vertexCount, BufferConstructor = ArrayBuffer ) {\n\n\tif ( vertexCount > 65535 ) {\n\n\t\treturn new Uint32Array( new BufferConstructor( 4 * vertexCount ) );\n\n\t} else {\n\n\t\treturn new Uint16Array( new BufferConstructor( 2 * vertexCount ) );\n\n\t}\n\n}\n\n// ensures that an index is present on the geometry\nexport function ensureIndex( geo, options ) {\n\n\tif ( ! geo.index ) {\n\n\t\tconst vertexCount = geo.attributes.position.count;\n\t\tconst BufferConstructor = options.useSharedArrayBuffer ? SharedArrayBuffer : ArrayBuffer;\n\t\tconst index = getIndexArray( vertexCount, BufferConstructor );\n\t\tgeo.setIndex( new BufferAttribute( index, 1 ) );\n\n\t\tfor ( let i = 0; i < vertexCount; i ++ ) {\n\n\t\t\tindex[ i ] = i;\n\n\t\t}\n\n\t}\n\n}\n\n// Computes the set of { offset, count } ranges which need independent BVH roots. Each\n// region in the geometry index that belongs to a different set of material groups requires\n// a separate BVH root, so that triangles indices belonging to one group never get swapped\n// with triangle indices belongs to another group. For example, if the groups were like this:\n//\n// [-------------------------------------------------------------]\n// |__________________|\n// g0 = [0, 20] |______________________||_____________________|\n// g1 = [16, 40] g2 = [41, 60]\n//\n// we would need four BVH roots: [0, 15], [16, 20], [21, 40], [41, 60].\nfunction getFullPrimitiveRange( geo, range, stride ) {\n\n\tconst primitiveCount = getVertexCount( geo ) / stride;\n\tconst drawRange = range ? range : geo.drawRange;\n\tconst start = drawRange.start / stride;\n\tconst end = ( drawRange.start + drawRange.count ) / stride;\n\n\tconst offset = Math.max( 0, start );\n\tconst count = Math.min( primitiveCount, end ) - offset;\n\treturn {\n\t\toffset: Math.floor( offset ),\n\t\tcount: Math.floor( count ),\n\t};\n\n}\n\nfunction getPrimitiveGroupRanges( geo, stride ) {\n\n\treturn geo.groups.map( group => ( {\n\t\toffset: group.start / stride,\n\t\tcount: group.count / stride,\n\t} ));\n\n}\n\n// Function that extracts a set of mutually exclusive ranges representing the primitives being\n// drawn as determined by the geometry groups, draw range, and user specified range\nexport function getRootPrimitiveRanges( geo, range, stride ) {\n\n\tconst drawRange = getFullPrimitiveRange( geo, range, stride );\n\tconst primitiveRanges = getPrimitiveGroupRanges( geo, stride );\n\tif ( ! primitiveRanges.length ) {\n\n\t\treturn [ drawRange ];\n\n\t}\n\n\tconst ranges = [];\n\tconst drawRangeStart = drawRange.offset;\n\tconst drawRangeEnd = drawRange.offset + drawRange.count;\n\n\t// Create events for group boundaries\n\tconst primitiveCount = getVertexCount( geo ) / stride;\n\tconst events = [];\n\tfor ( const group of primitiveRanges ) {\n\n\t\t// Account for cases where group size is set to Infinity\n\t\tconst { offset, count } = group;\n\t\tconst groupStart = offset;\n\t\tconst groupCount = isFinite( count ) ? count : ( primitiveCount - offset );\n\t\tconst groupEnd = ( offset + groupCount );\n\n\t\t// Only add events if the group intersects with the draw range\n\t\tif ( groupStart < drawRangeEnd && groupEnd > drawRangeStart ) {\n\n\t\t\tevents.push( { pos: Math.max( drawRangeStart, groupStart ), isStart: true } );\n\t\t\tevents.push( { pos: Math.min( drawRangeEnd, groupEnd ), isStart: false } );\n\n\t\t}\n\n\t}\n\n\t// Sort events by position, with 'end' events before 'start' events at the same position\n\tevents.sort( ( a, b ) => {\n\n\t\tif ( a.pos !== b.pos ) {\n\n\t\t\treturn a.pos - b.pos;\n\n\t\t} else {\n\n\t\t\treturn a.type === 'end' ? - 1 : 1;\n\n\t\t}\n\n\t} );\n\n\t// sweep through events and create ranges where activeGroups > 0\n\tlet activeGroups = 0;\n\tlet lastPos = null;\n\tfor ( const event of events ) {\n\n\t\tconst newPos = event.pos;\n\t\tif ( activeGroups !== 0 && newPos !== lastPos ) {\n\n\t\t\tranges.push( {\n\t\t\t\toffset: lastPos,\n\t\t\t\tcount: newPos - lastPos,\n\t\t\t} );\n\n\t\t}\n\n\t\tactiveGroups += event.isStart ? 1 : - 1;\n\t\tlastPos = newPos;\n\n\t}\n\n\treturn ranges;\n\n}\n","/** @import { BufferGeometry } from 'three' */\nimport { Box3 } from 'three';\nimport { SKIP_GENERATION, DEFAULT_OPTIONS } from './Constants.js';\nimport { isSharedArrayBufferSupported } from '../utils/BufferUtils.js';\nimport { ensureIndex, getRootPrimitiveRanges } from './build/geometryUtils.js';\nimport { BVH } from './BVH.js';\n\n// construct a new buffer that points to the set of triangles represented by the given ranges\nexport function generateIndirectBuffer( ranges, useSharedArrayBuffer ) {\n\n\tconst lastRange = ranges[ ranges.length - 1 ];\n\tconst useUint32 = lastRange.offset + lastRange.count > 2 ** 16;\n\n\t// use getRootIndexRanges which excludes gaps\n\tconst length = ranges.reduce( ( acc, val ) => acc + val.count, 0 );\n\tconst byteCount = useUint32 ? 4 : 2;\n\tconst buffer = useSharedArrayBuffer ? new SharedArrayBuffer( length * byteCount ) : new ArrayBuffer( length * byteCount );\n\tconst indirectBuffer = useUint32 ? new Uint32Array( buffer ) : new Uint16Array( buffer );\n\n\t// construct a compact form of the triangles in these ranges\n\tlet index = 0;\n\tfor ( let r = 0; r < ranges.length; r ++ ) {\n\n\t\tconst { offset, count } = ranges[ r ];\n\t\tfor ( let i = 0; i < count; i ++ ) {\n\n\t\t\tindirectBuffer[ index + i ] = offset + i;\n\n\t\t}\n\n\t\tindex += count;\n\n\t}\n\n\treturn indirectBuffer;\n\n}\n\n/**\n * Abstract base class for geometry-backed BVH implementations. Handles geometry\n * indexing, indirect mode, and bounding box initialization. Subclasses implement\n * primitive-specific bounds computation and raycasting via `writePrimitiveBounds`\n * and `raycastObject3D`.\n *\n * @param {BufferGeometry} geometry\n * @param {Object} [options]\n * @param {number} [options.strategy=CENTER] - Split strategy: `CENTER`, `AVERAGE`, or `SAH`.\n * @param {number} [options.maxDepth=40] - Maximum tree depth. Note that this can cause the target leaf size to not\n * be met if the tree is truncated.\n * @param {number} [options.targetLeafSize=10] - The target number of primitives per leaf node. Note that this is\n * a soft limit and generation strategies like SAH will terminate early if the heuristic determines.\n * @param {boolean} [options.setBoundingBox=true] - Set `geometry.boundingBox` if not already present.\n * @param {boolean} [options.useSharedArrayBuffer=false] - Use `SharedArrayBuffer` for BVH root buffers.\n * @param {boolean} [options.indirect=false] - Build using an indirect buffer, leaving the original index unmodified.\n * @param {boolean} [options.verbose=true] - Log build progress to the console.\n * @param {Function|null} [options.onProgress=null] - Called with a progress value in [0, 1] during build.\n * @param {Object|null} [options.range=null] - Restrict the BVH to a specific geometry group range.\n * @extends BVH\n */\nexport class GeometryBVH extends BVH {\n\n\t/**\n\t * Whether the BVH was built in indirect mode.\n\t * @type {boolean}\n\t * @readonly\n\t */\n\tget indirect() {\n\n\t\treturn ! ! this._indirectBuffer;\n\n\t}\n\n\tget primitiveStride() {\n\n\t\treturn null;\n\n\t}\n\n\tget primitiveBufferStride() {\n\n\t\treturn this.indirect ? 1 : this.primitiveStride;\n\n\t}\n\tset primitiveBufferStride( v ) {}\n\n\tget primitiveBuffer() {\n\n\t\treturn this.indirect ? this._indirectBuffer : this.geometry.index.array;\n\n\t}\n\tset primitiveBuffer( v ) {}\n\n\tconstructor( geometry, options = {} ) {\n\n\t\tif ( ! geometry.isBufferGeometry ) {\n\n\t\t\tthrow new Error( 'BVH: Only BufferGeometries are supported.' );\n\n\t\t} else if ( geometry.index && geometry.index.isInterleavedBufferAttribute ) {\n\n\t\t\tthrow new Error( 'BVH: InterleavedBufferAttribute is not supported for the index attribute.' );\n\n\t\t}\n\n\t\tif ( options.useSharedArrayBuffer && ! isSharedArrayBufferSupported() ) {\n\n\t\t\tthrow new Error( 'BVH: SharedArrayBuffer is not available.' );\n\n\t\t}\n\n\t\tsuper();\n\n\t\t// retain references to the geometry so we can use them it without having to\n\t\t// take a geometry reference in every function.\n\n\t\t/**\n\t\t * The geometry this BVH was built from.\n\t\t * @type {BufferGeometry}\n\t\t * @readonly\n\t\t */\n\t\tthis.geometry = geometry;\n\t\tthis.resolvePrimitiveIndex = options.indirect ? i => this._indirectBuffer[ i ] : i => i;\n\t\tthis.primitiveBuffer = null;\n\t\tthis.primitiveBufferStride = null;\n\t\tthis._indirectBuffer = null;\n\n\t\toptions = {\n\t\t\t...DEFAULT_OPTIONS,\n\t\t\t...options,\n\t\t};\n\n\t\t// build the BVH unless we're deserializing\n\t\tif ( ! options[ SKIP_GENERATION ] ) {\n\n\t\t\tthis.init( options );\n\n\t\t}\n\n\t}\n\n\tinit( options ) {\n\n\t\tconst { geometry, primitiveStride } = this;\n\n\t\tif ( options.indirect ) {\n\n\t\t\t// construct an buffer that is indirectly sorts the triangles used for the BVH\n\t\t\tconst ranges = getRootPrimitiveRanges( geometry, options.range, primitiveStride );\n\t\t\tconst indirectBuffer = generateIndirectBuffer( ranges, options.useSharedArrayBuffer );\n\t\t\tthis._indirectBuffer = indirectBuffer;\n\n\t\t} else {\n\n\t\t\tensureIndex( geometry, options );\n\n\t\t}\n\n\t\tsuper.init( options );\n\n\t\tif ( ! geometry.boundingBox && options.setBoundingBox ) {\n\n\t\t\tgeometry.boundingBox = this.getBoundingBox( new Box3() );\n\n\t\t}\n\n\t}\n\n\t// Abstract methods to be implemented by subclasses\n\tgetRootRanges( range ) {\n\n\t\t// TODO: can we avoid passing options in here\n\t\tif ( this.indirect ) {\n\n\t\t\treturn [ { offset: 0, count: this._indirectBuffer.length } ];\n\n\n\t\t} else {\n\n\t\t\treturn getRootPrimitiveRanges( this.geometry, range, this.primitiveStride );\n\n\t\t}\n\n\t}\n\n\traycastObject3D( /* object, raycaster, intersects = [] */ ) {\n\n\t\tthrow new Error( 'BVH: raycastObject3D() not implemented' );\n\n\t}\n\n}\n","import { Vector3 } from 'three';\n\nexport class SeparatingAxisBounds {\n\n\tconstructor() {\n\n\t\tthis.min = Infinity;\n\t\tthis.max = - Infinity;\n\n\t}\n\n\tsetFromPointsField( points, field ) {\n\n\t\tlet min = Infinity;\n\t\tlet max = - Infinity;\n\t\tfor ( let i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\tconst p = points[ i ];\n\t\t\tconst val = p[ field ];\n\t\t\tmin = val < min ? val : min;\n\t\t\tmax = val > max ? val : max;\n\n\t\t}\n\n\t\tthis.min = min;\n\t\tthis.max = max;\n\n\t}\n\n\tsetFromPoints( axis, points ) {\n\n\t\tlet min = Infinity;\n\t\tlet max = - Infinity;\n\t\tfor ( let i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\tconst p = points[ i ];\n\t\t\tconst val = axis.dot( p );\n\t\t\tmin = val < min ? val : min;\n\t\t\tmax = val > max ? val : max;\n\n\t\t}\n\n\t\tthis.min = min;\n\t\tthis.max = max;\n\n\t}\n\n\tisSeparated( other ) {\n\n\t\treturn this.min > other.max || other.min > this.max;\n\n\t}\n\n}\n\nSeparatingAxisBounds.prototype.setFromBox = ( function () {\n\n\tconst p = /* @__PURE__ */ new Vector3();\n\treturn function setFromBox( axis, box ) {\n\n\t\tconst boxMin = box.min;\n\t\tconst boxMax = box.max;\n\t\tlet min = Infinity;\n\t\tlet max = - Infinity;\n\t\tfor ( let x = 0; x <= 1; x ++ ) {\n\n\t\t\tfor ( let y = 0; y <= 1; y ++ ) {\n\n\t\t\t\tfor ( let z = 0; z <= 1; z ++ ) {\n\n\t\t\t\t\tp.x = boxMin.x * x + boxMax.x * ( 1 - x );\n\t\t\t\t\tp.y = boxMin.y * y + boxMax.y * ( 1 - y );\n\t\t\t\t\tp.z = boxMin.z * z + boxMax.z * ( 1 - z );\n\n\t\t\t\t\tconst val = axis.dot( p );\n\t\t\t\t\tmin = Math.min( val, min );\n\t\t\t\t\tmax = Math.max( val, max );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.min = min;\n\t\tthis.max = max;\n\n\t};\n\n} )();\n\nexport const areIntersecting = ( function () {\n\n\tconst cacheSatBounds = /* @__PURE__ */ new SeparatingAxisBounds();\n\treturn function areIntersecting( shape1, shape2 ) {\n\n\t\tconst points1 = shape1.points;\n\t\tconst satAxes1 = shape1.satAxes;\n\t\tconst satBounds1 = shape1.satBounds;\n\n\t\tconst points2 = shape2.points;\n\t\tconst satAxes2 = shape2.satAxes;\n\t\tconst satBounds2 = shape2.satBounds;\n\n\t\t// check axes of the first shape\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tconst sb = satBounds1[ i ];\n\t\t\tconst sa = satAxes1[ i ];\n\t\t\tcacheSatBounds.setFromPoints( sa, points2 );\n\t\t\tif ( sb.isSeparated( cacheSatBounds ) ) return false;\n\n\t\t}\n\n\t\t// check axes of the second shape\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tconst sb = satBounds2[ i ];\n\t\t\tconst sa = satAxes2[ i ];\n\t\t\tcacheSatBounds.setFromPoints( sa, points1 );\n\t\t\tif ( sb.isSeparated( cacheSatBounds ) ) return false;\n\n\t\t}\n\n\t};\n\n} )();\n","import { Vector3, Vector2, Plane, Line3 } from 'three';\n\nexport const closestPointLineToLine = ( function () {\n\n\t// https://github.com/juj/MathGeoLib/blob/master/src/Geometry/Line.cpp#L56\n\tconst dir1 = /* @__PURE__ */ new Vector3();\n\tconst dir2 = /* @__PURE__ */ new Vector3();\n\tconst v02 = /* @__PURE__ */ new Vector3();\n\treturn function closestPointLineToLine( l1, l2, result ) {\n\n\t\tconst v0 = l1.start;\n\t\tconst v10 = dir1;\n\t\tconst v2 = l2.start;\n\t\tconst v32 = dir2;\n\n\t\tv02.subVectors( v0, v2 );\n\t\tdir1.subVectors( l1.end, l1.start );\n\t\tdir2.subVectors( l2.end, l2.start );\n\n\t\t// float d0232 = v02.Dot(v32);\n\t\tconst d0232 = v02.dot( v32 );\n\n\t\t// float d3210 = v32.Dot(v10);\n\t\tconst d3210 = v32.dot( v10 );\n\n\t\t// float d3232 = v32.Dot(v32);\n\t\tconst d3232 = v32.dot( v32 );\n\n\t\t// float d0210 = v02.Dot(v10);\n\t\tconst d0210 = v02.dot( v10 );\n\n\t\t// float d1010 = v10.Dot(v10);\n\t\tconst d1010 = v10.dot( v10 );\n\n\t\t// float denom = d1010*d3232 - d3210*d3210;\n\t\tconst denom = d1010 * d3232 - d3210 * d3210;\n\n\t\tlet d, d2;\n\t\tif ( denom !== 0 ) {\n\n\t\t\td = ( d0232 * d3210 - d0210 * d3232 ) / denom;\n\n\t\t} else {\n\n\t\t\td = 0;\n\n\t\t}\n\n\t\td2 = ( d0232 + d * d3210 ) / d3232;\n\n\t\tresult.x = d;\n\t\tresult.y = d2;\n\n\t};\n\n} )();\n\nexport const closestPointsSegmentToSegment = ( function () {\n\n\t// https://github.com/juj/MathGeoLib/blob/master/src/Geometry/LineSegment.cpp#L187\n\tconst paramResult = /* @__PURE__ */ new Vector2();\n\tconst temp1 = /* @__PURE__ */ new Vector3();\n\tconst temp2 = /* @__PURE__ */ new Vector3();\n\treturn function closestPointsSegmentToSegment( l1, l2, target1, target2 ) {\n\n\t\tclosestPointLineToLine( l1, l2, paramResult );\n\n\t\tlet d = paramResult.x;\n\t\tlet d2 = paramResult.y;\n\t\tif ( d >= 0 && d <= 1 && d2 >= 0 && d2 <= 1 ) {\n\n\t\t\tl1.at( d, target1 );\n\t\t\tl2.at( d2, target2 );\n\n\t\t\treturn;\n\n\t\t} else if ( d >= 0 && d <= 1 ) {\n\n\t\t\t// Only d2 is out of bounds.\n\t\t\tif ( d2 < 0 ) {\n\n\t\t\t\tl2.at( 0, target2 );\n\n\t\t\t} else {\n\n\t\t\t\tl2.at( 1, target2 );\n\n\t\t\t}\n\n\t\t\tl1.closestPointToPoint( target2, true, target1 );\n\t\t\treturn;\n\n\t\t} else if ( d2 >= 0 && d2 <= 1 ) {\n\n\t\t\t// Only d is out of bounds.\n\t\t\tif ( d < 0 ) {\n\n\t\t\t\tl1.at( 0, target1 );\n\n\t\t\t} else {\n\n\t\t\t\tl1.at( 1, target1 );\n\n\t\t\t}\n\n\t\t\tl2.closestPointToPoint( target1, true, target2 );\n\t\t\treturn;\n\n\t\t} else {\n\n\t\t\t// Both u and u2 are out of bounds.\n\t\t\tlet p;\n\t\t\tif ( d < 0 ) {\n\n\t\t\t\tp = l1.start;\n\n\t\t\t} else {\n\n\t\t\t\tp = l1.end;\n\n\t\t\t}\n\n\t\t\tlet p2;\n\t\t\tif ( d2 < 0 ) {\n\n\t\t\t\tp2 = l2.start;\n\n\t\t\t} else {\n\n\t\t\t\tp2 = l2.end;\n\n\t\t\t}\n\n\t\t\tconst closestPoint = temp1;\n\t\t\tconst closestPoint2 = temp2;\n\t\t\tl1.closestPointToPoint( p2, true, temp1 );\n\t\t\tl2.closestPointToPoint( p, true, temp2 );\n\n\t\t\tif ( closestPoint.distanceToSquared( p2 ) <= closestPoint2.distanceToSquared( p ) ) {\n\n\t\t\t\ttarget1.copy( closestPoint );\n\t\t\t\ttarget2.copy( p2 );\n\t\t\t\treturn;\n\n\t\t\t} else {\n\n\t\t\t\ttarget1.copy( p );\n\t\t\t\ttarget2.copy( closestPoint2 );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n} )();\n\n\nexport const sphereIntersectTriangle = ( function () {\n\n\t// https://stackoverflow.com/questions/34043955/detect-collision-between-sphere-and-triangle-in-three-js\n\tconst closestPointTemp = /* @__PURE__ */ new Vector3();\n\tconst projectedPointTemp = /* @__PURE__ */ new Vector3();\n\tconst planeTemp = /* @__PURE__ */ new Plane();\n\tconst lineTemp = /* @__PURE__ */ new Line3();\n\treturn function sphereIntersectTriangle( sphere, triangle ) {\n\n\t\tconst { radius, center } = sphere;\n\t\tconst { a, b, c } = triangle;\n\n\t\t// phase 1\n\t\tlineTemp.start = a;\n\t\tlineTemp.end = b;\n\t\tconst closestPoint1 = lineTemp.closestPointToPoint( center, true, closestPointTemp );\n\t\tif ( closestPoint1.distanceTo( center ) <= radius ) return true;\n\n\t\tlineTemp.start = a;\n\t\tlineTemp.end = c;\n\t\tconst closestPoint2 = lineTemp.closestPointToPoint( center, true, closestPointTemp );\n\t\tif ( closestPoint2.distanceTo( center ) <= radius ) return true;\n\n\t\tlineTemp.start = b;\n\t\tlineTemp.end = c;\n\t\tconst closestPoint3 = lineTemp.closestPointToPoint( center, true, closestPointTemp );\n\t\tif ( closestPoint3.distanceTo( center ) <= radius ) return true;\n\n\t\t// phase 2\n\t\tconst plane = triangle.getPlane( planeTemp );\n\t\tconst dp = Math.abs( plane.distanceToPoint( center ) );\n\t\tif ( dp <= radius ) {\n\n\t\t\tconst pp = plane.projectPoint( center, projectedPointTemp );\n\t\t\tconst cp = triangle.containsPoint( pp );\n\t\t\tif ( cp ) return true;\n\n\t\t}\n\n\t\treturn false;\n\n\t};\n\n} )();\n","/** @import { Sphere } from 'three' */\nimport { Triangle, Vector3, Vector2, Line3, Plane } from 'three';\nimport { SeparatingAxisBounds } from './SeparatingAxisBounds.js';\nimport { closestPointsSegmentToSegment, sphereIntersectTriangle } from './MathUtilities.js';\n\nconst componentKeys = [ 'x', 'y', 'z' ];\nconst ZERO_EPSILON = 1e-15;\nconst ZERO_EPSILON_SQR = ZERO_EPSILON * ZERO_EPSILON;\nfunction isNearZero( value ) {\n\n\treturn Math.abs( value ) < ZERO_EPSILON;\n\n}\n\n/**\n * An extended version of three.js' Triangle class. A variety of derivative values are cached on\n * the object to accelerate the intersection functions. `.needsUpdate` must be set to true when\n * modifying the triangle parameters.\n * @extends Triangle\n */\nexport class ExtendedTriangle extends Triangle {\n\n\tconstructor( ...args ) {\n\n\t\tsuper( ...args );\n\n\t\tthis.isExtendedTriangle = true;\n\t\tthis.satAxes = new Array( 4 ).fill().map( () => new Vector3() );\n\t\tthis.satBounds = new Array( 4 ).fill().map( () => new SeparatingAxisBounds() );\n\t\tthis.points = [ this.a, this.b, this.c ];\n\t\tthis.plane = new Plane();\n\t\tthis.isDegenerateIntoSegment = false;\n\t\tthis.isDegenerateIntoPoint = false;\n\t\tthis.degenerateSegment = new Line3();\n\n\t\t/**\n\t\t * Indicates that the triangle fields have changed so cached variables to accelerate other\n\t\t * function execution can be updated. Must be set to true after modifying the triangle\n\t\t * `a`, `b`, `c` fields.\n\t\t * @type {boolean}\n\t\t */\n\t\tthis.needsUpdate = true;\n\n\t}\n\n\t/**\n\t * Returns whether the triangle intersects the given sphere.\n\t * @param {Sphere} sphere\n\t * @returns {boolean}\n\t */\n\tintersectsSphere( sphere ) {\n\n\t\treturn sphereIntersectTriangle( sphere, this );\n\n\t}\n\n\tupdate() {\n\n\t\tconst a = this.a;\n\t\tconst b = this.b;\n\t\tconst c = this.c;\n\t\tconst points = this.points;\n\n\t\tconst satAxes = this.satAxes;\n\t\tconst satBounds = this.satBounds;\n\n\t\tconst axis0 = satAxes[ 0 ];\n\t\tconst sab0 = satBounds[ 0 ];\n\t\tthis.getNormal( axis0 );\n\t\tsab0.setFromPoints( axis0, points );\n\n\t\tconst axis1 = satAxes[ 1 ];\n\t\tconst sab1 = satBounds[ 1 ];\n\t\taxis1.subVectors( a, b );\n\t\tsab1.setFromPoints( axis1, points );\n\n\t\tconst axis2 = satAxes[ 2 ];\n\t\tconst sab2 = satBounds[ 2 ];\n\t\taxis2.subVectors( b, c );\n\t\tsab2.setFromPoints( axis2, points );\n\n\t\tconst axis3 = satAxes[ 3 ];\n\t\tconst sab3 = satBounds[ 3 ];\n\t\taxis3.subVectors( c, a );\n\t\tsab3.setFromPoints( axis3, points );\n\n\t\tconst lengthAB = axis1.length();\n\t\tconst lengthBC = axis2.length();\n\t\tconst lengthCA = axis3.length();\n\n\t\tthis.isDegenerateIntoPoint = false;\n\t\tthis.isDegenerateIntoSegment = false;\n\n\t\tif ( lengthAB < ZERO_EPSILON ) {\n\n\t\t\tif ( lengthBC < ZERO_EPSILON || lengthCA < ZERO_EPSILON ) {\n\n\t\t\t\tthis.isDegenerateIntoPoint = true;\n\n\t\t\t} else {\n\n\t\t\t\tthis.isDegenerateIntoSegment = true;\n\t\t\t\tthis.degenerateSegment.start.copy( a );\n\t\t\t\tthis.degenerateSegment.end.copy( c );\n\n\t\t\t}\n\n\t\t} else if ( lengthBC < ZERO_EPSILON ) {\n\n\t\t\tif ( lengthCA < ZERO_EPSILON ) {\n\n\t\t\t\tthis.isDegenerateIntoPoint = true;\n\n\t\t\t} else {\n\n\t\t\t\tthis.isDegenerateIntoSegment = true;\n\t\t\t\tthis.degenerateSegment.start.copy( b );\n\t\t\t\tthis.degenerateSegment.end.copy( a );\n\n\t\t\t}\n\n\t\t} else if ( lengthCA < ZERO_EPSILON ) {\n\n\t\t\tthis.isDegenerateIntoSegment = true;\n\t\t\tthis.degenerateSegment.start.copy( c );\n\t\t\tthis.degenerateSegment.end.copy( b );\n\n\t\t}\n\n\t\tthis.plane.setFromNormalAndCoplanarPoint( axis0, a );\n\n\t\tthis.needsUpdate = false;\n\n\t}\n\n}\n\n/**\n * Returns the distance to the provided line segment. `target1` and `target2` are set to the\n * closest points on the triangle and segment respectively.\n * @function\n * @param {Line3} segment\n * @param {Vector3} [target1]\n * @param {Vector3} [target2]\n * @returns {number}\n */\nExtendedTriangle.prototype.closestPointToSegment = ( function () {\n\n\tconst point1 = /* @__PURE__ */ new Vector3();\n\tconst point2 = /* @__PURE__ */ new Vector3();\n\tconst edge = /* @__PURE__ */ new Line3();\n\n\treturn function distanceToSegment( segment, target1 = null, target2 = null ) {\n\n\t\tconst { start, end } = segment;\n\t\tconst points = this.points;\n\t\tlet distSq;\n\t\tlet closestDistanceSq = Infinity;\n\n\t\t// check the triangle edges\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tconst nexti = ( i + 1 ) % 3;\n\t\t\tedge.start.copy( points[ i ] );\n\t\t\tedge.end.copy( points[ nexti ] );\n\n\t\t\tclosestPointsSegmentToSegment( edge, segment, point1, point2 );\n\n\t\t\tdistSq = point1.distanceToSquared( point2 );\n\t\t\tif ( distSq < closestDistanceSq ) {\n\n\t\t\t\tclosestDistanceSq = distSq;\n\t\t\t\tif ( target1 ) target1.copy( point1 );\n\t\t\t\tif ( target2 ) target2.copy( point2 );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// check end points\n\t\tthis.closestPointToPoint( start, point1 );\n\t\tdistSq = start.distanceToSquared( point1 );\n\t\tif ( distSq < closestDistanceSq ) {\n\n\t\t\tclosestDistanceSq = distSq;\n\t\t\tif ( target1 ) target1.copy( point1 );\n\t\t\tif ( target2 ) target2.copy( start );\n\n\t\t}\n\n\t\tthis.closestPointToPoint( end, point1 );\n\t\tdistSq = end.distanceToSquared( point1 );\n\t\tif ( distSq < closestDistanceSq ) {\n\n\t\t\tclosestDistanceSq = distSq;\n\t\t\tif ( target1 ) target1.copy( point1 );\n\t\t\tif ( target2 ) target2.copy( end );\n\n\t\t}\n\n\t\treturn Math.sqrt( closestDistanceSq );\n\n\t};\n\n} )();\n\n/**\n * Returns whether the triangles intersect. `target` is set to the line segment representing\n * the intersection.\n * @function\n * @param {Triangle} other\n * @param {Line3} [target]\n * @param {boolean} [suppressLog=false]\n * @returns {boolean}\n */\nExtendedTriangle.prototype.intersectsTriangle = ( function () {\n\n\tconst saTri2 = /* @__PURE__ */ new ExtendedTriangle();\n\tconst cachedSatBounds = /* @__PURE__ */ new SeparatingAxisBounds();\n\tconst cachedSatBounds2 = /* @__PURE__ */ new SeparatingAxisBounds();\n\tconst tmpVec = /* @__PURE__ */ new Vector3();\n\tconst dir1 = /* @__PURE__ */ new Vector3();\n\tconst dir2 = /* @__PURE__ */ new Vector3();\n\tconst tempDir = /* @__PURE__ */ new Vector3();\n\tconst edge1 = /* @__PURE__ */ new Line3();\n\tconst edge2 = /* @__PURE__ */ new Line3();\n\tconst tempPoint = /* @__PURE__ */ new Vector3();\n\tconst bounds1 = /* @__PURE__ */ new Vector2();\n\tconst bounds2 = /* @__PURE__ */ new Vector2();\n\n\tfunction coplanarIntersectsTriangle( self, other, target, suppressLog ) {\n\n\t\t// Perform separating axis intersection test only for coplanar triangles\n\t\t// There should be at least one non-degenerate triangle when calling this\n\t\t// Otherwise we won't know the plane normal\n\t\tconst planeNormal = tmpVec;\n\t\tif ( ! self.isDegenerateIntoPoint && ! self.isDegenerateIntoSegment ) {\n\n\t\t\tplaneNormal.copy( self.plane.normal );\n\n\t\t} else {\n\n\t\t\tplaneNormal.copy( other.plane.normal );\n\n\t\t}\n\n\t\tconst satBounds1 = self.satBounds;\n\t\tconst satAxes1 = self.satAxes;\n\t\tfor ( let i = 1; i < 4; i ++ ) {\n\n\t\t\tconst sb = satBounds1[ i ];\n\t\t\tconst sa = satAxes1[ i ];\n\t\t\tcachedSatBounds.setFromPoints( sa, other.points );\n\t\t\tif ( sb.isSeparated( cachedSatBounds ) ) return false;\n\n\t\t\ttempDir.copy( planeNormal ).cross( sa );\n\t\t\tcachedSatBounds.setFromPoints( tempDir, self.points );\n\t\t\tcachedSatBounds2.setFromPoints( tempDir, other.points );\n\t\t\tif ( cachedSatBounds.isSeparated( cachedSatBounds2 ) ) return false;\n\n\t\t}\n\n\t\tconst satBounds2 = other.satBounds;\n\t\tconst satAxes2 = other.satAxes;\n\t\tfor ( let i = 1; i < 4; i ++ ) {\n\n\t\t\tconst sb = satBounds2[ i ];\n\t\t\tconst sa = satAxes2[ i ];\n\t\t\tcachedSatBounds.setFromPoints( sa, self.points );\n\t\t\tif ( sb.isSeparated( cachedSatBounds ) ) return false;\n\n\t\t\ttempDir.crossVectors( planeNormal, sa );\n\t\t\tcachedSatBounds.setFromPoints( tempDir, self.points );\n\t\t\tcachedSatBounds2.setFromPoints( tempDir, other.points );\n\t\t\tif ( cachedSatBounds.isSeparated( cachedSatBounds2 ) ) return false;\n\n\t\t}\n\n\t\tif ( target ) {\n\n\t\t\t// TODO find two points that intersect on the edges and make that the result\n\t\t\tif ( ! suppressLog ) {\n\n\t\t\t\tconsole.warn( 'ExtendedTriangle.intersectsTriangle: Triangles are coplanar which does not support an output edge. Setting edge to 0, 0, 0.' );\n\n\t\t\t}\n\n\t\t\ttarget.start.set( 0, 0, 0 );\n\t\t\ttarget.end.set( 0, 0, 0 );\n\n\t\t}\n\n\t\treturn true;\n\n\t}\n\n\tfunction findSingleBounds( a, b, c, aProj, bProj, cProj, aDist, bDist, cDist, bounds, edge ) {\n\n\t\tlet t = aDist / ( aDist - bDist );\n\t\tbounds.x = aProj + ( bProj - aProj ) * t;\n\t\tedge.start.subVectors( b, a ).multiplyScalar( t ).add( a );\n\n\t\tt = aDist / ( aDist - cDist );\n\t\tbounds.y = aProj + ( cProj - aProj ) * t;\n\t\tedge.end.subVectors( c, a ).multiplyScalar( t ).add( a );\n\n\t}\n\n\t/**\n\t * Calculates intersection segment of a triangle with intersection line.\n\t * Intersection line is snapped to its biggest component.\n\t * And triangle points are passed as a projection on that component.\n\t * @returns {boolean} whether this is a coplanar case or not\n\t */\n\tfunction findIntersectionLineBounds( self, aProj, bProj, cProj, abDist, acDist, aDist, bDist, cDist, bounds, edge ) {\n\n\t\tif ( abDist > 0 ) {\n\n\t\t\t// then bcDist < 0\n\t\t\tfindSingleBounds( self.c, self.a, self.b, cProj, aProj, bProj, cDist, aDist, bDist, bounds, edge );\n\n\t\t} else if ( acDist > 0 ) {\n\n\t\t\tfindSingleBounds( self.b, self.a, self.c, bProj, aProj, cProj, bDist, aDist, cDist, bounds, edge );\n\n\t\t} else if ( bDist * cDist > 0 || aDist != 0 ) {\n\n\t\t\tfindSingleBounds( self.a, self.b, self.c, aProj, bProj, cProj, aDist, bDist, cDist, bounds, edge );\n\n\t\t} else if ( bDist != 0 ) {\n\n\t\t\tfindSingleBounds( self.b, self.a, self.c, bProj, aProj, cProj, bDist, aDist, cDist, bounds, edge );\n\n\t\t} else if ( cDist != 0 ) {\n\n\t\t\tfindSingleBounds( self.c, self.a, self.b, cProj, aProj, bProj, cDist, aDist, bDist, bounds, edge );\n\n\t\t} else {\n\n\t\t\treturn true;\n\n\t\t}\n\n\t\treturn false;\n\n\t}\n\n\tfunction intersectTriangleSegment( triangle, degenerateTriangle, target, suppressLog ) {\n\n\t\tconst segment = degenerateTriangle.degenerateSegment;\n\t\tconst startDist = triangle.plane.distanceToPoint( segment.start );\n\t\tconst endDist = triangle.plane.distanceToPoint( segment.end );\n\t\tif ( isNearZero( startDist ) ) {\n\n\t\t\tif ( isNearZero( endDist ) ) {\n\n\t\t\t\treturn coplanarIntersectsTriangle( triangle, degenerateTriangle, target, suppressLog );\n\n\t\t\t} else {\n\n\t\t\t\t// Is this fine to modify target even if there might be no intersection?\n\t\t\t\tif ( target ) {\n\n\t\t\t\t\ttarget.start.copy( segment.start );\n\t\t\t\t\ttarget.end.copy( segment.start );\n\n\t\t\t\t}\n\n\t\t\t\treturn triangle.containsPoint( segment.start );\n\n\t\t\t}\n\n\t\t} else if ( isNearZero( endDist ) ) {\n\n\t\t\tif ( target ) {\n\n\t\t\t\ttarget.start.copy( segment.end );\n\t\t\t\ttarget.end.copy( segment.end );\n\n\t\t\t}\n\n\t\t\treturn triangle.containsPoint( segment.end );\n\n\t\t} else {\n\n\t\t\tif ( triangle.plane.intersectLine( segment, tmpVec ) != null ) {\n\n\t\t\t\tif ( target ) {\n\n\t\t\t\t\ttarget.start.copy( tmpVec );\n\t\t\t\t\ttarget.end.copy( tmpVec );\n\n\t\t\t\t}\n\n\t\t\t\treturn triangle.containsPoint( tmpVec );\n\n\t\t\t} else {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tfunction intersectTrianglePoint( triangle, degenerateTriangle, target ) {\n\n\t\tconst point = degenerateTriangle.a;\n\n\t\tif ( isNearZero( triangle.plane.distanceToPoint( point ) ) && triangle.containsPoint( point ) ) {\n\n\t\t\tif ( target ) {\n\n\t\t\t\ttarget.start.copy( point );\n\t\t\t\ttarget.end.copy( point );\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t} else {\n\n\t\t\treturn false;\n\n\t\t}\n\n\t}\n\n\tfunction intersectSegmentPoint( segmentTri, pointTri, target ) {\n\n\t\tconst segment = segmentTri.degenerateSegment;\n\t\tconst point = pointTri.a;\n\n\t\tsegment.closestPointToPoint( point, true, tmpVec );\n\n\t\tif ( point.distanceToSquared( tmpVec ) < ZERO_EPSILON_SQR ) {\n\n\t\t\tif ( target ) {\n\n\t\t\t\ttarget.start.copy( point );\n\t\t\t\ttarget.end.copy( point );\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t} else {\n\n\t\t\treturn false;\n\n\t\t}\n\n\t}\n\n\tfunction handleDegenerateCases( self, other, target, suppressLog ) {\n\n\t\tif ( self.isDegenerateIntoSegment ) {\n\n\t\t\tif ( other.isDegenerateIntoSegment ) {\n\n\t\t\t\t// TODO: replace with Line.distanceSqToLine3 after r179\n\t\t\t\tconst segment1 = self.degenerateSegment;\n\t\t\t\tconst segment2 = other.degenerateSegment;\n\t\t\t\tconst delta1 = dir1;\n\t\t\t\tconst delta2 = dir2;\n\t\t\t\tsegment1.delta( delta1 );\n\t\t\t\tsegment2.delta( delta2 );\n\t\t\t\tconst startDelta = tmpVec.subVectors( segment2.start, segment1.start );\n\n\t\t\t\tconst denom = delta1.x * delta2.y - delta1.y * delta2.x;\n\t\t\t\tif ( isNearZero( denom ) ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t\tconst t = ( startDelta.x * delta2.y - startDelta.y * delta2.x ) / denom;\n\t\t\t\tconst u = - ( delta1.x * startDelta.y - delta1.y * startDelta.x ) / denom;\n\n\t\t\t\tif ( t < 0 || t > 1 || u < 0 || u > 1 ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t\tconst z1 = segment1.start.z + delta1.z * t;\n\t\t\t\tconst z2 = segment2.start.z + delta2.z * u;\n\n\t\t\t\tif ( isNearZero( z1 - z2 ) ) {\n\n\t\t\t\t\tif ( target ) {\n\n\t\t\t\t\t\ttarget.start.copy( segment1.start ).addScaledVector( delta1, t );\n\t\t\t\t\t\ttarget.end.copy( segment1.start ).addScaledVector( delta1, t );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t} else if ( other.isDegenerateIntoPoint ) {\n\n\t\t\t\treturn intersectSegmentPoint( self, other, target );\n\n\t\t\t} else {\n\n\t\t\t\treturn intersectTriangleSegment( other, self, target, suppressLog );\n\n\t\t\t}\n\n\t\t} else if ( self.isDegenerateIntoPoint ) {\n\n\t\t\tif ( other.isDegenerateIntoPoint ) {\n\n\t\t\t\tif ( other.a.distanceToSquared( self.a ) < ZERO_EPSILON_SQR ) {\n\n\t\t\t\t\tif ( target ) {\n\n\t\t\t\t\t\ttarget.start.copy( self.a );\n\t\t\t\t\t\ttarget.end.copy( self.a );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t} else if ( other.isDegenerateIntoSegment ) {\n\n\t\t\t\treturn intersectSegmentPoint( other, self, target );\n\n\t\t\t} else {\n\n\t\t\t\treturn intersectTrianglePoint( other, self, target );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tif ( other.isDegenerateIntoPoint ) {\n\n\t\t\t\treturn intersectTrianglePoint( self, other, target );\n\n\t\t\t} else if ( other.isDegenerateIntoSegment ) {\n\n\t\t\t\treturn intersectTriangleSegment( self, other, target, suppressLog );\n\n\t\t\t} /* else this is a general triangle-traingle case, so return undefined */\n\n\t\t}\n\n\t}\n\n\t/* TODO: If the triangles are coplanar and intersecting the target is nonsensical. It should at least\n\t * be a line contained by both triangles if not a different special case somehow represented in the return result.\n\t *\n\t * General triangle intersection code is based on Moller's algorithm from here: https://web.stanford.edu/class/cs277/resources/papers/Moller1997b.pdf\n\t * Reference implementation from here: https://github.com/erich666/jgt-code/blob/master/Volume_08/Number_1/Shen2003/tri_tri_test/include/Moller97.c#L570\n\t * All degeneracies are handled before the general algorithm.\n\t * Coplanar check is different from Moller's and based on SAT tests.\n\t */\n\treturn function intersectsTriangle( other, target = null, suppressLog = false ) {\n\n\t\tif ( this.needsUpdate ) {\n\n\t\t\tthis.update();\n\n\t\t}\n\n\t\tif ( ! other.isExtendedTriangle ) {\n\n\t\t\tsaTri2.copy( other );\n\t\t\tsaTri2.update();\n\t\t\tother = saTri2;\n\n\t\t} else if ( other.needsUpdate ) {\n\n\t\t\tother.update();\n\n\t\t}\n\n\t\tconst res = handleDegenerateCases( this, other, target, suppressLog );\n\t\tif ( res !== undefined ) {\n\n\t\t\treturn res;\n\n\t\t}\n\n\t\tconst plane1 = this.plane;\n\t\tconst plane2 = other.plane;\n\n\t\tlet a1Dist = plane2.distanceToPoint( this.a );\n\t\tlet b1Dist = plane2.distanceToPoint( this.b );\n\t\tlet c1Dist = plane2.distanceToPoint( this.c );\n\n\t\tif ( isNearZero( a1Dist ) )\n\t\t\ta1Dist = 0;\n\n\t\tif ( isNearZero( b1Dist ) )\n\t\t\tb1Dist = 0;\n\n\t\tif ( isNearZero( c1Dist ) )\n\t\t\tc1Dist = 0;\n\n\t\tconst a1b1Dist = a1Dist * b1Dist;\n\t\tconst a1c1Dist = a1Dist * c1Dist;\n\t\tif ( a1b1Dist > 0 && a1c1Dist > 0 ) {\n\n\t\t\treturn false;\n\n\t\t}\n\n\t\tlet a2Dist = plane1.distanceToPoint( other.a );\n\t\tlet b2Dist = plane1.distanceToPoint( other.b );\n\t\tlet c2Dist = plane1.distanceToPoint( other.c );\n\n\t\tif ( isNearZero( a2Dist ) )\n\t\t\ta2Dist = 0;\n\n\t\tif ( isNearZero( b2Dist ) )\n\t\t\tb2Dist = 0;\n\n\t\tif ( isNearZero( c2Dist ) )\n\t\t\tc2Dist = 0;\n\n\t\tconst a2b2Dist = a2Dist * b2Dist;\n\t\tconst a2c2Dist = a2Dist * c2Dist;\n\t\tif ( a2b2Dist > 0 && a2c2Dist > 0 ) {\n\n\t\t\treturn false;\n\n\t\t}\n\n\t\tdir1.copy( plane1.normal );\n\t\tdir2.copy( plane2.normal );\n\t\tconst intersectionLine = dir1.cross( dir2 );\n\n\t\tlet componentIndex = 0;\n\t\tlet maxComponent = Math.abs( intersectionLine.x );\n\t\tconst comp1 = Math.abs( intersectionLine.y );\n\t\tif ( comp1 > maxComponent ) {\n\n\t\t\tmaxComponent = comp1;\n\t\t\tcomponentIndex = 1;\n\n\t\t}\n\n\t\tconst comp2 = Math.abs( intersectionLine.z );\n\t\tif ( comp2 > maxComponent ) {\n\n\t\t\tcomponentIndex = 2;\n\n\t\t}\n\n\t\tconst key = componentKeys[ componentIndex ];\n\t\tconst a1Proj = this.a[ key ];\n\t\tconst b1Proj = this.b[ key ];\n\t\tconst c1Proj = this.c[ key ];\n\n\t\tconst a2Proj = other.a[ key ];\n\t\tconst b2Proj = other.b[ key ];\n\t\tconst c2Proj = other.c[ key ];\n\n\t\tif ( findIntersectionLineBounds( this, a1Proj, b1Proj, c1Proj, a1b1Dist, a1c1Dist, a1Dist, b1Dist, c1Dist, bounds1, edge1 ) ) {\n\n\t\t\treturn coplanarIntersectsTriangle( this, other, target, suppressLog );\n\n\t\t}\n\n\t\tif ( findIntersectionLineBounds( other, a2Proj, b2Proj, c2Proj, a2b2Dist, a2c2Dist, a2Dist, b2Dist, c2Dist, bounds2, edge2 ) ) {\n\n\t\t\treturn coplanarIntersectsTriangle( this, other, target, suppressLog );\n\n\t\t}\n\n\t\tif ( bounds1.y < bounds1.x ) {\n\n\t\t\tconst tmp = bounds1.y;\n\t\t\tbounds1.y = bounds1.x;\n\t\t\tbounds1.x = tmp;\n\n\t\t\ttempPoint.copy( edge1.start );\n\t\t\tedge1.start.copy( edge1.end );\n\t\t\tedge1.end.copy( tempPoint );\n\n\t\t}\n\n\t\tif ( bounds2.y < bounds2.x ) {\n\n\t\t\tconst tmp = bounds2.y;\n\t\t\tbounds2.y = bounds2.x;\n\t\t\tbounds2.x = tmp;\n\n\t\t\ttempPoint.copy( edge2.start );\n\t\t\tedge2.start.copy( edge2.end );\n\t\t\tedge2.end.copy( tempPoint );\n\n\t\t}\n\n\t\tif ( bounds1.y < bounds2.x || bounds2.y < bounds1.x ) {\n\n\t\t\treturn false;\n\n\t\t}\n\n\t\tif ( target ) {\n\n\t\t\tif ( bounds2.x > bounds1.x ) {\n\n\t\t\t\ttarget.start.copy( edge2.start );\n\n\t\t\t} else {\n\n\t\t\t\ttarget.start.copy( edge1.start );\n\n\t\t\t}\n\n\t\t\tif ( bounds2.y < bounds1.y ) {\n\n\t\t\t\ttarget.end.copy( edge2.end );\n\n\t\t\t} else {\n\n\t\t\t\ttarget.end.copy( edge1.end );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn true;\n\n\t};\n\n} )();\n\n\n/**\n * Returns the distance to the provided point.\n * @function\n * @param {Vector3} point\n * @returns {number}\n */\nExtendedTriangle.prototype.distanceToPoint = ( function () {\n\n\tconst target = /* @__PURE__ */ new Vector3();\n\treturn function distanceToPoint( point ) {\n\n\t\tthis.closestPointToPoint( point, target );\n\t\treturn point.distanceTo( target );\n\n\t};\n\n} )();\n\n\n/**\n * Returns the distance to the provided triangle.\n * @function\n * @param {Triangle} other\n * @param {Vector3} [target1]\n * @param {Vector3} [target2]\n * @returns {number}\n */\nExtendedTriangle.prototype.distanceToTriangle = ( function () {\n\n\tconst point = /* @__PURE__ */ new Vector3();\n\tconst point2 = /* @__PURE__ */ new Vector3();\n\tconst cornerFields = [ 'a', 'b', 'c' ];\n\tconst line1 = /* @__PURE__ */ new Line3();\n\tconst line2 = /* @__PURE__ */ new Line3();\n\n\treturn function distanceToTriangle( other, target1 = null, target2 = null ) {\n\n\t\tconst lineTarget = target1 || target2 ? line1 : null;\n\t\t// `intersectsTriangle` returns a zero-length segment for coplanar\n\t\t// intersecting triangles, which is fine for our purposes here. We\n\t\t// don't need the segment itself in this function. So we can suppress\n\t\t// the warning about coplanar triangles.\n\t\tif ( this.intersectsTriangle( other, lineTarget, true ) ) {\n\n\t\t\tif ( target1 || target2 ) {\n\n\t\t\t\tif ( target1 ) lineTarget.getCenter( target1 );\n\t\t\t\tif ( target2 ) lineTarget.getCenter( target2 );\n\n\t\t\t}\n\n\t\t\treturn 0;\n\n\t\t}\n\n\t\tlet closestDistanceSq = Infinity;\n\n\t\t// check all point distances\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tlet dist;\n\t\t\tconst field = cornerFields[ i ];\n\t\t\tconst otherVec = other[ field ];\n\t\t\tthis.closestPointToPoint( otherVec, point );\n\n\t\t\tdist = otherVec.distanceToSquared( point );\n\n\t\t\tif ( dist < closestDistanceSq ) {\n\n\t\t\t\tclosestDistanceSq = dist;\n\t\t\t\tif ( target1 ) target1.copy( point );\n\t\t\t\tif ( target2 ) target2.copy( otherVec );\n\n\t\t\t}\n\n\n\t\t\tconst thisVec = this[ field ];\n\t\t\tother.closestPointToPoint( thisVec, point );\n\n\t\t\tdist = thisVec.distanceToSquared( point );\n\n\t\t\tif ( dist < closestDistanceSq ) {\n\n\t\t\t\tclosestDistanceSq = dist;\n\t\t\t\tif ( target1 ) target1.copy( thisVec );\n\t\t\t\tif ( target2 ) target2.copy( point );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tconst f11 = cornerFields[ i ];\n\t\t\tconst f12 = cornerFields[ ( i + 1 ) % 3 ];\n\t\t\tline1.set( this[ f11 ], this[ f12 ] );\n\t\t\tfor ( let i2 = 0; i2 < 3; i2 ++ ) {\n\n\t\t\t\tconst f21 = cornerFields[ i2 ];\n\t\t\t\tconst f22 = cornerFields[ ( i2 + 1 ) % 3 ];\n\t\t\t\tline2.set( other[ f21 ], other[ f22 ] );\n\n\t\t\t\tclosestPointsSegmentToSegment( line1, line2, point, point2 );\n\n\t\t\t\tconst dist = point.distanceToSquared( point2 );\n\t\t\t\tif ( dist < closestDistanceSq ) {\n\n\t\t\t\t\tclosestDistanceSq = dist;\n\t\t\t\t\tif ( target1 ) target1.copy( point );\n\t\t\t\t\tif ( target2 ) target2.copy( point2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn Math.sqrt( closestDistanceSq );\n\n\t};\n\n} )();\n","/** @import { Box3, Triangle } from 'three' */\nimport { Vector3, Matrix4, Line3 } from 'three';\nimport { SeparatingAxisBounds } from './SeparatingAxisBounds.js';\nimport { ExtendedTriangle } from './ExtendedTriangle.js';\nimport { closestPointsSegmentToSegment } from './MathUtilities.js';\n\n/**\n * An oriented version of three.js' Box3 class. A variety of derivative values are cached on the\n * object to accelerate the intersection functions. `.needsUpdate` must be set to true when\n * modifying the box parameters.\n *\n * @param {Vector3} [min]\n * @param {Vector3} [max]\n * @param {Matrix4} [matrix]\n */\nexport class OrientedBox {\n\n\tconstructor( min, max, matrix ) {\n\n\t\tthis.isOrientedBox = true;\n\n\t\t/** @type {Vector3} */\n\t\tthis.min = new Vector3();\n\n\t\t/** @type {Vector3} */\n\t\tthis.max = new Vector3();\n\n\t\t/**\n\t\t * Matrix transformation applied to the box.\n\t\t * @type {Matrix4}\n\t\t */\n\t\tthis.matrix = new Matrix4();\n\t\tthis.invMatrix = new Matrix4();\n\t\tthis.points = new Array( 8 ).fill().map( () => new Vector3() );\n\t\tthis.satAxes = new Array( 3 ).fill().map( () => new Vector3() );\n\t\tthis.satBounds = new Array( 3 ).fill().map( () => new SeparatingAxisBounds() );\n\t\tthis.alignedSatBounds = new Array( 3 ).fill().map( () => new SeparatingAxisBounds() );\n\t\t/**\n\t\t * Indicates that the bounding box fields have changed so cached variables to accelerate\n\t\t * other function execution can be updated. Must be set to true after modifying the\n\t\t * oriented box `min`, `max`, `matrix` fields.\n\t\t * @type {boolean}\n\t\t */\n\t\tthis.needsUpdate = false;\n\n\t\tif ( min ) this.min.copy( min );\n\t\tif ( max ) this.max.copy( max );\n\t\tif ( matrix ) this.matrix.copy( matrix );\n\n\t}\n\n\t/**\n\t * Sets the oriented box parameters.\n\t * @param {Vector3} min\n\t * @param {Vector3} max\n\t * @param {Matrix4} matrix\n\t */\n\tset( min, max, matrix ) {\n\n\t\tthis.min.copy( min );\n\t\tthis.max.copy( max );\n\t\tthis.matrix.copy( matrix );\n\t\tthis.needsUpdate = true;\n\n\t}\n\n\tcopy( other ) {\n\n\t\tthis.min.copy( other.min );\n\t\tthis.max.copy( other.max );\n\t\tthis.matrix.copy( other.matrix );\n\t\tthis.needsUpdate = true;\n\n\t}\n\n}\n\nOrientedBox.prototype.update = ( function () {\n\n\treturn function update() {\n\n\t\tconst matrix = this.matrix;\n\t\tconst min = this.min;\n\t\tconst max = this.max;\n\n\t\tconst points = this.points;\n\t\tfor ( let x = 0; x <= 1; x ++ ) {\n\n\t\t\tfor ( let y = 0; y <= 1; y ++ ) {\n\n\t\t\t\tfor ( let z = 0; z <= 1; z ++ ) {\n\n\t\t\t\t\tconst i = ( ( 1 << 0 ) * x ) | ( ( 1 << 1 ) * y ) | ( ( 1 << 2 ) * z );\n\t\t\t\t\tconst v = points[ i ];\n\t\t\t\t\tv.x = x ? max.x : min.x;\n\t\t\t\t\tv.y = y ? max.y : min.y;\n\t\t\t\t\tv.z = z ? max.z : min.z;\n\n\t\t\t\t\tv.applyMatrix4( matrix );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tconst satBounds = this.satBounds;\n\t\tconst satAxes = this.satAxes;\n\t\tconst minVec = points[ 0 ];\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tconst axis = satAxes[ i ];\n\t\t\tconst sb = satBounds[ i ];\n\t\t\tconst index = 1 << i;\n\t\t\tconst pi = points[ index ];\n\n\t\t\taxis.subVectors( minVec, pi );\n\t\t\tsb.setFromPoints( axis, points );\n\n\t\t}\n\n\t\tconst alignedSatBounds = this.alignedSatBounds;\n\t\talignedSatBounds[ 0 ].setFromPointsField( points, 'x' );\n\t\talignedSatBounds[ 1 ].setFromPointsField( points, 'y' );\n\t\talignedSatBounds[ 2 ].setFromPointsField( points, 'z' );\n\n\t\tthis.invMatrix.copy( this.matrix ).invert();\n\t\tthis.needsUpdate = false;\n\n\t};\n\n} )();\n\n/**\n * Returns true if intersecting with the provided box.\n * @function\n * @param {Box3} box\n * @returns {boolean}\n */\nOrientedBox.prototype.intersectsBox = ( function () {\n\n\tconst aabbBounds = /* @__PURE__ */ new SeparatingAxisBounds();\n\treturn function intersectsBox( box ) {\n\n\t\t// TODO: should this be doing SAT against the AABB?\n\t\tif ( this.needsUpdate ) {\n\n\t\t\tthis.update();\n\n\t\t}\n\n\t\tconst min = box.min;\n\t\tconst max = box.max;\n\t\tconst satBounds = this.satBounds;\n\t\tconst satAxes = this.satAxes;\n\t\tconst alignedSatBounds = this.alignedSatBounds;\n\n\t\taabbBounds.min = min.x;\n\t\taabbBounds.max = max.x;\n\t\tif ( alignedSatBounds[ 0 ].isSeparated( aabbBounds ) ) return false;\n\n\t\taabbBounds.min = min.y;\n\t\taabbBounds.max = max.y;\n\t\tif ( alignedSatBounds[ 1 ].isSeparated( aabbBounds ) ) return false;\n\n\t\taabbBounds.min = min.z;\n\t\taabbBounds.max = max.z;\n\t\tif ( alignedSatBounds[ 2 ].isSeparated( aabbBounds ) ) return false;\n\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tconst axis = satAxes[ i ];\n\t\t\tconst sb = satBounds[ i ];\n\t\t\taabbBounds.setFromBox( axis, box );\n\t\t\tif ( sb.isSeparated( aabbBounds ) ) return false;\n\n\t\t}\n\n\t\treturn true;\n\n\t};\n\n} )();\n\n/**\n * Returns true if intersecting with the provided triangle.\n * @function\n * @param {Triangle} triangle\n * @returns {boolean}\n */\nOrientedBox.prototype.intersectsTriangle = ( function () {\n\n\tconst saTri = /* @__PURE__ */ new ExtendedTriangle();\n\tconst pointsArr = /* @__PURE__ */ new Array( 3 );\n\tconst cachedSatBounds = /* @__PURE__ */ new SeparatingAxisBounds();\n\tconst cachedSatBounds2 = /* @__PURE__ */ new SeparatingAxisBounds();\n\tconst cachedAxis = /* @__PURE__ */ new Vector3();\n\treturn function intersectsTriangle( triangle ) {\n\n\t\tif ( this.needsUpdate ) {\n\n\t\t\tthis.update();\n\n\t\t}\n\n\t\tif ( ! triangle.isExtendedTriangle ) {\n\n\t\t\tsaTri.copy( triangle );\n\t\t\tsaTri.update();\n\t\t\ttriangle = saTri;\n\n\t\t} else if ( triangle.needsUpdate ) {\n\n\t\t\ttriangle.update();\n\n\t\t}\n\n\t\tconst satBounds = this.satBounds;\n\t\tconst satAxes = this.satAxes;\n\n\t\tpointsArr[ 0 ] = triangle.a;\n\t\tpointsArr[ 1 ] = triangle.b;\n\t\tpointsArr[ 2 ] = triangle.c;\n\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tconst sb = satBounds[ i ];\n\t\t\tconst sa = satAxes[ i ];\n\t\t\tcachedSatBounds.setFromPoints( sa, pointsArr );\n\t\t\tif ( sb.isSeparated( cachedSatBounds ) ) return false;\n\n\t\t}\n\n\t\tconst triSatBounds = triangle.satBounds;\n\t\tconst triSatAxes = triangle.satAxes;\n\t\tconst points = this.points;\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tconst sb = triSatBounds[ i ];\n\t\t\tconst sa = triSatAxes[ i ];\n\t\t\tcachedSatBounds.setFromPoints( sa, points );\n\t\t\tif ( sb.isSeparated( cachedSatBounds ) ) return false;\n\n\t\t}\n\n\t\t// check crossed axes\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tconst sa1 = satAxes[ i ];\n\t\t\tfor ( let i2 = 0; i2 < 4; i2 ++ ) {\n\n\t\t\t\tconst sa2 = triSatAxes[ i2 ];\n\t\t\t\tcachedAxis.crossVectors( sa1, sa2 );\n\t\t\t\tcachedSatBounds.setFromPoints( cachedAxis, pointsArr );\n\t\t\t\tcachedSatBounds2.setFromPoints( cachedAxis, points );\n\t\t\t\tif ( cachedSatBounds.isSeparated( cachedSatBounds2 ) ) return false;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn true;\n\n\t};\n\n} )();\n\n/**\n * Returns the distance to the provided point. Sets `target` to the closest point on the surface\n * of the box if provided.\n * @function\n * @param {Vector3} point\n * @param {Vector3} target\n * @returns {number}\n */\nOrientedBox.prototype.closestPointToPoint = ( function () {\n\n\treturn function closestPointToPoint( point, target1 ) {\n\n\t\tif ( this.needsUpdate ) {\n\n\t\t\tthis.update();\n\n\t\t}\n\n\t\ttarget1\n\t\t\t.copy( point )\n\t\t\t.applyMatrix4( this.invMatrix )\n\t\t\t.clamp( this.min, this.max )\n\t\t\t.applyMatrix4( this.matrix );\n\n\t\treturn target1;\n\n\t};\n\n} )();\n\n/**\n * Returns the distance to the provided point.\n * @function\n * @param {Vector3} point\n * @returns {number}\n */\nOrientedBox.prototype.distanceToPoint = ( function () {\n\n\tconst target = new Vector3();\n\treturn function distanceToPoint( point ) {\n\n\t\tthis.closestPointToPoint( point, target );\n\t\treturn point.distanceTo( target );\n\n\t};\n\n} )();\n\n/**\n * Returns the distance to the provided box. `threshold` is an optional distance to return early\n * if the distance is found to be within it. `target1` and `target2` are set to the points on the\n * surface of this box and the `box` argument respectively.\n * @function\n * @param {Box3} box\n * @param {number} [threshold=0]\n * @param {Vector3} [target1]\n * @param {Vector3} [target2]\n * @returns {number}\n */\nOrientedBox.prototype.distanceToBox = ( function () {\n\n\tconst xyzFields = [ 'x', 'y', 'z' ];\n\tconst segments1 = /* @__PURE__ */ new Array( 12 ).fill().map( () => new Line3() );\n\tconst segments2 = /* @__PURE__ */ new Array( 12 ).fill().map( () => new Line3() );\n\n\tconst point1 = /* @__PURE__ */ new Vector3();\n\tconst point2 = /* @__PURE__ */ new Vector3();\n\n\t// early out if we find a value below threshold\n\treturn function distanceToBox( box, threshold = 0, target1 = null, target2 = null ) {\n\n\t\tif ( this.needsUpdate ) {\n\n\t\t\tthis.update();\n\n\t\t}\n\n\t\tif ( this.intersectsBox( box ) ) {\n\n\t\t\tif ( target1 || target2 ) {\n\n\t\t\t\tbox.getCenter( point2 );\n\t\t\t\tthis.closestPointToPoint( point2, point1 );\n\t\t\t\tbox.closestPointToPoint( point1, point2 );\n\n\t\t\t\tif ( target1 ) target1.copy( point1 );\n\t\t\t\tif ( target2 ) target2.copy( point2 );\n\n\t\t\t}\n\n\t\t\treturn 0;\n\n\t\t}\n\n\t\tconst threshold2 = threshold * threshold;\n\t\tconst min = box.min;\n\t\tconst max = box.max;\n\t\tconst points = this.points;\n\n\n\t\t// iterate over every edge and compare distances\n\t\tlet closestDistanceSq = Infinity;\n\n\t\t// check over all these points\n\t\tfor ( let i = 0; i < 8; i ++ ) {\n\n\t\t\tconst p = points[ i ];\n\t\t\tpoint2.copy( p ).clamp( min, max );\n\n\t\t\tconst dist = p.distanceToSquared( point2 );\n\t\t\tif ( dist < closestDistanceSq ) {\n\n\t\t\t\tclosestDistanceSq = dist;\n\t\t\t\tif ( target1 ) target1.copy( p );\n\t\t\t\tif ( target2 ) target2.copy( point2 );\n\n\t\t\t\tif ( dist < threshold2 ) return Math.sqrt( dist );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate and check all line segment distances\n\t\tlet count = 0;\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tfor ( let i1 = 0; i1 <= 1; i1 ++ ) {\n\n\t\t\t\tfor ( let i2 = 0; i2 <= 1; i2 ++ ) {\n\n\t\t\t\t\tconst nextIndex = ( i + 1 ) % 3;\n\t\t\t\t\tconst nextIndex2 = ( i + 2 ) % 3;\n\n\t\t\t\t\t// get obb line segments\n\t\t\t\t\tconst index = i1 << nextIndex | i2 << nextIndex2;\n\t\t\t\t\tconst index2 = 1 << i | i1 << nextIndex | i2 << nextIndex2;\n\t\t\t\t\tconst p1 = points[ index ];\n\t\t\t\t\tconst p2 = points[ index2 ];\n\t\t\t\t\tconst line1 = segments1[ count ];\n\t\t\t\t\tline1.set( p1, p2 );\n\n\n\t\t\t\t\t// get aabb line segments\n\t\t\t\t\tconst f1 = xyzFields[ i ];\n\t\t\t\t\tconst f2 = xyzFields[ nextIndex ];\n\t\t\t\t\tconst f3 = xyzFields[ nextIndex2 ];\n\t\t\t\t\tconst line2 = segments2[ count ];\n\t\t\t\t\tconst start = line2.start;\n\t\t\t\t\tconst end = line2.end;\n\n\t\t\t\t\tstart[ f1 ] = min[ f1 ];\n\t\t\t\t\tstart[ f2 ] = i1 ? min[ f2 ] : max[ f2 ];\n\t\t\t\t\tstart[ f3 ] = i2 ? min[ f3 ] : max[ f2 ];\n\n\t\t\t\t\tend[ f1 ] = max[ f1 ];\n\t\t\t\t\tend[ f2 ] = i1 ? min[ f2 ] : max[ f2 ];\n\t\t\t\t\tend[ f3 ] = i2 ? min[ f3 ] : max[ f2 ];\n\n\t\t\t\t\tcount ++;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// check all the other boxes point\n\t\tfor ( let x = 0; x <= 1; x ++ ) {\n\n\t\t\tfor ( let y = 0; y <= 1; y ++ ) {\n\n\t\t\t\tfor ( let z = 0; z <= 1; z ++ ) {\n\n\t\t\t\t\tpoint2.x = x ? max.x : min.x;\n\t\t\t\t\tpoint2.y = y ? max.y : min.y;\n\t\t\t\t\tpoint2.z = z ? max.z : min.z;\n\n\t\t\t\t\tthis.closestPointToPoint( point2, point1 );\n\t\t\t\t\tconst dist = point2.distanceToSquared( point1 );\n\t\t\t\t\tif ( dist < closestDistanceSq ) {\n\n\t\t\t\t\t\tclosestDistanceSq = dist;\n\t\t\t\t\t\tif ( target1 ) target1.copy( point1 );\n\t\t\t\t\t\tif ( target2 ) target2.copy( point2 );\n\n\t\t\t\t\t\tif ( dist < threshold2 ) return Math.sqrt( dist );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfor ( let i = 0; i < 12; i ++ ) {\n\n\t\t\tconst l1 = segments1[ i ];\n\t\t\tfor ( let i2 = 0; i2 < 12; i2 ++ ) {\n\n\t\t\t\tconst l2 = segments2[ i2 ];\n\t\t\t\tclosestPointsSegmentToSegment( l1, l2, point1, point2 );\n\t\t\t\tconst dist = point1.distanceToSquared( point2 );\n\t\t\t\tif ( dist < closestDistanceSq ) {\n\n\t\t\t\t\tclosestDistanceSq = dist;\n\t\t\t\t\tif ( target1 ) target1.copy( point1 );\n\t\t\t\t\tif ( target2 ) target2.copy( point2 );\n\n\t\t\t\t\tif ( dist < threshold2 ) return Math.sqrt( dist );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn Math.sqrt( closestDistanceSq );\n\n\t};\n\n} )();\n","import { ExtendedTriangle } from '../math/ExtendedTriangle.js';\nimport { PrimitivePool } from './PrimitivePool.js';\n\nclass ExtendedTrianglePoolBase extends PrimitivePool {\n\n\tconstructor() {\n\n\t\tsuper( () => new ExtendedTriangle() );\n\n\t}\n\n}\n\nexport const ExtendedTrianglePool = /* @__PURE__ */ new ExtendedTrianglePoolBase();\n","import { Vector3 } from 'three';\n\nconst temp = /* @__PURE__ */ new Vector3();\nconst temp1 = /* @__PURE__ */ new Vector3();\n\nexport function closestPointToPoint(\n\tbvh,\n\tpoint,\n\ttarget = { },\n\tminThreshold = 0,\n\tmaxThreshold = Infinity,\n) {\n\n\t// early out if under minThreshold\n\t// skip checking if over maxThreshold\n\t// set minThreshold = maxThreshold to quickly check if a point is within a threshold\n\t// returns Infinity if no value found\n\tconst minThresholdSq = minThreshold * minThreshold;\n\tconst maxThresholdSq = maxThreshold * maxThreshold;\n\tlet closestDistanceSq = Infinity;\n\tlet closestDistanceTriIndex = null;\n\tbvh.shapecast(\n\n\t\t{\n\n\t\t\tboundsTraverseOrder: box => {\n\n\t\t\t\ttemp.copy( point ).clamp( box.min, box.max );\n\t\t\t\treturn temp.distanceToSquared( point );\n\n\t\t\t},\n\n\t\t\tintersectsBounds: ( box, isLeaf, score ) => {\n\n\t\t\t\treturn score < closestDistanceSq && score < maxThresholdSq;\n\n\t\t\t},\n\n\t\t\tintersectsTriangle: ( tri, triIndex ) => {\n\n\t\t\t\ttri.closestPointToPoint( point, temp );\n\t\t\t\tconst distSq = point.distanceToSquared( temp );\n\t\t\t\tif ( distSq < closestDistanceSq ) {\n\n\t\t\t\t\ttemp1.copy( temp );\n\t\t\t\t\tclosestDistanceSq = distSq;\n\t\t\t\t\tclosestDistanceTriIndex = triIndex;\n\n\t\t\t\t}\n\n\t\t\t\tif ( distSq < minThresholdSq ) {\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t}\n\n\t);\n\n\tif ( closestDistanceSq === Infinity ) return null;\n\n\tconst closestDistance = Math.sqrt( closestDistanceSq );\n\n\tif ( ! target.point ) target.point = temp1.clone();\n\telse target.point.copy( temp1 );\n\ttarget.distance = closestDistance,\n\ttarget.faceIndex = closestDistanceTriIndex;\n\n\treturn target;\n\n}\n","import { Vector3, Vector2, Triangle, DoubleSide, BackSide, REVISION } from 'three';\n\nconst IS_GT_REVISION_169 = parseInt( REVISION ) >= 169;\nconst IS_LT_REVISION_161 = parseInt( REVISION ) <= 161;\n\n// Ripped and modified From THREE.js Mesh raycast\n// https://github.com/mrdoob/three.js/blob/0aa87c999fe61e216c1133fba7a95772b503eddf/src/objects/Mesh.js#L115\nconst _vA = /* @__PURE__ */ new Vector3();\nconst _vB = /* @__PURE__ */ new Vector3();\nconst _vC = /* @__PURE__ */ new Vector3();\n\nconst _uvA = /* @__PURE__ */ new Vector2();\nconst _uvB = /* @__PURE__ */ new Vector2();\nconst _uvC = /* @__PURE__ */ new Vector2();\n\nconst _normalA = /* @__PURE__ */ new Vector3();\nconst _normalB = /* @__PURE__ */ new Vector3();\nconst _normalC = /* @__PURE__ */ new Vector3();\n\nconst _intersectionPoint = /* @__PURE__ */ new Vector3();\nfunction checkIntersection( ray, pA, pB, pC, point, side, near, far ) {\n\n\tlet intersect;\n\tif ( side === BackSide ) {\n\n\t\tintersect = ray.intersectTriangle( pC, pB, pA, true, point );\n\n\t} else {\n\n\t\tintersect = ray.intersectTriangle( pA, pB, pC, side !== DoubleSide, point );\n\n\t}\n\n\tif ( intersect === null ) return null;\n\n\tconst distance = ray.origin.distanceTo( point );\n\n\tif ( distance < near || distance > far ) return null;\n\n\treturn {\n\n\t\tdistance: distance,\n\t\tpoint: point.clone(),\n\n\t};\n\n}\n\nfunction checkBufferGeometryIntersection( ray, position, normal, uv, uv1, a, b, c, side, near, far ) {\n\n\t_vA.fromBufferAttribute( position, a );\n\t_vB.fromBufferAttribute( position, b );\n\t_vC.fromBufferAttribute( position, c );\n\n\tconst intersection = checkIntersection( ray, _vA, _vB, _vC, _intersectionPoint, side, near, far );\n\n\tif ( intersection ) {\n\n\t\tif ( uv ) {\n\n\t\t\t_uvA.fromBufferAttribute( uv, a );\n\t\t\t_uvB.fromBufferAttribute( uv, b );\n\t\t\t_uvC.fromBufferAttribute( uv, c );\n\n\t\t\tintersection.uv = new Vector2();\n\t\t\tconst res = Triangle.getInterpolation( _intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, intersection.uv );\n\t\t\tif ( ! IS_GT_REVISION_169 ) {\n\n\t\t\t\tintersection.uv = res;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( uv1 ) {\n\n\t\t\t_uvA.fromBufferAttribute( uv1, a );\n\t\t\t_uvB.fromBufferAttribute( uv1, b );\n\t\t\t_uvC.fromBufferAttribute( uv1, c );\n\n\t\t\tintersection.uv1 = new Vector2();\n\t\t\tconst res = Triangle.getInterpolation( _intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, intersection.uv1 );\n\t\t\tif ( ! IS_GT_REVISION_169 ) {\n\n\t\t\t\tintersection.uv1 = res;\n\n\t\t\t}\n\n\t\t\tif ( IS_LT_REVISION_161 ) {\n\n\t\t\t\tintersection.uv2 = intersection.uv1;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( normal ) {\n\n\t\t\t_normalA.fromBufferAttribute( normal, a );\n\t\t\t_normalB.fromBufferAttribute( normal, b );\n\t\t\t_normalC.fromBufferAttribute( normal, c );\n\n\t\t\tintersection.normal = new Vector3();\n\t\t\tconst res = Triangle.getInterpolation( _intersectionPoint, _vA, _vB, _vC, _normalA, _normalB, _normalC, intersection.normal );\n\t\t\tif ( intersection.normal.dot( ray.direction ) > 0 ) {\n\n\t\t\t\tintersection.normal.multiplyScalar( - 1 );\n\n\t\t\t}\n\n\t\t\tif ( ! IS_GT_REVISION_169 ) {\n\n\t\t\t\tintersection.normal = res;\n\n\t\t\t}\n\n\t\t}\n\n\t\tconst face = {\n\t\t\ta: a,\n\t\t\tb: b,\n\t\t\tc: c,\n\t\t\tnormal: new Vector3(),\n\t\t\tmaterialIndex: 0\n\t\t};\n\n\t\tTriangle.getNormal( _vA, _vB, _vC, face.normal );\n\n\t\tintersection.face = face;\n\t\tintersection.faceIndex = a;\n\n\t\tif ( IS_GT_REVISION_169 ) {\n\n\t\t\tconst barycoord = new Vector3();\n\t\t\tTriangle.getBarycoord( _intersectionPoint, _vA, _vB, _vC, barycoord );\n\n\t\t\tintersection.barycoord = barycoord;\n\n\t\t}\n\n\t}\n\n\treturn intersection;\n\n}\n\nfunction getSide( materialOrSide ) {\n\n\treturn materialOrSide && materialOrSide.isMaterial ? materialOrSide.side : materialOrSide;\n\n}\n\n// https://github.com/mrdoob/three.js/blob/0aa87c999fe61e216c1133fba7a95772b503eddf/src/objects/Mesh.js#L258\nexport function intersectTri( geometry, materialOrSide, ray, tri, intersections, near, far ) {\n\n\tconst triOffset = tri * 3;\n\tlet a = triOffset + 0;\n\tlet b = triOffset + 1;\n\tlet c = triOffset + 2;\n\n\tconst { index, groups } = geometry;\n\tif ( geometry.index ) {\n\n\t\ta = index.getX( a );\n\t\tb = index.getX( b );\n\t\tc = index.getX( c );\n\n\t}\n\n\tconst { position, normal, uv, uv1 } = geometry.attributes;\n\tif ( Array.isArray( materialOrSide ) ) {\n\n\t\t// check which groups a triangle is present in and run the intersections\n\t\t// TODO: we shouldn't need to run and intersection test multiple times\n\t\tconst firstIndex = tri * 3;\n\t\tfor ( let i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\tconst { start, count, materialIndex } = groups[ i ];\n\t\t\tif ( firstIndex >= start && firstIndex < start + count ) {\n\n\t\t\t\tconst side = getSide( materialOrSide[ materialIndex ] );\n\t\t\t\tconst intersection = checkBufferGeometryIntersection( ray, position, normal, uv, uv1, a, b, c, side, near, far );\n\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\tintersection.faceIndex = tri;\n\t\t\t\t\tintersection.face.materialIndex = materialIndex;\n\n\t\t\t\t\tif ( intersections ) {\n\n\t\t\t\t\t\tintersections.push( intersection );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn intersection;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t} else {\n\n\t\t// run the intersection for the single material\n\t\tconst side = getSide( materialOrSide );\n\t\tconst intersection = checkBufferGeometryIntersection( ray, position, normal, uv, uv1, a, b, c, side, near, far );\n\t\tif ( intersection ) {\n\n\t\t\tintersection.faceIndex = tri;\n\t\t\tintersection.face.materialIndex = 0;\n\n\t\t\tif ( intersections ) {\n\n\t\t\t\tintersections.push( intersection );\n\n\t\t\t} else {\n\n\t\t\t\treturn intersection;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\treturn null;\n\n}\n","/** @import { BufferGeometry } from 'three' */\nimport { Vector2, Vector3, Triangle } from 'three';\n\n// sets the vertices of triangle `tri` with the 3 vertices after i\nexport function setTriangle( tri, i, index, pos ) {\n\n\tconst ta = tri.a;\n\tconst tb = tri.b;\n\tconst tc = tri.c;\n\n\tlet i0 = i;\n\tlet i1 = i + 1;\n\tlet i2 = i + 2;\n\tif ( index ) {\n\n\t\ti0 = index.getX( i0 );\n\t\ti1 = index.getX( i1 );\n\t\ti2 = index.getX( i2 );\n\n\t}\n\n\tta.x = pos.getX( i0 );\n\tta.y = pos.getY( i0 );\n\tta.z = pos.getZ( i0 );\n\n\ttb.x = pos.getX( i1 );\n\ttb.y = pos.getY( i1 );\n\ttb.z = pos.getZ( i1 );\n\n\ttc.x = pos.getX( i2 );\n\ttc.y = pos.getY( i2 );\n\ttc.z = pos.getZ( i2 );\n\n}\n\nconst tempV1 = /* @__PURE__ */ new Vector3();\nconst tempV2 = /* @__PURE__ */ new Vector3();\nconst tempV3 = /* @__PURE__ */ new Vector3();\nconst tempUV1 = /* @__PURE__ */ new Vector2();\nconst tempUV2 = /* @__PURE__ */ new Vector2();\nconst tempUV3 = /* @__PURE__ */ new Vector2();\n\n/**\n * @typedef {Object} HitTriangleInfo\n * @property {{ a: number, b: number, c: number, materialIndex: number, normal: Vector3 }} face\n * Triangle vertex indices, material index, and face normal.\n * @property {Vector2|null} uv - UV coordinates at the hit point, or `null` if no UV attribute is present.\n * @property {Vector3} barycoord - Barycentric coordinates of the hit point within the triangle.\n */\n\n/**\n * Computes hit-point information for a point on a triangle within a `BufferGeometry`. Returns\n * the face vertex indices, face normal, material index, UV coordinates, and barycentric coordinates.\n * Useful for retrieving detailed hit data after a call to `MeshBVH.closestPointToPoint` or\n * `MeshBVH.closestPointToGeometry`.\n *\n * @section Functions\n * @param {Vector3} point - The point on the triangle surface (in the geometry's local space).\n * @param {BufferGeometry} geometry - The geometry containing the triangle.\n * @param {number} triangleIndex - The index of the triangle within the geometry.\n * @param {HitTriangleInfo} [target] - Optional object to write results into. Reuses existing\n * `face`, `uv`, and `barycoord` sub-objects if present.\n * @returns {HitTriangleInfo}\n */\nexport function getTriangleHitPointInfo( point, geometry, triangleIndex, target ) {\n\n\tconst indices = geometry.getIndex().array;\n\tconst positions = geometry.getAttribute( 'position' );\n\tconst uvs = geometry.getAttribute( 'uv' );\n\n\tconst a = indices[ triangleIndex * 3 ];\n\tconst b = indices[ triangleIndex * 3 + 1 ];\n\tconst c = indices[ triangleIndex * 3 + 2 ];\n\n\ttempV1.fromBufferAttribute( positions, a );\n\ttempV2.fromBufferAttribute( positions, b );\n\ttempV3.fromBufferAttribute( positions, c );\n\n\t// find the associated material index\n\tlet materialIndex = 0;\n\tconst groups = geometry.groups;\n\tconst firstVertexIndex = triangleIndex * 3;\n\tfor ( let i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\tconst group = groups[ i ];\n\t\tconst { start, count } = group;\n\t\tif ( firstVertexIndex >= start && firstVertexIndex < start + count ) {\n\n\t\t\tmaterialIndex = group.materialIndex;\n\t\t\tbreak;\n\n\t\t}\n\n\t}\n\n\t// extract barycoord\n\tconst barycoord = target && target.barycoord ? target.barycoord : new Vector3();\n\tTriangle.getBarycoord( point, tempV1, tempV2, tempV3, barycoord );\n\n\t// extract uvs\n\tlet uv = null;\n\tif ( uvs ) {\n\n\t\ttempUV1.fromBufferAttribute( uvs, a );\n\t\ttempUV2.fromBufferAttribute( uvs, b );\n\t\ttempUV3.fromBufferAttribute( uvs, c );\n\n\t\tif ( target && target.uv ) uv = target.uv;\n\t\telse uv = new Vector2();\n\n\t\tTriangle.getInterpolation( point, tempV1, tempV2, tempV3, tempUV1, tempUV2, tempUV3, uv );\n\n\t}\n\n\t// adjust the provided target or create a new one\n\tif ( target ) {\n\n\t\tif ( ! target.face ) target.face = { };\n\t\ttarget.face.a = a;\n\t\ttarget.face.b = b;\n\t\ttarget.face.c = c;\n\t\ttarget.face.materialIndex = materialIndex;\n\t\tif ( ! target.face.normal ) target.face.normal = new Vector3();\n\t\tTriangle.getNormal( tempV1, tempV2, tempV3, target.face.normal );\n\n\t\tif ( uv ) target.uv = uv;\n\t\ttarget.barycoord = barycoord;\n\n\t\treturn target;\n\n\t} else {\n\n\t\treturn {\n\t\t\tface: {\n\t\t\t\ta: a,\n\t\t\t\tb: b,\n\t\t\t\tc: c,\n\t\t\t\tmaterialIndex: materialIndex,\n\t\t\t\tnormal: Triangle.getNormal( tempV1, tempV2, tempV3, new Vector3() )\n\t\t\t},\n\t\t\tuv: uv,\n\t\t\tbarycoord: barycoord,\n\t\t};\n\n\t}\n\n}\n","import { intersectTri } from '../../utils/ThreeRayIntersectUtilities.js';\nimport { setTriangle } from '../../utils/TriangleUtilities.js';\n\n/*************************************************************/\n/* This file is generated from \"iterationUtils.template.js\". */\n/*************************************************************/\n\nfunction intersectTris( bvh, materialOrSide, ray, offset, count, intersections, near, far ) {\n\n\tconst { geometry, _indirectBuffer } = bvh;\n\tfor ( let i = offset, end = offset + count; i < end; i ++ ) {\n\n\n\t\tintersectTri( geometry, materialOrSide, ray, i, intersections, near, far );\n\n\n\t}\n\n}\n\nfunction intersectClosestTri( bvh, materialOrSide, ray, offset, count, near, far ) {\n\n\tconst { geometry, _indirectBuffer } = bvh;\n\tlet dist = Infinity;\n\tlet res = null;\n\tfor ( let i = offset, end = offset + count; i < end; i ++ ) {\n\n\t\tlet intersection;\n\n\t\tintersection = intersectTri( geometry, materialOrSide, ray, i, null, near, far );\n\n\n\t\tif ( intersection && intersection.distance < dist ) {\n\n\t\t\tres = intersection;\n\t\t\tdist = intersection.distance;\n\n\t\t}\n\n\t}\n\n\treturn res;\n\n}\n\nfunction iterateOverTriangles(\n\toffset,\n\tcount,\n\tbvh,\n\tintersectsTriangleFunc,\n\tcontained,\n\tdepth,\n\ttriangle\n) {\n\n\tconst { geometry } = bvh;\n\tconst { index } = geometry;\n\tconst pos = geometry.attributes.position;\n\tfor ( let i = offset, l = count + offset; i < l; i ++ ) {\n\n\t\tlet tri;\n\n\t\ttri = i;\n\n\t\tsetTriangle( triangle, tri * 3, index, pos );\n\t\ttriangle.needsUpdate = true;\n\n\t\tif ( intersectsTriangleFunc( triangle, tri, contained, depth ) ) {\n\n\t\t\treturn true;\n\n\t\t}\n\n\t}\n\n\treturn false;\n\n}\n\nexport { intersectClosestTri, intersectTris, iterateOverTriangles };\n","import { UINT32_PER_NODE, BYTES_PER_NODE } from '../Constants.js';\nimport { IS_LEAF, OFFSET, COUNT, LEFT_NODE, RIGHT_NODE } from '../utils/nodeBufferUtils.js';\n\n/****************************************************/\n/* This file is generated from \"refit.template.js\". */\n/****************************************************/\n\nfunction refit( bvh, nodeIndices = null ) {\n\n\tif ( nodeIndices && Array.isArray( nodeIndices ) ) {\n\n\t\tnodeIndices = new Set( nodeIndices );\n\n\t}\n\n\tconst geometry = bvh.geometry;\n\tconst indexArr = geometry.index ? geometry.index.array : null;\n\tconst posAttr = geometry.attributes.position;\n\n\tlet buffer, uint32Array, uint16Array, float32Array;\n\tlet byteOffset = 0;\n\tconst roots = bvh._roots;\n\tfor ( let i = 0, l = roots.length; i < l; i ++ ) {\n\n\t\tbuffer = roots[ i ];\n\t\tuint32Array = new Uint32Array( buffer );\n\t\tuint16Array = new Uint16Array( buffer );\n\t\tfloat32Array = new Float32Array( buffer );\n\n\t\t_traverse( 0, byteOffset );\n\t\tbyteOffset += buffer.byteLength;\n\n\t}\n\n\tfunction _traverse( nodeIndex32, byteOffset, force = false ) {\n\n\t\tconst nodeIndex16 = nodeIndex32 * 2;\n\t\tif ( IS_LEAF( nodeIndex16, uint16Array ) ) {\n\n\t\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\n\t\t\tlet minx = Infinity;\n\t\t\tlet miny = Infinity;\n\t\t\tlet minz = Infinity;\n\t\t\tlet maxx = - Infinity;\n\t\t\tlet maxy = - Infinity;\n\t\t\tlet maxz = - Infinity;\n\n\n\t\t\tfor ( let i = 3 * offset, l = 3 * ( offset + count ); i < l; i ++ ) {\n\n\t\t\t\tlet index = indexArr[ i ];\n\t\t\t\tconst x = posAttr.getX( index );\n\t\t\t\tconst y = posAttr.getY( index );\n\t\t\t\tconst z = posAttr.getZ( index );\n\n\t\t\t\tif ( x < minx ) minx = x;\n\t\t\t\tif ( x > maxx ) maxx = x;\n\n\t\t\t\tif ( y < miny ) miny = y;\n\t\t\t\tif ( y > maxy ) maxy = y;\n\n\t\t\t\tif ( z < minz ) minz = z;\n\t\t\t\tif ( z > maxz ) maxz = z;\n\n\t\t\t}\n\n\n\t\t\tif (\n\t\t\t\tfloat32Array[ nodeIndex32 + 0 ] !== minx ||\n\t\t\t\tfloat32Array[ nodeIndex32 + 1 ] !== miny ||\n\t\t\t\tfloat32Array[ nodeIndex32 + 2 ] !== minz ||\n\n\t\t\t\tfloat32Array[ nodeIndex32 + 3 ] !== maxx ||\n\t\t\t\tfloat32Array[ nodeIndex32 + 4 ] !== maxy ||\n\t\t\t\tfloat32Array[ nodeIndex32 + 5 ] !== maxz\n\t\t\t) {\n\n\t\t\t\tfloat32Array[ nodeIndex32 + 0 ] = minx;\n\t\t\t\tfloat32Array[ nodeIndex32 + 1 ] = miny;\n\t\t\t\tfloat32Array[ nodeIndex32 + 2 ] = minz;\n\n\t\t\t\tfloat32Array[ nodeIndex32 + 3 ] = maxx;\n\t\t\t\tfloat32Array[ nodeIndex32 + 4 ] = maxy;\n\t\t\t\tfloat32Array[ nodeIndex32 + 5 ] = maxz;\n\n\t\t\t\treturn true;\n\n\t\t\t} else {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tconst left = LEFT_NODE( nodeIndex32 );\n\t\t\tconst right = RIGHT_NODE( nodeIndex32, uint32Array );\n\n\t\t\t// the identifying node indices provided by the shapecast function include offsets of all\n\t\t\t// root buffers to guarantee they're unique between roots so offset left and right indices here.\n\t\t\tlet forceChildren = force;\n\t\t\tlet includesLeft = false;\n\t\t\tlet includesRight = false;\n\n\t\t\tif ( nodeIndices ) {\n\n\t\t\t\t// if we see that neither the left or right child are included in the set that need to be updated\n\t\t\t\t// then we assume that all children need to be updated.\n\t\t\t\tif ( ! forceChildren ) {\n\n\t\t\t\t\tconst leftNodeId = left / UINT32_PER_NODE + byteOffset / BYTES_PER_NODE;\n\t\t\t\t\tconst rightNodeId = right / UINT32_PER_NODE + byteOffset / BYTES_PER_NODE;\n\t\t\t\t\tincludesLeft = nodeIndices.has( leftNodeId );\n\t\t\t\t\tincludesRight = nodeIndices.has( rightNodeId );\n\t\t\t\t\tforceChildren = ! includesLeft && ! includesRight;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tincludesLeft = true;\n\t\t\t\tincludesRight = true;\n\n\t\t\t}\n\n\t\t\tconst traverseLeft = forceChildren || includesLeft;\n\t\t\tconst traverseRight = forceChildren || includesRight;\n\n\t\t\tlet leftChange = false;\n\t\t\tif ( traverseLeft ) {\n\n\t\t\t\tleftChange = _traverse( left, byteOffset, forceChildren );\n\n\t\t\t}\n\n\t\t\tlet rightChange = false;\n\t\t\tif ( traverseRight ) {\n\n\t\t\t\trightChange = _traverse( right, byteOffset, forceChildren );\n\n\t\t\t}\n\n\t\t\tconst didChange = leftChange || rightChange;\n\t\t\tif ( didChange ) {\n\n\t\t\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\tconst left_i = left + i;\n\t\t\t\t\tconst right_i = right + i;\n\t\t\t\t\tconst minLeftValue = float32Array[ left_i ];\n\t\t\t\t\tconst maxLeftValue = float32Array[ left_i + 3 ];\n\t\t\t\t\tconst minRightValue = float32Array[ right_i ];\n\t\t\t\t\tconst maxRightValue = float32Array[ right_i + 3 ];\n\n\t\t\t\t\tfloat32Array[ nodeIndex32 + i ] = minLeftValue < minRightValue ? minLeftValue : minRightValue;\n\t\t\t\t\tfloat32Array[ nodeIndex32 + i + 3 ] = maxLeftValue > maxRightValue ? maxLeftValue : maxRightValue;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn didChange;\n\n\t\t}\n\n\t}\n\n}\n\nexport { refit };\n","\nexport function intersectsNodeBounds( nodeIndex32, array, ray, near, far ) {\n\n\t// This function performs intersection tests similar to Ray.intersectBox in three.js,\n\t// with the difference that the box values are read from an array to improve performance.\n\n\tlet tmin, tmax, tymin, tymax, tzmin, tzmax;\n\n\tconst invdirx = 1 / ray.direction.x,\n\t\tinvdiry = 1 / ray.direction.y,\n\t\tinvdirz = 1 / ray.direction.z;\n\n\tconst ox = ray.origin.x;\n\tconst oy = ray.origin.y;\n\tconst oz = ray.origin.z;\n\n\tlet minx = array[ nodeIndex32 ];\n\tlet maxx = array[ nodeIndex32 + 3 ];\n\n\tlet miny = array[ nodeIndex32 + 1 ];\n\tlet maxy = array[ nodeIndex32 + 3 + 1 ];\n\n\tlet minz = array[ nodeIndex32 + 2 ];\n\tlet maxz = array[ nodeIndex32 + 3 + 2 ];\n\n\tif ( invdirx >= 0 ) {\n\n\t\ttmin = ( minx - ox ) * invdirx;\n\t\ttmax = ( maxx - ox ) * invdirx;\n\n\t} else {\n\n\t\ttmin = ( maxx - ox ) * invdirx;\n\t\ttmax = ( minx - ox ) * invdirx;\n\n\t}\n\n\tif ( invdiry >= 0 ) {\n\n\t\ttymin = ( miny - oy ) * invdiry;\n\t\ttymax = ( maxy - oy ) * invdiry;\n\n\t} else {\n\n\t\ttymin = ( maxy - oy ) * invdiry;\n\t\ttymax = ( miny - oy ) * invdiry;\n\n\t}\n\n\tif ( ( tmin > tymax ) || ( tymin > tmax ) ) return false;\n\n\tif ( tymin > tmin || isNaN( tmin ) ) tmin = tymin;\n\n\tif ( tymax < tmax || isNaN( tmax ) ) tmax = tymax;\n\n\tif ( invdirz >= 0 ) {\n\n\t\ttzmin = ( minz - oz ) * invdirz;\n\t\ttzmax = ( maxz - oz ) * invdirz;\n\n\t} else {\n\n\t\ttzmin = ( maxz - oz ) * invdirz;\n\t\ttzmax = ( minz - oz ) * invdirz;\n\n\t}\n\n\tif ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return false;\n\n\tif ( tzmin > tmin || tmin !== tmin ) tmin = tzmin;\n\n\tif ( tzmax < tmax || tmax !== tmax ) tmax = tzmax;\n\n\t//return point closest to the ray (positive side)\n\n\treturn tmin <= far && tmax >= near;\n\n}\n","import { intersectTri } from '../../utils/ThreeRayIntersectUtilities.js';\nimport { setTriangle } from '../../utils/TriangleUtilities.js';\n\n/*************************************************************/\n/* This file is generated from \"iterationUtils.template.js\". */\n/*************************************************************/\n\nfunction intersectTris_indirect( bvh, materialOrSide, ray, offset, count, intersections, near, far ) {\n\n\tconst { geometry, _indirectBuffer } = bvh;\n\tfor ( let i = offset, end = offset + count; i < end; i ++ ) {\n\n\t\tlet vi = _indirectBuffer ? _indirectBuffer[ i ] : i;\n\t\tintersectTri( geometry, materialOrSide, ray, vi, intersections, near, far );\n\n\n\t}\n\n}\n\nfunction intersectClosestTri_indirect( bvh, materialOrSide, ray, offset, count, near, far ) {\n\n\tconst { geometry, _indirectBuffer } = bvh;\n\tlet dist = Infinity;\n\tlet res = null;\n\tfor ( let i = offset, end = offset + count; i < end; i ++ ) {\n\n\t\tlet intersection;\n\t\tintersection = intersectTri( geometry, materialOrSide, ray, _indirectBuffer ? _indirectBuffer[ i ] : i, null, near, far );\n\n\n\t\tif ( intersection && intersection.distance < dist ) {\n\n\t\t\tres = intersection;\n\t\t\tdist = intersection.distance;\n\n\t\t}\n\n\t}\n\n\treturn res;\n\n}\n\nfunction iterateOverTriangles_indirect(\n\toffset,\n\tcount,\n\tbvh,\n\tintersectsTriangleFunc,\n\tcontained,\n\tdepth,\n\ttriangle\n) {\n\n\tconst { geometry } = bvh;\n\tconst { index } = geometry;\n\tconst pos = geometry.attributes.position;\n\tfor ( let i = offset, l = count + offset; i < l; i ++ ) {\n\n\t\tlet tri;\n\t\ttri = bvh.resolveTriangleIndex( i );\n\n\t\tsetTriangle( triangle, tri * 3, index, pos );\n\t\ttriangle.needsUpdate = true;\n\n\t\tif ( intersectsTriangleFunc( triangle, tri, contained, depth ) ) {\n\n\t\t\treturn true;\n\n\t\t}\n\n\t}\n\n\treturn false;\n\n}\n\nexport { intersectClosestTri_indirect, intersectTris_indirect, iterateOverTriangles_indirect };\n","import { intersectsNodeBounds } from '../utils/intersectUtils.js';\nimport { IS_LEAF, OFFSET, COUNT, LEFT_NODE, RIGHT_NODE } from '../utils/nodeBufferUtils.js';\nimport { BufferStack } from '../utils/BufferStack.js';\nimport { intersectTris } from '../utils/iterationUtils.generated.js';\nimport '../utils/iterationUtils_indirect.generated.js';\n\n/******************************************************/\n/* This file is generated from \"raycast.template.js\". */\n/******************************************************/\n\nfunction raycast( bvh, root, materialOrSide, ray, intersects, near, far ) {\n\n\tBufferStack.setBuffer( bvh._roots[ root ] );\n\t_raycast( 0, bvh, materialOrSide, ray, intersects, near, far );\n\tBufferStack.clearBuffer();\n\n}\n\nfunction _raycast( nodeIndex32, bvh, materialOrSide, ray, intersects, near, far ) {\n\n\tconst { float32Array, uint16Array, uint32Array } = BufferStack;\n\tconst nodeIndex16 = nodeIndex32 * 2;\n\tconst isLeaf = IS_LEAF( nodeIndex16, uint16Array );\n\tif ( isLeaf ) {\n\n\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\n\n\t\tintersectTris( bvh, materialOrSide, ray, offset, count, intersects, near, far );\n\n\n\t} else {\n\n\t\tconst leftIndex = LEFT_NODE( nodeIndex32 );\n\t\tif ( intersectsNodeBounds( leftIndex, float32Array, ray, near, far ) ) {\n\n\t\t\t_raycast( leftIndex, bvh, materialOrSide, ray, intersects, near, far );\n\n\t\t}\n\n\t\tconst rightIndex = RIGHT_NODE( nodeIndex32, uint32Array );\n\t\tif ( intersectsNodeBounds( rightIndex, float32Array, ray, near, far ) ) {\n\n\t\t\t_raycast( rightIndex, bvh, materialOrSide, ray, intersects, near, far );\n\n\t\t}\n\n\t}\n\n}\n\nexport { raycast };\n","import { IS_LEAF, OFFSET, COUNT, SPLIT_AXIS, LEFT_NODE, RIGHT_NODE } from '../utils/nodeBufferUtils.js';\nimport { BufferStack } from '../utils/BufferStack.js';\nimport { intersectsNodeBounds } from '../utils/intersectUtils.js';\nimport { intersectClosestTri } from '../utils/iterationUtils.generated.js';\nimport '../utils/iterationUtils_indirect.generated.js';\n\n/***********************************************************/\n/* This file is generated from \"raycastFirst.template.js\". */\n/***********************************************************/\n\nconst _xyzFields = [ 'x', 'y', 'z' ];\n\nfunction raycastFirst( bvh, root, materialOrSide, ray, near, far ) {\n\n\tBufferStack.setBuffer( bvh._roots[ root ] );\n\tconst result = _raycastFirst( 0, bvh, materialOrSide, ray, near, far );\n\tBufferStack.clearBuffer();\n\n\treturn result;\n\n}\n\nfunction _raycastFirst( nodeIndex32, bvh, materialOrSide, ray, near, far ) {\n\n\tconst { float32Array, uint16Array, uint32Array } = BufferStack;\n\tlet nodeIndex16 = nodeIndex32 * 2;\n\n\tconst isLeaf = IS_LEAF( nodeIndex16, uint16Array );\n\tif ( isLeaf ) {\n\n\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\n\n\t\t// eslint-disable-next-line no-unreachable\n\t\treturn intersectClosestTri( bvh, materialOrSide, ray, offset, count, near, far );\n\n\n\t} else {\n\n\t\t// consider the position of the split plane with respect to the oncoming ray; whichever direction\n\t\t// the ray is coming from, look for an intersection among that side of the tree first\n\t\tconst splitAxis = SPLIT_AXIS( nodeIndex32, uint32Array );\n\t\tconst xyzAxis = _xyzFields[ splitAxis ];\n\t\tconst rayDir = ray.direction[ xyzAxis ];\n\t\tconst leftToRight = rayDir >= 0;\n\n\t\t// c1 is the child to check first\n\t\tlet c1, c2;\n\t\tif ( leftToRight ) {\n\n\t\t\tc1 = LEFT_NODE( nodeIndex32 );\n\t\t\tc2 = RIGHT_NODE( nodeIndex32, uint32Array );\n\n\t\t} else {\n\n\t\t\tc1 = RIGHT_NODE( nodeIndex32, uint32Array );\n\t\t\tc2 = LEFT_NODE( nodeIndex32 );\n\n\t\t}\n\n\t\tconst c1Intersection = intersectsNodeBounds( c1, float32Array, ray, near, far );\n\t\tconst c1Result = c1Intersection ? _raycastFirst( c1, bvh, materialOrSide, ray, near, far ) : null;\n\n\t\t// if we got an intersection in the first node and it's closer than the second node's bounding\n\t\t// box, we don't need to consider the second node because it couldn't possibly be a better result\n\t\tif ( c1Result ) {\n\n\t\t\t// check if the point is within the second bounds\n\t\t\t// \"point\" is in the local frame of the bvh\n\t\t\tconst point = c1Result.point[ xyzAxis ];\n\t\t\tconst isOutside = leftToRight ?\n\t\t\t\tpoint <= float32Array[ c2 + splitAxis ] : // min bounding data\n\t\t\t\tpoint >= float32Array[ c2 + splitAxis + 3 ]; // max bounding data\n\n\t\t\tif ( isOutside ) {\n\n\t\t\t\treturn c1Result;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// either there was no intersection in the first node, or there could still be a closer\n\t\t// intersection in the second, so check the second node and then take the better of the two\n\t\tconst c2Intersection = intersectsNodeBounds( c2, float32Array, ray, near, far );\n\t\tconst c2Result = c2Intersection ? _raycastFirst( c2, bvh, materialOrSide, ray, near, far ) : null;\n\n\t\tif ( c1Result && c2Result ) {\n\n\t\t\treturn c1Result.distance <= c2Result.distance ? c1Result : c2Result;\n\n\t\t} else {\n\n\t\t\treturn c1Result || c2Result || null;\n\n\t\t}\n\n\t}\n\n}\n\nexport { raycastFirst };\n","import { Box3, Matrix4 } from 'three';\nimport { OrientedBox } from '../../math/OrientedBox.js';\nimport { ExtendedTriangle } from '../../math/ExtendedTriangle.js';\nimport { setTriangle } from '../../utils/TriangleUtilities.js';\nimport { arrayToBox } from '../../utils/ArrayBoxUtilities.js';\nimport { IS_LEAF, OFFSET, COUNT, BOUNDING_DATA_INDEX, LEFT_NODE, RIGHT_NODE } from '../utils/nodeBufferUtils.js';\nimport { BufferStack } from '../utils/BufferStack.js';\nimport { getTriCount } from '../build/geometryUtils.js';\n\n/*****************************************************************/\n/* This file is generated from \"intersectsGeometry.template.js\". */\n/*****************************************************************/\n/* eslint-disable indent */\n\nconst boundingBox = /* @__PURE__ */ new Box3();\nconst triangle = /* @__PURE__ */ new ExtendedTriangle();\nconst triangle2 = /* @__PURE__ */ new ExtendedTriangle();\nconst invertedMat = /* @__PURE__ */ new Matrix4();\n\nconst obb = /* @__PURE__ */ new OrientedBox();\nconst obb2 = /* @__PURE__ */ new OrientedBox();\n\nfunction intersectsGeometry( bvh, root, otherGeometry, geometryToBvh ) {\n\n\tBufferStack.setBuffer( bvh._roots[ root ] );\n\tconst result = _intersectsGeometry( 0, bvh, otherGeometry, geometryToBvh );\n\tBufferStack.clearBuffer();\n\n\treturn result;\n\n}\n\nfunction _intersectsGeometry( nodeIndex32, bvh, otherGeometry, geometryToBvh, cachedObb = null ) {\n\n\tconst { float32Array, uint16Array, uint32Array } = BufferStack;\n\tlet nodeIndex16 = nodeIndex32 * 2;\n\n\tif ( cachedObb === null ) {\n\n\t\tif ( ! otherGeometry.boundingBox ) {\n\n\t\t\totherGeometry.computeBoundingBox();\n\n\t\t}\n\n\t\tobb.set( otherGeometry.boundingBox.min, otherGeometry.boundingBox.max, geometryToBvh );\n\t\tcachedObb = obb;\n\n\t}\n\n\tconst isLeaf = IS_LEAF( nodeIndex16, uint16Array );\n\tif ( isLeaf ) {\n\n\t\tconst thisGeometry = bvh.geometry;\n\t\tconst thisIndex = thisGeometry.index;\n\t\tconst thisPos = thisGeometry.attributes.position;\n\n\t\tconst otherIndex = otherGeometry.index;\n\t\tconst otherPos = otherGeometry.attributes.position;\n\n\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\n\t\t// get the inverse of the geometry matrix so we can transform our triangles into the\n\t\t// geometry space we're trying to test. We assume there are fewer triangles being checked\n\t\t// here.\n\t\tinvertedMat.copy( geometryToBvh ).invert();\n\n\t\tif ( otherGeometry.boundsTree ) {\n\n\t\t\t// if there's a bounds tree\n\t\t\tarrayToBox( BOUNDING_DATA_INDEX( nodeIndex32 ), float32Array, obb2 );\n\t\t\tobb2.matrix.copy( invertedMat );\n\t\t\tobb2.needsUpdate = true;\n\n\t\t\t// TODO: use a triangle iteration function here\n\t\t\tconst res = otherGeometry.boundsTree.shapecast( {\n\n\t\t\t\tintersectsBounds: box => obb2.intersectsBox( box ),\n\n\t\t\t\tintersectsTriangle: tri => {\n\n\t\t\t\t\ttri.a.applyMatrix4( geometryToBvh );\n\t\t\t\t\ttri.b.applyMatrix4( geometryToBvh );\n\t\t\t\t\ttri.c.applyMatrix4( geometryToBvh );\n\t\t\t\t\ttri.needsUpdate = true;\n\n\n\t\t\t\t\tfor ( let i = offset * 3, l = ( count + offset ) * 3; i < l; i += 3 ) {\n\n\t\t\t\t\t\t// this triangle needs to be transformed into the current BVH coordinate frame\n\t\t\t\t\t\tsetTriangle( triangle2, i, thisIndex, thisPos );\n\t\t\t\t\t\ttriangle2.needsUpdate = true;\n\t\t\t\t\t\tif ( tri.intersectsTriangle( triangle2 ) ) {\n\n\t\t\t\t\t\t\treturn true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t\treturn res;\n\n\t\t} else {\n\n\t\t\t// if we're just dealing with raw geometry\n\t\t\tconst otherTriangleCount = getTriCount( otherGeometry );\n\n\n\t\t\tfor ( let i = offset * 3, l = ( count + offset ) * 3; i < l; i += 3 ) {\n\n\t\t\t\t// this triangle needs to be transformed into the current BVH coordinate frame\n\t\t\t\tsetTriangle( triangle, i, thisIndex, thisPos );\n\n\n\t\t\t\ttriangle.a.applyMatrix4( invertedMat );\n\t\t\t\ttriangle.b.applyMatrix4( invertedMat );\n\t\t\t\ttriangle.c.applyMatrix4( invertedMat );\n\t\t\t\ttriangle.needsUpdate = true;\n\n\t\t\t\tfor ( let i2 = 0, l2 = otherTriangleCount * 3; i2 < l2; i2 += 3 ) {\n\n\t\t\t\t\tsetTriangle( triangle2, i2, otherIndex, otherPos );\n\t\t\t\t\ttriangle2.needsUpdate = true;\n\n\t\t\t\t\tif ( triangle.intersectsTriangle( triangle2 ) ) {\n\n\t\t\t\t\t\treturn true;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\n\t\t\t}\n\n\n\t\t}\n\n\t} else {\n\n\t\tconst left = LEFT_NODE( nodeIndex32 );\n\t\tconst right = RIGHT_NODE( nodeIndex32, uint32Array );\n\n\t\tarrayToBox( BOUNDING_DATA_INDEX( left ), float32Array, boundingBox );\n\t\tconst leftIntersection =\n\t\t\tcachedObb.intersectsBox( boundingBox ) &&\n\t\t\t_intersectsGeometry( left, bvh, otherGeometry, geometryToBvh, cachedObb );\n\n\t\tif ( leftIntersection ) return true;\n\n\t\tarrayToBox( BOUNDING_DATA_INDEX( right ), float32Array, boundingBox );\n\t\tconst rightIntersection =\n\t\t\tcachedObb.intersectsBox( boundingBox ) &&\n\t\t\t_intersectsGeometry( right, bvh, otherGeometry, geometryToBvh, cachedObb );\n\n\t\tif ( rightIntersection ) return true;\n\n\t\treturn false;\n\n\t}\n\n}\n\nexport { intersectsGeometry };\n","import { Matrix4, Vector3 } from 'three';\nimport { OrientedBox } from '../../math/OrientedBox.js';\nimport { setTriangle } from '../../utils/TriangleUtilities.js';\nimport { getTriCount } from '../build/geometryUtils.js';\nimport { ExtendedTrianglePool } from '../../utils/ExtendedTrianglePool.js';\n\n/*********************************************************************/\n/* This file is generated from \"closestPointToGeometry.template.js\". */\n/*********************************************************************/\n\nconst tempMatrix = /* @__PURE__ */ new Matrix4();\nconst obb = /* @__PURE__ */ new OrientedBox();\nconst obb2 = /* @__PURE__ */ new OrientedBox();\nconst temp1 = /* @__PURE__ */ new Vector3();\nconst temp2 = /* @__PURE__ */ new Vector3();\nconst temp3 = /* @__PURE__ */ new Vector3();\nconst temp4 = /* @__PURE__ */ new Vector3();\n\nfunction closestPointToGeometry(\n\tbvh,\n\totherGeometry,\n\tgeometryToBvh,\n\ttarget1 = { },\n\ttarget2 = { },\n\tminThreshold = 0,\n\tmaxThreshold = Infinity,\n) {\n\n\tif ( ! otherGeometry.boundingBox ) {\n\n\t\totherGeometry.computeBoundingBox();\n\n\t}\n\n\tobb.set( otherGeometry.boundingBox.min, otherGeometry.boundingBox.max, geometryToBvh );\n\tobb.needsUpdate = true;\n\n\tconst geometry = bvh.geometry;\n\tconst pos = geometry.attributes.position;\n\tconst index = geometry.index;\n\tconst otherPos = otherGeometry.attributes.position;\n\tconst otherIndex = otherGeometry.index;\n\tconst triangle = ExtendedTrianglePool.getPrimitive();\n\tconst triangle2 = ExtendedTrianglePool.getPrimitive();\n\n\tlet tempTarget1 = temp1;\n\tlet tempTargetDest1 = temp2;\n\tlet tempTarget2 = null;\n\tlet tempTargetDest2 = null;\n\n\tif ( target2 ) {\n\n\t\ttempTarget2 = temp3;\n\t\ttempTargetDest2 = temp4;\n\n\t}\n\n\tlet closestDistance = Infinity;\n\tlet closestDistanceTriIndex = null;\n\tlet closestDistanceOtherTriIndex = null;\n\ttempMatrix.copy( geometryToBvh ).invert();\n\tobb2.matrix.copy( tempMatrix );\n\tbvh.shapecast(\n\t\t{\n\n\t\t\tboundsTraverseOrder: box => {\n\n\t\t\t\treturn obb.distanceToBox( box );\n\n\t\t\t},\n\n\t\t\tintersectsBounds: ( box, isLeaf, score ) => {\n\n\t\t\t\tif ( score < closestDistance && score < maxThreshold ) {\n\n\t\t\t\t\t// if we know the triangles of this bounds will be intersected next then\n\t\t\t\t\t// save the bounds to use during triangle checks.\n\t\t\t\t\tif ( isLeaf ) {\n\n\t\t\t\t\t\tobb2.min.copy( box.min );\n\t\t\t\t\t\tobb2.max.copy( box.max );\n\t\t\t\t\t\tobb2.needsUpdate = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\n\t\t\t},\n\n\t\t\tintersectsRange: ( offset, count ) => {\n\n\t\t\t\tif ( otherGeometry.boundsTree ) {\n\n\t\t\t\t\t// if the other geometry has a bvh then use the accelerated path where we use shapecast to find\n\t\t\t\t\t// the closest bounds in the other geometry to check.\n\t\t\t\t\tconst otherBvh = otherGeometry.boundsTree;\n\t\t\t\t\treturn otherBvh.shapecast( {\n\t\t\t\t\t\tboundsTraverseOrder: box => {\n\n\t\t\t\t\t\t\treturn obb2.distanceToBox( box );\n\n\t\t\t\t\t\t},\n\n\t\t\t\t\t\tintersectsBounds: ( box, isLeaf, score ) => {\n\n\t\t\t\t\t\t\treturn score < closestDistance && score < maxThreshold;\n\n\t\t\t\t\t\t},\n\n\t\t\t\t\t\tintersectsRange: ( otherOffset, otherCount ) => {\n\n\t\t\t\t\t\t\tfor ( let i2 = otherOffset, l2 = otherOffset + otherCount; i2 < l2; i2 ++ ) {\n\n\n\t\t\t\t\t\t\t\tsetTriangle( triangle2, 3 * i2, otherIndex, otherPos );\n\n\t\t\t\t\t\t\t\ttriangle2.a.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\t\t\ttriangle2.b.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\t\t\ttriangle2.c.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\t\t\ttriangle2.needsUpdate = true;\n\n\t\t\t\t\t\t\t\tfor ( let i = offset, l = offset + count; i < l; i ++ ) {\n\n\n\t\t\t\t\t\t\t\t\tsetTriangle( triangle, 3 * i, index, pos );\n\n\t\t\t\t\t\t\t\t\ttriangle.needsUpdate = true;\n\n\t\t\t\t\t\t\t\t\tconst dist = triangle.distanceToTriangle( triangle2, tempTarget1, tempTarget2 );\n\t\t\t\t\t\t\t\t\tif ( dist < closestDistance ) {\n\n\t\t\t\t\t\t\t\t\t\ttempTargetDest1.copy( tempTarget1 );\n\n\t\t\t\t\t\t\t\t\t\tif ( tempTargetDest2 ) {\n\n\t\t\t\t\t\t\t\t\t\t\ttempTargetDest2.copy( tempTarget2 );\n\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tclosestDistance = dist;\n\t\t\t\t\t\t\t\t\t\tclosestDistanceTriIndex = i;\n\t\t\t\t\t\t\t\t\t\tclosestDistanceOtherTriIndex = i2;\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// stop traversal if we find a point that's under the given threshold\n\t\t\t\t\t\t\t\t\tif ( dist < minThreshold ) {\n\n\t\t\t\t\t\t\t\t\t\treturn true;\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t},\n\t\t\t\t\t} );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// If no bounds tree then we'll just check every triangle.\n\t\t\t\t\tconst triCount = getTriCount( otherGeometry );\n\t\t\t\t\tfor ( let i2 = 0, l2 = triCount; i2 < l2; i2 ++ ) {\n\n\t\t\t\t\t\tsetTriangle( triangle2, 3 * i2, otherIndex, otherPos );\n\t\t\t\t\t\ttriangle2.a.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\ttriangle2.b.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\ttriangle2.c.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\ttriangle2.needsUpdate = true;\n\n\t\t\t\t\t\tfor ( let i = offset, l = offset + count; i < l; i ++ ) {\n\n\n\t\t\t\t\t\t\tsetTriangle( triangle, 3 * i, index, pos );\n\n\t\t\t\t\t\t\ttriangle.needsUpdate = true;\n\n\t\t\t\t\t\t\tconst dist = triangle.distanceToTriangle( triangle2, tempTarget1, tempTarget2 );\n\t\t\t\t\t\t\tif ( dist < closestDistance ) {\n\n\t\t\t\t\t\t\t\ttempTargetDest1.copy( tempTarget1 );\n\n\t\t\t\t\t\t\t\tif ( tempTargetDest2 ) {\n\n\t\t\t\t\t\t\t\t\ttempTargetDest2.copy( tempTarget2 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tclosestDistance = dist;\n\t\t\t\t\t\t\t\tclosestDistanceTriIndex = i;\n\t\t\t\t\t\t\t\tclosestDistanceOtherTriIndex = i2;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// stop traversal if we find a point that's under the given threshold\n\t\t\t\t\t\t\tif ( dist < minThreshold ) {\n\n\t\t\t\t\t\t\t\treturn true;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t}\n\n\t);\n\n\tExtendedTrianglePool.releasePrimitive( triangle );\n\tExtendedTrianglePool.releasePrimitive( triangle2 );\n\n\tif ( closestDistance === Infinity ) {\n\n\t\treturn null;\n\n\t}\n\n\tif ( ! target1.point ) {\n\n\t\ttarget1.point = tempTargetDest1.clone();\n\n\t} else {\n\n\t\ttarget1.point.copy( tempTargetDest1 );\n\n\t}\n\n\ttarget1.distance = closestDistance,\n\ttarget1.faceIndex = closestDistanceTriIndex;\n\n\tif ( target2 ) {\n\n\t\tif ( ! target2.point ) target2.point = tempTargetDest2.clone();\n\t\telse target2.point.copy( tempTargetDest2 );\n\t\ttarget2.point.applyMatrix4( tempMatrix );\n\t\ttempTargetDest1.applyMatrix4( tempMatrix );\n\t\ttarget2.distance = tempTargetDest1.sub( target2.point ).length();\n\t\ttarget2.faceIndex = closestDistanceOtherTriIndex;\n\n\t}\n\n\treturn target1;\n\n}\n\nexport { closestPointToGeometry };\n","import { UINT32_PER_NODE, BYTES_PER_NODE } from '../Constants.js';\nimport { IS_LEAF, OFFSET, COUNT, LEFT_NODE, RIGHT_NODE } from '../utils/nodeBufferUtils.js';\n\n/****************************************************/\n/* This file is generated from \"refit.template.js\". */\n/****************************************************/\n\nfunction refit_indirect( bvh, nodeIndices = null ) {\n\n\tif ( nodeIndices && Array.isArray( nodeIndices ) ) {\n\n\t\tnodeIndices = new Set( nodeIndices );\n\n\t}\n\n\tconst geometry = bvh.geometry;\n\tconst indexArr = geometry.index ? geometry.index.array : null;\n\tconst posAttr = geometry.attributes.position;\n\n\tlet buffer, uint32Array, uint16Array, float32Array;\n\tlet byteOffset = 0;\n\tconst roots = bvh._roots;\n\tfor ( let i = 0, l = roots.length; i < l; i ++ ) {\n\n\t\tbuffer = roots[ i ];\n\t\tuint32Array = new Uint32Array( buffer );\n\t\tuint16Array = new Uint16Array( buffer );\n\t\tfloat32Array = new Float32Array( buffer );\n\n\t\t_traverse( 0, byteOffset );\n\t\tbyteOffset += buffer.byteLength;\n\n\t}\n\n\tfunction _traverse( nodeIndex32, byteOffset, force = false ) {\n\n\t\tconst nodeIndex16 = nodeIndex32 * 2;\n\t\tif ( IS_LEAF( nodeIndex16, uint16Array ) ) {\n\n\t\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\n\t\t\tlet minx = Infinity;\n\t\t\tlet miny = Infinity;\n\t\t\tlet minz = Infinity;\n\t\t\tlet maxx = - Infinity;\n\t\t\tlet maxy = - Infinity;\n\t\t\tlet maxz = - Infinity;\n\n\t\t\tfor ( let i = offset, l = offset + count; i < l; i ++ ) {\n\n\t\t\t\tconst t = 3 * bvh.resolveTriangleIndex( i );\n\t\t\t\tfor ( let j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\tlet index = t + j;\n\t\t\t\t\tindex = indexArr ? indexArr[ index ] : index;\n\n\t\t\t\t\tconst x = posAttr.getX( index );\n\t\t\t\t\tconst y = posAttr.getY( index );\n\t\t\t\t\tconst z = posAttr.getZ( index );\n\n\t\t\t\t\tif ( x < minx ) minx = x;\n\t\t\t\t\tif ( x > maxx ) maxx = x;\n\n\t\t\t\t\tif ( y < miny ) miny = y;\n\t\t\t\t\tif ( y > maxy ) maxy = y;\n\n\t\t\t\t\tif ( z < minz ) minz = z;\n\t\t\t\t\tif ( z > maxz ) maxz = z;\n\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tif (\n\t\t\t\tfloat32Array[ nodeIndex32 + 0 ] !== minx ||\n\t\t\t\tfloat32Array[ nodeIndex32 + 1 ] !== miny ||\n\t\t\t\tfloat32Array[ nodeIndex32 + 2 ] !== minz ||\n\n\t\t\t\tfloat32Array[ nodeIndex32 + 3 ] !== maxx ||\n\t\t\t\tfloat32Array[ nodeIndex32 + 4 ] !== maxy ||\n\t\t\t\tfloat32Array[ nodeIndex32 + 5 ] !== maxz\n\t\t\t) {\n\n\t\t\t\tfloat32Array[ nodeIndex32 + 0 ] = minx;\n\t\t\t\tfloat32Array[ nodeIndex32 + 1 ] = miny;\n\t\t\t\tfloat32Array[ nodeIndex32 + 2 ] = minz;\n\n\t\t\t\tfloat32Array[ nodeIndex32 + 3 ] = maxx;\n\t\t\t\tfloat32Array[ nodeIndex32 + 4 ] = maxy;\n\t\t\t\tfloat32Array[ nodeIndex32 + 5 ] = maxz;\n\n\t\t\t\treturn true;\n\n\t\t\t} else {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tconst left = LEFT_NODE( nodeIndex32 );\n\t\t\tconst right = RIGHT_NODE( nodeIndex32, uint32Array );\n\n\t\t\t// the identifying node indices provided by the shapecast function include offsets of all\n\t\t\t// root buffers to guarantee they're unique between roots so offset left and right indices here.\n\t\t\tlet forceChildren = force;\n\t\t\tlet includesLeft = false;\n\t\t\tlet includesRight = false;\n\n\t\t\tif ( nodeIndices ) {\n\n\t\t\t\t// if we see that neither the left or right child are included in the set that need to be updated\n\t\t\t\t// then we assume that all children need to be updated.\n\t\t\t\tif ( ! forceChildren ) {\n\n\t\t\t\t\tconst leftNodeId = left / UINT32_PER_NODE + byteOffset / BYTES_PER_NODE;\n\t\t\t\t\tconst rightNodeId = right / UINT32_PER_NODE + byteOffset / BYTES_PER_NODE;\n\t\t\t\t\tincludesLeft = nodeIndices.has( leftNodeId );\n\t\t\t\t\tincludesRight = nodeIndices.has( rightNodeId );\n\t\t\t\t\tforceChildren = ! includesLeft && ! includesRight;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tincludesLeft = true;\n\t\t\t\tincludesRight = true;\n\n\t\t\t}\n\n\t\t\tconst traverseLeft = forceChildren || includesLeft;\n\t\t\tconst traverseRight = forceChildren || includesRight;\n\n\t\t\tlet leftChange = false;\n\t\t\tif ( traverseLeft ) {\n\n\t\t\t\tleftChange = _traverse( left, byteOffset, forceChildren );\n\n\t\t\t}\n\n\t\t\tlet rightChange = false;\n\t\t\tif ( traverseRight ) {\n\n\t\t\t\trightChange = _traverse( right, byteOffset, forceChildren );\n\n\t\t\t}\n\n\t\t\tconst didChange = leftChange || rightChange;\n\t\t\tif ( didChange ) {\n\n\t\t\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\tconst left_i = left + i;\n\t\t\t\t\tconst right_i = right + i;\n\t\t\t\t\tconst minLeftValue = float32Array[ left_i ];\n\t\t\t\t\tconst maxLeftValue = float32Array[ left_i + 3 ];\n\t\t\t\t\tconst minRightValue = float32Array[ right_i ];\n\t\t\t\t\tconst maxRightValue = float32Array[ right_i + 3 ];\n\n\t\t\t\t\tfloat32Array[ nodeIndex32 + i ] = minLeftValue < minRightValue ? minLeftValue : minRightValue;\n\t\t\t\t\tfloat32Array[ nodeIndex32 + i + 3 ] = maxLeftValue > maxRightValue ? maxLeftValue : maxRightValue;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn didChange;\n\n\t\t}\n\n\t}\n\n}\n\nexport { refit_indirect };\n","import { intersectsNodeBounds } from '../utils/intersectUtils.js';\nimport { IS_LEAF, OFFSET, COUNT, LEFT_NODE, RIGHT_NODE } from '../utils/nodeBufferUtils.js';\nimport { BufferStack } from '../utils/BufferStack.js';\nimport '../utils/iterationUtils.generated.js';\nimport { intersectTris_indirect } from '../utils/iterationUtils_indirect.generated.js';\n\n/******************************************************/\n/* This file is generated from \"raycast.template.js\". */\n/******************************************************/\n\nfunction raycast_indirect( bvh, root, materialOrSide, ray, intersects, near, far ) {\n\n\tBufferStack.setBuffer( bvh._roots[ root ] );\n\t_raycast( 0, bvh, materialOrSide, ray, intersects, near, far );\n\tBufferStack.clearBuffer();\n\n}\n\nfunction _raycast( nodeIndex32, bvh, materialOrSide, ray, intersects, near, far ) {\n\n\tconst { float32Array, uint16Array, uint32Array } = BufferStack;\n\tconst nodeIndex16 = nodeIndex32 * 2;\n\tconst isLeaf = IS_LEAF( nodeIndex16, uint16Array );\n\tif ( isLeaf ) {\n\n\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\n\t\tintersectTris_indirect( bvh, materialOrSide, ray, offset, count, intersects, near, far );\n\n\n\t} else {\n\n\t\tconst leftIndex = LEFT_NODE( nodeIndex32 );\n\t\tif ( intersectsNodeBounds( leftIndex, float32Array, ray, near, far ) ) {\n\n\t\t\t_raycast( leftIndex, bvh, materialOrSide, ray, intersects, near, far );\n\n\t\t}\n\n\t\tconst rightIndex = RIGHT_NODE( nodeIndex32, uint32Array );\n\t\tif ( intersectsNodeBounds( rightIndex, float32Array, ray, near, far ) ) {\n\n\t\t\t_raycast( rightIndex, bvh, materialOrSide, ray, intersects, near, far );\n\n\t\t}\n\n\t}\n\n}\n\nexport { raycast_indirect };\n","import { IS_LEAF, OFFSET, COUNT, SPLIT_AXIS, LEFT_NODE, RIGHT_NODE } from '../utils/nodeBufferUtils.js';\nimport { BufferStack } from '../utils/BufferStack.js';\nimport { intersectsNodeBounds } from '../utils/intersectUtils.js';\nimport '../utils/iterationUtils.generated.js';\nimport { intersectClosestTri_indirect } from '../utils/iterationUtils_indirect.generated.js';\n\n/***********************************************************/\n/* This file is generated from \"raycastFirst.template.js\". */\n/***********************************************************/\n\nconst _xyzFields = [ 'x', 'y', 'z' ];\n\nfunction raycastFirst_indirect( bvh, root, materialOrSide, ray, near, far ) {\n\n\tBufferStack.setBuffer( bvh._roots[ root ] );\n\tconst result = _raycastFirst( 0, bvh, materialOrSide, ray, near, far );\n\tBufferStack.clearBuffer();\n\n\treturn result;\n\n}\n\nfunction _raycastFirst( nodeIndex32, bvh, materialOrSide, ray, near, far ) {\n\n\tconst { float32Array, uint16Array, uint32Array } = BufferStack;\n\tlet nodeIndex16 = nodeIndex32 * 2;\n\n\tconst isLeaf = IS_LEAF( nodeIndex16, uint16Array );\n\tif ( isLeaf ) {\n\n\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\n\t\treturn intersectClosestTri_indirect( bvh, materialOrSide, ray, offset, count, near, far );\n\n\n\t} else {\n\n\t\t// consider the position of the split plane with respect to the oncoming ray; whichever direction\n\t\t// the ray is coming from, look for an intersection among that side of the tree first\n\t\tconst splitAxis = SPLIT_AXIS( nodeIndex32, uint32Array );\n\t\tconst xyzAxis = _xyzFields[ splitAxis ];\n\t\tconst rayDir = ray.direction[ xyzAxis ];\n\t\tconst leftToRight = rayDir >= 0;\n\n\t\t// c1 is the child to check first\n\t\tlet c1, c2;\n\t\tif ( leftToRight ) {\n\n\t\t\tc1 = LEFT_NODE( nodeIndex32 );\n\t\t\tc2 = RIGHT_NODE( nodeIndex32, uint32Array );\n\n\t\t} else {\n\n\t\t\tc1 = RIGHT_NODE( nodeIndex32, uint32Array );\n\t\t\tc2 = LEFT_NODE( nodeIndex32 );\n\n\t\t}\n\n\t\tconst c1Intersection = intersectsNodeBounds( c1, float32Array, ray, near, far );\n\t\tconst c1Result = c1Intersection ? _raycastFirst( c1, bvh, materialOrSide, ray, near, far ) : null;\n\n\t\t// if we got an intersection in the first node and it's closer than the second node's bounding\n\t\t// box, we don't need to consider the second node because it couldn't possibly be a better result\n\t\tif ( c1Result ) {\n\n\t\t\t// check if the point is within the second bounds\n\t\t\t// \"point\" is in the local frame of the bvh\n\t\t\tconst point = c1Result.point[ xyzAxis ];\n\t\t\tconst isOutside = leftToRight ?\n\t\t\t\tpoint <= float32Array[ c2 + splitAxis ] : // min bounding data\n\t\t\t\tpoint >= float32Array[ c2 + splitAxis + 3 ]; // max bounding data\n\n\t\t\tif ( isOutside ) {\n\n\t\t\t\treturn c1Result;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// either there was no intersection in the first node, or there could still be a closer\n\t\t// intersection in the second, so check the second node and then take the better of the two\n\t\tconst c2Intersection = intersectsNodeBounds( c2, float32Array, ray, near, far );\n\t\tconst c2Result = c2Intersection ? _raycastFirst( c2, bvh, materialOrSide, ray, near, far ) : null;\n\n\t\tif ( c1Result && c2Result ) {\n\n\t\t\treturn c1Result.distance <= c2Result.distance ? c1Result : c2Result;\n\n\t\t} else {\n\n\t\t\treturn c1Result || c2Result || null;\n\n\t\t}\n\n\t}\n\n}\n\nexport { raycastFirst_indirect };\n","import { Box3, Matrix4 } from 'three';\nimport { OrientedBox } from '../../math/OrientedBox.js';\nimport { ExtendedTriangle } from '../../math/ExtendedTriangle.js';\nimport { setTriangle } from '../../utils/TriangleUtilities.js';\nimport { arrayToBox } from '../../utils/ArrayBoxUtilities.js';\nimport { IS_LEAF, OFFSET, COUNT, BOUNDING_DATA_INDEX, LEFT_NODE, RIGHT_NODE } from '../utils/nodeBufferUtils.js';\nimport { BufferStack } from '../utils/BufferStack.js';\nimport { getTriCount } from '../build/geometryUtils.js';\n\n/*****************************************************************/\n/* This file is generated from \"intersectsGeometry.template.js\". */\n/*****************************************************************/\n/* eslint-disable indent */\n\nconst boundingBox = /* @__PURE__ */ new Box3();\nconst triangle = /* @__PURE__ */ new ExtendedTriangle();\nconst triangle2 = /* @__PURE__ */ new ExtendedTriangle();\nconst invertedMat = /* @__PURE__ */ new Matrix4();\n\nconst obb = /* @__PURE__ */ new OrientedBox();\nconst obb2 = /* @__PURE__ */ new OrientedBox();\n\nfunction intersectsGeometry_indirect( bvh, root, otherGeometry, geometryToBvh ) {\n\n\tBufferStack.setBuffer( bvh._roots[ root ] );\n\tconst result = _intersectsGeometry( 0, bvh, otherGeometry, geometryToBvh );\n\tBufferStack.clearBuffer();\n\n\treturn result;\n\n}\n\nfunction _intersectsGeometry( nodeIndex32, bvh, otherGeometry, geometryToBvh, cachedObb = null ) {\n\n\tconst { float32Array, uint16Array, uint32Array } = BufferStack;\n\tlet nodeIndex16 = nodeIndex32 * 2;\n\n\tif ( cachedObb === null ) {\n\n\t\tif ( ! otherGeometry.boundingBox ) {\n\n\t\t\totherGeometry.computeBoundingBox();\n\n\t\t}\n\n\t\tobb.set( otherGeometry.boundingBox.min, otherGeometry.boundingBox.max, geometryToBvh );\n\t\tcachedObb = obb;\n\n\t}\n\n\tconst isLeaf = IS_LEAF( nodeIndex16, uint16Array );\n\tif ( isLeaf ) {\n\n\t\tconst thisGeometry = bvh.geometry;\n\t\tconst thisIndex = thisGeometry.index;\n\t\tconst thisPos = thisGeometry.attributes.position;\n\n\t\tconst otherIndex = otherGeometry.index;\n\t\tconst otherPos = otherGeometry.attributes.position;\n\n\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\n\t\t// get the inverse of the geometry matrix so we can transform our triangles into the\n\t\t// geometry space we're trying to test. We assume there are fewer triangles being checked\n\t\t// here.\n\t\tinvertedMat.copy( geometryToBvh ).invert();\n\n\t\tif ( otherGeometry.boundsTree ) {\n\n\t\t\t// if there's a bounds tree\n\t\t\tarrayToBox( BOUNDING_DATA_INDEX( nodeIndex32 ), float32Array, obb2 );\n\t\t\tobb2.matrix.copy( invertedMat );\n\t\t\tobb2.needsUpdate = true;\n\n\t\t\t// TODO: use a triangle iteration function here\n\t\t\tconst res = otherGeometry.boundsTree.shapecast( {\n\n\t\t\t\tintersectsBounds: box => obb2.intersectsBox( box ),\n\n\t\t\t\tintersectsTriangle: tri => {\n\n\t\t\t\t\ttri.a.applyMatrix4( geometryToBvh );\n\t\t\t\t\ttri.b.applyMatrix4( geometryToBvh );\n\t\t\t\t\ttri.c.applyMatrix4( geometryToBvh );\n\t\t\t\t\ttri.needsUpdate = true;\n\n\t\t\t\t\tfor ( let i = offset, l = count + offset; i < l; i ++ ) {\n\n\t\t\t\t\t\t// this triangle needs to be transformed into the current BVH coordinate frame\n\t\t\t\t\t\tsetTriangle( triangle2, 3 * bvh.resolveTriangleIndex( i ), thisIndex, thisPos );\n\t\t\t\t\t\ttriangle2.needsUpdate = true;\n\t\t\t\t\t\tif ( tri.intersectsTriangle( triangle2 ) ) {\n\n\t\t\t\t\t\t\treturn true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t\treturn res;\n\n\t\t} else {\n\n\t\t\t// if we're just dealing with raw geometry\n\t\t\tconst otherTriangleCount = getTriCount( otherGeometry );\n\n\t\t\tfor ( let i = offset, l = count + offset; i < l; i ++ ) {\n\n\t\t\t\t// this triangle needs to be transformed into the current BVH coordinate frame\n\t\t\t\tconst ti = bvh.resolveTriangleIndex( i );\n\t\t\t\tsetTriangle( triangle, 3 * ti, thisIndex, thisPos );\n\n\n\t\t\t\ttriangle.a.applyMatrix4( invertedMat );\n\t\t\t\ttriangle.b.applyMatrix4( invertedMat );\n\t\t\t\ttriangle.c.applyMatrix4( invertedMat );\n\t\t\t\ttriangle.needsUpdate = true;\n\n\t\t\t\tfor ( let i2 = 0, l2 = otherTriangleCount * 3; i2 < l2; i2 += 3 ) {\n\n\t\t\t\t\tsetTriangle( triangle2, i2, otherIndex, otherPos );\n\t\t\t\t\ttriangle2.needsUpdate = true;\n\n\t\t\t\t\tif ( triangle.intersectsTriangle( triangle2 ) ) {\n\n\t\t\t\t\t\treturn true;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t}\n\n\t} else {\n\n\t\tconst left = LEFT_NODE( nodeIndex32 );\n\t\tconst right = RIGHT_NODE( nodeIndex32, uint32Array );\n\n\t\tarrayToBox( BOUNDING_DATA_INDEX( left ), float32Array, boundingBox );\n\t\tconst leftIntersection =\n\t\t\tcachedObb.intersectsBox( boundingBox ) &&\n\t\t\t_intersectsGeometry( left, bvh, otherGeometry, geometryToBvh, cachedObb );\n\n\t\tif ( leftIntersection ) return true;\n\n\t\tarrayToBox( BOUNDING_DATA_INDEX( right ), float32Array, boundingBox );\n\t\tconst rightIntersection =\n\t\t\tcachedObb.intersectsBox( boundingBox ) &&\n\t\t\t_intersectsGeometry( right, bvh, otherGeometry, geometryToBvh, cachedObb );\n\n\t\tif ( rightIntersection ) return true;\n\n\t\treturn false;\n\n\t}\n\n}\n\nexport { intersectsGeometry_indirect };\n","import { Matrix4, Vector3 } from 'three';\nimport { OrientedBox } from '../../math/OrientedBox.js';\nimport { setTriangle } from '../../utils/TriangleUtilities.js';\nimport { getTriCount } from '../build/geometryUtils.js';\nimport { ExtendedTrianglePool } from '../../utils/ExtendedTrianglePool.js';\n\n/*********************************************************************/\n/* This file is generated from \"closestPointToGeometry.template.js\". */\n/*********************************************************************/\n\nconst tempMatrix = /* @__PURE__ */ new Matrix4();\nconst obb = /* @__PURE__ */ new OrientedBox();\nconst obb2 = /* @__PURE__ */ new OrientedBox();\nconst temp1 = /* @__PURE__ */ new Vector3();\nconst temp2 = /* @__PURE__ */ new Vector3();\nconst temp3 = /* @__PURE__ */ new Vector3();\nconst temp4 = /* @__PURE__ */ new Vector3();\n\nfunction closestPointToGeometry_indirect(\n\tbvh,\n\totherGeometry,\n\tgeometryToBvh,\n\ttarget1 = { },\n\ttarget2 = { },\n\tminThreshold = 0,\n\tmaxThreshold = Infinity,\n) {\n\n\tif ( ! otherGeometry.boundingBox ) {\n\n\t\totherGeometry.computeBoundingBox();\n\n\t}\n\n\tobb.set( otherGeometry.boundingBox.min, otherGeometry.boundingBox.max, geometryToBvh );\n\tobb.needsUpdate = true;\n\n\tconst geometry = bvh.geometry;\n\tconst pos = geometry.attributes.position;\n\tconst index = geometry.index;\n\tconst otherPos = otherGeometry.attributes.position;\n\tconst otherIndex = otherGeometry.index;\n\tconst triangle = ExtendedTrianglePool.getPrimitive();\n\tconst triangle2 = ExtendedTrianglePool.getPrimitive();\n\n\tlet tempTarget1 = temp1;\n\tlet tempTargetDest1 = temp2;\n\tlet tempTarget2 = null;\n\tlet tempTargetDest2 = null;\n\n\tif ( target2 ) {\n\n\t\ttempTarget2 = temp3;\n\t\ttempTargetDest2 = temp4;\n\n\t}\n\n\tlet closestDistance = Infinity;\n\tlet closestDistanceTriIndex = null;\n\tlet closestDistanceOtherTriIndex = null;\n\ttempMatrix.copy( geometryToBvh ).invert();\n\tobb2.matrix.copy( tempMatrix );\n\tbvh.shapecast(\n\t\t{\n\n\t\t\tboundsTraverseOrder: box => {\n\n\t\t\t\treturn obb.distanceToBox( box );\n\n\t\t\t},\n\n\t\t\tintersectsBounds: ( box, isLeaf, score ) => {\n\n\t\t\t\tif ( score < closestDistance && score < maxThreshold ) {\n\n\t\t\t\t\t// if we know the triangles of this bounds will be intersected next then\n\t\t\t\t\t// save the bounds to use during triangle checks.\n\t\t\t\t\tif ( isLeaf ) {\n\n\t\t\t\t\t\tobb2.min.copy( box.min );\n\t\t\t\t\t\tobb2.max.copy( box.max );\n\t\t\t\t\t\tobb2.needsUpdate = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\n\t\t\t},\n\n\t\t\tintersectsRange: ( offset, count ) => {\n\n\t\t\t\tif ( otherGeometry.boundsTree ) {\n\n\t\t\t\t\t// if the other geometry has a bvh then use the accelerated path where we use shapecast to find\n\t\t\t\t\t// the closest bounds in the other geometry to check.\n\t\t\t\t\tconst otherBvh = otherGeometry.boundsTree;\n\t\t\t\t\treturn otherBvh.shapecast( {\n\t\t\t\t\t\tboundsTraverseOrder: box => {\n\n\t\t\t\t\t\t\treturn obb2.distanceToBox( box );\n\n\t\t\t\t\t\t},\n\n\t\t\t\t\t\tintersectsBounds: ( box, isLeaf, score ) => {\n\n\t\t\t\t\t\t\treturn score < closestDistance && score < maxThreshold;\n\n\t\t\t\t\t\t},\n\n\t\t\t\t\t\tintersectsRange: ( otherOffset, otherCount ) => {\n\n\t\t\t\t\t\t\tfor ( let i2 = otherOffset, l2 = otherOffset + otherCount; i2 < l2; i2 ++ ) {\n\n\t\t\t\t\t\t\t\tconst ti2 = otherBvh.resolveTriangleIndex( i2 );\n\t\t\t\t\t\t\t\tsetTriangle( triangle2, 3 * ti2, otherIndex, otherPos );\n\n\t\t\t\t\t\t\t\ttriangle2.a.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\t\t\ttriangle2.b.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\t\t\ttriangle2.c.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\t\t\ttriangle2.needsUpdate = true;\n\n\t\t\t\t\t\t\t\tfor ( let i = offset, l = offset + count; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tconst ti = bvh.resolveTriangleIndex( i );\n\t\t\t\t\t\t\t\t\tsetTriangle( triangle, 3 * ti, index, pos );\n\n\t\t\t\t\t\t\t\t\ttriangle.needsUpdate = true;\n\n\t\t\t\t\t\t\t\t\tconst dist = triangle.distanceToTriangle( triangle2, tempTarget1, tempTarget2 );\n\t\t\t\t\t\t\t\t\tif ( dist < closestDistance ) {\n\n\t\t\t\t\t\t\t\t\t\ttempTargetDest1.copy( tempTarget1 );\n\n\t\t\t\t\t\t\t\t\t\tif ( tempTargetDest2 ) {\n\n\t\t\t\t\t\t\t\t\t\t\ttempTargetDest2.copy( tempTarget2 );\n\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tclosestDistance = dist;\n\t\t\t\t\t\t\t\t\t\tclosestDistanceTriIndex = i;\n\t\t\t\t\t\t\t\t\t\tclosestDistanceOtherTriIndex = i2;\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// stop traversal if we find a point that's under the given threshold\n\t\t\t\t\t\t\t\t\tif ( dist < minThreshold ) {\n\n\t\t\t\t\t\t\t\t\t\treturn true;\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t},\n\t\t\t\t\t} );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// If no bounds tree then we'll just check every triangle.\n\t\t\t\t\tconst triCount = getTriCount( otherGeometry );\n\t\t\t\t\tfor ( let i2 = 0, l2 = triCount; i2 < l2; i2 ++ ) {\n\n\t\t\t\t\t\tsetTriangle( triangle2, 3 * i2, otherIndex, otherPos );\n\t\t\t\t\t\ttriangle2.a.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\ttriangle2.b.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\ttriangle2.c.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\ttriangle2.needsUpdate = true;\n\n\t\t\t\t\t\tfor ( let i = offset, l = offset + count; i < l; i ++ ) {\n\n\t\t\t\t\t\t\tconst ti = bvh.resolveTriangleIndex( i );\n\t\t\t\t\t\t\tsetTriangle( triangle, 3 * ti, index, pos );\n\n\t\t\t\t\t\t\ttriangle.needsUpdate = true;\n\n\t\t\t\t\t\t\tconst dist = triangle.distanceToTriangle( triangle2, tempTarget1, tempTarget2 );\n\t\t\t\t\t\t\tif ( dist < closestDistance ) {\n\n\t\t\t\t\t\t\t\ttempTargetDest1.copy( tempTarget1 );\n\n\t\t\t\t\t\t\t\tif ( tempTargetDest2 ) {\n\n\t\t\t\t\t\t\t\t\ttempTargetDest2.copy( tempTarget2 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tclosestDistance = dist;\n\t\t\t\t\t\t\t\tclosestDistanceTriIndex = i;\n\t\t\t\t\t\t\t\tclosestDistanceOtherTriIndex = i2;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// stop traversal if we find a point that's under the given threshold\n\t\t\t\t\t\t\tif ( dist < minThreshold ) {\n\n\t\t\t\t\t\t\t\treturn true;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t}\n\n\t);\n\n\tExtendedTrianglePool.releasePrimitive( triangle );\n\tExtendedTrianglePool.releasePrimitive( triangle2 );\n\n\tif ( closestDistance === Infinity ) {\n\n\t\treturn null;\n\n\t}\n\n\tif ( ! target1.point ) {\n\n\t\ttarget1.point = tempTargetDest1.clone();\n\n\t} else {\n\n\t\ttarget1.point.copy( tempTargetDest1 );\n\n\t}\n\n\ttarget1.distance = closestDistance,\n\ttarget1.faceIndex = closestDistanceTriIndex;\n\n\tif ( target2 ) {\n\n\t\tif ( ! target2.point ) target2.point = tempTargetDest2.clone();\n\t\telse target2.point.copy( tempTargetDest2 );\n\t\ttarget2.point.applyMatrix4( tempMatrix );\n\t\ttempTargetDest1.applyMatrix4( tempMatrix );\n\t\ttarget2.distance = tempTargetDest1.sub( target2.point ).length();\n\t\ttarget2.faceIndex = closestDistanceOtherTriIndex;\n\n\t}\n\n\treturn target1;\n\n}\n\nexport { closestPointToGeometry_indirect };\n","// converts the given BVH raycast intersection to align with the three.js raycast\n// structure (include object, world space distance and point).\nexport function convertRaycastIntersect( hit, object, raycaster ) {\n\n\tif ( hit === null ) {\n\n\t\treturn null;\n\n\t}\n\n\thit.point.applyMatrix4( object.matrixWorld );\n\thit.distance = hit.point.distanceTo( raycaster.ray.origin );\n\thit.object = object;\n\n\treturn hit;\n\n}\n","/** @import { BufferGeometry, Sphere, Box3, Intersection, Material, Object3D, Raycaster } from 'three' */\n/** @import { ExtendedTriangle } from '../math/ExtendedTriangle.js' */\n/** @import { IntersectsBoundsCallback, IntersectsRangeCallback, BoundsTraverseOrderCallback, IntersectsRangesCallback } from './BVH.js' */\nimport { BufferAttribute, FrontSide, Ray, Vector3, Matrix4 } from 'three';\nimport { SKIP_GENERATION, BYTES_PER_NODE, UINT32_PER_NODE, FLOAT32_EPSILON } from './Constants.js';\nimport { OrientedBox } from '../math/OrientedBox.js';\nimport { ExtendedTrianglePool } from '../utils/ExtendedTrianglePool.js';\nimport { closestPointToPoint } from './cast/closestPointToPoint.js';\nimport { IS_LEAF } from './utils/nodeBufferUtils.js';\n\nimport { iterateOverTriangles } from './utils/iterationUtils.generated.js';\nimport { refit } from './cast/refit.generated.js';\nimport { raycast } from './cast/raycast.generated.js';\nimport { raycastFirst } from './cast/raycastFirst.generated.js';\nimport { intersectsGeometry } from './cast/intersectsGeometry.generated.js';\nimport { closestPointToGeometry } from './cast/closestPointToGeometry.generated.js';\n\nimport { iterateOverTriangles_indirect } from './utils/iterationUtils_indirect.generated.js';\nimport { refit_indirect } from './cast/refit_indirect.generated.js';\nimport { raycast_indirect } from './cast/raycast_indirect.generated.js';\nimport { raycastFirst_indirect } from './cast/raycastFirst_indirect.generated.js';\nimport { intersectsGeometry_indirect } from './cast/intersectsGeometry_indirect.generated.js';\nimport { closestPointToGeometry_indirect } from './cast/closestPointToGeometry_indirect.generated.js';\nimport { setTriangle } from '../utils/TriangleUtilities.js';\nimport { convertRaycastIntersect } from '../utils/GeometryRayIntersectUtilities.js';\nimport { GeometryBVH } from './GeometryBVH.js';\n\nconst _obb = /* @__PURE__ */ new OrientedBox();\nconst _ray = /* @__PURE__ */ new Ray();\nconst _direction = /* @__PURE__ */ new Vector3();\nconst _inverseMatrix = /* @__PURE__ */ new Matrix4();\nconst _worldScale = /* @__PURE__ */ new Vector3();\nconst _getters = [ 'getX', 'getY', 'getZ' ];\n\n/**\n * @callback IntersectsTriangleCallback\n * @param {ExtendedTriangle} triangle - The triangle primitive in local space.\n * @param {number} triangleIndex - The index of the triangle in the geometry.\n * @param {boolean} contained - Whether the node bounds are fully contained by the query shape.\n * @param {number} depth - The depth of the node in the tree.\n * @returns {boolean} Return `true` to stop traversal.\n */\n\n/**\n * @callback IntersectsTrianglesCallback\n * @param {ExtendedTriangle} triangle1 - Triangle from this BVH in local space.\n * @param {ExtendedTriangle} triangle2 - Triangle from `otherBvh`, transformed into local space.\n * @param {number} triangleIndex1 - Triangle index in the first geometry.\n * @param {number} triangleIndex2 - Triangle index in the second geometry.\n * @param {number} depth1 - Depth of the node in the first BVH.\n * @param {number} nodeIndex1 - Node index in the first BVH.\n * @param {number} depth2 - Depth of the node in the second BVH.\n * @param {number} nodeIndex2 - Node index in the second BVH.\n * @returns {boolean} Return `true` to stop traversal.\n */\n\n/**\n * Plain-object representation of a `MeshBVH` produced by `MeshBVH.serialize` and\n * consumed by `MeshBVH.deserialize`. Suitable for transfer across WebWorker boundaries\n * or storage, with optional buffer sharing via `SharedArrayBuffer`.\n *\n * @typedef {Object} SerializedBVH\n * @property {Array<ArrayBuffer>} roots - BVH root node buffers.\n * @property {Int32Array|Uint32Array|Uint16Array|null} index - Serialized geometry index buffer.\n * @property {Uint32Array|Uint16Array|null} indirectBuffer - Indirect primitive index buffer, or `null`\n * if the BVH was not built in indirect mode.\n */\n\n/**\n * @typedef {Object} HitPointInfo\n * @property {Vector3} point - The closest point on the mesh surface.\n * @property {number} distance - Distance from the query point to the closest point.\n * @property {number} faceIndex - Index of the triangle containing the closest point. Can be\n * passed to `getTriangleHitPointInfo` to retrieve UV, normal, and material index.\n */\n\n/**\n * The MeshBVH generation process modifies the geometry's index bufferAttribute in place to save\n * memory. The BVH construction will use the geometry's boundingBox if it exists or set it if it\n * does not. The BVH will no longer work correctly if the index buffer is modified.\n *\n * Only triangles within the geometry's draw range (or provided `range` option) are included in the\n * BVH. When a geometry has multiple groups, only triangles within the defined group ranges are\n * included. Triangles in gaps between groups are excluded.\n *\n * Note that all query functions expect arguments in local space of the BVH and return results in\n * local space, as well. If world space results are needed they must be transformed into world space\n * using `object.matrixWorld`.\n *\n * @param {BufferGeometry} geometry\n * @param {Object} [options] - Same options as {@link GeometryBVH}.\n * @extends GeometryBVH\n */\nexport class MeshBVH extends GeometryBVH {\n\n\t/**\n\t * Generates a representation of the complete bounds tree and the geometry index buffer which\n\t * can be used to recreate a bounds tree using the `deserialize` function. The `serialize` and\n\t * `deserialize` functions can be used to generate a MeshBVH asynchronously in a background web\n\t * worker to prevent the main thread from stuttering. The BVH roots buffer stored in the\n\t * serialized representation are the same as the ones used by the original BVH so they should\n\t * not be modified. If `SharedArrayBuffers` are used then the same BVH memory can be used for\n\t * multiple BVH in multiple WebWorkers.\n\t *\n\t * @static\n\t * @param {MeshBVH} bvh - The BVH to serialize.\n\t * @param {Object} [options]\n\t * @param {boolean} [options.cloneBuffers=true] - If `true`, the index and BVH root buffers\n\t * are cloned so the serialized data is independent of the live BVH.\n\t * @returns {SerializedBVH}\n\t */\n\tstatic serialize( bvh, options = {} ) {\n\n\t\toptions = {\n\t\t\tcloneBuffers: true,\n\t\t\t...options,\n\t\t};\n\n\t\tconst geometry = bvh.geometry;\n\t\tconst rootData = bvh._roots;\n\t\tconst indirectBuffer = bvh._indirectBuffer;\n\t\tconst indexAttribute = geometry.getIndex();\n\t\tconst result = {\n\t\t\tversion: 1,\n\t\t\troots: null,\n\t\t\tindex: null,\n\t\t\tindirectBuffer: null,\n\t\t};\n\t\tif ( options.cloneBuffers ) {\n\n\t\t\tresult.roots = rootData.map( root => root.slice() );\n\t\t\tresult.index = indexAttribute ? indexAttribute.array.slice() : null;\n\t\t\tresult.indirectBuffer = indirectBuffer ? indirectBuffer.slice() : null;\n\n\t\t} else {\n\n\t\t\tresult.roots = rootData;\n\t\t\tresult.index = indexAttribute ? indexAttribute.array : null;\n\t\t\tresult.indirectBuffer = indirectBuffer;\n\n\t\t}\n\n\t\treturn result;\n\n\t}\n\n\t/**\n\t * Returns a new MeshBVH instance from the serialized data. `geometry` is the geometry used\n\t * to generate the original BVH `data` was derived from. The root buffers stored in `data`\n\t * are set directly on the new BVH so the memory is shared.\n\t *\n\t * @static\n\t * @param {SerializedBVH} data - Serialized BVH data.\n\t * @param {BufferGeometry} geometry - The geometry the BVH was originally built from.\n\t * @param {Object} [options]\n\t * @param {boolean} [options.setIndex=true] - If `true`, sets `geometry.index` from the\n\t * serialized index buffer (creating one if none exists).\n\t * @returns {MeshBVH}\n\t */\n\tstatic deserialize( data, geometry, options = {} ) {\n\n\t\toptions = {\n\t\t\tsetIndex: true,\n\t\t\tindirect: Boolean( data.indirectBuffer ),\n\t\t\t...options,\n\t\t};\n\n\t\tconst { index, roots, indirectBuffer } = data;\n\n\t\t// handle backwards compatibility by fixing up the buffer roots\n\t\t// see issue gkjohnson/three-mesh-bvh#759\n\t\tif ( ! data.version ) {\n\n\t\t\tconsole.warn(\n\t\t\t\t'MeshBVH.deserialize: Serialization format has been changed and will be fixed up. ' +\n\t\t\t\t'It is recommended to regenerate any stored serialized data.'\n\t\t\t);\n\t\t\tfixupVersion0( roots );\n\n\t\t}\n\n\t\tconst bvh = new MeshBVH( geometry, { ...options, [ SKIP_GENERATION ]: true } );\n\t\tbvh._roots = roots;\n\t\tbvh._indirectBuffer = indirectBuffer || null;\n\n\t\tif ( options.setIndex ) {\n\n\t\t\tconst indexAttribute = geometry.getIndex();\n\t\t\tif ( indexAttribute === null ) {\n\n\t\t\t\tconst newIndex = new BufferAttribute( data.index, 1, false );\n\t\t\t\tgeometry.setIndex( newIndex );\n\n\t\t\t} else if ( indexAttribute.array !== index ) {\n\n\t\t\t\tindexAttribute.array.set( index );\n\t\t\t\tindexAttribute.needsUpdate = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn bvh;\n\n\t\t// convert version 0 serialized data (uint32 indices) to version 1 (node indices)\n\t\tfunction fixupVersion0( roots ) {\n\n\t\t\tfor ( let rootIndex = 0; rootIndex < roots.length; rootIndex ++ ) {\n\n\t\t\t\tconst root = roots[ rootIndex ];\n\t\t\t\tconst uint32Array = new Uint32Array( root );\n\t\t\t\tconst uint16Array = new Uint16Array( root );\n\n\t\t\t\t// iterate over nodes and convert right child offsets\n\t\t\t\tfor ( let node = 0, l = root.byteLength / BYTES_PER_NODE; node < l; node ++ ) {\n\n\t\t\t\t\tconst node32Index = UINT32_PER_NODE * node;\n\t\t\t\t\tconst node16Index = 2 * node32Index;\n\t\t\t\t\tif ( ! IS_LEAF( node16Index, uint16Array ) ) {\n\n\t\t\t\t\t\t// convert absolute right child offset to relative offset\n\t\t\t\t\t\tuint32Array[ node32Index + 6 ] = uint32Array[ node32Index + 6 ] / UINT32_PER_NODE - node;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tget primitiveStride() {\n\n\t\treturn 3;\n\n\t}\n\n\t/**\n\t * Helper function for use when `indirect` is set to true. This function takes a triangle\n\t * index in the BVH layout and returns the associated triangle index in the geometry index\n\t * buffer or position attribute.\n\t * @type {function(number): number}\n\t * @readonly\n\t */\n\tget resolveTriangleIndex() {\n\n\t\treturn this.resolvePrimitiveIndex;\n\n\t}\n\n\tconstructor( geometry, options = {} ) {\n\n\t\tif ( options.maxLeafTris ) {\n\n\t\t\tconsole.warn( 'MeshBVH: \"maxLeafTris\" option has been deprecated. Use \"targetLeafSize\", instead.' );\n\t\t\toptions = {\n\t\t\t\t...options,\n\t\t\t\ttargetLeafSize: options.maxLeafTris,\n\t\t\t};\n\n\t\t}\n\n\t\tsuper( geometry, options );\n\n\t}\n\n\t/**\n\t * Adjusts all triangle offsets stored in the BVH by the given offset. This is useful when the\n\t * triangle data has been compacted or shifted in the geometry buffers (e.g. in `BatchedMesh`\n\t * when geometries are compacted using the 'optimize' function or constructing a 'merged' BVH).\n\t * This function only adjusts the BVH to point to different triangles in the geometry. The\n\t * geometry's index buffer and/or position attributes must be updated separately to match.\n\t *\n\t * @param {number} offset\n\t * @returns {void}\n\t */\n\t// implement abstract methods from BVH base class\n\tshiftTriangleOffsets( offset ) {\n\n\t\treturn super.shiftPrimitiveOffsets( offset );\n\n\t}\n\n\t// write primitive bounds to the buffer - used only for validateBounds at the moment\n\twritePrimitiveBounds( i, targetBuffer, baseIndex ) {\n\n\t\tconst geometry = this.geometry;\n\t\tconst indirectBuffer = this._indirectBuffer;\n\t\tconst posAttr = geometry.attributes.position;\n\t\tconst index = geometry.index ? geometry.index.array : null;\n\n\t\tconst tri = indirectBuffer ? indirectBuffer[ i ] : i;\n\t\tconst tri3 = tri * 3;\n\n\t\tlet ai = tri3 + 0;\n\t\tlet bi = tri3 + 1;\n\t\tlet ci = tri3 + 2;\n\n\t\tif ( index ) {\n\n\t\t\tai = index[ ai ];\n\t\t\tbi = index[ bi ];\n\t\t\tci = index[ ci ];\n\n\t\t}\n\n\t\tfor ( let el = 0; el < 3; el ++ ) {\n\n\t\t\tconst a = posAttr[ _getters[ el ] ]( ai );\n\t\t\tconst b = posAttr[ _getters[ el ] ]( bi );\n\t\t\tconst c = posAttr[ _getters[ el ] ]( ci );\n\n\t\t\tlet min = a;\n\t\t\tif ( b < min ) min = b;\n\t\t\tif ( c < min ) min = c;\n\n\t\t\tlet max = a;\n\t\t\tif ( b > max ) max = b;\n\t\t\tif ( c > max ) max = c;\n\n\t\t\t// Write in min/max format [minx, miny, minz, maxx, maxy, maxz]\n\t\t\ttargetBuffer[ baseIndex + el ] = min;\n\t\t\ttargetBuffer[ baseIndex + el + 3 ] = max;\n\n\t\t}\n\n\t\treturn targetBuffer;\n\n\t}\n\n\t// precomputes the bounding box for each triangle; required for quickly calculating tree splits.\n\t// result is an array of size count * 6 where triangle i maps to a\n\t// [x_center, x_delta, y_center, y_delta, z_center, z_delta] tuple starting at index (i - offset) * 6,\n\t// representing the center and half-extent in each dimension of triangle i\n\tcomputePrimitiveBounds( offset, count, targetBuffer ) {\n\n\t\tconst geometry = this.geometry;\n\t\tconst indirectBuffer = this._indirectBuffer;\n\t\tconst posAttr = geometry.attributes.position;\n\t\tconst index = geometry.index ? geometry.index.array : null;\n\t\tconst normalized = posAttr.normalized;\n\n\t\tif ( offset < 0 || count + offset - targetBuffer.offset > targetBuffer.length / 6 ) {\n\n\t\t\tthrow new Error( 'MeshBVH: compute triangle bounds range is invalid.' );\n\n\t\t}\n\n\t\t// used for non-normalized positions\n\t\tconst posArr = posAttr.array;\n\n\t\t// support for an interleaved position buffer\n\t\tconst bufferOffset = posAttr.offset || 0;\n\t\tlet stride = 3;\n\t\tif ( posAttr.isInterleavedBufferAttribute ) {\n\n\t\t\tstride = posAttr.data.stride;\n\n\t\t}\n\n\t\t// used for normalized positions\n\t\tconst getters = [ 'getX', 'getY', 'getZ' ];\n\t\tconst writeOffset = targetBuffer.offset;\n\n\t\t// iterate over the triangle range\n\t\tfor ( let i = offset, l = offset + count; i < l; i ++ ) {\n\n\t\t\tconst tri = indirectBuffer ? indirectBuffer[ i ] : i;\n\t\t\tconst tri3 = tri * 3;\n\t\t\tconst boundsIndexOffset = ( i - writeOffset ) * 6;\n\n\t\t\tlet ai = tri3 + 0;\n\t\t\tlet bi = tri3 + 1;\n\t\t\tlet ci = tri3 + 2;\n\n\t\t\tif ( index ) {\n\n\t\t\t\tai = index[ ai ];\n\t\t\t\tbi = index[ bi ];\n\t\t\t\tci = index[ ci ];\n\n\t\t\t}\n\n\t\t\t// we add the stride and offset here since we access the array directly\n\t\t\t// below for the sake of performance\n\t\t\tif ( ! normalized ) {\n\n\t\t\t\tai = ai * stride + bufferOffset;\n\t\t\t\tbi = bi * stride + bufferOffset;\n\t\t\t\tci = ci * stride + bufferOffset;\n\n\t\t\t}\n\n\t\t\tfor ( let el = 0; el < 3; el ++ ) {\n\n\t\t\t\tlet a, b, c;\n\n\t\t\t\tif ( normalized ) {\n\n\t\t\t\t\ta = posAttr[ getters[ el ] ]( ai );\n\t\t\t\t\tb = posAttr[ getters[ el ] ]( bi );\n\t\t\t\t\tc = posAttr[ getters[ el ] ]( ci );\n\n\t\t\t\t} else {\n\n\t\t\t\t\ta = posArr[ ai + el ];\n\t\t\t\t\tb = posArr[ bi + el ];\n\t\t\t\t\tc = posArr[ ci + el ];\n\n\t\t\t\t}\n\n\t\t\t\tlet min = a;\n\t\t\t\tif ( b < min ) min = b;\n\t\t\t\tif ( c < min ) min = c;\n\n\t\t\t\tlet max = a;\n\t\t\t\tif ( b > max ) max = b;\n\t\t\t\tif ( c > max ) max = c;\n\n\t\t\t\t// Increase the bounds size by float32 epsilon to avoid precision errors when\n\t\t\t\t// converting to 32 bit float. Scale the epsilon by the size of the numbers being\n\t\t\t\t// worked with.\n\t\t\t\tconst halfExtents = ( max - min ) / 2;\n\t\t\t\tconst el2 = el * 2;\n\t\t\t\ttargetBuffer[ boundsIndexOffset + el2 + 0 ] = min + halfExtents;\n\t\t\t\ttargetBuffer[ boundsIndexOffset + el2 + 1 ] = halfExtents + ( Math.abs( min ) + halfExtents ) * FLOAT32_EPSILON;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn targetBuffer;\n\n\t}\n\n\t/**\n\t * A convenience function for performing a raycast based on a mesh. Results are formed like\n\t * three.js raycast results in world frame.\n\t *\n\t * @param {Object3D} object\n\t * @param {Raycaster} raycaster\n\t * @param {Array<Intersection>} [intersects=[]]\n\t * @returns {Array<Intersection>}\n\t */\n\traycastObject3D( object, raycaster, intersects = [] ) {\n\n\t\tconst { material } = object;\n\t\tif ( material === undefined ) {\n\n\t\t\treturn;\n\n\t\t}\n\n\t\t_inverseMatrix.copy( object.matrixWorld ).invert();\n\t\t_ray.copy( raycaster.ray ).applyMatrix4( _inverseMatrix );\n\n\t\t_worldScale.setFromMatrixScale( object.matrixWorld );\n\t\t_direction.copy( _ray.direction ).multiply( _worldScale );\n\n\t\tconst scaleFactor = _direction.length();\n\t\tconst near = raycaster.near / scaleFactor;\n\t\tconst far = raycaster.far / scaleFactor;\n\n\t\tif ( raycaster.firstHitOnly === true ) {\n\n\t\t\tlet hit = this.raycastFirst( _ray, material, near, far );\n\t\t\thit = convertRaycastIntersect( hit, object, raycaster );\n\t\t\tif ( hit ) {\n\n\t\t\t\tintersects.push( hit );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tconst hits = this.raycast( _ray, material, near, far );\n\t\t\tfor ( let i = 0, l = hits.length; i < l; i ++ ) {\n\n\t\t\t\tconst hit = convertRaycastIntersect( hits[ i ], object, raycaster );\n\t\t\t\tif ( hit ) {\n\n\t\t\t\t\tintersects.push( hit );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn intersects;\n\n\t}\n\n\t/**\n\t * Refit the node bounds to the current triangle positions. This is quicker than regenerating\n\t * a new BVH but will not be optimal after significant changes to the vertices. `nodeIndices`\n\t * is a set of node indices (provided by the `shapecast` function) that need to be refit\n\t * including all internal nodes.\n\t *\n\t * @param {Set<number>|Array<number>|null} [nodeIndices=null]\n\t */\n\trefit( nodeIndices = null ) {\n\n\t\tconst refitFunc = this.indirect ? refit_indirect : refit;\n\t\treturn refitFunc( this, nodeIndices );\n\n\t}\n\n\t/* Core Cast Functions */\n\n\t/**\n\t * Returns all raycast triangle hits in unsorted order. It is expected that `ray` is in the\n\t * frame of the BVH already. Likewise the returned results are also provided in the local\n\t * frame of the BVH. The `side` identifier is used to determine the side to check when\n\t * raycasting or a material with the given side field can be passed. If an array of materials\n\t * is provided then it is expected that the geometry has groups and the appropriate material\n\t * side is used per group.\n\t *\n\t * Note that unlike three.js' Raycaster results the points and distances in the intersections\n\t * returned from this function are relative to the local frame of the MeshBVH. When using the\n\t * `acceleratedRaycast` function as an override for `Mesh.raycast` they are transformed into\n\t * world space to be consistent with three's results.\n\t *\n\t * @param {Ray} ray\n\t * @param {number|Material|Array<Material>} [materialOrSide=FrontSide]\n\t * @param {number} [near=0]\n\t * @param {number} [far=Infinity]\n\t * @returns {Array<Intersection>}\n\t */\n\traycast( ray, materialOrSide = FrontSide, near = 0, far = Infinity ) {\n\n\t\tconst roots = this._roots;\n\t\tconst intersects = [];\n\t\tconst raycastFunc = this.indirect ? raycast_indirect : raycast;\n\t\tfor ( let i = 0, l = roots.length; i < l; i ++ ) {\n\n\t\t\traycastFunc( this, i, materialOrSide, ray, intersects, near, far );\n\n\t\t}\n\n\t\treturn intersects;\n\n\t}\n\n\t/**\n\t * Returns the first raycast hit in the model. This is typically much faster than returning\n\t * all hits. See `raycast` for information on the side and material options as well as the\n\t * frame of the returned intersections.\n\t *\n\t * @param {Ray} ray\n\t * @param {number|Material|Array<Material>} [materialOrSide=FrontSide]\n\t * @param {number} [near=0]\n\t * @param {number} [far=Infinity]\n\t * @returns {Intersection|null}\n\t */\n\traycastFirst( ray, materialOrSide = FrontSide, near = 0, far = Infinity ) {\n\n\t\tconst roots = this._roots;\n\t\tlet closestResult = null;\n\n\t\tconst raycastFirstFunc = this.indirect ? raycastFirst_indirect : raycastFirst;\n\t\tfor ( let i = 0, l = roots.length; i < l; i ++ ) {\n\n\t\t\tconst result = raycastFirstFunc( this, i, materialOrSide, ray, near, far );\n\t\t\tif ( result != null && ( closestResult == null || result.distance < closestResult.distance ) ) {\n\n\t\t\t\tclosestResult = result;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn closestResult;\n\n\t}\n\n\t/**\n\t * Returns whether or not the mesh intersects the given geometry.\n\t *\n\t * The `geometryToBvh` parameter is the transform of the geometry in the BVH's local frame.\n\t *\n\t * Performance improves considerably if the provided geometry also has a `boundsTree`.\n\t *\n\t * @param {BufferGeometry} otherGeometry\n\t * @param {Matrix4} geometryToBvh - Transform of `otherGeometry` into the local space of\n\t * this BVH.\n\t * @returns {boolean}\n\t */\n\tintersectsGeometry( otherGeometry, geomToMesh ) {\n\n\t\tlet result = false;\n\t\tconst roots = this._roots;\n\t\tconst intersectsGeometryFunc = this.indirect ? intersectsGeometry_indirect : intersectsGeometry;\n\t\tfor ( let i = 0, l = roots.length; i < l; i ++ ) {\n\n\t\t\tresult = intersectsGeometryFunc( this, i, otherGeometry, geomToMesh );\n\n\t\t\tif ( result ) {\n\n\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn result;\n\n\t}\n\n\t/**\n\t * A generalized cast function that can be used to implement intersection logic for custom\n\t * shapes. This is used internally for `intersectsBox`, `intersectsSphere`, and more. The\n\t * function returns as soon as a triangle has been reported as intersected and returns `true`\n\t * if a triangle has been intersected.\n\t *\n\t * @param {Object} callbacks\n\t * @param {IntersectsBoundsCallback} callbacks.intersectsBounds\n\t * @param {IntersectsTriangleCallback} [callbacks.intersectsTriangle]\n\t * @param {IntersectsRangeCallback} [callbacks.intersectsRange]\n\t * @param {BoundsTraverseOrderCallback} [callbacks.boundsTraverseOrder]\n\t * @returns {boolean}\n\t */\n\tshapecast( callbacks ) {\n\n\t\tconst triangle = ExtendedTrianglePool.getPrimitive();\n\t\tconst result = super.shapecast(\n\t\t\t{\n\t\t\t\t...callbacks,\n\t\t\t\tintersectsPrimitive: callbacks.intersectsTriangle,\n\t\t\t\tscratchPrimitive: triangle,\n\n\t\t\t\t// TODO: is the performance significant enough for the added complexity here?\n\t\t\t\t// can we just use one function?\n\t\t\t\titerate: this.indirect ? iterateOverTriangles_indirect : iterateOverTriangles,\n\t\t\t}\n\t\t);\n\t\tExtendedTrianglePool.releasePrimitive( triangle );\n\n\t\treturn result;\n\n\t}\n\n\t/**\n\t * A generalized cast function that traverses two BVH structures simultaneously to perform\n\t * intersection tests between them. This is used internally by `intersectsGeometry`. The\n\t * function returns `true` as soon as a triangle pair has been reported as intersected by\n\t * the callbacks.\n\t *\n\t * `matrixToLocal` is a Matrix4 that transforms `otherBvh` into the local space of this BVH.\n\t * The other BVH's triangles are transformed by this matrix before intersection tests.\n\t *\n\t * @param {MeshBVH} otherBvh\n\t * @param {Matrix4} matrixToLocal - Transforms `otherBvh` into the local space of this BVH.\n\t * @param {Object} callbacks\n\t * @param {IntersectsRangesCallback} [callbacks.intersectsRanges]\n\t * @param {IntersectsTrianglesCallback} [callbacks.intersectsTriangles]\n\t * @returns {boolean}\n\t */\n\tbvhcast( otherBvh, matrixToLocal, callbacks ) {\n\n\t\tlet {\n\t\t\tintersectsRanges,\n\t\t\tintersectsTriangles,\n\t\t} = callbacks;\n\n\t\tconst triangle1 = ExtendedTrianglePool.getPrimitive();\n\t\tconst indexAttr1 = this.geometry.index;\n\t\tconst positionAttr1 = this.geometry.attributes.position;\n\t\tconst assignTriangle1 = this.indirect ?\n\t\t\ti1 => {\n\n\n\t\t\t\tconst ti = this.resolveTriangleIndex( i1 );\n\t\t\t\tsetTriangle( triangle1, ti * 3, indexAttr1, positionAttr1 );\n\n\t\t\t} :\n\t\t\ti1 => {\n\n\t\t\t\tsetTriangle( triangle1, i1 * 3, indexAttr1, positionAttr1 );\n\n\t\t\t};\n\n\t\tconst triangle2 = ExtendedTrianglePool.getPrimitive();\n\t\tconst indexAttr2 = otherBvh.geometry.index;\n\t\tconst positionAttr2 = otherBvh.geometry.attributes.position;\n\t\tconst assignTriangle2 = otherBvh.indirect ?\n\t\t\ti2 => {\n\n\t\t\t\tconst ti2 = otherBvh.resolveTriangleIndex( i2 );\n\t\t\t\tsetTriangle( triangle2, ti2 * 3, indexAttr2, positionAttr2 );\n\n\t\t\t} :\n\t\t\ti2 => {\n\n\t\t\t\tsetTriangle( triangle2, i2 * 3, indexAttr2, positionAttr2 );\n\n\t\t\t};\n\n\t\t// generate triangle callback if needed\n\t\tif ( intersectsTriangles ) {\n\n\t\t\tif ( ! ( otherBvh instanceof MeshBVH ) ) {\n\n\t\t\t\tthrow new Error( 'MeshBVH: \"intersectsTriangles\" callback can only be used with another MeshBVH.' );\n\n\t\t\t}\n\n\t\t\tconst iterateOverDoubleTriangles = ( offset1, count1, offset2, count2, depth1, nodeIndex1, depth2, nodeIndex2 ) => {\n\n\t\t\t\tfor ( let i2 = offset2, l2 = offset2 + count2; i2 < l2; i2 ++ ) {\n\n\t\t\t\t\tassignTriangle2( i2 );\n\n\t\t\t\t\ttriangle2.a.applyMatrix4( matrixToLocal );\n\t\t\t\t\ttriangle2.b.applyMatrix4( matrixToLocal );\n\t\t\t\t\ttriangle2.c.applyMatrix4( matrixToLocal );\n\t\t\t\t\ttriangle2.needsUpdate = true;\n\n\t\t\t\t\tfor ( let i1 = offset1, l1 = offset1 + count1; i1 < l1; i1 ++ ) {\n\n\t\t\t\t\t\tassignTriangle1( i1 );\n\n\t\t\t\t\t\ttriangle1.needsUpdate = true;\n\n\t\t\t\t\t\tif ( intersectsTriangles( triangle1, triangle2, i1, i2, depth1, nodeIndex1, depth2, nodeIndex2 ) ) {\n\n\t\t\t\t\t\t\treturn true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\n\t\t\t};\n\n\t\t\tif ( intersectsRanges ) {\n\n\t\t\t\tconst originalIntersectsRanges = intersectsRanges;\n\t\t\t\tintersectsRanges = function ( offset1, count1, offset2, count2, depth1, nodeIndex1, depth2, nodeIndex2 ) {\n\n\t\t\t\t\tif ( ! originalIntersectsRanges( offset1, count1, offset2, count2, depth1, nodeIndex1, depth2, nodeIndex2 ) ) {\n\n\t\t\t\t\t\treturn iterateOverDoubleTriangles( offset1, count1, offset2, count2, depth1, nodeIndex1, depth2, nodeIndex2 );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t};\n\n\t\t\t} else {\n\n\t\t\t\tintersectsRanges = iterateOverDoubleTriangles;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn super.bvhcast( otherBvh, matrixToLocal, { intersectsRanges } );\n\n\t}\n\n\n\t/* Derived Cast Functions */\n\n\t/**\n\t * Returns whether or not the mesh intersects the given box.\n\t *\n\t * The `boxToBvh` parameter is the transform of the box in the meshes frame.\n\t *\n\t * @param {Box3} box\n\t * @param {Matrix4} boxToBvh - Transform of the box in the local space of this BVH.\n\t * @returns {boolean}\n\t */\n\tintersectsBox( box, boxToMesh ) {\n\n\t\t_obb.set( box.min, box.max, boxToMesh );\n\t\t_obb.needsUpdate = true;\n\n\t\treturn this.shapecast(\n\t\t\t{\n\t\t\t\tintersectsBounds: box => _obb.intersectsBox( box ),\n\t\t\t\tintersectsTriangle: tri => _obb.intersectsTriangle( tri )\n\t\t\t}\n\t\t);\n\n\t}\n\n\t/**\n\t * Returns whether or not the mesh intersects the given sphere.\n\t *\n\t * @param {Sphere} sphere\n\t * @returns {boolean}\n\t */\n\tintersectsSphere( sphere ) {\n\n\t\treturn this.shapecast(\n\t\t\t{\n\t\t\t\tintersectsBounds: box => sphere.intersectsBox( box ),\n\t\t\t\tintersectsTriangle: tri => tri.intersectsSphere( sphere )\n\t\t\t}\n\t\t);\n\n\t}\n\n\t/**\n\t * Computes the closest distance from the geometry to the mesh and puts the closest point on\n\t * the mesh in `target1` (in the frame of the BVH) and the closest point on the other\n\t * geometry in `target2` (in the geometry frame). If `target1` is not provided a new Object\n\t * is created and returned from the function.\n\t *\n\t * The `geometryToBvh` parameter is the transform of the geometry in the BVH's local frame.\n\t *\n\t * If a point is found that is closer than `minThreshold` then the function will return that\n\t * result early. Any triangles or points outside of `maxThreshold` are ignored. If no point\n\t * is found within the min / max thresholds then `null` is returned and the target objects\n\t * are not modified.\n\t *\n\t * The returned faceIndex in `target1` and `target2` can be used with the standalone function\n\t * `getTriangleHitPointInfo` to obtain more information like UV coordinates, triangle normal\n\t * and materialIndex.\n\t *\n\t * _Note that this function can be very slow if `geometry` does not have a\n\t * `geometry.boundsTree` computed._\n\t *\n\t * @param {BufferGeometry} otherGeometry\n\t * @param {Matrix4} geometryToBvh - Transform of `otherGeometry` into the local space of\n\t * this BVH.\n\t * @param {HitPointInfo} [target1={}]\n\t * @param {HitPointInfo} [target2={}]\n\t * @param {number} [minThreshold=0]\n\t * @param {number} [maxThreshold=Infinity]\n\t * @returns {HitPointInfo|null}\n\t */\n\tclosestPointToGeometry( otherGeometry, geometryToBvh, target1 = { }, target2 = { }, minThreshold = 0, maxThreshold = Infinity ) {\n\n\t\tconst closestPointToGeometryFunc = this.indirect ? closestPointToGeometry_indirect : closestPointToGeometry;\n\t\treturn closestPointToGeometryFunc(\n\t\t\tthis,\n\t\t\totherGeometry,\n\t\t\tgeometryToBvh,\n\t\t\ttarget1,\n\t\t\ttarget2,\n\t\t\tminThreshold,\n\t\t\tmaxThreshold,\n\t\t);\n\n\t}\n\n\t/**\n\t * Computes the closest distance from the point to the mesh and gives additional information\n\t * in `target`. The target can be left undefined to default to a new object which is\n\t * ultimately returned by the function.\n\t *\n\t * If a point is found that is closer than `minThreshold` then the function will return that\n\t * result early. Any triangles or points outside of `maxThreshold` are ignored. If no point\n\t * is found within the min / max thresholds then `null` is returned and the `target` object\n\t * is not modified.\n\t *\n\t * The returned faceIndex can be used with the standalone function `getTriangleHitPointInfo`\n\t * to obtain more information like UV coordinates, triangle normal and materialIndex.\n\t *\n\t * @param {Vector3} point\n\t * @param {HitPointInfo} [target={}]\n\t * @param {number} [minThreshold=0]\n\t * @param {number} [maxThreshold=Infinity]\n\t * @returns {HitPointInfo|null}\n\t */\n\tclosestPointToPoint( point, target = { }, minThreshold = 0, maxThreshold = Infinity ) {\n\n\t\treturn closestPointToPoint(\n\t\t\tthis,\n\t\t\tpoint,\n\t\t\ttarget,\n\t\t\tminThreshold,\n\t\t\tmaxThreshold,\n\t\t);\n\n\t}\n\n}\n","/** @import { BufferAttribute } from 'three' */\nimport {\n\tDataTexture,\n\tFloatType,\n\tIntType,\n\tUnsignedIntType,\n\tByteType,\n\tUnsignedByteType,\n\tShortType,\n\tUnsignedShortType,\n\n\tRedFormat,\n\tRGFormat,\n\tRGBAFormat,\n\n\tRedIntegerFormat,\n\tRGIntegerFormat,\n\tRGBAIntegerFormat,\n\n\tNearestFilter,\n} from 'three';\n\nfunction countToStringFormat( count ) {\n\n\tswitch ( count ) {\n\n\t\tcase 1: return 'R';\n\t\tcase 2: return 'RG';\n\t\tcase 3: return 'RGBA';\n\t\tcase 4: return 'RGBA';\n\n\t}\n\n\tthrow new Error();\n\n}\n\nfunction countToFormat( count ) {\n\n\tswitch ( count ) {\n\n\t\tcase 1: return RedFormat;\n\t\tcase 2: return RGFormat;\n\t\tcase 3: return RGBAFormat;\n\t\tcase 4: return RGBAFormat;\n\n\t}\n\n}\n\nfunction countToIntFormat( count ) {\n\n\tswitch ( count ) {\n\n\t\tcase 1: return RedIntegerFormat;\n\t\tcase 2: return RGIntegerFormat;\n\t\tcase 3: return RGBAIntegerFormat;\n\t\tcase 4: return RGBAIntegerFormat;\n\n\t}\n\n}\n\n/**\n * Float, Uint, and Int VertexAttributeTexture implementations are designed to simplify the\n * efficient packing of a three.js BufferAttribute into a texture. An instance can be treated as a\n * texture and when passing as a uniform to a shader they should be used as a `sampler2d`,\n * `usampler2d`, and `isampler2d` when using the Float, Uint, and Int texture types respectively.\n *\n * _extends THREE.DataTexture_\n *\n * @section Shader and Texture Packing API\n */\nexport class VertexAttributeTexture extends DataTexture {\n\n\tconstructor() {\n\n\t\tsuper();\n\t\tthis.minFilter = NearestFilter;\n\t\tthis.magFilter = NearestFilter;\n\t\tthis.generateMipmaps = false;\n\n\t\t/**\n\t\t * Treats `BufferAttribute.itemSize` as though it were set to this value when packing the\n\t\t * buffer attribute texture. Throws an error if the value does not divide evenly into the\n\t\t * length of the BufferAttribute buffer (`count * itemSize % overrideItemSize`).\n\t\t *\n\t\t * Specifically used to pack geometry indices into an RGB texture rather than an Red texture.\n\t\t * @type {number}\n\t\t */\n\t\tthis.overrideItemSize = null;\n\t\tthis._forcedType = null;\n\n\t}\n\n\t/**\n\t * Updates the texture to have the data contained in the passed BufferAttribute using the\n\t * BufferAttribute `itemSize` field, `normalized` field, and TypedArray layout to determine\n\t * the appropriate texture layout, format, and type. The texture dimensions will always be\n\t * square. Because these are intended to be sampled as 1D arrays the width of the texture must\n\t * be taken into account to derive a sampling uv. See `texelFetch1D` in shaderFunctions.\n\t *\n\t * @param {BufferAttribute} attribute\n\t * @returns {void}\n\t */\n\tupdateFrom( attr ) {\n\n\t\tconst overrideItemSize = this.overrideItemSize;\n\t\tconst originalItemSize = attr.itemSize;\n\t\tconst originalCount = attr.count;\n\t\tif ( overrideItemSize !== null ) {\n\n\t\t\tif ( ( originalItemSize * originalCount ) % overrideItemSize !== 0.0 ) {\n\n\t\t\t\tthrow new Error( 'VertexAttributeTexture: overrideItemSize must divide evenly into buffer length.' );\n\n\t\t\t}\n\n\t\t\tattr.itemSize = overrideItemSize;\n\t\t\tattr.count = originalCount * originalItemSize / overrideItemSize;\n\n\t\t}\n\n\t\tconst itemSize = attr.itemSize;\n\t\tconst count = attr.count;\n\t\tconst normalized = attr.normalized;\n\t\tconst originalBufferCons = attr.array.constructor;\n\t\tconst byteCount = originalBufferCons.BYTES_PER_ELEMENT;\n\t\tlet targetType = this._forcedType;\n\t\tlet finalStride = itemSize;\n\n\t\t// derive the type of texture this should be in the shader\n\t\tif ( targetType === null ) {\n\n\t\t\tswitch ( originalBufferCons ) {\n\n\t\t\t\tcase Float32Array:\n\t\t\t\t\ttargetType = FloatType;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase Uint8Array:\n\t\t\t\tcase Uint16Array:\n\t\t\t\tcase Uint32Array:\n\t\t\t\t\ttargetType = UnsignedIntType;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase Int8Array:\n\t\t\t\tcase Int16Array:\n\t\t\t\tcase Int32Array:\n\t\t\t\t\ttargetType = IntType;\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// get the target format to store the texture as\n\t\tlet type, format, normalizeValue, targetBufferCons;\n\t\tlet internalFormat = countToStringFormat( itemSize );\n\t\tswitch ( targetType ) {\n\n\t\t\tcase FloatType:\n\t\t\t\tnormalizeValue = 1.0;\n\t\t\t\tformat = countToFormat( itemSize );\n\n\t\t\t\tif ( normalized && byteCount === 1 ) {\n\n\t\t\t\t\ttargetBufferCons = originalBufferCons;\n\t\t\t\t\tinternalFormat += '8';\n\n\t\t\t\t\tif ( originalBufferCons === Uint8Array ) {\n\n\t\t\t\t\t\ttype = UnsignedByteType;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttype = ByteType;\n\t\t\t\t\t\tinternalFormat += '_SNORM';\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\ttargetBufferCons = Float32Array;\n\t\t\t\t\tinternalFormat += '32F';\n\t\t\t\t\ttype = FloatType;\n\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t\tcase IntType:\n\t\t\t\tinternalFormat += byteCount * 8 + 'I';\n\t\t\t\tnormalizeValue = normalized ? Math.pow( 2, originalBufferCons.BYTES_PER_ELEMENT * 8 - 1 ) : 1.0;\n\t\t\t\tformat = countToIntFormat( itemSize );\n\n\t\t\t\tif ( byteCount === 1 ) {\n\n\t\t\t\t\ttargetBufferCons = Int8Array;\n\t\t\t\t\ttype = ByteType;\n\n\t\t\t\t} else if ( byteCount === 2 ) {\n\n\t\t\t\t\ttargetBufferCons = Int16Array;\n\t\t\t\t\ttype = ShortType;\n\n\t\t\t\t} else {\n\n\t\t\t\t\ttargetBufferCons = Int32Array;\n\t\t\t\t\ttype = IntType;\n\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t\tcase UnsignedIntType:\n\t\t\t\tinternalFormat += byteCount * 8 + 'UI';\n\t\t\t\tnormalizeValue = normalized ? Math.pow( 2, originalBufferCons.BYTES_PER_ELEMENT * 8 - 1 ) : 1.0;\n\t\t\t\tformat = countToIntFormat( itemSize );\n\n\t\t\t\tif ( byteCount === 1 ) {\n\n\t\t\t\t\ttargetBufferCons = Uint8Array;\n\t\t\t\t\ttype = UnsignedByteType;\n\n\t\t\t\t} else if ( byteCount === 2 ) {\n\n\t\t\t\t\ttargetBufferCons = Uint16Array;\n\t\t\t\t\ttype = UnsignedShortType;\n\n\t\t\t\t} else {\n\n\t\t\t\t\ttargetBufferCons = Uint32Array;\n\t\t\t\t\ttype = UnsignedIntType;\n\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t}\n\n\t\t// there will be a mismatch between format length and final length because\n\t\t// RGBFormat and RGBIntegerFormat was removed\n\t\tif ( finalStride === 3 && ( format === RGBAFormat || format === RGBAIntegerFormat ) ) {\n\n\t\t\tfinalStride = 4;\n\n\t\t}\n\n\t\t// copy the data over to the new texture array\n\t\tconst dimension = Math.ceil( Math.sqrt( count ) ) || 1;\n\t\tconst length = finalStride * dimension * dimension;\n\t\tconst dataArray = new targetBufferCons( length );\n\n\t\t// temporarily set the normalized state to false since we have custom normalization logic\n\t\tconst originalNormalized = attr.normalized;\n\t\tattr.normalized = false;\n\t\tfor ( let i = 0; i < count; i ++ ) {\n\n\t\t\tconst ii = finalStride * i;\n\t\t\tdataArray[ ii ] = attr.getX( i ) / normalizeValue;\n\n\t\t\tif ( itemSize >= 2 ) {\n\n\t\t\t\tdataArray[ ii + 1 ] = attr.getY( i ) / normalizeValue;\n\n\t\t\t}\n\n\t\t\tif ( itemSize >= 3 ) {\n\n\t\t\t\tdataArray[ ii + 2 ] = attr.getZ( i ) / normalizeValue;\n\n\t\t\t\tif ( finalStride === 4 ) {\n\n\t\t\t\t\tdataArray[ ii + 3 ] = 1.0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( itemSize >= 4 ) {\n\n\t\t\t\tdataArray[ ii + 3 ] = attr.getW( i ) / normalizeValue;\n\n\t\t\t}\n\n\t\t}\n\n\t\tattr.normalized = originalNormalized;\n\n\t\tthis.internalFormat = internalFormat;\n\t\tthis.format = format;\n\t\tthis.type = type;\n\t\tthis.image.width = dimension;\n\t\tthis.image.height = dimension;\n\t\tthis.image.data = dataArray;\n\t\tthis.needsUpdate = true;\n\t\tthis.dispose();\n\n\t\tattr.itemSize = originalItemSize;\n\t\tattr.count = originalCount;\n\n\t}\n\n}\n\n/**\n * A VertexAttributeTexture that forces the unsigned integer texture type.\n * @extends VertexAttributeTexture\n * @section Shader and Texture Packing API\n */\nexport class UIntVertexAttributeTexture extends VertexAttributeTexture {\n\n\tconstructor() {\n\n\t\tsuper();\n\t\tthis._forcedType = UnsignedIntType;\n\n\t}\n\n}\n\n/**\n * A VertexAttributeTexture that forces the signed integer texture type.\n * @extends VertexAttributeTexture\n * @section Shader and Texture Packing API\n */\nexport class IntVertexAttributeTexture extends VertexAttributeTexture {\n\n\tconstructor() {\n\n\t\tsuper();\n\t\tthis._forcedType = IntType;\n\n\t}\n\n\n}\n\n/**\n * A VertexAttributeTexture that forces the float texture type.\n * @extends VertexAttributeTexture\n * @section Shader and Texture Packing API\n */\nexport class FloatVertexAttributeTexture extends VertexAttributeTexture {\n\n\tconstructor() {\n\n\t\tsuper();\n\t\tthis._forcedType = FloatType;\n\n\t}\n\n}\n","/** @import { MeshBVH } from '../core/MeshBVH.js' */\nimport {\n\tDataTexture,\n\tFloatType,\n\tUnsignedIntType,\n\tRGBAFormat,\n\tRGIntegerFormat,\n\tNearestFilter,\n\tBufferAttribute,\n} from 'three';\nimport {\n\tFloatVertexAttributeTexture,\n\tUIntVertexAttributeTexture,\n} from './VertexAttributeTexture.js';\nimport { BYTES_PER_NODE, LEAFNODE_MASK_32 } from '../core/Constants.js';\nimport {\n\tBOUNDING_DATA_INDEX,\n\tCOUNT,\n\tIS_LEAF,\n\tOFFSET,\n\tSPLIT_AXIS,\n} from '../core/utils/nodeBufferUtils.js';\nimport { getIndexArray, getVertexCount } from '../core/build/geometryUtils.js';\n\n/**\n * A shader uniform object corresponding to the `BVH` shader struct defined in shaderStructs. The\n * object contains four textures containing information about the BVH and geometry so it can be\n * queried in a shader using the bvh intersection functions defined in shaderFunctions. This object\n * is intended to be used as a shader uniform and read in the shader as a `BVH` struct.\n *\n * @section Shader and Texture Packing API\n */\nexport class MeshBVHUniformStruct {\n\n\tconstructor() {\n\n\t\tthis.index = new UIntVertexAttributeTexture();\n\t\tthis.position = new FloatVertexAttributeTexture();\n\t\tthis.bvhBounds = new DataTexture();\n\t\tthis.bvhContents = new DataTexture();\n\t\tthis._cachedIndexAttr = null;\n\n\t\tthis.index.overrideItemSize = 3;\n\n\t}\n\n\t/**\n\t * Updates the object and associated textures with data from the provided BVH.\n\t *\n\t * @param {MeshBVH} bvh\n\t * @returns {void}\n\t */\n\tupdateFrom( bvh ) {\n\n\t\tconst { geometry } = bvh;\n\t\tbvhToTextures( bvh, this.bvhBounds, this.bvhContents );\n\n\t\tthis.position.updateFrom( geometry.attributes.position );\n\n\t\t// dereference a new index attribute if we're using indirect storage\n\t\tif ( bvh.indirect ) {\n\n\t\t\tconst indirectBuffer = bvh._indirectBuffer;\n\t\t\tif (\n\t\t\t\tthis._cachedIndexAttr === null ||\n\t\t\t\tthis._cachedIndexAttr.count !== indirectBuffer.length\n\t\t\t) {\n\n\t\t\t\tif ( geometry.index ) {\n\n\t\t\t\t\tthis._cachedIndexAttr = geometry.index.clone();\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconst array = getIndexArray( getVertexCount( geometry ) );\n\t\t\t\t\tthis._cachedIndexAttr = new BufferAttribute( array, 1, false );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tdereferenceIndex( geometry, indirectBuffer, this._cachedIndexAttr );\n\t\t\tthis.index.updateFrom( this._cachedIndexAttr );\n\n\t\t} else {\n\n\t\t\tthis.index.updateFrom( geometry.index );\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Dispose of the associated textures.\n\t *\n\t * @returns {void}\n\t */\n\tdispose() {\n\n\t\tconst { index, position, bvhBounds, bvhContents } = this;\n\n\t\tif ( index ) index.dispose();\n\t\tif ( position ) position.dispose();\n\t\tif ( bvhBounds ) bvhBounds.dispose();\n\t\tif ( bvhContents ) bvhContents.dispose();\n\n\t}\n\n}\n\nfunction dereferenceIndex( geometry, indirectBuffer, target ) {\n\n\tconst unpacked = target.array;\n\tconst indexArray = geometry.index ? geometry.index.array : null;\n\tfor ( let i = 0, l = indirectBuffer.length; i < l; i ++ ) {\n\n\t\tconst i3 = 3 * i;\n\t\tconst v3 = 3 * indirectBuffer[ i ];\n\t\tfor ( let c = 0; c < 3; c ++ ) {\n\n\t\t\tunpacked[ i3 + c ] = indexArray ? indexArray[ v3 + c ] : v3 + c;\n\n\t\t}\n\n\t}\n\n}\n\nfunction bvhToTextures( bvh, boundsTexture, contentsTexture ) {\n\n\tconst roots = bvh._roots;\n\n\tif ( roots.length !== 1 ) {\n\n\t\tthrow new Error( 'MeshBVHUniformStruct: Multi-root BVHs not supported.' );\n\n\t}\n\n\tconst root = roots[ 0 ];\n\tconst uint16Array = new Uint16Array( root );\n\tconst uint32Array = new Uint32Array( root );\n\tconst float32Array = new Float32Array( root );\n\n\t// Both bounds need two elements per node so compute the height so it's twice as long as\n\t// the width so we can expand the row by two and still have a square texture\n\tconst nodeCount = root.byteLength / BYTES_PER_NODE;\n\tconst boundsDimension = 2 * Math.ceil( Math.sqrt( nodeCount / 2 ) );\n\tconst boundsArray = new Float32Array( 4 * boundsDimension * boundsDimension );\n\n\tconst contentsDimension = Math.ceil( Math.sqrt( nodeCount ) );\n\tconst contentsArray = new Uint32Array( 2 * contentsDimension * contentsDimension );\n\n\tfor ( let i = 0; i < nodeCount; i ++ ) {\n\n\t\tconst nodeIndex32 = i * BYTES_PER_NODE / 4;\n\t\tconst nodeIndex16 = nodeIndex32 * 2;\n\t\tconst boundsIndex = BOUNDING_DATA_INDEX( nodeIndex32 );\n\t\tfor ( let b = 0; b < 3; b ++ ) {\n\n\t\t\tboundsArray[ 8 * i + 0 + b ] = float32Array[ boundsIndex + 0 + b ];\n\t\t\tboundsArray[ 8 * i + 4 + b ] = float32Array[ boundsIndex + 3 + b ];\n\n\t\t}\n\n\t\tif ( IS_LEAF( nodeIndex16, uint16Array ) ) {\n\n\t\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\t\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\n\t\t\tconst mergedLeafCount = LEAFNODE_MASK_32 | count;\n\t\t\tcontentsArray[ i * 2 + 0 ] = mergedLeafCount;\n\t\t\tcontentsArray[ i * 2 + 1 ] = offset;\n\n\t\t} else {\n\n\t\t\tconst rightNodeIndex = uint32Array[ nodeIndex32 + 6 ];\n\t\t\tconst splitAxis = SPLIT_AXIS( nodeIndex32, uint32Array );\n\n\t\t\tcontentsArray[ i * 2 + 0 ] = splitAxis;\n\t\t\tcontentsArray[ i * 2 + 1 ] = rightNodeIndex;\n\n\t\t}\n\n\t}\n\n\tboundsTexture.image.data = boundsArray;\n\tboundsTexture.image.width = boundsDimension;\n\tboundsTexture.image.height = boundsDimension;\n\tboundsTexture.format = RGBAFormat;\n\tboundsTexture.type = FloatType;\n\tboundsTexture.internalFormat = 'RGBA32F';\n\tboundsTexture.minFilter = NearestFilter;\n\tboundsTexture.magFilter = NearestFilter;\n\tboundsTexture.generateMipmaps = false;\n\tboundsTexture.needsUpdate = true;\n\tboundsTexture.dispose();\n\n\tcontentsTexture.image.data = contentsArray;\n\tcontentsTexture.image.width = contentsDimension;\n\tcontentsTexture.image.height = contentsDimension;\n\tcontentsTexture.format = RGIntegerFormat;\n\tcontentsTexture.type = UnsignedIntType;\n\tcontentsTexture.internalFormat = 'RG32UI';\n\tcontentsTexture.minFilter = NearestFilter;\n\tcontentsTexture.magFilter = NearestFilter;\n\tcontentsTexture.generateMipmaps = false;\n\tcontentsTexture.needsUpdate = true;\n\tcontentsTexture.dispose();\n\n}\n","/**\n * Set of shader functions used for interacting with the packed BVH in a shader and sampling\n * VertexAttributeTextures. Provides common utility functions including `texelFetch1D`. See\n * [src/webgl/glsl](https://github.com/gkjohnson/three-mesh-bvh/tree/master/src/webgl/glsl)\n * for full implementations and declarations.\n *\n * Accessed as `BVHShaderGLSL.common_functions`.\n *\n * @section Shader and Texture Packing API\n * @type {string}\n */\nexport const common_functions = /* glsl */`\n\n// A stack of uint32 indices can can store the indices for\n// a perfectly balanced tree with a depth up to 31. Lower stack\n// depth gets higher performance.\n//\n// However not all trees are balanced. Best value to set this to\n// is the trees max depth.\n#ifndef BVH_STACK_DEPTH\n#define BVH_STACK_DEPTH 60\n#endif\n\n#ifndef INFINITY\n#define INFINITY 1e20\n#endif\n\n// Utilities\nuvec4 uTexelFetch1D( usampler2D tex, uint index ) {\n\n\tuint width = uint( textureSize( tex, 0 ).x );\n\tuvec2 uv;\n\tuv.x = index % width;\n\tuv.y = index / width;\n\n\treturn texelFetch( tex, ivec2( uv ), 0 );\n\n}\n\nivec4 iTexelFetch1D( isampler2D tex, uint index ) {\n\n\tuint width = uint( textureSize( tex, 0 ).x );\n\tuvec2 uv;\n\tuv.x = index % width;\n\tuv.y = index / width;\n\n\treturn texelFetch( tex, ivec2( uv ), 0 );\n\n}\n\nvec4 texelFetch1D( sampler2D tex, uint index ) {\n\n\tuint width = uint( textureSize( tex, 0 ).x );\n\tuvec2 uv;\n\tuv.x = index % width;\n\tuv.y = index / width;\n\n\treturn texelFetch( tex, ivec2( uv ), 0 );\n\n}\n\nvec4 textureSampleBarycoord( sampler2D tex, vec3 barycoord, uvec3 faceIndices ) {\n\n\treturn\n\t\tbarycoord.x * texelFetch1D( tex, faceIndices.x ) +\n\t\tbarycoord.y * texelFetch1D( tex, faceIndices.y ) +\n\t\tbarycoord.z * texelFetch1D( tex, faceIndices.z );\n\n}\n\nvoid ndcToCameraRay(\n\tvec2 coord, mat4 cameraWorld, mat4 invProjectionMatrix,\n\tout vec3 rayOrigin, out vec3 rayDirection\n) {\n\n\t// get camera look direction and near plane for camera clipping\n\tvec4 lookDirection = cameraWorld * vec4( 0.0, 0.0, - 1.0, 0.0 );\n\tvec4 nearVector = invProjectionMatrix * vec4( 0.0, 0.0, - 1.0, 1.0 );\n\tfloat near = abs( nearVector.z / nearVector.w );\n\n\t// get the camera direction and position from camera matrices\n\tvec4 origin = cameraWorld * vec4( 0.0, 0.0, 0.0, 1.0 );\n\tvec4 direction = invProjectionMatrix * vec4( coord, 0.5, 1.0 );\n\tdirection /= direction.w;\n\tdirection = cameraWorld * direction - origin;\n\n\t// slide the origin along the ray until it sits at the near clip plane position\n\torigin.xyz += direction.xyz * near / dot( direction, lookDirection );\n\n\trayOrigin = origin.xyz;\n\trayDirection = direction.xyz;\n\n}\n`;\n","/**\n * Set of shader functions used for interacting with the packed BVH in a shader and sampling\n * VertexAttributeTextures. Provides ray intersection functions. See\n * [src/webgl/glsl](https://github.com/gkjohnson/three-mesh-bvh/tree/master/src/webgl/glsl)\n * for full implementations and declarations.\n *\n * Accessed as `BVHShaderGLSL.bvh_ray_functions`.\n *\n * @section Shader and Texture Packing API\n * @type {string}\n */\nexport const bvh_ray_functions = /* glsl */`\n\n#ifndef TRI_INTERSECT_EPSILON\n#define TRI_INTERSECT_EPSILON 1e-5\n#endif\n\n// Raycasting\nbool intersectsBounds( vec3 rayOrigin, vec3 rayDirection, vec3 boundsMin, vec3 boundsMax, out float dist ) {\n\n\t// https://www.reddit.com/r/opengl/comments/8ntzz5/fast_glsl_ray_box_intersection/\n\t// https://tavianator.com/2011/ray_box.html\n\tvec3 invDir = 1.0 / rayDirection;\n\n\t// find intersection distances for each plane\n\tvec3 tMinPlane = invDir * ( boundsMin - rayOrigin );\n\tvec3 tMaxPlane = invDir * ( boundsMax - rayOrigin );\n\n\t// get the min and max distances from each intersection\n\tvec3 tMinHit = min( tMaxPlane, tMinPlane );\n\tvec3 tMaxHit = max( tMaxPlane, tMinPlane );\n\n\t// get the furthest hit distance\n\tvec2 t = max( tMinHit.xx, tMinHit.yz );\n\tfloat t0 = max( t.x, t.y );\n\n\t// get the minimum hit distance\n\tt = min( tMaxHit.xx, tMaxHit.yz );\n\tfloat t1 = min( t.x, t.y );\n\n\t// set distance to 0.0 if the ray starts inside the box\n\tdist = max( t0, 0.0 );\n\n\treturn t1 >= dist;\n\n}\n\nbool intersectsTriangle(\n\tvec3 rayOrigin, vec3 rayDirection, vec3 a, vec3 b, vec3 c,\n\tout vec3 barycoord, out vec3 norm, out float dist, out float side\n) {\n\n\t// https://stackoverflow.com/questions/42740765/intersection-between-line-and-triangle-in-3d\n\tvec3 edge1 = b - a;\n\tvec3 edge2 = c - a;\n\tnorm = cross( edge1, edge2 );\n\n\tfloat det = - dot( rayDirection, norm );\n\tfloat invdet = 1.0 / det;\n\n\tvec3 AO = rayOrigin - a;\n\tvec3 DAO = cross( AO, rayDirection );\n\n\tvec4 uvt;\n\tuvt.x = dot( edge2, DAO ) * invdet;\n\tuvt.y = - dot( edge1, DAO ) * invdet;\n\tuvt.z = dot( AO, norm ) * invdet;\n\tuvt.w = 1.0 - uvt.x - uvt.y;\n\n\t// set the hit information\n\tbarycoord = uvt.wxy; // arranged in A, B, C order\n\tdist = uvt.z;\n\tside = sign( det );\n\tnorm = side * normalize( norm );\n\n\t// add an epsilon to avoid misses between triangles\n\tuvt += vec4( TRI_INTERSECT_EPSILON );\n\n\treturn all( greaterThanEqual( uvt, vec4( 0.0 ) ) );\n\n}\n\nbool intersectTriangles(\n\t// geometry info and triangle range\n\tsampler2D positionAttr, usampler2D indexAttr, uint offset, uint count,\n\n\t// ray\n\tvec3 rayOrigin, vec3 rayDirection,\n\n\t// outputs\n\tinout float minDistance, inout uvec4 faceIndices, inout vec3 faceNormal, inout vec3 barycoord,\n\tinout float side, inout float dist\n) {\n\n\tbool found = false;\n\tvec3 localBarycoord, localNormal;\n\tfloat localDist, localSide;\n\tfor ( uint i = offset, l = offset + count; i < l; i ++ ) {\n\n\t\tuvec3 indices = uTexelFetch1D( indexAttr, i ).xyz;\n\t\tvec3 a = texelFetch1D( positionAttr, indices.x ).rgb;\n\t\tvec3 b = texelFetch1D( positionAttr, indices.y ).rgb;\n\t\tvec3 c = texelFetch1D( positionAttr, indices.z ).rgb;\n\n\t\tif (\n\t\t\tintersectsTriangle( rayOrigin, rayDirection, a, b, c, localBarycoord, localNormal, localDist, localSide )\n\t\t\t&& localDist < minDistance\n\t\t) {\n\n\t\t\tfound = true;\n\t\t\tminDistance = localDist;\n\n\t\t\tfaceIndices = uvec4( indices.xyz, i );\n\t\t\tfaceNormal = localNormal;\n\n\t\t\tside = localSide;\n\t\t\tbarycoord = localBarycoord;\n\t\t\tdist = localDist;\n\n\t\t}\n\n\t}\n\n\treturn found;\n\n}\n\nbool intersectsBVHNodeBounds( vec3 rayOrigin, vec3 rayDirection, sampler2D bvhBounds, uint currNodeIndex, out float dist ) {\n\n\tuint cni2 = currNodeIndex * 2u;\n\tvec3 boundsMin = texelFetch1D( bvhBounds, cni2 ).xyz;\n\tvec3 boundsMax = texelFetch1D( bvhBounds, cni2 + 1u ).xyz;\n\treturn intersectsBounds( rayOrigin, rayDirection, boundsMin, boundsMax, dist );\n\n}\n\n// use a macro to hide the fact that we need to expand the struct into separate fields\n#define\\\n\tbvhIntersectFirstHit(\\\n\t\tbvh,\\\n\t\trayOrigin, rayDirection, faceIndices, faceNormal, barycoord, side, dist\\\n\t)\\\n\t_bvhIntersectFirstHit(\\\n\t\tbvh.position, bvh.index, bvh.bvhBounds, bvh.bvhContents,\\\n\t\trayOrigin, rayDirection, faceIndices, faceNormal, barycoord, side, dist\\\n\t)\n\nbool _bvhIntersectFirstHit(\n\t// bvh info\n\tsampler2D bvh_position, usampler2D bvh_index, sampler2D bvh_bvhBounds, usampler2D bvh_bvhContents,\n\n\t// ray\n\tvec3 rayOrigin, vec3 rayDirection,\n\n\t// output variables split into separate variables due to output precision\n\tinout uvec4 faceIndices, inout vec3 faceNormal, inout vec3 barycoord,\n\tinout float side, inout float dist\n) {\n\n\t// stack needs to be twice as long as the deepest tree we expect because\n\t// we push both the left and right child onto the stack every traversal\n\tint pointer = 0;\n\tuint stack[ BVH_STACK_DEPTH ];\n\tstack[ 0 ] = 0u;\n\n\tfloat triangleDistance = INFINITY;\n\tbool found = false;\n\twhile ( pointer > - 1 && pointer < BVH_STACK_DEPTH ) {\n\n\t\tuint currNodeIndex = stack[ pointer ];\n\t\tpointer --;\n\n\t\t// check if we intersect the current bounds\n\t\tfloat boundsHitDistance;\n\t\tif (\n\t\t\t! intersectsBVHNodeBounds( rayOrigin, rayDirection, bvh_bvhBounds, currNodeIndex, boundsHitDistance )\n\t\t\t|| boundsHitDistance > triangleDistance\n\t\t) {\n\n\t\t\tcontinue;\n\n\t\t}\n\n\t\tuvec2 boundsInfo = uTexelFetch1D( bvh_bvhContents, currNodeIndex ).xy;\n\t\tbool isLeaf = bool( boundsInfo.x & 0xffff0000u );\n\n\t\tif ( isLeaf ) {\n\n\t\t\tuint count = boundsInfo.x & 0x0000ffffu;\n\t\t\tuint offset = boundsInfo.y;\n\n\t\t\tfound = intersectTriangles(\n\t\t\t\tbvh_position, bvh_index, offset, count,\n\t\t\t\trayOrigin, rayDirection, triangleDistance,\n\t\t\t\tfaceIndices, faceNormal, barycoord, side, dist\n\t\t\t) || found;\n\n\t\t} else {\n\n\t\t\tuint leftIndex = currNodeIndex + 1u;\n\t\t\tuint splitAxis = boundsInfo.x & 0x0000ffffu;\n\t\t\tuint rightIndex = currNodeIndex + boundsInfo.y;\n\n\t\t\tbool leftToRight = rayDirection[ splitAxis ] >= 0.0;\n\t\t\tuint c1 = leftToRight ? leftIndex : rightIndex;\n\t\t\tuint c2 = leftToRight ? rightIndex : leftIndex;\n\n\t\t\t// set c2 in the stack so we traverse it later. We need to keep track of a pointer in\n\t\t\t// the stack while we traverse. The second pointer added is the one that will be\n\t\t\t// traversed first\n\t\t\tpointer ++;\n\t\t\tstack[ pointer ] = c2;\n\n\t\t\tpointer ++;\n\t\t\tstack[ pointer ] = c1;\n\n\t\t}\n\n\t}\n\n\treturn found;\n\n}\n`;\n","// Note that a struct cannot be used for the hit record including faceIndices, faceNormal, barycoord,\n// side, and dist because on some mobile GPUS (such as Adreno) numbers are afforded less precision specifically\n// when in a struct leading to inaccurate hit results. See KhronosGroup/WebGL#3351 for more details.\n\n/**\n * Set of shader structs and defined constants used for interacting with the packed BVH in a\n * shader. See [src/webgl/glsl/bvh_struct_definitions.glsl.js](https://github.com/gkjohnson/three-mesh-bvh/blob/master/src/webgl/glsl/bvh_struct_definitions.glsl.js)\n * for full implementations and declarations.\n *\n * Accessed as `BVHShaderGLSL.bvh_struct_definitions`.\n *\n * @section Shader and Texture Packing API\n * @type {string}\n */\nexport const bvh_struct_definitions = /* glsl */`\nstruct BVH {\n\n\tusampler2D index;\n\tsampler2D position;\n\n\tsampler2D bvhBounds;\n\tusampler2D bvhContents;\n\n};\n`;\n","export * from './core/BVH.js';\nexport * from './core/GeometryBVH.js';\nexport * from './core/MeshBVH.js';\nexport * from './core/LineBVH.js';\nexport * from './core/PointsBVH.js';\nexport * from './core/ObjectBVH.js';\nexport * from './core/SkinnedMeshBVH.js';\nexport * from './objects/BVHHelper.js';\nexport { CENTER, AVERAGE, SAH, NOT_INTERSECTED, INTERSECTED, CONTAINED, SKIP_GENERATION } from './core/Constants.js';\nexport { getBVHExtremes, estimateMemoryInBytes, getJSONStructure, validateBounds } from './debug/Debug.js';\nexport * from './utils/ExtensionUtilities.js';\nexport { getTriangleHitPointInfo } from './utils/TriangleUtilities.js';\nexport * from './math/ExtendedTriangle.js';\nexport * from './math/OrientedBox.js';\nexport * from './webgl/MeshBVHUniformStruct.js';\nexport * from './webgl/VertexAttributeTexture.js';\nexport * from './utils/StaticGeometryGenerator.js';\nexport * as BVHShaderGLSL from './webgl/BVHShaderGLSL.js';\n\n// backwards compatibility\nimport * as BVHShaderGLSL from './webgl/BVHShaderGLSL.js';\nexport const shaderStructs = BVHShaderGLSL.bvh_struct_definitions;\nexport const shaderDistanceFunction = BVHShaderGLSL.bvh_distance_functions;\nexport const shaderIntersectFunction = `\n\t${ BVHShaderGLSL.common_functions }\n\t${ BVHShaderGLSL.bvh_ray_functions }\n`;\n","import { shaderStructs, shaderIntersectFunction } from 'three-mesh-bvh'\r\n\r\n// Bake shaders kept for compatibility\r\nexport const DIAMOND_BAKE_VERT = /* glsl */ `\r\nuniform vec3 uCentroid;\r\nuniform float uRadius;\r\nattribute vec4 aFacet;\r\nvarying vec4 vFacet;\r\n\r\nvoid main() {\r\n vFacet = aFacet;\r\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\r\n}\r\n`\r\n\r\nexport const DIAMOND_BAKE_FRAG = /* glsl */ `\r\nvarying vec4 vFacet;\r\n\r\nvoid main() {\r\n gl_FragColor = vFacet;\r\n}\r\n`\r\n\r\n// BVH Raytraced Diamond Vertex Shader (GLSL 3.00)\r\nexport const DIAMOND_RAYMARCH_VERT = /* glsl */ `\r\nvarying vec3 vWorldPos;\r\nvarying vec3 vLocalPos;\r\nvarying vec3 vLocalNormal;\r\nvarying vec3 vLocalCameraPos;\r\nvarying mat3 vModelRotation;\r\n\r\nuniform vec3 cameraPos;\r\n\r\nvoid main() {\r\n vLocalPos = position;\r\n #ifdef USE_NORMAL\r\n vLocalNormal = normal;\r\n #else\r\n vLocalNormal = vec3(0.0, 1.0, 0.0);\r\n #endif\r\n vec4 worldPosition = modelMatrix * vec4(position, 1.0);\r\n vWorldPos = worldPosition.xyz;\r\n vModelRotation = mat3(modelMatrix);\r\n vLocalCameraPos = (inverse(modelMatrix) * vec4(cameraPos, 1.0)).xyz;\r\n gl_Position = projectionMatrix * viewMatrix * worldPosition;\r\n}\r\n`\r\n\r\n// BVH Raytraced Diamond Fragment Shader (GLSL 3.00)\r\nexport const DIAMOND_RAYMARCH_FRAG = /* glsl */ `\r\nprecision highp float;\r\nprecision highp int;\r\nprecision highp usampler2D;\r\nprecision highp isampler2D;\r\n\r\nout highp vec4 pc_fragColor;\r\n#define gl_FragColor pc_fragColor\r\n\r\n#ifdef USE_CUBE_ENV\r\n uniform samplerCube envMap;\r\n#else\r\n uniform sampler2D envMap;\r\n#endif\r\n\r\nuniform mat3 envRotationMatrix;\r\nuniform vec3 cameraPos;\r\nuniform float ior;\r\nuniform float dispersion;\r\nuniform float absorption;\r\nuniform float envIntensity;\r\nuniform float gamma;\r\nuniform vec3 color;\r\nuniform vec3 rgbBoost;\r\nuniform float transmission;\r\nuniform float reflectivity;\r\nuniform float facetSharpness;\r\nuniform int rayBounces;\r\nuniform float uRadius;\r\n\r\n${shaderStructs}\r\n${shaderIntersectFunction}\r\nuniform BVH bvh;\r\n\r\nvarying vec3 vWorldPos;\r\nvarying vec3 vLocalPos;\r\nvarying vec3 vLocalNormal;\r\nvarying vec3 vLocalCameraPos;\r\nvarying mat3 vModelRotation;\r\n\r\n#define PI 3.14159265359\r\n\r\nvec3 aces(vec3 col) {\r\n const float a = 2.51;\r\n const float b = 0.03;\r\n const float c = 2.43;\r\n const float d = 0.59;\r\n const float e = 0.14;\r\n return clamp((col * (a * col + b)) / (col * (c * col + d) + e), 0.0, 1.0);\r\n}\r\n\r\nfloat schlick(float cosTheta, float f0) {\r\n return clamp(f0 + (1.0 - f0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0), 0.0, 0.95);\r\n}\r\n\r\nvec3 sampleEnv(vec3 direction) {\r\n vec3 dir = normalize(envRotationMatrix * direction);\r\n #ifdef USE_CUBE_ENV\r\n return texture(envMap, dir).rgb;\r\n #else\r\n float v = asin(clamp(dir.y, -0.9999, 0.9999)) / PI + 0.5;\r\n float u = fract(atan(dir.z, dir.x) / (2.0 * PI) + 0.5);\r\n return textureLod(envMap, vec2(u, v), 0.0).rgb;\r\n #endif\r\n}\r\n\r\nvec3 sampleChromaticEnv(vec3 localR, vec3 localG, vec3 localB) {\r\n vec3 worldR = normalize(vModelRotation * localR);\r\n vec3 worldG = normalize(vModelRotation * localG);\r\n vec3 worldB = normalize(vModelRotation * localB);\r\n return vec3(sampleEnv(worldR).r, sampleEnv(worldG).g, sampleEnv(worldB).b);\r\n}\r\n\r\nvec3 traceDiamondBVH(vec3 localIncident, vec3 localNormal, float baseIor, float fire, int bounces) {\r\n vec3 entryRay = refract(localIncident, localNormal, 1.0 / baseIor);\r\n if (length(entryRay) < 0.001) entryRay = reflect(localIncident, localNormal);\r\n\r\n vec3 ray = normalize(entryRay);\r\n vec3 position = vLocalPos + ray * 0.0001;\r\n float weight = 1.0;\r\n float totalDistance = 0.0;\r\n float normRadius = max(uRadius, 0.01);\r\n\r\n vec3 targetColor = clamp(color, vec3(0.005), vec3(1.0));\r\n float density = max(absorption, 0.5);\r\n vec3 sigma = -log(targetColor) * density;\r\n\r\n // Dispersion per-channel refractive indices\r\n float delta = fire * 1.5;\r\n#ifdef CORRECT_DISPERSION_SIGN\r\n // Physical: red lower IOR, blue higher IOR\r\n float iorR = baseIor - delta;\r\n float iorG = baseIor;\r\n float iorB = baseIor + delta;\r\n#else\r\n // Reference quirk: inverted dispersion (red higher IOR, blue lower IOR)\r\n float iorR = baseIor + delta;\r\n float iorG = baseIor;\r\n float iorB = baseIor - delta;\r\n#endif\r\n\r\n // Critical angle for Total Internal Reflection (gem -> air)\r\n float critSinSq = max(0.0, 1.0 - 1.0 / (baseIor * baseIor));\r\n vec3 accumulated = vec3(0.0);\r\n\r\n for (int bounce = 0; bounce < 8; bounce++) {\r\n if (bounce >= bounces) break;\r\n\r\n uvec4 faceIndices;\r\n vec3 faceNormal;\r\n vec3 barycoord;\r\n float side;\r\n float distance;\r\n bool hit = bvhIntersectFirstHit(bvh, position, ray, faceIndices, faceNormal, barycoord, side, distance);\r\n if (!hit) break;\r\n\r\n vec3 hitPosition = position + ray * distance;\r\n totalDistance += distance;\r\n if (dot(faceNormal, ray) > 0.0) faceNormal = -faceNormal;\r\n\r\n float cosI = clamp(dot(-ray, faceNormal), 0.0, 1.0);\r\n float cosSq = cosI * cosI;\r\n\r\n if (cosSq <= critSinSq) {\r\n // Total Internal Reflection (TIR) — 100% of ray energy bounces internally\r\n#ifdef ACCUMULATE_TIR\r\n vec3 worldRay = normalize(vModelRotation * ray);\r\n vec3 envVal = sampleEnv(worldRay);\r\n vec3 beer = exp(-sigma * (totalDistance / normRadius));\r\n accumulated += weight * envVal * beer;\r\n#endif\r\n ray = reflect(ray, faceNormal);\r\n position = hitPosition + ray * 0.0001;\r\n } else {\r\n // Partial transmission and reflection via Snell & Fresnel\r\n float sinTransSq = baseIor * baseIor * (1.0 - cosSq);\r\n float cosT = sqrt(max(1.0 - sinTransSq, 0.0));\r\n float rParallel = (cosI - baseIor * cosT) / (cosI + baseIor * cosT);\r\n float rPerp = (baseIor * cosI - cosT) / (baseIor * cosI + cosT);\r\n float R = clamp(0.5 * (rParallel * rParallel + rPerp * rPerp), 0.0, 0.96);\r\n float T = 1.0 - R;\r\n\r\n // Chromatic exit refraction for each wavelength\r\n vec3 exitR = refract(ray, faceNormal, iorR);\r\n vec3 exitG = refract(ray, faceNormal, iorG);\r\n vec3 exitB = refract(ray, faceNormal, iorB);\r\n\r\n if (length(exitG) > 0.001 && weight * T > 0.002) {\r\n vec3 eR = length(exitR) > 0.001 ? exitR : exitG;\r\n vec3 eB = length(exitB) > 0.001 ? exitB : exitG;\r\n vec3 envVal = sampleChromaticEnv(eR, exitG, eB);\r\n vec3 beer = exp(-sigma * (totalDistance / normRadius));\r\n accumulated += weight * T * envVal * beer;\r\n }\r\n\r\n // Continue internal reflection with remaining weight\r\n ray = reflect(ray, faceNormal);\r\n position = hitPosition + ray * 0.0001;\r\n weight *= R;\r\n }\r\n\r\n if (weight < 0.005) break;\r\n }\r\n\r\n // Smooth exhaustion tail: sample final escaped direction\r\n if (weight > 0.005) {\r\n vec3 worldRay = normalize(vModelRotation * ray);\r\n vec3 envVal = sampleEnv(worldRay);\r\n vec3 beer = exp(-sigma * (totalDistance / normRadius));\r\n accumulated += weight * envVal * beer * 0.6;\r\n }\r\n\r\n return accumulated;\r\n}\r\n\r\nvoid main() {\r\n vec3 flatFacetNormal = normalize(cross(dFdx(vLocalPos), dFdy(vLocalPos)));\r\n #ifdef USE_NORMAL\r\n if (dot(flatFacetNormal, vLocalNormal) < 0.0) flatFacetNormal = -flatFacetNormal;\r\n vec3 localNormal = normalize(mix(vLocalNormal, flatFacetNormal, clamp(facetSharpness, 0.0, 1.0)));\r\n #else\r\n vec3 localNormal = flatFacetNormal;\r\n #endif\r\n\r\n vec3 localView = normalize(vLocalCameraPos - vLocalPos);\r\n vec3 localIncident = -localView;\r\n if (dot(localNormal, localIncident) > 0.0) localNormal = -localNormal;\r\n\r\n vec3 worldNormal = normalize(vModelRotation * localNormal);\r\n vec3 view = normalize(cameraPos - vWorldPos);\r\n vec3 incident = -view;\r\n if (dot(worldNormal, incident) > 0.0) worldNormal = -worldNormal;\r\n\r\n // External Fresnel (dielectric surface reflection)\r\n float cosTheta = clamp(dot(view, worldNormal), 0.0, 1.0);\r\n float r0 = pow((ior - 1.0) / (ior + 1.0), 2.0);\r\n#ifdef USE_CORRECT_FRESNEL\r\n // Physical: cosI from incident angle (DIAMOND_PLAN §3 physics fix)\r\n float fresnel = schlick(abs(dot(-incident, worldNormal)), r0);\r\n#else\r\n // Reference quirk: cosT (transmitted angle) — reproduces RMJ visual\r\n vec3 entryRefracted = refract(incident, worldNormal, 1.0 / ior);\r\n float fresnel = schlick(abs(dot(entryRefracted, -worldNormal)), r0);\r\n#endif\r\n vec3 externalReflection = sampleEnv(reflect(incident, worldNormal));\r\n\r\n // BVH ray-traced internal transmission with true multi-channel dispersion\r\n vec3 internalTransmission = traceDiamondBVH(localIncident, localNormal, ior, dispersion, rayBounces);\r\n internalTransmission = pow(max(internalTransmission, vec3(0.0)), vec3(max(gamma, 0.01)));\r\n internalTransmission *= rgbBoost * envIntensity;\r\n\r\n float bvhMaxC = max(max(color.r, color.g), color.b);\r\n float bvhMinC = min(min(color.r, color.g), color.b);\r\n float bvhChroma = bvhMaxC - bvhMinC;\r\n float bvhLum = dot(color, vec3(0.299, 0.587, 0.114));\r\n\r\n // External surface reflection:\r\n // For black/dark stones, provide full adamantine luster & ambient reflection so 3D faceting is never lost\r\n // For colored stones, tint specular highlight with gem color to prevent washed out white blowout\r\n vec3 bvhReflTint = (bvhChroma >= 0.05 && bvhLum >= 0.15 && bvhMaxC > 0.001)\r\n ? mix(vec3(1.0), color / bvhMaxC, 0.70)\r\n : vec3(1.0);\r\n float reflScale = (bvhLum < 0.2) ? 1.3 : 0.45;\r\n vec3 surfaceReflection = externalReflection * (fresnel * reflectivity * envIntensity * reflScale) * bvhReflTint;\r\n if (bvhLum < 0.2) {\r\n surfaceReflection += externalReflection * r0 * 0.45;\r\n }\r\n\r\n // Subtle inner facet-edge accents at grazing angles\r\n float innerGlintAngle = 1.0 - cosTheta;\r\n float innerGlint = pow(clamp(innerGlintAngle * 1.4, 0.0, 1.0), 6.0) * 0.35;\r\n vec3 innerGlintColor = externalReflection * bvhReflTint * innerGlint * envIntensity * reflectivity;\r\n\r\n vec3 hdrColor = internalTransmission * (1.0 - fresnel * reflectivity * 0.25)\r\n + surfaceReflection\r\n + innerGlintColor;\r\n\r\n if (transmission > 0.001) {\r\n vec3 directTransmission = refract(incident, worldNormal, 1.0 / ior);\r\n if (length(directTransmission) < 0.001) directTransmission = reflect(incident, worldNormal);\r\n vec3 tColor = clamp(color, vec3(0.005), vec3(1.0));\r\n vec3 sigma2 = -log(tColor) * max(absorption, 0.5);\r\n vec3 directTransBeer = exp(-sigma2 * 0.5);\r\n hdrColor = mix(hdrColor, sampleEnv(directTransmission) * envIntensity * directTransBeer, transmission);\r\n }\r\n\r\n pc_fragColor = vec4(aces(hdrColor), 1.0);\r\n}\r\n`\r\n","import * as THREE from 'three'\r\nimport {\r\n analyzeGeometry,\r\n buildFacetAttribute,\r\n hashGeometry,\r\n type BakeHandle,\r\n type GemAnalysis,\r\n} from './gem-geometry'\r\nimport { DIAMOND_BAKE_VERT, DIAMOND_BAKE_FRAG } from './diamond-shaders'\r\nimport { getOrCreateDiamondBVH } from './diamond-bvh'\r\n\r\nexport type { BakeHandle }\r\n\r\nexport interface CacheEntry {\r\n handle: BakeHandle\r\n renderTarget: THREE.WebGLCubeRenderTarget\r\n refCount: number\r\n disposalTimer: ReturnType<typeof setTimeout> | null\r\n geometryRef: WeakRef<THREE.BufferGeometry>\r\n resolution: 128 | 256 | 512\r\n analysis: GemAnalysis\r\n}\r\n\r\nexport class DiamondNormalBaker {\r\n private cache = new Map<string, CacheEntry>()\r\n\r\n get cacheSize(): number {\r\n return this.cache.size\r\n }\r\n\r\n getEntry(key: string): CacheEntry | undefined {\r\n return this.cache.get(key)\r\n }\r\n\r\n acquire(\r\n g: THREE.BufferGeometry,\r\n renderer: THREE.WebGLRenderer,\r\n opts?: { resolution?: 128 | 256 | 512 }\r\n ): BakeHandle | null {\r\n const analysis = analyzeGeometry(g)\r\n if (!analysis.isBakeable) {\r\n return null\r\n }\r\n\r\n const res: 128 | 256 | 512 = opts?.resolution ?? 256\r\n // Include resolution in cache key so tier changes re-bake at requested resolution\r\n const key = `${hashGeometry(g, analysis)}_${res}`\r\n const existing = this.cache.get(key)\r\n if (existing) {\r\n if (existing.disposalTimer !== null) {\r\n clearTimeout(existing.disposalTimer)\r\n existing.disposalTimer = null\r\n }\r\n existing.refCount++\r\n return existing.handle\r\n }\r\n\r\n return this.bake(g, analysis, key, renderer, res)\r\n }\r\n\r\n private bake(\r\n g: THREE.BufferGeometry,\r\n analysis: GemAnalysis,\r\n key: string,\r\n renderer: THREE.WebGLRenderer,\r\n res: 128 | 256 | 512\r\n ): BakeHandle {\r\n const isUnorm = !renderer.capabilities?.isWebGL2\r\n const renderTarget = new THREE.WebGLCubeRenderTarget(res, {\r\n type: isUnorm ? THREE.UnsignedByteType : THREE.HalfFloatType,\r\n format: THREE.RGBAFormat,\r\n depthBuffer: true,\r\n generateMipmaps: false,\r\n minFilter: THREE.NearestFilter,\r\n magFilter: THREE.NearestFilter,\r\n })\r\n\r\n this.renderToTarget(g, analysis, renderer, renderTarget, isUnorm)\r\n\r\n const handle: BakeHandle = {\r\n key,\r\n texture: renderTarget.texture,\r\n centroid: analysis.centroid.clone(),\r\n radius: analysis.radius,\r\n encoding: isUnorm ? 'unorm' : 'signed',\r\n }\r\n\r\n this.cache.set(key, {\r\n handle,\r\n renderTarget,\r\n refCount: 1,\r\n disposalTimer: null,\r\n geometryRef: new WeakRef(g),\r\n resolution: res,\r\n analysis,\r\n })\r\n\r\n return handle\r\n }\r\n\r\n private renderToTarget(\r\n g: THREE.BufferGeometry,\r\n analysis: GemAnalysis,\r\n renderer: THREE.WebGLRenderer,\r\n renderTarget: THREE.WebGLCubeRenderTarget,\r\n isUnorm: boolean\r\n ): void {\r\n const facetData = buildFacetAttribute(g, analysis)\r\n const bakeGeo = g.getIndex() ? g.toNonIndexed() : g.clone()\r\n bakeGeo.setAttribute('aFacet', new THREE.BufferAttribute(facetData, 4))\r\n\r\n console.log('[DiamondBaker] renderToTarget called', {\r\n isUnorm,\r\n triangleCount: analysis.triangleCount,\r\n centroid: analysis.centroid.toArray(),\r\n radius: analysis.radius,\r\n facetDataLength: facetData.length,\r\n facetSample: Array.from(facetData.slice(0, 8)), // first 2 floats of first 2 vertices\r\n bakeGeoVertexCount: bakeGeo.getAttribute('position').count,\r\n rendererCapabilities: renderer.capabilities?.isWebGL2,\r\n })\r\n\r\n const bakeMat = new THREE.ShaderMaterial({\r\n vertexShader: DIAMOND_BAKE_VERT,\r\n fragmentShader: DIAMOND_BAKE_FRAG,\r\n side: THREE.DoubleSide,\r\n blending: THREE.NoBlending,\r\n transparent: false,\r\n depthTest: true,\r\n depthWrite: true,\r\n toneMapped: false,\r\n defines: isUnorm ? { GEM_NORMALS_UNORM: 1 } : {},\r\n uniforms: {\r\n uCentroid: { value: analysis.centroid },\r\n uRadius: { value: analysis.radius },\r\n },\r\n })\r\n\r\n const scene = new THREE.Scene()\r\n const mesh = new THREE.Mesh(bakeGeo, bakeMat)\r\n scene.add(mesh)\r\n\r\n const near = Math.max(0.001, analysis.radius * 0.001)\r\n const far = Math.max(2.5, analysis.radius * 3.0)\r\n const camera = new THREE.CubeCamera(near, far, renderTarget)\r\n camera.position.copy(analysis.centroid)\r\n\r\n const prevRenderTarget = renderer.getRenderTarget?.() ?? null\r\n const prevAutoClear = renderer.autoClear\r\n const prevToneMapping = renderer.toneMapping\r\n const prevClearColor = new THREE.Color()\r\n if (renderer.getClearColor) {\r\n renderer.getClearColor(prevClearColor)\r\n }\r\n const prevClearAlpha = renderer.getClearAlpha ? renderer.getClearAlpha() : 1\r\n\r\n renderer.toneMapping = THREE.NoToneMapping\r\n renderer.autoClear = true\r\n if (renderer.setClearColor) {\r\n renderer.setClearColor(0x000000, 0)\r\n }\r\n\r\n // Check for pre-existing GL errors if context is available\r\n const gl = renderer.getContext?.()\r\n if (gl) {\r\n const preError = gl.getError()\r\n if (preError !== 0) console.warn('[DiamondBaker] GL error BEFORE camera.update:', preError)\r\n }\r\n\r\n camera.update(renderer, scene)\r\n\r\n // Check for GL errors after the bake render\r\n if (gl) {\r\n const postError = gl.getError()\r\n if (postError !== 0) {\r\n console.error('[DiamondBaker] GL error AFTER camera.update:', postError, '— bake likely failed!')\r\n }\r\n }\r\n\r\n if (renderer.setRenderTarget) {\r\n renderer.setRenderTarget(prevRenderTarget)\r\n }\r\n renderer.autoClear = prevAutoClear\r\n renderer.toneMapping = prevToneMapping\r\n if (renderer.setClearColor) {\r\n renderer.setClearColor(prevClearColor, prevClearAlpha)\r\n }\r\n\r\n bakeGeo.dispose()\r\n bakeMat.dispose()\r\n }\r\n\r\n release(handle: BakeHandle): void {\r\n const entry = this.cache.get(handle.key)\r\n if (!entry) return\r\n\r\n entry.refCount--\r\n if (entry.refCount <= 0) {\r\n entry.refCount = 0\r\n if (entry.disposalTimer !== null) {\r\n clearTimeout(entry.disposalTimer)\r\n }\r\n entry.disposalTimer = setTimeout(() => {\r\n entry.renderTarget.dispose()\r\n this.cache.delete(handle.key)\r\n }, 1000)\r\n }\r\n }\r\n\r\n clearCache(): void {\r\n for (const entry of this.cache.values()) {\r\n if (entry.disposalTimer !== null) {\r\n clearTimeout(entry.disposalTimer)\r\n entry.disposalTimer = null\r\n }\r\n entry.renderTarget.dispose()\r\n }\r\n this.cache.clear()\r\n }\r\n\r\n onContextRestored(renderer: THREE.WebGLRenderer): void {\r\n for (const [key, entry] of this.cache.entries()) {\r\n const geo = entry.geometryRef.deref()\r\n if (!geo) {\r\n if (entry.disposalTimer !== null) {\r\n clearTimeout(entry.disposalTimer)\r\n entry.disposalTimer = null\r\n }\r\n entry.renderTarget.dispose()\r\n this.cache.delete(key)\r\n continue\r\n }\r\n\r\n const isUnorm = !renderer.capabilities?.isWebGL2\r\n entry.renderTarget.dispose()\r\n const newTarget = new THREE.WebGLCubeRenderTarget(entry.resolution, {\r\n type: isUnorm ? THREE.UnsignedByteType : THREE.HalfFloatType,\r\n format: THREE.RGBAFormat,\r\n depthBuffer: true,\r\n generateMipmaps: false,\r\n minFilter: THREE.NearestFilter,\r\n magFilter: THREE.NearestFilter,\r\n })\r\n entry.renderTarget = newTarget\r\n entry.handle.texture = newTarget.texture\r\n entry.handle.encoding = isUnorm ? 'unorm' : 'signed'\r\n\r\n this.renderToTarget(geo, entry.analysis, renderer, newTarget, isUnorm)\r\n }\r\n }\r\n}\r\n\r\nexport const globalDiamondBaker = new DiamondNormalBaker()\r\n","import * as THREE from 'three'\nimport { MeshBVHUniformStruct } from 'three-mesh-bvh'\nimport type { BakeHandle } from './gem-geometry'\nimport { DIAMOND_RAYMARCH_VERT, DIAMOND_RAYMARCH_FRAG } from './diamond-shaders'\nimport type { StonePreset } from './presets'\n\nconst _invMat = new THREE.Matrix4()\n\nexport interface PhysicalModeOptions {\n useCorrectFresnel?: boolean // use cosI (physical) at entry instead of cosT (reference quirk)\n correctDispersionSign?: boolean // iorR=n-delta, iorB=n+delta (physical direction)\n accumulateTIR?: boolean // accumulate TIR contribution at every bounce, not just last\n}\n\nexport class DiamondMaterial extends THREE.ShaderMaterial {\n bakeHandle: BakeHandle\n onBeforeRender: (\n renderer: THREE.WebGLRenderer,\n scene: THREE.Scene,\n camera: THREE.Camera,\n geometry: THREE.BufferGeometry,\n object: THREE.Object3D,\n ) => void\n\n constructor(handle: BakeHandle, envMap: THREE.Texture, preset: StonePreset, physOpts: PhysicalModeOptions = {}) {\n const bvhValue = handle.bvh ?? new MeshBVHUniformStruct()\n\n super({\n vertexShader: DIAMOND_RAYMARCH_VERT,\n fragmentShader: DIAMOND_RAYMARCH_FRAG,\n glslVersion: THREE.GLSL3,\n defines: {\n USE_CUBE_ENV: 1,\n MAX_BOUNCES: 5,\n ...(handle.encoding === 'unorm' ? { GEM_NORMALS_UNORM: 1 } : {}),\n ...(physOpts.useCorrectFresnel ? { USE_CORRECT_FRESNEL: 1 } : {}),\n ...(physOpts.correctDispersionSign ? { CORRECT_DISPERSION_SIGN: 1 } : {}),\n ...(physOpts.accumulateTIR ? { ACCUMULATE_TIR: 1 } : {}),\n },\n uniforms: {\n bvh: { value: bvhValue },\n envMap: { value: envMap },\n envRotationMatrix: { value: new THREE.Matrix3() },\n cameraPos: { value: new THREE.Vector3() },\n ior: { value: preset.ior ?? 2.417 },\n dispersion: { value: preset.dispersion ?? 0.012 },\n absorption: { value: 1.0 + (preset.absorptionFactor ?? 0.0) * 2.0 },\n envIntensity: { value: preset.envMapIntensity ?? 2.2 },\n gamma: { value: 1.0 },\n color: { value: new THREE.Color(preset.hex) },\n rgbBoost: { value: new THREE.Vector3(...(preset.boostFactors ?? [1.3, 1.3, 1.3])) },\n transmission: { value: 0.0 },\n reflectivity: { value: 0.46 },\n facetSharpness: { value: 1.0 },\n rayBounces: { value: 8 }, // More bounces for richer internal facet patterns\n\n // Retain previous uniforms for tests and compatibility:\n tCubeMapNormals: { value: handle.texture },\n uEnvFlip: { value: (envMap as any)?.isRenderTargetTexture ? 1.0 : -1.0 },\n uCentroid: { value: handle.centroid ? handle.centroid.clone() : new THREE.Vector3() },\n uRadius: { value: handle.radius ?? 1.0 },\n uCamLocal: { value: new THREE.Vector3() },\n refractiveIndex: { value: preset.ior ?? 2.417 },\n rIndexDelta: { value: preset.dispersion ?? 0.012 },\n absorptionFactor: { value: preset.absorptionFactor ?? 0.0 },\n gemColor: { value: new THREE.Color(preset.hex) },\n uExhaustionResidual: { value: 0.5 },\n bounces: { value: 5 },\n uSplitBounces: { value: 2 },\n uDebugMode: { value: 0 },\n },\n side: THREE.FrontSide,\n transparent: false,\n depthTest: true,\n depthWrite: true,\n toneMapped: true,\n extensions: {\n derivatives: true,\n },\n })\n\n this.bakeHandle = handle\n\n this.onBeforeRender = (_renderer, _scene, camera, _geometry, object) => {\n ;(this.uniforms.cameraPos.value as THREE.Vector3).copy(camera.position)\n _invMat.copy(object.matrixWorld).invert()\n ;(this.uniforms.uCamLocal.value as THREE.Vector3).copy(camera.position).applyMatrix4(_invMat)\n }\n }\n\n updatePreset(preset: StonePreset): void {\n if (this.uniforms.color) {\n ;(this.uniforms.color.value as THREE.Color).set(preset.hex)\n }\n if (this.uniforms.gemColor) {\n ;(this.uniforms.gemColor.value as THREE.Color).set(preset.hex)\n }\n if (this.uniforms.ior) {\n this.uniforms.ior.value = preset.ior ?? 2.417\n }\n if (this.uniforms.refractiveIndex) {\n this.uniforms.refractiveIndex.value = preset.ior ?? 2.417\n }\n if (this.uniforms.dispersion) {\n this.uniforms.dispersion.value = preset.dispersion ?? 0.012\n }\n if (this.uniforms.rIndexDelta) {\n this.uniforms.rIndexDelta.value = preset.dispersion ?? 0.012\n }\n if (this.uniforms.absorption) {\n this.uniforms.absorption.value = 1.0 + (preset.absorptionFactor ?? 0.0) * 2.0\n }\n if (this.uniforms.absorptionFactor) {\n this.uniforms.absorptionFactor.value = preset.absorptionFactor ?? 0.0\n }\n if (this.uniforms.rgbBoost) {\n const [r, g, b] = preset.boostFactors ?? [2.0, 2.0, 2.0]\n ;(this.uniforms.rgbBoost.value as THREE.Vector3).set(r, g, b)\n }\n this.uniformsNeedUpdate = true\n }\n}\n\ninterface CacheEntry {\n material: DiamondMaterial\n refCount: number\n}\n\nconst materialCache = new Map<string, CacheEntry>()\n\nexport function acquireDiamondMaterial(\n handle: BakeHandle,\n envMap: THREE.Texture,\n preset: StonePreset,\n physOpts: PhysicalModeOptions = {},\n): DiamondMaterial {\n const optSuffix = `${physOpts.useCorrectFresnel ? '_cf' : ''}${physOpts.correctDispersionSign ? '_cd' : ''}${physOpts.accumulateTIR ? '_at' : ''}`\n const key = `${handle.key}_${preset.id}_${preset.hex}${optSuffix}`\n const existing = materialCache.get(key)\n if (existing) {\n existing.refCount++\n return existing.material\n }\n\n const material = new DiamondMaterial(handle, envMap, preset, physOpts)\n materialCache.set(key, { material, refCount: 1 })\n return material\n}\n\nexport function releaseDiamondMaterial(mat: DiamondMaterial): void {\n for (const [key, entry] of materialCache.entries()) {\n if (entry.material === mat) {\n entry.refCount--\n if (entry.refCount <= 0) {\n mat.dispose()\n materialCache.delete(key)\n }\n return\n }\n }\n}\n\nexport function getDiamondMaterialCacheSize(): number {\n return materialCache.size\n}\n\nexport function clearDiamondMaterialCache(): void {\n for (const entry of materialCache.values()) {\n entry.material.dispose()\n }\n materialCache.clear()\n}\n","import * as THREE from 'three'\r\nimport { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js'\r\n\r\n/**\r\n * Procedural luxury jewelry photography light tent environment.\r\n * Generates a complete 360° studio lighting dome with an overhead softbox,\r\n * bilateral key/fill light panels, linear rim highlight strips, bottom reflector,\r\n * and subtle dark contrast flags for crisp metallic edge definition.\r\n */\r\nexport class JewelryStudioEnvironment extends THREE.Scene {\r\n constructor() {\r\n super()\r\n\r\n // 1. Studio Light Tent Dome:\r\n // Bright studio diffuser enclosure providing high-key ambient light so metallic bodies retain\r\n // their true, rich, saturated color while softbox panels provide specular gleam.\r\n const domeGeo = new THREE.SphereGeometry(30, 32, 16)\r\n const domeMat = new THREE.MeshBasicMaterial({\r\n color: 0x9098a6,\r\n side: THREE.BackSide,\r\n })\r\n const dome = new THREE.Mesh(domeGeo, domeMat)\r\n this.add(dome)\r\n\r\n // 2. Overhead Key Softbox:\r\n // Large diffuser panel directly above illuminating gemstone tables and ring crowns.\r\n const topGeo = new THREE.PlaneGeometry(16, 16)\r\n const topMat = new THREE.MeshBasicMaterial({\r\n color: 0xffffff,\r\n side: THREE.DoubleSide,\r\n })\r\n topMat.color.setScalar(4.0) // Brilliant catchlight\r\n const topPanel = new THREE.Mesh(topGeo, topMat)\r\n topPanel.position.set(0, 14, 0)\r\n topPanel.rotation.x = Math.PI / 2\r\n this.add(topPanel)\r\n\r\n // 3. Front-Left Key Softbox:\r\n // High-radiance softbox casting broad, soft highlights across the left shanks and facets.\r\n const leftSoftboxGeo = new THREE.PlaneGeometry(12, 16)\r\n const leftSoftboxMat = new THREE.MeshBasicMaterial({\r\n color: 0xffffff,\r\n side: THREE.DoubleSide,\r\n })\r\n leftSoftboxMat.color.setScalar(3.0)\r\n const leftSoftbox = new THREE.Mesh(leftSoftboxGeo, leftSoftboxMat)\r\n leftSoftbox.position.set(-10, 8, 10)\r\n leftSoftbox.lookAt(0, 0, 0)\r\n this.add(leftSoftbox)\r\n\r\n // 4. Front-Right Fill Softbox:\r\n // Balanced fill softbox preventing harsh asymmetric falloff on right surfaces.\r\n const rightSoftboxGeo = new THREE.PlaneGeometry(12, 16)\r\n const rightSoftboxMat = new THREE.MeshBasicMaterial({\r\n color: 0xffffff,\r\n side: THREE.DoubleSide,\r\n })\r\n rightSoftboxMat.color.setScalar(2.8)\r\n const rightSoftbox = new THREE.Mesh(rightSoftboxGeo, rightSoftboxMat)\r\n rightSoftbox.position.set(10, 8, 10)\r\n rightSoftbox.lookAt(0, 0, 0)\r\n this.add(rightSoftbox)\r\n\r\n // 5. Bilateral Rim Glint Strips:\r\n // Narrow vertical light panels creating signature sleek, razor-sharp specular streaks\r\n // along the outer polished curvature of the shank.\r\n const rimGeo = new THREE.PlaneGeometry(2, 22)\r\n const rimMat = new THREE.MeshBasicMaterial({\r\n color: 0xffffff,\r\n side: THREE.DoubleSide,\r\n })\r\n rimMat.color.setScalar(4.5)\r\n\r\n const leftRim = new THREE.Mesh(rimGeo, rimMat)\r\n leftRim.position.set(-14, 2, -2)\r\n leftRim.lookAt(0, 0, 0)\r\n this.add(leftRim)\r\n\r\n const rightRim = new THREE.Mesh(rimGeo, rimMat)\r\n rightRim.position.set(14, 2, -2)\r\n rightRim.lookAt(0, 0, 0)\r\n this.add(rightRim)\r\n\r\n // 6. Ground Bounce Reflector:\r\n // Upward-facing reflector preventing under-prongs and bottom band from going dark.\r\n const groundGeo = new THREE.PlaneGeometry(24, 24)\r\n const groundMat = new THREE.MeshBasicMaterial({\r\n color: 0xf5f7fa,\r\n side: THREE.DoubleSide,\r\n })\r\n groundMat.color.setScalar(1.2)\r\n const ground = new THREE.Mesh(groundGeo, groundMat)\r\n ground.position.set(0, -12, 0)\r\n ground.rotation.x = -Math.PI / 2\r\n this.add(ground)\r\n\r\n // 7. Dark Contrast Accent Flags (Studio Black Cards):\r\n // In professional photography, narrow black cards create crisp reflection horizon lines,\r\n // giving precious metals physical depth, liquid sheen, and facet definition without flat wash.\r\n const flagGeo = new THREE.PlaneGeometry(1.2, 16)\r\n const flagMat = new THREE.MeshBasicMaterial({\r\n color: 0x121216,\r\n side: THREE.DoubleSide,\r\n })\r\n const leftFlag = new THREE.Mesh(flagGeo, flagMat)\r\n leftFlag.position.set(-5, 4, -9)\r\n leftFlag.lookAt(0, 0, 0)\r\n this.add(leftFlag)\r\n\r\n const rightFlag = new THREE.Mesh(flagGeo, flagMat)\r\n rightFlag.position.set(5, 4, -9)\r\n rightFlag.lookAt(0, 0, 0)\r\n this.add(rightFlag)\r\n }\r\n\r\n dispose(): void {\r\n const resources = new Set<THREE.BufferGeometry | THREE.Material>()\r\n this.traverse((obj) => {\r\n if (obj instanceof THREE.Mesh) {\r\n if (obj.geometry) resources.add(obj.geometry)\r\n if (obj.material) {\r\n if (Array.isArray(obj.material)) {\r\n obj.material.forEach((m) => resources.add(m))\r\n } else {\r\n resources.add(obj.material)\r\n }\r\n }\r\n }\r\n })\r\n for (const res of resources) {\r\n res.dispose()\r\n }\r\n this.clear()\r\n }\r\n}\r\n\r\n/**\r\n * Generates a JewelryStudioEnvironment PMREMTexture and sets it on the scene.\r\n * Call once after WebGLRenderer is created.\r\n */\r\nexport function setupEnvironment(\r\n scene: THREE.Scene,\r\n renderer: THREE.WebGLRenderer,\r\n): THREE.Texture {\r\n const pmremGenerator = new THREE.PMREMGenerator(renderer)\r\n pmremGenerator.compileEquirectangularShader()\r\n\r\n const studioEnv = new JewelryStudioEnvironment()\r\n const env = pmremGenerator.fromScene(studioEnv).texture\r\n scene.environment = env\r\n studioEnv.dispose()\r\n pmremGenerator.dispose()\r\n\r\n return env\r\n}\r\n\r\n/**\r\n * Procedural gem lighting environment dome.\r\n * Generates an enclosing dark dome with 7 high-radiance pinpoint emitter panels\r\n * optimized for multi-bounce total internal reflection and scintillation in gemstones.\r\n */\r\nexport class JewelryGemEnvironment extends THREE.Scene {\r\n constructor() {\r\n super()\r\n\r\n // 1. Studio Photography Tent Dome:\r\n // Soft photography diffuser enclosure providing realistic white/silver ambient fill\r\n // so diamond facets reflect bright, clean light with crisp contrast.\r\n const domeGeo = new THREE.SphereGeometry(30, 32, 16)\r\n const domeMat = new THREE.MeshBasicMaterial({\r\n color: 0xa0a8b5,\r\n side: THREE.BackSide,\r\n })\r\n const dome = new THREE.Mesh(domeGeo, domeMat)\r\n this.add(dome)\r\n\r\n // 2. Baffled Overhead Softbox Array (arranged around zenith, NOT directly on zenith):\r\n // Positioned at 40°-50° angles around the zenith to illuminate the crown facets and pump light\r\n // into the pavilion without placing a blinding direct glare on the flat table facet.\r\n const upperSoftboxes: Array<{ pos: [number, number, number]; size: [number, number]; intensity: number }> = [\r\n { pos: [0, 15, 8], size: [10, 8], intensity: 4.5 }, // Front-top key\r\n { pos: [0, 15, -8], size: [10, 8], intensity: 4.0 }, // Back-top rim\r\n { pos: [-9, 14, 0], size: [8, 10], intensity: 4.0 }, // Left-top fill\r\n { pos: [9, 14, 0], size: [8, 10], intensity: 4.0 }, // Right-top fill\r\n ]\r\n\r\n for (const p of upperSoftboxes) {\r\n const geo = new THREE.PlaneGeometry(p.size[0], p.size[1])\r\n const mat = new THREE.MeshBasicMaterial({ color: 0xffffff, side: THREE.DoubleSide })\r\n mat.color.setScalar(p.intensity)\r\n const mesh = new THREE.Mesh(geo, mat)\r\n mesh.position.set(p.pos[0], p.pos[1], p.pos[2])\r\n mesh.lookAt(0, 0, 0)\r\n this.add(mesh)\r\n }\r\n\r\n // 3. Lateral Wing Softboxes (Profile & Pavé/Side Stone Illumination):\r\n const lateralSoftboxes: Array<{ pos: [number, number, number]; size: [number, number]; intensity: number }> = [\r\n { pos: [-13, 8, 6], size: [8, 9], intensity: 3.5 },\r\n { pos: [13, 8, 6], size: [8, 9], intensity: 3.5 },\r\n { pos: [0, 8, 14], size: [10, 7], intensity: 3.8 },\r\n { pos: [0, 8, -14], size: [10, 7], intensity: 3.2 },\r\n ]\r\n\r\n for (const p of lateralSoftboxes) {\r\n const geo = new THREE.PlaneGeometry(p.size[0], p.size[1])\r\n const mat = new THREE.MeshBasicMaterial({ color: 0xffffff, side: THREE.DoubleSide })\r\n mat.color.setScalar(p.intensity)\r\n const mesh = new THREE.Mesh(geo, mat)\r\n mesh.position.set(p.pos[0], p.pos[1], p.pos[2])\r\n mesh.lookAt(0, 0, 0)\r\n this.add(mesh)\r\n }\r\n\r\n // 4. Center Zenith Camera Body Baffle:\r\n // Simulates the camera card overhead for contrast definition without a black void.\r\n const zenithBaffleGeo = new THREE.PlaneGeometry(5.0, 5.0)\r\n const zenithBaffleMat = new THREE.MeshBasicMaterial({\r\n color: 0x404550,\r\n side: THREE.DoubleSide,\r\n })\r\n const zenithBaffle = new THREE.Mesh(zenithBaffleGeo, zenithBaffleMat)\r\n zenithBaffle.position.set(0, 18, 0)\r\n zenithBaffle.rotation.x = Math.PI / 2\r\n this.add(zenithBaffle)\r\n\r\n // 5. Ground Plane:\r\n // Studio ground bounce preventing downward rays from turning black.\r\n const groundGeo = new THREE.PlaneGeometry(24, 24)\r\n const groundMat = new THREE.MeshBasicMaterial({\r\n color: 0x505662,\r\n side: THREE.DoubleSide,\r\n })\r\n const ground = new THREE.Mesh(groundGeo, groundMat)\r\n ground.position.set(0, -12, 0)\r\n ground.rotation.x = -Math.PI / 2\r\n this.add(ground)\r\n\r\n // 6. Geometric Contrast Flags (Soft charcoal cards for subtle facet definition without pitch-black triangles):\r\n const flagGeo = new THREE.PlaneGeometry(1.4, 15)\r\n const flagMat = new THREE.MeshBasicMaterial({\r\n color: 0x383e4a,\r\n side: THREE.DoubleSide,\r\n })\r\n const flagPositions: [number, number, number][] = [\r\n [7, 11, 7],\r\n [-7, 11, 7],\r\n [7, 11, -7],\r\n [-7, 11, -7],\r\n ]\r\n for (const [fx, fy, fz] of flagPositions) {\r\n const flag = new THREE.Mesh(flagGeo, flagMat)\r\n flag.position.set(fx, fy, fz)\r\n flag.lookAt(0, 0, 0)\r\n this.add(flag)\r\n }\r\n\r\n // 7. 10 High-Radiance Pinpoint Emitter Panels for Dispersion Fire & Scintillation:\r\n const emitterPositions: [number, number, number][] = [\r\n [10, 13, 7],\r\n [-10, 13, 7],\r\n [10, 13, -7],\r\n [-10, 13, -7],\r\n [14, 6, 9],\r\n [-14, 6, 9],\r\n [14, 6, -9],\r\n [-14, 6, -9],\r\n [0, 6, 17],\r\n [7, -6, 8],\r\n ]\r\n\r\n for (const [x, y, z] of emitterPositions) {\r\n const panelGeo = new THREE.PlaneGeometry(2.6, 2.6)\r\n const panelMat = new THREE.MeshBasicMaterial({\r\n color: 0xffffff,\r\n side: THREE.DoubleSide,\r\n })\r\n panelMat.color.setScalar(45.0)\r\n const panel = new THREE.Mesh(panelGeo, panelMat)\r\n panel.position.set(x, y, z)\r\n panel.lookAt(0, 0, 0)\r\n this.add(panel)\r\n }\r\n }\r\n\r\n dispose(): void {\r\n const resources = new Set<THREE.BufferGeometry | THREE.Material>()\r\n this.traverse((obj) => {\r\n if (obj instanceof THREE.Mesh) {\r\n if (obj.geometry) resources.add(obj.geometry)\r\n if (obj.material) {\r\n if (Array.isArray(obj.material)) {\r\n obj.material.forEach((m) => resources.add(m))\r\n } else {\r\n resources.add(obj.material)\r\n }\r\n }\r\n }\r\n })\r\n for (const res of resources) {\r\n res.dispose()\r\n }\r\n this.clear()\r\n }\r\n}\r\n\r\n/**\r\n * Generates high-radiance gem HDR cubemap texture via CubeCamera.\r\n */\r\nexport function setupGemEnvironment(\r\n renderer: THREE.WebGLRenderer,\r\n source?: THREE.Scene,\r\n size = 512,\r\n): THREE.Texture {\r\n const cubeTarget = new THREE.WebGLCubeRenderTarget(size, {\r\n format: THREE.RGBAFormat,\r\n type: THREE.HalfFloatType,\r\n generateMipmaps: false,\r\n minFilter: THREE.LinearFilter,\r\n magFilter: THREE.LinearFilter,\r\n })\r\n\r\n const cubeCamera = new THREE.CubeCamera(0.1, 100, cubeTarget)\r\n const gemEnv = source ?? new JewelryGemEnvironment()\r\n\r\n const prevTarget = renderer?.getRenderTarget ? renderer.getRenderTarget() : null\r\n\r\n cubeCamera.update(renderer, gemEnv)\r\n\r\n if (renderer?.setRenderTarget) {\r\n renderer.setRenderTarget(prevTarget)\r\n }\r\n\r\n if (!source && gemEnv instanceof JewelryGemEnvironment) {\r\n gemEnv.dispose()\r\n }\r\n\r\n return cubeTarget.texture\r\n}\r\n\r\nimport { EXRLoader } from 'three/examples/jsm/loaders/EXRLoader.js'\r\n\r\nexport interface HdrEnvironmentHandle {\r\n renderTarget: THREE.WebGLRenderTarget\r\n texture: THREE.Texture\r\n gemRenderTarget?: THREE.WebGLCubeRenderTarget\r\n gemTexture?: THREE.Texture\r\n dispose: () => void\r\n}\r\n\r\n/**\r\n * Loads an HDR or EXR equirectangular environment and converts it to:\r\n * 1. A PMREM-filtered texture for scene.environment (PBR metals)\r\n * 2. A true WebGLCubeRenderTarget cubemap for DiamondMaterial\r\n */\r\nexport async function loadHdrEnvironment(\r\n urlOrData: string | ArrayBuffer,\r\n renderer: THREE.WebGLRenderer,\r\n): Promise<HdrEnvironmentHandle> {\r\n const pmremGenerator = new THREE.PMREMGenerator(renderer)\r\n pmremGenerator.compileEquirectangularShader()\r\n\r\n function processDataTexture(dataTexture: THREE.DataTexture): HdrEnvironmentHandle {\r\n const renderTarget = pmremGenerator.fromEquirectangular(dataTexture)\r\n let gemRenderTarget: THREE.WebGLCubeRenderTarget | undefined\r\n try {\r\n gemRenderTarget = new THREE.WebGLCubeRenderTarget(512, {\r\n format: THREE.RGBAFormat,\r\n type: THREE.HalfFloatType,\r\n generateMipmaps: true,\r\n minFilter: THREE.LinearMipmapLinearFilter,\r\n magFilter: THREE.LinearFilter,\r\n })\r\n gemRenderTarget.fromEquirectangularTexture(renderer, dataTexture)\r\n } catch {\r\n // Graceful fallback for mock environments or tests\r\n }\r\n dataTexture.dispose()\r\n pmremGenerator.dispose()\r\n\r\n return {\r\n renderTarget,\r\n texture: renderTarget.texture,\r\n gemRenderTarget,\r\n gemTexture: gemRenderTarget ? gemRenderTarget.texture : renderTarget.texture,\r\n dispose: () => {\r\n renderTarget.dispose()\r\n gemRenderTarget?.dispose()\r\n },\r\n }\r\n }\r\n\r\n const isExr = typeof urlOrData === 'string'\r\n ? urlOrData.toLowerCase().includes('.exr')\r\n : (urlOrData instanceof ArrayBuffer && urlOrData.byteLength >= 4 &&\r\n new Uint8Array(urlOrData, 0, 4)[0] === 0x76 &&\r\n new Uint8Array(urlOrData, 0, 4)[1] === 0x2f)\r\n\r\n if (urlOrData instanceof ArrayBuffer) {\r\n try {\r\n if (isExr) {\r\n const res = new EXRLoader().parse(urlOrData)\r\n const dataTex = new THREE.DataTexture(res.data, res.width, res.height, res.format, res.type)\r\n dataTex.needsUpdate = true\r\n return processDataTexture(dataTex)\r\n } else {\r\n const dataTexture = new RGBELoader().parse(urlOrData) as unknown as THREE.DataTexture\r\n return processDataTexture(dataTexture)\r\n }\r\n } catch (err) {\r\n pmremGenerator.dispose()\r\n throw err\r\n }\r\n }\r\n\r\n return new Promise<HdrEnvironmentHandle>((resolve, reject) => {\r\n if (isExr) {\r\n new EXRLoader().load(\r\n urlOrData,\r\n (dataTex) => {\r\n try {\r\n resolve(processDataTexture(dataTex as unknown as THREE.DataTexture))\r\n } catch (err) {\r\n dataTex.dispose()\r\n pmremGenerator.dispose()\r\n reject(err)\r\n }\r\n },\r\n undefined,\r\n (err) => {\r\n pmremGenerator.dispose()\r\n reject(err)\r\n },\r\n )\r\n } else {\r\n new RGBELoader().load(\r\n urlOrData,\r\n (hdrTexture) => {\r\n try {\r\n resolve(processDataTexture(hdrTexture as unknown as THREE.DataTexture))\r\n } catch (err) {\r\n hdrTexture.dispose()\r\n pmremGenerator.dispose()\r\n reject(err)\r\n }\r\n },\r\n undefined,\r\n (err) => {\r\n pmremGenerator.dispose()\r\n reject(err)\r\n },\r\n )\r\n }\r\n })\r\n}\r\n\r\n\r\n","import * as THREE from 'three'\nimport { MeshBVH, MeshBVHUniformStruct, SAH } from 'three-mesh-bvh'\n\nconst bvhCache = new WeakMap<THREE.BufferGeometry, MeshBVHUniformStruct>()\n\n/**\n * Builds or retrieves the GPU MeshBVH acceleration structure for a diamond geometry.\n * Handles geometries with multi-groups gracefully by ensuring a single-root tree.\n */\nexport function getOrCreateDiamondBVH(geometry: THREE.BufferGeometry): MeshBVHUniformStruct {\n const cached = bvhCache.get(geometry)\n if (cached) return cached\n\n let targetGeom = geometry\n if (geometry.groups && geometry.groups.length > 1) {\n targetGeom = geometry.clone()\n targetGeom.clearGroups()\n }\n\n const boundsTree = (targetGeom as any).boundsTree ?? new MeshBVH(targetGeom, {\n strategy: SAH,\n setBoundingBox: false,\n })\n ;(targetGeom as any).boundsTree = boundsTree\n\n const bvhStruct = new MeshBVHUniformStruct()\n bvhStruct.updateFrom(boundsTree)\n\n bvhCache.set(geometry, bvhStruct)\n return bvhStruct\n}\n","import * as THREE from 'three'\nimport type { StonePreset } from './presets'\nimport { DiamondMaterial, acquireDiamondMaterial } from './diamond-material'\nimport type { BakeHandle } from './gem-geometry'\n\nexport interface PmatJson {\n type: string\n name?: string\n color: number | string\n roughness: number\n metalness: number\n clearcoat?: number\n clearcoatRoughness?: number\n sheen?: number\n sheenColor?: number | string\n sheenRoughness?: number\n specularIntensity?: number\n specularColor?: number | string\n iridescence?: number\n iridescenceIOR?: number\n anisotropy?: number\n envMapIntensity?: number\n reflectivity?: number\n transmission?: number\n thickness?: number\n attenuationDistance?: number\n attenuationColor?: number | string\n side?: number\n [key: string]: unknown\n}\n\nexport interface DmatJson {\n type: string\n name?: string\n color: number | string\n refractiveIndex?: number\n dispersion?: number\n rayBounces?: number\n squashFactor?: number\n geometryFactor?: number\n gammaFactor?: number\n absorptionFactor?: number\n reflectivity?: number\n envMapIntensity?: number\n boostFactors?: { x: number; y: number; z: number; isVector3?: boolean }\n transmission?: number\n [key: string]: unknown\n}\n\nfunction parseJson<T>(input: string | T): T {\n if (typeof input === 'string') {\n return JSON.parse(input) as T\n }\n return input\n}\n\nfunction toColorHex(value: number | string): string {\n if (typeof value === 'string') {\n return value.startsWith('#') ? value : `#${value}`\n }\n return '#' + (value >>> 0).toString(16).padStart(6, '0')\n}\n\n/**\n * Parses a RenderMyJewelry .pmat JSON export into a Three.js MeshPhysicalMaterial.\n */\nexport function loadPmat(input: string | PmatJson): THREE.MeshPhysicalMaterial {\n const json = parseJson<PmatJson>(input)\n\n const side = json.side === 2\n ? THREE.DoubleSide\n : json.side === 1\n ? THREE.BackSide\n : THREE.FrontSide\n\n const mat = new THREE.MeshPhysicalMaterial({\n name: json.name ?? 'pmat-metal',\n color: new THREE.Color(toColorHex(json.color)),\n roughness: json.roughness ?? 0.0,\n metalness: json.metalness ?? 1.0,\n envMapIntensity: json.envMapIntensity ?? 1.0,\n clearcoat: json.clearcoat ?? 0.0,\n clearcoatRoughness: json.clearcoatRoughness ?? 0.0,\n side,\n })\n\n if (json.specularColor !== undefined) {\n mat.specularColor = new THREE.Color(toColorHex(json.specularColor))\n }\n if (json.specularIntensity !== undefined) {\n mat.specularIntensity = json.specularIntensity\n }\n if (json.reflectivity !== undefined) {\n mat.reflectivity = json.reflectivity\n }\n\n return mat\n}\n\n/**\n * Parses a RenderMyJewelry .dmat JSON export into a calibrated StonePreset object.\n */\nexport function loadDmatPreset(input: string | DmatJson): StonePreset {\n const json = parseJson<DmatJson>(input)\n const hex = toColorHex(json.color ?? 0xffffff)\n const bf = json.boostFactors ?? { x: 1, y: 1, z: 1 }\n\n return {\n id: json.name ? `dmat-${json.name.toLowerCase().replace(/\\s+/g, '-')}` : 'dmat-custom',\n label: json.name ?? 'Custom Diamond',\n hex,\n ior: json.refractiveIndex ?? 2.6,\n dispersion: json.dispersion ?? 0.01,\n absorptionFactor: json.absorptionFactor ?? 0.0,\n roughness: 0.0,\n transmission: json.transmission ?? 0.0,\n boostFactors: [bf.x, bf.y, bf.z],\n category: 'diamond',\n ...(json.squashFactor !== undefined ? { squashFactor: json.squashFactor } : {}),\n ...(json.geometryFactor !== undefined ? { geometryFactor: json.geometryFactor } : {}),\n ...(json.gammaFactor !== undefined ? { gammaFactor: json.gammaFactor } : {}),\n }\n}\n\n/**\n * Instantiates or acquires a DiamondMaterial from a .dmat JSON definition.\n */\nexport function loadDmatMaterial(\n input: string | DmatJson,\n handle: BakeHandle,\n envMap: THREE.Texture,\n): DiamondMaterial {\n const preset = loadDmatPreset(input)\n return acquireDiamondMaterial(handle, envMap, preset)\n}\n","/**\r\n * diamond-reference-shaders.ts\r\n *\r\n * Clean-room GLSL 3.00 es shaders for ReferenceDiamondMaterial.\r\n * Algorithm derived from DIAMOND_PLAN.md §3.2 pseudocode.\r\n * BRDF: Lazarov/Karis, Siggraph 2014 \"Getting More Physical in Call of Duty\".\r\n * DO NOT incorporate text from rendermyjewelry_research/shaders/diamond.frag.glsl.\r\n */\r\n\r\nexport const DIAMOND_REF_VERT = /* glsl */ `\r\nprecision highp float;\r\n\r\nout vec3 vWorldNormal;\r\nout vec3 vWorldPosition;\r\n\r\nvoid main() {\r\n vec4 worldPos = modelMatrix * vec4(position, 1.0);\r\n vWorldPosition = worldPos.xyz;\r\n vWorldNormal = normalize(mat3(modelMatrix) * normal);\r\n gl_Position = projectionMatrix * viewMatrix * worldPos;\r\n}\r\n`\r\n\r\n// Compile-time defines injected by ReferenceDiamondMaterial:\r\n// RAY_BOUNCES — int (3/5/6/8)\r\n// ENV_MAP_TYPE — 0=samplerCube, 1=sampler2D equirect\r\n// DIA_ORIENT_ENVMAP — 0=apply modelOffset, 1=skip\r\n// HAS_GEM_INCLUSIONS — 0 (MVP always 0)\r\n// GEM_NORMALS_UNORM — 0=signed HalfFloat, 1=unorm 8-bit\r\n\r\nexport const DIAMOND_REF_FRAG = /* glsl */ `\r\nprecision highp float;\r\nprecision highp sampler2D;\r\nprecision highp samplerCube;\r\n\r\nuniform mat4 modelOffsetMatrix;\r\nuniform mat4 modelOffsetMatrixInv;\r\nuniform mat4 viewMatrixUniform;\r\n\r\nuniform samplerCube tCubeMapNormals;\r\nuniform float radius;\r\nuniform vec3 centerOffset;\r\n\r\n#if ENV_MAP_TYPE == 0\r\n uniform samplerCube envMap;\r\n#else\r\n uniform sampler2D envMap;\r\n#endif\r\nuniform float envMapRotation;\r\nuniform float envMapIntensity;\r\n\r\nuniform float refractiveIndex;\r\nuniform float rIndexDelta;\r\nuniform float absorptionFactor;\r\nuniform float squashFactor;\r\nuniform float geometryFactor;\r\nuniform float gammaFactor;\r\nuniform float ambientFloor;\r\nuniform float reflectivity;\r\nuniform vec3 boostFactors;\r\nuniform vec3 color;\r\nuniform vec3 colorCorrection;\r\nuniform float transmission;\r\nuniform bool clampHDR;\r\nuniform bool useInclusion;\r\n\r\nin vec3 vWorldNormal;\r\nin vec3 vWorldPosition;\r\nout vec4 fragColor;\r\n\r\n// Lazarov/Karis 2014 BRDF (Siggraph, published constants — safe to reproduce)\r\nvec3 brdfGGXEnv(vec3 viewDir, vec3 normal, vec3 f0, float roughness) {\r\n float dotNV = abs(dot(normal, viewDir));\r\n vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);\r\n vec4 c1 = vec4( 1.0, 0.0425, 1.04, -0.04);\r\n vec4 r = roughness * c0 + c1;\r\n float a004 = min(r.x * r.x, exp2(-9.28 * dotNV)) * r.x + r.y;\r\n vec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;\r\n return f0 * AB.x + AB.y;\r\n}\r\n\r\nvec3 rotateY(vec3 d, float a) {\r\n float c = cos(a), s = sin(a);\r\n return vec3(c*d.x + s*d.z, d.y, -s*d.x + c*d.z);\r\n}\r\n\r\nvec4 sampleEnvMap(vec3 dir, float roughness) {\r\n dir = rotateY(dir, envMapRotation);\r\n dir = -dir; // full negate per reference algorithm (DIAMOND_PLAN §3.4 step 6)\r\n#if ENV_MAP_TYPE == 0\r\n return envMapIntensity * textureLod(envMap, dir, roughness * 8.0);\r\n#else\r\n float u = atan(dir.z, dir.x) / (2.0 * 3.14159265) + 0.5;\r\n float v = asin(clamp(dir.y, -1.0, 1.0)) / 3.14159265 + 0.5;\r\n return envMapIntensity * textureLod(envMap, vec2(u, v), roughness * 8.0);\r\n#endif\r\n}\r\n\r\n// Internal bounce: apply modelOffset + view-space + xz-flip (DIAMOND_PLAN §3.4)\r\nvec4 sampleInternalEnv(vec3 dir, float roughness) {\r\n#if DIA_ORIENT_ENVMAP < 1\r\n dir = mat3(modelOffsetMatrix) * dir;\r\n#endif\r\n dir = (viewMatrixUniform * vec4(dir, 0.0)).xyz;\r\n dir = normalize(dir);\r\n dir.x *= -1.0;\r\n dir.z *= -1.0;\r\n vec4 sharpLight = sampleEnvMap(dir, roughness);\r\n if (ambientFloor > 0.0) {\r\n vec4 diffuseLight = sampleEnvMap(dir, 0.85);\r\n return max(sharpLight, diffuseLight * ambientFloor);\r\n }\r\n return sharpLight;\r\n}\r\n\r\n// Front surface: only viewMatrix (DIAMOND_PLAN §10.6)\r\nvec4 sampleFrontEnv(vec3 dir, float roughness) {\r\n dir = (viewMatrixUniform * vec4(dir, 0.0)).xyz;\r\n return sampleEnvMap(dir, roughness);\r\n}\r\n\r\n// Line-plane intersection with divide-by-zero guard (DIAMOND_PLAN §10.1)\r\nvec3 linePlaneIntersect(vec3 p, vec3 d, vec3 pp, vec3 pn) {\r\n float denom = dot(pn, d);\r\n if (abs(denom) < 1e-6) return p; // ray parallel to plane\r\n return p + d * (dot(pn, pp - p) / denom);\r\n}\r\n\r\n// Sphere intersect with squash and sphere-miss guard (DIAMOND_PLAN §2.2, §6)\r\n// Returns vec3(0) on miss — caller checks length < 1e-6\r\nvec3 intersectSphere(vec3 origin, vec3 dir) {\r\n vec3 o = origin - centerOffset;\r\n float savedY = dir.y;\r\n dir.y /= squashFactor;\r\n float A = dot(dir, dir);\r\n float B = 2.0 * dot(o, dir);\r\n float C = dot(o, o) - radius * radius;\r\n float disc = B*B - 4.0*A*C;\r\n if (disc <= 0.0) return vec3(0.0); // miss\r\n float sqrtDisc = sqrt(disc);\r\n float t = max((-B + sqrtDisc) * geometryFactor / A,\r\n (-B - sqrtDisc) * geometryFactor / A);\r\n dir.y = savedY;\r\n return origin + dir * t; // origin + dir * t (rayOrigin preserved)\r\n}\r\n\r\nstruct HitResult { vec3 point; vec3 normal; };\r\n\r\n// Facet normal decoding respecting GEM_NORMALS_UNORM define\r\nvec3 decodeFacetNormal(vec3 raw) {\r\n#if GEM_NORMALS_UNORM == 1\r\n return -normalize(raw * 2.0 - 1.0);\r\n#else\r\n return -normalize(raw);\r\n#endif\r\n}\r\n\r\nHitResult doIntersect(vec3 origin, vec3 dir) {\r\n vec3 sphereHit = intersectSphere(origin, dir);\r\n if (length(sphereHit) < 1e-6) {\r\n return HitResult(origin, vec3(0.0, 1.0, 0.0)); // miss sentinel\r\n }\r\n // Stage 2: first facet (nd.a is perpendicular plane distance D in radius units; pn is -normal)\r\n vec3 d1 = normalize(sphereHit - centerOffset);\r\n vec4 nd1 = texture(tCubeMapNormals, d1);\r\n vec3 pn1 = decodeFacetNormal(nd1.rgb);\r\n vec3 hp1 = linePlaneIntersect(origin, dir, centerOffset - pn1 * (nd1.a * radius), pn1);\r\n // Stage 3: second facet\r\n vec3 d2 = normalize(hp1 - centerOffset);\r\n vec4 nd2 = texture(tCubeMapNormals, d2);\r\n vec3 pn2 = decodeFacetNormal(nd2.rgb);\r\n vec3 hp2 = linePlaneIntersect(origin, dir, centerOffset - pn2 * (nd2.a * radius), pn2);\r\n return HitResult(hp2, pn2);\r\n}\r\n\r\nvec3 getRefractionColor(vec3 worldOrigin, vec3 viewDir, vec3 surfaceNormal, vec3 f0) {\r\n float ior = refractiveIndex;\r\n vec3 entryRefracted = refract(viewDir, surfaceNormal, 1.0 / ior);\r\n if (dot(entryRefracted, entryRefracted) < 1e-4) return vec3(0.0);\r\n\r\n vec3 brdfEntry = brdfGGXEnv(entryRefracted, -surfaceNormal, f0, 0.0);\r\n vec3 attenuation = vec3(1.0) - brdfEntry;\r\n\r\n vec3 origin = (modelOffsetMatrixInv * vec4(worldOrigin, 1.0)).xyz;\r\n vec3 dir = normalize((modelOffsetMatrixInv * vec4(entryRefracted, 0.0)).xyz);\r\n\r\n vec3 outColor = vec3(0.0);\r\n\r\n for (int i = 0; i < RAY_BOUNCES; i++) {\r\n HitResult hit = doIntersect(origin, dir);\r\n // Sphere-miss: hit.point == origin (sentinel) — break after first iteration\r\n if (i > 0 && length(hit.point - origin) < 1e-6) break;\r\n\r\n // Third cube lookup for mapped normal (DIAMOND_PLAN §2.3)\r\n vec3 d3 = normalize(hit.point - centerOffset);\r\n vec4 nd3 = texture(tCubeMapNormals, d3);\r\n vec3 mappedNormal = decodeFacetNormal(nd3.rgb);\r\n\r\n // Beer-Lambert (DIAMOND_PLAN §2.4)\r\n float r = length(hit.point - origin) / radius * absorptionFactor;\r\n attenuation *= exp(-r * (vec3(1.0) - color));\r\n\r\n origin = hit.point;\r\n vec3 oldDir = dir;\r\n dir = refract(oldDir, mappedNormal, ior / 1.0);\r\n\r\n if (dot(dir, dir) < 1e-4) {\r\n // TIR — DIAMOND_PLAN §2.7 + §10.5 correction: use -oldDir for BRDF\r\n dir = reflect(oldDir, mappedNormal);\r\n if (i == RAY_BOUNCES - 1) {\r\n vec3 brdfTIR = brdfGGXEnv(-oldDir, mappedNormal, f0, 0.0);\r\n vec4 envS = sampleInternalEnv(oldDir, 0.0);\r\n outColor += envS.rgb * (vec3(1.0) - brdfTIR) * attenuation * colorCorrection * boostFactors;\r\n }\r\n } else {\r\n // Exit — dispersed RGB (wavelength-dependent refraction)\r\n vec3 dir0 = dir;\r\n vec3 dir1 = refract(oldDir, mappedNormal, (ior + rIndexDelta) / 1.0);\r\n vec3 dir2 = refract(oldDir, mappedNormal, (ior - rIndexDelta) / 1.0);\r\n\r\n vec3 brdfExit = vec3(1.0) - min(vec3(1.0), brdfGGXEnv(dir0, -mappedNormal, f0, 0.0));\r\n vec3 envRGB = vec3(\r\n dot(dir1, dir1) > 1e-4 ? sampleInternalEnv(dir1, 0.0).r : 0.0,\r\n dot(dir0, dir0) > 1e-4 ? sampleInternalEnv(dir0, 0.0).g : 0.0,\r\n dot(dir2, dir2) > 1e-4 ? sampleInternalEnv(dir2, 0.0).b : 0.0\r\n );\r\n outColor += envRGB * brdfExit * attenuation * colorCorrection * boostFactors;\r\n\r\n dir = reflect(oldDir, mappedNormal);\r\n attenuation *= brdfGGXEnv(dir, mappedNormal, f0, 0.0) * boostFactors; // §2.8 compounding\r\n }\r\n }\r\n return outColor;\r\n}\r\n\r\nvoid main() {\r\n vec3 N = normalize(vWorldNormal);\r\n vec3 V = normalize(vWorldPosition - cameraPosition);\r\n float ior = refractiveIndex;\r\n float f0s = pow((ior - 1.0) / (ior + 1.0), 2.0);\r\n vec3 f0 = vec3(f0s);\r\n\r\n vec3 reflDir = reflect(V, N);\r\n vec3 brdfFront = brdfGGXEnv(reflDir, N, f0, 0.0);\r\n\r\n // Tint specular shine for colored gems, keep pure white for black & colorless stones\r\n float maxC = max(max(color.r, color.g), color.b);\r\n float minC = min(min(color.r, color.g), color.b);\r\n float chroma = maxC - minC;\r\n float lum = dot(color, vec3(0.299, 0.587, 0.114));\r\n\r\n vec3 reflTint = vec3(1.0);\r\n if (chroma >= 0.05 && lum >= 0.15 && maxC > 0.001) {\r\n vec3 gemHue = color / maxC;\r\n reflTint = mix(vec3(1.0), gemHue, 0.70);\r\n }\r\n\r\n vec3 rawEnv = sampleFrontEnv(reflDir, 0.0).rgb;\r\n vec3 reflectionColor = rawEnv * brdfFront * reflectivity * 2.0 * reflTint;\r\n\r\n // Subtle ambient surface luster so facets never drop to harsh pitch black\r\n if (ambientFloor > 0.0 || lum < 0.2) {\r\n vec3 ambientEnv = sampleFrontEnv(reflDir, 0.7).rgb;\r\n float luster = (lum < 0.2) ? 0.6 : (ambientFloor * 2.0);\r\n reflectionColor += ambientEnv * f0 * luster;\r\n }\r\n\r\n vec3 refractionColor = getRefractionColor(vWorldPosition, V, N, f0);\r\n vec3 outColor = reflectionColor + refractionColor;\r\n\r\n if (gammaFactor != 1.0) {\r\n outColor = pow(max(outColor, vec3(0.0)), vec3(gammaFactor));\r\n }\r\n if (clampHDR) outColor = min(outColor, vec3(1.0));\r\n\r\n fragColor = vec4(outColor, 1.0);\r\n#define gl_FragColor fragColor\r\n #include <colorspace_fragment>\r\n}\r\n`\r\n","import * as THREE from 'three'\r\nimport { DIAMOND_REF_VERT, DIAMOND_REF_FRAG } from './diamond-reference-shaders'\r\nimport type { BakeHandle } from './gem-geometry'\r\nimport type { StonePreset } from './presets'\r\n\r\nexport type DiamondMode = 'reference' | 'physical'\r\n\r\nexport type DiamondQuality = 'low' | 'medium' | 'high' | 'ultra'\r\n\r\n/** Maps a quality tier to compile-time bounce count and cube-map resolution.\r\n * DIAMOND_PLAN.md §5.3 Phase 4 table. */\r\nexport function resolveQualityTier(q: DiamondQuality): { rayBounces: number; cubeResolution: 128 | 256 | 512 } {\r\n switch (q) {\r\n case 'low': return { rayBounces: 3, cubeResolution: 128 }\r\n case 'medium':return { rayBounces: 5, cubeResolution: 256 }\r\n case 'high': return { rayBounces: 6, cubeResolution: 256 }\r\n case 'ultra': return { rayBounces: 8, cubeResolution: 512 }\r\n }\r\n}\r\n\r\nexport interface ReferenceDiamondMaterialOptions {\r\n rayBounces?: number // explicit bounce count — overridden by quality when both are set\r\n quality?: DiamondQuality // auto-sets rayBounces; quality wins over explicit rayBounces\r\n orientEnvMap?: boolean // DIA_ORIENT_ENVMAP, default: false\r\n}\r\n\r\nconst _invMat = new THREE.Matrix4()\r\n\r\nexport class ReferenceDiamondMaterial extends THREE.ShaderMaterial {\r\n bakeHandle: BakeHandle\r\n preset: StonePreset\r\n onBeforeRender: (\r\n renderer: THREE.WebGLRenderer,\r\n scene: THREE.Scene,\r\n camera: THREE.Camera,\r\n geometry: THREE.BufferGeometry,\r\n object: THREE.Object3D,\r\n ) => void\r\n\r\n constructor(\r\n handle: BakeHandle,\r\n envMap: THREE.Texture,\r\n preset: StonePreset,\r\n opts: ReferenceDiamondMaterialOptions = {},\r\n ) {\r\n // quality wins over explicit rayBounces\r\n const resolvedBounces = opts.quality\r\n ? resolveQualityTier(opts.quality).rayBounces\r\n : (opts.rayBounces ?? 5)\r\n const rayBounces = resolvedBounces\r\n const isCube = (envMap as any).isCubeTexture === true\r\n const bf = preset.boostFactors ?? [1.0, 1.0, 1.0]\r\n const [bfR, bfG, bfB] = bf\r\n\r\n super({\r\n vertexShader: DIAMOND_REF_VERT,\r\n fragmentShader: DIAMOND_REF_FRAG,\r\n glslVersion: THREE.GLSL3,\r\n defines: {\r\n RAY_BOUNCES: rayBounces,\r\n ENV_MAP_TYPE: isCube ? 0 : 1,\r\n DIA_ORIENT_ENVMAP: opts.orientEnvMap ? 1 : 0,\r\n HAS_GEM_INCLUSIONS: 0,\r\n GEM_NORMALS_UNORM: handle.encoding === 'unorm' ? 1 : 0,\r\n },\r\n uniforms: {\r\n // Per-frame (set in onBeforeRender)\r\n modelOffsetMatrix: { value: new THREE.Matrix4() },\r\n modelOffsetMatrixInv: { value: new THREE.Matrix4() },\r\n viewMatrixUniform: { value: new THREE.Matrix4() },\r\n cameraPosition: { value: new THREE.Vector3() },\r\n // Gem geometry\r\n tCubeMapNormals: { value: handle.texture },\r\n radius: { value: handle.radius ?? 1.0 },\r\n centerOffset: { value: handle.centroid ? handle.centroid.clone() : new THREE.Vector3() },\r\n // Environment\r\n envMap: { value: envMap },\r\n envMapRotation: { value: 0.0 },\r\n envMapIntensity: { value: preset.envMapIntensity ?? 1.0 },\r\n // Material\r\n refractiveIndex: { value: preset.ior ?? 2.6 },\r\n rIndexDelta: { value: preset.dispersion ?? 0.012 },\r\n absorptionFactor:{ value: preset.absorptionFactor ?? 1.0 },\r\n squashFactor: { value: preset.squashFactor ?? 0.98 },\r\n geometryFactor: { value: preset.geometryFactor ?? 0.5 },\r\n gammaFactor: { value: preset.gammaFactor ?? 1.0 },\r\n ambientFloor: { value: preset.ambientFloor ?? 0.05 },\r\n reflectivity: { value: 0.5 },\r\n boostFactors: { value: new THREE.Vector3(bfR, bfG, bfB) },\r\n color: { value: new THREE.Color(preset.hex) },\r\n colorCorrection: { value: new THREE.Vector3(1, 1, 1) },\r\n transmission: { value: 0.0 },\r\n clampHDR: { value: false },\r\n useInclusion: { value: false },\r\n },\r\n side: THREE.FrontSide,\r\n transparent: false,\r\n depthTest: true,\r\n depthWrite: true,\r\n toneMapped: true,\r\n })\r\n\r\n this.bakeHandle = handle\r\n this.preset = { ...preset }\r\n\r\n this.onBeforeRender = (\r\n _r: THREE.WebGLRenderer,\r\n _s: THREE.Scene,\r\n camera: THREE.Camera,\r\n _g: THREE.BufferGeometry,\r\n object: THREE.Object3D,\r\n ) => {\r\n camera.getWorldPosition(this.uniforms.cameraPosition.value as THREE.Vector3)\r\n ;(this.uniforms.modelOffsetMatrix.value as THREE.Matrix4).copy(object.matrixWorld)\r\n _invMat.copy(object.matrixWorld).invert()\r\n ;(this.uniforms.modelOffsetMatrixInv.value as THREE.Matrix4).copy(_invMat)\r\n ;(this.uniforms.viewMatrixUniform.value as THREE.Matrix4).copy(camera.matrixWorldInverse)\r\n }\r\n }\r\n\r\n updatePreset(preset: StonePreset): void {\r\n this.preset = { ...this.preset, ...preset }\r\n this.uniforms.refractiveIndex.value = preset.ior ?? 2.6\r\n this.uniforms.rIndexDelta.value = preset.dispersion ?? 0.012\r\n this.uniforms.absorptionFactor.value = preset.absorptionFactor ?? 1.0\r\n ;(this.uniforms.color.value as THREE.Color).set(preset.hex)\r\n if (preset.squashFactor !== undefined) this.uniforms.squashFactor.value = preset.squashFactor\r\n if (preset.geometryFactor !== undefined) this.uniforms.geometryFactor.value = preset.geometryFactor\r\n if (preset.gammaFactor !== undefined) this.uniforms.gammaFactor.value = preset.gammaFactor\r\n if (preset.envMapIntensity !== undefined) this.uniforms.envMapIntensity.value = preset.envMapIntensity\r\n if (preset.ambientFloor !== undefined) this.uniforms.ambientFloor.value = preset.ambientFloor\r\n if (preset.boostFactors) {\r\n const [r, g, b] = preset.boostFactors\r\n ;(this.uniforms.boostFactors.value as THREE.Vector3).set(r, g, b)\r\n }\r\n this.uniformsNeedUpdate = true\r\n }\r\n\r\n setEnvMap(tex: THREE.Texture): void {\r\n this.uniforms.envMap.value = tex\r\n const isCube = (tex as any).isCubeTexture === true\r\n const newType = isCube ? 0 : 1\r\n if (this.defines['ENV_MAP_TYPE'] !== newType) {\r\n this.defines['ENV_MAP_TYPE'] = newType\r\n this.needsUpdate = true\r\n }\r\n }\r\n\r\n clone(): this {\r\n const cloned = new ReferenceDiamondMaterial(\r\n this.bakeHandle,\r\n this.uniforms.envMap.value,\r\n this.preset,\r\n {\r\n orientEnvMap: this.defines['DIA_ORIENT_ENVMAP'] === 1,\r\n rayBounces: this.defines['RAY_BOUNCES'],\r\n },\r\n ) as this\r\n cloned.name = this.name\r\n if (this.uniforms.color?.value) {\r\n ;(cloned.uniforms.color.value as THREE.Color).copy(this.uniforms.color.value as THREE.Color)\r\n }\r\n return cloned\r\n }\r\n}\r\n\r\n// ── Material cache ────────────────────────────────────────────────────────\r\n\r\ninterface CacheEntry { material: ReferenceDiamondMaterial; refCount: number }\r\nconst materialCache = new Map<string, CacheEntry>()\r\n\r\nexport function acquireReferenceDiamondMaterial(\r\n handle: BakeHandle,\r\n envMap: THREE.Texture,\r\n preset: StonePreset,\r\n opts: ReferenceDiamondMaterialOptions = {},\r\n): ReferenceDiamondMaterial {\r\n const qualityKey = opts.quality ?? `b${opts.rayBounces ?? 5}`\r\n const orientKey = opts.orientEnvMap ? '_o1' : '_o0'\r\n const key = `ref_${handle.key}_${preset.id}_${preset.hex}_${qualityKey}${orientKey}`\r\n const existing = materialCache.get(key)\r\n if (existing) { existing.refCount++; return existing.material }\r\n const mat = new ReferenceDiamondMaterial(handle, envMap, preset, opts)\r\n materialCache.set(key, { material: mat, refCount: 1 })\r\n return mat\r\n}\r\n\r\nexport function releaseReferenceDiamondMaterial(mat: ReferenceDiamondMaterial): void {\r\n for (const [key, entry] of materialCache.entries()) {\r\n if (entry.material === mat) {\r\n entry.refCount--\r\n if (entry.refCount <= 0) { mat.dispose(); materialCache.delete(key) }\r\n return\r\n }\r\n }\r\n}\r\n","import * as THREE from 'three'\r\nimport {\r\n METAL_PRESETS,\r\n STONE_PRESETS,\r\n PHYSICALLY_BASED_METAL_PRESETS,\r\n DIAMOND_PRESETS,\r\n GEMSTONE_PRESETS,\r\n ALL_METAL_PRESETS,\r\n ALL_STONE_PRESETS,\r\n} from './presets'\r\nimport { globalDiamondBaker, type BakeHandle } from './diamond-baker'\r\nimport { DiamondMaterial, acquireDiamondMaterial, releaseDiamondMaterial } from './diamond-material'\r\nimport { setupGemEnvironment, JewelryGemEnvironment, setupEnvironment, loadHdrEnvironment, type HdrEnvironmentHandle } from './environment'\r\nimport { getOrCreateDiamondBVH } from './diamond-bvh'\r\nimport { loadPmat, loadDmatPreset, loadDmatMaterial, type PmatJson, type DmatJson } from './format-loaders'\r\nimport {\r\n ReferenceDiamondMaterial,\r\n acquireReferenceDiamondMaterial,\r\n releaseReferenceDiamondMaterial,\r\n resolveQualityTier,\r\n type DiamondMode,\r\n type DiamondQuality,\r\n} from './diamond-reference-material'\r\n\r\nexport { setupEnvironment, setupGemEnvironment, JewelryGemEnvironment, loadHdrEnvironment }\r\nexport type { HdrEnvironmentHandle }\r\nexport { globalDiamondBaker, DiamondMaterial, acquireDiamondMaterial, releaseDiamondMaterial }\r\nexport type { BakeHandle }\r\nexport { loadPmat, loadDmatPreset, loadDmatMaterial }\r\nexport type { PmatJson, DmatJson }\r\n\r\nexport function applyMetalMaterial(mesh: THREE.Mesh, hexOrPresetId: string, slotIndex?: number): void {\r\n const preset =\r\n ALL_METAL_PRESETS.find((p) => p.id === hexOrPresetId) ??\r\n METAL_PRESETS.find((p) => p.id === hexOrPresetId)\r\n\r\n const materials = Array.isArray(mesh.material)\r\n ? slotIndex !== undefined\r\n ? mesh.material[slotIndex]\r\n ? [mesh.material[slotIndex]]\r\n : []\r\n : mesh.material\r\n : slotIndex === undefined || slotIndex === 0\r\n ? mesh.material\r\n ? [mesh.material]\r\n : []\r\n : []\r\n\r\n for (const mat of materials) {\r\n if (!mat) continue\r\n // Spec §4.3: metal uses MeshPhysicalMaterial; MeshStandardMaterial is its base so\r\n // instanceof MeshStandardMaterial catches both — guard specifically for physical.\r\n if (!(mat instanceof THREE.MeshStandardMaterial)) continue\r\n mat.color.set(preset ? preset.hex : hexOrPresetId)\r\n mat.metalness = preset?.metalness ?? mat.metalness ?? 1.0\r\n mat.roughness = preset?.roughness ?? mat.roughness\r\n mat.envMapIntensity = 1.2\r\n if (mat instanceof THREE.MeshPhysicalMaterial) {\r\n mat.clearcoat = 0.0\r\n if (preset?.specularColor) {\r\n mat.specularColor = new THREE.Color(preset.specularColor)\r\n }\r\n if (preset?.ior) {\r\n mat.ior = preset.ior\r\n }\r\n }\r\n mat.needsUpdate = true\r\n }\r\n}\r\n\r\nexport function applyStoneMaterial(mesh: THREE.Mesh, hexOrPresetId: string, slotIndex?: number): void {\r\n const preset =\r\n ALL_STONE_PRESETS.find((p) => p.id === hexOrPresetId) ??\r\n STONE_PRESETS.find((p) => p.id === hexOrPresetId)\r\n\r\n const materials = Array.isArray(mesh.material)\r\n ? slotIndex !== undefined\r\n ? mesh.material[slotIndex]\r\n ? [mesh.material[slotIndex]]\r\n : []\r\n : mesh.material\r\n : slotIndex === undefined || slotIndex === 0\r\n ? mesh.material\r\n ? [mesh.material]\r\n : []\r\n : []\r\n\r\n for (const mat of materials) {\r\n if (!mat) continue\r\n if (mat instanceof ReferenceDiamondMaterial) {\r\n if (preset) {\r\n mat.updatePreset(preset)\r\n } else {\r\n // Raw hex tint: update color without flattening diamond physics/dispersion\r\n ;(mat.uniforms.color.value as THREE.Color).set(hexOrPresetId)\r\n mat.uniformsNeedUpdate = true\r\n }\r\n } else if (mat instanceof DiamondMaterial) {\r\n if (preset) {\r\n const oldHandle = mat.bakeHandle\r\n const newMat = acquireDiamondMaterial(\r\n oldHandle,\r\n mat.uniforms.envMap.value,\r\n preset,\r\n )\r\n if (newMat !== mat) {\r\n releaseDiamondMaterial(mat)\r\n if (Array.isArray(mesh.material)) {\r\n const idx = mesh.material.indexOf(mat)\r\n if (idx !== -1) mesh.material[idx] = newMat\r\n } else {\r\n mesh.material = newMat\r\n }\r\n } else {\r\n mat.updatePreset(preset)\r\n }\r\n } else {\r\n ;(mat.uniforms.color.value as THREE.Color).set(hexOrPresetId)\r\n mat.uniformsNeedUpdate = true\r\n }\r\n } else if (mat instanceof THREE.MeshPhysicalMaterial) {\r\n mat.color.set(preset ? preset.hex : hexOrPresetId)\r\n if (preset) {\r\n mat.ior = preset.ior\r\n mat.roughness = preset.roughness\r\n if (preset.specularColor) {\r\n mat.specularColor = new THREE.Color(preset.specularColor)\r\n }\r\n if (preset.attenuationColor) {\r\n mat.attenuationColor = new THREE.Color(preset.attenuationColor)\r\n mat.attenuationDistance = preset.attenuationDistance ?? 0.5\r\n }\r\n }\r\n mat.transmission = 0.0\r\n mat.transparent = false\r\n mat.envMapIntensity = 3.0\r\n mat.needsUpdate = true\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Ensures a mesh has the correct material class for its part type.\r\n * When renderer is provided and geometry is bakeable, equips DiamondMaterial.\r\n * Otherwise falls back to opaque MeshPhysicalMaterial with transmission: 0.\r\n */\r\nexport function ensureMaterial(\r\n mesh: THREE.Mesh,\r\n type: 'metal' | 'stone',\r\n renderer?: THREE.WebGLRenderer,\r\n envMap?: THREE.Texture,\r\n diamondMode: DiamondMode = 'reference',\r\n): void {\r\n const existing = Array.isArray(mesh.material) ? mesh.material[0] : mesh.material\r\n const isPhysical = existing instanceof THREE.MeshPhysicalMaterial\r\n const isDiamond = existing instanceof DiamondMaterial\r\n const isMetal = isPhysical && (existing as THREE.MeshPhysicalMaterial).metalness > 0.5\r\n\r\n if (type === 'metal') {\r\n if (!isPhysical || !isMetal) {\r\n const prev = existing as THREE.Material | null\r\n const metal = new THREE.MeshPhysicalMaterial({\r\n color: prev instanceof THREE.MeshStandardMaterial ? prev.color.clone() : new THREE.Color('#C0C0C0'),\r\n metalness: 1.0,\r\n roughness: 0.0,\r\n clearcoat: 0.0,\r\n envMapIntensity: 1.0,\r\n side: THREE.DoubleSide,\r\n })\r\n if (existing instanceof DiamondMaterial) {\r\n releaseDiamondMaterial(existing)\r\n } else if (existing instanceof ReferenceDiamondMaterial) {\r\n releaseReferenceDiamondMaterial(existing)\r\n } else {\r\n prev?.dispose()\r\n }\r\n if (prev?.name) metal.name = prev.name\r\n if (prev?.userData) metal.userData = { ...prev.userData, ...metal.userData }\r\n mesh.material = metal\r\n }\r\n return\r\n }\r\n\r\n // type === 'stone'\r\n const isRefDiamond = existing instanceof ReferenceDiamondMaterial\r\n if (isDiamond || isRefDiamond) {\r\n if (envMap) {\r\n if (isRefDiamond) {\r\n (existing as ReferenceDiamondMaterial).setEnvMap(envMap)\r\n } else {\r\n (existing as DiamondMaterial).uniforms.envMap.value = envMap\r\n }\r\n }\r\n return\r\n }\r\n\r\n if (renderer) {\r\n let handle = globalDiamondBaker.acquire(mesh.geometry, renderer)\r\n if (!handle) {\r\n const triCount = (mesh.geometry.index ? mesh.geometry.index.count : mesh.geometry.attributes.position?.count ?? 0) / 3\r\n if (triCount < 5000) {\r\n if (!mesh.geometry.boundingSphere) {\r\n mesh.geometry.computeBoundingSphere()\r\n }\r\n const bvh = getOrCreateDiamondBVH(mesh.geometry)\r\n const resolvedEnv = envMap ?? setupGemEnvironment(renderer)\r\n handle = {\r\n key: `bvh_${mesh.geometry.id}`,\r\n texture: (resolvedEnv instanceof THREE.CubeTexture ? resolvedEnv : new THREE.WebGLCubeRenderTarget(1).texture) as any,\r\n centroid: mesh.geometry.boundingSphere?.center ? mesh.geometry.boundingSphere.center.clone() : new THREE.Vector3(),\r\n radius: mesh.geometry.boundingSphere?.radius ?? 1.0,\r\n encoding: 'signed',\r\n bvh,\r\n }\r\n }\r\n }\r\n\r\n if (handle) {\r\n const resolvedEnv = envMap ?? setupGemEnvironment(renderer)\r\n let mat: THREE.Material\r\n if (diamondMode === 'reference' && !handle.key.startsWith('bvh_')) {\r\n mat = acquireReferenceDiamondMaterial(handle, resolvedEnv, STONE_PRESETS[0]!)\r\n } else {\r\n mat = acquireDiamondMaterial(handle, resolvedEnv, STONE_PRESETS[0]!)\r\n }\r\n const prev = existing as THREE.Material | null\r\n prev?.dispose()\r\n if (prev?.name) mat.name = prev.name\r\n if (prev?.userData) mat.userData = { ...prev.userData, ...mat.userData }\r\n mesh.material = mat\r\n return\r\n }\r\n }\r\n\r\n // Fallback: MeshPhysicalMaterial with transmission: 0.0\r\n if (!isPhysical || isMetal) {\r\n const prev = existing as THREE.Material | null\r\n const stone = new THREE.MeshPhysicalMaterial({\r\n color: prev instanceof THREE.MeshStandardMaterial ? prev.color.clone() : new THREE.Color('#FFFFFF'),\r\n metalness: 0,\r\n transmission: 0.0,\r\n ior: 2.417,\r\n roughness: 0.0,\r\n thickness: 0.5,\r\n envMapIntensity: 3.0,\r\n transparent: false,\r\n })\r\n prev?.dispose()\r\n if (prev?.name) stone.name = prev.name\r\n if (prev?.userData) stone.userData = { ...prev.userData, ...stone.userData }\r\n mesh.material = stone\r\n }\r\n}\r\n\r\nexport {\r\n METAL_PRESETS,\r\n STONE_PRESETS,\r\n PHYSICALLY_BASED_METAL_PRESETS,\r\n DIAMOND_PRESETS,\r\n GEMSTONE_PRESETS,\r\n ALL_METAL_PRESETS,\r\n ALL_STONE_PRESETS,\r\n}\r\nexport type { MetalPreset, StonePreset } from './presets'\r\nexport {\r\n ReferenceDiamondMaterial,\r\n acquireReferenceDiamondMaterial,\r\n releaseReferenceDiamondMaterial,\r\n resolveQualityTier,\r\n}\r\nexport type { DiamondMode, DiamondQuality }\r\n\r\n","import * as THREE from 'three'\r\nimport type { ViewerOptions } from '../types'\r\n\r\nexport interface RendererHandle {\r\n renderer: THREE.WebGLRenderer\r\n setQuality: (quality: 'low' | 'medium' | 'high') => void\r\n dispose: () => void\r\n}\r\n\r\nexport function createRenderer(\r\n container: HTMLElement,\r\n camera: THREE.PerspectiveCamera,\r\n antialias?: boolean | ViewerOptions,\r\n): RendererHandle\r\nexport function createRenderer(\r\n container: HTMLElement,\r\n antialiasOrOptions?: boolean | ViewerOptions,\r\n): RendererHandle\r\nexport function createRenderer(\r\n container: HTMLElement,\r\n cameraOrOptions?: THREE.PerspectiveCamera | boolean | ViewerOptions,\r\n antialiasOrOptions: boolean | ViewerOptions = true,\r\n): RendererHandle {\r\n let camera: THREE.PerspectiveCamera | undefined\r\n let aa = true\r\n let initialQuality: 'low' | 'medium' | 'high' = 'high'\r\n\r\n if (cameraOrOptions instanceof THREE.PerspectiveCamera) {\r\n camera = cameraOrOptions\r\n if (typeof antialiasOrOptions === 'boolean') {\r\n aa = antialiasOrOptions\r\n } else if (antialiasOrOptions && typeof antialiasOrOptions === 'object') {\r\n aa = antialiasOrOptions.antialias ?? true\r\n if (antialiasOrOptions.quality) {\r\n initialQuality = antialiasOrOptions.quality\r\n }\r\n }\r\n } else if (typeof cameraOrOptions === 'boolean') {\r\n aa = cameraOrOptions\r\n } else if (cameraOrOptions && typeof cameraOrOptions === 'object') {\r\n aa = cameraOrOptions.antialias ?? true\r\n if (cameraOrOptions.quality) {\r\n initialQuality = cameraOrOptions.quality\r\n }\r\n }\r\n\r\n const renderer = new THREE.WebGLRenderer({ antialias: aa, alpha: false })\r\n renderer.outputColorSpace = THREE.SRGBColorSpace\r\n renderer.toneMapping = THREE.ACESFilmicToneMapping\r\n renderer.toneMappingExposure = 1.0\r\n renderer.setSize(container.clientWidth, container.clientHeight)\r\n renderer.shadowMap.enabled = false\r\n container.appendChild(renderer.domElement)\r\n\r\n function setQuality(quality: 'low' | 'medium' | 'high'): void {\r\n const dpr = typeof window !== 'undefined' ? window.devicePixelRatio : 1\r\n let targetDpr = 1.0\r\n if (quality === 'low') {\r\n targetDpr = 1.0\r\n } else if (quality === 'medium') {\r\n targetDpr = Math.min(dpr, 1.5)\r\n } else if (quality === 'high') {\r\n targetDpr = Math.min(dpr, 2.0)\r\n }\r\n renderer.setPixelRatio(targetDpr)\r\n }\r\n\r\n setQuality(initialQuality)\r\n\r\n // Single ResizeObserver handles both renderer size AND camera aspect —\r\n // avoids a second observer in viewer/index.ts (Gap 3 fix).\r\n let ro: ResizeObserver | null = null\r\n if (typeof ResizeObserver !== 'undefined') {\r\n ro = new ResizeObserver(() => {\r\n const w = container.clientWidth\r\n const h = container.clientHeight\r\n renderer.setSize(w, h)\r\n if (camera) {\r\n camera.aspect = h > 0 ? w / h : 1\r\n camera.updateProjectionMatrix()\r\n }\r\n })\r\n ro.observe(container)\r\n }\r\n\r\n return {\r\n renderer,\r\n setQuality,\r\n dispose: () => {\r\n ro?.disconnect()\r\n renderer.dispose()\r\n renderer.domElement.remove()\r\n },\r\n }\r\n}\r\n","import * as THREE from 'three'\r\n\r\nexport interface SceneHandle {\r\n scene: THREE.Scene\r\n camera: THREE.PerspectiveCamera\r\n dispose: () => void\r\n}\r\n\r\nexport function createScene(\r\n background: string | number = 0x1a1a1a,\r\n fov = 25,\r\n): SceneHandle {\r\n const scene = new THREE.Scene()\r\n const bgColor: THREE.ColorRepresentation = background === 'studio' ? 0x161618 : background\r\n scene.background = new THREE.Color(bgColor)\r\n\r\n const camera = new THREE.PerspectiveCamera(\r\n fov,\r\n 1, // aspect updated on resize\r\n 0.01,\r\n 1000,\r\n )\r\n camera.position.set(0, 0, 3)\r\n\r\n // Studio lighting\r\n const keyLight = new THREE.DirectionalLight('#ffffff', 1.0)\r\n keyLight.position.set(5, 8, 5)\r\n scene.add(keyLight)\r\n\r\n const fillLight = new THREE.DirectionalLight('#e0e8ff', 0.4)\r\n fillLight.position.set(-5, 3, -5)\r\n scene.add(fillLight)\r\n\r\n // ResizeObserver aspect update is handled by whoever owns the renderer.\r\n // The viewer/index.ts calls camera.aspect = w/h; camera.updateProjectionMatrix().\r\n\r\n return {\r\n scene,\r\n camera,\r\n dispose: () => {\r\n scene.clear()\r\n },\r\n }\r\n}\r\n\r\nexport function updateCameraAspect(\r\n camera: THREE.PerspectiveCamera,\r\n width: number,\r\n height: number,\r\n): void {\r\n camera.aspect = height > 0 ? width / height : 1\r\n camera.updateProjectionMatrix()\r\n}\r\n","import * as THREE from 'three'\r\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'\r\nimport type { ViewerOptions } from '../types'\r\n\r\nexport interface ControlsHandle {\r\n controls: OrbitControls\r\n initialPosition: THREE.Vector3\r\n initialTarget: THREE.Vector3\r\n resetCamera: () => void\r\n dispose: () => void\r\n}\r\n\r\nexport function createControls(\r\n camera: THREE.PerspectiveCamera,\r\n domElement: HTMLElement,\r\n options: ViewerOptions = {},\r\n): ControlsHandle {\r\n const controls = new OrbitControls(camera, domElement)\r\n controls.enableDamping = true\r\n controls.dampingFactor = 0.05\r\n controls.screenSpacePanning = false\r\n controls.autoRotate = options.autoRotate ?? false\r\n controls.autoRotateSpeed = options.autoRotateSpeed ?? 2.0\r\n\r\n const initialPosition = camera.position.clone()\r\n const initialTarget = controls.target.clone()\r\n\r\n function resetCamera(): void {\r\n camera.position.copy(initialPosition)\r\n controls.target.copy(initialTarget)\r\n controls.update()\r\n }\r\n\r\n return {\r\n controls,\r\n initialPosition,\r\n initialTarget,\r\n resetCamera,\r\n dispose: () => {\r\n controls.dispose()\r\n },\r\n }\r\n}\r\n\r\nexport function fitCameraToScene(\r\n root: THREE.Object3D,\r\n camera: THREE.PerspectiveCamera,\r\n controlsOrHandle: OrbitControls | ControlsHandle,\r\n options: ViewerOptions = {},\r\n): void {\r\n const controls = 'controls' in controlsOrHandle ? controlsOrHandle.controls : controlsOrHandle\r\n const box = new THREE.Box3().setFromObject(root)\r\n const sphere = box.getBoundingSphere(new THREE.Sphere())\r\n const r = sphere.radius > 0 ? sphere.radius : 1\r\n\r\n const fovRad = THREE.MathUtils.degToRad(camera.fov)\r\n const distance = (r / Math.tan(fovRad / 2)) * 1.15\r\n\r\n controls.target.copy(sphere.center)\r\n camera.position.set(sphere.center.x, sphere.center.y, sphere.center.z + distance)\r\n camera.near = r * 0.01\r\n camera.far = r * 100\r\n camera.updateProjectionMatrix()\r\n\r\n controls.minDistance = options.minZoom ?? r * 0.5\r\n controls.maxDistance = options.maxZoom ?? r * 6\r\n controls.update()\r\n}\r\n","import * as THREE from 'three'\nimport type { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'\nimport type { TypedEmitter } from '../events'\nimport type { ViewerEvents, PartInfo } from '../types'\n\nexport interface InteractionHandle {\n dispose: () => void\n}\n\nexport interface InteractionOptions {\n /** Whether to apply white emissive highlight on hover. Defaults to true for standalone interaction. */\n hoverHighlight?: boolean\n}\n\nexport function createInteraction(\n renderer: THREE.WebGLRenderer,\n scene: THREE.Scene,\n camera: THREE.PerspectiveCamera,\n controls: OrbitControls,\n emitter: TypedEmitter<ViewerEvents>,\n getParts: () => PartInfo[] = () => [],\n options?: InteractionOptions,\n): InteractionHandle {\n const raycaster = new THREE.Raycaster()\n const pointer = new THREE.Vector2()\n let hoveredMesh: THREE.Mesh | null = null\n let hoveredSlotIndex: number | undefined\n const hoveredOriginalEmissive = new THREE.Color()\n let hoveredOriginalIntensity = 0\n let isDragging = false\n let pointerDownPos = { x: 0, y: 0 }\n\n const enableHighlight = options?.hoverHighlight ?? false\n\n function getMeshes(): THREE.Mesh[] {\n const meshes: THREE.Mesh[] = []\n scene.traverse((obj) => {\n if ((obj as THREE.Mesh).isMesh) meshes.push(obj as THREE.Mesh)\n })\n return meshes\n }\n\n function getMaterial(mesh: THREE.Mesh): THREE.MeshStandardMaterial | null {\n const mat = Array.isArray(mesh.material) ? mesh.material[0] : mesh.material\n return mat instanceof THREE.MeshStandardMaterial ? mat : null\n }\n\n function setHover(mesh: THREE.Mesh | null, materialIndex?: number): void {\n if (mesh === hoveredMesh && materialIndex === hoveredSlotIndex) return\n\n // Restore previous\n if (hoveredMesh) {\n if (enableHighlight) {\n const mat = getMaterial(hoveredMesh)\n if (mat) {\n mat.emissive.copy(hoveredOriginalEmissive)\n mat.emissiveIntensity = hoveredOriginalIntensity\n }\n }\n }\n\n hoveredMesh = mesh\n hoveredSlotIndex = materialIndex\n\n if (mesh) {\n if (enableHighlight) {\n const mat = getMaterial(mesh)\n if (mat) {\n hoveredOriginalEmissive.copy(mat.emissive)\n hoveredOriginalIntensity = mat.emissiveIntensity\n mat.emissive.set(0xffffff)\n mat.emissiveIntensity = 0.3\n }\n }\n\n if (renderer.domElement?.style) {\n renderer.domElement.style.cursor = 'pointer'\n }\n\n const part = getParts().find((p) => p.meshId === mesh.uuid)\n if (part) {\n const slotIdx =\n materialIndex !== undefined && part.slots[materialIndex] !== undefined\n ? materialIndex\n : 0\n const slot = part.slots[slotIdx]\n emitter.emit('partHover', {\n meshId: part.meshId,\n partId: part.partId,\n type: part.type,\n slotIndex: slotIdx,\n slotId: slot?.slotId,\n materialName: slot?.materialName ?? part.materialName,\n })\n } else {\n emitter.emit('partHover', null)\n }\n } else {\n if (renderer.domElement?.style) {\n renderer.domElement.style.cursor = 'default'\n }\n emitter.emit('partHover', null)\n }\n }\n\n function onPointerMove(e: PointerEvent): void {\n if (isDragging) return\n const rect = renderer.domElement.getBoundingClientRect()\n if (rect.width === 0 || rect.height === 0) return\n pointer.x = ((e.clientX - rect.left) / rect.width) * 2 - 1\n pointer.y = -((e.clientY - rect.top) / rect.height) * 2 + 1\n\n raycaster.setFromCamera(pointer, camera)\n const hits = raycaster.intersectObjects(getMeshes(), false)\n const firstHit = hits[0]\n setHover(firstHit ? (firstHit.object as THREE.Mesh) : null, firstHit?.face?.materialIndex)\n }\n\n function onPointerLeave(): void {\n setHover(null, undefined)\n }\n\n function onPointerDown(e: PointerEvent): void {\n pointerDownPos = { x: e.clientX, y: e.clientY }\n }\n\n function onPointerUp(e: PointerEvent): void {\n const dx = e.clientX - pointerDownPos.x\n const dy = e.clientY - pointerDownPos.y\n const dist = Math.sqrt(dx * dx + dy * dy)\n if (dist < 4) {\n let targetMesh = hoveredMesh\n let clickedSlotIndex = hoveredSlotIndex\n if (!targetMesh) {\n const rect = renderer.domElement.getBoundingClientRect()\n if (rect.width > 0 && rect.height > 0) {\n pointer.x = ((e.clientX - rect.left) / rect.width) * 2 - 1\n pointer.y = -((e.clientY - rect.top) / rect.height) * 2 + 1\n raycaster.setFromCamera(pointer, camera)\n const hits = raycaster.intersectObjects(getMeshes(), false)\n if (hits.length > 0) {\n targetMesh = hits[0]!.object as THREE.Mesh\n clickedSlotIndex = hits[0]!.face?.materialIndex\n }\n }\n }\n if (targetMesh) {\n const part = getParts().find((p) => p.meshId === targetMesh!.uuid)\n if (part) {\n const slotIdx =\n clickedSlotIndex !== undefined && part.slots[clickedSlotIndex] !== undefined\n ? clickedSlotIndex\n : 0\n const slot = part.slots[slotIdx]\n emitter.emit('partSelected', {\n meshId: part.meshId,\n partId: part.partId,\n type: part.type,\n slotIndex: slotIdx,\n slotId: slot?.slotId,\n materialName: slot?.materialName ?? part.materialName,\n })\n }\n }\n }\n }\n\n function onDragStart(): void {\n isDragging = true\n }\n\n function onDragEnd(): void {\n isDragging = false\n }\n\n const el = renderer.domElement\n el.addEventListener('pointermove', onPointerMove as EventListener)\n el.addEventListener('pointerdown', onPointerDown as EventListener)\n el.addEventListener('pointerup', onPointerUp as EventListener)\n el.addEventListener('pointerleave', onPointerLeave as EventListener)\n controls.addEventListener('start', onDragStart)\n controls.addEventListener('end', onDragEnd)\n\n return {\n dispose: () => {\n el.removeEventListener('pointermove', onPointerMove as EventListener)\n el.removeEventListener('pointerdown', onPointerDown as EventListener)\n el.removeEventListener('pointerup', onPointerUp as EventListener)\n el.removeEventListener('pointerleave', onPointerLeave as EventListener)\n controls.removeEventListener('start', onDragStart)\n controls.removeEventListener('end', onDragEnd)\n setHover(null)\n if (el?.style) {\n el.style.cursor = 'default'\n }\n },\n }\n}\n","import * as THREE from 'three'\nimport type { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'\nimport type { ViewerState, PartType, StateRestoreResult } from '../types'\n\nexport function buildState(\n metalColor: string,\n stoneColor: string,\n partOverrides: Record<string, PartType>,\n camera: THREE.PerspectiveCamera,\n controls: OrbitControls,\n materialColors?: Record<string, string>,\n partColors?: Record<string, string>,\n modelId?: string,\n): ViewerState {\n const state: ViewerState = {\n metalColor,\n stoneColor,\n parts: { ...partOverrides },\n cameraState: {\n position: camera.position.toArray() as [number, number, number],\n target: controls.target.toArray() as [number, number, number],\n },\n }\n\n if (modelId) {\n state.modelId = modelId\n }\n\n if (materialColors && Object.keys(materialColors).length > 0) {\n state.materialColors = { ...materialColors }\n }\n\n if (partColors && Object.keys(partColors).length > 0) {\n state.partColors = { ...partColors }\n }\n\n return state\n}\n\nexport interface RestoreStateOptions {\n setMaterialColor?: (slotIdOrName: string, color: string) => void\n setPartColor?: (partIdOrMeshId: string, color: string, slotIndex?: number) => void\n availablePartIds?: Set<string>\n availableSlotIds?: Set<string>\n availableMaterialNames?: Set<string>\n}\n\nexport function restoreState(\n state: ViewerState,\n applyMetalColor: (hex: string) => void,\n applyStoneColor: (hex: string) => void,\n setPartType: (partIdOrMeshId: string, type: PartType) => void,\n camera: THREE.PerspectiveCamera,\n controls: OrbitControls,\n options?: RestoreStateOptions,\n): StateRestoreResult {\n const unresolvedParts: string[] = []\n const unresolvedMaterials: string[] = []\n const warnings: string[] = []\n\n // 1. Global defaults\n applyMetalColor(state.metalColor)\n applyStoneColor(state.stoneColor)\n\n // 2. Part type overrides\n for (const [partIdOrMeshId, type] of Object.entries(state.parts || {})) {\n if (options?.availablePartIds && !options.availablePartIds.has(partIdOrMeshId)) {\n unresolvedParts.push(partIdOrMeshId)\n warnings.push(`Part type override target '${partIdOrMeshId}' not found in model`)\n console.warn(`[3d-viewer] Part type override target '${partIdOrMeshId}' not found in loaded model`)\n }\n setPartType(partIdOrMeshId, type)\n }\n\n // 3. Material slot overrides\n if (state.materialColors && options?.setMaterialColor) {\n for (const [slotIdOrName, color] of Object.entries(state.materialColors)) {\n const isKnown =\n (!options.availableSlotIds && !options.availableMaterialNames) ||\n options.availableSlotIds?.has(slotIdOrName) ||\n options.availableMaterialNames?.has(slotIdOrName)\n\n if (!isKnown) {\n unresolvedMaterials.push(slotIdOrName)\n warnings.push(`Material slot '${slotIdOrName}' not found in model`)\n console.warn(`[3d-viewer] Material slot '${slotIdOrName}' not found in loaded model`)\n }\n options.setMaterialColor(slotIdOrName, color)\n }\n }\n\n // 4. Part overrides (supports whole-part 'partId' and part-slot 'partId:slotIndex')\n if (state.partColors && options?.setPartColor) {\n for (const [partTarget, color] of Object.entries(state.partColors)) {\n let partId = partTarget\n let slotIndex: number | undefined = undefined\n\n const colonIdx = partTarget.lastIndexOf(':')\n if (colonIdx > 0 && !isNaN(Number(partTarget.slice(colonIdx + 1)))) {\n partId = partTarget.slice(0, colonIdx)\n slotIndex = Number(partTarget.slice(colonIdx + 1))\n }\n\n if (options.availablePartIds && !options.availablePartIds.has(partId)) {\n unresolvedParts.push(partId)\n warnings.push(`Part '${partId}' not found in model`)\n console.warn(`[3d-viewer] Part '${partId}' not found in loaded model`)\n }\n options.setPartColor(partId, color, slotIndex)\n }\n }\n\n // 5. Camera & controls\n if (state.cameraState) {\n camera.position.fromArray(state.cameraState.position)\n controls.target.fromArray(state.cameraState.target)\n controls.update()\n }\n\n return {\n success: true,\n unresolvedParts: unresolvedParts.length > 0 ? unresolvedParts : undefined,\n unresolvedMaterials: unresolvedMaterials.length > 0 ? unresolvedMaterials : undefined,\n warnings: warnings.length > 0 ? warnings : undefined,\n }\n}\n","import * as THREE from 'three'\n\nexport interface ContactShadowHandle {\n mesh: THREE.Mesh\n setVisible: (visible: boolean) => void\n setScale: (scale: number) => void\n dispose: () => void\n}\n\nexport function createContactShadowPlane(scene: THREE.Scene, radius = 1.2): ContactShadowHandle {\n let texture: THREE.Texture\n\n if (typeof document !== 'undefined' && typeof document.createElement === 'function') {\n const canvas = document.createElement('canvas')\n canvas.width = 256\n canvas.height = 256\n const ctx = canvas.getContext ? canvas.getContext('2d') : null\n if (ctx) {\n const gradient = ctx.createRadialGradient(128, 128, 0, 128, 128, 128)\n gradient.addColorStop(0, 'rgba(0, 0, 0, 0.65)')\n gradient.addColorStop(0.3, 'rgba(0, 0, 0, 0.4)')\n gradient.addColorStop(0.7, 'rgba(0, 0, 0, 0.15)')\n gradient.addColorStop(1, 'rgba(0, 0, 0, 0)')\n ctx.fillStyle = gradient\n ctx.fillRect(0, 0, 256, 256)\n }\n\n const canvasTexture = new THREE.CanvasTexture(canvas)\n canvasTexture.needsUpdate = true\n texture = canvasTexture\n } else {\n // Headless / SSR environment fallback\n texture = new THREE.Texture()\n texture.needsUpdate = true\n }\n\n const geometry = new THREE.PlaneGeometry(radius * 2, radius * 2)\n geometry.rotateX(-Math.PI / 2)\n\n const material = new THREE.MeshBasicMaterial({\n map: texture,\n transparent: true,\n opacity: 0.85,\n depthWrite: false,\n })\n\n const mesh = new THREE.Mesh(geometry, material)\n mesh.position.y = -0.5\n mesh.renderOrder = -1\n scene.add(mesh)\n\n return {\n mesh,\n setVisible: (visible) => {\n mesh.visible = visible\n },\n setScale: (scale) => {\n mesh.scale.setScalar(scale)\n },\n dispose: () => {\n scene.remove(mesh)\n geometry.dispose()\n material.dispose()\n texture.dispose()\n },\n }\n}\n","import * as THREE from 'three'\r\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'\r\nimport { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'\r\nimport { DEFAULT_DRACO_DECODER_PATH } from '../converter/loaders'\r\nimport { TypedEmitter } from '../events'\r\nimport { convert, normalizeScene } from '../converter'\r\nimport { classifyParts, extractMaterialSlots } from '../parts'\r\nimport {\r\n applyMetalMaterial,\r\n applyStoneMaterial,\r\n ensureMaterial,\r\n setupEnvironment,\r\n setupGemEnvironment,\r\n loadHdrEnvironment,\r\n globalDiamondBaker,\r\n DiamondMaterial,\r\n type HdrEnvironmentHandle,\r\n} from '../materials'\r\nimport {\r\n ReferenceDiamondMaterial,\r\n acquireReferenceDiamondMaterial,\r\n releaseReferenceDiamondMaterial,\r\n resolveQualityTier,\r\n type DiamondQuality,\r\n} from '../materials/diamond-reference-material'\r\nimport {\r\n METAL_PRESETS,\r\n STONE_PRESETS,\r\n ALL_METAL_PRESETS,\r\n ALL_STONE_PRESETS,\r\n} from '../materials/presets'\r\nimport { createRenderer } from './renderer'\r\nimport { createScene, updateCameraAspect } from './scene'\r\nimport { createControls, fitCameraToScene } from './controls'\r\nimport { createInteraction } from './interaction'\r\nimport { buildState, restoreState } from './state'\r\nimport { createContactShadowPlane } from './shadow'\r\nimport type {\r\n ModelSource,\r\n LoadOptions,\r\n ViewerOptions,\r\n ViewerEvents,\r\n ViewerState,\r\n PartInfo,\r\n PartType,\r\n MaterialSlotInfo,\r\n MeshMaterialSlot,\r\n StateRestoreResult,\r\n Viewer,\r\n} from '../types'\r\n\r\nexport type { Viewer } from '../types'\r\n\r\nfunction disposeModel(model: THREE.Object3D): void {\r\n model.traverse((obj) => {\r\n if (obj instanceof THREE.Mesh) {\r\n obj.geometry?.dispose()\r\n const mats = Array.isArray(obj.material) ? obj.material : [obj.material]\r\n mats.forEach((m) => {\r\n // Spec §4.4 Dispose: geometry, material, AND texture disposal required\r\n if (m instanceof THREE.MeshStandardMaterial) {\r\n m.map?.dispose()\r\n m.normalMap?.dispose()\r\n m.roughnessMap?.dispose()\r\n m.metalnessMap?.dispose()\r\n m.envMap?.dispose()\r\n }\r\n m.dispose()\r\n })\r\n }\r\n })\r\n}\r\n\r\nexport function createViewer(\r\n container: HTMLElement,\r\n options: ViewerOptions = {},\r\n): Viewer {\r\n const emitter = new TypedEmitter<ViewerEvents>()\r\n const sceneHandle = createScene(options.background ?? 0xffffff, options.fov ?? 25)\r\n const { scene, camera, dispose: disposeScene } = sceneHandle\r\n const rendererHandle = createRenderer(\r\n container,\r\n camera,\r\n options,\r\n )\r\n const { renderer } = rendererHandle\r\n const controlsHandle = createControls(camera, renderer.domElement, options)\r\n const controls = controlsHandle.controls\r\n\r\n // Contact shadow plane\r\n const shadowHandle = createContactShadowPlane(scene)\r\n if (options.shadows === false) {\r\n shadowHandle.setVisible(false)\r\n }\r\n\r\n // Environment (Dual Lighting)\r\n setupEnvironment(scene, renderer)\r\n let gemEnv: THREE.Texture | undefined\r\n try {\r\n gemEnv = setupGemEnvironment(renderer)\r\n } catch {\r\n // Graceful fallback if mock or test renderer lacks WebGLCubeRenderTarget support\r\n }\r\n\r\n let metalHdrHandle: HdrEnvironmentHandle | null = null\r\n let gemHdrHandle: HdrEnvironmentHandle | null = null\r\n\r\n /**\r\n * Detects mobile devices and caps quality to 'medium'.\r\n * Heuristic: user agent contains \"Mobi\" AND devicePixelRatio is not high-end.\r\n * Only applies if the user did not explicitly request 'high' or 'ultra'.\r\n */\r\n function applyMobileCap(requested: DiamondQuality): DiamondQuality {\r\n const isMobile =\r\n typeof navigator !== 'undefined' &&\r\n /Mobi/i.test(navigator.userAgent) &&\r\n (typeof window === 'undefined' || window.devicePixelRatio <= 2)\r\n if (!isMobile) return requested\r\n // Cap: mobile max is 'medium'\r\n const mobileMax: DiamondQuality = 'medium'\r\n const order: DiamondQuality[] = ['low', 'medium', 'high', 'ultra']\r\n return order.indexOf(requested) <= order.indexOf(mobileMax) ? requested : mobileMax\r\n }\r\n\r\n // Diamond quality state\r\n let currentDiamondQuality: DiamondQuality = applyMobileCap(\r\n (options.diamondQuality as DiamondQuality | undefined) ?? 'medium'\r\n )\r\n let qualityDebounceTimer: ReturnType<typeof setTimeout> | null = null\r\n\r\n async function setMetalEnvironment(urlOrData: string | ArrayBuffer): Promise<void> {\r\n try {\r\n const handle = await loadHdrEnvironment(urlOrData, renderer)\r\n metalHdrHandle?.dispose()\r\n metalHdrHandle = handle\r\n scene.environment = handle.texture\r\n\r\n // If no dedicated gem environment was configured, bind this HDR to diamonds as well\r\n if (!options.gemEnvUrl) {\r\n gemEnv = handle.gemTexture ?? handle.texture\r\n currentModel?.traverse((obj) => {\r\n if (!(obj instanceof THREE.Mesh)) return\r\n if (obj.material instanceof ReferenceDiamondMaterial) {\r\n obj.material.setEnvMap(gemEnv!)\r\n } else if (obj.material instanceof DiamondMaterial) {\r\n obj.material.uniforms.envMap.value = gemEnv\r\n }\r\n })\r\n }\r\n } catch (err) {\r\n emitter.emit('error', err instanceof Error ? err : new Error(String(err)))\r\n throw err\r\n }\r\n }\r\n\r\n async function setGemEnvironment(urlOrData: string | ArrayBuffer): Promise<void> {\r\n try {\r\n const handle = await loadHdrEnvironment(urlOrData, renderer)\r\n gemHdrHandle?.dispose()\r\n gemHdrHandle = handle\r\n gemEnv = handle.gemTexture ?? handle.texture\r\n currentModel?.traverse((obj) => {\r\n if (!(obj instanceof THREE.Mesh)) return\r\n if (obj.material instanceof ReferenceDiamondMaterial) {\r\n obj.material.setEnvMap(gemEnv!)\r\n } else if (obj.material instanceof DiamondMaterial) {\r\n obj.material.uniforms.envMap.value = gemEnv\r\n }\r\n })\r\n } catch (err) {\r\n emitter.emit('error', err instanceof Error ? err : new Error(String(err)))\r\n throw err\r\n }\r\n }\r\n\r\n if (options.metalEnvUrl) {\r\n setMetalEnvironment(options.metalEnvUrl).catch(() => {})\r\n }\r\n if (options.gemEnvUrl) {\r\n setGemEnvironment(options.gemEnvUrl).catch(() => {})\r\n }\r\n\r\n // WebGL context restoration\r\n const canvas = renderer.domElement\r\n const handleContextRestored = () => {\r\n globalDiamondBaker.onContextRestored(renderer)\r\n }\r\n canvas.addEventListener?.('webglcontextrestored', handleContextRestored)\r\n\r\n // Model state\r\n let currentModel: THREE.Group | null = null\r\n let partInfos: PartInfo[] = []\r\n let materialSlots: MaterialSlotInfo[] = []\r\n let partOverrides: Record<string, PartType> = {}\r\n let materialOverrides: Record<string, string> = {}\r\n let partColorOverrides: Record<string, string> = {}\r\n let metalColor = METAL_PRESETS[0]!.hex\r\n let stoneColor = STONE_PRESETS[0]!.hex\r\n let abortController: AbortController | null = null\r\n\r\n // Camera aspect on resize\r\n let ro: ResizeObserver | null = null\r\n if (typeof ResizeObserver !== 'undefined') {\r\n ro = new ResizeObserver(() => {\r\n updateCameraAspect(camera, container.clientWidth, container.clientHeight)\r\n })\r\n ro.observe(container)\r\n }\r\n\r\n // Render loop\r\n let rafId = 0\r\n let paused = false\r\n\r\n function render(): void {\r\n controls.update()\r\n renderer.render(scene, camera)\r\n if (!paused && typeof requestAnimationFrame !== 'undefined') {\r\n rafId = requestAnimationFrame(render)\r\n }\r\n }\r\n\r\n function onVisibility(): void {\r\n const wasPaused = paused\r\n paused = typeof document !== 'undefined' ? document.hidden : false\r\n if (wasPaused && !paused && typeof requestAnimationFrame !== 'undefined') {\r\n rafId = requestAnimationFrame(render)\r\n }\r\n }\r\n\r\n if (typeof document !== 'undefined') {\r\n document.addEventListener('visibilitychange', onVisibility)\r\n }\r\n if (typeof requestAnimationFrame !== 'undefined') {\r\n rafId = requestAnimationFrame(render)\r\n }\r\n\r\n // Interaction\r\n const interaction = createInteraction(\r\n renderer,\r\n scene,\r\n camera,\r\n controls,\r\n emitter,\r\n () => partInfos,\r\n { hoverHighlight: options.hoverHighlight ?? false },\r\n )\r\n\r\n // ── Public API ──────────────────────────────────────────────────────────\r\n\r\n function getEffectiveModel(): THREE.Group | null {\r\n if (typeof (viewer as any)?.__getCurrentModel === 'function') {\r\n const mock = (viewer as any).__getCurrentModel()\r\n if (mock) return mock\r\n }\r\n return currentModel\r\n }\r\n\r\n function resolveMeshSlotColor(\r\n part: PartInfo,\r\n slotIndex: number,\r\n slot?: MeshMaterialSlot,\r\n ): { color: string; isOverridden: boolean } {\r\n // 1. Part-slot override: 'partId:slotIndex' or 'meshId:slotIndex'\r\n const partSlotKey = `${part.partId}:${slotIndex}`\r\n if (partColorOverrides[partSlotKey]) {\r\n return { color: partColorOverrides[partSlotKey]!, isOverridden: true }\r\n }\r\n const meshSlotKey = `${part.meshId}:${slotIndex}`\r\n if (partColorOverrides[meshSlotKey]) {\r\n return { color: partColorOverrides[meshSlotKey]!, isOverridden: true }\r\n }\r\n\r\n // 2. Whole-part override: 'partId' or 'meshId'\r\n if (partColorOverrides[part.partId]) {\r\n return { color: partColorOverrides[part.partId]!, isOverridden: true }\r\n }\r\n if (partColorOverrides[part.meshId]) {\r\n return { color: partColorOverrides[part.meshId]!, isOverridden: true }\r\n }\r\n\r\n // 3. Pinpoint slot override: 'slotId'\r\n if (slot?.slotId && materialOverrides[slot.slotId]) {\r\n return { color: materialOverrides[slot.slotId]!, isOverridden: true }\r\n }\r\n\r\n // 4. Bulk slot name override: 'materialName'\r\n if (slot?.materialName && materialOverrides[slot.materialName]) {\r\n return { color: materialOverrides[slot.materialName]!, isOverridden: true }\r\n }\r\n if (part.materialName && materialOverrides[part.materialName]) {\r\n return { color: materialOverrides[part.materialName]!, isOverridden: true }\r\n }\r\n\r\n // 5. Global default\r\n const globalDefault = part.type === 'metal' ? metalColor : stoneColor\r\n return { color: globalDefault, isOverridden: false }\r\n }\r\n\r\n function ensureUniqueMeshMaterial(mesh: THREE.Mesh, model: THREE.Group): void {\r\n if (Array.isArray(mesh.material)) {\r\n mesh.material = mesh.material.map((m) => {\r\n let count = 0\r\n model.traverse((o) => {\r\n if (o instanceof THREE.Mesh) {\r\n if (Array.isArray(o.material) ? o.material.includes(m) : o.material === m) count++\r\n }\r\n })\r\n if (count > 1 && typeof m.clone === 'function') {\r\n const cloned = m.clone()\r\n cloned.name = m.name\r\n return cloned\r\n }\r\n return m\r\n })\r\n } else if (mesh.material) {\r\n let count = 0\r\n model.traverse((o) => {\r\n if (o instanceof THREE.Mesh) {\r\n if (Array.isArray(o.material) ? o.material.includes(mesh.material) : o.material === mesh.material) count++\r\n }\r\n })\r\n if (count > 1 && typeof mesh.material.clone === 'function') {\r\n const cloned = mesh.material.clone()\r\n cloned.name = mesh.material.name\r\n mesh.material = cloned\r\n }\r\n }\r\n }\r\n\r\n function applyColorsToMesh(mesh: THREE.Mesh, part: PartInfo): void {\r\n const model = getEffectiveModel()\r\n if (model) {\r\n let anyOverridden = false\r\n if (Array.isArray(mesh.material)) {\r\n mesh.material.forEach((_, idx) => {\r\n const slot = part.slots[idx]\r\n if (resolveMeshSlotColor(part, idx, slot).isOverridden) anyOverridden = true\r\n })\r\n } else {\r\n const slot = part.slots[0]\r\n if (resolveMeshSlotColor(part, 0, slot).isOverridden) anyOverridden = true\r\n }\r\n if (anyOverridden) {\r\n ensureUniqueMeshMaterial(mesh, model)\r\n }\r\n }\r\n\r\n if (Array.isArray(mesh.material)) {\r\n mesh.material.forEach((_, idx) => {\r\n const slot = part.slots[idx]\r\n const { color } = resolveMeshSlotColor(part, idx, slot)\r\n if (part.type === 'metal') applyMetalMaterial(mesh, color, idx)\r\n else applyStoneMaterial(mesh, color, idx)\r\n })\r\n } else {\r\n const slot = part.slots[0]\r\n const { color } = resolveMeshSlotColor(part, 0, slot)\r\n if (part.type === 'metal') applyMetalMaterial(mesh, color)\r\n else applyStoneMaterial(mesh, color)\r\n }\r\n }\r\n\r\n async function load(\r\n source: ModelSource,\r\n opts: LoadOptions = {},\r\n ): Promise<void> {\r\n // Cancel any in-flight load\r\n abortController?.abort()\r\n abortController = new AbortController()\r\n const currentAbort = abortController\r\n\r\n if (opts.signal) {\r\n if (opts.signal.aborted) {\r\n currentAbort.abort()\r\n } else {\r\n opts.signal.addEventListener('abort', () => currentAbort.abort(), { once: true })\r\n }\r\n }\r\n const signal = currentAbort.signal\r\n\r\n emitter.emit('loading', { progress: 0 })\r\n\r\n try {\r\n const dracoDecoderPath = opts.dracoDecoderPath ?? options.dracoDecoderPath ?? DEFAULT_DRACO_DECODER_PATH\r\n const converted = await convert(\r\n source,\r\n signal,\r\n (p) => {\r\n emitter.emit('loading', { progress: p * 0.8 })\r\n },\r\n { dracoDecoderPath },\r\n )\r\n\r\n if (signal.aborted) return\r\n\r\n emitter.emit('loading', { progress: 0.85 })\r\n\r\n // Parse to Three.js scene\r\n const loader = new GLTFLoader()\r\n const dracoLoader = new DRACOLoader()\r\n dracoLoader.setDecoderPath(dracoDecoderPath)\r\n loader.setDRACOLoader(dracoLoader)\r\n\r\n let gltf: { scene: THREE.Group }\r\n try {\r\n gltf = await new Promise<{ scene: THREE.Group }>((resolve, reject) => {\r\n loader.parse(converted.glb, '', resolve, reject)\r\n })\r\n } finally {\r\n dracoLoader.dispose()\r\n }\r\n\r\n if (signal.aborted) return\r\n\r\n emitter.emit('loading', { progress: 0.9 })\r\n\r\n // Remove old model\r\n if (currentModel) {\r\n scene.remove(currentModel)\r\n disposeModel(currentModel)\r\n currentModel = null\r\n }\r\n\r\n currentModel = gltf.scene\r\n normalizeScene(currentModel)\r\n scene.add(currentModel)\r\n\r\n // Classify parts and extract material slots\r\n partInfos = classifyParts(currentModel, partOverrides)\r\n materialSlots = extractMaterialSlots(partInfos)\r\n\r\n // Apply materials\r\n currentModel.traverse((obj) => {\r\n if (!(obj instanceof THREE.Mesh)) return\r\n const part = partInfos.find((p) => p.meshId === obj.uuid)\r\n const type = part?.type ?? 'metal'\r\n ensureMaterial(obj, type, renderer, gemEnv, options.diamondMode ?? 'reference')\r\n if (part) applyColorsToMesh(obj, part)\r\n else if (type === 'metal') applyMetalMaterial(obj, metalColor)\r\n else applyStoneMaterial(obj, stoneColor)\r\n })\r\n\r\n // Apply initial diamond quality (no-op if 'medium'/default — materials already at 5 bounces/256px)\r\n if (currentDiamondQuality !== 'medium') {\r\n setDiamondQuality(currentDiamondQuality)\r\n }\r\n\r\n // Fit camera\r\n fitCameraToScene(currentModel, camera, controls, options)\r\n updateCameraAspect(camera, container.clientWidth, container.clientHeight)\r\n\r\n // Position contact shadow plane beneath the model\r\n const box = new THREE.Box3().setFromObject(currentModel)\r\n const sphere = box.getBoundingSphere(new THREE.Sphere())\r\n const r = sphere.radius > 0 ? sphere.radius : 1\r\n shadowHandle.mesh.position.y = box.min.y\r\n shadowHandle.setScale(r)\r\n\r\n emitter.emit('loading', { progress: 1 })\r\n emitter.emit('loaded', { parts: partInfos, materials: materialSlots })\r\n } catch (err) {\r\n if ((err as Error).name === 'AbortError' || signal.aborted) return // silently cancel\r\n emitter.emit('error', err instanceof Error ? err : new Error(String(err)))\r\n }\r\n }\r\n\r\n function setMetalColor(hexOrPresetId: string): void {\r\n metalColor =\r\n ALL_METAL_PRESETS.find((p) => p.id === hexOrPresetId)?.hex ??\r\n METAL_PRESETS.find((p) => p.id === hexOrPresetId)?.hex ??\r\n hexOrPresetId\r\n const model = getEffectiveModel()\r\n if (!model) return\r\n model.traverse((obj: THREE.Object3D) => {\r\n if (!(obj instanceof THREE.Mesh)) return\r\n const part = partInfos.find((p) => p.meshId === obj.uuid)\r\n if ((part?.type ?? 'metal') !== 'metal') return\r\n if (part) {\r\n if (Array.isArray(obj.material)) {\r\n obj.material.forEach((_, idx) => {\r\n const slot = part.slots[idx]\r\n const { isOverridden } = resolveMeshSlotColor(part, idx, slot)\r\n if (!isOverridden) applyMetalMaterial(obj, metalColor, idx)\r\n })\r\n } else {\r\n const slot = part.slots[0]\r\n const { isOverridden } = resolveMeshSlotColor(part, 0, slot)\r\n if (!isOverridden) applyMetalMaterial(obj, metalColor)\r\n }\r\n } else {\r\n applyMetalMaterial(obj, metalColor)\r\n }\r\n })\r\n emitter.emit('change', getState())\r\n }\r\n\r\n function setStoneColor(hexOrPresetId: string): void {\r\n stoneColor =\r\n ALL_STONE_PRESETS.find((p) => p.id === hexOrPresetId)?.hex ??\r\n STONE_PRESETS.find((p) => p.id === hexOrPresetId)?.hex ??\r\n hexOrPresetId\r\n const model = getEffectiveModel()\r\n if (!model) return\r\n model.traverse((obj: THREE.Object3D) => {\r\n if (!(obj instanceof THREE.Mesh)) return\r\n const part = partInfos.find((p) => p.meshId === obj.uuid)\r\n if (part?.type !== 'stone') return\r\n if (part) {\r\n if (Array.isArray(obj.material)) {\r\n obj.material.forEach((_, idx) => {\r\n const slot = part.slots[idx]\r\n const { isOverridden } = resolveMeshSlotColor(part, idx, slot)\r\n if (!isOverridden) applyStoneMaterial(obj, stoneColor, idx)\r\n })\r\n } else {\r\n const slot = part.slots[0]\r\n const { isOverridden } = resolveMeshSlotColor(part, 0, slot)\r\n if (!isOverridden) applyStoneMaterial(obj, stoneColor)\r\n }\r\n } else {\r\n applyStoneMaterial(obj, stoneColor)\r\n }\r\n })\r\n emitter.emit('change', getState())\r\n }\r\n\r\n function setPartType(meshIdOrPartId: string, type: PartType): void {\r\n const part = partInfos.find((p) => p.meshId === meshIdOrPartId || p.partId === meshIdOrPartId)\r\n const targetKey = part ? part.partId : meshIdOrPartId\r\n partOverrides[targetKey] = type\r\n\r\n const model = getEffectiveModel()\r\n if (model) {\r\n partInfos = classifyParts(model, partOverrides)\r\n materialSlots = extractMaterialSlots(partInfos)\r\n model.traverse((obj: THREE.Object3D) => {\r\n if (!(obj instanceof THREE.Mesh)) return\r\n const p = partInfos.find((pi) => pi.meshId === obj.uuid)\r\n if (!p || (p.partId !== targetKey && p.meshId !== meshIdOrPartId)) return\r\n ensureMaterial(obj, type, renderer, gemEnv, options.diamondMode ?? 'reference')\r\n applyColorsToMesh(obj, p)\r\n })\r\n if (type === 'stone' && currentDiamondQuality !== 'medium') {\r\n setDiamondQuality(currentDiamondQuality)\r\n }\r\n }\r\n emitter.emit('change', getState())\r\n }\r\n\r\n function setMaterialColor(slotIdOrName: string, colorOrPresetId: string): void {\r\n const matchingSlots = materialSlots.filter(\r\n (s) => s.slotId === slotIdOrName || s.name === slotIdOrName,\r\n )\r\n if (matchingSlots.length > 0) {\r\n for (const slot of matchingSlots) {\r\n materialOverrides[slot.slotId] = colorOrPresetId\r\n }\r\n }\r\n materialOverrides[slotIdOrName] = colorOrPresetId\r\n\r\n const model = getEffectiveModel()\r\n if (model) {\r\n model.traverse((obj: THREE.Object3D) => {\r\n if (!(obj instanceof THREE.Mesh)) return\r\n const part = partInfos.find((p) => p.meshId === obj.uuid)\r\n if (!part) return\r\n applyColorsToMesh(obj, part)\r\n })\r\n }\r\n emitter.emit('change', getState())\r\n }\r\n\r\n function setPartColor(partIdOrMeshId: string, colorOrPresetId: string, slotIndex?: number): void {\r\n const key = slotIndex !== undefined ? `${partIdOrMeshId}:${slotIndex}` : partIdOrMeshId\r\n partColorOverrides[key] = colorOrPresetId\r\n\r\n const model = getEffectiveModel()\r\n if (model) {\r\n model.traverse((obj: THREE.Object3D) => {\r\n if (!(obj instanceof THREE.Mesh)) return\r\n const part = partInfos.find((p) => p.meshId === obj.uuid)\r\n if (!part) return\r\n if (part.partId === partIdOrMeshId || part.meshId === partIdOrMeshId) {\r\n applyColorsToMesh(obj, part)\r\n }\r\n })\r\n }\r\n emitter.emit('change', getState())\r\n }\r\n\r\n function clearMaterialColor(slotIdOrName: string): void {\r\n delete materialOverrides[slotIdOrName]\r\n for (const slot of materialSlots) {\r\n if (slot.slotId === slotIdOrName || slot.name === slotIdOrName) {\r\n delete materialOverrides[slot.slotId]\r\n delete materialOverrides[slot.name]\r\n }\r\n }\r\n const model = getEffectiveModel()\r\n if (model) {\r\n model.traverse((obj: THREE.Object3D) => {\r\n if (!(obj instanceof THREE.Mesh)) return\r\n const part = partInfos.find((p) => p.meshId === obj.uuid)\r\n if (!part) return\r\n applyColorsToMesh(obj, part)\r\n })\r\n }\r\n emitter.emit('change', getState())\r\n }\r\n\r\n function clearPartColor(partIdOrMeshId: string, slotIndex?: number): void {\r\n if (slotIndex !== undefined) {\r\n delete partColorOverrides[`${partIdOrMeshId}:${slotIndex}`]\r\n } else {\r\n delete partColorOverrides[partIdOrMeshId]\r\n for (const k of Object.keys(partColorOverrides)) {\r\n if (k.startsWith(`${partIdOrMeshId}:`)) {\r\n delete partColorOverrides[k]\r\n }\r\n }\r\n }\r\n const model = getEffectiveModel()\r\n if (model) {\r\n model.traverse((obj: THREE.Object3D) => {\r\n if (!(obj instanceof THREE.Mesh)) return\r\n const part = partInfos.find((p) => p.meshId === obj.uuid)\r\n if (!part) return\r\n if (part.partId === partIdOrMeshId || part.meshId === partIdOrMeshId) {\r\n applyColorsToMesh(obj, part)\r\n }\r\n })\r\n }\r\n emitter.emit('change', getState())\r\n }\r\n\r\n function clearOverrides(): void {\r\n materialOverrides = {}\r\n partColorOverrides = {}\r\n const model = getEffectiveModel()\r\n if (model) {\r\n model.traverse((obj: THREE.Object3D) => {\r\n if (!(obj instanceof THREE.Mesh)) return\r\n const part = partInfos.find((p) => p.meshId === obj.uuid)\r\n if (!part) return\r\n applyColorsToMesh(obj, part)\r\n })\r\n }\r\n emitter.emit('change', getState())\r\n }\r\n\r\n function getMaterials(): MaterialSlotInfo[] {\r\n return [...materialSlots]\r\n }\r\n\r\n function getParts(): PartInfo[] {\r\n return [...partInfos]\r\n }\r\n\r\n function getState(): ViewerState {\r\n return buildState(\r\n metalColor,\r\n stoneColor,\r\n partOverrides,\r\n camera,\r\n controls,\r\n materialOverrides,\r\n partColorOverrides,\r\n )\r\n }\r\n\r\n function setState(state: ViewerState): StateRestoreResult {\r\n partOverrides = {}\r\n materialOverrides = {}\r\n partColorOverrides = {}\r\n\r\n const availablePartIds = new Set(partInfos.map((p) => p.partId))\r\n const availableSlotIds = new Set(materialSlots.map((s) => s.slotId))\r\n const availableMaterialNames = new Set(materialSlots.map((s) => s.name))\r\n\r\n const result = restoreState(\r\n state,\r\n setMetalColor,\r\n setStoneColor,\r\n setPartType,\r\n camera,\r\n controls,\r\n {\r\n setMaterialColor,\r\n setPartColor,\r\n availablePartIds,\r\n availableSlotIds,\r\n availableMaterialNames,\r\n },\r\n )\r\n return result\r\n }\r\n\r\n // Restore initial state if passed in options\r\n if (options.initialState) {\r\n setState(options.initialState)\r\n controlsHandle.initialPosition.copy(camera.position)\r\n controlsHandle.initialTarget.copy(controls.target)\r\n }\r\n\r\n function on<K extends keyof ViewerEvents>(\r\n event: K,\r\n cb: (data: ViewerEvents[K]) => void,\r\n ): () => void {\r\n return emitter.on(event, cb)\r\n }\r\n\r\n function dispose(): void {\r\n if (qualityDebounceTimer !== null) {\r\n clearTimeout(qualityDebounceTimer)\r\n qualityDebounceTimer = null\r\n }\r\n abortController?.abort()\r\n if (typeof cancelAnimationFrame !== 'undefined') {\r\n cancelAnimationFrame(rafId)\r\n }\r\n if (typeof document !== 'undefined') {\r\n document.removeEventListener('visibilitychange', onVisibility)\r\n }\r\n canvas.removeEventListener?.('webglcontextrestored', handleContextRestored)\r\n globalDiamondBaker.clearCache()\r\n ro?.disconnect()\r\n shadowHandle.dispose()\r\n interaction.dispose()\r\n controlsHandle.dispose()\r\n if (currentModel) {\r\n scene.remove(currentModel)\r\n disposeModel(currentModel)\r\n currentModel = null\r\n }\r\n metalHdrHandle?.dispose()\r\n gemHdrHandle?.dispose()\r\n disposeScene()\r\n rendererHandle.dispose()\r\n emitter.clear()\r\n }\r\n\r\n function toggleRotation(speed?: number): boolean {\r\n if (speed !== undefined) {\r\n controls.autoRotateSpeed = speed\r\n }\r\n controls.autoRotate = !controls.autoRotate\r\n return controls.autoRotate\r\n }\r\n\r\n function startRotation(speed?: number): void {\r\n if (speed !== undefined) {\r\n controls.autoRotateSpeed = speed\r\n }\r\n controls.autoRotate = true\r\n }\r\n\r\n function stopRotation(): void {\r\n controls.autoRotate = false\r\n }\r\n\r\n function isRotating(): boolean {\r\n return controls.autoRotate\r\n }\r\n\r\n function resetCamera(): void {\r\n controlsHandle.resetCamera()\r\n }\r\n\r\n function fitToScene(): void {\r\n if (currentModel) {\r\n fitCameraToScene(currentModel, camera, controls, options)\r\n }\r\n }\r\n\r\n async function captureSnapshot(\r\n snapshotOptions?: { format?: 'image/png' | 'image/jpeg'; quality?: number },\r\n ): Promise<string> {\r\n const format = snapshotOptions?.format ?? 'image/png'\r\n const quality = snapshotOptions?.quality ?? 0.95\r\n renderer.render(scene, camera)\r\n return renderer.domElement.toDataURL(format, quality)\r\n }\r\n\r\n function setQuality(quality: 'low' | 'medium' | 'high'): void {\r\n rendererHandle.setQuality(quality)\r\n }\r\n\r\n function setShadowsEnabled(enabled: boolean): void {\r\n shadowHandle.setVisible(enabled)\r\n }\r\n\r\n function unload(): void {\r\n abortController?.abort()\r\n if (currentModel) {\r\n scene.remove(currentModel)\r\n disposeModel(currentModel)\r\n currentModel = null\r\n }\r\n partInfos = []\r\n partOverrides = {}\r\n materialSlots = []\r\n materialOverrides = {}\r\n partColorOverrides = {}\r\n shadowHandle.mesh.position.y = 0\r\n shadowHandle.setScale(1)\r\n }\r\n\r\n function setDiamondQuality(quality: DiamondQuality): void {\r\n const capped = applyMobileCap(quality)\r\n\r\n // Debounce: shader recompile is expensive; ignore rapid calls, apply last value\r\n if (qualityDebounceTimer !== null) {\r\n clearTimeout(qualityDebounceTimer)\r\n }\r\n qualityDebounceTimer = setTimeout(() => {\r\n qualityDebounceTimer = null\r\n currentDiamondQuality = capped\r\n if (!currentModel) return\r\n\r\n const { rayBounces, cubeResolution } = resolveQualityTier(capped)\r\n\r\n currentModel.traverse((obj) => {\r\n if (!(obj instanceof THREE.Mesh)) return\r\n const part = partInfos.find((p) => p.meshId === obj.uuid)\r\n if (part?.type !== 'stone') return\r\n\r\n const mat = obj.material\r\n if (!(mat instanceof ReferenceDiamondMaterial)) return\r\n\r\n // Re-acquire handle at new resolution, then swap material\r\n const oldHandle = mat.bakeHandle\r\n const newHandle = globalDiamondBaker.acquire(obj.geometry, renderer, { resolution: cubeResolution })\r\n if (!newHandle) return // not bakeable\r\n globalDiamondBaker.release(oldHandle)\r\n\r\n const envTex = (mat.uniforms.envMap?.value as THREE.Texture | undefined) ?? gemEnv\r\n // Use mat.preset to preserve stone identity and prevent cross-mesh cache collisions\r\n const newMat = acquireReferenceDiamondMaterial(\r\n newHandle,\r\n envTex!,\r\n mat.preset,\r\n { rayBounces, quality: capped, orientEnvMap: mat.defines['DIA_ORIENT_ENVMAP'] === 1 },\r\n )\r\n\r\n releaseReferenceDiamondMaterial(mat)\r\n obj.material = newMat\r\n })\r\n }, 300) // 300 ms debounce\r\n }\r\n\r\n const viewer: Viewer = {\r\n load,\r\n unload,\r\n setMetalColor,\r\n setStoneColor,\r\n setPartType,\r\n setMaterialColor,\r\n setPartColor,\r\n clearMaterialColor,\r\n clearPartColor,\r\n clearOverrides,\r\n getMaterials,\r\n getParts,\r\n getState,\r\n setState,\r\n on,\r\n dispose,\r\n toggleRotation,\r\n startRotation,\r\n stopRotation,\r\n isRotating,\r\n resetCamera,\r\n fitToScene,\r\n captureSnapshot,\r\n setQuality,\r\n setShadowsEnabled,\r\n setMetalEnvironment,\r\n setGemEnvironment,\r\n setDiamondQuality,\r\n }\r\n\r\n if (typeof window !== 'undefined') {\r\n ;(viewer as any).__scene = scene\r\n ;(viewer as any).__getCurrentModel = () => currentModel\r\n }\r\n\r\n return viewer\r\n}\r\n","// Public API for @3d-viewer/core\r\n\r\nexport { createViewer } from './viewer'\r\nexport type { Viewer } from './types'\r\n\r\nexport {\r\n METAL_PRESETS,\r\n STONE_PRESETS,\r\n PHYSICALLY_BASED_METAL_PRESETS,\r\n DIAMOND_PRESETS,\r\n GEMSTONE_PRESETS,\r\n ALL_METAL_PRESETS,\r\n ALL_STONE_PRESETS,\r\n CANONICAL_METAL_PRESETS,\r\n CANONICAL_STONE_PRESETS,\r\n getMetalPreset,\r\n getStonePreset,\r\n} from './materials/presets'\r\nexport type {\r\n MetalPreset,\r\n StonePreset,\r\n StandardMetalId,\r\n StandardStoneId,\r\n MetalColorProp,\r\n StoneColorProp,\r\n} from './materials/presets'\r\n\r\nexport type {\r\n ModelSource,\r\n ViewerSourceInput,\r\n LoadOptions,\r\n SupportedFormat,\r\n ConvertedModel,\r\n PartType,\r\n PartInfo,\r\n MaterialSlotInfo,\r\n MeshMaterialSlot,\r\n StateRestoreResult,\r\n ViewerState,\r\n ViewerEvents,\r\n ViewerOptions,\r\n DiamondQuality,\r\n} from './types'\r\n\r\nexport { resolveQualityTier } from './materials'\r\nexport { UnsupportedFormatError, CorruptFileError, NetworkError } from './converter/errors'\r\nexport { convert, normalizeModelSource, inferFormatFromUrl } from './converter'\r\nexport { DEFAULT_DRACO_DECODER_PATH } from './converter/loaders'\r\nexport { loadHdrEnvironment } from './materials/environment'\r\nexport type { HdrEnvironmentHandle } from './materials/environment'\r\nexport { loadPmat, loadDmatPreset, loadDmatMaterial } from './materials/format-loaders'\r\nexport type { PmatJson, DmatJson } from './materials/format-loaders'\r\nexport const VERSION = '1.0.0'\r\n"],"names":["UnsupportedFormatError","format","__publicField","CorruptFileError","message","cause","NetworkError","status","url","normalizeScene","scene","box","THREE","center","size","maxDim","scale","DEFAULT_DRACO_DECODER_PATH","NodeFileReader","blob","buf","_a","_b","err","nodeBuffer","base64","SIZE_WARN_BYTES","parseToScene","fetched","dracoDecoderPath","warnings","parseGltf","parseStl","parseObj","loader","GLTFLoader","dracoLoader","DRACOLoader","gltf","resolve","reject","STLLoader","geometry","material","mesh","materials","mtlLoader","MTLLoader","mtlText","objLoader","OBJLoader","text","exportToGlb","exporter","GLTFExporter","result","bytes","TypedEmitter","event","cb","data","EXT_TO_FORMAT","MIME_TO_FORMAT","inferFormatFromUrl","pathname","dot","ext","inferFormatFromMime","mime","base","inferFormatFromBuffer","buffer","decompressIfGzip","ds","stream","decompressed","fetchSource","source","signal","mtlData","response","ct","mtlRes","SUPPORTED_FORMATS","normalizeModelSource","trimmed","convert","onProgress","options","glb","meshCount","obj","STONE_KEYWORDS","METAL_KEYWORDS","hasKeyword","keywords","lower","kw","sanitizeName","name","getStablePartId","usedIds","id","clean","path","curr","uniquePath","counter","getMeshMaterialSlots","mat","idx","_c","classifyByName","materialName","combined","isStone","isMetal","classifyParts","overrides","parts","partId","slots","primaryMaterialName","allMaterialNames","s","isOverridden","overriddenType","extractMaterialSlots","map","part","slot","existing","METAL_PRESETS","STONE_PRESETS","ALL_METAL_PRESETS","ALL_STONE_PRESETS","PHYSICALLY_BASED_METAL_PRESETS","m","DIAMOND_PRESETS","GEMSTONE_PRESETS","LEGACY_METAL_ALIAS_IDS","LEGACY_STONE_ALIAS_IDS","CANONICAL_METAL_PRESETS","CANONICAL_STONE_PRESETS","getMetalPreset","idOrHex","query","getStonePreset","hashMap","analyzeGeometry","g","centroid","rawRadius","radius","posAttr","index","triangleCount","totalArea","failureArea","signedVolume","p0","p1","p2","e1","e2","normal","crossP1P2","i","i0","i1","i2","doubleArea","area","D","starConvexFailureArea","flippedWinding","buildFacetAttribute","a","vertexCount","facetData","windingSign","len","v","hashGeometry","cached","hash","fnv1a","val","p","CENTER","AVERAGE","SAH","CONTAINED","PRIMITIVE_INTERSECT_COST","TRAVERSAL_COST","BYTES_PER_NODE","UINT32_PER_NODE","IS_LEAFNODE_FLAG","LEAFNODE_MASK_32","FLOAT32_EPSILON","SKIP_GENERATION","DEFAULT_OPTIONS","arrayToBox","nodeIndex32","array","target","getLongestEdgeIndex","bounds","splitDimIdx","splitDist","dist","copyBounds","unionBounds","b","aVal","bVal","d","d3","expandByPrimitiveBounds","startIndex","primitiveBounds","tCenter","tHalf","tMin","tMax","computeSurfaceArea","d0","d1","d2","IS_LEAF","n16","uint16Array","OFFSET","n32","uint32Array","COUNT","LEFT_NODE","RIGHT_NODE","relativeOffset","SPLIT_AXIS","getBounds","offset","count","centroidTarget","minx","miny","minz","maxx","maxy","maxz","cminx","cminy","cminz","cmaxx","cmaxy","cmaxz","boundsOffset","end","cx","hx","lx","rx","cy","hy","ly","ry","cz","hz","lz","rz","BIN_COUNT","binsSort","sahBins","leftBounds","getOptimalSplit","nodeBoundingData","centroidBoundingData","strategy","axis","pos","getAverage","rootSurfaceArea","bestCost","cStart","cEnd","axisLeft","binWidth","truncatedBins","c","bin","leftCacheBounds","rightCacheBounds","splitCount","bi","leftCount","rightCount","rightBounds","leftProb","rightProb","cost","binIndex","lastBin","nextBin","binCount","avg","BVHNode","partition","stride","split","left","right","axisOffset","t0","r","tb","float32Array","uint8Array","MAX_POINTER","countNodes","node","populateBuffer","byteOffset","_populateBuffer","node32Index","node16Index","isLeaf","boundingData","splitAxis","leftByteOffset","rightByteOffset","currentNodeIndex","relativeRightIndex","buildTree","bvh","loadRange","maxDepth","verbose","targetLeafSize","_strictLeafSize","partitionBuffer","partitionStride","cacheCentroidBoundingData","reachedMaxDepth","root","splitNode","triggerProgress","primitivesProcessed","depth","mustSplit","splitOffset","lstart","lcount","rstart","rcount","buildPackedTree","BufferConstructor","rootRanges","firstRange","lastRange","fullRange","range","nodeCount","PrimitivePool","getNewPrimitive","primitives","primitive","_BufferStack","stack","prevBuffer","BufferStack","_box1","_box2","boxStack","boxPool","Box3","shapecast","intersectsBounds","intersectsRange","boundsTraverseOrder","nodeOffset","shapecastTraverse","length","intersectsBoundsFunc","intersectsRangeFunc","nodeScoreFunc","nodeIndexOffset","nodeIndex16","getLeftOffset","getRightEndOffset","c1","c2","score1","score2","box1","box2","temp","isC1Leaf","c1Intersection","c1StopTraversal","isC2Leaf","c2Intersection","c2StopTraversal","_bufferStack1","_bufferStack2","_boxPool","_leftBox1","_rightBox1","_leftBox2","_rightBox2","_active","bvhcast","otherBvh","matrixToLocal","intersectsRanges","roots","otherRoots","nodeOffset1","nodeOffset2","invMat","Matrix4","il","localBox","j","jl","_traverse","node1Index32","node2Index32","matrix2to1","matrix1to2","intersectsRangesFunc","node1IndexOffset","node2IndexOffset","depth1","depth2","currBox","reversed","bufferStack1","bufferStack2","float32Array1","uint32Array1","uint16Array1","float32Array2","uint32Array2","uint16Array2","node1Index16","node2Index16","isLeaf1","isLeaf2","newBox","cl1","cr1","intersectCl1","intersectCr1","cl2","cr2","leftIntersects","rightIntersects","BVHTraversalHelper","traversing","walk","callback","_tempBox","_tempBuffer","BVH","targetBuffer","baseIndex","minX","minY","minZ","maxX","maxY","maxZ","indirectBuffer","l","rootIndex","totalNodes","rootCount","nodeIndex","leftMin","leftMax","rightMin","rightMax","callbacks","intersectsPrimitive","scratchPrimitive","iterate","originalIntersectsRange","contained","shapecastFunc","isSharedArrayBufferSupported","getVertexCount","geo","getTriCount","getIndexArray","ensureIndex","BufferAttribute","getFullPrimitiveRange","primitiveCount","drawRange","start","getPrimitiveGroupRanges","group","getRootPrimitiveRanges","primitiveRanges","ranges","drawRangeStart","drawRangeEnd","events","groupStart","groupCount","groupEnd","activeGroups","lastPos","newPos","generateIndirectBuffer","useSharedArrayBuffer","useUint32","acc","byteCount","GeometryBVH","primitiveStride","SeparatingAxisBounds","points","field","min","max","other","Vector3","boxMin","boxMax","x","y","z","closestPointLineToLine","dir1","dir2","v02","l1","l2","v0","v10","v2","v32","d0232","d3210","d3232","d0210","denom","closestPointsSegmentToSegment","paramResult","Vector2","temp1","temp2","target1","target2","closestPoint","closestPoint2","sphereIntersectTriangle","closestPointTemp","projectedPointTemp","planeTemp","Plane","lineTemp","Line3","sphere","triangle","plane","pp","componentKeys","ZERO_EPSILON","ZERO_EPSILON_SQR","isNearZero","value","ExtendedTriangle","Triangle","args","satAxes","satBounds","axis0","sab0","axis1","sab1","axis2","sab2","axis3","sab3","lengthAB","lengthBC","lengthCA","point1","point2","edge","segment","distSq","closestDistanceSq","nexti","saTri2","cachedSatBounds","cachedSatBounds2","tmpVec","tempDir","edge1","edge2","tempPoint","bounds1","bounds2","coplanarIntersectsTriangle","self","suppressLog","planeNormal","satBounds1","satAxes1","sb","sa","satBounds2","satAxes2","findSingleBounds","aProj","bProj","cProj","aDist","bDist","cDist","t","findIntersectionLineBounds","abDist","acDist","intersectTriangleSegment","degenerateTriangle","startDist","endDist","intersectTrianglePoint","point","intersectSegmentPoint","segmentTri","pointTri","handleDegenerateCases","segment1","segment2","delta1","delta2","startDelta","u","z1","z2","res","plane1","plane2","a1Dist","b1Dist","c1Dist","a1b1Dist","a1c1Dist","a2Dist","b2Dist","c2Dist","a2b2Dist","a2c2Dist","intersectionLine","componentIndex","maxComponent","comp1","key","a1Proj","b1Proj","c1Proj","a2Proj","b2Proj","c2Proj","tmp","cornerFields","line1","line2","lineTarget","otherVec","thisVec","f11","f12","f21","f22","OrientedBox","matrix","minVec","pi","alignedSatBounds","aabbBounds","saTri","pointsArr","cachedAxis","triSatBounds","triSatAxes","sa1","sa2","xyzFields","segments1","segments2","threshold","threshold2","nextIndex","nextIndex2","index2","f1","f2","f3","ExtendedTrianglePoolBase","ExtendedTrianglePool","closestPointToPoint","minThreshold","maxThreshold","minThresholdSq","maxThresholdSq","closestDistanceTriIndex","score","tri","triIndex","closestDistance","IS_GT_REVISION_169","REVISION","IS_LT_REVISION_161","_vA","_vB","_vC","_uvA","_uvB","_uvC","_normalA","_normalB","_normalC","_intersectionPoint","checkIntersection","ray","pA","pB","pC","side","near","far","intersect","BackSide","DoubleSide","distance","checkBufferGeometryIntersection","position","uv","uv1","intersection","face","barycoord","getSide","materialOrSide","intersectTri","intersections","triOffset","groups","firstIndex","materialIndex","setTriangle","ta","tc","intersectTris","_indirectBuffer","intersectClosestTri","iterateOverTriangles","intersectsTriangleFunc","refit","nodeIndices","indexArr","force","forceChildren","includesLeft","includesRight","leftNodeId","rightNodeId","traverseLeft","traverseRight","leftChange","rightChange","didChange","left_i","right_i","minLeftValue","maxLeftValue","minRightValue","maxRightValue","intersectsNodeBounds","tmin","tmax","tymin","tymax","tzmin","tzmax","invdirx","invdiry","invdirz","ox","oy","oz","intersectTris_indirect","vi","intersectClosestTri_indirect","iterateOverTriangles_indirect","raycast","intersects","_raycast","leftIndex","rightIndex","_xyzFields","raycastFirst","_raycastFirst","xyzAxis","leftToRight","c1Result","c2Result","boundingBox","triangle2","invertedMat","obb","obb2","intersectsGeometry","otherGeometry","geometryToBvh","_intersectsGeometry","cachedObb","thisGeometry","thisIndex","thisPos","otherIndex","otherPos","otherTriangleCount","tempMatrix","temp3","temp4","closestPointToGeometry","tempTarget1","tempTargetDest1","tempTarget2","tempTargetDest2","closestDistanceOtherTriIndex","otherOffset","otherCount","triCount","refit_indirect","raycast_indirect","raycastFirst_indirect","intersectsGeometry_indirect","ti","closestPointToGeometry_indirect","ti2","convertRaycastIntersect","hit","object","raycaster","_obb","_ray","Ray","_direction","_inverseMatrix","_worldScale","_getters","MeshBVH","rootData","indexAttribute","fixupVersion0","newIndex","tri3","ai","ci","el","normalized","posArr","bufferOffset","getters","writeOffset","boundsIndexOffset","halfExtents","el2","scaleFactor","hits","FrontSide","raycastFunc","closestResult","raycastFirstFunc","geomToMesh","intersectsGeometryFunc","intersectsTriangles","triangle1","indexAttr1","positionAttr1","assignTriangle1","indexAttr2","positionAttr2","assignTriangle2","iterateOverDoubleTriangles","offset1","count1","offset2","count2","nodeIndex1","nodeIndex2","originalIntersectsRanges","boxToMesh","countToStringFormat","countToFormat","RedFormat","RGFormat","RGBAFormat","countToIntFormat","RedIntegerFormat","RGIntegerFormat","RGBAIntegerFormat","VertexAttributeTexture","DataTexture","NearestFilter","attr","overrideItemSize","originalItemSize","originalCount","itemSize","originalBufferCons","targetType","finalStride","FloatType","UnsignedIntType","IntType","type","normalizeValue","targetBufferCons","internalFormat","UnsignedByteType","ByteType","ShortType","UnsignedShortType","dimension","dataArray","originalNormalized","ii","UIntVertexAttributeTexture","FloatVertexAttributeTexture","MeshBVHUniformStruct","bvhToTextures","dereferenceIndex","bvhBounds","bvhContents","unpacked","indexArray","i3","v3","boundsTexture","contentsTexture","boundsDimension","boundsArray","contentsDimension","contentsArray","boundsIndex","mergedLeafCount","rightNodeIndex","common_functions","bvh_ray_functions","bvh_struct_definitions","shaderStructs","BVHShaderGLSL.bvh_struct_definitions","shaderIntersectFunction","BVHShaderGLSL.common_functions","BVHShaderGLSL.bvh_ray_functions","DIAMOND_BAKE_VERT","DIAMOND_BAKE_FRAG","DIAMOND_RAYMARCH_VERT","DIAMOND_RAYMARCH_FRAG","DiamondNormalBaker","renderer","opts","analysis","isUnorm","renderTarget","handle","bakeGeo","bakeMat","camera","prevRenderTarget","prevAutoClear","prevToneMapping","prevClearColor","prevClearAlpha","gl","preError","postError","entry","newTarget","globalDiamondBaker","_invMat","DiamondMaterial","envMap","preset","physOpts","bvhValue","_renderer","_scene","_geometry","materialCache","acquireDiamondMaterial","optSuffix","releaseDiamondMaterial","JewelryStudioEnvironment","domeGeo","domeMat","dome","topGeo","topMat","topPanel","leftSoftboxGeo","leftSoftboxMat","leftSoftbox","rightSoftboxGeo","rightSoftboxMat","rightSoftbox","rimGeo","rimMat","leftRim","rightRim","groundGeo","groundMat","ground","flagGeo","flagMat","leftFlag","rightFlag","resources","setupEnvironment","pmremGenerator","studioEnv","env","JewelryGemEnvironment","upperSoftboxes","lateralSoftboxes","zenithBaffleGeo","zenithBaffleMat","zenithBaffle","flagPositions","fx","fy","fz","flag","emitterPositions","panelGeo","panelMat","panel","setupGemEnvironment","cubeTarget","cubeCamera","gemEnv","prevTarget","loadHdrEnvironment","urlOrData","processDataTexture","dataTexture","gemRenderTarget","isExr","EXRLoader","dataTex","RGBELoader","hdrTexture","bvhCache","getOrCreateDiamondBVH","targetGeom","boundsTree","bvhStruct","parseJson","input","toColorHex","loadPmat","json","loadDmatPreset","hex","bf","loadDmatMaterial","DIAMOND_REF_VERT","DIAMOND_REF_FRAG","resolveQualityTier","q","ReferenceDiamondMaterial","rayBounces","isCube","bfR","bfG","bfB","_r","_s","_g","tex","newType","cloned","acquireReferenceDiamondMaterial","qualityKey","orientKey","releaseReferenceDiamondMaterial","applyMetalMaterial","hexOrPresetId","slotIndex","applyStoneMaterial","oldHandle","newMat","ensureMaterial","diamondMode","isPhysical","isDiamond","prev","metal","isRefDiamond","resolvedEnv","stone","createRenderer","container","cameraOrOptions","antialiasOrOptions","aa","initialQuality","setQuality","quality","dpr","targetDpr","ro","w","h","createScene","background","fov","bgColor","keyLight","fillLight","updateCameraAspect","width","height","createControls","domElement","controls","OrbitControls","initialPosition","initialTarget","resetCamera","fitCameraToScene","controlsOrHandle","fovRad","createInteraction","emitter","getParts","pointer","hoveredMesh","hoveredSlotIndex","hoveredOriginalEmissive","hoveredOriginalIntensity","isDragging","pointerDownPos","enableHighlight","getMeshes","meshes","getMaterial","setHover","slotIdx","onPointerMove","e","rect","firstHit","onPointerLeave","onPointerDown","onPointerUp","dx","dy","targetMesh","clickedSlotIndex","onDragStart","onDragEnd","buildState","metalColor","stoneColor","partOverrides","materialColors","partColors","modelId","state","restoreState","applyMetalColor","applyStoneColor","setPartType","unresolvedParts","unresolvedMaterials","partIdOrMeshId","slotIdOrName","color","partTarget","colonIdx","createContactShadowPlane","texture","canvas","ctx","gradient","canvasTexture","visible","disposeModel","model","_d","_e","createViewer","sceneHandle","disposeScene","rendererHandle","controlsHandle","shadowHandle","metalHdrHandle","gemHdrHandle","applyMobileCap","requested","mobileMax","order","currentDiamondQuality","qualityDebounceTimer","setMetalEnvironment","currentModel","setGemEnvironment","handleContextRestored","partInfos","materialSlots","materialOverrides","partColorOverrides","abortController","rafId","paused","render","onVisibility","wasPaused","interaction","getEffectiveModel","viewer","mock","resolveMeshSlotColor","partSlotKey","meshSlotKey","ensureUniqueMeshMaterial","o","applyColorsToMesh","anyOverridden","_","load","currentAbort","converted","setDiamondQuality","setMetalColor","getState","setStoneColor","meshIdOrPartId","targetKey","setMaterialColor","colorOrPresetId","matchingSlots","setPartColor","clearMaterialColor","clearPartColor","k","clearOverrides","getMaterials","setState","availablePartIds","availableSlotIds","availableMaterialNames","on","dispose","toggleRotation","speed","startRotation","stopRotation","isRotating","fitToScene","captureSnapshot","snapshotOptions","setShadowsEnabled","enabled","unload","capped","cubeResolution","newHandle","envTex","VERSION"],"mappings":"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AA6B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,ECA7BC,GAA8B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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","x_google_ignoreList":[11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57]}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/converter/errors.ts","../src/converter/normalize.ts","../src/converter/loaders.ts","../src/events/index.ts","../src/converter/fetch.ts","../src/converter/source-resolver.ts","../src/converter/index.ts","../src/parts/keywords.ts","../src/parts/index.ts","../src/materials/presets.ts","../src/materials/gem-geometry.ts","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/Constants.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/utils/ArrayBoxUtilities.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/utils/nodeBufferUtils.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/build/computeBoundsUtils.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/build/splitUtils.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/BVHNode.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/build/sortUtils.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/build/buildUtils.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/build/buildTree.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/utils/PrimitivePool.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/utils/BufferStack.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/cast/shapecast.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/cast/bvhcast.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/BVHTraversalHelper.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/BVH.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/utils/BufferUtils.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/build/geometryUtils.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/GeometryBVH.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/math/SeparatingAxisBounds.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/math/MathUtilities.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/math/ExtendedTriangle.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/math/OrientedBox.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/utils/ExtendedTrianglePool.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/cast/closestPointToPoint.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/utils/ThreeRayIntersectUtilities.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/utils/TriangleUtilities.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/utils/iterationUtils.generated.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/cast/refit.generated.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/utils/intersectUtils.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/utils/iterationUtils_indirect.generated.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/cast/raycast.generated.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/cast/raycastFirst.generated.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/cast/intersectsGeometry.generated.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/cast/closestPointToGeometry.generated.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/cast/refit_indirect.generated.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/cast/raycast_indirect.generated.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/cast/raycastFirst_indirect.generated.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/cast/intersectsGeometry_indirect.generated.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/cast/closestPointToGeometry_indirect.generated.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/utils/GeometryRayIntersectUtilities.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/core/MeshBVH.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/webgl/VertexAttributeTexture.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/webgl/MeshBVHUniformStruct.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/webgl/glsl/common_functions.glsl.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/webgl/glsl/bvh_ray_functions.glsl.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/webgl/glsl/bvh_struct_definitions.glsl.js","../../../node_modules/.pnpm/three-mesh-bvh@0.9.15_three@0.160.1/node_modules/three-mesh-bvh/src/index.js","../src/materials/diamond-shaders.ts","../src/materials/diamond-baker.ts","../src/materials/diamond-material.ts","../src/materials/environment.ts","../src/materials/diamond-bvh.ts","../src/materials/format-loaders.ts","../src/materials/diamond-reference-shaders.ts","../src/materials/diamond-reference-material.ts","../src/materials/index.ts","../src/viewer/renderer.ts","../src/viewer/scene.ts","../src/viewer/controls.ts","../src/viewer/interaction.ts","../src/viewer/state.ts","../src/viewer/shadow.ts","../src/viewer/index.ts","../src/index.ts"],"sourcesContent":["export class UnsupportedFormatError extends Error {\n readonly format: string\n\n constructor(format: string) {\n super(`Unsupported format: \"${format}\"`)\n this.name = 'UnsupportedFormatError'\n this.format = format\n Object.setPrototypeOf(this, UnsupportedFormatError.prototype)\n }\n}\n\nexport class CorruptFileError extends Error {\n override readonly cause?: unknown\n\n constructor(message: string, cause?: unknown) {\n super(message)\n this.name = 'CorruptFileError'\n this.cause = cause\n Object.setPrototypeOf(this, CorruptFileError.prototype)\n }\n}\n\nexport class NetworkError extends Error {\n readonly status?: number\n readonly url?: string\n\n constructor(message: string, status?: number, url?: string) {\n super(message)\n this.name = 'NetworkError'\n this.status = status\n this.url = url\n Object.setPrototypeOf(this, NetworkError.prototype)\n }\n}\n","import * as THREE from 'three'\n\n/**\n * Mutates the scene in place:\n * 1. Centers the bounding box at the world origin.\n * 2. Scales uniformly so the longest axis = 1.0 unit.\n */\nexport function normalizeScene(scene: THREE.Group): void {\n scene.position.set(0, 0, 0)\n scene.scale.set(1, 1, 1)\n scene.updateMatrixWorld(true)\n\n const box = new THREE.Box3().setFromObject(scene)\n const center = box.getCenter(new THREE.Vector3())\n const size = box.getSize(new THREE.Vector3())\n\n const maxDim = Math.max(size.x, size.y, size.z)\n const scale = maxDim > 0 ? 1 / maxDim : 1\n\n // Scale\n scene.scale.setScalar(scale)\n // Center\n scene.position.sub(center.multiplyScalar(scale))\n // Re-center after scale\n scene.updateMatrixWorld(true)\n}\n","import * as THREE from 'three'\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'\nimport { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'\nimport { STLLoader } from 'three/examples/jsm/loaders/STLLoader.js'\nimport { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js'\nimport { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader.js'\nimport { GLTFExporter } from 'three/examples/jsm/exporters/GLTFExporter.js'\n\nexport const DEFAULT_DRACO_DECODER_PATH = 'https://www.gstatic.com/draco/versioned/decoders/1.5.6/'\nimport { CorruptFileError } from './errors'\nimport type { FetchedSource } from './fetch'\nimport { normalizeScene } from './normalize'\n\n// Polyfill FileReader for Node environments (e.g. Vitest / Node runtime) if not present\nif (typeof globalThis.FileReader === 'undefined') {\n class NodeFileReader {\n result: ArrayBuffer | string | null = null\n onloadend: (() => void) | null = null\n onload: (() => void) | null = null\n onerror: ((err: unknown) => void) | null = null\n\n readAsArrayBuffer(blob: Blob) {\n blob.arrayBuffer().then(\n (buf) => {\n this.result = buf\n this.onload?.()\n this.onloadend?.()\n },\n (err) => {\n this.onerror?.(err)\n this.onloadend?.()\n },\n )\n }\n\n readAsDataURL(blob: Blob) {\n blob.arrayBuffer().then(\n (buf) => {\n const nodeBuffer = (globalThis as unknown as { Buffer?: { from: (b: ArrayBuffer) => { toString: (e: string) => string } } }).Buffer\n const base64 = nodeBuffer ? nodeBuffer.from(buf).toString('base64') : ''\n this.result = `data:${blob.type};base64,${base64}`\n this.onload?.()\n this.onloadend?.()\n },\n (err) => {\n this.onerror?.(err)\n this.onloadend?.()\n },\n )\n }\n }\n ;(globalThis as unknown as { FileReader: typeof NodeFileReader }).FileReader = NodeFileReader\n}\n\nconst SIZE_WARN_BYTES = 50 * 1024 * 1024 // 50 MB\n\nexport interface ParseResult {\n scene: THREE.Group\n warnings: string[]\n}\n\nexport async function parseToScene(\n fetched: FetchedSource,\n dracoDecoderPath?: string,\n): Promise<ParseResult> {\n const warnings: string[] = []\n\n if (fetched.data.byteLength > SIZE_WARN_BYTES) {\n warnings.push('File exceeds 50 MB; performance may be affected')\n }\n\n switch (fetched.format) {\n case 'glb':\n case 'gltf':\n return parseGltf(fetched, warnings, dracoDecoderPath)\n case 'stl':\n return parseStl(fetched, warnings)\n case 'obj':\n return parseObj(fetched, warnings)\n }\n}\n\nasync function parseGltf(\n fetched: FetchedSource,\n warnings: string[],\n dracoDecoderPath?: string,\n): Promise<ParseResult> {\n const loader = new GLTFLoader()\n const dracoLoader = new DRACOLoader()\n dracoLoader.setDecoderPath(dracoDecoderPath ?? DEFAULT_DRACO_DECODER_PATH)\n loader.setDRACOLoader(dracoLoader)\n\n try {\n const gltf = await new Promise<{ scene: THREE.Group }>((resolve, reject) => {\n loader.parse(\n fetched.data,\n '',\n resolve,\n reject,\n )\n })\n dracoLoader.dispose()\n normalizeScene(gltf.scene)\n return { scene: gltf.scene, warnings }\n } catch (err) {\n dracoLoader.dispose()\n throw new CorruptFileError('Failed to parse GLTF/GLB', err)\n }\n}\n\nfunction parseStl(fetched: FetchedSource, warnings: string[]): ParseResult {\n const loader = new STLLoader()\n let geometry: THREE.BufferGeometry\n try {\n geometry = loader.parse(fetched.data)\n } catch (err) {\n throw new CorruptFileError('Failed to parse STL', err)\n }\n // Spec §4.3: metal uses MeshPhysicalMaterial with metalness ~1.0\n const material = new THREE.MeshPhysicalMaterial({\n name: 'metal',\n color: 0xc0c0c0,\n metalness: 1.0,\n roughness: 0.10,\n envMapIntensity: 1.0,\n })\n const mesh = new THREE.Mesh(geometry, material)\n mesh.name = 'metal'\n const scene = new THREE.Group()\n scene.add(mesh)\n normalizeScene(scene)\n return { scene, warnings }\n}\n\nasync function parseObj(fetched: FetchedSource, warnings: string[]): Promise<ParseResult> {\n if (!fetched.mtlData) {\n warnings.push('No material file provided; default material applied')\n }\n\n let materials: MTLLoader.MaterialCreator | undefined\n\n if (fetched.mtlData) {\n const mtlLoader = new MTLLoader()\n const mtlText = new TextDecoder().decode(fetched.mtlData)\n try {\n materials = mtlLoader.parse(mtlText, '')\n materials.preload()\n } catch {\n warnings.push('Failed to parse MTL file; default material applied')\n materials = undefined\n }\n }\n\n const objLoader = new OBJLoader()\n if (materials) {\n objLoader.setMaterials(materials)\n }\n\n let scene: THREE.Group\n try {\n const text = new TextDecoder().decode(fetched.data)\n scene = objLoader.parse(text) as THREE.Group\n } catch (err) {\n throw new CorruptFileError('Failed to parse OBJ', err)\n }\n\n normalizeScene(scene)\n return { scene, warnings }\n}\n\nexport async function exportToGlb(scene: THREE.Group): Promise<ArrayBuffer> {\n const exporter = new GLTFExporter()\n return new Promise<ArrayBuffer>((resolve, reject) => {\n exporter.parse(\n scene,\n (result) => {\n if (result instanceof ArrayBuffer) {\n resolve(result)\n } else {\n // JSON result — encode to binary\n const text = JSON.stringify(result)\n const bytes = new TextEncoder().encode(text)\n resolve(bytes.buffer)\n }\n },\n reject,\n { binary: true },\n )\n })\n}\n","type Listener<T> = (data: T) => void\n\nexport class TypedEmitter<Events extends object> {\n private readonly _listeners = new Map<\n keyof Events,\n Set<Listener<unknown>>\n >()\n\n on<K extends keyof Events>(\n event: K,\n cb: Listener<Events[K]>,\n ): () => void {\n if (!this._listeners.has(event)) {\n this._listeners.set(event, new Set())\n }\n this._listeners.get(event)!.add(cb as Listener<unknown>)\n return () => this.off(event, cb)\n }\n\n off<K extends keyof Events>(event: K, cb: Listener<Events[K]>): void {\n this._listeners.get(event)?.delete(cb as Listener<unknown>)\n }\n\n emit<K extends keyof Events>(event: K, data: Events[K]): void {\n this._listeners.get(event)?.forEach((cb) => {\n try {\n cb(data)\n } catch (err) {\n console.error(`[3d-viewer] uncaught listener error on \"${String(event)}\":`, err)\n }\n })\n }\n\n clear(): void {\n this._listeners.clear()\n }\n}\n","import { UnsupportedFormatError, NetworkError } from './errors'\nimport type { ModelSource, SupportedFormat } from '../types'\n\nconst EXT_TO_FORMAT: Record<string, SupportedFormat> = {\n '.stl': 'stl',\n '.obj': 'obj',\n '.glb': 'glb',\n '.gltf': 'gltf',\n}\n\nconst MIME_TO_FORMAT: Record<string, SupportedFormat> = {\n 'model/gltf-binary': 'glb',\n 'model/gltf+json': 'gltf',\n}\n\nexport function inferFormatFromUrl(url: string): SupportedFormat | null {\n try {\n const pathname = new URL(url, 'http://dummy').pathname\n const dot = pathname.lastIndexOf('.')\n if (dot === -1) return null\n const ext = pathname.slice(dot).toLowerCase()\n return EXT_TO_FORMAT[ext] ?? null\n } catch {\n return null\n }\n}\n\nexport function inferFormatFromMime(mime: string): SupportedFormat | null {\n const base = mime.split(';')[0].trim().toLowerCase()\n return MIME_TO_FORMAT[base] ?? null\n}\n\nexport function inferFormatFromBuffer(buffer: ArrayBuffer): SupportedFormat | null {\n if (buffer.byteLength < 4) return null\n const bytes = new Uint8Array(buffer, 0, Math.min(buffer.byteLength, 80))\n // GLB magic number: 0x46546C67 ('glTF' in little endian: 0x67, 0x6c, 0x54, 0x46)\n if (bytes[0] === 0x67 && bytes[1] === 0x6c && bytes[2] === 0x54 && bytes[3] === 0x46) {\n return 'glb'\n }\n // Check for JSON gltf: starts with '{'\n if (bytes[0] === 0x7b) {\n return 'gltf'\n }\n // Check for ASCII STL: starts with 'solid'\n const header = String.fromCharCode(...bytes.slice(0, 5)).toLowerCase()\n if (header === 'solid') {\n return 'stl'\n }\n return null\n}\n\nexport async function decompressIfGzip(buffer: ArrayBuffer): Promise<ArrayBuffer> {\n const bytes = new Uint8Array(buffer)\n if (bytes.length >= 2 && bytes[0] === 0x1f && bytes[1] === 0x8b) {\n if (typeof DecompressionStream !== 'undefined') {\n try {\n const ds = new DecompressionStream('gzip')\n const stream = new Blob([buffer]).stream().pipeThrough(ds)\n const decompressed = await new Response(stream).arrayBuffer()\n if (decompressed.byteLength > 0) {\n return decompressed\n }\n } catch (err) {\n console.warn('[fetchSource] Decompression failed, proceeding with original buffer:', err)\n }\n }\n }\n return buffer\n}\n\nexport interface FetchedSource {\n data: ArrayBuffer\n mtlData?: ArrayBuffer\n format: SupportedFormat\n}\n\nexport async function fetchSource(\n source: ModelSource,\n signal?: AbortSignal,\n): Promise<FetchedSource> {\n // data variant — no network call\n if ('data' in source) {\n let data =\n source.data instanceof Blob ? await source.data.arrayBuffer() : source.data\n data = await decompressIfGzip(data)\n const mtlData =\n source.mtlData instanceof Blob\n ? await source.mtlData.arrayBuffer()\n : source.mtlData\n const format = source.format || inferFormatFromBuffer(data) || 'glb'\n return { data, mtlData, format }\n }\n\n // URL variant\n let format: SupportedFormat | null | undefined = source.format ?? inferFormatFromUrl(source.url)\n\n const response = await fetch(source.url, {\n headers: source.headers,\n signal,\n }).catch((err: unknown) => {\n if ((err as Error).name === 'AbortError') throw err\n throw new NetworkError(\n `Fetch failed: ${(err as Error).message}`,\n undefined,\n source.url,\n )\n })\n\n if (!response.ok) {\n throw new NetworkError(`HTTP ${response.status}`, response.status, source.url)\n }\n\n if (!format) {\n const ct = response.headers.get('content-type') ?? ''\n format = inferFormatFromMime(ct)\n }\n\n let data = await response.arrayBuffer()\n data = await decompressIfGzip(data)\n\n if (!format) {\n format = inferFormatFromBuffer(data)\n }\n\n if (!format) {\n throw new UnsupportedFormatError('unknown')\n }\n\n let mtlData: ArrayBuffer | undefined\n if (source.mtlUrl) {\n const mtlRes = await fetch(source.mtlUrl, {\n headers: source.headers,\n signal,\n })\n if (mtlRes.ok) {\n mtlData = await mtlRes.arrayBuffer()\n }\n }\n\n return { data, mtlData, format }\n}\n","import type { ModelSource, SupportedFormat, ViewerSourceInput } from '../types'\n\nconst SUPPORTED_FORMATS: readonly SupportedFormat[] = ['glb', 'gltf', 'obj', 'stl'] as const\n\n/**\n * Infer format from a file URL or path string.\n * Defaults to 'glb' if not recognised or absent.\n */\nexport function inferFormatFromUrl(url: string): SupportedFormat {\n const cleanUrl = url.split('?')[0].split('#')[0]\n const ext = cleanUrl.split('.').pop()?.toLowerCase()\n if (ext && (SUPPORTED_FORMATS as readonly string[]).includes(ext)) {\n return ext as SupportedFormat\n }\n return 'glb'\n}\n\n/**\n * Normalizes any supported source input (string URL, ModelSource object, or null/undefined)\n * into a canonical ModelSource object or null.\n */\nexport function normalizeModelSource(source: ViewerSourceInput): ModelSource | null {\n if (!source) return null\n\n if (typeof source === 'string') {\n const trimmed = source.trim()\n if (!trimmed) return null\n return {\n url: trimmed,\n format: inferFormatFromUrl(trimmed),\n }\n }\n\n // Already a ModelSource (url object or binary data object)\n return source\n}\n","import { fetchSource } from './fetch'\nimport { parseToScene, exportToGlb } from './loaders'\nimport type { ModelSource, ConvertedModel } from '../types'\nexport { UnsupportedFormatError, CorruptFileError, NetworkError } from './errors'\nexport { normalizeScene } from './normalize'\nexport { normalizeModelSource, inferFormatFromUrl } from './source-resolver'\n\nexport async function convert(\n source: ModelSource,\n signal?: AbortSignal,\n onProgress?: (progress: number) => void,\n options?: { dracoDecoderPath?: string },\n): Promise<ConvertedModel> {\n onProgress?.(0)\n\n const fetched = await fetchSource(source, signal)\n\n onProgress?.(0.3)\n\n const { scene, warnings } = await parseToScene(fetched, options?.dracoDecoderPath)\n\n onProgress?.(0.7)\n\n const glb = fetched.format === 'glb' ? fetched.data : await exportToGlb(scene)\n\n onProgress?.(1.0)\n\n // Count meshes\n let meshCount = 0\n scene.traverse((obj) => {\n if ((obj as { isMesh?: boolean }).isMesh) meshCount++\n })\n\n return {\n glb,\n sourceFormat: fetched.format,\n meshCount,\n warnings,\n }\n}\n","export const STONE_KEYWORDS = ['stone', 'diamond', 'gem', 'jewel', 'crystal']\nexport const METAL_KEYWORDS = ['metal', 'gold', 'silver', 'platinum', 'band', 'ring', 'prong', 'shank']\n","import * as THREE from 'three'\nimport { STONE_KEYWORDS, METAL_KEYWORDS } from './keywords'\nimport type { PartInfo, PartType, MeshMaterialSlot, MaterialSlotInfo } from '../types'\n\nfunction hasKeyword(text: string, keywords: string[]): boolean {\n const lower = text.toLowerCase()\n return keywords.some((kw) => lower.includes(kw))\n}\n\nfunction sanitizeName(name: string): string {\n return name.trim().replace(/[^a-zA-Z0-9_-]/g, '_')\n}\n\nexport function getStablePartId(\n mesh: THREE.Mesh,\n scene: THREE.Group,\n usedIds: Set<string>,\n): string {\n // 1. Author-defined metadata in CAD / GLTF extras\n if (typeof mesh.userData?.partId === 'string' && mesh.userData.partId.trim()) {\n const id = mesh.userData.partId.trim()\n usedIds.add(id)\n return id\n }\n if (typeof mesh.userData?.id === 'string' && mesh.userData.id.trim()) {\n const id = mesh.userData.id.trim()\n usedIds.add(id)\n return id\n }\n\n // 2. Clean, unique mesh name\n if (mesh.name && mesh.name.trim()) {\n const clean = mesh.name.trim()\n if (!usedIds.has(clean)) {\n usedIds.add(clean)\n return clean\n }\n }\n\n // 3. Hierarchical path fallback\n let path = mesh.name ? mesh.name.trim() : 'mesh'\n let curr: THREE.Object3D | null = mesh.parent\n while (curr && curr !== scene) {\n if (curr.name && curr.name.trim()) {\n path = `${curr.name.trim()}/${path}`\n }\n curr = curr.parent\n }\n\n let uniquePath = path\n let counter = 1\n while (usedIds.has(uniquePath)) {\n uniquePath = `${path}_${counter++}`\n }\n usedIds.add(uniquePath)\n return uniquePath\n}\n\nexport function getMeshMaterialSlots(mesh: THREE.Mesh): MeshMaterialSlot[] {\n if (Array.isArray(mesh.userData?.originalSlots) && mesh.userData.originalSlots.length > 0) {\n return mesh.userData.originalSlots\n }\n\n if (Array.isArray(mesh.material)) {\n return mesh.material.map((mat, idx) => {\n const name = mat?.name?.trim() || `Material_${idx}`\n const slotId =\n (typeof mat?.userData?.slotId === 'string' && mat.userData.slotId) ||\n `slot_${idx}_${sanitizeName(name)}`\n return {\n slotId,\n materialName: name,\n index: idx,\n }\n })\n }\n\n const mat = mesh.material as THREE.Material | null\n const name = mat?.name?.trim() || (mesh.name ? `${mesh.name}_mat` : 'default')\n const slotId =\n (typeof mat?.userData?.slotId === 'string' && mat.userData.slotId) ||\n `slot_0_${sanitizeName(name)}`\n\n return [\n {\n slotId,\n materialName: name,\n index: 0,\n },\n ]\n}\n\nfunction classifyByName(name: string, materialName: string): PartType {\n const combined = `${name} ${materialName}`\n const isStone = hasKeyword(combined, STONE_KEYWORDS)\n const isMetal = hasKeyword(combined, METAL_KEYWORDS)\n\n if (isStone) return 'stone' // stone wins when both match\n if (isMetal) return 'metal'\n return 'metal' // default\n}\n\nexport function classifyParts(\n scene: THREE.Group,\n overrides: Record<string, PartType>,\n): PartInfo[] {\n const parts: PartInfo[] = []\n const usedIds = new Set<string>()\n\n scene.traverse((obj) => {\n if (!(obj instanceof THREE.Mesh)) return\n\n const mesh = obj as THREE.Mesh\n const partId = getStablePartId(mesh, scene, usedIds)\n mesh.userData.partId = partId\n\n const slots = getMeshMaterialSlots(mesh)\n mesh.userData.originalSlots = slots\n\n const primaryMaterialName = slots[0]?.materialName ?? ''\n mesh.userData.originalMaterialName = primaryMaterialName\n\n const allMaterialNames = slots.map((s) => s.materialName).join(' ')\n\n // Support override by runtime mesh UUID or stable partId\n const isOverridden = mesh.uuid in overrides || partId in overrides\n const overriddenType = overrides[partId] ?? overrides[mesh.uuid]\n\n if (isOverridden && overriddenType) {\n parts.push({\n meshId: mesh.uuid,\n partId,\n meshName: mesh.name,\n materialName: primaryMaterialName,\n slots,\n type: overriddenType,\n overridden: true,\n })\n } else {\n parts.push({\n meshId: mesh.uuid,\n partId,\n meshName: mesh.name,\n materialName: primaryMaterialName,\n slots,\n type: classifyByName(mesh.name, allMaterialNames),\n overridden: false,\n })\n }\n })\n\n return parts\n}\n\nexport function extractMaterialSlots(parts: PartInfo[]): MaterialSlotInfo[] {\n const map = new Map<string, MaterialSlotInfo>()\n\n for (const part of parts) {\n for (const slot of part.slots) {\n const existing = map.get(slot.slotId)\n if (existing) {\n if (!existing.partIds.includes(part.partId)) {\n existing.partIds.push(part.partId)\n }\n if (!existing.meshIds.includes(part.meshId)) {\n existing.meshIds.push(part.meshId)\n }\n // Conflict rule: stone wins over metal\n if (existing.type !== 'stone' && part.type === 'stone') {\n existing.type = 'stone'\n }\n } else {\n map.set(slot.slotId, {\n slotId: slot.slotId,\n name: slot.materialName,\n type: part.type,\n partIds: [part.partId],\n meshIds: [part.meshId],\n })\n }\n }\n }\n\n return Array.from(map.values())\n}\n","// ─── Interfaces ──────────────────────────────────────────────────────────────\n\nexport interface MetalPreset {\n // Required\n id: string\n label: string\n hex: string\n metalness: number\n roughness: number\n // Optional\n category?: 'gold' | 'platinum-silver' | 'alternative'\n thumbnail?: string\n specularColor?: string\n ior?: number\n density?: number\n source?: string\n}\n\nexport interface StonePreset {\n // Required\n id: string\n label: string\n hex: string\n ior: number\n transmission: number\n roughness: number\n // Optional\n category?: 'diamond' | 'gemstone'\n thumbnail?: string\n dispersion?: number // Cauchy half-spread Delta: IOR_blue = n+Delta, IOR_red = n-Delta\n absorptionFactor?: number // Beer-Lambert coefficient in radius-normalised units\n boostFactors?: [number, number, number] // RGB radiance gain [r, g, b]\n envMapIntensity?: number // Per-stone environment intensity multiplier\n squashFactor?: number // Y-axis squash for sphere intersect (default 0.98)\n geometryFactor?: number // Geometry scale for sphere intersect (default 0.5)\n gammaFactor?: number // Pre-colorspace gamma correction (default 1.0)\n ambientFloor?: number // Ambient light floor (0.0 = pure black extinction, 0.05 = soft luminous graphite)\n attenuationColor?: string\n attenuationDistance?: number\n specularColor?: string\n grade?: string\n source?: string\n}\n\n// ─── Unified Metal Presets ────────────────────────────────────────────────────\n// Single collection containing all precious metals (physically-based, RMJ, and legacy).\n\nexport const METAL_PRESETS: MetalPreset[] = [\n // ── Physically-Based Precious Metals (physicallybased.info) ──\n { id: 'yellow-gold-18k', label: '18K Yellow Gold', hex: '#ffd566', metalness: 1.0, roughness: 0.04, category: 'gold', specularColor: '#fffdbf', density: 15500, thumbnail: '/thumbnails/yellow-gold-18k.svg' },\n { id: 'yellow-gold-14k', label: '14K Yellow Gold', hex: '#fed882', metalness: 1.0, roughness: 0.05, category: 'gold', specularColor: '#fffec9', density: 13500, thumbnail: '/thumbnails/yellow-gold-14k.svg' },\n { id: 'pure-gold-24k', label: '24K Pure Gold', hex: '#ffe496', metalness: 1.0, roughness: 0.03, category: 'gold', specularColor: '#fffdbf', density: 19320, source: 'physicallybased.info/gold', thumbnail: '/thumbnails/pure-gold-24k.svg' },\n { id: 'rose-gold-18k', label: '18K Rose Gold', hex: '#e8927c', metalness: 1.0, roughness: 0.04, category: 'gold', specularColor: '#ffd7cb', density: 15400, thumbnail: '/thumbnails/rose-gold-18k.svg' },\n { id: 'rose-gold-14k', label: '14K Rose Gold', hex: '#f1a998', metalness: 1.0, roughness: 0.05, category: 'gold', specularColor: '#ffe4db', density: 13300, thumbnail: '/thumbnails/rose-gold-14k.svg' },\n { id: 'white-gold-18k', label: '18K White Gold', hex: '#f5f6f8', metalness: 1.0, roughness: 0.03, category: 'gold', specularColor: '#ffffff', density: 15600, thumbnail: '/thumbnails/white-gold-18k.svg' },\n { id: 'platinum-950', label: 'Platinum 950', hex: '#e3ded7', metalness: 1.0, roughness: 0.04, category: 'platinum-silver', specularColor: '#edebe6', density: 21450, source: 'physicallybased.info/platinum', thumbnail: '/thumbnails/platinum-950.svg' },\n { id: 'silver-925', label: 'Sterling Silver 925', hex: '#fefdfc', metalness: 1.0, roughness: 0.05, category: 'platinum-silver', specularColor: '#ffffff', density: 10360, source: 'physicallybased.info/silver', thumbnail: '/thumbnails/silver-925.svg' },\n { id: 'titanium', label: 'Titanium', hex: '#b1aaa2', metalness: 1.0, roughness: 0.10, category: 'alternative', specularColor: '#c8c3bd', density: 4506, source: 'physicallybased.info/titanium', thumbnail: '/thumbnails/titanium.svg' },\n { id: 'black-ruthenium', label: 'Black Ruthenium', hex: '#28282c', metalness: 0.95, roughness: 0.06, category: 'alternative', specularColor: '#444448', density: 12450, thumbnail: '/thumbnails/black-ruthenium.svg' },\n\n // ── RenderMyJewelry Metals (app.rendermyjewelry.com) ──\n { id: 'rmj-custom-yellow-gold', label: 'RMJ Custom Yellow Gold', hex: '#ffc766', metalness: 1.0, roughness: 0.00, category: 'gold', specularColor: '#ffffff', ior: 1.5, source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-custom-yellow-gold.svg' },\n { id: 'rmj-custom-rose-gold', label: 'RMJ Custom Rose Gold', hex: '#ffb6a3', metalness: 1.0, roughness: 0.00, category: 'gold', specularColor: '#ffffff', ior: 1.5, source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-custom-rose-gold.svg' },\n { id: 'rmj-white-gold-polished', label: 'RMJ White Gold Polished', hex: '#c2c2c3', metalness: 1.0, roughness: 0.00, category: 'gold', specularColor: '#ffffff', ior: 1.5, source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-white-gold-polished.svg' },\n { id: 'rmj-gold-polished', label: 'RMJ Gold Polished (18K)', hex: '#e5b377', metalness: 1.0, roughness: 0.00, category: 'gold', specularColor: '#ffffff', ior: 1.5, source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-gold-polished.svg' },\n { id: 'rmj-rose-gold-polished', label: 'RMJ Rose Gold Polished', hex: '#f2af83', metalness: 1.0, roughness: 0.00, category: 'gold', specularColor: '#ffffff', ior: 1.5, source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-rose-gold-polished.svg' },\n { id: 'rmj-gold-22k', label: 'RMJ Gold 22K', hex: '#eaa958', metalness: 1.0, roughness: 0.00, category: 'gold', specularColor: '#ffffff', ior: 1.5, source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-gold-22k.svg' },\n { id: 'rmj-gold-14k', label: 'RMJ Gold 14K', hex: '#d6af80', metalness: 1.0, roughness: 0.00, category: 'gold', specularColor: '#ffffff', ior: 1.5, source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-gold-14k.svg' },\n { id: 'rmj-gold-09k', label: 'RMJ Gold 9K', hex: '#d4b38c', metalness: 1.0, roughness: 0.00, category: 'gold', specularColor: '#ffffff', ior: 1.5, source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-gold-09k.svg' },\n { id: 'rmj-silver-polished', label: 'RMJ Silver Polished', hex: '#dedede', metalness: 1.0, roughness: 0.10, category: 'platinum-silver', specularColor: '#ffffff', ior: 1.5, source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-silver-polished.svg' },\n { id: 'rmj-platinum-polished', label: 'RMJ Platinum Polished', hex: '#b9bbbc', metalness: 1.0, roughness: 0.00, category: 'platinum-silver', specularColor: '#ffffff', ior: 1.5, source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-platinum-polished.svg' },\n\n // ── Legacy Basic Metals ──\n { id: 'yellow-gold', label: 'Yellow Gold', hex: '#ffc766', metalness: 1.0, roughness: 0.06, thumbnail: '/thumbnails/yellow-gold.svg' },\n { id: 'rose-gold', label: 'Rose Gold', hex: '#ffb6a3', metalness: 1.0, roughness: 0.06, thumbnail: '/thumbnails/rose-gold.svg' },\n { id: 'white-gold', label: 'White Gold', hex: '#f0f0f0', metalness: 1.0, roughness: 0.05, thumbnail: '/thumbnails/white-gold.svg' },\n { id: 'platinum', label: 'Platinum', hex: '#e5e5e5', metalness: 1.0, roughness: 0.05, thumbnail: '/thumbnails/platinum.svg' },\n { id: 'silver', label: 'Silver', hex: '#dcdcdc', metalness: 1.0, roughness: 0.08, thumbnail: '/thumbnails/silver.svg' },\n]\n\n// ─── Unified Stone Presets ────────────────────────────────────────────────────\n// Single collection containing all stones & diamonds (physical, gemstones, RMJ, and legacy).\n\nexport const STONE_PRESETS: StonePreset[] = [\n // ── Diamonds (GIA & Fancy Color Spectrum, IOR 2.417) ──\n { id: 'diamond-d', label: 'White Diamond', hex: '#ffffff', ior: 2.417, transmission: 0.98, roughness: 0.0, category: 'diamond', grade: 'D-F Colorless', dispersion: 0.024, absorptionFactor: 0.00, ambientFloor: 0.05, source: 'physicallybased.info/diamond', thumbnail: '/thumbnails/diamond-d.svg' },\n { id: 'diamond-gh', label: 'Near Colorless Diamond', hex: '#fbf9f5', ior: 2.417, transmission: 0.97, roughness: 0.0, category: 'diamond', grade: 'G-H Near Colorless', dispersion: 0.012, absorptionFactor: 0.00, ambientFloor: 0.05, thumbnail: '/thumbnails/diamond-gh.svg' },\n { id: 'diamond-fancy-yellow', label: 'Yellow Diamond', hex: '#fdd835', ior: 2.417, transmission: 0.95, roughness: 0.0, category: 'diamond', grade: 'Fancy Yellow', dispersion: 0.010, absorptionFactor: 0.11, thumbnail: '/thumbnails/diamond-fancy-yellow.svg' },\n { id: 'diamond-fancy-pink', label: 'Pink Diamond', hex: '#f472b6', ior: 2.417, transmission: 0.94, roughness: 0.0, category: 'diamond', grade: 'Fancy Pink', dispersion: 0.010, absorptionFactor: 0.14, thumbnail: '/thumbnails/diamond-fancy-pink.svg' },\n { id: 'diamond-fancy-blue', label: 'Blue Diamond', hex: '#38bdf8', ior: 2.417, transmission: 0.94, roughness: 0.0, category: 'diamond', grade: 'Fancy Blue', dispersion: 0.010, absorptionFactor: 0.14, thumbnail: '/thumbnails/diamond-fancy-blue.svg' },\n { id: 'diamond-fancy-green', label: 'Green Diamond', hex: '#34d399', ior: 2.417, transmission: 0.94, roughness: 0.0, category: 'diamond', grade: 'Fancy Green', dispersion: 0.010, absorptionFactor: 0.14, thumbnail: '/thumbnails/diamond-fancy-green.svg' },\n { id: 'diamond-fancy-champagne', label: 'Champagne Diamond', hex: '#c28b51', ior: 2.417, transmission: 0.93, roughness: 0.0, category: 'diamond', grade: 'Fancy Champagne', dispersion: 0.010, absorptionFactor: 0.18, thumbnail: '/thumbnails/diamond-fancy-champagne.svg' },\n { id: 'diamond-fancy-black', label: 'Black Diamond', hex: '#151515', ior: 2.417, transmission: 0.00, roughness: 0.05, category: 'diamond', grade: 'Fancy Black', dispersion: 0.000, absorptionFactor: 0.00, thumbnail: '/thumbnails/diamond-fancy-black.svg' },\n\n // ── Colored Gemstones ──\n { id: 'ruby', label: 'Ruby', hex: '#e14276', ior: 1.770, transmission: 0.88, roughness: 0.03, category: 'gemstone', dispersion: 0.000, absorptionFactor: 0.50, thumbnail: '/thumbnails/ruby.svg' },\n { id: 'sapphire', label: 'Sapphire', hex: '#1a4fb4', ior: 1.770, transmission: 0.88, roughness: 0.03, category: 'gemstone', dispersion: 0.000, absorptionFactor: 0.45, source: 'physicallybased.info/sapphire', thumbnail: '/thumbnails/sapphire.svg' },\n { id: 'emerald', label: 'Emerald', hex: '#20cc95', ior: 1.580, transmission: 0.90, roughness: 0.04, category: 'gemstone', dispersion: 0.000, absorptionFactor: 0.40, thumbnail: '/thumbnails/emerald.svg' },\n { id: 'aquamarine', label: 'Aquamarine', hex: '#5eead4', ior: 1.577, transmission: 0.94, roughness: 0.00, category: 'gemstone', dispersion: 0.000, absorptionFactor: 0.10, thumbnail: '/thumbnails/aquamarine.svg' },\n { id: 'amethyst', label: 'Amethyst', hex: '#9333ea', ior: 1.544, transmission: 0.91, roughness: 0.00, category: 'gemstone', dispersion: 0.000, absorptionFactor: 0.35, source: 'physicallybased.info/quartz', thumbnail: '/thumbnails/amethyst.svg' },\n { id: 'tanzanite', label: 'Tanzanite', hex: '#6366f1', ior: 1.691, transmission: 0.90, roughness: 0.00, category: 'gemstone', dispersion: 0.000, absorptionFactor: 0.42, thumbnail: '/thumbnails/tanzanite.svg' },\n\n // ── RenderMyJewelry Gems (app.rendermyjewelry.com) ──\n { id: 'rmj-diamond-d-colorless', label: 'RMJ Diamond D Colorless', hex: '#ececec', ior: 2.400, transmission: 0.98, roughness: 0.0, category: 'diamond', dispersion: 0.004, absorptionFactor: 1.0, boostFactors: [2.0, 2.0, 2.0], source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-diamond-d-colorless.svg' },\n { id: 'rmj-ruby-1', label: 'RMJ Ruby 1', hex: '#e14276', ior: 1.770, transmission: 0.88, roughness: 0.0, category: 'gemstone', dispersion: 0.000, absorptionFactor: 1.6, boostFactors: [1.3, 0.16, 0.9], source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-ruby-1.svg' },\n { id: 'rmj-emerald-1', label: 'RMJ Emerald 1', hex: '#20cc95', ior: 1.577, transmission: 0.90, roughness: 0.0, category: 'gemstone', dispersion: 0.012, absorptionFactor: 1.0, boostFactors: [0.892, 0.892, 0.986], source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-emerald-1.svg' },\n { id: 'rmj-sapphire-cabachon-2', label: 'RMJ Sapphire Cabochon 2', hex: '#45b1e1', ior: 1.660, transmission: 0.88, roughness: 0.0, category: 'gemstone', dispersion: 0.000, absorptionFactor: 2.51, boostFactors: [1.0, 1.0, 1.0], source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-sapphire-cabachon-2.svg' },\n { id: 'rmj-diamond-pink-2', label: 'RMJ Diamond Pink 2', hex: '#f1bcd5', ior: 2.600, transmission: 0.94, roughness: 0.0, category: 'diamond', dispersion: 0.012, absorptionFactor: 1.0, boostFactors: [1.3, 1.0, 1.0], source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-diamond-pink-2.svg' },\n { id: 'rmj-diamond-yellow-2', label: 'RMJ Diamond Yellow 2', hex: '#fce88c', ior: 2.600, transmission: 0.94, roughness: 0.0, category: 'diamond', dispersion: 0.012, absorptionFactor: 1.3, boostFactors: [1.0, 1.0, 1.0], source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-diamond-yellow-2.svg' },\n { id: 'rmj-diamond-blue-2', label: 'RMJ Diamond Blue 2', hex: '#80c9fc', ior: 2.600, transmission: 0.94, roughness: 0.0, category: 'diamond', dispersion: 0.013, absorptionFactor: 1.0, boostFactors: [0.9, 1.0, 1.0], source: 'app.rendermyjewelry.com', thumbnail: '/thumbnails/rmj-diamond-blue-2.svg' },\n\n // ── Legacy Aliases ──\n { id: 'diamond', label: 'White Diamond', hex: '#ffffff', ior: 2.417, transmission: 0.95, roughness: 0.02, dispersion: 0.012, absorptionFactor: 0.00, ambientFloor: 0.05, thumbnail: '/thumbnails/diamond-d.svg' },\n { id: 'yellow-diamond', label: 'Yellow Diamond', hex: '#fcd34d', ior: 2.420, transmission: 0.94, roughness: 0.02, dispersion: 0.010, absorptionFactor: 0.11, thumbnail: '/thumbnails/diamond-fancy-yellow.svg' },\n { id: 'pink-diamond', label: 'Pink Diamond', hex: '#f472b6', ior: 2.420, transmission: 0.94, roughness: 0.02, dispersion: 0.010, absorptionFactor: 0.14, thumbnail: '/thumbnails/diamond-fancy-pink.svg' },\n { id: 'blue-diamond', label: 'Blue Diamond', hex: '#60a5fa', ior: 2.420, transmission: 0.94, roughness: 0.02, dispersion: 0.010, absorptionFactor: 0.14, thumbnail: '/thumbnails/diamond-fancy-blue.svg' },\n { id: 'black-diamond', label: 'Black Diamond', hex: '#1a1a1a', ior: 2.420, transmission: 0.00, roughness: 0.05, dispersion: 0.000, absorptionFactor: 0.00, thumbnail: '/thumbnails/diamond-fancy-black.svg' },\n]\n\n// ─── Convenience Subsets & Aliases ────────────────────────────────────────────\n// Derived views from the master single arrays for backwards compatibility.\n\nexport const ALL_METAL_PRESETS: MetalPreset[] = METAL_PRESETS\nexport const ALL_STONE_PRESETS: StonePreset[] = STONE_PRESETS\n\nexport const PHYSICALLY_BASED_METAL_PRESETS: MetalPreset[] = METAL_PRESETS.filter(\n (m) => m.category !== undefined && !m.id.startsWith('rmj-')\n)\nexport const RENDERMYJEWELRY_METALS: MetalPreset[] = METAL_PRESETS.filter(\n (m) => m.id.startsWith('rmj-')\n)\n\nexport const DIAMOND_PRESETS: StonePreset[] = STONE_PRESETS.filter(\n (s) => s.category === 'diamond' && !s.id.startsWith('rmj-') && s.id.startsWith('diamond-')\n)\nexport const GEMSTONE_PRESETS: StonePreset[] = STONE_PRESETS.filter(\n (s) => s.category === 'gemstone' && !s.id.startsWith('rmj-')\n)\nexport const RENDERMYJEWELRY_GEMS: StonePreset[] = STONE_PRESETS.filter(\n (s) => s.id.startsWith('rmj-')\n)\n\n// ─── Canonical Presets (No Legacy Duplicates) ─────────────────────────────────\nconst LEGACY_METAL_ALIAS_IDS = new Set(['yellow-gold', 'rose-gold', 'white-gold', 'platinum', 'silver'])\nconst LEGACY_STONE_ALIAS_IDS = new Set(['diamond', 'yellow-diamond', 'pink-diamond', 'blue-diamond', 'black-diamond'])\n\nexport const CANONICAL_METAL_PRESETS: MetalPreset[] = METAL_PRESETS.filter(\n (m) => !LEGACY_METAL_ALIAS_IDS.has(m.id)\n)\n\nexport const CANONICAL_STONE_PRESETS: StonePreset[] = STONE_PRESETS.filter(\n (s) => !LEGACY_STONE_ALIAS_IDS.has(s.id)\n)\n\n// ─── Autocomplete-Friendly Types ──────────────────────────────────────────────\nexport type StandardMetalId =\n | 'yellow-gold-18k'\n | 'yellow-gold-14k'\n | 'pure-gold-24k'\n | 'rose-gold-18k'\n | 'rose-gold-14k'\n | 'white-gold-18k'\n | 'platinum-950'\n | 'silver-925'\n | 'titanium'\n | 'black-ruthenium'\n | 'rmj-custom-yellow-gold'\n | 'rmj-custom-rose-gold'\n | 'rmj-white-gold-polished'\n | 'rmj-gold-polished'\n | 'rmj-rose-gold-polished'\n | 'rmj-gold-22k'\n | 'rmj-gold-14k'\n | 'rmj-gold-09k'\n | 'rmj-silver-polished'\n | 'rmj-platinum-polished'\n | 'yellow-gold'\n | 'rose-gold'\n | 'white-gold'\n | 'platinum'\n | 'silver'\n\nexport type StandardStoneId =\n | 'diamond-d'\n | 'diamond-gh'\n | 'diamond-fancy-yellow'\n | 'diamond-fancy-pink'\n | 'diamond-fancy-blue'\n | 'diamond-fancy-green'\n | 'diamond-fancy-champagne'\n | 'diamond-fancy-black'\n | 'ruby'\n | 'sapphire'\n | 'emerald'\n | 'aquamarine'\n | 'amethyst'\n | 'tanzanite'\n | 'rmj-diamond-d-colorless'\n | 'rmj-ruby-1'\n | 'rmj-emerald-1'\n | 'rmj-sapphire-cabachon-2'\n | 'rmj-diamond-pink-2'\n | 'rmj-diamond-yellow-2'\n | 'rmj-diamond-blue-2'\n | 'diamond'\n | 'yellow-diamond'\n | 'pink-diamond'\n | 'blue-diamond'\n | 'black-diamond'\n\n/**\n * Autocomplete-friendly metal color type. Suggests canonical preset IDs while allowing arbitrary hex codes.\n */\nexport type MetalColorProp = StandardMetalId | (string & {})\n\n/**\n * Autocomplete-friendly stone color type. Suggests canonical preset IDs while allowing arbitrary hex codes.\n */\nexport type StoneColorProp = StandardStoneId | (string & {})\n\n// ─── Lookup Helpers ───────────────────────────────────────────────────────────\nexport function getMetalPreset(idOrHex: string): MetalPreset | undefined {\n if (!idOrHex) return undefined\n const query = idOrHex.toLowerCase().trim()\n return METAL_PRESETS.find((m) => m.id.toLowerCase() === query || m.hex.toLowerCase() === query)\n}\n\nexport function getStonePreset(idOrHex: string): StonePreset | undefined {\n if (!idOrHex) return undefined\n const query = idOrHex.toLowerCase().trim()\n return STONE_PRESETS.find((s) => s.id.toLowerCase() === query || s.hex.toLowerCase() === query)\n}\n","import * as THREE from 'three'\n\nexport interface GemAnalysis {\n centroid: THREE.Vector3\n radius: number\n triangleCount: number\n starConvexFailureArea: number\n isBakeable: boolean\n flippedWinding: boolean\n}\n\nexport interface BakeHandle {\n key: string\n texture: THREE.CubeTexture\n centroid: THREE.Vector3\n radius: number\n encoding: 'signed' | 'unorm'\n bvh?: any\n}\n\nconst hashMap = new WeakMap<THREE.BufferGeometry, string>()\n\nexport function analyzeGeometry(g: THREE.BufferGeometry): GemAnalysis {\n if (!g.boundingSphere) {\n g.computeBoundingSphere()\n }\n const centroid = g.boundingSphere?.center ? g.boundingSphere.center.clone() : new THREE.Vector3()\n const rawRadius = g.boundingSphere?.radius ?? 1.0\n const radius = Math.max(rawRadius, 0.01)\n\n const posAttr = g.getAttribute('position')\n if (!posAttr || posAttr.count === 0) {\n return {\n centroid,\n radius,\n triangleCount: 0,\n starConvexFailureArea: 1.0,\n isBakeable: false,\n flippedWinding: false,\n }\n }\n\n const index = g.getIndex()\n const triangleCount = index ? index.count / 3 : posAttr.count / 3\n\n let totalArea = 0\n let failureArea = 0\n let signedVolume = 0\n\n const p0 = new THREE.Vector3()\n const p1 = new THREE.Vector3()\n const p2 = new THREE.Vector3()\n const e1 = new THREE.Vector3()\n const e2 = new THREE.Vector3()\n const normal = new THREE.Vector3()\n const crossP1P2 = new THREE.Vector3()\n\n for (let i = 0; i < triangleCount; i++) {\n const i0 = index ? index.getX(i * 3) : i * 3\n const i1 = index ? index.getX(i * 3 + 1) : i * 3 + 1\n const i2 = index ? index.getX(i * 3 + 2) : i * 3 + 2\n\n p0.fromBufferAttribute(posAttr, i0).sub(centroid).divideScalar(radius)\n p1.fromBufferAttribute(posAttr, i1).sub(centroid).divideScalar(radius)\n p2.fromBufferAttribute(posAttr, i2).sub(centroid).divideScalar(radius)\n\n e1.subVectors(p1, p0)\n e2.subVectors(p2, p0)\n normal.crossVectors(e1, e2)\n const doubleArea = normal.length()\n if (doubleArea < 1e-12) continue\n\n const area = doubleArea * 0.5\n totalArea += area\n\n normal.divideScalar(doubleArea)\n const D = p0.dot(normal)\n\n // Signed volume contribution: dot(p0, cross(p1, p2)) / 6\n crossP1P2.crossVectors(p1, p2)\n signedVolume += p0.dot(crossP1P2) / 6.0\n\n if (D <= 1e-4) {\n failureArea += area\n }\n }\n\n const starConvexFailureArea = totalArea > 0 ? failureArea / totalArea : 1.0\n const flippedWinding = signedVolume < 0\n\n return {\n centroid,\n radius,\n triangleCount,\n starConvexFailureArea,\n isBakeable: starConvexFailureArea <= 0.005 && !isNaN(totalArea) && totalArea > 0,\n flippedWinding,\n }\n}\n\nexport function buildFacetAttribute(g: THREE.BufferGeometry, a: GemAnalysis): Float32Array {\n const nonIndexed = g.getIndex() ? g.toNonIndexed() : g.clone()\n const posAttr = nonIndexed.getAttribute('position')\n const vertexCount = posAttr.count\n const facetData = new Float32Array(vertexCount * 4)\n\n const p0 = new THREE.Vector3()\n const p1 = new THREE.Vector3()\n const p2 = new THREE.Vector3()\n const e1 = new THREE.Vector3()\n const e2 = new THREE.Vector3()\n const normal = new THREE.Vector3()\n\n const windingSign = a.flippedWinding ? -1 : 1\n\n for (let i = 0; i < vertexCount; i += 3) {\n p0.fromBufferAttribute(posAttr, i).sub(a.centroid).divideScalar(a.radius)\n p1.fromBufferAttribute(posAttr, i + 1).sub(a.centroid).divideScalar(a.radius)\n p2.fromBufferAttribute(posAttr, i + 2).sub(a.centroid).divideScalar(a.radius)\n\n e1.subVectors(p1, p0)\n e2.subVectors(p2, p0)\n normal.crossVectors(e1, e2).multiplyScalar(windingSign)\n\n const len = normal.length()\n if (len > 1e-12) {\n normal.divideScalar(len)\n } else {\n normal.set(0, 1, 0)\n }\n\n const D = p0.dot(normal)\n\n for (let v = 0; v < 3; v++) {\n const idx = (i + v) * 4\n facetData[idx] = normal.x\n facetData[idx + 1] = normal.y\n facetData[idx + 2] = normal.z\n facetData[idx + 3] = D\n }\n }\n\n return facetData\n}\n\nexport function hashGeometry(g: THREE.BufferGeometry, a: GemAnalysis): string {\n const cached = hashMap.get(g)\n if (cached) return cached\n\n const posAttr = g.getAttribute('position')\n const index = g.getIndex()\n let hash = 0x811c9dc5 // FNV-1a 32-bit offset basis\n\n const fnv1a = (val: number) => {\n hash ^= val & 0xff\n hash = Math.imul(hash, 0x01000193)\n hash ^= (val >> 8) & 0xff\n hash = Math.imul(hash, 0x01000193)\n hash ^= (val >> 16) & 0xff\n hash = Math.imul(hash, 0x01000193)\n hash ^= (val >> 24) & 0xff\n hash = Math.imul(hash, 0x01000193)\n }\n\n fnv1a(a.triangleCount)\n if (index) {\n for (let i = 0; i < index.count; i++) {\n fnv1a(index.getX(i))\n }\n }\n\n const p = new THREE.Vector3()\n for (let i = 0; i < posAttr.count; i++) {\n p.fromBufferAttribute(posAttr, i).sub(a.centroid).divideScalar(a.radius)\n fnv1a(Math.round(p.x * 10000))\n fnv1a(Math.round(p.y * 10000))\n fnv1a(Math.round(p.z * 10000))\n }\n\n const result = (hash >>> 0).toString(16)\n hashMap.set(g, result)\n return result\n}\n","// Split strategy constants\n\n/**\n * Option for splitting each BVH node down the center of the longest axis of the bounds.\n *\n * This is the fastest construction option and will yield a good, performant bounds.\n * @type {number}\n */\nexport const CENTER = 0;\n\n/**\n * Option for splitting each BVH node at the average point along the longest axis for\n * all triangle centroids in the bounds.\n *\n * This strategy may be better than `CENTER` with some geometry.\n * @type {number}\n */\nexport const AVERAGE = 1;\n\n/**\n * Option to use a Surface Area Heuristic to split the bounds more optimally. This SAH\n * implementation tests 32 discrete splits in each node along each axis to determine\n * which split is the lowest cost.\n *\n * This is the slowest construction option but will yield the best bounds of the three\n * options and use the least memory.\n * @type {number}\n */\nexport const SAH = 2;\n\n// Traversal constants\n\n/**\n * Indicates the shape did not intersect the given bounding box.\n * @type {number}\n */\nexport const NOT_INTERSECTED = 0;\n\n/**\n * Indicates the shape did intersect the given bounding box.\n * @type {number}\n */\nexport const INTERSECTED = 1;\n\n/**\n * Indicate the shape entirely contains the given bounding box.\n * @type {number}\n */\nexport const CONTAINED = 2;\n\n// SAH cost constants\n// TODO: hone these costs more. The relative difference between them should be the\n// difference in measured time to perform a primitive intersection vs traversing\n// bounds.\n// TODO: could be tuned per primitive type (triangles vs lines vs points)\nexport const PRIMITIVE_INTERSECT_COST = 1.25;\nexport const TRAVERSAL_COST = 1;\n\n\n// Build constants\nexport const BYTES_PER_NODE = 6 * 4 + 4 + 4;\nexport const UINT32_PER_NODE = BYTES_PER_NODE / 4;\nexport const IS_LEAFNODE_FLAG = 0xFFFF;\n\n// Bit masks for 32 bit node data\nexport const LEAFNODE_MASK_32 = IS_LEAFNODE_FLAG << 16;\n\n// EPSILON for computing floating point error during build\n// https://en.wikipedia.org/wiki/Machine_epsilon#Values_for_standard_hardware_floating_point_arithmetics\nexport const FLOAT32_EPSILON = Math.pow( 2, - 24 );\n\nexport const SKIP_GENERATION = Symbol( 'SKIP_GENERATION' );\n\nexport const DEFAULT_OPTIONS = {\n\tstrategy: CENTER,\n\tmaxDepth: 40,\n\ttargetLeafSize: 10,\n\tuseSharedArrayBuffer: false,\n\tsetBoundingBox: true,\n\tonProgress: null,\n\tindirect: false,\n\tverbose: true,\n\trange: null,\n\t[ SKIP_GENERATION ]: false,\n};\n\n","export function arrayToBox( nodeIndex32, array, target ) {\n\n\ttarget.min.x = array[ nodeIndex32 ];\n\ttarget.min.y = array[ nodeIndex32 + 1 ];\n\ttarget.min.z = array[ nodeIndex32 + 2 ];\n\n\ttarget.max.x = array[ nodeIndex32 + 3 ];\n\ttarget.max.y = array[ nodeIndex32 + 4 ];\n\ttarget.max.z = array[ nodeIndex32 + 5 ];\n\n\treturn target;\n\n}\n\nexport function makeEmptyBounds( target ) {\n\n\ttarget[ 0 ] = target[ 1 ] = target[ 2 ] = Infinity;\n\ttarget[ 3 ] = target[ 4 ] = target[ 5 ] = - Infinity;\n\n}\n\nexport function getLongestEdgeIndex( bounds ) {\n\n\tlet splitDimIdx = - 1;\n\tlet splitDist = - Infinity;\n\n\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\tconst dist = bounds[ i + 3 ] - bounds[ i ];\n\t\tif ( dist > splitDist ) {\n\n\t\t\tsplitDist = dist;\n\t\t\tsplitDimIdx = i;\n\n\t\t}\n\n\t}\n\n\treturn splitDimIdx;\n\n}\n\n// copies bounds a into bounds b\nexport function copyBounds( source, target ) {\n\n\ttarget.set( source );\n\n}\n\n// sets bounds target to the union of bounds a and b\nexport function unionBounds( a, b, target ) {\n\n\tlet aVal, bVal;\n\tfor ( let d = 0; d < 3; d ++ ) {\n\n\t\tconst d3 = d + 3;\n\n\t\t// set the minimum values\n\t\taVal = a[ d ];\n\t\tbVal = b[ d ];\n\t\ttarget[ d ] = aVal < bVal ? aVal : bVal;\n\n\t\t// set the max values\n\t\taVal = a[ d3 ];\n\t\tbVal = b[ d3 ];\n\t\ttarget[ d3 ] = aVal > bVal ? aVal : bVal;\n\n\t}\n\n}\n\n// expands the given bounds by the provided primitive bounds\nexport function expandByPrimitiveBounds( startIndex, primitiveBounds, bounds ) {\n\n\tfor ( let d = 0; d < 3; d ++ ) {\n\n\t\tconst tCenter = primitiveBounds[ startIndex + 2 * d ];\n\t\tconst tHalf = primitiveBounds[ startIndex + 2 * d + 1 ];\n\n\t\tconst tMin = tCenter - tHalf;\n\t\tconst tMax = tCenter + tHalf;\n\n\t\tif ( tMin < bounds[ d ] ) {\n\n\t\t\tbounds[ d ] = tMin;\n\n\t\t}\n\n\t\tif ( tMax > bounds[ d + 3 ] ) {\n\n\t\t\tbounds[ d + 3 ] = tMax;\n\n\t\t}\n\n\t}\n\n}\n\n// compute bounds surface area\nexport function computeSurfaceArea( bounds ) {\n\n\tconst d0 = bounds[ 3 ] - bounds[ 0 ];\n\tconst d1 = bounds[ 4 ] - bounds[ 1 ];\n\tconst d2 = bounds[ 5 ] - bounds[ 2 ];\n\n\treturn 2 * ( d0 * d1 + d1 * d2 + d2 * d0 );\n\n}\n","import { IS_LEAFNODE_FLAG, UINT32_PER_NODE } from '../Constants.js';\n\nexport function IS_LEAF( n16, uint16Array ) {\n\n\treturn uint16Array[ n16 + 15 ] === IS_LEAFNODE_FLAG;\n\n}\n\nexport function OFFSET( n32, uint32Array ) {\n\n\treturn uint32Array[ n32 + 6 ];\n\n}\n\nexport function COUNT( n16, uint16Array ) {\n\n\treturn uint16Array[ n16 + 14 ];\n\n}\n\n// Returns the uint32-aligned offset of the left child node for performance\nexport function LEFT_NODE( n32 ) {\n\n\treturn n32 + UINT32_PER_NODE;\n\n}\n\n// Returns the uint32-aligned offset of the right child node for performance\nexport function RIGHT_NODE( n32, uint32Array ) {\n\n\t// stored value is relative offset from parent, convert to absolute uint32 index\n\tconst relativeOffset = uint32Array[ n32 + 6 ];\n\treturn n32 + relativeOffset * UINT32_PER_NODE;\n\n}\n\nexport function SPLIT_AXIS( n32, uint32Array ) {\n\n\treturn uint32Array[ n32 + 7 ];\n\n}\n\nexport function BOUNDING_DATA_INDEX( n32 ) {\n\n\treturn n32;\n\n}\n","// computes the union of the bounds of all of the given primitives and puts the resulting box in \"target\".\n// A bounding box is computed for the centroids of the primitives, as well, and placed in \"centroidTarget\".\n// These are computed together to avoid redundant accesses to bounds array.\nexport function getBounds( primitiveBounds, offset, count, target, centroidTarget ) {\n\n\tlet minx = Infinity;\n\tlet miny = Infinity;\n\tlet minz = Infinity;\n\tlet maxx = - Infinity;\n\tlet maxy = - Infinity;\n\tlet maxz = - Infinity;\n\n\tlet cminx = Infinity;\n\tlet cminy = Infinity;\n\tlet cminz = Infinity;\n\tlet cmaxx = - Infinity;\n\tlet cmaxy = - Infinity;\n\tlet cmaxz = - Infinity;\n\n\tconst boundsOffset = primitiveBounds.offset || 0;\n\tfor ( let i = ( offset - boundsOffset ) * 6, end = ( offset + count - boundsOffset ) * 6; i < end; i += 6 ) {\n\n\t\tconst cx = primitiveBounds[ i + 0 ];\n\t\tconst hx = primitiveBounds[ i + 1 ];\n\t\tconst lx = cx - hx;\n\t\tconst rx = cx + hx;\n\t\tif ( lx < minx ) minx = lx;\n\t\tif ( rx > maxx ) maxx = rx;\n\t\tif ( cx < cminx ) cminx = cx;\n\t\tif ( cx > cmaxx ) cmaxx = cx;\n\n\t\tconst cy = primitiveBounds[ i + 2 ];\n\t\tconst hy = primitiveBounds[ i + 3 ];\n\t\tconst ly = cy - hy;\n\t\tconst ry = cy + hy;\n\t\tif ( ly < miny ) miny = ly;\n\t\tif ( ry > maxy ) maxy = ry;\n\t\tif ( cy < cminy ) cminy = cy;\n\t\tif ( cy > cmaxy ) cmaxy = cy;\n\n\t\tconst cz = primitiveBounds[ i + 4 ];\n\t\tconst hz = primitiveBounds[ i + 5 ];\n\t\tconst lz = cz - hz;\n\t\tconst rz = cz + hz;\n\t\tif ( lz < minz ) minz = lz;\n\t\tif ( rz > maxz ) maxz = rz;\n\t\tif ( cz < cminz ) cminz = cz;\n\t\tif ( cz > cmaxz ) cmaxz = cz;\n\n\t}\n\n\ttarget[ 0 ] = minx;\n\ttarget[ 1 ] = miny;\n\ttarget[ 2 ] = minz;\n\n\ttarget[ 3 ] = maxx;\n\ttarget[ 4 ] = maxy;\n\ttarget[ 5 ] = maxz;\n\n\tcentroidTarget[ 0 ] = cminx;\n\tcentroidTarget[ 1 ] = cminy;\n\tcentroidTarget[ 2 ] = cminz;\n\n\tcentroidTarget[ 3 ] = cmaxx;\n\tcentroidTarget[ 4 ] = cmaxy;\n\tcentroidTarget[ 5 ] = cmaxz;\n\n}\n","import { getLongestEdgeIndex, computeSurfaceArea, copyBounds, unionBounds, expandByPrimitiveBounds } from '../../utils/ArrayBoxUtilities.js';\nimport { CENTER, AVERAGE, SAH, PRIMITIVE_INTERSECT_COST, TRAVERSAL_COST } from '../Constants.js';\n\nconst BIN_COUNT = 32;\nconst binsSort = ( a, b ) => a.candidate - b.candidate;\nconst sahBins = /* @__PURE__ */ new Array( BIN_COUNT ).fill().map( () => {\n\n\treturn {\n\n\t\tcount: 0,\n\t\tbounds: new Float32Array( 6 ),\n\t\trightCacheBounds: new Float32Array( 6 ),\n\t\tleftCacheBounds: new Float32Array( 6 ),\n\t\tcandidate: 0,\n\n\t};\n\n} );\nconst leftBounds = /* @__PURE__ */ new Float32Array( 6 );\n\nexport function getOptimalSplit( nodeBoundingData, centroidBoundingData, primitiveBounds, offset, count, strategy ) {\n\n\tlet axis = - 1;\n\tlet pos = 0;\n\n\t// Center\n\tif ( strategy === CENTER ) {\n\n\t\taxis = getLongestEdgeIndex( centroidBoundingData );\n\t\tif ( axis !== - 1 ) {\n\n\t\t\tpos = ( centroidBoundingData[ axis ] + centroidBoundingData[ axis + 3 ] ) / 2;\n\n\t\t}\n\n\t} else if ( strategy === AVERAGE ) {\n\n\t\taxis = getLongestEdgeIndex( nodeBoundingData );\n\t\tif ( axis !== - 1 ) {\n\n\t\t\tpos = getAverage( primitiveBounds, offset, count, axis );\n\n\t\t}\n\n\t} else if ( strategy === SAH ) {\n\n\t\tconst rootSurfaceArea = computeSurfaceArea( nodeBoundingData );\n\t\tlet bestCost = PRIMITIVE_INTERSECT_COST * count;\n\n\t\t// iterate over all axes\n\t\tconst boundsOffset = primitiveBounds.offset || 0;\n\t\tconst cStart = ( offset - boundsOffset ) * 6;\n\t\tconst cEnd = ( offset + count - boundsOffset ) * 6;\n\t\tfor ( let a = 0; a < 3; a ++ ) {\n\n\t\t\tconst axisLeft = centroidBoundingData[ a ];\n\t\t\tconst axisRight = centroidBoundingData[ a + 3 ];\n\t\t\tconst axisLength = axisRight - axisLeft;\n\t\t\tconst binWidth = axisLength / BIN_COUNT;\n\n\t\t\t// If we have fewer primitives than we're planning to split then just check all\n\t\t\t// the primitive positions because it will be faster.\n\t\t\tif ( count < BIN_COUNT / 4 ) {\n\n\t\t\t\t// initialize the bin candidates\n\t\t\t\tconst truncatedBins = [ ...sahBins ];\n\t\t\t\ttruncatedBins.length = count;\n\n\t\t\t\t// set the candidates\n\t\t\t\tlet b = 0;\n\t\t\t\tfor ( let c = cStart; c < cEnd; c += 6, b ++ ) {\n\n\t\t\t\t\tconst bin = truncatedBins[ b ];\n\t\t\t\t\tbin.candidate = primitiveBounds[ c + 2 * a ];\n\t\t\t\t\tbin.count = 0;\n\n\t\t\t\t\tconst {\n\t\t\t\t\t\tbounds,\n\t\t\t\t\t\tleftCacheBounds,\n\t\t\t\t\t\trightCacheBounds,\n\t\t\t\t\t} = bin;\n\t\t\t\t\tfor ( let d = 0; d < 3; d ++ ) {\n\n\t\t\t\t\t\trightCacheBounds[ d ] = Infinity;\n\t\t\t\t\t\trightCacheBounds[ d + 3 ] = - Infinity;\n\n\t\t\t\t\t\tleftCacheBounds[ d ] = Infinity;\n\t\t\t\t\t\tleftCacheBounds[ d + 3 ] = - Infinity;\n\n\t\t\t\t\t\tbounds[ d ] = Infinity;\n\t\t\t\t\t\tbounds[ d + 3 ] = - Infinity;\n\n\t\t\t\t\t}\n\n\t\t\t\t\texpandByPrimitiveBounds( c, primitiveBounds, bounds );\n\n\t\t\t\t}\n\n\t\t\t\ttruncatedBins.sort( binsSort );\n\n\t\t\t\t// remove redundant splits\n\t\t\t\tlet splitCount = count;\n\t\t\t\tfor ( let bi = 0; bi < splitCount; bi ++ ) {\n\n\t\t\t\t\tconst bin = truncatedBins[ bi ];\n\t\t\t\t\twhile ( bi + 1 < splitCount && truncatedBins[ bi + 1 ].candidate === bin.candidate ) {\n\n\t\t\t\t\t\ttruncatedBins.splice( bi + 1, 1 );\n\t\t\t\t\t\tsplitCount --;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// find the appropriate bin for each primitive and expand the bounds.\n\t\t\t\tfor ( let c = cStart; c < cEnd; c += 6 ) {\n\n\t\t\t\t\tconst center = primitiveBounds[ c + 2 * a ];\n\t\t\t\t\tfor ( let bi = 0; bi < splitCount; bi ++ ) {\n\n\t\t\t\t\t\tconst bin = truncatedBins[ bi ];\n\t\t\t\t\t\tif ( center >= bin.candidate ) {\n\n\t\t\t\t\t\t\texpandByPrimitiveBounds( c, primitiveBounds, bin.rightCacheBounds );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\texpandByPrimitiveBounds( c, primitiveBounds, bin.leftCacheBounds );\n\t\t\t\t\t\t\tbin.count ++;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// expand all the bounds\n\t\t\t\tfor ( let bi = 0; bi < splitCount; bi ++ ) {\n\n\t\t\t\t\tconst bin = truncatedBins[ bi ];\n\t\t\t\t\tconst leftCount = bin.count;\n\t\t\t\t\tconst rightCount = count - bin.count;\n\n\t\t\t\t\t// check the cost of this split\n\t\t\t\t\tconst leftBounds = bin.leftCacheBounds;\n\t\t\t\t\tconst rightBounds = bin.rightCacheBounds;\n\n\t\t\t\t\tlet leftProb = 0;\n\t\t\t\t\tif ( leftCount !== 0 ) {\n\n\t\t\t\t\t\tleftProb = computeSurfaceArea( leftBounds ) / rootSurfaceArea;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tlet rightProb = 0;\n\t\t\t\t\tif ( rightCount !== 0 ) {\n\n\t\t\t\t\t\trightProb = computeSurfaceArea( rightBounds ) / rootSurfaceArea;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tconst cost = TRAVERSAL_COST + PRIMITIVE_INTERSECT_COST * (\n\t\t\t\t\t\tleftProb * leftCount + rightProb * rightCount\n\t\t\t\t\t);\n\n\t\t\t\t\tif ( cost < bestCost ) {\n\n\t\t\t\t\t\taxis = a;\n\t\t\t\t\t\tbestCost = cost;\n\t\t\t\t\t\tpos = bin.candidate;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// reset the bins\n\t\t\t\tfor ( let i = 0; i < BIN_COUNT; i ++ ) {\n\n\t\t\t\t\tconst bin = sahBins[ i ];\n\t\t\t\t\tbin.count = 0;\n\t\t\t\t\tbin.candidate = axisLeft + binWidth + i * binWidth;\n\n\t\t\t\t\tconst bounds = bin.bounds;\n\t\t\t\t\tfor ( let d = 0; d < 3; d ++ ) {\n\n\t\t\t\t\t\tbounds[ d ] = Infinity;\n\t\t\t\t\t\tbounds[ d + 3 ] = - Infinity;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// iterate over all center positions\n\t\t\t\tfor ( let c = cStart; c < cEnd; c += 6 ) {\n\n\t\t\t\t\tconst triCenter = primitiveBounds[ c + 2 * a ];\n\t\t\t\t\tconst relativeCenter = triCenter - axisLeft;\n\n\t\t\t\t\t// in the partition function if the centroid lies on the split plane then it is\n\t\t\t\t\t// considered to be on the right side of the split\n\t\t\t\t\tlet binIndex = ~ ~ ( relativeCenter / binWidth );\n\t\t\t\t\tif ( binIndex >= BIN_COUNT ) binIndex = BIN_COUNT - 1;\n\n\t\t\t\t\tconst bin = sahBins[ binIndex ];\n\t\t\t\t\tbin.count ++;\n\n\t\t\t\t\texpandByPrimitiveBounds( c, primitiveBounds, bin.bounds );\n\n\t\t\t\t}\n\n\t\t\t\t// cache the unioned bounds from right to left so we don't have to regenerate them each time\n\t\t\t\tconst lastBin = sahBins[ BIN_COUNT - 1 ];\n\t\t\t\tcopyBounds( lastBin.bounds, lastBin.rightCacheBounds );\n\t\t\t\tfor ( let i = BIN_COUNT - 2; i >= 0; i -- ) {\n\n\t\t\t\t\tconst bin = sahBins[ i ];\n\t\t\t\t\tconst nextBin = sahBins[ i + 1 ];\n\t\t\t\t\tunionBounds( bin.bounds, nextBin.rightCacheBounds, bin.rightCacheBounds );\n\n\t\t\t\t}\n\n\t\t\t\tlet leftCount = 0;\n\t\t\t\tfor ( let i = 0; i < BIN_COUNT - 1; i ++ ) {\n\n\t\t\t\t\tconst bin = sahBins[ i ];\n\t\t\t\t\tconst binCount = bin.count;\n\t\t\t\t\tconst bounds = bin.bounds;\n\n\t\t\t\t\tconst nextBin = sahBins[ i + 1 ];\n\t\t\t\t\tconst rightBounds = nextBin.rightCacheBounds;\n\n\t\t\t\t\t// don't do anything with the bounds if the new bounds have no primitives\n\t\t\t\t\tif ( binCount !== 0 ) {\n\n\t\t\t\t\t\tif ( leftCount === 0 ) {\n\n\t\t\t\t\t\t\tcopyBounds( bounds, leftBounds );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tunionBounds( bounds, leftBounds, leftBounds );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tleftCount += binCount;\n\n\t\t\t\t\t// check the cost of this split\n\t\t\t\t\tlet leftProb = 0;\n\t\t\t\t\tlet rightProb = 0;\n\n\t\t\t\t\tif ( leftCount !== 0 ) {\n\n\t\t\t\t\t\tleftProb = computeSurfaceArea( leftBounds ) / rootSurfaceArea;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tconst rightCount = count - leftCount;\n\t\t\t\t\tif ( rightCount !== 0 ) {\n\n\t\t\t\t\t\trightProb = computeSurfaceArea( rightBounds ) / rootSurfaceArea;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tconst cost = TRAVERSAL_COST + PRIMITIVE_INTERSECT_COST * (\n\t\t\t\t\t\tleftProb * leftCount + rightProb * rightCount\n\t\t\t\t\t);\n\n\t\t\t\t\tif ( cost < bestCost ) {\n\n\t\t\t\t\t\taxis = a;\n\t\t\t\t\t\tbestCost = cost;\n\t\t\t\t\t\tpos = bin.candidate;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t} else {\n\n\t\tconsole.warn( `BVH: Invalid build strategy value ${ strategy } used.` );\n\n\t}\n\n\treturn { axis, pos };\n\n}\n\n// returns the average coordinate on the specified axis of all the provided primitives\nfunction getAverage( primitiveBounds, offset, count, axis ) {\n\n\tlet avg = 0;\n\tconst boundsOffset = primitiveBounds.offset;\n\tfor ( let i = offset, end = offset + count; i < end; i ++ ) {\n\n\t\tavg += primitiveBounds[ ( i - boundsOffset ) * 6 + axis * 2 ];\n\n\t}\n\n\treturn avg / count;\n\n}\n","export class BVHNode {\n\n\tconstructor() {\n\n\t\t// internal nodes have boundingData, left, right, and splitAxis\n\t\t// leaf nodes have offset and count (referring to primitives in the mesh geometry)\n\n\t\tthis.boundingData = new Float32Array( 6 );\n\n\t}\n\n}\n","// reorders the partition buffer such that for `count` elements after `offset`, elements on the left side of the split\n// will be on the left and elements on the right side of the split will be on the right. returns the index\n// of the first element on the right side, or offset + count if there are no elements on the right side.\nexport function partition( buffer, stride, primitiveBounds, offset, count, split ) {\n\n\tlet left = offset;\n\tlet right = offset + count - 1;\n\tconst pos = split.pos;\n\tconst axisOffset = split.axis * 2;\n\tconst boundsOffset = primitiveBounds.offset || 0;\n\n\t// hoare partitioning, see e.g. https://en.wikipedia.org/wiki/Quicksort#Hoare_partition_scheme\n\twhile ( true ) {\n\n\t\twhile ( left <= right && primitiveBounds[ ( left - boundsOffset ) * 6 + axisOffset ] < pos ) {\n\n\t\t\tleft ++;\n\n\t\t}\n\n\t\t// if a primitive center lies on the partition plane it is considered to be on the right side\n\t\twhile ( left <= right && primitiveBounds[ ( right - boundsOffset ) * 6 + axisOffset ] >= pos ) {\n\n\t\t\tright --;\n\n\t\t}\n\n\t\tif ( left < right ) {\n\n\t\t\t// we need to swap all of the information associated with the primitives at index\n\t\t\t// left and right; that's the elements in the partition buffer and the bounds\n\t\t\tfor ( let i = 0; i < stride; i ++ ) {\n\n\t\t\t\tlet t0 = buffer[ left * stride + i ];\n\t\t\t\tbuffer[ left * stride + i ] = buffer[ right * stride + i ];\n\t\t\t\tbuffer[ right * stride + i ] = t0;\n\n\t\t\t}\n\n\t\t\t// swap bounds\n\t\t\tfor ( let i = 0; i < 6; i ++ ) {\n\n\t\t\t\tconst l = left - boundsOffset;\n\t\t\t\tconst r = right - boundsOffset;\n\t\t\t\tconst tb = primitiveBounds[ l * 6 + i ];\n\t\t\t\tprimitiveBounds[ l * 6 + i ] = primitiveBounds[ r * 6 + i ];\n\t\t\t\tprimitiveBounds[ r * 6 + i ] = tb;\n\n\t\t\t}\n\n\t\t\tleft ++;\n\t\t\tright --;\n\n\t\t} else {\n\n\t\t\treturn left;\n\n\t\t}\n\n\t}\n\n}\n","import { BYTES_PER_NODE, IS_LEAFNODE_FLAG } from '../Constants.js';\n\nlet float32Array, uint32Array, uint16Array, uint8Array;\nconst MAX_POINTER = Math.pow( 2, 32 );\n\nexport function countNodes( node ) {\n\n\tif ( 'count' in node ) {\n\n\t\treturn 1;\n\n\t} else {\n\n\t\treturn 1 + countNodes( node.left ) + countNodes( node.right );\n\n\t}\n\n}\n\nexport function populateBuffer( byteOffset, node, buffer ) {\n\n\tfloat32Array = new Float32Array( buffer );\n\tuint32Array = new Uint32Array( buffer );\n\tuint16Array = new Uint16Array( buffer );\n\tuint8Array = new Uint8Array( buffer );\n\n\treturn _populateBuffer( byteOffset, node );\n\n}\n\n// pack structure\n// boundingData \t\t\t\t: 6 float32\n// right / offset \t\t\t\t: 1 uint32\n// splitAxis / isLeaf + count \t: 1 uint32 / 2 uint16\nfunction _populateBuffer( byteOffset, node ) {\n\n\tconst node32Index = byteOffset / 4;\n\tconst node16Index = byteOffset / 2;\n\tconst isLeaf = 'count' in node;\n\tconst boundingData = node.boundingData;\n\tfor ( let i = 0; i < 6; i ++ ) {\n\n\t\tfloat32Array[ node32Index + i ] = boundingData[ i ];\n\n\t}\n\n\tif ( isLeaf ) {\n\n\t\tif ( node.buffer ) {\n\n\t\t\tuint8Array.set( new Uint8Array( node.buffer ), byteOffset );\n\t\t\treturn byteOffset + node.buffer.byteLength;\n\n\t\t} else {\n\n\t\t\tuint32Array[ node32Index + 6 ] = node.offset;\n\t\t\tuint16Array[ node16Index + 14 ] = node.count;\n\t\t\tuint16Array[ node16Index + 15 ] = IS_LEAFNODE_FLAG;\n\t\t\treturn byteOffset + BYTES_PER_NODE;\n\n\t\t}\n\n\t} else {\n\n\t\tconst { left, right, splitAxis } = node;\n\n\t\t// fill in the left node contents\n\t\tconst leftByteOffset = byteOffset + BYTES_PER_NODE;\n\t\tlet rightByteOffset = _populateBuffer( leftByteOffset, left );\n\n\t\t// calculate relative offset from parent to right child\n\t\tconst currentNodeIndex = byteOffset / BYTES_PER_NODE;\n\t\tconst rightNodeIndex = rightByteOffset / BYTES_PER_NODE;\n\t\tconst relativeRightIndex = rightNodeIndex - currentNodeIndex;\n\n\t\t// check if the relative offset is too high\n\t\tif ( relativeRightIndex > MAX_POINTER ) {\n\n\t\t\tthrow new Error( 'MeshBVH: Cannot store relative child node offset greater than 32 bits.' );\n\n\t\t}\n\n\t\t// fill in the right node contents (store as relative offset)\n\t\tuint32Array[ node32Index + 6 ] = relativeRightIndex;\n\t\tuint32Array[ node32Index + 7 ] = splitAxis;\n\n\t\t// return the next available buffer pointer\n\t\treturn _populateBuffer( rightByteOffset, right );\n\n\t}\n\n}\n","import { getBounds } from './computeBoundsUtils.js';\nimport { getOptimalSplit } from './splitUtils.js';\nimport { getLongestEdgeIndex } from '../../utils/ArrayBoxUtilities.js';\nimport { BVHNode } from '../BVHNode.js';\nimport { BYTES_PER_NODE } from '../Constants.js';\n\nimport { partition } from './sortUtils.js';\nimport { countNodes, populateBuffer } from './buildUtils.js';\n\nexport function buildTree( bvh, primitiveBounds, offset, count, options, loadRange ) {\n\n\t// expand variables\n\tconst {\n\t\tmaxDepth,\n\t\tverbose,\n\t\ttargetLeafSize,\n\t\t_strictLeafSize = Infinity,\n\t\tstrategy,\n\t\tonProgress,\n\t} = options;\n\n\tconst partitionBuffer = bvh.primitiveBuffer;\n\tconst partitionStride = bvh.primitiveBufferStride;\n\n\t// generate intermediate variables\n\tconst cacheCentroidBoundingData = new Float32Array( 6 );\n\tlet reachedMaxDepth = false;\n\n\tconst root = new BVHNode();\n\tgetBounds( primitiveBounds, offset, count, root.boundingData, cacheCentroidBoundingData );\n\tsplitNode( root, offset, count, cacheCentroidBoundingData );\n\treturn root;\n\n\tfunction triggerProgress( primitivesProcessed ) {\n\n\t\tif ( onProgress ) {\n\n\t\t\tonProgress( ( primitivesProcessed - loadRange.offset ) / loadRange.count );\n\n\t\t}\n\n\t}\n\n\t// either recursively splits the given node, creating left and right subtrees for it, or makes it a leaf node,\n\t// recording the offset and count of its primitives and writing them into the reordered geometry index.\n\tfunction splitNode( node, offset, count, centroidBoundingData = null, depth = 0 ) {\n\n\t\tif ( ! reachedMaxDepth && depth >= maxDepth ) {\n\n\t\t\treachedMaxDepth = true;\n\t\t\tif ( verbose ) {\n\n\t\t\t\tconsole.warn( `BVH: Max depth of ${ maxDepth } reached when generating BVH. Consider increasing maxDepth.` );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// A hard guarantee that no leaf exceeds \"_strictLeafSize\" primitives. When this node is over\n\t\t// that limit it must keep splitting regardless of the heuristic.\n\t\tconst mustSplit = count > _strictLeafSize;\n\n\t\t// early out if we've met our capacity - unless the strict guarantee still requires a split\n\t\tif ( ( count <= targetLeafSize && ! mustSplit ) || depth >= maxDepth ) {\n\n\t\t\ttriggerProgress( offset + count );\n\t\t\tnode.offset = offset;\n\t\t\tnode.count = count;\n\t\t\treturn node;\n\n\t\t}\n\n\t\t// Find where to split the volume\n\t\tconst split = getOptimalSplit( node.boundingData, centroidBoundingData, primitiveBounds, offset, count, strategy );\n\t\tlet splitOffset = split.axis === - 1 ? - 1 : partition( partitionBuffer, partitionStride, primitiveBounds, offset, count, split );\n\n\t\t// If the heuristic can't produce a usable split then make a leaf unless the strict guarantee requires the split -\n\t\t// in which case force an arbitrary median split. The axis comes from the node bounds so parallel and serial\n\t\t// builds produce identical trees.\n\t\tif ( split.axis === - 1 || splitOffset === offset || splitOffset === offset + count ) {\n\n\t\t\tif ( ! mustSplit ) {\n\n\t\t\t\ttriggerProgress( offset + count );\n\t\t\t\tnode.offset = offset;\n\t\t\t\tnode.count = count;\n\t\t\t\treturn node;\n\n\t\t\t}\n\n\t\t\tsplit.axis = Math.max( 0, getLongestEdgeIndex( node.boundingData ) );\n\t\t\tsplitOffset = offset + Math.max( 1, Math.floor( count / 2 ) );\n\n\t\t}\n\n\t\t// create the two new child nodes\n\t\tnode.splitAxis = split.axis;\n\n\t\t// create the left child and compute its bounding box\n\t\tconst left = new BVHNode();\n\t\tconst lstart = offset;\n\t\tconst lcount = splitOffset - offset;\n\t\tnode.left = left;\n\n\t\tgetBounds( primitiveBounds, lstart, lcount, left.boundingData, cacheCentroidBoundingData );\n\t\tsplitNode( left, lstart, lcount, cacheCentroidBoundingData, depth + 1 );\n\n\t\t// repeat for right\n\t\tconst right = new BVHNode();\n\t\tconst rstart = splitOffset;\n\t\tconst rcount = count - lcount;\n\t\tnode.right = right;\n\n\t\tgetBounds( primitiveBounds, rstart, rcount, right.boundingData, cacheCentroidBoundingData );\n\t\tsplitNode( right, rstart, rcount, cacheCentroidBoundingData, depth + 1 );\n\n\t\treturn node;\n\n\t}\n\n}\n\nexport function buildPackedTree( bvh, options ) {\n\n\tconst BufferConstructor = options.useSharedArrayBuffer ? SharedArrayBuffer : ArrayBuffer;\n\n\t// get the range of buffer data to construct / arrange\n\tconst rootRanges = bvh.getRootRanges( options.range );\n\tconst firstRange = rootRanges[ 0 ];\n\tconst lastRange = rootRanges[ rootRanges.length - 1 ];\n\tconst fullRange = {\n\t\toffset: firstRange.offset,\n\t\tcount: lastRange.offset + lastRange.count - firstRange.offset,\n\t};\n\n\t// construct the primitive bounds for sorting\n\tconst primitiveBounds = new Float32Array( 6 * fullRange.count );\n\tprimitiveBounds.offset = fullRange.offset;\n\tbvh.computePrimitiveBounds( fullRange.offset, fullRange.count, primitiveBounds );\n\n\t// Build BVH roots\n\tbvh._roots = rootRanges.map( range => {\n\n\t\tconst root = buildTree( bvh, primitiveBounds, range.offset, range.count, options, fullRange );\n\t\tconst nodeCount = countNodes( root );\n\t\tconst buffer = new BufferConstructor( BYTES_PER_NODE * nodeCount );\n\t\tpopulateBuffer( 0, root, buffer );\n\t\treturn buffer;\n\n\t} );\n\n}\n","export class PrimitivePool {\n\n\tconstructor( getNewPrimitive ) {\n\n\t\tthis._getNewPrimitive = getNewPrimitive;\n\t\tthis._primitives = [];\n\n\t}\n\n\tgetPrimitive() {\n\n\t\tconst primitives = this._primitives;\n\t\tif ( primitives.length === 0 ) {\n\n\t\t\treturn this._getNewPrimitive();\n\n\t\t} else {\n\n\t\t\treturn primitives.pop();\n\n\t\t}\n\n\t}\n\n\treleasePrimitive( primitive ) {\n\n\t\tthis._primitives.push( primitive );\n\n\t}\n\n}\n","class _BufferStack {\n\n\tconstructor() {\n\n\t\tthis.float32Array = null;\n\t\tthis.uint16Array = null;\n\t\tthis.uint32Array = null;\n\n\t\tconst stack = [];\n\t\tlet prevBuffer = null;\n\t\tthis.setBuffer = buffer => {\n\n\t\t\tif ( prevBuffer ) {\n\n\t\t\t\tstack.push( prevBuffer );\n\n\t\t\t}\n\n\t\t\tprevBuffer = buffer;\n\t\t\tthis.float32Array = new Float32Array( buffer );\n\t\t\tthis.uint16Array = new Uint16Array( buffer );\n\t\t\tthis.uint32Array = new Uint32Array( buffer );\n\n\t\t};\n\n\t\tthis.clearBuffer = () => {\n\n\t\t\tprevBuffer = null;\n\t\t\tthis.float32Array = null;\n\t\t\tthis.uint16Array = null;\n\t\t\tthis.uint32Array = null;\n\n\t\t\tif ( stack.length !== 0 ) {\n\n\t\t\t\tthis.setBuffer( stack.pop() );\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n}\n\nexport const BufferStack = /* @__PURE__ */ new _BufferStack();\n","import { Box3 } from 'three';\nimport { CONTAINED, UINT32_PER_NODE } from '../Constants.js';\nimport { arrayToBox } from '../../utils/ArrayBoxUtilities.js';\nimport { PrimitivePool } from '../../utils/PrimitivePool.js';\nimport { COUNT, OFFSET, LEFT_NODE, RIGHT_NODE, IS_LEAF, BOUNDING_DATA_INDEX } from '../utils/nodeBufferUtils.js';\nimport { BufferStack } from '../utils/BufferStack.js';\n\nlet _box1, _box2;\nconst boxStack = [];\nconst boxPool = /* @__PURE__ */ new PrimitivePool( () => new Box3() );\n\nexport function shapecast( bvh, root, intersectsBounds, intersectsRange, boundsTraverseOrder, nodeOffset ) {\n\n\t// setup\n\t_box1 = boxPool.getPrimitive();\n\t_box2 = boxPool.getPrimitive();\n\tboxStack.push( _box1, _box2 );\n\tBufferStack.setBuffer( bvh._roots[ root ] );\n\n\tconst result = shapecastTraverse( 0, bvh.geometry, intersectsBounds, intersectsRange, boundsTraverseOrder, nodeOffset );\n\n\t// cleanup\n\tBufferStack.clearBuffer();\n\tboxPool.releasePrimitive( _box1 );\n\tboxPool.releasePrimitive( _box2 );\n\tboxStack.pop();\n\tboxStack.pop();\n\n\tconst length = boxStack.length;\n\tif ( length > 0 ) {\n\n\t\t_box2 = boxStack[ length - 1 ];\n\t\t_box1 = boxStack[ length - 2 ];\n\n\t}\n\n\treturn result;\n\n}\n\nfunction shapecastTraverse(\n\tnodeIndex32,\n\tgeometry,\n\tintersectsBoundsFunc,\n\tintersectsRangeFunc,\n\tnodeScoreFunc = null,\n\tnodeIndexOffset = 0, // offset for unique node identifier\n\tdepth = 0\n) {\n\n\tconst { float32Array, uint16Array, uint32Array } = BufferStack;\n\tlet nodeIndex16 = nodeIndex32 * 2;\n\n\tconst isLeaf = IS_LEAF( nodeIndex16, uint16Array );\n\tif ( isLeaf ) {\n\n\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\t\tarrayToBox( BOUNDING_DATA_INDEX( nodeIndex32 ), float32Array, _box1 );\n\t\treturn intersectsRangeFunc( offset, count, false, depth, nodeIndexOffset + nodeIndex32 / UINT32_PER_NODE, _box1 );\n\n\t} else {\n\n\t\tconst left = LEFT_NODE( nodeIndex32 );\n\t\tconst right = RIGHT_NODE( nodeIndex32, uint32Array );\n\t\tlet c1 = left;\n\t\tlet c2 = right;\n\n\t\tlet score1, score2;\n\t\tlet box1, box2;\n\t\tif ( nodeScoreFunc ) {\n\n\t\t\tbox1 = _box1;\n\t\t\tbox2 = _box2;\n\n\t\t\t// bounding data is not offset\n\t\t\tarrayToBox( BOUNDING_DATA_INDEX( c1 ), float32Array, box1 );\n\t\t\tarrayToBox( BOUNDING_DATA_INDEX( c2 ), float32Array, box2 );\n\n\t\t\tscore1 = nodeScoreFunc( box1 );\n\t\t\tscore2 = nodeScoreFunc( box2 );\n\n\t\t\tif ( score2 < score1 ) {\n\n\t\t\t\tc1 = right;\n\t\t\t\tc2 = left;\n\n\t\t\t\tconst temp = score1;\n\t\t\t\tscore1 = score2;\n\t\t\t\tscore2 = temp;\n\n\t\t\t\tbox1 = box2;\n\t\t\t\t// box2 is always set before use below\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Check box 1 intersection\n\t\tif ( ! box1 ) {\n\n\t\t\tbox1 = _box1;\n\t\t\tarrayToBox( BOUNDING_DATA_INDEX( c1 ), float32Array, box1 );\n\n\t\t}\n\n\t\tconst isC1Leaf = IS_LEAF( c1 * 2, uint16Array );\n\t\tconst c1Intersection = intersectsBoundsFunc( box1, isC1Leaf, score1, depth + 1, nodeIndexOffset + c1 / UINT32_PER_NODE );\n\n\t\tlet c1StopTraversal;\n\t\tif ( c1Intersection === CONTAINED ) {\n\n\t\t\tconst offset = getLeftOffset( c1 );\n\t\t\tconst end = getRightEndOffset( c1 );\n\t\t\tconst count = end - offset;\n\n\t\t\tc1StopTraversal = intersectsRangeFunc( offset, count, true, depth + 1, nodeIndexOffset + c1 / UINT32_PER_NODE, box1 );\n\n\t\t} else {\n\n\t\t\tc1StopTraversal =\n\t\t\t\tc1Intersection &&\n\t\t\t\tshapecastTraverse(\n\t\t\t\t\tc1,\n\t\t\t\t\tgeometry,\n\t\t\t\t\tintersectsBoundsFunc,\n\t\t\t\t\tintersectsRangeFunc,\n\t\t\t\t\tnodeScoreFunc,\n\t\t\t\t\tnodeIndexOffset,\n\t\t\t\t\tdepth + 1\n\t\t\t\t);\n\n\t\t}\n\n\t\tif ( c1StopTraversal ) return true;\n\n\t\t// Check box 2 intersection\n\t\t// cached box2 will have been overwritten by previous traversal\n\t\tbox2 = _box2;\n\t\tarrayToBox( BOUNDING_DATA_INDEX( c2 ), float32Array, box2 );\n\n\t\tconst isC2Leaf = IS_LEAF( c2 * 2, uint16Array );\n\t\tconst c2Intersection = intersectsBoundsFunc( box2, isC2Leaf, score2, depth + 1, nodeIndexOffset + c2 / UINT32_PER_NODE );\n\n\t\tlet c2StopTraversal;\n\t\tif ( c2Intersection === CONTAINED ) {\n\n\t\t\tconst offset = getLeftOffset( c2 );\n\t\t\tconst end = getRightEndOffset( c2 );\n\t\t\tconst count = end - offset;\n\n\t\t\tc2StopTraversal = intersectsRangeFunc( offset, count, true, depth + 1, nodeIndexOffset + c2 / UINT32_PER_NODE, box2 );\n\n\t\t} else {\n\n\t\t\tc2StopTraversal =\n\t\t\t\tc2Intersection &&\n\t\t\t\tshapecastTraverse(\n\t\t\t\t\tc2,\n\t\t\t\t\tgeometry,\n\t\t\t\t\tintersectsBoundsFunc,\n\t\t\t\t\tintersectsRangeFunc,\n\t\t\t\t\tnodeScoreFunc,\n\t\t\t\t\tnodeIndexOffset,\n\t\t\t\t\tdepth + 1\n\t\t\t\t);\n\n\t\t}\n\n\t\tif ( c2StopTraversal ) return true;\n\n\t\treturn false;\n\n\t\t// Define these inside the function so it has access to the local variables needed\n\t\t// when converting to the buffer equivalents\n\t\tfunction getLeftOffset( nodeIndex32 ) {\n\n\t\t\tconst { uint16Array, uint32Array } = BufferStack;\n\t\t\tlet nodeIndex16 = nodeIndex32 * 2;\n\n\t\t\t// traverse until we find a leaf\n\t\t\twhile ( ! IS_LEAF( nodeIndex16, uint16Array ) ) {\n\n\t\t\t\tnodeIndex32 = LEFT_NODE( nodeIndex32 );\n\t\t\t\tnodeIndex16 = nodeIndex32 * 2;\n\n\t\t\t}\n\n\t\t\treturn OFFSET( nodeIndex32, uint32Array );\n\n\t\t}\n\n\t\tfunction getRightEndOffset( nodeIndex32 ) {\n\n\t\t\tconst { uint16Array, uint32Array } = BufferStack;\n\t\t\tlet nodeIndex16 = nodeIndex32 * 2;\n\n\t\t\t// traverse until we find a leaf\n\t\t\twhile ( ! IS_LEAF( nodeIndex16, uint16Array ) ) {\n\n\t\t\t\t// adjust offset to point to the right node\n\t\t\t\tnodeIndex32 = RIGHT_NODE( nodeIndex32, uint32Array );\n\t\t\t\tnodeIndex16 = nodeIndex32 * 2;\n\n\t\t\t}\n\n\t\t\t// return the end offset of the triangle range\n\t\t\treturn OFFSET( nodeIndex32, uint32Array ) + COUNT( nodeIndex16, uint16Array );\n\n\t\t}\n\n\t}\n\n}\n","import { Box3, Matrix4 } from 'three';\nimport { BufferStack } from '../utils/BufferStack.js';\nimport { BOUNDING_DATA_INDEX, COUNT, IS_LEAF, LEFT_NODE, OFFSET, RIGHT_NODE } from '../utils/nodeBufferUtils.js';\nimport { arrayToBox } from '../../utils/ArrayBoxUtilities.js';\nimport { PrimitivePool } from '../../utils/PrimitivePool.js';\nimport { BYTES_PER_NODE, UINT32_PER_NODE } from '../Constants.js';\n\nconst _bufferStack1 = /* @__PURE__ */ new BufferStack.constructor();\nconst _bufferStack2 = /* @__PURE__ */ new BufferStack.constructor();\nconst _boxPool = /* @__PURE__ */ new PrimitivePool( () => new Box3() );\nconst _leftBox1 = /* @__PURE__ */ new Box3();\nconst _rightBox1 = /* @__PURE__ */ new Box3();\n\nconst _leftBox2 = /* @__PURE__ */ new Box3();\nconst _rightBox2 = /* @__PURE__ */ new Box3();\n\nlet _active = false;\n\nexport function bvhcast( bvh, otherBvh, matrixToLocal, intersectsRanges ) {\n\n\tif ( _active ) {\n\n\t\tthrow new Error( 'MeshBVH: Recursive calls to bvhcast not supported.' );\n\n\t}\n\n\t_active = true;\n\n\tconst roots = bvh._roots;\n\tconst otherRoots = otherBvh._roots;\n\tlet result;\n\tlet nodeOffset1 = 0;\n\tlet nodeOffset2 = 0;\n\tconst invMat = new Matrix4().copy( matrixToLocal ).invert();\n\n\t// iterate over the first set of roots\n\tfor ( let i = 0, il = roots.length; i < il; i ++ ) {\n\n\t\t_bufferStack1.setBuffer( roots[ i ] );\n\t\tnodeOffset2 = 0;\n\n\t\t// prep the initial root box\n\t\tconst localBox = _boxPool.getPrimitive();\n\t\tarrayToBox( BOUNDING_DATA_INDEX( 0 ), _bufferStack1.float32Array, localBox );\n\t\tlocalBox.applyMatrix4( invMat );\n\n\t\t// iterate over the second set of roots\n\t\tfor ( let j = 0, jl = otherRoots.length; j < jl; j ++ ) {\n\n\t\t\t_bufferStack2.setBuffer( otherRoots[ j ] );\n\n\t\t\tresult = _traverse(\n\t\t\t\t0, 0, matrixToLocal, invMat, intersectsRanges,\n\t\t\t\tnodeOffset1, nodeOffset2, 0, 0,\n\t\t\t\tlocalBox,\n\t\t\t);\n\n\t\t\t_bufferStack2.clearBuffer();\n\t\t\tnodeOffset2 += otherRoots[ j ].byteLength / BYTES_PER_NODE;\n\n\t\t\tif ( result ) {\n\n\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// release stack info\n\t\t_boxPool.releasePrimitive( localBox );\n\t\t_bufferStack1.clearBuffer();\n\t\tnodeOffset1 += roots[ i ].byteLength / BYTES_PER_NODE;\n\n\t\tif ( result ) {\n\n\t\t\tbreak;\n\n\t\t}\n\n\t}\n\n\t_active = false;\n\treturn result;\n\n}\n\nfunction _traverse(\n\tnode1Index32,\n\tnode2Index32,\n\tmatrix2to1,\n\tmatrix1to2,\n\tintersectsRangesFunc,\n\n\t// offsets for ids\n\tnode1IndexOffset = 0,\n\tnode2IndexOffset = 0,\n\n\t// tree depth\n\tdepth1 = 0,\n\tdepth2 = 0,\n\n\tcurrBox = null,\n\treversed = false,\n\n) {\n\n\t// get the buffer stacks associated with the current indices\n\tlet bufferStack1, bufferStack2;\n\tif ( reversed ) {\n\n\t\tbufferStack1 = _bufferStack2;\n\t\tbufferStack2 = _bufferStack1;\n\n\t} else {\n\n\t\tbufferStack1 = _bufferStack1;\n\t\tbufferStack2 = _bufferStack2;\n\n\t}\n\n\t// get the local instances of the typed buffers\n\tconst\n\t\tfloat32Array1 = bufferStack1.float32Array,\n\t\tuint32Array1 = bufferStack1.uint32Array,\n\t\tuint16Array1 = bufferStack1.uint16Array,\n\t\tfloat32Array2 = bufferStack2.float32Array,\n\t\tuint32Array2 = bufferStack2.uint32Array,\n\t\tuint16Array2 = bufferStack2.uint16Array;\n\n\tconst node1Index16 = node1Index32 * 2;\n\tconst node2Index16 = node2Index32 * 2;\n\tconst isLeaf1 = IS_LEAF( node1Index16, uint16Array1 );\n\tconst isLeaf2 = IS_LEAF( node2Index16, uint16Array2 );\n\tlet result = false;\n\tif ( isLeaf2 && isLeaf1 ) {\n\n\t\t// if both bounds are leaf nodes then fire the callback if the boxes intersect\n\t\t// Note the \"nodeIndex\" values are just intended to be used as unique identifiers in the tree and\n\t\t// not used for accessing data\n\t\tif ( reversed ) {\n\n\t\t\tresult = intersectsRangesFunc(\n\t\t\t\tOFFSET( node2Index32, uint32Array2 ), COUNT( node2Index32 * 2, uint16Array2 ),\n\t\t\t\tOFFSET( node1Index32, uint32Array1 ), COUNT( node1Index32 * 2, uint16Array1 ),\n\t\t\t\tdepth2, node2IndexOffset + node2Index32 / UINT32_PER_NODE,\n\t\t\t\tdepth1, node1IndexOffset + node1Index32 / UINT32_PER_NODE,\n\t\t\t);\n\n\t\t} else {\n\n\t\t\tresult = intersectsRangesFunc(\n\t\t\t\tOFFSET( node1Index32, uint32Array1 ), COUNT( node1Index32 * 2, uint16Array1 ),\n\t\t\t\tOFFSET( node2Index32, uint32Array2 ), COUNT( node2Index32 * 2, uint16Array2 ),\n\t\t\t\tdepth1, node1IndexOffset + node1Index32 / UINT32_PER_NODE,\n\t\t\t\tdepth2, node2IndexOffset + node2Index32 / UINT32_PER_NODE,\n\t\t\t);\n\n\t\t}\n\n\t} else if ( isLeaf2 ) {\n\n\t\t// SWAP\n\t\t// If we've traversed to the leaf node on the other bvh then we need to swap over\n\t\t// to traverse down the first one\n\n\t\t// get the new box to use\n\t\tconst newBox = _boxPool.getPrimitive();\n\t\tarrayToBox( BOUNDING_DATA_INDEX( node2Index32 ), float32Array2, newBox );\n\t\tnewBox.applyMatrix4( matrix2to1 );\n\n\t\t// get the child bounds to check before traversal\n\t\tconst cl1 = LEFT_NODE( node1Index32 );\n\t\tconst cr1 = RIGHT_NODE( node1Index32, uint32Array1 );\n\t\tarrayToBox( BOUNDING_DATA_INDEX( cl1 ), float32Array1, _leftBox1 );\n\t\tarrayToBox( BOUNDING_DATA_INDEX( cr1 ), float32Array1, _rightBox1 );\n\n\t\t// precompute the intersections otherwise the global boxes will be modified during traversal\n\t\tconst intersectCl1 = newBox.intersectsBox( _leftBox1 );\n\t\tconst intersectCr1 = newBox.intersectsBox( _rightBox1 );\n\t\tresult = (\n\t\t\tintersectCl1 && _traverse(\n\t\t\t\tnode2Index32, cl1, matrix1to2, matrix2to1, intersectsRangesFunc,\n\t\t\t\tnode2IndexOffset, node1IndexOffset, depth2, depth1 + 1,\n\t\t\t\tnewBox, ! reversed,\n\t\t\t)\n\t\t) || (\n\t\t\tintersectCr1 && _traverse(\n\t\t\t\tnode2Index32, cr1, matrix1to2, matrix2to1, intersectsRangesFunc,\n\t\t\t\tnode2IndexOffset, node1IndexOffset, depth2, depth1 + 1,\n\t\t\t\tnewBox, ! reversed,\n\t\t\t)\n\t\t);\n\n\t\t_boxPool.releasePrimitive( newBox );\n\n\t} else {\n\n\t\t// if neither are leaves then we should swap if one of the children does not\n\t\t// intersect with the current bounds\n\n\t\t// get the child bounds to check\n\t\tconst cl2 = LEFT_NODE( node2Index32 );\n\t\tconst cr2 = RIGHT_NODE( node2Index32, uint32Array2 );\n\t\tarrayToBox( BOUNDING_DATA_INDEX( cl2 ), float32Array2, _leftBox2 );\n\t\tarrayToBox( BOUNDING_DATA_INDEX( cr2 ), float32Array2, _rightBox2 );\n\n\t\tconst leftIntersects = currBox.intersectsBox( _leftBox2 );\n\t\tconst rightIntersects = currBox.intersectsBox( _rightBox2 );\n\t\tif ( leftIntersects && rightIntersects ) {\n\n\t\t\t// continue to traverse both children if they both intersect\n\t\t\tresult = _traverse(\n\t\t\t\tnode1Index32, cl2, matrix2to1, matrix1to2, intersectsRangesFunc,\n\t\t\t\tnode1IndexOffset, node2IndexOffset, depth1, depth2 + 1,\n\t\t\t\tcurrBox, reversed,\n\t\t\t) || _traverse(\n\t\t\t\tnode1Index32, cr2, matrix2to1, matrix1to2, intersectsRangesFunc,\n\t\t\t\tnode1IndexOffset, node2IndexOffset, depth1, depth2 + 1,\n\t\t\t\tcurrBox, reversed,\n\t\t\t);\n\n\t\t} else if ( leftIntersects ) {\n\n\t\t\tif ( isLeaf1 ) {\n\n\t\t\t\t// if the current box is a leaf then just continue\n\t\t\t\tresult = _traverse(\n\t\t\t\t\tnode1Index32, cl2, matrix2to1, matrix1to2, intersectsRangesFunc,\n\t\t\t\t\tnode1IndexOffset, node2IndexOffset, depth1, depth2 + 1,\n\t\t\t\t\tcurrBox, reversed,\n\t\t\t\t);\n\n\t\t\t} else {\n\n\t\t\t\t// SWAP\n\t\t\t\t// if only one box intersects then we have to swap to the other bvh to continue\n\t\t\t\tconst newBox = _boxPool.getPrimitive();\n\t\t\t\tnewBox.copy( _leftBox2 ).applyMatrix4( matrix2to1 );\n\n\t\t\t\tconst cl1 = LEFT_NODE( node1Index32 );\n\t\t\t\tconst cr1 = RIGHT_NODE( node1Index32, uint32Array1 );\n\t\t\t\tarrayToBox( BOUNDING_DATA_INDEX( cl1 ), float32Array1, _leftBox1 );\n\t\t\t\tarrayToBox( BOUNDING_DATA_INDEX( cr1 ), float32Array1, _rightBox1 );\n\n\t\t\t\t// precompute the intersections otherwise the global boxes will be modified during traversal\n\t\t\t\tconst intersectCl1 = newBox.intersectsBox( _leftBox1 );\n\t\t\t\tconst intersectCr1 = newBox.intersectsBox( _rightBox1 );\n\t\t\t\tresult = (\n\t\t\t\t\tintersectCl1 && _traverse(\n\t\t\t\t\t\tcl2, cl1, matrix1to2, matrix2to1, intersectsRangesFunc,\n\t\t\t\t\t\tnode2IndexOffset, node1IndexOffset, depth2, depth1 + 1,\n\t\t\t\t\t\tnewBox, ! reversed,\n\t\t\t\t\t)\n\t\t\t\t) || (\n\t\t\t\t\tintersectCr1 && _traverse(\n\t\t\t\t\t\tcl2, cr1, matrix1to2, matrix2to1, intersectsRangesFunc,\n\t\t\t\t\t\tnode2IndexOffset, node1IndexOffset, depth2, depth1 + 1,\n\t\t\t\t\t\tnewBox, ! reversed,\n\t\t\t\t\t)\n\t\t\t\t);\n\n\t\t\t\t_boxPool.releasePrimitive( newBox );\n\n\t\t\t}\n\n\t\t} else if ( rightIntersects ) {\n\n\t\t\tif ( isLeaf1 ) {\n\n\t\t\t\t// if the current box is a leaf then just continue\n\t\t\t\tresult = _traverse(\n\t\t\t\t\tnode1Index32, cr2, matrix2to1, matrix1to2, intersectsRangesFunc,\n\t\t\t\t\tnode1IndexOffset, node2IndexOffset, depth1, depth2 + 1,\n\t\t\t\t\tcurrBox, reversed,\n\t\t\t\t);\n\n\t\t\t} else {\n\n\t\t\t\t// SWAP\n\t\t\t\t// if only one box intersects then we have to swap to the other bvh to continue\n\t\t\t\tconst newBox = _boxPool.getPrimitive();\n\t\t\t\tnewBox.copy( _rightBox2 ).applyMatrix4( matrix2to1 );\n\n\t\t\t\tconst cl1 = LEFT_NODE( node1Index32 );\n\t\t\t\tconst cr1 = RIGHT_NODE( node1Index32, uint32Array1 );\n\t\t\t\tarrayToBox( BOUNDING_DATA_INDEX( cl1 ), float32Array1, _leftBox1 );\n\t\t\t\tarrayToBox( BOUNDING_DATA_INDEX( cr1 ), float32Array1, _rightBox1 );\n\n\t\t\t\t// precompute the intersections otherwise the global boxes will be modified during traversal\n\t\t\t\tconst intersectCl1 = newBox.intersectsBox( _leftBox1 );\n\t\t\t\tconst intersectCr1 = newBox.intersectsBox( _rightBox1 );\n\t\t\t\tresult = (\n\t\t\t\t\tintersectCl1 && _traverse(\n\t\t\t\t\t\tcr2, cl1, matrix1to2, matrix2to1, intersectsRangesFunc,\n\t\t\t\t\t\tnode2IndexOffset, node1IndexOffset, depth2, depth1 + 1,\n\t\t\t\t\t\tnewBox, ! reversed,\n\t\t\t\t\t)\n\t\t\t\t) || (\n\t\t\t\t\tintersectCr1 && _traverse(\n\t\t\t\t\t\tcr2, cr1, matrix1to2, matrix2to1, intersectsRangesFunc,\n\t\t\t\t\t\tnode2IndexOffset, node1IndexOffset, depth2, depth1 + 1,\n\t\t\t\t\t\tnewBox, ! reversed,\n\t\t\t\t\t)\n\t\t\t\t);\n\n\t\t\t\t_boxPool.releasePrimitive( newBox );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\treturn result;\n\n}\n\n","import { COUNT, IS_LEAF, LEFT_NODE, OFFSET, RIGHT_NODE, SPLIT_AXIS } from './utils/nodeBufferUtils.js';\n\nexport const BVHTraversalHelper = new ( class {\n\n\tconstructor() {\n\n\t\tlet buffer = null;\n\t\tlet uint32Array = null;\n\t\tlet uint16Array = null;\n\t\tlet traversing = false;\n\n\t\tthis.root = null;\n\t\tthis.buffer = null;\n\t\tthis.uint32Array = null;\n\t\tthis.uint16Array = null;\n\n\t\tthis.setBVH = ( bvh, root ) => {\n\n\t\t\tif ( traversing ) {\n\n\t\t\t\tthrow new Error( 'BVHTraversalHelper: cannot call setBVH during an active traversal.' );\n\n\t\t\t}\n\n\t\t\tthis.root = root;\n\t\t\tthis.buffer = buffer = bvh._roots[ root ];\n\t\t\tthis.uint16Array = uint16Array = new Uint16Array( buffer );\n\t\t\tthis.uint32Array = uint32Array = new Uint32Array( buffer );\n\n\t\t};\n\n\t\tthis.reset = () => {\n\n\t\t\tthis.root = null;\n\t\t\tthis.buffer = buffer = null;\n\t\t\tthis.uint16Array = uint16Array = null;\n\t\t\tthis.uint32Array = uint32Array = null;\n\n\t\t};\n\n\t\tthis.getRangeStart = node32Index => {\n\n\t\t\tlet node16Index = node32Index * 2;\n\t\t\twhile ( ! IS_LEAF( node16Index, uint16Array ) ) {\n\n\t\t\t\tnode32Index = LEFT_NODE( node32Index );\n\t\t\t\tnode16Index = node32Index * 2;\n\n\t\t\t}\n\n\t\t\treturn OFFSET( node32Index, uint32Array );\n\n\t\t};\n\n\t\tthis.getRangeEnd = node32Index => {\n\n\t\t\tlet node16Index = node32Index * 2;\n\t\t\twhile ( ! IS_LEAF( node16Index, uint16Array ) ) {\n\n\t\t\t\tnode32Index = RIGHT_NODE( node32Index, uint32Array );\n\t\t\t\tnode16Index = node32Index * 2;\n\n\t\t\t}\n\n\t\t\treturn OFFSET( node32Index, uint32Array ) + COUNT( node16Index, uint16Array );\n\n\t\t};\n\n\t\t// internal recursive walk - the public \"traverseBuffer\" wraps this with the re-entrancy guard\n\t\tconst walk = ( callback, node32Index, depth ) => {\n\n\t\t\tconst node16Index = node32Index * 2;\n\t\t\tconst isLeaf = IS_LEAF( node16Index, uint16Array );\n\t\t\tconst stopTraversal = callback( depth, isLeaf, node32Index );\n\t\t\tif ( ! stopTraversal && ! isLeaf ) {\n\n\t\t\t\tconst left = LEFT_NODE( node32Index );\n\t\t\t\tconst right = RIGHT_NODE( node32Index, uint32Array );\n\t\t\t\twalk( callback, left, depth + 1 );\n\t\t\t\twalk( callback, right, depth + 1 );\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.traverseBuffer = callback => {\n\n\t\t\tif ( traversing ) {\n\n\t\t\t\tthrow new Error( 'BVHTraversalHelper: cannot start a traversal during an active traversal.' );\n\n\t\t\t}\n\n\t\t\ttraversing = true;\n\t\t\ttry {\n\n\t\t\t\twalk( callback, 0, 0 );\n\n\t\t\t} finally {\n\n\t\t\t\ttraversing = false;\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.traverse = callback => {\n\n\t\t\tthis.traverseBuffer( ( depth, isLeaf, node32Index ) => {\n\n\t\t\t\tif ( isLeaf ) {\n\n\t\t\t\t\tconst node16Index = node32Index * 2;\n\t\t\t\t\tconst offset = uint32Array[ node32Index + 6 ];\n\t\t\t\t\tconst count = uint16Array[ node16Index + 14 ];\n\t\t\t\t\treturn callback( depth, isLeaf, new Float32Array( buffer, node32Index * 4, 6 ), offset, count );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconst splitAxis = SPLIT_AXIS( node32Index, uint32Array );\n\t\t\t\t\treturn callback( depth, isLeaf, new Float32Array( buffer, node32Index * 4, 6 ), splitAxis );\n\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t};\n\n\t}\n\n} )();\n","/** @import { Matrix4 } from 'three' */\nimport { Box3 } from 'three';\nimport { BYTES_PER_NODE, UINT32_PER_NODE, DEFAULT_OPTIONS, FLOAT32_EPSILON } from './Constants.js';\nimport { arrayToBox } from '../utils/ArrayBoxUtilities.js';\nimport { IS_LEAF, LEFT_NODE, RIGHT_NODE, COUNT, OFFSET } from './utils/nodeBufferUtils.js';\nimport { buildPackedTree } from './build/buildTree.js';\nimport { shapecast as shapecastFunc } from './cast/shapecast.js';\nimport { bvhcast } from './cast/bvhcast.js';\nimport { BVHTraversalHelper } from './BVHTraversalHelper.js';\n\nconst _tempBox = /* @__PURE__ */ new Box3();\nconst _tempBuffer = /* @__PURE__ */ new Float32Array( 6 );\n\n/**\n * @callback BoundsTraverseOrderCallback\n * @param {Box3} box\n * @returns {number}\n */\n\n/**\n * @callback IntersectsBoundsCallback\n * @param {Box3} box\n * @param {boolean} isLeaf\n * @param {number|undefined} score\n * @param {number} depth\n * @param {number} nodeIndex\n * @returns {number}\n */\n\n/**\n * @callback IntersectsRangeCallback\n * @param {number} offset\n * @param {number} count\n * @param {boolean} contained\n * @param {number} depth\n * @param {number} nodeIndex\n * @param {Box3} box\n * @returns {boolean}\n */\n\n/**\n * @callback IntersectsRangesCallback\n * @param {number} offset1\n * @param {number} count1\n * @param {number} offset2\n * @param {number} count2\n * @param {number} depth1\n * @param {number} nodeIndex1\n * @param {number} depth2\n * @param {number} nodeIndex2\n * @returns {boolean}\n */\n\n/**\n * Abstract base class for BVH implementations. Provides core tree traversal and spatial query\n * methods. Subclasses implement primitive-specific logic by overriding `writePrimitiveBounds`\n * and related internal methods.\n */\nexport class BVH {\n\n\tconstructor() {\n\n\t\tthis._roots = null;\n\t\tthis.primitiveBuffer = null;\n\t\tthis.primitiveBufferStride = null;\n\n\t}\n\n\tinit( options ) {\n\n\t\toptions = {\n\t\t\t...DEFAULT_OPTIONS,\n\t\t\t...options,\n\t\t};\n\n\t\tif ( 'maxLeafSize' in options ) {\n\n\t\t\tconsole.warn( 'BVH: \"maxLeafSize\" option has been deprecated. Use \"targetLeafSize\", instead.' );\n\t\t\toptions = {\n\t\t\t\t...options,\n\t\t\t\ttargetLeafSize: options.maxLeafSize,\n\t\t\t};\n\n\t\t}\n\n\t\tbuildPackedTree( this, options );\n\n\t}\n\n\tgetRootRanges( /* range */ ) {\n\n\t\t// TODO: can we avoid passing range in here?\n\t\tthrow new Error( 'BVH: getRootRanges() not implemented' );\n\n\t}\n\n\t// write the i-th primitive bounds in a 6-value min / max format to the buffer\n\t// starting at the given \"writeOffset\"\n\twritePrimitiveBounds( /* i, buffer, writeOffset */ ) {\n\n\t\tthrow new Error( 'BVH: writePrimitiveBounds() not implemented' );\n\n\t}\n\n\t// writes the union bounds of all primitives in the given range in a min / max format\n\t// to the buffer\n\twritePrimitiveRangeBounds( offset, count, targetBuffer, baseIndex ) {\n\n\t\t// Initialize bounds\n\t\tlet minX = Infinity;\n\t\tlet minY = Infinity;\n\t\tlet minZ = Infinity;\n\t\tlet maxX = - Infinity;\n\t\tlet maxY = - Infinity;\n\t\tlet maxZ = - Infinity;\n\n\t\t// compute union of all bounds\n\t\tfor ( let i = offset, end = offset + count; i < end; i ++ ) {\n\n\t\t\tthis.writePrimitiveBounds( i, _tempBuffer, 0 );\n\n\t\t\t// compute union\n\t\t\tconst [ lx, ly, lz, rx, ry, rz ] = _tempBuffer;\n\t\t\tif ( lx < minX ) minX = lx;\n\t\t\tif ( rx > maxX ) maxX = rx;\n\t\t\tif ( ly < minY ) minY = ly;\n\t\t\tif ( ry > maxY ) maxY = ry;\n\t\t\tif ( lz < minZ ) minZ = lz;\n\t\t\tif ( rz > maxZ ) maxZ = rz;\n\n\t\t}\n\n\t\t// write bounds\n\t\ttargetBuffer[ baseIndex + 0 ] = minX;\n\t\ttargetBuffer[ baseIndex + 1 ] = minY;\n\t\ttargetBuffer[ baseIndex + 2 ] = minZ;\n\t\ttargetBuffer[ baseIndex + 3 ] = maxX;\n\t\ttargetBuffer[ baseIndex + 4 ] = maxY;\n\t\ttargetBuffer[ baseIndex + 5 ] = maxZ;\n\n\t\treturn targetBuffer;\n\n\t}\n\n\tcomputePrimitiveBounds( offset, count, targetBuffer ) {\n\n\t\tconst boundsOffset = targetBuffer.offset || 0;\n\t\tfor ( let i = offset, end = offset + count; i < end; i ++ ) {\n\n\t\t\tthis.writePrimitiveBounds( i, _tempBuffer, 0 );\n\n\t\t\t// construction primitive bounds requires a center + half extents format\n\t\t\tconst [ lx, ly, lz, rx, ry, rz ] = _tempBuffer;\n\n\t\t\tconst cx = ( lx + rx ) / 2;\n\t\t\tconst cy = ( ly + ry ) / 2;\n\t\t\tconst cz = ( lz + rz ) / 2;\n\n\t\t\tconst hx = ( rx - lx ) / 2;\n\t\t\tconst hy = ( ry - ly ) / 2;\n\t\t\tconst hz = ( rz - lz ) / 2;\n\n\t\t\tconst baseIndex = ( i - boundsOffset ) * 6;\n\t\t\ttargetBuffer[ baseIndex + 0 ] = cx;\n\t\t\ttargetBuffer[ baseIndex + 1 ] = hx + ( Math.abs( cx ) + hx ) * FLOAT32_EPSILON;\n\t\t\ttargetBuffer[ baseIndex + 2 ] = cy;\n\t\t\ttargetBuffer[ baseIndex + 3 ] = hy + ( Math.abs( cy ) + hy ) * FLOAT32_EPSILON;\n\t\t\ttargetBuffer[ baseIndex + 4 ] = cz;\n\t\t\ttargetBuffer[ baseIndex + 5 ] = hz + ( Math.abs( cz ) + hz ) * FLOAT32_EPSILON;\n\n\t\t}\n\n\t\treturn targetBuffer;\n\n\t}\n\n\t/**\n\t * Adjusts all primitive offsets stored in the BVH leaf nodes by the given value. Useful when\n\t * geometry buffers have been shifted or compacted (e.g. when merging geometries).\n\t * @param {number} offset\n\t */\n\tshiftPrimitiveOffsets( offset ) {\n\n\t\tconst indirectBuffer = this._indirectBuffer;\n\t\tif ( indirectBuffer ) {\n\n\t\t\t// the offsets are embedded in the indirect buffer\n\t\t\tfor ( let i = 0, l = indirectBuffer.length; i < l; i ++ ) {\n\n\t\t\t\tindirectBuffer[ i ] += offset;\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// offsets are embedded in the leaf nodes\n\t\t\tconst roots = this._roots;\n\t\t\tfor ( let rootIndex = 0; rootIndex < roots.length; rootIndex ++ ) {\n\n\t\t\t\tconst root = roots[ rootIndex ];\n\t\t\t\tconst uint32Array = new Uint32Array( root );\n\t\t\t\tconst uint16Array = new Uint16Array( root );\n\t\t\t\tconst totalNodes = root.byteLength / BYTES_PER_NODE;\n\t\t\t\tfor ( let node = 0; node < totalNodes; node ++ ) {\n\n\t\t\t\t\tconst node32Index = UINT32_PER_NODE * node;\n\t\t\t\t\tconst node16Index = 2 * node32Index;\n\t\t\t\t\tif ( IS_LEAF( node16Index, uint16Array ) ) {\n\n\t\t\t\t\t\t// offset value\n\t\t\t\t\t\tuint32Array[ node32Index + 6 ] += offset;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Traverses all nodes of the BVH, invoking a callback for each node.\n\t *\n\t * For leaf nodes the callback receives `( depth, isLeaf, boundingData, offset, count )`.\n\t * For internal nodes it receives `( depth, isLeaf, boundingData, splitAxis )` and may\n\t * return `true` to stop descending into that node's children.\n\t *\n\t * @param {Function} callback\n\t * @param {number} [rootIndex=0]\n\t */\n\ttraverse( callback, rootIndex = 0 ) {\n\n\t\tBVHTraversalHelper.setBVH( this, rootIndex );\n\t\tBVHTraversalHelper.traverse( callback );\n\t\tBVHTraversalHelper.reset();\n\n\t}\n\n\t/**\n\t * Refits all BVH node bounds to reflect the current primitive positions. Faster than\n\t * rebuilding the BVH but produces a less optimal tree after large vertex deformations.\n\t */\n\trefit( /* nodeIndices = null */ ) {\n\n\t\t// TODO: add support for \"nodeIndices\"\n\t\t// if ( nodeIndices && Array.isArray( nodeIndices ) ) {\n\n\t\t// \tnodeIndices = new Set( nodeIndices );\n\n\t\t// }\n\n\t\tconst roots = this._roots;\n\t\tfor ( let rootIndex = 0, rootCount = roots.length; rootIndex < rootCount; rootIndex ++ ) {\n\n\t\t\tconst buffer = roots[ rootIndex ];\n\t\t\tconst uint32Array = new Uint32Array( buffer );\n\t\t\tconst uint16Array = new Uint16Array( buffer );\n\t\t\tconst float32Array = new Float32Array( buffer );\n\t\t\tconst totalNodes = buffer.byteLength / BYTES_PER_NODE;\n\n\t\t\t// Traverse nodes from right to left so children are updated before parents\n\t\t\tfor ( let nodeIndex = totalNodes - 1; nodeIndex >= 0; nodeIndex -- ) {\n\n\t\t\t\tconst nodeIndex32 = nodeIndex * UINT32_PER_NODE;\n\t\t\t\tconst nodeIndex16 = nodeIndex32 * 2;\n\t\t\t\tconst isLeaf = IS_LEAF( nodeIndex16, uint16Array );\n\n\t\t\t\tif ( isLeaf ) {\n\n\t\t\t\t\t// get the bounds\n\t\t\t\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\t\t\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\t\t\t\t\tthis.writePrimitiveRangeBounds( offset, count, _tempBuffer, 0 );\n\n\t\t\t\t\t// write directly to node bounds (already in min/max format)\n\t\t\t\t\tfloat32Array.set( _tempBuffer, nodeIndex32 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconst left = LEFT_NODE( nodeIndex32 );\n\t\t\t\t\tconst right = RIGHT_NODE( nodeIndex32, uint32Array );\n\n\t\t\t\t\t// Union the bounds of left and right children\n\t\t\t\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\tconst leftMin = float32Array[ left + i ];\n\t\t\t\t\t\tconst leftMax = float32Array[ left + i + 3 ];\n\t\t\t\t\t\tconst rightMin = float32Array[ right + i ];\n\t\t\t\t\t\tconst rightMax = float32Array[ right + i + 3 ];\n\n\t\t\t\t\t\tfloat32Array[ nodeIndex32 + i ] = leftMin < rightMin ? leftMin : rightMin;\n\t\t\t\t\t\tfloat32Array[ nodeIndex32 + i + 3 ] = leftMax > rightMax ? leftMax : rightMax;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Computes the axis-aligned bounding box of all primitives in the BVH.\n\t * @param {Box3} target - Target box to write the result into.\n\t * @returns {Box3}\n\t */\n\tgetBoundingBox( target ) {\n\n\t\ttarget.makeEmpty();\n\n\t\tconst roots = this._roots;\n\t\troots.forEach( buffer => {\n\n\t\t\tarrayToBox( 0, new Float32Array( buffer ), _tempBox );\n\t\t\ttarget.union( _tempBox );\n\n\t\t} );\n\n\t\treturn target;\n\n\t}\n\n\t/**\n\t * A generalized traversal function for performing spatial queries against the BVH. Returns\n\t * `true` as soon as a primitive has been reported as intersected. The tree is traversed\n\t * depth-first; `boundsTraverseOrder` controls which child is visited first. Returning\n\t * `CONTAINED` from `intersectsBounds` skips further child traversal and intersects all\n\t * primitives in that subtree immediately.\n\t *\n\t * @param {Object} callbacks\n\t * @param {IntersectsBoundsCallback} callbacks.intersectsBounds\n\t * @param {IntersectsRangeCallback} [callbacks.intersectsRange]\n\t * @param {BoundsTraverseOrderCallback} [callbacks.boundsTraverseOrder]\n\t * @returns {boolean}\n\t */\n\t// TODO: see if we can get rid of \"iterateFunc\" here as well as the primitive so the function\n\t// API aligns with the \"shapecast\" implementation\n\tshapecast( callbacks ) {\n\n\t\t// TODO: can we get rid of \"scratchPrimitive\" and / or \"iterate\"? Or merge them somehow\n\t\tlet {\n\t\t\tboundsTraverseOrder,\n\t\t\tintersectsBounds,\n\t\t\tintersectsRange,\n\t\t\tintersectsPrimitive,\n\t\t\tscratchPrimitive,\n\t\t\titerate,\n\t\t} = callbacks;\n\n\t\t// wrap the intersectsRange function\n\t\tif ( intersectsRange && intersectsPrimitive ) {\n\n\t\t\tconst originalIntersectsRange = intersectsRange;\n\t\t\tintersectsRange = ( offset, count, contained, depth, nodeIndex ) => {\n\n\t\t\t\tif ( ! originalIntersectsRange( offset, count, contained, depth, nodeIndex ) ) {\n\n\t\t\t\t\treturn iterate( offset, count, this, intersectsPrimitive, contained, depth, scratchPrimitive );\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t};\n\n\t\t} else if ( ! intersectsRange ) {\n\n\t\t\tif ( intersectsPrimitive ) {\n\n\t\t\t\tintersectsRange = ( offset, count, contained, depth ) => {\n\n\t\t\t\t\treturn iterate( offset, count, this, intersectsPrimitive, contained, depth, scratchPrimitive );\n\n\t\t\t\t};\n\n\t\t\t} else {\n\n\t\t\t\tintersectsRange = ( offset, count, contained ) => {\n\n\t\t\t\t\treturn contained;\n\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t}\n\n\t\t// run shapecast\n\t\tlet result = false;\n\t\tlet nodeOffset = 0;\n\t\tconst roots = this._roots;\n\t\tfor ( let i = 0, l = roots.length; i < l; i ++ ) {\n\n\t\t\tconst root = roots[ i ];\n\t\t\tresult = shapecastFunc( this, i, intersectsBounds, intersectsRange, boundsTraverseOrder, nodeOffset );\n\n\t\t\tif ( result ) {\n\n\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tnodeOffset += root.byteLength / BYTES_PER_NODE;\n\n\t\t}\n\n\t\treturn result;\n\n\t}\n\n\t/**\n\t * Simultaneously traverses two BVH structures to find intersecting primitive pairs. Returns\n\t * `true` as soon as any intersection is reported. Both trees are traversed depth-first with\n\t * alternating descent. `matrixToLocal` transforms `otherBvh` into the local space of this BVH.\n\t *\n\t * @param {BVH} otherBvh\n\t * @param {Matrix4} matrixToLocal\n\t * @param {Object} callbacks\n\t * @param {IntersectsRangesCallback} callbacks.intersectsRanges\n\t * @returns {boolean}\n\t */\n\tbvhcast( otherBvh, matrixToLocal, callbacks ) {\n\n\t\tlet { intersectsRanges } = callbacks;\n\t\treturn bvhcast( this, otherBvh, matrixToLocal, intersectsRanges );\n\n\n\t}\n\n}\n","export function isSharedArrayBufferSupported() {\n\n\treturn typeof SharedArrayBuffer !== 'undefined';\n\n}\n\nexport function convertToBufferType( array, BufferConstructor ) {\n\n\tif ( array === null ) {\n\n\t\treturn array;\n\n\t} else if ( array.buffer ) {\n\n\t\tconst buffer = array.buffer;\n\t\tif ( buffer.constructor === BufferConstructor ) {\n\n\t\t\treturn array;\n\n\t\t}\n\n\t\tconst ArrayConstructor = array.constructor;\n\t\tconst result = new ArrayConstructor( new BufferConstructor( buffer.byteLength ) );\n\t\tresult.set( array );\n\t\treturn result;\n\n\t} else {\n\n\t\tif ( array.constructor === BufferConstructor ) {\n\n\t\t\treturn array;\n\n\t\t}\n\n\t\tconst result = new BufferConstructor( array.byteLength );\n\t\tnew Uint8Array( result ).set( new Uint8Array( array ) );\n\t\treturn result;\n\n\t}\n\n}\n","import { BufferAttribute } from 'three';\n\nexport function getVertexCount( geo ) {\n\n\treturn geo.index ? geo.index.count : geo.attributes.position.count;\n\n}\n\nexport function getTriCount( geo ) {\n\n\treturn getVertexCount( geo ) / 3;\n\n}\n\nexport function getIndexArray( vertexCount, BufferConstructor = ArrayBuffer ) {\n\n\tif ( vertexCount > 65535 ) {\n\n\t\treturn new Uint32Array( new BufferConstructor( 4 * vertexCount ) );\n\n\t} else {\n\n\t\treturn new Uint16Array( new BufferConstructor( 2 * vertexCount ) );\n\n\t}\n\n}\n\n// ensures that an index is present on the geometry\nexport function ensureIndex( geo, options ) {\n\n\tif ( ! geo.index ) {\n\n\t\tconst vertexCount = geo.attributes.position.count;\n\t\tconst BufferConstructor = options.useSharedArrayBuffer ? SharedArrayBuffer : ArrayBuffer;\n\t\tconst index = getIndexArray( vertexCount, BufferConstructor );\n\t\tgeo.setIndex( new BufferAttribute( index, 1 ) );\n\n\t\tfor ( let i = 0; i < vertexCount; i ++ ) {\n\n\t\t\tindex[ i ] = i;\n\n\t\t}\n\n\t}\n\n}\n\n// Computes the set of { offset, count } ranges which need independent BVH roots. Each\n// region in the geometry index that belongs to a different set of material groups requires\n// a separate BVH root, so that triangles indices belonging to one group never get swapped\n// with triangle indices belongs to another group. For example, if the groups were like this:\n//\n// [-------------------------------------------------------------]\n// |__________________|\n// g0 = [0, 20] |______________________||_____________________|\n// g1 = [16, 40] g2 = [41, 60]\n//\n// we would need four BVH roots: [0, 15], [16, 20], [21, 40], [41, 60].\nfunction getFullPrimitiveRange( geo, range, stride ) {\n\n\tconst primitiveCount = getVertexCount( geo ) / stride;\n\tconst drawRange = range ? range : geo.drawRange;\n\tconst start = drawRange.start / stride;\n\tconst end = ( drawRange.start + drawRange.count ) / stride;\n\n\tconst offset = Math.max( 0, start );\n\tconst count = Math.min( primitiveCount, end ) - offset;\n\treturn {\n\t\toffset: Math.floor( offset ),\n\t\tcount: Math.floor( count ),\n\t};\n\n}\n\nfunction getPrimitiveGroupRanges( geo, stride ) {\n\n\treturn geo.groups.map( group => ( {\n\t\toffset: group.start / stride,\n\t\tcount: group.count / stride,\n\t} ));\n\n}\n\n// Function that extracts a set of mutually exclusive ranges representing the primitives being\n// drawn as determined by the geometry groups, draw range, and user specified range\nexport function getRootPrimitiveRanges( geo, range, stride ) {\n\n\tconst drawRange = getFullPrimitiveRange( geo, range, stride );\n\tconst primitiveRanges = getPrimitiveGroupRanges( geo, stride );\n\tif ( ! primitiveRanges.length ) {\n\n\t\treturn [ drawRange ];\n\n\t}\n\n\tconst ranges = [];\n\tconst drawRangeStart = drawRange.offset;\n\tconst drawRangeEnd = drawRange.offset + drawRange.count;\n\n\t// Create events for group boundaries\n\tconst primitiveCount = getVertexCount( geo ) / stride;\n\tconst events = [];\n\tfor ( const group of primitiveRanges ) {\n\n\t\t// Account for cases where group size is set to Infinity\n\t\tconst { offset, count } = group;\n\t\tconst groupStart = offset;\n\t\tconst groupCount = isFinite( count ) ? count : ( primitiveCount - offset );\n\t\tconst groupEnd = ( offset + groupCount );\n\n\t\t// Only add events if the group intersects with the draw range\n\t\tif ( groupStart < drawRangeEnd && groupEnd > drawRangeStart ) {\n\n\t\t\tevents.push( { pos: Math.max( drawRangeStart, groupStart ), isStart: true } );\n\t\t\tevents.push( { pos: Math.min( drawRangeEnd, groupEnd ), isStart: false } );\n\n\t\t}\n\n\t}\n\n\t// Sort events by position, with 'end' events before 'start' events at the same position\n\tevents.sort( ( a, b ) => {\n\n\t\tif ( a.pos !== b.pos ) {\n\n\t\t\treturn a.pos - b.pos;\n\n\t\t} else {\n\n\t\t\treturn a.type === 'end' ? - 1 : 1;\n\n\t\t}\n\n\t} );\n\n\t// sweep through events and create ranges where activeGroups > 0\n\tlet activeGroups = 0;\n\tlet lastPos = null;\n\tfor ( const event of events ) {\n\n\t\tconst newPos = event.pos;\n\t\tif ( activeGroups !== 0 && newPos !== lastPos ) {\n\n\t\t\tranges.push( {\n\t\t\t\toffset: lastPos,\n\t\t\t\tcount: newPos - lastPos,\n\t\t\t} );\n\n\t\t}\n\n\t\tactiveGroups += event.isStart ? 1 : - 1;\n\t\tlastPos = newPos;\n\n\t}\n\n\treturn ranges;\n\n}\n","/** @import { BufferGeometry } from 'three' */\nimport { Box3 } from 'three';\nimport { SKIP_GENERATION, DEFAULT_OPTIONS } from './Constants.js';\nimport { isSharedArrayBufferSupported } from '../utils/BufferUtils.js';\nimport { ensureIndex, getRootPrimitiveRanges } from './build/geometryUtils.js';\nimport { BVH } from './BVH.js';\n\n// construct a new buffer that points to the set of triangles represented by the given ranges\nexport function generateIndirectBuffer( ranges, useSharedArrayBuffer ) {\n\n\tconst lastRange = ranges[ ranges.length - 1 ];\n\tconst useUint32 = lastRange.offset + lastRange.count > 2 ** 16;\n\n\t// use getRootIndexRanges which excludes gaps\n\tconst length = ranges.reduce( ( acc, val ) => acc + val.count, 0 );\n\tconst byteCount = useUint32 ? 4 : 2;\n\tconst buffer = useSharedArrayBuffer ? new SharedArrayBuffer( length * byteCount ) : new ArrayBuffer( length * byteCount );\n\tconst indirectBuffer = useUint32 ? new Uint32Array( buffer ) : new Uint16Array( buffer );\n\n\t// construct a compact form of the triangles in these ranges\n\tlet index = 0;\n\tfor ( let r = 0; r < ranges.length; r ++ ) {\n\n\t\tconst { offset, count } = ranges[ r ];\n\t\tfor ( let i = 0; i < count; i ++ ) {\n\n\t\t\tindirectBuffer[ index + i ] = offset + i;\n\n\t\t}\n\n\t\tindex += count;\n\n\t}\n\n\treturn indirectBuffer;\n\n}\n\n/**\n * Abstract base class for geometry-backed BVH implementations. Handles geometry\n * indexing, indirect mode, and bounding box initialization. Subclasses implement\n * primitive-specific bounds computation and raycasting via `writePrimitiveBounds`\n * and `raycastObject3D`.\n *\n * @param {BufferGeometry} geometry\n * @param {Object} [options]\n * @param {number} [options.strategy=CENTER] - Split strategy: `CENTER`, `AVERAGE`, or `SAH`.\n * @param {number} [options.maxDepth=40] - Maximum tree depth. Note that this can cause the target leaf size to not\n * be met if the tree is truncated.\n * @param {number} [options.targetLeafSize=10] - The target number of primitives per leaf node. Note that this is\n * a soft limit and generation strategies like SAH will terminate early if the heuristic determines.\n * @param {boolean} [options.setBoundingBox=true] - Set `geometry.boundingBox` if not already present.\n * @param {boolean} [options.useSharedArrayBuffer=false] - Use `SharedArrayBuffer` for BVH root buffers.\n * @param {boolean} [options.indirect=false] - Build using an indirect buffer, leaving the original index unmodified.\n * @param {boolean} [options.verbose=true] - Log build progress to the console.\n * @param {Function|null} [options.onProgress=null] - Called with a progress value in [0, 1] during build.\n * @param {Object|null} [options.range=null] - Restrict the BVH to a specific geometry group range.\n * @extends BVH\n */\nexport class GeometryBVH extends BVH {\n\n\t/**\n\t * Whether the BVH was built in indirect mode.\n\t * @type {boolean}\n\t * @readonly\n\t */\n\tget indirect() {\n\n\t\treturn ! ! this._indirectBuffer;\n\n\t}\n\n\tget primitiveStride() {\n\n\t\treturn null;\n\n\t}\n\n\tget primitiveBufferStride() {\n\n\t\treturn this.indirect ? 1 : this.primitiveStride;\n\n\t}\n\tset primitiveBufferStride( v ) {}\n\n\tget primitiveBuffer() {\n\n\t\treturn this.indirect ? this._indirectBuffer : this.geometry.index.array;\n\n\t}\n\tset primitiveBuffer( v ) {}\n\n\tconstructor( geometry, options = {} ) {\n\n\t\tif ( ! geometry.isBufferGeometry ) {\n\n\t\t\tthrow new Error( 'BVH: Only BufferGeometries are supported.' );\n\n\t\t} else if ( geometry.index && geometry.index.isInterleavedBufferAttribute ) {\n\n\t\t\tthrow new Error( 'BVH: InterleavedBufferAttribute is not supported for the index attribute.' );\n\n\t\t}\n\n\t\tif ( options.useSharedArrayBuffer && ! isSharedArrayBufferSupported() ) {\n\n\t\t\tthrow new Error( 'BVH: SharedArrayBuffer is not available.' );\n\n\t\t}\n\n\t\tsuper();\n\n\t\t// retain references to the geometry so we can use them it without having to\n\t\t// take a geometry reference in every function.\n\n\t\t/**\n\t\t * The geometry this BVH was built from.\n\t\t * @type {BufferGeometry}\n\t\t * @readonly\n\t\t */\n\t\tthis.geometry = geometry;\n\t\tthis.resolvePrimitiveIndex = options.indirect ? i => this._indirectBuffer[ i ] : i => i;\n\t\tthis.primitiveBuffer = null;\n\t\tthis.primitiveBufferStride = null;\n\t\tthis._indirectBuffer = null;\n\n\t\toptions = {\n\t\t\t...DEFAULT_OPTIONS,\n\t\t\t...options,\n\t\t};\n\n\t\t// build the BVH unless we're deserializing\n\t\tif ( ! options[ SKIP_GENERATION ] ) {\n\n\t\t\tthis.init( options );\n\n\t\t}\n\n\t}\n\n\tinit( options ) {\n\n\t\tconst { geometry, primitiveStride } = this;\n\n\t\tif ( options.indirect ) {\n\n\t\t\t// construct an buffer that is indirectly sorts the triangles used for the BVH\n\t\t\tconst ranges = getRootPrimitiveRanges( geometry, options.range, primitiveStride );\n\t\t\tconst indirectBuffer = generateIndirectBuffer( ranges, options.useSharedArrayBuffer );\n\t\t\tthis._indirectBuffer = indirectBuffer;\n\n\t\t} else {\n\n\t\t\tensureIndex( geometry, options );\n\n\t\t}\n\n\t\tsuper.init( options );\n\n\t\tif ( ! geometry.boundingBox && options.setBoundingBox ) {\n\n\t\t\tgeometry.boundingBox = this.getBoundingBox( new Box3() );\n\n\t\t}\n\n\t}\n\n\t// Abstract methods to be implemented by subclasses\n\tgetRootRanges( range ) {\n\n\t\t// TODO: can we avoid passing options in here\n\t\tif ( this.indirect ) {\n\n\t\t\treturn [ { offset: 0, count: this._indirectBuffer.length } ];\n\n\n\t\t} else {\n\n\t\t\treturn getRootPrimitiveRanges( this.geometry, range, this.primitiveStride );\n\n\t\t}\n\n\t}\n\n\traycastObject3D( /* object, raycaster, intersects = [] */ ) {\n\n\t\tthrow new Error( 'BVH: raycastObject3D() not implemented' );\n\n\t}\n\n}\n","import { Vector3 } from 'three';\n\nexport class SeparatingAxisBounds {\n\n\tconstructor() {\n\n\t\tthis.min = Infinity;\n\t\tthis.max = - Infinity;\n\n\t}\n\n\tsetFromPointsField( points, field ) {\n\n\t\tlet min = Infinity;\n\t\tlet max = - Infinity;\n\t\tfor ( let i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\tconst p = points[ i ];\n\t\t\tconst val = p[ field ];\n\t\t\tmin = val < min ? val : min;\n\t\t\tmax = val > max ? val : max;\n\n\t\t}\n\n\t\tthis.min = min;\n\t\tthis.max = max;\n\n\t}\n\n\tsetFromPoints( axis, points ) {\n\n\t\tlet min = Infinity;\n\t\tlet max = - Infinity;\n\t\tfor ( let i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\tconst p = points[ i ];\n\t\t\tconst val = axis.dot( p );\n\t\t\tmin = val < min ? val : min;\n\t\t\tmax = val > max ? val : max;\n\n\t\t}\n\n\t\tthis.min = min;\n\t\tthis.max = max;\n\n\t}\n\n\tisSeparated( other ) {\n\n\t\treturn this.min > other.max || other.min > this.max;\n\n\t}\n\n}\n\nSeparatingAxisBounds.prototype.setFromBox = ( function () {\n\n\tconst p = /* @__PURE__ */ new Vector3();\n\treturn function setFromBox( axis, box ) {\n\n\t\tconst boxMin = box.min;\n\t\tconst boxMax = box.max;\n\t\tlet min = Infinity;\n\t\tlet max = - Infinity;\n\t\tfor ( let x = 0; x <= 1; x ++ ) {\n\n\t\t\tfor ( let y = 0; y <= 1; y ++ ) {\n\n\t\t\t\tfor ( let z = 0; z <= 1; z ++ ) {\n\n\t\t\t\t\tp.x = boxMin.x * x + boxMax.x * ( 1 - x );\n\t\t\t\t\tp.y = boxMin.y * y + boxMax.y * ( 1 - y );\n\t\t\t\t\tp.z = boxMin.z * z + boxMax.z * ( 1 - z );\n\n\t\t\t\t\tconst val = axis.dot( p );\n\t\t\t\t\tmin = Math.min( val, min );\n\t\t\t\t\tmax = Math.max( val, max );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.min = min;\n\t\tthis.max = max;\n\n\t};\n\n} )();\n\nexport const areIntersecting = ( function () {\n\n\tconst cacheSatBounds = /* @__PURE__ */ new SeparatingAxisBounds();\n\treturn function areIntersecting( shape1, shape2 ) {\n\n\t\tconst points1 = shape1.points;\n\t\tconst satAxes1 = shape1.satAxes;\n\t\tconst satBounds1 = shape1.satBounds;\n\n\t\tconst points2 = shape2.points;\n\t\tconst satAxes2 = shape2.satAxes;\n\t\tconst satBounds2 = shape2.satBounds;\n\n\t\t// check axes of the first shape\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tconst sb = satBounds1[ i ];\n\t\t\tconst sa = satAxes1[ i ];\n\t\t\tcacheSatBounds.setFromPoints( sa, points2 );\n\t\t\tif ( sb.isSeparated( cacheSatBounds ) ) return false;\n\n\t\t}\n\n\t\t// check axes of the second shape\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tconst sb = satBounds2[ i ];\n\t\t\tconst sa = satAxes2[ i ];\n\t\t\tcacheSatBounds.setFromPoints( sa, points1 );\n\t\t\tif ( sb.isSeparated( cacheSatBounds ) ) return false;\n\n\t\t}\n\n\t};\n\n} )();\n","import { Vector3, Vector2, Plane, Line3 } from 'three';\n\nexport const closestPointLineToLine = ( function () {\n\n\t// https://github.com/juj/MathGeoLib/blob/master/src/Geometry/Line.cpp#L56\n\tconst dir1 = /* @__PURE__ */ new Vector3();\n\tconst dir2 = /* @__PURE__ */ new Vector3();\n\tconst v02 = /* @__PURE__ */ new Vector3();\n\treturn function closestPointLineToLine( l1, l2, result ) {\n\n\t\tconst v0 = l1.start;\n\t\tconst v10 = dir1;\n\t\tconst v2 = l2.start;\n\t\tconst v32 = dir2;\n\n\t\tv02.subVectors( v0, v2 );\n\t\tdir1.subVectors( l1.end, l1.start );\n\t\tdir2.subVectors( l2.end, l2.start );\n\n\t\t// float d0232 = v02.Dot(v32);\n\t\tconst d0232 = v02.dot( v32 );\n\n\t\t// float d3210 = v32.Dot(v10);\n\t\tconst d3210 = v32.dot( v10 );\n\n\t\t// float d3232 = v32.Dot(v32);\n\t\tconst d3232 = v32.dot( v32 );\n\n\t\t// float d0210 = v02.Dot(v10);\n\t\tconst d0210 = v02.dot( v10 );\n\n\t\t// float d1010 = v10.Dot(v10);\n\t\tconst d1010 = v10.dot( v10 );\n\n\t\t// float denom = d1010*d3232 - d3210*d3210;\n\t\tconst denom = d1010 * d3232 - d3210 * d3210;\n\n\t\tlet d, d2;\n\t\tif ( denom !== 0 ) {\n\n\t\t\td = ( d0232 * d3210 - d0210 * d3232 ) / denom;\n\n\t\t} else {\n\n\t\t\td = 0;\n\n\t\t}\n\n\t\td2 = ( d0232 + d * d3210 ) / d3232;\n\n\t\tresult.x = d;\n\t\tresult.y = d2;\n\n\t};\n\n} )();\n\nexport const closestPointsSegmentToSegment = ( function () {\n\n\t// https://github.com/juj/MathGeoLib/blob/master/src/Geometry/LineSegment.cpp#L187\n\tconst paramResult = /* @__PURE__ */ new Vector2();\n\tconst temp1 = /* @__PURE__ */ new Vector3();\n\tconst temp2 = /* @__PURE__ */ new Vector3();\n\treturn function closestPointsSegmentToSegment( l1, l2, target1, target2 ) {\n\n\t\tclosestPointLineToLine( l1, l2, paramResult );\n\n\t\tlet d = paramResult.x;\n\t\tlet d2 = paramResult.y;\n\t\tif ( d >= 0 && d <= 1 && d2 >= 0 && d2 <= 1 ) {\n\n\t\t\tl1.at( d, target1 );\n\t\t\tl2.at( d2, target2 );\n\n\t\t\treturn;\n\n\t\t} else if ( d >= 0 && d <= 1 ) {\n\n\t\t\t// Only d2 is out of bounds.\n\t\t\tif ( d2 < 0 ) {\n\n\t\t\t\tl2.at( 0, target2 );\n\n\t\t\t} else {\n\n\t\t\t\tl2.at( 1, target2 );\n\n\t\t\t}\n\n\t\t\tl1.closestPointToPoint( target2, true, target1 );\n\t\t\treturn;\n\n\t\t} else if ( d2 >= 0 && d2 <= 1 ) {\n\n\t\t\t// Only d is out of bounds.\n\t\t\tif ( d < 0 ) {\n\n\t\t\t\tl1.at( 0, target1 );\n\n\t\t\t} else {\n\n\t\t\t\tl1.at( 1, target1 );\n\n\t\t\t}\n\n\t\t\tl2.closestPointToPoint( target1, true, target2 );\n\t\t\treturn;\n\n\t\t} else {\n\n\t\t\t// Both u and u2 are out of bounds.\n\t\t\tlet p;\n\t\t\tif ( d < 0 ) {\n\n\t\t\t\tp = l1.start;\n\n\t\t\t} else {\n\n\t\t\t\tp = l1.end;\n\n\t\t\t}\n\n\t\t\tlet p2;\n\t\t\tif ( d2 < 0 ) {\n\n\t\t\t\tp2 = l2.start;\n\n\t\t\t} else {\n\n\t\t\t\tp2 = l2.end;\n\n\t\t\t}\n\n\t\t\tconst closestPoint = temp1;\n\t\t\tconst closestPoint2 = temp2;\n\t\t\tl1.closestPointToPoint( p2, true, temp1 );\n\t\t\tl2.closestPointToPoint( p, true, temp2 );\n\n\t\t\tif ( closestPoint.distanceToSquared( p2 ) <= closestPoint2.distanceToSquared( p ) ) {\n\n\t\t\t\ttarget1.copy( closestPoint );\n\t\t\t\ttarget2.copy( p2 );\n\t\t\t\treturn;\n\n\t\t\t} else {\n\n\t\t\t\ttarget1.copy( p );\n\t\t\t\ttarget2.copy( closestPoint2 );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n} )();\n\n\nexport const sphereIntersectTriangle = ( function () {\n\n\t// https://stackoverflow.com/questions/34043955/detect-collision-between-sphere-and-triangle-in-three-js\n\tconst closestPointTemp = /* @__PURE__ */ new Vector3();\n\tconst projectedPointTemp = /* @__PURE__ */ new Vector3();\n\tconst planeTemp = /* @__PURE__ */ new Plane();\n\tconst lineTemp = /* @__PURE__ */ new Line3();\n\treturn function sphereIntersectTriangle( sphere, triangle ) {\n\n\t\tconst { radius, center } = sphere;\n\t\tconst { a, b, c } = triangle;\n\n\t\t// phase 1\n\t\tlineTemp.start = a;\n\t\tlineTemp.end = b;\n\t\tconst closestPoint1 = lineTemp.closestPointToPoint( center, true, closestPointTemp );\n\t\tif ( closestPoint1.distanceTo( center ) <= radius ) return true;\n\n\t\tlineTemp.start = a;\n\t\tlineTemp.end = c;\n\t\tconst closestPoint2 = lineTemp.closestPointToPoint( center, true, closestPointTemp );\n\t\tif ( closestPoint2.distanceTo( center ) <= radius ) return true;\n\n\t\tlineTemp.start = b;\n\t\tlineTemp.end = c;\n\t\tconst closestPoint3 = lineTemp.closestPointToPoint( center, true, closestPointTemp );\n\t\tif ( closestPoint3.distanceTo( center ) <= radius ) return true;\n\n\t\t// phase 2\n\t\tconst plane = triangle.getPlane( planeTemp );\n\t\tconst dp = Math.abs( plane.distanceToPoint( center ) );\n\t\tif ( dp <= radius ) {\n\n\t\t\tconst pp = plane.projectPoint( center, projectedPointTemp );\n\t\t\tconst cp = triangle.containsPoint( pp );\n\t\t\tif ( cp ) return true;\n\n\t\t}\n\n\t\treturn false;\n\n\t};\n\n} )();\n","/** @import { Sphere } from 'three' */\nimport { Triangle, Vector3, Vector2, Line3, Plane } from 'three';\nimport { SeparatingAxisBounds } from './SeparatingAxisBounds.js';\nimport { closestPointsSegmentToSegment, sphereIntersectTriangle } from './MathUtilities.js';\n\nconst componentKeys = [ 'x', 'y', 'z' ];\nconst ZERO_EPSILON = 1e-15;\nconst ZERO_EPSILON_SQR = ZERO_EPSILON * ZERO_EPSILON;\nfunction isNearZero( value ) {\n\n\treturn Math.abs( value ) < ZERO_EPSILON;\n\n}\n\n/**\n * An extended version of three.js' Triangle class. A variety of derivative values are cached on\n * the object to accelerate the intersection functions. `.needsUpdate` must be set to true when\n * modifying the triangle parameters.\n * @extends Triangle\n */\nexport class ExtendedTriangle extends Triangle {\n\n\tconstructor( ...args ) {\n\n\t\tsuper( ...args );\n\n\t\tthis.isExtendedTriangle = true;\n\t\tthis.satAxes = new Array( 4 ).fill().map( () => new Vector3() );\n\t\tthis.satBounds = new Array( 4 ).fill().map( () => new SeparatingAxisBounds() );\n\t\tthis.points = [ this.a, this.b, this.c ];\n\t\tthis.plane = new Plane();\n\t\tthis.isDegenerateIntoSegment = false;\n\t\tthis.isDegenerateIntoPoint = false;\n\t\tthis.degenerateSegment = new Line3();\n\n\t\t/**\n\t\t * Indicates that the triangle fields have changed so cached variables to accelerate other\n\t\t * function execution can be updated. Must be set to true after modifying the triangle\n\t\t * `a`, `b`, `c` fields.\n\t\t * @type {boolean}\n\t\t */\n\t\tthis.needsUpdate = true;\n\n\t}\n\n\t/**\n\t * Returns whether the triangle intersects the given sphere.\n\t * @param {Sphere} sphere\n\t * @returns {boolean}\n\t */\n\tintersectsSphere( sphere ) {\n\n\t\treturn sphereIntersectTriangle( sphere, this );\n\n\t}\n\n\tupdate() {\n\n\t\tconst a = this.a;\n\t\tconst b = this.b;\n\t\tconst c = this.c;\n\t\tconst points = this.points;\n\n\t\tconst satAxes = this.satAxes;\n\t\tconst satBounds = this.satBounds;\n\n\t\tconst axis0 = satAxes[ 0 ];\n\t\tconst sab0 = satBounds[ 0 ];\n\t\tthis.getNormal( axis0 );\n\t\tsab0.setFromPoints( axis0, points );\n\n\t\tconst axis1 = satAxes[ 1 ];\n\t\tconst sab1 = satBounds[ 1 ];\n\t\taxis1.subVectors( a, b );\n\t\tsab1.setFromPoints( axis1, points );\n\n\t\tconst axis2 = satAxes[ 2 ];\n\t\tconst sab2 = satBounds[ 2 ];\n\t\taxis2.subVectors( b, c );\n\t\tsab2.setFromPoints( axis2, points );\n\n\t\tconst axis3 = satAxes[ 3 ];\n\t\tconst sab3 = satBounds[ 3 ];\n\t\taxis3.subVectors( c, a );\n\t\tsab3.setFromPoints( axis3, points );\n\n\t\tconst lengthAB = axis1.length();\n\t\tconst lengthBC = axis2.length();\n\t\tconst lengthCA = axis3.length();\n\n\t\tthis.isDegenerateIntoPoint = false;\n\t\tthis.isDegenerateIntoSegment = false;\n\n\t\tif ( lengthAB < ZERO_EPSILON ) {\n\n\t\t\tif ( lengthBC < ZERO_EPSILON || lengthCA < ZERO_EPSILON ) {\n\n\t\t\t\tthis.isDegenerateIntoPoint = true;\n\n\t\t\t} else {\n\n\t\t\t\tthis.isDegenerateIntoSegment = true;\n\t\t\t\tthis.degenerateSegment.start.copy( a );\n\t\t\t\tthis.degenerateSegment.end.copy( c );\n\n\t\t\t}\n\n\t\t} else if ( lengthBC < ZERO_EPSILON ) {\n\n\t\t\tif ( lengthCA < ZERO_EPSILON ) {\n\n\t\t\t\tthis.isDegenerateIntoPoint = true;\n\n\t\t\t} else {\n\n\t\t\t\tthis.isDegenerateIntoSegment = true;\n\t\t\t\tthis.degenerateSegment.start.copy( b );\n\t\t\t\tthis.degenerateSegment.end.copy( a );\n\n\t\t\t}\n\n\t\t} else if ( lengthCA < ZERO_EPSILON ) {\n\n\t\t\tthis.isDegenerateIntoSegment = true;\n\t\t\tthis.degenerateSegment.start.copy( c );\n\t\t\tthis.degenerateSegment.end.copy( b );\n\n\t\t}\n\n\t\tthis.plane.setFromNormalAndCoplanarPoint( axis0, a );\n\n\t\tthis.needsUpdate = false;\n\n\t}\n\n}\n\n/**\n * Returns the distance to the provided line segment. `target1` and `target2` are set to the\n * closest points on the triangle and segment respectively.\n * @function\n * @param {Line3} segment\n * @param {Vector3} [target1]\n * @param {Vector3} [target2]\n * @returns {number}\n */\nExtendedTriangle.prototype.closestPointToSegment = ( function () {\n\n\tconst point1 = /* @__PURE__ */ new Vector3();\n\tconst point2 = /* @__PURE__ */ new Vector3();\n\tconst edge = /* @__PURE__ */ new Line3();\n\n\treturn function distanceToSegment( segment, target1 = null, target2 = null ) {\n\n\t\tconst { start, end } = segment;\n\t\tconst points = this.points;\n\t\tlet distSq;\n\t\tlet closestDistanceSq = Infinity;\n\n\t\t// check the triangle edges\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tconst nexti = ( i + 1 ) % 3;\n\t\t\tedge.start.copy( points[ i ] );\n\t\t\tedge.end.copy( points[ nexti ] );\n\n\t\t\tclosestPointsSegmentToSegment( edge, segment, point1, point2 );\n\n\t\t\tdistSq = point1.distanceToSquared( point2 );\n\t\t\tif ( distSq < closestDistanceSq ) {\n\n\t\t\t\tclosestDistanceSq = distSq;\n\t\t\t\tif ( target1 ) target1.copy( point1 );\n\t\t\t\tif ( target2 ) target2.copy( point2 );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// check end points\n\t\tthis.closestPointToPoint( start, point1 );\n\t\tdistSq = start.distanceToSquared( point1 );\n\t\tif ( distSq < closestDistanceSq ) {\n\n\t\t\tclosestDistanceSq = distSq;\n\t\t\tif ( target1 ) target1.copy( point1 );\n\t\t\tif ( target2 ) target2.copy( start );\n\n\t\t}\n\n\t\tthis.closestPointToPoint( end, point1 );\n\t\tdistSq = end.distanceToSquared( point1 );\n\t\tif ( distSq < closestDistanceSq ) {\n\n\t\t\tclosestDistanceSq = distSq;\n\t\t\tif ( target1 ) target1.copy( point1 );\n\t\t\tif ( target2 ) target2.copy( end );\n\n\t\t}\n\n\t\treturn Math.sqrt( closestDistanceSq );\n\n\t};\n\n} )();\n\n/**\n * Returns whether the triangles intersect. `target` is set to the line segment representing\n * the intersection.\n * @function\n * @param {Triangle} other\n * @param {Line3} [target]\n * @param {boolean} [suppressLog=false]\n * @returns {boolean}\n */\nExtendedTriangle.prototype.intersectsTriangle = ( function () {\n\n\tconst saTri2 = /* @__PURE__ */ new ExtendedTriangle();\n\tconst cachedSatBounds = /* @__PURE__ */ new SeparatingAxisBounds();\n\tconst cachedSatBounds2 = /* @__PURE__ */ new SeparatingAxisBounds();\n\tconst tmpVec = /* @__PURE__ */ new Vector3();\n\tconst dir1 = /* @__PURE__ */ new Vector3();\n\tconst dir2 = /* @__PURE__ */ new Vector3();\n\tconst tempDir = /* @__PURE__ */ new Vector3();\n\tconst edge1 = /* @__PURE__ */ new Line3();\n\tconst edge2 = /* @__PURE__ */ new Line3();\n\tconst tempPoint = /* @__PURE__ */ new Vector3();\n\tconst bounds1 = /* @__PURE__ */ new Vector2();\n\tconst bounds2 = /* @__PURE__ */ new Vector2();\n\n\tfunction coplanarIntersectsTriangle( self, other, target, suppressLog ) {\n\n\t\t// Perform separating axis intersection test only for coplanar triangles\n\t\t// There should be at least one non-degenerate triangle when calling this\n\t\t// Otherwise we won't know the plane normal\n\t\tconst planeNormal = tmpVec;\n\t\tif ( ! self.isDegenerateIntoPoint && ! self.isDegenerateIntoSegment ) {\n\n\t\t\tplaneNormal.copy( self.plane.normal );\n\n\t\t} else {\n\n\t\t\tplaneNormal.copy( other.plane.normal );\n\n\t\t}\n\n\t\tconst satBounds1 = self.satBounds;\n\t\tconst satAxes1 = self.satAxes;\n\t\tfor ( let i = 1; i < 4; i ++ ) {\n\n\t\t\tconst sb = satBounds1[ i ];\n\t\t\tconst sa = satAxes1[ i ];\n\t\t\tcachedSatBounds.setFromPoints( sa, other.points );\n\t\t\tif ( sb.isSeparated( cachedSatBounds ) ) return false;\n\n\t\t\ttempDir.copy( planeNormal ).cross( sa );\n\t\t\tcachedSatBounds.setFromPoints( tempDir, self.points );\n\t\t\tcachedSatBounds2.setFromPoints( tempDir, other.points );\n\t\t\tif ( cachedSatBounds.isSeparated( cachedSatBounds2 ) ) return false;\n\n\t\t}\n\n\t\tconst satBounds2 = other.satBounds;\n\t\tconst satAxes2 = other.satAxes;\n\t\tfor ( let i = 1; i < 4; i ++ ) {\n\n\t\t\tconst sb = satBounds2[ i ];\n\t\t\tconst sa = satAxes2[ i ];\n\t\t\tcachedSatBounds.setFromPoints( sa, self.points );\n\t\t\tif ( sb.isSeparated( cachedSatBounds ) ) return false;\n\n\t\t\ttempDir.crossVectors( planeNormal, sa );\n\t\t\tcachedSatBounds.setFromPoints( tempDir, self.points );\n\t\t\tcachedSatBounds2.setFromPoints( tempDir, other.points );\n\t\t\tif ( cachedSatBounds.isSeparated( cachedSatBounds2 ) ) return false;\n\n\t\t}\n\n\t\tif ( target ) {\n\n\t\t\t// TODO find two points that intersect on the edges and make that the result\n\t\t\tif ( ! suppressLog ) {\n\n\t\t\t\tconsole.warn( 'ExtendedTriangle.intersectsTriangle: Triangles are coplanar which does not support an output edge. Setting edge to 0, 0, 0.' );\n\n\t\t\t}\n\n\t\t\ttarget.start.set( 0, 0, 0 );\n\t\t\ttarget.end.set( 0, 0, 0 );\n\n\t\t}\n\n\t\treturn true;\n\n\t}\n\n\tfunction findSingleBounds( a, b, c, aProj, bProj, cProj, aDist, bDist, cDist, bounds, edge ) {\n\n\t\tlet t = aDist / ( aDist - bDist );\n\t\tbounds.x = aProj + ( bProj - aProj ) * t;\n\t\tedge.start.subVectors( b, a ).multiplyScalar( t ).add( a );\n\n\t\tt = aDist / ( aDist - cDist );\n\t\tbounds.y = aProj + ( cProj - aProj ) * t;\n\t\tedge.end.subVectors( c, a ).multiplyScalar( t ).add( a );\n\n\t}\n\n\t/**\n\t * Calculates intersection segment of a triangle with intersection line.\n\t * Intersection line is snapped to its biggest component.\n\t * And triangle points are passed as a projection on that component.\n\t * @returns {boolean} whether this is a coplanar case or not\n\t */\n\tfunction findIntersectionLineBounds( self, aProj, bProj, cProj, abDist, acDist, aDist, bDist, cDist, bounds, edge ) {\n\n\t\tif ( abDist > 0 ) {\n\n\t\t\t// then bcDist < 0\n\t\t\tfindSingleBounds( self.c, self.a, self.b, cProj, aProj, bProj, cDist, aDist, bDist, bounds, edge );\n\n\t\t} else if ( acDist > 0 ) {\n\n\t\t\tfindSingleBounds( self.b, self.a, self.c, bProj, aProj, cProj, bDist, aDist, cDist, bounds, edge );\n\n\t\t} else if ( bDist * cDist > 0 || aDist != 0 ) {\n\n\t\t\tfindSingleBounds( self.a, self.b, self.c, aProj, bProj, cProj, aDist, bDist, cDist, bounds, edge );\n\n\t\t} else if ( bDist != 0 ) {\n\n\t\t\tfindSingleBounds( self.b, self.a, self.c, bProj, aProj, cProj, bDist, aDist, cDist, bounds, edge );\n\n\t\t} else if ( cDist != 0 ) {\n\n\t\t\tfindSingleBounds( self.c, self.a, self.b, cProj, aProj, bProj, cDist, aDist, bDist, bounds, edge );\n\n\t\t} else {\n\n\t\t\treturn true;\n\n\t\t}\n\n\t\treturn false;\n\n\t}\n\n\tfunction intersectTriangleSegment( triangle, degenerateTriangle, target, suppressLog ) {\n\n\t\tconst segment = degenerateTriangle.degenerateSegment;\n\t\tconst startDist = triangle.plane.distanceToPoint( segment.start );\n\t\tconst endDist = triangle.plane.distanceToPoint( segment.end );\n\t\tif ( isNearZero( startDist ) ) {\n\n\t\t\tif ( isNearZero( endDist ) ) {\n\n\t\t\t\treturn coplanarIntersectsTriangle( triangle, degenerateTriangle, target, suppressLog );\n\n\t\t\t} else {\n\n\t\t\t\t// Is this fine to modify target even if there might be no intersection?\n\t\t\t\tif ( target ) {\n\n\t\t\t\t\ttarget.start.copy( segment.start );\n\t\t\t\t\ttarget.end.copy( segment.start );\n\n\t\t\t\t}\n\n\t\t\t\treturn triangle.containsPoint( segment.start );\n\n\t\t\t}\n\n\t\t} else if ( isNearZero( endDist ) ) {\n\n\t\t\tif ( target ) {\n\n\t\t\t\ttarget.start.copy( segment.end );\n\t\t\t\ttarget.end.copy( segment.end );\n\n\t\t\t}\n\n\t\t\treturn triangle.containsPoint( segment.end );\n\n\t\t} else {\n\n\t\t\tif ( triangle.plane.intersectLine( segment, tmpVec ) != null ) {\n\n\t\t\t\tif ( target ) {\n\n\t\t\t\t\ttarget.start.copy( tmpVec );\n\t\t\t\t\ttarget.end.copy( tmpVec );\n\n\t\t\t\t}\n\n\t\t\t\treturn triangle.containsPoint( tmpVec );\n\n\t\t\t} else {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tfunction intersectTrianglePoint( triangle, degenerateTriangle, target ) {\n\n\t\tconst point = degenerateTriangle.a;\n\n\t\tif ( isNearZero( triangle.plane.distanceToPoint( point ) ) && triangle.containsPoint( point ) ) {\n\n\t\t\tif ( target ) {\n\n\t\t\t\ttarget.start.copy( point );\n\t\t\t\ttarget.end.copy( point );\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t} else {\n\n\t\t\treturn false;\n\n\t\t}\n\n\t}\n\n\tfunction intersectSegmentPoint( segmentTri, pointTri, target ) {\n\n\t\tconst segment = segmentTri.degenerateSegment;\n\t\tconst point = pointTri.a;\n\n\t\tsegment.closestPointToPoint( point, true, tmpVec );\n\n\t\tif ( point.distanceToSquared( tmpVec ) < ZERO_EPSILON_SQR ) {\n\n\t\t\tif ( target ) {\n\n\t\t\t\ttarget.start.copy( point );\n\t\t\t\ttarget.end.copy( point );\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t} else {\n\n\t\t\treturn false;\n\n\t\t}\n\n\t}\n\n\tfunction handleDegenerateCases( self, other, target, suppressLog ) {\n\n\t\tif ( self.isDegenerateIntoSegment ) {\n\n\t\t\tif ( other.isDegenerateIntoSegment ) {\n\n\t\t\t\t// TODO: replace with Line.distanceSqToLine3 after r179\n\t\t\t\tconst segment1 = self.degenerateSegment;\n\t\t\t\tconst segment2 = other.degenerateSegment;\n\t\t\t\tconst delta1 = dir1;\n\t\t\t\tconst delta2 = dir2;\n\t\t\t\tsegment1.delta( delta1 );\n\t\t\t\tsegment2.delta( delta2 );\n\t\t\t\tconst startDelta = tmpVec.subVectors( segment2.start, segment1.start );\n\n\t\t\t\tconst denom = delta1.x * delta2.y - delta1.y * delta2.x;\n\t\t\t\tif ( isNearZero( denom ) ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t\tconst t = ( startDelta.x * delta2.y - startDelta.y * delta2.x ) / denom;\n\t\t\t\tconst u = - ( delta1.x * startDelta.y - delta1.y * startDelta.x ) / denom;\n\n\t\t\t\tif ( t < 0 || t > 1 || u < 0 || u > 1 ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t\tconst z1 = segment1.start.z + delta1.z * t;\n\t\t\t\tconst z2 = segment2.start.z + delta2.z * u;\n\n\t\t\t\tif ( isNearZero( z1 - z2 ) ) {\n\n\t\t\t\t\tif ( target ) {\n\n\t\t\t\t\t\ttarget.start.copy( segment1.start ).addScaledVector( delta1, t );\n\t\t\t\t\t\ttarget.end.copy( segment1.start ).addScaledVector( delta1, t );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t} else if ( other.isDegenerateIntoPoint ) {\n\n\t\t\t\treturn intersectSegmentPoint( self, other, target );\n\n\t\t\t} else {\n\n\t\t\t\treturn intersectTriangleSegment( other, self, target, suppressLog );\n\n\t\t\t}\n\n\t\t} else if ( self.isDegenerateIntoPoint ) {\n\n\t\t\tif ( other.isDegenerateIntoPoint ) {\n\n\t\t\t\tif ( other.a.distanceToSquared( self.a ) < ZERO_EPSILON_SQR ) {\n\n\t\t\t\t\tif ( target ) {\n\n\t\t\t\t\t\ttarget.start.copy( self.a );\n\t\t\t\t\t\ttarget.end.copy( self.a );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t} else if ( other.isDegenerateIntoSegment ) {\n\n\t\t\t\treturn intersectSegmentPoint( other, self, target );\n\n\t\t\t} else {\n\n\t\t\t\treturn intersectTrianglePoint( other, self, target );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tif ( other.isDegenerateIntoPoint ) {\n\n\t\t\t\treturn intersectTrianglePoint( self, other, target );\n\n\t\t\t} else if ( other.isDegenerateIntoSegment ) {\n\n\t\t\t\treturn intersectTriangleSegment( self, other, target, suppressLog );\n\n\t\t\t} /* else this is a general triangle-traingle case, so return undefined */\n\n\t\t}\n\n\t}\n\n\t/* TODO: If the triangles are coplanar and intersecting the target is nonsensical. It should at least\n\t * be a line contained by both triangles if not a different special case somehow represented in the return result.\n\t *\n\t * General triangle intersection code is based on Moller's algorithm from here: https://web.stanford.edu/class/cs277/resources/papers/Moller1997b.pdf\n\t * Reference implementation from here: https://github.com/erich666/jgt-code/blob/master/Volume_08/Number_1/Shen2003/tri_tri_test/include/Moller97.c#L570\n\t * All degeneracies are handled before the general algorithm.\n\t * Coplanar check is different from Moller's and based on SAT tests.\n\t */\n\treturn function intersectsTriangle( other, target = null, suppressLog = false ) {\n\n\t\tif ( this.needsUpdate ) {\n\n\t\t\tthis.update();\n\n\t\t}\n\n\t\tif ( ! other.isExtendedTriangle ) {\n\n\t\t\tsaTri2.copy( other );\n\t\t\tsaTri2.update();\n\t\t\tother = saTri2;\n\n\t\t} else if ( other.needsUpdate ) {\n\n\t\t\tother.update();\n\n\t\t}\n\n\t\tconst res = handleDegenerateCases( this, other, target, suppressLog );\n\t\tif ( res !== undefined ) {\n\n\t\t\treturn res;\n\n\t\t}\n\n\t\tconst plane1 = this.plane;\n\t\tconst plane2 = other.plane;\n\n\t\tlet a1Dist = plane2.distanceToPoint( this.a );\n\t\tlet b1Dist = plane2.distanceToPoint( this.b );\n\t\tlet c1Dist = plane2.distanceToPoint( this.c );\n\n\t\tif ( isNearZero( a1Dist ) )\n\t\t\ta1Dist = 0;\n\n\t\tif ( isNearZero( b1Dist ) )\n\t\t\tb1Dist = 0;\n\n\t\tif ( isNearZero( c1Dist ) )\n\t\t\tc1Dist = 0;\n\n\t\tconst a1b1Dist = a1Dist * b1Dist;\n\t\tconst a1c1Dist = a1Dist * c1Dist;\n\t\tif ( a1b1Dist > 0 && a1c1Dist > 0 ) {\n\n\t\t\treturn false;\n\n\t\t}\n\n\t\tlet a2Dist = plane1.distanceToPoint( other.a );\n\t\tlet b2Dist = plane1.distanceToPoint( other.b );\n\t\tlet c2Dist = plane1.distanceToPoint( other.c );\n\n\t\tif ( isNearZero( a2Dist ) )\n\t\t\ta2Dist = 0;\n\n\t\tif ( isNearZero( b2Dist ) )\n\t\t\tb2Dist = 0;\n\n\t\tif ( isNearZero( c2Dist ) )\n\t\t\tc2Dist = 0;\n\n\t\tconst a2b2Dist = a2Dist * b2Dist;\n\t\tconst a2c2Dist = a2Dist * c2Dist;\n\t\tif ( a2b2Dist > 0 && a2c2Dist > 0 ) {\n\n\t\t\treturn false;\n\n\t\t}\n\n\t\tdir1.copy( plane1.normal );\n\t\tdir2.copy( plane2.normal );\n\t\tconst intersectionLine = dir1.cross( dir2 );\n\n\t\tlet componentIndex = 0;\n\t\tlet maxComponent = Math.abs( intersectionLine.x );\n\t\tconst comp1 = Math.abs( intersectionLine.y );\n\t\tif ( comp1 > maxComponent ) {\n\n\t\t\tmaxComponent = comp1;\n\t\t\tcomponentIndex = 1;\n\n\t\t}\n\n\t\tconst comp2 = Math.abs( intersectionLine.z );\n\t\tif ( comp2 > maxComponent ) {\n\n\t\t\tcomponentIndex = 2;\n\n\t\t}\n\n\t\tconst key = componentKeys[ componentIndex ];\n\t\tconst a1Proj = this.a[ key ];\n\t\tconst b1Proj = this.b[ key ];\n\t\tconst c1Proj = this.c[ key ];\n\n\t\tconst a2Proj = other.a[ key ];\n\t\tconst b2Proj = other.b[ key ];\n\t\tconst c2Proj = other.c[ key ];\n\n\t\tif ( findIntersectionLineBounds( this, a1Proj, b1Proj, c1Proj, a1b1Dist, a1c1Dist, a1Dist, b1Dist, c1Dist, bounds1, edge1 ) ) {\n\n\t\t\treturn coplanarIntersectsTriangle( this, other, target, suppressLog );\n\n\t\t}\n\n\t\tif ( findIntersectionLineBounds( other, a2Proj, b2Proj, c2Proj, a2b2Dist, a2c2Dist, a2Dist, b2Dist, c2Dist, bounds2, edge2 ) ) {\n\n\t\t\treturn coplanarIntersectsTriangle( this, other, target, suppressLog );\n\n\t\t}\n\n\t\tif ( bounds1.y < bounds1.x ) {\n\n\t\t\tconst tmp = bounds1.y;\n\t\t\tbounds1.y = bounds1.x;\n\t\t\tbounds1.x = tmp;\n\n\t\t\ttempPoint.copy( edge1.start );\n\t\t\tedge1.start.copy( edge1.end );\n\t\t\tedge1.end.copy( tempPoint );\n\n\t\t}\n\n\t\tif ( bounds2.y < bounds2.x ) {\n\n\t\t\tconst tmp = bounds2.y;\n\t\t\tbounds2.y = bounds2.x;\n\t\t\tbounds2.x = tmp;\n\n\t\t\ttempPoint.copy( edge2.start );\n\t\t\tedge2.start.copy( edge2.end );\n\t\t\tedge2.end.copy( tempPoint );\n\n\t\t}\n\n\t\tif ( bounds1.y < bounds2.x || bounds2.y < bounds1.x ) {\n\n\t\t\treturn false;\n\n\t\t}\n\n\t\tif ( target ) {\n\n\t\t\tif ( bounds2.x > bounds1.x ) {\n\n\t\t\t\ttarget.start.copy( edge2.start );\n\n\t\t\t} else {\n\n\t\t\t\ttarget.start.copy( edge1.start );\n\n\t\t\t}\n\n\t\t\tif ( bounds2.y < bounds1.y ) {\n\n\t\t\t\ttarget.end.copy( edge2.end );\n\n\t\t\t} else {\n\n\t\t\t\ttarget.end.copy( edge1.end );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn true;\n\n\t};\n\n} )();\n\n\n/**\n * Returns the distance to the provided point.\n * @function\n * @param {Vector3} point\n * @returns {number}\n */\nExtendedTriangle.prototype.distanceToPoint = ( function () {\n\n\tconst target = /* @__PURE__ */ new Vector3();\n\treturn function distanceToPoint( point ) {\n\n\t\tthis.closestPointToPoint( point, target );\n\t\treturn point.distanceTo( target );\n\n\t};\n\n} )();\n\n\n/**\n * Returns the distance to the provided triangle.\n * @function\n * @param {Triangle} other\n * @param {Vector3} [target1]\n * @param {Vector3} [target2]\n * @returns {number}\n */\nExtendedTriangle.prototype.distanceToTriangle = ( function () {\n\n\tconst point = /* @__PURE__ */ new Vector3();\n\tconst point2 = /* @__PURE__ */ new Vector3();\n\tconst cornerFields = [ 'a', 'b', 'c' ];\n\tconst line1 = /* @__PURE__ */ new Line3();\n\tconst line2 = /* @__PURE__ */ new Line3();\n\n\treturn function distanceToTriangle( other, target1 = null, target2 = null ) {\n\n\t\tconst lineTarget = target1 || target2 ? line1 : null;\n\t\t// `intersectsTriangle` returns a zero-length segment for coplanar\n\t\t// intersecting triangles, which is fine for our purposes here. We\n\t\t// don't need the segment itself in this function. So we can suppress\n\t\t// the warning about coplanar triangles.\n\t\tif ( this.intersectsTriangle( other, lineTarget, true ) ) {\n\n\t\t\tif ( target1 || target2 ) {\n\n\t\t\t\tif ( target1 ) lineTarget.getCenter( target1 );\n\t\t\t\tif ( target2 ) lineTarget.getCenter( target2 );\n\n\t\t\t}\n\n\t\t\treturn 0;\n\n\t\t}\n\n\t\tlet closestDistanceSq = Infinity;\n\n\t\t// check all point distances\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tlet dist;\n\t\t\tconst field = cornerFields[ i ];\n\t\t\tconst otherVec = other[ field ];\n\t\t\tthis.closestPointToPoint( otherVec, point );\n\n\t\t\tdist = otherVec.distanceToSquared( point );\n\n\t\t\tif ( dist < closestDistanceSq ) {\n\n\t\t\t\tclosestDistanceSq = dist;\n\t\t\t\tif ( target1 ) target1.copy( point );\n\t\t\t\tif ( target2 ) target2.copy( otherVec );\n\n\t\t\t}\n\n\n\t\t\tconst thisVec = this[ field ];\n\t\t\tother.closestPointToPoint( thisVec, point );\n\n\t\t\tdist = thisVec.distanceToSquared( point );\n\n\t\t\tif ( dist < closestDistanceSq ) {\n\n\t\t\t\tclosestDistanceSq = dist;\n\t\t\t\tif ( target1 ) target1.copy( thisVec );\n\t\t\t\tif ( target2 ) target2.copy( point );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tconst f11 = cornerFields[ i ];\n\t\t\tconst f12 = cornerFields[ ( i + 1 ) % 3 ];\n\t\t\tline1.set( this[ f11 ], this[ f12 ] );\n\t\t\tfor ( let i2 = 0; i2 < 3; i2 ++ ) {\n\n\t\t\t\tconst f21 = cornerFields[ i2 ];\n\t\t\t\tconst f22 = cornerFields[ ( i2 + 1 ) % 3 ];\n\t\t\t\tline2.set( other[ f21 ], other[ f22 ] );\n\n\t\t\t\tclosestPointsSegmentToSegment( line1, line2, point, point2 );\n\n\t\t\t\tconst dist = point.distanceToSquared( point2 );\n\t\t\t\tif ( dist < closestDistanceSq ) {\n\n\t\t\t\t\tclosestDistanceSq = dist;\n\t\t\t\t\tif ( target1 ) target1.copy( point );\n\t\t\t\t\tif ( target2 ) target2.copy( point2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn Math.sqrt( closestDistanceSq );\n\n\t};\n\n} )();\n","/** @import { Box3, Triangle } from 'three' */\nimport { Vector3, Matrix4, Line3 } from 'three';\nimport { SeparatingAxisBounds } from './SeparatingAxisBounds.js';\nimport { ExtendedTriangle } from './ExtendedTriangle.js';\nimport { closestPointsSegmentToSegment } from './MathUtilities.js';\n\n/**\n * An oriented version of three.js' Box3 class. A variety of derivative values are cached on the\n * object to accelerate the intersection functions. `.needsUpdate` must be set to true when\n * modifying the box parameters.\n *\n * @param {Vector3} [min]\n * @param {Vector3} [max]\n * @param {Matrix4} [matrix]\n */\nexport class OrientedBox {\n\n\tconstructor( min, max, matrix ) {\n\n\t\tthis.isOrientedBox = true;\n\n\t\t/** @type {Vector3} */\n\t\tthis.min = new Vector3();\n\n\t\t/** @type {Vector3} */\n\t\tthis.max = new Vector3();\n\n\t\t/**\n\t\t * Matrix transformation applied to the box.\n\t\t * @type {Matrix4}\n\t\t */\n\t\tthis.matrix = new Matrix4();\n\t\tthis.invMatrix = new Matrix4();\n\t\tthis.points = new Array( 8 ).fill().map( () => new Vector3() );\n\t\tthis.satAxes = new Array( 3 ).fill().map( () => new Vector3() );\n\t\tthis.satBounds = new Array( 3 ).fill().map( () => new SeparatingAxisBounds() );\n\t\tthis.alignedSatBounds = new Array( 3 ).fill().map( () => new SeparatingAxisBounds() );\n\t\t/**\n\t\t * Indicates that the bounding box fields have changed so cached variables to accelerate\n\t\t * other function execution can be updated. Must be set to true after modifying the\n\t\t * oriented box `min`, `max`, `matrix` fields.\n\t\t * @type {boolean}\n\t\t */\n\t\tthis.needsUpdate = false;\n\n\t\tif ( min ) this.min.copy( min );\n\t\tif ( max ) this.max.copy( max );\n\t\tif ( matrix ) this.matrix.copy( matrix );\n\n\t}\n\n\t/**\n\t * Sets the oriented box parameters.\n\t * @param {Vector3} min\n\t * @param {Vector3} max\n\t * @param {Matrix4} matrix\n\t */\n\tset( min, max, matrix ) {\n\n\t\tthis.min.copy( min );\n\t\tthis.max.copy( max );\n\t\tthis.matrix.copy( matrix );\n\t\tthis.needsUpdate = true;\n\n\t}\n\n\tcopy( other ) {\n\n\t\tthis.min.copy( other.min );\n\t\tthis.max.copy( other.max );\n\t\tthis.matrix.copy( other.matrix );\n\t\tthis.needsUpdate = true;\n\n\t}\n\n}\n\nOrientedBox.prototype.update = ( function () {\n\n\treturn function update() {\n\n\t\tconst matrix = this.matrix;\n\t\tconst min = this.min;\n\t\tconst max = this.max;\n\n\t\tconst points = this.points;\n\t\tfor ( let x = 0; x <= 1; x ++ ) {\n\n\t\t\tfor ( let y = 0; y <= 1; y ++ ) {\n\n\t\t\t\tfor ( let z = 0; z <= 1; z ++ ) {\n\n\t\t\t\t\tconst i = ( ( 1 << 0 ) * x ) | ( ( 1 << 1 ) * y ) | ( ( 1 << 2 ) * z );\n\t\t\t\t\tconst v = points[ i ];\n\t\t\t\t\tv.x = x ? max.x : min.x;\n\t\t\t\t\tv.y = y ? max.y : min.y;\n\t\t\t\t\tv.z = z ? max.z : min.z;\n\n\t\t\t\t\tv.applyMatrix4( matrix );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tconst satBounds = this.satBounds;\n\t\tconst satAxes = this.satAxes;\n\t\tconst minVec = points[ 0 ];\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tconst axis = satAxes[ i ];\n\t\t\tconst sb = satBounds[ i ];\n\t\t\tconst index = 1 << i;\n\t\t\tconst pi = points[ index ];\n\n\t\t\taxis.subVectors( minVec, pi );\n\t\t\tsb.setFromPoints( axis, points );\n\n\t\t}\n\n\t\tconst alignedSatBounds = this.alignedSatBounds;\n\t\talignedSatBounds[ 0 ].setFromPointsField( points, 'x' );\n\t\talignedSatBounds[ 1 ].setFromPointsField( points, 'y' );\n\t\talignedSatBounds[ 2 ].setFromPointsField( points, 'z' );\n\n\t\tthis.invMatrix.copy( this.matrix ).invert();\n\t\tthis.needsUpdate = false;\n\n\t};\n\n} )();\n\n/**\n * Returns true if intersecting with the provided box.\n * @function\n * @param {Box3} box\n * @returns {boolean}\n */\nOrientedBox.prototype.intersectsBox = ( function () {\n\n\tconst aabbBounds = /* @__PURE__ */ new SeparatingAxisBounds();\n\treturn function intersectsBox( box ) {\n\n\t\t// TODO: should this be doing SAT against the AABB?\n\t\tif ( this.needsUpdate ) {\n\n\t\t\tthis.update();\n\n\t\t}\n\n\t\tconst min = box.min;\n\t\tconst max = box.max;\n\t\tconst satBounds = this.satBounds;\n\t\tconst satAxes = this.satAxes;\n\t\tconst alignedSatBounds = this.alignedSatBounds;\n\n\t\taabbBounds.min = min.x;\n\t\taabbBounds.max = max.x;\n\t\tif ( alignedSatBounds[ 0 ].isSeparated( aabbBounds ) ) return false;\n\n\t\taabbBounds.min = min.y;\n\t\taabbBounds.max = max.y;\n\t\tif ( alignedSatBounds[ 1 ].isSeparated( aabbBounds ) ) return false;\n\n\t\taabbBounds.min = min.z;\n\t\taabbBounds.max = max.z;\n\t\tif ( alignedSatBounds[ 2 ].isSeparated( aabbBounds ) ) return false;\n\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tconst axis = satAxes[ i ];\n\t\t\tconst sb = satBounds[ i ];\n\t\t\taabbBounds.setFromBox( axis, box );\n\t\t\tif ( sb.isSeparated( aabbBounds ) ) return false;\n\n\t\t}\n\n\t\treturn true;\n\n\t};\n\n} )();\n\n/**\n * Returns true if intersecting with the provided triangle.\n * @function\n * @param {Triangle} triangle\n * @returns {boolean}\n */\nOrientedBox.prototype.intersectsTriangle = ( function () {\n\n\tconst saTri = /* @__PURE__ */ new ExtendedTriangle();\n\tconst pointsArr = /* @__PURE__ */ new Array( 3 );\n\tconst cachedSatBounds = /* @__PURE__ */ new SeparatingAxisBounds();\n\tconst cachedSatBounds2 = /* @__PURE__ */ new SeparatingAxisBounds();\n\tconst cachedAxis = /* @__PURE__ */ new Vector3();\n\treturn function intersectsTriangle( triangle ) {\n\n\t\tif ( this.needsUpdate ) {\n\n\t\t\tthis.update();\n\n\t\t}\n\n\t\tif ( ! triangle.isExtendedTriangle ) {\n\n\t\t\tsaTri.copy( triangle );\n\t\t\tsaTri.update();\n\t\t\ttriangle = saTri;\n\n\t\t} else if ( triangle.needsUpdate ) {\n\n\t\t\ttriangle.update();\n\n\t\t}\n\n\t\tconst satBounds = this.satBounds;\n\t\tconst satAxes = this.satAxes;\n\n\t\tpointsArr[ 0 ] = triangle.a;\n\t\tpointsArr[ 1 ] = triangle.b;\n\t\tpointsArr[ 2 ] = triangle.c;\n\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tconst sb = satBounds[ i ];\n\t\t\tconst sa = satAxes[ i ];\n\t\t\tcachedSatBounds.setFromPoints( sa, pointsArr );\n\t\t\tif ( sb.isSeparated( cachedSatBounds ) ) return false;\n\n\t\t}\n\n\t\tconst triSatBounds = triangle.satBounds;\n\t\tconst triSatAxes = triangle.satAxes;\n\t\tconst points = this.points;\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tconst sb = triSatBounds[ i ];\n\t\t\tconst sa = triSatAxes[ i ];\n\t\t\tcachedSatBounds.setFromPoints( sa, points );\n\t\t\tif ( sb.isSeparated( cachedSatBounds ) ) return false;\n\n\t\t}\n\n\t\t// check crossed axes\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tconst sa1 = satAxes[ i ];\n\t\t\tfor ( let i2 = 0; i2 < 4; i2 ++ ) {\n\n\t\t\t\tconst sa2 = triSatAxes[ i2 ];\n\t\t\t\tcachedAxis.crossVectors( sa1, sa2 );\n\t\t\t\tcachedSatBounds.setFromPoints( cachedAxis, pointsArr );\n\t\t\t\tcachedSatBounds2.setFromPoints( cachedAxis, points );\n\t\t\t\tif ( cachedSatBounds.isSeparated( cachedSatBounds2 ) ) return false;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn true;\n\n\t};\n\n} )();\n\n/**\n * Returns the distance to the provided point. Sets `target` to the closest point on the surface\n * of the box if provided.\n * @function\n * @param {Vector3} point\n * @param {Vector3} target\n * @returns {number}\n */\nOrientedBox.prototype.closestPointToPoint = ( function () {\n\n\treturn function closestPointToPoint( point, target1 ) {\n\n\t\tif ( this.needsUpdate ) {\n\n\t\t\tthis.update();\n\n\t\t}\n\n\t\ttarget1\n\t\t\t.copy( point )\n\t\t\t.applyMatrix4( this.invMatrix )\n\t\t\t.clamp( this.min, this.max )\n\t\t\t.applyMatrix4( this.matrix );\n\n\t\treturn target1;\n\n\t};\n\n} )();\n\n/**\n * Returns the distance to the provided point.\n * @function\n * @param {Vector3} point\n * @returns {number}\n */\nOrientedBox.prototype.distanceToPoint = ( function () {\n\n\tconst target = new Vector3();\n\treturn function distanceToPoint( point ) {\n\n\t\tthis.closestPointToPoint( point, target );\n\t\treturn point.distanceTo( target );\n\n\t};\n\n} )();\n\n/**\n * Returns the distance to the provided box. `threshold` is an optional distance to return early\n * if the distance is found to be within it. `target1` and `target2` are set to the points on the\n * surface of this box and the `box` argument respectively.\n * @function\n * @param {Box3} box\n * @param {number} [threshold=0]\n * @param {Vector3} [target1]\n * @param {Vector3} [target2]\n * @returns {number}\n */\nOrientedBox.prototype.distanceToBox = ( function () {\n\n\tconst xyzFields = [ 'x', 'y', 'z' ];\n\tconst segments1 = /* @__PURE__ */ new Array( 12 ).fill().map( () => new Line3() );\n\tconst segments2 = /* @__PURE__ */ new Array( 12 ).fill().map( () => new Line3() );\n\n\tconst point1 = /* @__PURE__ */ new Vector3();\n\tconst point2 = /* @__PURE__ */ new Vector3();\n\n\t// early out if we find a value below threshold\n\treturn function distanceToBox( box, threshold = 0, target1 = null, target2 = null ) {\n\n\t\tif ( this.needsUpdate ) {\n\n\t\t\tthis.update();\n\n\t\t}\n\n\t\tif ( this.intersectsBox( box ) ) {\n\n\t\t\tif ( target1 || target2 ) {\n\n\t\t\t\tbox.getCenter( point2 );\n\t\t\t\tthis.closestPointToPoint( point2, point1 );\n\t\t\t\tbox.closestPointToPoint( point1, point2 );\n\n\t\t\t\tif ( target1 ) target1.copy( point1 );\n\t\t\t\tif ( target2 ) target2.copy( point2 );\n\n\t\t\t}\n\n\t\t\treturn 0;\n\n\t\t}\n\n\t\tconst threshold2 = threshold * threshold;\n\t\tconst min = box.min;\n\t\tconst max = box.max;\n\t\tconst points = this.points;\n\n\n\t\t// iterate over every edge and compare distances\n\t\tlet closestDistanceSq = Infinity;\n\n\t\t// check over all these points\n\t\tfor ( let i = 0; i < 8; i ++ ) {\n\n\t\t\tconst p = points[ i ];\n\t\t\tpoint2.copy( p ).clamp( min, max );\n\n\t\t\tconst dist = p.distanceToSquared( point2 );\n\t\t\tif ( dist < closestDistanceSq ) {\n\n\t\t\t\tclosestDistanceSq = dist;\n\t\t\t\tif ( target1 ) target1.copy( p );\n\t\t\t\tif ( target2 ) target2.copy( point2 );\n\n\t\t\t\tif ( dist < threshold2 ) return Math.sqrt( dist );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate and check all line segment distances\n\t\tlet count = 0;\n\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\tfor ( let i1 = 0; i1 <= 1; i1 ++ ) {\n\n\t\t\t\tfor ( let i2 = 0; i2 <= 1; i2 ++ ) {\n\n\t\t\t\t\tconst nextIndex = ( i + 1 ) % 3;\n\t\t\t\t\tconst nextIndex2 = ( i + 2 ) % 3;\n\n\t\t\t\t\t// get obb line segments\n\t\t\t\t\tconst index = i1 << nextIndex | i2 << nextIndex2;\n\t\t\t\t\tconst index2 = 1 << i | i1 << nextIndex | i2 << nextIndex2;\n\t\t\t\t\tconst p1 = points[ index ];\n\t\t\t\t\tconst p2 = points[ index2 ];\n\t\t\t\t\tconst line1 = segments1[ count ];\n\t\t\t\t\tline1.set( p1, p2 );\n\n\n\t\t\t\t\t// get aabb line segments\n\t\t\t\t\tconst f1 = xyzFields[ i ];\n\t\t\t\t\tconst f2 = xyzFields[ nextIndex ];\n\t\t\t\t\tconst f3 = xyzFields[ nextIndex2 ];\n\t\t\t\t\tconst line2 = segments2[ count ];\n\t\t\t\t\tconst start = line2.start;\n\t\t\t\t\tconst end = line2.end;\n\n\t\t\t\t\tstart[ f1 ] = min[ f1 ];\n\t\t\t\t\tstart[ f2 ] = i1 ? min[ f2 ] : max[ f2 ];\n\t\t\t\t\tstart[ f3 ] = i2 ? min[ f3 ] : max[ f2 ];\n\n\t\t\t\t\tend[ f1 ] = max[ f1 ];\n\t\t\t\t\tend[ f2 ] = i1 ? min[ f2 ] : max[ f2 ];\n\t\t\t\t\tend[ f3 ] = i2 ? min[ f3 ] : max[ f2 ];\n\n\t\t\t\t\tcount ++;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// check all the other boxes point\n\t\tfor ( let x = 0; x <= 1; x ++ ) {\n\n\t\t\tfor ( let y = 0; y <= 1; y ++ ) {\n\n\t\t\t\tfor ( let z = 0; z <= 1; z ++ ) {\n\n\t\t\t\t\tpoint2.x = x ? max.x : min.x;\n\t\t\t\t\tpoint2.y = y ? max.y : min.y;\n\t\t\t\t\tpoint2.z = z ? max.z : min.z;\n\n\t\t\t\t\tthis.closestPointToPoint( point2, point1 );\n\t\t\t\t\tconst dist = point2.distanceToSquared( point1 );\n\t\t\t\t\tif ( dist < closestDistanceSq ) {\n\n\t\t\t\t\t\tclosestDistanceSq = dist;\n\t\t\t\t\t\tif ( target1 ) target1.copy( point1 );\n\t\t\t\t\t\tif ( target2 ) target2.copy( point2 );\n\n\t\t\t\t\t\tif ( dist < threshold2 ) return Math.sqrt( dist );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfor ( let i = 0; i < 12; i ++ ) {\n\n\t\t\tconst l1 = segments1[ i ];\n\t\t\tfor ( let i2 = 0; i2 < 12; i2 ++ ) {\n\n\t\t\t\tconst l2 = segments2[ i2 ];\n\t\t\t\tclosestPointsSegmentToSegment( l1, l2, point1, point2 );\n\t\t\t\tconst dist = point1.distanceToSquared( point2 );\n\t\t\t\tif ( dist < closestDistanceSq ) {\n\n\t\t\t\t\tclosestDistanceSq = dist;\n\t\t\t\t\tif ( target1 ) target1.copy( point1 );\n\t\t\t\t\tif ( target2 ) target2.copy( point2 );\n\n\t\t\t\t\tif ( dist < threshold2 ) return Math.sqrt( dist );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn Math.sqrt( closestDistanceSq );\n\n\t};\n\n} )();\n","import { ExtendedTriangle } from '../math/ExtendedTriangle.js';\nimport { PrimitivePool } from './PrimitivePool.js';\n\nclass ExtendedTrianglePoolBase extends PrimitivePool {\n\n\tconstructor() {\n\n\t\tsuper( () => new ExtendedTriangle() );\n\n\t}\n\n}\n\nexport const ExtendedTrianglePool = /* @__PURE__ */ new ExtendedTrianglePoolBase();\n","import { Vector3 } from 'three';\n\nconst temp = /* @__PURE__ */ new Vector3();\nconst temp1 = /* @__PURE__ */ new Vector3();\n\nexport function closestPointToPoint(\n\tbvh,\n\tpoint,\n\ttarget = { },\n\tminThreshold = 0,\n\tmaxThreshold = Infinity,\n) {\n\n\t// early out if under minThreshold\n\t// skip checking if over maxThreshold\n\t// set minThreshold = maxThreshold to quickly check if a point is within a threshold\n\t// returns Infinity if no value found\n\tconst minThresholdSq = minThreshold * minThreshold;\n\tconst maxThresholdSq = maxThreshold * maxThreshold;\n\tlet closestDistanceSq = Infinity;\n\tlet closestDistanceTriIndex = null;\n\tbvh.shapecast(\n\n\t\t{\n\n\t\t\tboundsTraverseOrder: box => {\n\n\t\t\t\ttemp.copy( point ).clamp( box.min, box.max );\n\t\t\t\treturn temp.distanceToSquared( point );\n\n\t\t\t},\n\n\t\t\tintersectsBounds: ( box, isLeaf, score ) => {\n\n\t\t\t\treturn score < closestDistanceSq && score < maxThresholdSq;\n\n\t\t\t},\n\n\t\t\tintersectsTriangle: ( tri, triIndex ) => {\n\n\t\t\t\ttri.closestPointToPoint( point, temp );\n\t\t\t\tconst distSq = point.distanceToSquared( temp );\n\t\t\t\tif ( distSq < closestDistanceSq ) {\n\n\t\t\t\t\ttemp1.copy( temp );\n\t\t\t\t\tclosestDistanceSq = distSq;\n\t\t\t\t\tclosestDistanceTriIndex = triIndex;\n\n\t\t\t\t}\n\n\t\t\t\tif ( distSq < minThresholdSq ) {\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t}\n\n\t);\n\n\tif ( closestDistanceSq === Infinity ) return null;\n\n\tconst closestDistance = Math.sqrt( closestDistanceSq );\n\n\tif ( ! target.point ) target.point = temp1.clone();\n\telse target.point.copy( temp1 );\n\ttarget.distance = closestDistance,\n\ttarget.faceIndex = closestDistanceTriIndex;\n\n\treturn target;\n\n}\n","import { Vector3, Vector2, Triangle, DoubleSide, BackSide, REVISION } from 'three';\n\nconst IS_GT_REVISION_169 = parseInt( REVISION ) >= 169;\nconst IS_LT_REVISION_161 = parseInt( REVISION ) <= 161;\n\n// Ripped and modified From THREE.js Mesh raycast\n// https://github.com/mrdoob/three.js/blob/0aa87c999fe61e216c1133fba7a95772b503eddf/src/objects/Mesh.js#L115\nconst _vA = /* @__PURE__ */ new Vector3();\nconst _vB = /* @__PURE__ */ new Vector3();\nconst _vC = /* @__PURE__ */ new Vector3();\n\nconst _uvA = /* @__PURE__ */ new Vector2();\nconst _uvB = /* @__PURE__ */ new Vector2();\nconst _uvC = /* @__PURE__ */ new Vector2();\n\nconst _normalA = /* @__PURE__ */ new Vector3();\nconst _normalB = /* @__PURE__ */ new Vector3();\nconst _normalC = /* @__PURE__ */ new Vector3();\n\nconst _intersectionPoint = /* @__PURE__ */ new Vector3();\nfunction checkIntersection( ray, pA, pB, pC, point, side, near, far ) {\n\n\tlet intersect;\n\tif ( side === BackSide ) {\n\n\t\tintersect = ray.intersectTriangle( pC, pB, pA, true, point );\n\n\t} else {\n\n\t\tintersect = ray.intersectTriangle( pA, pB, pC, side !== DoubleSide, point );\n\n\t}\n\n\tif ( intersect === null ) return null;\n\n\tconst distance = ray.origin.distanceTo( point );\n\n\tif ( distance < near || distance > far ) return null;\n\n\treturn {\n\n\t\tdistance: distance,\n\t\tpoint: point.clone(),\n\n\t};\n\n}\n\nfunction checkBufferGeometryIntersection( ray, position, normal, uv, uv1, a, b, c, side, near, far ) {\n\n\t_vA.fromBufferAttribute( position, a );\n\t_vB.fromBufferAttribute( position, b );\n\t_vC.fromBufferAttribute( position, c );\n\n\tconst intersection = checkIntersection( ray, _vA, _vB, _vC, _intersectionPoint, side, near, far );\n\n\tif ( intersection ) {\n\n\t\tif ( uv ) {\n\n\t\t\t_uvA.fromBufferAttribute( uv, a );\n\t\t\t_uvB.fromBufferAttribute( uv, b );\n\t\t\t_uvC.fromBufferAttribute( uv, c );\n\n\t\t\tintersection.uv = new Vector2();\n\t\t\tconst res = Triangle.getInterpolation( _intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, intersection.uv );\n\t\t\tif ( ! IS_GT_REVISION_169 ) {\n\n\t\t\t\tintersection.uv = res;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( uv1 ) {\n\n\t\t\t_uvA.fromBufferAttribute( uv1, a );\n\t\t\t_uvB.fromBufferAttribute( uv1, b );\n\t\t\t_uvC.fromBufferAttribute( uv1, c );\n\n\t\t\tintersection.uv1 = new Vector2();\n\t\t\tconst res = Triangle.getInterpolation( _intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, intersection.uv1 );\n\t\t\tif ( ! IS_GT_REVISION_169 ) {\n\n\t\t\t\tintersection.uv1 = res;\n\n\t\t\t}\n\n\t\t\tif ( IS_LT_REVISION_161 ) {\n\n\t\t\t\tintersection.uv2 = intersection.uv1;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( normal ) {\n\n\t\t\t_normalA.fromBufferAttribute( normal, a );\n\t\t\t_normalB.fromBufferAttribute( normal, b );\n\t\t\t_normalC.fromBufferAttribute( normal, c );\n\n\t\t\tintersection.normal = new Vector3();\n\t\t\tconst res = Triangle.getInterpolation( _intersectionPoint, _vA, _vB, _vC, _normalA, _normalB, _normalC, intersection.normal );\n\t\t\tif ( intersection.normal.dot( ray.direction ) > 0 ) {\n\n\t\t\t\tintersection.normal.multiplyScalar( - 1 );\n\n\t\t\t}\n\n\t\t\tif ( ! IS_GT_REVISION_169 ) {\n\n\t\t\t\tintersection.normal = res;\n\n\t\t\t}\n\n\t\t}\n\n\t\tconst face = {\n\t\t\ta: a,\n\t\t\tb: b,\n\t\t\tc: c,\n\t\t\tnormal: new Vector3(),\n\t\t\tmaterialIndex: 0\n\t\t};\n\n\t\tTriangle.getNormal( _vA, _vB, _vC, face.normal );\n\n\t\tintersection.face = face;\n\t\tintersection.faceIndex = a;\n\n\t\tif ( IS_GT_REVISION_169 ) {\n\n\t\t\tconst barycoord = new Vector3();\n\t\t\tTriangle.getBarycoord( _intersectionPoint, _vA, _vB, _vC, barycoord );\n\n\t\t\tintersection.barycoord = barycoord;\n\n\t\t}\n\n\t}\n\n\treturn intersection;\n\n}\n\nfunction getSide( materialOrSide ) {\n\n\treturn materialOrSide && materialOrSide.isMaterial ? materialOrSide.side : materialOrSide;\n\n}\n\n// https://github.com/mrdoob/three.js/blob/0aa87c999fe61e216c1133fba7a95772b503eddf/src/objects/Mesh.js#L258\nexport function intersectTri( geometry, materialOrSide, ray, tri, intersections, near, far ) {\n\n\tconst triOffset = tri * 3;\n\tlet a = triOffset + 0;\n\tlet b = triOffset + 1;\n\tlet c = triOffset + 2;\n\n\tconst { index, groups } = geometry;\n\tif ( geometry.index ) {\n\n\t\ta = index.getX( a );\n\t\tb = index.getX( b );\n\t\tc = index.getX( c );\n\n\t}\n\n\tconst { position, normal, uv, uv1 } = geometry.attributes;\n\tif ( Array.isArray( materialOrSide ) ) {\n\n\t\t// check which groups a triangle is present in and run the intersections\n\t\t// TODO: we shouldn't need to run and intersection test multiple times\n\t\tconst firstIndex = tri * 3;\n\t\tfor ( let i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\tconst { start, count, materialIndex } = groups[ i ];\n\t\t\tif ( firstIndex >= start && firstIndex < start + count ) {\n\n\t\t\t\tconst side = getSide( materialOrSide[ materialIndex ] );\n\t\t\t\tconst intersection = checkBufferGeometryIntersection( ray, position, normal, uv, uv1, a, b, c, side, near, far );\n\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\tintersection.faceIndex = tri;\n\t\t\t\t\tintersection.face.materialIndex = materialIndex;\n\n\t\t\t\t\tif ( intersections ) {\n\n\t\t\t\t\t\tintersections.push( intersection );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn intersection;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t} else {\n\n\t\t// run the intersection for the single material\n\t\tconst side = getSide( materialOrSide );\n\t\tconst intersection = checkBufferGeometryIntersection( ray, position, normal, uv, uv1, a, b, c, side, near, far );\n\t\tif ( intersection ) {\n\n\t\t\tintersection.faceIndex = tri;\n\t\t\tintersection.face.materialIndex = 0;\n\n\t\t\tif ( intersections ) {\n\n\t\t\t\tintersections.push( intersection );\n\n\t\t\t} else {\n\n\t\t\t\treturn intersection;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\treturn null;\n\n}\n","/** @import { BufferGeometry } from 'three' */\nimport { Vector2, Vector3, Triangle } from 'three';\n\n// sets the vertices of triangle `tri` with the 3 vertices after i\nexport function setTriangle( tri, i, index, pos ) {\n\n\tconst ta = tri.a;\n\tconst tb = tri.b;\n\tconst tc = tri.c;\n\n\tlet i0 = i;\n\tlet i1 = i + 1;\n\tlet i2 = i + 2;\n\tif ( index ) {\n\n\t\ti0 = index.getX( i0 );\n\t\ti1 = index.getX( i1 );\n\t\ti2 = index.getX( i2 );\n\n\t}\n\n\tta.x = pos.getX( i0 );\n\tta.y = pos.getY( i0 );\n\tta.z = pos.getZ( i0 );\n\n\ttb.x = pos.getX( i1 );\n\ttb.y = pos.getY( i1 );\n\ttb.z = pos.getZ( i1 );\n\n\ttc.x = pos.getX( i2 );\n\ttc.y = pos.getY( i2 );\n\ttc.z = pos.getZ( i2 );\n\n}\n\nconst tempV1 = /* @__PURE__ */ new Vector3();\nconst tempV2 = /* @__PURE__ */ new Vector3();\nconst tempV3 = /* @__PURE__ */ new Vector3();\nconst tempUV1 = /* @__PURE__ */ new Vector2();\nconst tempUV2 = /* @__PURE__ */ new Vector2();\nconst tempUV3 = /* @__PURE__ */ new Vector2();\n\n/**\n * @typedef {Object} HitTriangleInfo\n * @property {{ a: number, b: number, c: number, materialIndex: number, normal: Vector3 }} face\n * Triangle vertex indices, material index, and face normal.\n * @property {Vector2|null} uv - UV coordinates at the hit point, or `null` if no UV attribute is present.\n * @property {Vector3} barycoord - Barycentric coordinates of the hit point within the triangle.\n */\n\n/**\n * Computes hit-point information for a point on a triangle within a `BufferGeometry`. Returns\n * the face vertex indices, face normal, material index, UV coordinates, and barycentric coordinates.\n * Useful for retrieving detailed hit data after a call to `MeshBVH.closestPointToPoint` or\n * `MeshBVH.closestPointToGeometry`.\n *\n * @section Functions\n * @param {Vector3} point - The point on the triangle surface (in the geometry's local space).\n * @param {BufferGeometry} geometry - The geometry containing the triangle.\n * @param {number} triangleIndex - The index of the triangle within the geometry.\n * @param {HitTriangleInfo} [target] - Optional object to write results into. Reuses existing\n * `face`, `uv`, and `barycoord` sub-objects if present.\n * @returns {HitTriangleInfo}\n */\nexport function getTriangleHitPointInfo( point, geometry, triangleIndex, target ) {\n\n\tconst indices = geometry.getIndex().array;\n\tconst positions = geometry.getAttribute( 'position' );\n\tconst uvs = geometry.getAttribute( 'uv' );\n\n\tconst a = indices[ triangleIndex * 3 ];\n\tconst b = indices[ triangleIndex * 3 + 1 ];\n\tconst c = indices[ triangleIndex * 3 + 2 ];\n\n\ttempV1.fromBufferAttribute( positions, a );\n\ttempV2.fromBufferAttribute( positions, b );\n\ttempV3.fromBufferAttribute( positions, c );\n\n\t// find the associated material index\n\tlet materialIndex = 0;\n\tconst groups = geometry.groups;\n\tconst firstVertexIndex = triangleIndex * 3;\n\tfor ( let i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\tconst group = groups[ i ];\n\t\tconst { start, count } = group;\n\t\tif ( firstVertexIndex >= start && firstVertexIndex < start + count ) {\n\n\t\t\tmaterialIndex = group.materialIndex;\n\t\t\tbreak;\n\n\t\t}\n\n\t}\n\n\t// extract barycoord\n\tconst barycoord = target && target.barycoord ? target.barycoord : new Vector3();\n\tTriangle.getBarycoord( point, tempV1, tempV2, tempV3, barycoord );\n\n\t// extract uvs\n\tlet uv = null;\n\tif ( uvs ) {\n\n\t\ttempUV1.fromBufferAttribute( uvs, a );\n\t\ttempUV2.fromBufferAttribute( uvs, b );\n\t\ttempUV3.fromBufferAttribute( uvs, c );\n\n\t\tif ( target && target.uv ) uv = target.uv;\n\t\telse uv = new Vector2();\n\n\t\tTriangle.getInterpolation( point, tempV1, tempV2, tempV3, tempUV1, tempUV2, tempUV3, uv );\n\n\t}\n\n\t// adjust the provided target or create a new one\n\tif ( target ) {\n\n\t\tif ( ! target.face ) target.face = { };\n\t\ttarget.face.a = a;\n\t\ttarget.face.b = b;\n\t\ttarget.face.c = c;\n\t\ttarget.face.materialIndex = materialIndex;\n\t\tif ( ! target.face.normal ) target.face.normal = new Vector3();\n\t\tTriangle.getNormal( tempV1, tempV2, tempV3, target.face.normal );\n\n\t\tif ( uv ) target.uv = uv;\n\t\ttarget.barycoord = barycoord;\n\n\t\treturn target;\n\n\t} else {\n\n\t\treturn {\n\t\t\tface: {\n\t\t\t\ta: a,\n\t\t\t\tb: b,\n\t\t\t\tc: c,\n\t\t\t\tmaterialIndex: materialIndex,\n\t\t\t\tnormal: Triangle.getNormal( tempV1, tempV2, tempV3, new Vector3() )\n\t\t\t},\n\t\t\tuv: uv,\n\t\t\tbarycoord: barycoord,\n\t\t};\n\n\t}\n\n}\n","import { intersectTri } from '../../utils/ThreeRayIntersectUtilities.js';\nimport { setTriangle } from '../../utils/TriangleUtilities.js';\n\n/*************************************************************/\n/* This file is generated from \"iterationUtils.template.js\". */\n/*************************************************************/\n\nfunction intersectTris( bvh, materialOrSide, ray, offset, count, intersections, near, far ) {\n\n\tconst { geometry, _indirectBuffer } = bvh;\n\tfor ( let i = offset, end = offset + count; i < end; i ++ ) {\n\n\n\t\tintersectTri( geometry, materialOrSide, ray, i, intersections, near, far );\n\n\n\t}\n\n}\n\nfunction intersectClosestTri( bvh, materialOrSide, ray, offset, count, near, far ) {\n\n\tconst { geometry, _indirectBuffer } = bvh;\n\tlet dist = Infinity;\n\tlet res = null;\n\tfor ( let i = offset, end = offset + count; i < end; i ++ ) {\n\n\t\tlet intersection;\n\n\t\tintersection = intersectTri( geometry, materialOrSide, ray, i, null, near, far );\n\n\n\t\tif ( intersection && intersection.distance < dist ) {\n\n\t\t\tres = intersection;\n\t\t\tdist = intersection.distance;\n\n\t\t}\n\n\t}\n\n\treturn res;\n\n}\n\nfunction iterateOverTriangles(\n\toffset,\n\tcount,\n\tbvh,\n\tintersectsTriangleFunc,\n\tcontained,\n\tdepth,\n\ttriangle\n) {\n\n\tconst { geometry } = bvh;\n\tconst { index } = geometry;\n\tconst pos = geometry.attributes.position;\n\tfor ( let i = offset, l = count + offset; i < l; i ++ ) {\n\n\t\tlet tri;\n\n\t\ttri = i;\n\n\t\tsetTriangle( triangle, tri * 3, index, pos );\n\t\ttriangle.needsUpdate = true;\n\n\t\tif ( intersectsTriangleFunc( triangle, tri, contained, depth ) ) {\n\n\t\t\treturn true;\n\n\t\t}\n\n\t}\n\n\treturn false;\n\n}\n\nexport { intersectClosestTri, intersectTris, iterateOverTriangles };\n","import { UINT32_PER_NODE, BYTES_PER_NODE } from '../Constants.js';\nimport { IS_LEAF, OFFSET, COUNT, LEFT_NODE, RIGHT_NODE } from '../utils/nodeBufferUtils.js';\n\n/****************************************************/\n/* This file is generated from \"refit.template.js\". */\n/****************************************************/\n\nfunction refit( bvh, nodeIndices = null ) {\n\n\tif ( nodeIndices && Array.isArray( nodeIndices ) ) {\n\n\t\tnodeIndices = new Set( nodeIndices );\n\n\t}\n\n\tconst geometry = bvh.geometry;\n\tconst indexArr = geometry.index ? geometry.index.array : null;\n\tconst posAttr = geometry.attributes.position;\n\n\tlet buffer, uint32Array, uint16Array, float32Array;\n\tlet byteOffset = 0;\n\tconst roots = bvh._roots;\n\tfor ( let i = 0, l = roots.length; i < l; i ++ ) {\n\n\t\tbuffer = roots[ i ];\n\t\tuint32Array = new Uint32Array( buffer );\n\t\tuint16Array = new Uint16Array( buffer );\n\t\tfloat32Array = new Float32Array( buffer );\n\n\t\t_traverse( 0, byteOffset );\n\t\tbyteOffset += buffer.byteLength;\n\n\t}\n\n\tfunction _traverse( nodeIndex32, byteOffset, force = false ) {\n\n\t\tconst nodeIndex16 = nodeIndex32 * 2;\n\t\tif ( IS_LEAF( nodeIndex16, uint16Array ) ) {\n\n\t\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\n\t\t\tlet minx = Infinity;\n\t\t\tlet miny = Infinity;\n\t\t\tlet minz = Infinity;\n\t\t\tlet maxx = - Infinity;\n\t\t\tlet maxy = - Infinity;\n\t\t\tlet maxz = - Infinity;\n\n\n\t\t\tfor ( let i = 3 * offset, l = 3 * ( offset + count ); i < l; i ++ ) {\n\n\t\t\t\tlet index = indexArr[ i ];\n\t\t\t\tconst x = posAttr.getX( index );\n\t\t\t\tconst y = posAttr.getY( index );\n\t\t\t\tconst z = posAttr.getZ( index );\n\n\t\t\t\tif ( x < minx ) minx = x;\n\t\t\t\tif ( x > maxx ) maxx = x;\n\n\t\t\t\tif ( y < miny ) miny = y;\n\t\t\t\tif ( y > maxy ) maxy = y;\n\n\t\t\t\tif ( z < minz ) minz = z;\n\t\t\t\tif ( z > maxz ) maxz = z;\n\n\t\t\t}\n\n\n\t\t\tif (\n\t\t\t\tfloat32Array[ nodeIndex32 + 0 ] !== minx ||\n\t\t\t\tfloat32Array[ nodeIndex32 + 1 ] !== miny ||\n\t\t\t\tfloat32Array[ nodeIndex32 + 2 ] !== minz ||\n\n\t\t\t\tfloat32Array[ nodeIndex32 + 3 ] !== maxx ||\n\t\t\t\tfloat32Array[ nodeIndex32 + 4 ] !== maxy ||\n\t\t\t\tfloat32Array[ nodeIndex32 + 5 ] !== maxz\n\t\t\t) {\n\n\t\t\t\tfloat32Array[ nodeIndex32 + 0 ] = minx;\n\t\t\t\tfloat32Array[ nodeIndex32 + 1 ] = miny;\n\t\t\t\tfloat32Array[ nodeIndex32 + 2 ] = minz;\n\n\t\t\t\tfloat32Array[ nodeIndex32 + 3 ] = maxx;\n\t\t\t\tfloat32Array[ nodeIndex32 + 4 ] = maxy;\n\t\t\t\tfloat32Array[ nodeIndex32 + 5 ] = maxz;\n\n\t\t\t\treturn true;\n\n\t\t\t} else {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tconst left = LEFT_NODE( nodeIndex32 );\n\t\t\tconst right = RIGHT_NODE( nodeIndex32, uint32Array );\n\n\t\t\t// the identifying node indices provided by the shapecast function include offsets of all\n\t\t\t// root buffers to guarantee they're unique between roots so offset left and right indices here.\n\t\t\tlet forceChildren = force;\n\t\t\tlet includesLeft = false;\n\t\t\tlet includesRight = false;\n\n\t\t\tif ( nodeIndices ) {\n\n\t\t\t\t// if we see that neither the left or right child are included in the set that need to be updated\n\t\t\t\t// then we assume that all children need to be updated.\n\t\t\t\tif ( ! forceChildren ) {\n\n\t\t\t\t\tconst leftNodeId = left / UINT32_PER_NODE + byteOffset / BYTES_PER_NODE;\n\t\t\t\t\tconst rightNodeId = right / UINT32_PER_NODE + byteOffset / BYTES_PER_NODE;\n\t\t\t\t\tincludesLeft = nodeIndices.has( leftNodeId );\n\t\t\t\t\tincludesRight = nodeIndices.has( rightNodeId );\n\t\t\t\t\tforceChildren = ! includesLeft && ! includesRight;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tincludesLeft = true;\n\t\t\t\tincludesRight = true;\n\n\t\t\t}\n\n\t\t\tconst traverseLeft = forceChildren || includesLeft;\n\t\t\tconst traverseRight = forceChildren || includesRight;\n\n\t\t\tlet leftChange = false;\n\t\t\tif ( traverseLeft ) {\n\n\t\t\t\tleftChange = _traverse( left, byteOffset, forceChildren );\n\n\t\t\t}\n\n\t\t\tlet rightChange = false;\n\t\t\tif ( traverseRight ) {\n\n\t\t\t\trightChange = _traverse( right, byteOffset, forceChildren );\n\n\t\t\t}\n\n\t\t\tconst didChange = leftChange || rightChange;\n\t\t\tif ( didChange ) {\n\n\t\t\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\tconst left_i = left + i;\n\t\t\t\t\tconst right_i = right + i;\n\t\t\t\t\tconst minLeftValue = float32Array[ left_i ];\n\t\t\t\t\tconst maxLeftValue = float32Array[ left_i + 3 ];\n\t\t\t\t\tconst minRightValue = float32Array[ right_i ];\n\t\t\t\t\tconst maxRightValue = float32Array[ right_i + 3 ];\n\n\t\t\t\t\tfloat32Array[ nodeIndex32 + i ] = minLeftValue < minRightValue ? minLeftValue : minRightValue;\n\t\t\t\t\tfloat32Array[ nodeIndex32 + i + 3 ] = maxLeftValue > maxRightValue ? maxLeftValue : maxRightValue;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn didChange;\n\n\t\t}\n\n\t}\n\n}\n\nexport { refit };\n","\nexport function intersectsNodeBounds( nodeIndex32, array, ray, near, far ) {\n\n\t// This function performs intersection tests similar to Ray.intersectBox in three.js,\n\t// with the difference that the box values are read from an array to improve performance.\n\n\tlet tmin, tmax, tymin, tymax, tzmin, tzmax;\n\n\tconst invdirx = 1 / ray.direction.x,\n\t\tinvdiry = 1 / ray.direction.y,\n\t\tinvdirz = 1 / ray.direction.z;\n\n\tconst ox = ray.origin.x;\n\tconst oy = ray.origin.y;\n\tconst oz = ray.origin.z;\n\n\tlet minx = array[ nodeIndex32 ];\n\tlet maxx = array[ nodeIndex32 + 3 ];\n\n\tlet miny = array[ nodeIndex32 + 1 ];\n\tlet maxy = array[ nodeIndex32 + 3 + 1 ];\n\n\tlet minz = array[ nodeIndex32 + 2 ];\n\tlet maxz = array[ nodeIndex32 + 3 + 2 ];\n\n\tif ( invdirx >= 0 ) {\n\n\t\ttmin = ( minx - ox ) * invdirx;\n\t\ttmax = ( maxx - ox ) * invdirx;\n\n\t} else {\n\n\t\ttmin = ( maxx - ox ) * invdirx;\n\t\ttmax = ( minx - ox ) * invdirx;\n\n\t}\n\n\tif ( invdiry >= 0 ) {\n\n\t\ttymin = ( miny - oy ) * invdiry;\n\t\ttymax = ( maxy - oy ) * invdiry;\n\n\t} else {\n\n\t\ttymin = ( maxy - oy ) * invdiry;\n\t\ttymax = ( miny - oy ) * invdiry;\n\n\t}\n\n\tif ( ( tmin > tymax ) || ( tymin > tmax ) ) return false;\n\n\tif ( tymin > tmin || isNaN( tmin ) ) tmin = tymin;\n\n\tif ( tymax < tmax || isNaN( tmax ) ) tmax = tymax;\n\n\tif ( invdirz >= 0 ) {\n\n\t\ttzmin = ( minz - oz ) * invdirz;\n\t\ttzmax = ( maxz - oz ) * invdirz;\n\n\t} else {\n\n\t\ttzmin = ( maxz - oz ) * invdirz;\n\t\ttzmax = ( minz - oz ) * invdirz;\n\n\t}\n\n\tif ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return false;\n\n\tif ( tzmin > tmin || tmin !== tmin ) tmin = tzmin;\n\n\tif ( tzmax < tmax || tmax !== tmax ) tmax = tzmax;\n\n\t//return point closest to the ray (positive side)\n\n\treturn tmin <= far && tmax >= near;\n\n}\n","import { intersectTri } from '../../utils/ThreeRayIntersectUtilities.js';\nimport { setTriangle } from '../../utils/TriangleUtilities.js';\n\n/*************************************************************/\n/* This file is generated from \"iterationUtils.template.js\". */\n/*************************************************************/\n\nfunction intersectTris_indirect( bvh, materialOrSide, ray, offset, count, intersections, near, far ) {\n\n\tconst { geometry, _indirectBuffer } = bvh;\n\tfor ( let i = offset, end = offset + count; i < end; i ++ ) {\n\n\t\tlet vi = _indirectBuffer ? _indirectBuffer[ i ] : i;\n\t\tintersectTri( geometry, materialOrSide, ray, vi, intersections, near, far );\n\n\n\t}\n\n}\n\nfunction intersectClosestTri_indirect( bvh, materialOrSide, ray, offset, count, near, far ) {\n\n\tconst { geometry, _indirectBuffer } = bvh;\n\tlet dist = Infinity;\n\tlet res = null;\n\tfor ( let i = offset, end = offset + count; i < end; i ++ ) {\n\n\t\tlet intersection;\n\t\tintersection = intersectTri( geometry, materialOrSide, ray, _indirectBuffer ? _indirectBuffer[ i ] : i, null, near, far );\n\n\n\t\tif ( intersection && intersection.distance < dist ) {\n\n\t\t\tres = intersection;\n\t\t\tdist = intersection.distance;\n\n\t\t}\n\n\t}\n\n\treturn res;\n\n}\n\nfunction iterateOverTriangles_indirect(\n\toffset,\n\tcount,\n\tbvh,\n\tintersectsTriangleFunc,\n\tcontained,\n\tdepth,\n\ttriangle\n) {\n\n\tconst { geometry } = bvh;\n\tconst { index } = geometry;\n\tconst pos = geometry.attributes.position;\n\tfor ( let i = offset, l = count + offset; i < l; i ++ ) {\n\n\t\tlet tri;\n\t\ttri = bvh.resolveTriangleIndex( i );\n\n\t\tsetTriangle( triangle, tri * 3, index, pos );\n\t\ttriangle.needsUpdate = true;\n\n\t\tif ( intersectsTriangleFunc( triangle, tri, contained, depth ) ) {\n\n\t\t\treturn true;\n\n\t\t}\n\n\t}\n\n\treturn false;\n\n}\n\nexport { intersectClosestTri_indirect, intersectTris_indirect, iterateOverTriangles_indirect };\n","import { intersectsNodeBounds } from '../utils/intersectUtils.js';\nimport { IS_LEAF, OFFSET, COUNT, LEFT_NODE, RIGHT_NODE } from '../utils/nodeBufferUtils.js';\nimport { BufferStack } from '../utils/BufferStack.js';\nimport { intersectTris } from '../utils/iterationUtils.generated.js';\nimport '../utils/iterationUtils_indirect.generated.js';\n\n/******************************************************/\n/* This file is generated from \"raycast.template.js\". */\n/******************************************************/\n\nfunction raycast( bvh, root, materialOrSide, ray, intersects, near, far ) {\n\n\tBufferStack.setBuffer( bvh._roots[ root ] );\n\t_raycast( 0, bvh, materialOrSide, ray, intersects, near, far );\n\tBufferStack.clearBuffer();\n\n}\n\nfunction _raycast( nodeIndex32, bvh, materialOrSide, ray, intersects, near, far ) {\n\n\tconst { float32Array, uint16Array, uint32Array } = BufferStack;\n\tconst nodeIndex16 = nodeIndex32 * 2;\n\tconst isLeaf = IS_LEAF( nodeIndex16, uint16Array );\n\tif ( isLeaf ) {\n\n\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\n\n\t\tintersectTris( bvh, materialOrSide, ray, offset, count, intersects, near, far );\n\n\n\t} else {\n\n\t\tconst leftIndex = LEFT_NODE( nodeIndex32 );\n\t\tif ( intersectsNodeBounds( leftIndex, float32Array, ray, near, far ) ) {\n\n\t\t\t_raycast( leftIndex, bvh, materialOrSide, ray, intersects, near, far );\n\n\t\t}\n\n\t\tconst rightIndex = RIGHT_NODE( nodeIndex32, uint32Array );\n\t\tif ( intersectsNodeBounds( rightIndex, float32Array, ray, near, far ) ) {\n\n\t\t\t_raycast( rightIndex, bvh, materialOrSide, ray, intersects, near, far );\n\n\t\t}\n\n\t}\n\n}\n\nexport { raycast };\n","import { IS_LEAF, OFFSET, COUNT, SPLIT_AXIS, LEFT_NODE, RIGHT_NODE } from '../utils/nodeBufferUtils.js';\nimport { BufferStack } from '../utils/BufferStack.js';\nimport { intersectsNodeBounds } from '../utils/intersectUtils.js';\nimport { intersectClosestTri } from '../utils/iterationUtils.generated.js';\nimport '../utils/iterationUtils_indirect.generated.js';\n\n/***********************************************************/\n/* This file is generated from \"raycastFirst.template.js\". */\n/***********************************************************/\n\nconst _xyzFields = [ 'x', 'y', 'z' ];\n\nfunction raycastFirst( bvh, root, materialOrSide, ray, near, far ) {\n\n\tBufferStack.setBuffer( bvh._roots[ root ] );\n\tconst result = _raycastFirst( 0, bvh, materialOrSide, ray, near, far );\n\tBufferStack.clearBuffer();\n\n\treturn result;\n\n}\n\nfunction _raycastFirst( nodeIndex32, bvh, materialOrSide, ray, near, far ) {\n\n\tconst { float32Array, uint16Array, uint32Array } = BufferStack;\n\tlet nodeIndex16 = nodeIndex32 * 2;\n\n\tconst isLeaf = IS_LEAF( nodeIndex16, uint16Array );\n\tif ( isLeaf ) {\n\n\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\n\n\t\t// eslint-disable-next-line no-unreachable\n\t\treturn intersectClosestTri( bvh, materialOrSide, ray, offset, count, near, far );\n\n\n\t} else {\n\n\t\t// consider the position of the split plane with respect to the oncoming ray; whichever direction\n\t\t// the ray is coming from, look for an intersection among that side of the tree first\n\t\tconst splitAxis = SPLIT_AXIS( nodeIndex32, uint32Array );\n\t\tconst xyzAxis = _xyzFields[ splitAxis ];\n\t\tconst rayDir = ray.direction[ xyzAxis ];\n\t\tconst leftToRight = rayDir >= 0;\n\n\t\t// c1 is the child to check first\n\t\tlet c1, c2;\n\t\tif ( leftToRight ) {\n\n\t\t\tc1 = LEFT_NODE( nodeIndex32 );\n\t\t\tc2 = RIGHT_NODE( nodeIndex32, uint32Array );\n\n\t\t} else {\n\n\t\t\tc1 = RIGHT_NODE( nodeIndex32, uint32Array );\n\t\t\tc2 = LEFT_NODE( nodeIndex32 );\n\n\t\t}\n\n\t\tconst c1Intersection = intersectsNodeBounds( c1, float32Array, ray, near, far );\n\t\tconst c1Result = c1Intersection ? _raycastFirst( c1, bvh, materialOrSide, ray, near, far ) : null;\n\n\t\t// if we got an intersection in the first node and it's closer than the second node's bounding\n\t\t// box, we don't need to consider the second node because it couldn't possibly be a better result\n\t\tif ( c1Result ) {\n\n\t\t\t// check if the point is within the second bounds\n\t\t\t// \"point\" is in the local frame of the bvh\n\t\t\tconst point = c1Result.point[ xyzAxis ];\n\t\t\tconst isOutside = leftToRight ?\n\t\t\t\tpoint <= float32Array[ c2 + splitAxis ] : // min bounding data\n\t\t\t\tpoint >= float32Array[ c2 + splitAxis + 3 ]; // max bounding data\n\n\t\t\tif ( isOutside ) {\n\n\t\t\t\treturn c1Result;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// either there was no intersection in the first node, or there could still be a closer\n\t\t// intersection in the second, so check the second node and then take the better of the two\n\t\tconst c2Intersection = intersectsNodeBounds( c2, float32Array, ray, near, far );\n\t\tconst c2Result = c2Intersection ? _raycastFirst( c2, bvh, materialOrSide, ray, near, far ) : null;\n\n\t\tif ( c1Result && c2Result ) {\n\n\t\t\treturn c1Result.distance <= c2Result.distance ? c1Result : c2Result;\n\n\t\t} else {\n\n\t\t\treturn c1Result || c2Result || null;\n\n\t\t}\n\n\t}\n\n}\n\nexport { raycastFirst };\n","import { Box3, Matrix4 } from 'three';\nimport { OrientedBox } from '../../math/OrientedBox.js';\nimport { ExtendedTriangle } from '../../math/ExtendedTriangle.js';\nimport { setTriangle } from '../../utils/TriangleUtilities.js';\nimport { arrayToBox } from '../../utils/ArrayBoxUtilities.js';\nimport { IS_LEAF, OFFSET, COUNT, BOUNDING_DATA_INDEX, LEFT_NODE, RIGHT_NODE } from '../utils/nodeBufferUtils.js';\nimport { BufferStack } from '../utils/BufferStack.js';\nimport { getTriCount } from '../build/geometryUtils.js';\n\n/*****************************************************************/\n/* This file is generated from \"intersectsGeometry.template.js\". */\n/*****************************************************************/\n/* eslint-disable indent */\n\nconst boundingBox = /* @__PURE__ */ new Box3();\nconst triangle = /* @__PURE__ */ new ExtendedTriangle();\nconst triangle2 = /* @__PURE__ */ new ExtendedTriangle();\nconst invertedMat = /* @__PURE__ */ new Matrix4();\n\nconst obb = /* @__PURE__ */ new OrientedBox();\nconst obb2 = /* @__PURE__ */ new OrientedBox();\n\nfunction intersectsGeometry( bvh, root, otherGeometry, geometryToBvh ) {\n\n\tBufferStack.setBuffer( bvh._roots[ root ] );\n\tconst result = _intersectsGeometry( 0, bvh, otherGeometry, geometryToBvh );\n\tBufferStack.clearBuffer();\n\n\treturn result;\n\n}\n\nfunction _intersectsGeometry( nodeIndex32, bvh, otherGeometry, geometryToBvh, cachedObb = null ) {\n\n\tconst { float32Array, uint16Array, uint32Array } = BufferStack;\n\tlet nodeIndex16 = nodeIndex32 * 2;\n\n\tif ( cachedObb === null ) {\n\n\t\tif ( ! otherGeometry.boundingBox ) {\n\n\t\t\totherGeometry.computeBoundingBox();\n\n\t\t}\n\n\t\tobb.set( otherGeometry.boundingBox.min, otherGeometry.boundingBox.max, geometryToBvh );\n\t\tcachedObb = obb;\n\n\t}\n\n\tconst isLeaf = IS_LEAF( nodeIndex16, uint16Array );\n\tif ( isLeaf ) {\n\n\t\tconst thisGeometry = bvh.geometry;\n\t\tconst thisIndex = thisGeometry.index;\n\t\tconst thisPos = thisGeometry.attributes.position;\n\n\t\tconst otherIndex = otherGeometry.index;\n\t\tconst otherPos = otherGeometry.attributes.position;\n\n\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\n\t\t// get the inverse of the geometry matrix so we can transform our triangles into the\n\t\t// geometry space we're trying to test. We assume there are fewer triangles being checked\n\t\t// here.\n\t\tinvertedMat.copy( geometryToBvh ).invert();\n\n\t\tif ( otherGeometry.boundsTree ) {\n\n\t\t\t// if there's a bounds tree\n\t\t\tarrayToBox( BOUNDING_DATA_INDEX( nodeIndex32 ), float32Array, obb2 );\n\t\t\tobb2.matrix.copy( invertedMat );\n\t\t\tobb2.needsUpdate = true;\n\n\t\t\t// TODO: use a triangle iteration function here\n\t\t\tconst res = otherGeometry.boundsTree.shapecast( {\n\n\t\t\t\tintersectsBounds: box => obb2.intersectsBox( box ),\n\n\t\t\t\tintersectsTriangle: tri => {\n\n\t\t\t\t\ttri.a.applyMatrix4( geometryToBvh );\n\t\t\t\t\ttri.b.applyMatrix4( geometryToBvh );\n\t\t\t\t\ttri.c.applyMatrix4( geometryToBvh );\n\t\t\t\t\ttri.needsUpdate = true;\n\n\n\t\t\t\t\tfor ( let i = offset * 3, l = ( count + offset ) * 3; i < l; i += 3 ) {\n\n\t\t\t\t\t\t// this triangle needs to be transformed into the current BVH coordinate frame\n\t\t\t\t\t\tsetTriangle( triangle2, i, thisIndex, thisPos );\n\t\t\t\t\t\ttriangle2.needsUpdate = true;\n\t\t\t\t\t\tif ( tri.intersectsTriangle( triangle2 ) ) {\n\n\t\t\t\t\t\t\treturn true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t\treturn res;\n\n\t\t} else {\n\n\t\t\t// if we're just dealing with raw geometry\n\t\t\tconst otherTriangleCount = getTriCount( otherGeometry );\n\n\n\t\t\tfor ( let i = offset * 3, l = ( count + offset ) * 3; i < l; i += 3 ) {\n\n\t\t\t\t// this triangle needs to be transformed into the current BVH coordinate frame\n\t\t\t\tsetTriangle( triangle, i, thisIndex, thisPos );\n\n\n\t\t\t\ttriangle.a.applyMatrix4( invertedMat );\n\t\t\t\ttriangle.b.applyMatrix4( invertedMat );\n\t\t\t\ttriangle.c.applyMatrix4( invertedMat );\n\t\t\t\ttriangle.needsUpdate = true;\n\n\t\t\t\tfor ( let i2 = 0, l2 = otherTriangleCount * 3; i2 < l2; i2 += 3 ) {\n\n\t\t\t\t\tsetTriangle( triangle2, i2, otherIndex, otherPos );\n\t\t\t\t\ttriangle2.needsUpdate = true;\n\n\t\t\t\t\tif ( triangle.intersectsTriangle( triangle2 ) ) {\n\n\t\t\t\t\t\treturn true;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\n\t\t\t}\n\n\n\t\t}\n\n\t} else {\n\n\t\tconst left = LEFT_NODE( nodeIndex32 );\n\t\tconst right = RIGHT_NODE( nodeIndex32, uint32Array );\n\n\t\tarrayToBox( BOUNDING_DATA_INDEX( left ), float32Array, boundingBox );\n\t\tconst leftIntersection =\n\t\t\tcachedObb.intersectsBox( boundingBox ) &&\n\t\t\t_intersectsGeometry( left, bvh, otherGeometry, geometryToBvh, cachedObb );\n\n\t\tif ( leftIntersection ) return true;\n\n\t\tarrayToBox( BOUNDING_DATA_INDEX( right ), float32Array, boundingBox );\n\t\tconst rightIntersection =\n\t\t\tcachedObb.intersectsBox( boundingBox ) &&\n\t\t\t_intersectsGeometry( right, bvh, otherGeometry, geometryToBvh, cachedObb );\n\n\t\tif ( rightIntersection ) return true;\n\n\t\treturn false;\n\n\t}\n\n}\n\nexport { intersectsGeometry };\n","import { Matrix4, Vector3 } from 'three';\nimport { OrientedBox } from '../../math/OrientedBox.js';\nimport { setTriangle } from '../../utils/TriangleUtilities.js';\nimport { getTriCount } from '../build/geometryUtils.js';\nimport { ExtendedTrianglePool } from '../../utils/ExtendedTrianglePool.js';\n\n/*********************************************************************/\n/* This file is generated from \"closestPointToGeometry.template.js\". */\n/*********************************************************************/\n\nconst tempMatrix = /* @__PURE__ */ new Matrix4();\nconst obb = /* @__PURE__ */ new OrientedBox();\nconst obb2 = /* @__PURE__ */ new OrientedBox();\nconst temp1 = /* @__PURE__ */ new Vector3();\nconst temp2 = /* @__PURE__ */ new Vector3();\nconst temp3 = /* @__PURE__ */ new Vector3();\nconst temp4 = /* @__PURE__ */ new Vector3();\n\nfunction closestPointToGeometry(\n\tbvh,\n\totherGeometry,\n\tgeometryToBvh,\n\ttarget1 = { },\n\ttarget2 = { },\n\tminThreshold = 0,\n\tmaxThreshold = Infinity,\n) {\n\n\tif ( ! otherGeometry.boundingBox ) {\n\n\t\totherGeometry.computeBoundingBox();\n\n\t}\n\n\tobb.set( otherGeometry.boundingBox.min, otherGeometry.boundingBox.max, geometryToBvh );\n\tobb.needsUpdate = true;\n\n\tconst geometry = bvh.geometry;\n\tconst pos = geometry.attributes.position;\n\tconst index = geometry.index;\n\tconst otherPos = otherGeometry.attributes.position;\n\tconst otherIndex = otherGeometry.index;\n\tconst triangle = ExtendedTrianglePool.getPrimitive();\n\tconst triangle2 = ExtendedTrianglePool.getPrimitive();\n\n\tlet tempTarget1 = temp1;\n\tlet tempTargetDest1 = temp2;\n\tlet tempTarget2 = null;\n\tlet tempTargetDest2 = null;\n\n\tif ( target2 ) {\n\n\t\ttempTarget2 = temp3;\n\t\ttempTargetDest2 = temp4;\n\n\t}\n\n\tlet closestDistance = Infinity;\n\tlet closestDistanceTriIndex = null;\n\tlet closestDistanceOtherTriIndex = null;\n\ttempMatrix.copy( geometryToBvh ).invert();\n\tobb2.matrix.copy( tempMatrix );\n\tbvh.shapecast(\n\t\t{\n\n\t\t\tboundsTraverseOrder: box => {\n\n\t\t\t\treturn obb.distanceToBox( box );\n\n\t\t\t},\n\n\t\t\tintersectsBounds: ( box, isLeaf, score ) => {\n\n\t\t\t\tif ( score < closestDistance && score < maxThreshold ) {\n\n\t\t\t\t\t// if we know the triangles of this bounds will be intersected next then\n\t\t\t\t\t// save the bounds to use during triangle checks.\n\t\t\t\t\tif ( isLeaf ) {\n\n\t\t\t\t\t\tobb2.min.copy( box.min );\n\t\t\t\t\t\tobb2.max.copy( box.max );\n\t\t\t\t\t\tobb2.needsUpdate = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\n\t\t\t},\n\n\t\t\tintersectsRange: ( offset, count ) => {\n\n\t\t\t\tif ( otherGeometry.boundsTree ) {\n\n\t\t\t\t\t// if the other geometry has a bvh then use the accelerated path where we use shapecast to find\n\t\t\t\t\t// the closest bounds in the other geometry to check.\n\t\t\t\t\tconst otherBvh = otherGeometry.boundsTree;\n\t\t\t\t\treturn otherBvh.shapecast( {\n\t\t\t\t\t\tboundsTraverseOrder: box => {\n\n\t\t\t\t\t\t\treturn obb2.distanceToBox( box );\n\n\t\t\t\t\t\t},\n\n\t\t\t\t\t\tintersectsBounds: ( box, isLeaf, score ) => {\n\n\t\t\t\t\t\t\treturn score < closestDistance && score < maxThreshold;\n\n\t\t\t\t\t\t},\n\n\t\t\t\t\t\tintersectsRange: ( otherOffset, otherCount ) => {\n\n\t\t\t\t\t\t\tfor ( let i2 = otherOffset, l2 = otherOffset + otherCount; i2 < l2; i2 ++ ) {\n\n\n\t\t\t\t\t\t\t\tsetTriangle( triangle2, 3 * i2, otherIndex, otherPos );\n\n\t\t\t\t\t\t\t\ttriangle2.a.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\t\t\ttriangle2.b.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\t\t\ttriangle2.c.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\t\t\ttriangle2.needsUpdate = true;\n\n\t\t\t\t\t\t\t\tfor ( let i = offset, l = offset + count; i < l; i ++ ) {\n\n\n\t\t\t\t\t\t\t\t\tsetTriangle( triangle, 3 * i, index, pos );\n\n\t\t\t\t\t\t\t\t\ttriangle.needsUpdate = true;\n\n\t\t\t\t\t\t\t\t\tconst dist = triangle.distanceToTriangle( triangle2, tempTarget1, tempTarget2 );\n\t\t\t\t\t\t\t\t\tif ( dist < closestDistance ) {\n\n\t\t\t\t\t\t\t\t\t\ttempTargetDest1.copy( tempTarget1 );\n\n\t\t\t\t\t\t\t\t\t\tif ( tempTargetDest2 ) {\n\n\t\t\t\t\t\t\t\t\t\t\ttempTargetDest2.copy( tempTarget2 );\n\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tclosestDistance = dist;\n\t\t\t\t\t\t\t\t\t\tclosestDistanceTriIndex = i;\n\t\t\t\t\t\t\t\t\t\tclosestDistanceOtherTriIndex = i2;\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// stop traversal if we find a point that's under the given threshold\n\t\t\t\t\t\t\t\t\tif ( dist < minThreshold ) {\n\n\t\t\t\t\t\t\t\t\t\treturn true;\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t},\n\t\t\t\t\t} );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// If no bounds tree then we'll just check every triangle.\n\t\t\t\t\tconst triCount = getTriCount( otherGeometry );\n\t\t\t\t\tfor ( let i2 = 0, l2 = triCount; i2 < l2; i2 ++ ) {\n\n\t\t\t\t\t\tsetTriangle( triangle2, 3 * i2, otherIndex, otherPos );\n\t\t\t\t\t\ttriangle2.a.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\ttriangle2.b.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\ttriangle2.c.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\ttriangle2.needsUpdate = true;\n\n\t\t\t\t\t\tfor ( let i = offset, l = offset + count; i < l; i ++ ) {\n\n\n\t\t\t\t\t\t\tsetTriangle( triangle, 3 * i, index, pos );\n\n\t\t\t\t\t\t\ttriangle.needsUpdate = true;\n\n\t\t\t\t\t\t\tconst dist = triangle.distanceToTriangle( triangle2, tempTarget1, tempTarget2 );\n\t\t\t\t\t\t\tif ( dist < closestDistance ) {\n\n\t\t\t\t\t\t\t\ttempTargetDest1.copy( tempTarget1 );\n\n\t\t\t\t\t\t\t\tif ( tempTargetDest2 ) {\n\n\t\t\t\t\t\t\t\t\ttempTargetDest2.copy( tempTarget2 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tclosestDistance = dist;\n\t\t\t\t\t\t\t\tclosestDistanceTriIndex = i;\n\t\t\t\t\t\t\t\tclosestDistanceOtherTriIndex = i2;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// stop traversal if we find a point that's under the given threshold\n\t\t\t\t\t\t\tif ( dist < minThreshold ) {\n\n\t\t\t\t\t\t\t\treturn true;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t}\n\n\t);\n\n\tExtendedTrianglePool.releasePrimitive( triangle );\n\tExtendedTrianglePool.releasePrimitive( triangle2 );\n\n\tif ( closestDistance === Infinity ) {\n\n\t\treturn null;\n\n\t}\n\n\tif ( ! target1.point ) {\n\n\t\ttarget1.point = tempTargetDest1.clone();\n\n\t} else {\n\n\t\ttarget1.point.copy( tempTargetDest1 );\n\n\t}\n\n\ttarget1.distance = closestDistance,\n\ttarget1.faceIndex = closestDistanceTriIndex;\n\n\tif ( target2 ) {\n\n\t\tif ( ! target2.point ) target2.point = tempTargetDest2.clone();\n\t\telse target2.point.copy( tempTargetDest2 );\n\t\ttarget2.point.applyMatrix4( tempMatrix );\n\t\ttempTargetDest1.applyMatrix4( tempMatrix );\n\t\ttarget2.distance = tempTargetDest1.sub( target2.point ).length();\n\t\ttarget2.faceIndex = closestDistanceOtherTriIndex;\n\n\t}\n\n\treturn target1;\n\n}\n\nexport { closestPointToGeometry };\n","import { UINT32_PER_NODE, BYTES_PER_NODE } from '../Constants.js';\nimport { IS_LEAF, OFFSET, COUNT, LEFT_NODE, RIGHT_NODE } from '../utils/nodeBufferUtils.js';\n\n/****************************************************/\n/* This file is generated from \"refit.template.js\". */\n/****************************************************/\n\nfunction refit_indirect( bvh, nodeIndices = null ) {\n\n\tif ( nodeIndices && Array.isArray( nodeIndices ) ) {\n\n\t\tnodeIndices = new Set( nodeIndices );\n\n\t}\n\n\tconst geometry = bvh.geometry;\n\tconst indexArr = geometry.index ? geometry.index.array : null;\n\tconst posAttr = geometry.attributes.position;\n\n\tlet buffer, uint32Array, uint16Array, float32Array;\n\tlet byteOffset = 0;\n\tconst roots = bvh._roots;\n\tfor ( let i = 0, l = roots.length; i < l; i ++ ) {\n\n\t\tbuffer = roots[ i ];\n\t\tuint32Array = new Uint32Array( buffer );\n\t\tuint16Array = new Uint16Array( buffer );\n\t\tfloat32Array = new Float32Array( buffer );\n\n\t\t_traverse( 0, byteOffset );\n\t\tbyteOffset += buffer.byteLength;\n\n\t}\n\n\tfunction _traverse( nodeIndex32, byteOffset, force = false ) {\n\n\t\tconst nodeIndex16 = nodeIndex32 * 2;\n\t\tif ( IS_LEAF( nodeIndex16, uint16Array ) ) {\n\n\t\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\n\t\t\tlet minx = Infinity;\n\t\t\tlet miny = Infinity;\n\t\t\tlet minz = Infinity;\n\t\t\tlet maxx = - Infinity;\n\t\t\tlet maxy = - Infinity;\n\t\t\tlet maxz = - Infinity;\n\n\t\t\tfor ( let i = offset, l = offset + count; i < l; i ++ ) {\n\n\t\t\t\tconst t = 3 * bvh.resolveTriangleIndex( i );\n\t\t\t\tfor ( let j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\tlet index = t + j;\n\t\t\t\t\tindex = indexArr ? indexArr[ index ] : index;\n\n\t\t\t\t\tconst x = posAttr.getX( index );\n\t\t\t\t\tconst y = posAttr.getY( index );\n\t\t\t\t\tconst z = posAttr.getZ( index );\n\n\t\t\t\t\tif ( x < minx ) minx = x;\n\t\t\t\t\tif ( x > maxx ) maxx = x;\n\n\t\t\t\t\tif ( y < miny ) miny = y;\n\t\t\t\t\tif ( y > maxy ) maxy = y;\n\n\t\t\t\t\tif ( z < minz ) minz = z;\n\t\t\t\t\tif ( z > maxz ) maxz = z;\n\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tif (\n\t\t\t\tfloat32Array[ nodeIndex32 + 0 ] !== minx ||\n\t\t\t\tfloat32Array[ nodeIndex32 + 1 ] !== miny ||\n\t\t\t\tfloat32Array[ nodeIndex32 + 2 ] !== minz ||\n\n\t\t\t\tfloat32Array[ nodeIndex32 + 3 ] !== maxx ||\n\t\t\t\tfloat32Array[ nodeIndex32 + 4 ] !== maxy ||\n\t\t\t\tfloat32Array[ nodeIndex32 + 5 ] !== maxz\n\t\t\t) {\n\n\t\t\t\tfloat32Array[ nodeIndex32 + 0 ] = minx;\n\t\t\t\tfloat32Array[ nodeIndex32 + 1 ] = miny;\n\t\t\t\tfloat32Array[ nodeIndex32 + 2 ] = minz;\n\n\t\t\t\tfloat32Array[ nodeIndex32 + 3 ] = maxx;\n\t\t\t\tfloat32Array[ nodeIndex32 + 4 ] = maxy;\n\t\t\t\tfloat32Array[ nodeIndex32 + 5 ] = maxz;\n\n\t\t\t\treturn true;\n\n\t\t\t} else {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tconst left = LEFT_NODE( nodeIndex32 );\n\t\t\tconst right = RIGHT_NODE( nodeIndex32, uint32Array );\n\n\t\t\t// the identifying node indices provided by the shapecast function include offsets of all\n\t\t\t// root buffers to guarantee they're unique between roots so offset left and right indices here.\n\t\t\tlet forceChildren = force;\n\t\t\tlet includesLeft = false;\n\t\t\tlet includesRight = false;\n\n\t\t\tif ( nodeIndices ) {\n\n\t\t\t\t// if we see that neither the left or right child are included in the set that need to be updated\n\t\t\t\t// then we assume that all children need to be updated.\n\t\t\t\tif ( ! forceChildren ) {\n\n\t\t\t\t\tconst leftNodeId = left / UINT32_PER_NODE + byteOffset / BYTES_PER_NODE;\n\t\t\t\t\tconst rightNodeId = right / UINT32_PER_NODE + byteOffset / BYTES_PER_NODE;\n\t\t\t\t\tincludesLeft = nodeIndices.has( leftNodeId );\n\t\t\t\t\tincludesRight = nodeIndices.has( rightNodeId );\n\t\t\t\t\tforceChildren = ! includesLeft && ! includesRight;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tincludesLeft = true;\n\t\t\t\tincludesRight = true;\n\n\t\t\t}\n\n\t\t\tconst traverseLeft = forceChildren || includesLeft;\n\t\t\tconst traverseRight = forceChildren || includesRight;\n\n\t\t\tlet leftChange = false;\n\t\t\tif ( traverseLeft ) {\n\n\t\t\t\tleftChange = _traverse( left, byteOffset, forceChildren );\n\n\t\t\t}\n\n\t\t\tlet rightChange = false;\n\t\t\tif ( traverseRight ) {\n\n\t\t\t\trightChange = _traverse( right, byteOffset, forceChildren );\n\n\t\t\t}\n\n\t\t\tconst didChange = leftChange || rightChange;\n\t\t\tif ( didChange ) {\n\n\t\t\t\tfor ( let i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\tconst left_i = left + i;\n\t\t\t\t\tconst right_i = right + i;\n\t\t\t\t\tconst minLeftValue = float32Array[ left_i ];\n\t\t\t\t\tconst maxLeftValue = float32Array[ left_i + 3 ];\n\t\t\t\t\tconst minRightValue = float32Array[ right_i ];\n\t\t\t\t\tconst maxRightValue = float32Array[ right_i + 3 ];\n\n\t\t\t\t\tfloat32Array[ nodeIndex32 + i ] = minLeftValue < minRightValue ? minLeftValue : minRightValue;\n\t\t\t\t\tfloat32Array[ nodeIndex32 + i + 3 ] = maxLeftValue > maxRightValue ? maxLeftValue : maxRightValue;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn didChange;\n\n\t\t}\n\n\t}\n\n}\n\nexport { refit_indirect };\n","import { intersectsNodeBounds } from '../utils/intersectUtils.js';\nimport { IS_LEAF, OFFSET, COUNT, LEFT_NODE, RIGHT_NODE } from '../utils/nodeBufferUtils.js';\nimport { BufferStack } from '../utils/BufferStack.js';\nimport '../utils/iterationUtils.generated.js';\nimport { intersectTris_indirect } from '../utils/iterationUtils_indirect.generated.js';\n\n/******************************************************/\n/* This file is generated from \"raycast.template.js\". */\n/******************************************************/\n\nfunction raycast_indirect( bvh, root, materialOrSide, ray, intersects, near, far ) {\n\n\tBufferStack.setBuffer( bvh._roots[ root ] );\n\t_raycast( 0, bvh, materialOrSide, ray, intersects, near, far );\n\tBufferStack.clearBuffer();\n\n}\n\nfunction _raycast( nodeIndex32, bvh, materialOrSide, ray, intersects, near, far ) {\n\n\tconst { float32Array, uint16Array, uint32Array } = BufferStack;\n\tconst nodeIndex16 = nodeIndex32 * 2;\n\tconst isLeaf = IS_LEAF( nodeIndex16, uint16Array );\n\tif ( isLeaf ) {\n\n\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\n\t\tintersectTris_indirect( bvh, materialOrSide, ray, offset, count, intersects, near, far );\n\n\n\t} else {\n\n\t\tconst leftIndex = LEFT_NODE( nodeIndex32 );\n\t\tif ( intersectsNodeBounds( leftIndex, float32Array, ray, near, far ) ) {\n\n\t\t\t_raycast( leftIndex, bvh, materialOrSide, ray, intersects, near, far );\n\n\t\t}\n\n\t\tconst rightIndex = RIGHT_NODE( nodeIndex32, uint32Array );\n\t\tif ( intersectsNodeBounds( rightIndex, float32Array, ray, near, far ) ) {\n\n\t\t\t_raycast( rightIndex, bvh, materialOrSide, ray, intersects, near, far );\n\n\t\t}\n\n\t}\n\n}\n\nexport { raycast_indirect };\n","import { IS_LEAF, OFFSET, COUNT, SPLIT_AXIS, LEFT_NODE, RIGHT_NODE } from '../utils/nodeBufferUtils.js';\nimport { BufferStack } from '../utils/BufferStack.js';\nimport { intersectsNodeBounds } from '../utils/intersectUtils.js';\nimport '../utils/iterationUtils.generated.js';\nimport { intersectClosestTri_indirect } from '../utils/iterationUtils_indirect.generated.js';\n\n/***********************************************************/\n/* This file is generated from \"raycastFirst.template.js\". */\n/***********************************************************/\n\nconst _xyzFields = [ 'x', 'y', 'z' ];\n\nfunction raycastFirst_indirect( bvh, root, materialOrSide, ray, near, far ) {\n\n\tBufferStack.setBuffer( bvh._roots[ root ] );\n\tconst result = _raycastFirst( 0, bvh, materialOrSide, ray, near, far );\n\tBufferStack.clearBuffer();\n\n\treturn result;\n\n}\n\nfunction _raycastFirst( nodeIndex32, bvh, materialOrSide, ray, near, far ) {\n\n\tconst { float32Array, uint16Array, uint32Array } = BufferStack;\n\tlet nodeIndex16 = nodeIndex32 * 2;\n\n\tconst isLeaf = IS_LEAF( nodeIndex16, uint16Array );\n\tif ( isLeaf ) {\n\n\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\n\t\treturn intersectClosestTri_indirect( bvh, materialOrSide, ray, offset, count, near, far );\n\n\n\t} else {\n\n\t\t// consider the position of the split plane with respect to the oncoming ray; whichever direction\n\t\t// the ray is coming from, look for an intersection among that side of the tree first\n\t\tconst splitAxis = SPLIT_AXIS( nodeIndex32, uint32Array );\n\t\tconst xyzAxis = _xyzFields[ splitAxis ];\n\t\tconst rayDir = ray.direction[ xyzAxis ];\n\t\tconst leftToRight = rayDir >= 0;\n\n\t\t// c1 is the child to check first\n\t\tlet c1, c2;\n\t\tif ( leftToRight ) {\n\n\t\t\tc1 = LEFT_NODE( nodeIndex32 );\n\t\t\tc2 = RIGHT_NODE( nodeIndex32, uint32Array );\n\n\t\t} else {\n\n\t\t\tc1 = RIGHT_NODE( nodeIndex32, uint32Array );\n\t\t\tc2 = LEFT_NODE( nodeIndex32 );\n\n\t\t}\n\n\t\tconst c1Intersection = intersectsNodeBounds( c1, float32Array, ray, near, far );\n\t\tconst c1Result = c1Intersection ? _raycastFirst( c1, bvh, materialOrSide, ray, near, far ) : null;\n\n\t\t// if we got an intersection in the first node and it's closer than the second node's bounding\n\t\t// box, we don't need to consider the second node because it couldn't possibly be a better result\n\t\tif ( c1Result ) {\n\n\t\t\t// check if the point is within the second bounds\n\t\t\t// \"point\" is in the local frame of the bvh\n\t\t\tconst point = c1Result.point[ xyzAxis ];\n\t\t\tconst isOutside = leftToRight ?\n\t\t\t\tpoint <= float32Array[ c2 + splitAxis ] : // min bounding data\n\t\t\t\tpoint >= float32Array[ c2 + splitAxis + 3 ]; // max bounding data\n\n\t\t\tif ( isOutside ) {\n\n\t\t\t\treturn c1Result;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// either there was no intersection in the first node, or there could still be a closer\n\t\t// intersection in the second, so check the second node and then take the better of the two\n\t\tconst c2Intersection = intersectsNodeBounds( c2, float32Array, ray, near, far );\n\t\tconst c2Result = c2Intersection ? _raycastFirst( c2, bvh, materialOrSide, ray, near, far ) : null;\n\n\t\tif ( c1Result && c2Result ) {\n\n\t\t\treturn c1Result.distance <= c2Result.distance ? c1Result : c2Result;\n\n\t\t} else {\n\n\t\t\treturn c1Result || c2Result || null;\n\n\t\t}\n\n\t}\n\n}\n\nexport { raycastFirst_indirect };\n","import { Box3, Matrix4 } from 'three';\nimport { OrientedBox } from '../../math/OrientedBox.js';\nimport { ExtendedTriangle } from '../../math/ExtendedTriangle.js';\nimport { setTriangle } from '../../utils/TriangleUtilities.js';\nimport { arrayToBox } from '../../utils/ArrayBoxUtilities.js';\nimport { IS_LEAF, OFFSET, COUNT, BOUNDING_DATA_INDEX, LEFT_NODE, RIGHT_NODE } from '../utils/nodeBufferUtils.js';\nimport { BufferStack } from '../utils/BufferStack.js';\nimport { getTriCount } from '../build/geometryUtils.js';\n\n/*****************************************************************/\n/* This file is generated from \"intersectsGeometry.template.js\". */\n/*****************************************************************/\n/* eslint-disable indent */\n\nconst boundingBox = /* @__PURE__ */ new Box3();\nconst triangle = /* @__PURE__ */ new ExtendedTriangle();\nconst triangle2 = /* @__PURE__ */ new ExtendedTriangle();\nconst invertedMat = /* @__PURE__ */ new Matrix4();\n\nconst obb = /* @__PURE__ */ new OrientedBox();\nconst obb2 = /* @__PURE__ */ new OrientedBox();\n\nfunction intersectsGeometry_indirect( bvh, root, otherGeometry, geometryToBvh ) {\n\n\tBufferStack.setBuffer( bvh._roots[ root ] );\n\tconst result = _intersectsGeometry( 0, bvh, otherGeometry, geometryToBvh );\n\tBufferStack.clearBuffer();\n\n\treturn result;\n\n}\n\nfunction _intersectsGeometry( nodeIndex32, bvh, otherGeometry, geometryToBvh, cachedObb = null ) {\n\n\tconst { float32Array, uint16Array, uint32Array } = BufferStack;\n\tlet nodeIndex16 = nodeIndex32 * 2;\n\n\tif ( cachedObb === null ) {\n\n\t\tif ( ! otherGeometry.boundingBox ) {\n\n\t\t\totherGeometry.computeBoundingBox();\n\n\t\t}\n\n\t\tobb.set( otherGeometry.boundingBox.min, otherGeometry.boundingBox.max, geometryToBvh );\n\t\tcachedObb = obb;\n\n\t}\n\n\tconst isLeaf = IS_LEAF( nodeIndex16, uint16Array );\n\tif ( isLeaf ) {\n\n\t\tconst thisGeometry = bvh.geometry;\n\t\tconst thisIndex = thisGeometry.index;\n\t\tconst thisPos = thisGeometry.attributes.position;\n\n\t\tconst otherIndex = otherGeometry.index;\n\t\tconst otherPos = otherGeometry.attributes.position;\n\n\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\n\t\t// get the inverse of the geometry matrix so we can transform our triangles into the\n\t\t// geometry space we're trying to test. We assume there are fewer triangles being checked\n\t\t// here.\n\t\tinvertedMat.copy( geometryToBvh ).invert();\n\n\t\tif ( otherGeometry.boundsTree ) {\n\n\t\t\t// if there's a bounds tree\n\t\t\tarrayToBox( BOUNDING_DATA_INDEX( nodeIndex32 ), float32Array, obb2 );\n\t\t\tobb2.matrix.copy( invertedMat );\n\t\t\tobb2.needsUpdate = true;\n\n\t\t\t// TODO: use a triangle iteration function here\n\t\t\tconst res = otherGeometry.boundsTree.shapecast( {\n\n\t\t\t\tintersectsBounds: box => obb2.intersectsBox( box ),\n\n\t\t\t\tintersectsTriangle: tri => {\n\n\t\t\t\t\ttri.a.applyMatrix4( geometryToBvh );\n\t\t\t\t\ttri.b.applyMatrix4( geometryToBvh );\n\t\t\t\t\ttri.c.applyMatrix4( geometryToBvh );\n\t\t\t\t\ttri.needsUpdate = true;\n\n\t\t\t\t\tfor ( let i = offset, l = count + offset; i < l; i ++ ) {\n\n\t\t\t\t\t\t// this triangle needs to be transformed into the current BVH coordinate frame\n\t\t\t\t\t\tsetTriangle( triangle2, 3 * bvh.resolveTriangleIndex( i ), thisIndex, thisPos );\n\t\t\t\t\t\ttriangle2.needsUpdate = true;\n\t\t\t\t\t\tif ( tri.intersectsTriangle( triangle2 ) ) {\n\n\t\t\t\t\t\t\treturn true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t\treturn res;\n\n\t\t} else {\n\n\t\t\t// if we're just dealing with raw geometry\n\t\t\tconst otherTriangleCount = getTriCount( otherGeometry );\n\n\t\t\tfor ( let i = offset, l = count + offset; i < l; i ++ ) {\n\n\t\t\t\t// this triangle needs to be transformed into the current BVH coordinate frame\n\t\t\t\tconst ti = bvh.resolveTriangleIndex( i );\n\t\t\t\tsetTriangle( triangle, 3 * ti, thisIndex, thisPos );\n\n\n\t\t\t\ttriangle.a.applyMatrix4( invertedMat );\n\t\t\t\ttriangle.b.applyMatrix4( invertedMat );\n\t\t\t\ttriangle.c.applyMatrix4( invertedMat );\n\t\t\t\ttriangle.needsUpdate = true;\n\n\t\t\t\tfor ( let i2 = 0, l2 = otherTriangleCount * 3; i2 < l2; i2 += 3 ) {\n\n\t\t\t\t\tsetTriangle( triangle2, i2, otherIndex, otherPos );\n\t\t\t\t\ttriangle2.needsUpdate = true;\n\n\t\t\t\t\tif ( triangle.intersectsTriangle( triangle2 ) ) {\n\n\t\t\t\t\t\treturn true;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t}\n\n\t} else {\n\n\t\tconst left = LEFT_NODE( nodeIndex32 );\n\t\tconst right = RIGHT_NODE( nodeIndex32, uint32Array );\n\n\t\tarrayToBox( BOUNDING_DATA_INDEX( left ), float32Array, boundingBox );\n\t\tconst leftIntersection =\n\t\t\tcachedObb.intersectsBox( boundingBox ) &&\n\t\t\t_intersectsGeometry( left, bvh, otherGeometry, geometryToBvh, cachedObb );\n\n\t\tif ( leftIntersection ) return true;\n\n\t\tarrayToBox( BOUNDING_DATA_INDEX( right ), float32Array, boundingBox );\n\t\tconst rightIntersection =\n\t\t\tcachedObb.intersectsBox( boundingBox ) &&\n\t\t\t_intersectsGeometry( right, bvh, otherGeometry, geometryToBvh, cachedObb );\n\n\t\tif ( rightIntersection ) return true;\n\n\t\treturn false;\n\n\t}\n\n}\n\nexport { intersectsGeometry_indirect };\n","import { Matrix4, Vector3 } from 'three';\nimport { OrientedBox } from '../../math/OrientedBox.js';\nimport { setTriangle } from '../../utils/TriangleUtilities.js';\nimport { getTriCount } from '../build/geometryUtils.js';\nimport { ExtendedTrianglePool } from '../../utils/ExtendedTrianglePool.js';\n\n/*********************************************************************/\n/* This file is generated from \"closestPointToGeometry.template.js\". */\n/*********************************************************************/\n\nconst tempMatrix = /* @__PURE__ */ new Matrix4();\nconst obb = /* @__PURE__ */ new OrientedBox();\nconst obb2 = /* @__PURE__ */ new OrientedBox();\nconst temp1 = /* @__PURE__ */ new Vector3();\nconst temp2 = /* @__PURE__ */ new Vector3();\nconst temp3 = /* @__PURE__ */ new Vector3();\nconst temp4 = /* @__PURE__ */ new Vector3();\n\nfunction closestPointToGeometry_indirect(\n\tbvh,\n\totherGeometry,\n\tgeometryToBvh,\n\ttarget1 = { },\n\ttarget2 = { },\n\tminThreshold = 0,\n\tmaxThreshold = Infinity,\n) {\n\n\tif ( ! otherGeometry.boundingBox ) {\n\n\t\totherGeometry.computeBoundingBox();\n\n\t}\n\n\tobb.set( otherGeometry.boundingBox.min, otherGeometry.boundingBox.max, geometryToBvh );\n\tobb.needsUpdate = true;\n\n\tconst geometry = bvh.geometry;\n\tconst pos = geometry.attributes.position;\n\tconst index = geometry.index;\n\tconst otherPos = otherGeometry.attributes.position;\n\tconst otherIndex = otherGeometry.index;\n\tconst triangle = ExtendedTrianglePool.getPrimitive();\n\tconst triangle2 = ExtendedTrianglePool.getPrimitive();\n\n\tlet tempTarget1 = temp1;\n\tlet tempTargetDest1 = temp2;\n\tlet tempTarget2 = null;\n\tlet tempTargetDest2 = null;\n\n\tif ( target2 ) {\n\n\t\ttempTarget2 = temp3;\n\t\ttempTargetDest2 = temp4;\n\n\t}\n\n\tlet closestDistance = Infinity;\n\tlet closestDistanceTriIndex = null;\n\tlet closestDistanceOtherTriIndex = null;\n\ttempMatrix.copy( geometryToBvh ).invert();\n\tobb2.matrix.copy( tempMatrix );\n\tbvh.shapecast(\n\t\t{\n\n\t\t\tboundsTraverseOrder: box => {\n\n\t\t\t\treturn obb.distanceToBox( box );\n\n\t\t\t},\n\n\t\t\tintersectsBounds: ( box, isLeaf, score ) => {\n\n\t\t\t\tif ( score < closestDistance && score < maxThreshold ) {\n\n\t\t\t\t\t// if we know the triangles of this bounds will be intersected next then\n\t\t\t\t\t// save the bounds to use during triangle checks.\n\t\t\t\t\tif ( isLeaf ) {\n\n\t\t\t\t\t\tobb2.min.copy( box.min );\n\t\t\t\t\t\tobb2.max.copy( box.max );\n\t\t\t\t\t\tobb2.needsUpdate = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\n\t\t\t},\n\n\t\t\tintersectsRange: ( offset, count ) => {\n\n\t\t\t\tif ( otherGeometry.boundsTree ) {\n\n\t\t\t\t\t// if the other geometry has a bvh then use the accelerated path where we use shapecast to find\n\t\t\t\t\t// the closest bounds in the other geometry to check.\n\t\t\t\t\tconst otherBvh = otherGeometry.boundsTree;\n\t\t\t\t\treturn otherBvh.shapecast( {\n\t\t\t\t\t\tboundsTraverseOrder: box => {\n\n\t\t\t\t\t\t\treturn obb2.distanceToBox( box );\n\n\t\t\t\t\t\t},\n\n\t\t\t\t\t\tintersectsBounds: ( box, isLeaf, score ) => {\n\n\t\t\t\t\t\t\treturn score < closestDistance && score < maxThreshold;\n\n\t\t\t\t\t\t},\n\n\t\t\t\t\t\tintersectsRange: ( otherOffset, otherCount ) => {\n\n\t\t\t\t\t\t\tfor ( let i2 = otherOffset, l2 = otherOffset + otherCount; i2 < l2; i2 ++ ) {\n\n\t\t\t\t\t\t\t\tconst ti2 = otherBvh.resolveTriangleIndex( i2 );\n\t\t\t\t\t\t\t\tsetTriangle( triangle2, 3 * ti2, otherIndex, otherPos );\n\n\t\t\t\t\t\t\t\ttriangle2.a.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\t\t\ttriangle2.b.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\t\t\ttriangle2.c.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\t\t\ttriangle2.needsUpdate = true;\n\n\t\t\t\t\t\t\t\tfor ( let i = offset, l = offset + count; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tconst ti = bvh.resolveTriangleIndex( i );\n\t\t\t\t\t\t\t\t\tsetTriangle( triangle, 3 * ti, index, pos );\n\n\t\t\t\t\t\t\t\t\ttriangle.needsUpdate = true;\n\n\t\t\t\t\t\t\t\t\tconst dist = triangle.distanceToTriangle( triangle2, tempTarget1, tempTarget2 );\n\t\t\t\t\t\t\t\t\tif ( dist < closestDistance ) {\n\n\t\t\t\t\t\t\t\t\t\ttempTargetDest1.copy( tempTarget1 );\n\n\t\t\t\t\t\t\t\t\t\tif ( tempTargetDest2 ) {\n\n\t\t\t\t\t\t\t\t\t\t\ttempTargetDest2.copy( tempTarget2 );\n\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tclosestDistance = dist;\n\t\t\t\t\t\t\t\t\t\tclosestDistanceTriIndex = i;\n\t\t\t\t\t\t\t\t\t\tclosestDistanceOtherTriIndex = i2;\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// stop traversal if we find a point that's under the given threshold\n\t\t\t\t\t\t\t\t\tif ( dist < minThreshold ) {\n\n\t\t\t\t\t\t\t\t\t\treturn true;\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t},\n\t\t\t\t\t} );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// If no bounds tree then we'll just check every triangle.\n\t\t\t\t\tconst triCount = getTriCount( otherGeometry );\n\t\t\t\t\tfor ( let i2 = 0, l2 = triCount; i2 < l2; i2 ++ ) {\n\n\t\t\t\t\t\tsetTriangle( triangle2, 3 * i2, otherIndex, otherPos );\n\t\t\t\t\t\ttriangle2.a.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\ttriangle2.b.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\ttriangle2.c.applyMatrix4( geometryToBvh );\n\t\t\t\t\t\ttriangle2.needsUpdate = true;\n\n\t\t\t\t\t\tfor ( let i = offset, l = offset + count; i < l; i ++ ) {\n\n\t\t\t\t\t\t\tconst ti = bvh.resolveTriangleIndex( i );\n\t\t\t\t\t\t\tsetTriangle( triangle, 3 * ti, index, pos );\n\n\t\t\t\t\t\t\ttriangle.needsUpdate = true;\n\n\t\t\t\t\t\t\tconst dist = triangle.distanceToTriangle( triangle2, tempTarget1, tempTarget2 );\n\t\t\t\t\t\t\tif ( dist < closestDistance ) {\n\n\t\t\t\t\t\t\t\ttempTargetDest1.copy( tempTarget1 );\n\n\t\t\t\t\t\t\t\tif ( tempTargetDest2 ) {\n\n\t\t\t\t\t\t\t\t\ttempTargetDest2.copy( tempTarget2 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tclosestDistance = dist;\n\t\t\t\t\t\t\t\tclosestDistanceTriIndex = i;\n\t\t\t\t\t\t\t\tclosestDistanceOtherTriIndex = i2;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// stop traversal if we find a point that's under the given threshold\n\t\t\t\t\t\t\tif ( dist < minThreshold ) {\n\n\t\t\t\t\t\t\t\treturn true;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t}\n\n\t);\n\n\tExtendedTrianglePool.releasePrimitive( triangle );\n\tExtendedTrianglePool.releasePrimitive( triangle2 );\n\n\tif ( closestDistance === Infinity ) {\n\n\t\treturn null;\n\n\t}\n\n\tif ( ! target1.point ) {\n\n\t\ttarget1.point = tempTargetDest1.clone();\n\n\t} else {\n\n\t\ttarget1.point.copy( tempTargetDest1 );\n\n\t}\n\n\ttarget1.distance = closestDistance,\n\ttarget1.faceIndex = closestDistanceTriIndex;\n\n\tif ( target2 ) {\n\n\t\tif ( ! target2.point ) target2.point = tempTargetDest2.clone();\n\t\telse target2.point.copy( tempTargetDest2 );\n\t\ttarget2.point.applyMatrix4( tempMatrix );\n\t\ttempTargetDest1.applyMatrix4( tempMatrix );\n\t\ttarget2.distance = tempTargetDest1.sub( target2.point ).length();\n\t\ttarget2.faceIndex = closestDistanceOtherTriIndex;\n\n\t}\n\n\treturn target1;\n\n}\n\nexport { closestPointToGeometry_indirect };\n","// converts the given BVH raycast intersection to align with the three.js raycast\n// structure (include object, world space distance and point).\nexport function convertRaycastIntersect( hit, object, raycaster ) {\n\n\tif ( hit === null ) {\n\n\t\treturn null;\n\n\t}\n\n\thit.point.applyMatrix4( object.matrixWorld );\n\thit.distance = hit.point.distanceTo( raycaster.ray.origin );\n\thit.object = object;\n\n\treturn hit;\n\n}\n","/** @import { BufferGeometry, Sphere, Box3, Intersection, Material, Object3D, Raycaster } from 'three' */\n/** @import { ExtendedTriangle } from '../math/ExtendedTriangle.js' */\n/** @import { IntersectsBoundsCallback, IntersectsRangeCallback, BoundsTraverseOrderCallback, IntersectsRangesCallback } from './BVH.js' */\nimport { BufferAttribute, FrontSide, Ray, Vector3, Matrix4 } from 'three';\nimport { SKIP_GENERATION, BYTES_PER_NODE, UINT32_PER_NODE, FLOAT32_EPSILON } from './Constants.js';\nimport { OrientedBox } from '../math/OrientedBox.js';\nimport { ExtendedTrianglePool } from '../utils/ExtendedTrianglePool.js';\nimport { closestPointToPoint } from './cast/closestPointToPoint.js';\nimport { IS_LEAF } from './utils/nodeBufferUtils.js';\n\nimport { iterateOverTriangles } from './utils/iterationUtils.generated.js';\nimport { refit } from './cast/refit.generated.js';\nimport { raycast } from './cast/raycast.generated.js';\nimport { raycastFirst } from './cast/raycastFirst.generated.js';\nimport { intersectsGeometry } from './cast/intersectsGeometry.generated.js';\nimport { closestPointToGeometry } from './cast/closestPointToGeometry.generated.js';\n\nimport { iterateOverTriangles_indirect } from './utils/iterationUtils_indirect.generated.js';\nimport { refit_indirect } from './cast/refit_indirect.generated.js';\nimport { raycast_indirect } from './cast/raycast_indirect.generated.js';\nimport { raycastFirst_indirect } from './cast/raycastFirst_indirect.generated.js';\nimport { intersectsGeometry_indirect } from './cast/intersectsGeometry_indirect.generated.js';\nimport { closestPointToGeometry_indirect } from './cast/closestPointToGeometry_indirect.generated.js';\nimport { setTriangle } from '../utils/TriangleUtilities.js';\nimport { convertRaycastIntersect } from '../utils/GeometryRayIntersectUtilities.js';\nimport { GeometryBVH } from './GeometryBVH.js';\n\nconst _obb = /* @__PURE__ */ new OrientedBox();\nconst _ray = /* @__PURE__ */ new Ray();\nconst _direction = /* @__PURE__ */ new Vector3();\nconst _inverseMatrix = /* @__PURE__ */ new Matrix4();\nconst _worldScale = /* @__PURE__ */ new Vector3();\nconst _getters = [ 'getX', 'getY', 'getZ' ];\n\n/**\n * @callback IntersectsTriangleCallback\n * @param {ExtendedTriangle} triangle - The triangle primitive in local space.\n * @param {number} triangleIndex - The index of the triangle in the geometry.\n * @param {boolean} contained - Whether the node bounds are fully contained by the query shape.\n * @param {number} depth - The depth of the node in the tree.\n * @returns {boolean} Return `true` to stop traversal.\n */\n\n/**\n * @callback IntersectsTrianglesCallback\n * @param {ExtendedTriangle} triangle1 - Triangle from this BVH in local space.\n * @param {ExtendedTriangle} triangle2 - Triangle from `otherBvh`, transformed into local space.\n * @param {number} triangleIndex1 - Triangle index in the first geometry.\n * @param {number} triangleIndex2 - Triangle index in the second geometry.\n * @param {number} depth1 - Depth of the node in the first BVH.\n * @param {number} nodeIndex1 - Node index in the first BVH.\n * @param {number} depth2 - Depth of the node in the second BVH.\n * @param {number} nodeIndex2 - Node index in the second BVH.\n * @returns {boolean} Return `true` to stop traversal.\n */\n\n/**\n * Plain-object representation of a `MeshBVH` produced by `MeshBVH.serialize` and\n * consumed by `MeshBVH.deserialize`. Suitable for transfer across WebWorker boundaries\n * or storage, with optional buffer sharing via `SharedArrayBuffer`.\n *\n * @typedef {Object} SerializedBVH\n * @property {Array<ArrayBuffer>} roots - BVH root node buffers.\n * @property {Int32Array|Uint32Array|Uint16Array|null} index - Serialized geometry index buffer.\n * @property {Uint32Array|Uint16Array|null} indirectBuffer - Indirect primitive index buffer, or `null`\n * if the BVH was not built in indirect mode.\n */\n\n/**\n * @typedef {Object} HitPointInfo\n * @property {Vector3} point - The closest point on the mesh surface.\n * @property {number} distance - Distance from the query point to the closest point.\n * @property {number} faceIndex - Index of the triangle containing the closest point. Can be\n * passed to `getTriangleHitPointInfo` to retrieve UV, normal, and material index.\n */\n\n/**\n * The MeshBVH generation process modifies the geometry's index bufferAttribute in place to save\n * memory. The BVH construction will use the geometry's boundingBox if it exists or set it if it\n * does not. The BVH will no longer work correctly if the index buffer is modified.\n *\n * Only triangles within the geometry's draw range (or provided `range` option) are included in the\n * BVH. When a geometry has multiple groups, only triangles within the defined group ranges are\n * included. Triangles in gaps between groups are excluded.\n *\n * Note that all query functions expect arguments in local space of the BVH and return results in\n * local space, as well. If world space results are needed they must be transformed into world space\n * using `object.matrixWorld`.\n *\n * @param {BufferGeometry} geometry\n * @param {Object} [options] - Same options as {@link GeometryBVH}.\n * @extends GeometryBVH\n */\nexport class MeshBVH extends GeometryBVH {\n\n\t/**\n\t * Generates a representation of the complete bounds tree and the geometry index buffer which\n\t * can be used to recreate a bounds tree using the `deserialize` function. The `serialize` and\n\t * `deserialize` functions can be used to generate a MeshBVH asynchronously in a background web\n\t * worker to prevent the main thread from stuttering. The BVH roots buffer stored in the\n\t * serialized representation are the same as the ones used by the original BVH so they should\n\t * not be modified. If `SharedArrayBuffers` are used then the same BVH memory can be used for\n\t * multiple BVH in multiple WebWorkers.\n\t *\n\t * @static\n\t * @param {MeshBVH} bvh - The BVH to serialize.\n\t * @param {Object} [options]\n\t * @param {boolean} [options.cloneBuffers=true] - If `true`, the index and BVH root buffers\n\t * are cloned so the serialized data is independent of the live BVH.\n\t * @returns {SerializedBVH}\n\t */\n\tstatic serialize( bvh, options = {} ) {\n\n\t\toptions = {\n\t\t\tcloneBuffers: true,\n\t\t\t...options,\n\t\t};\n\n\t\tconst geometry = bvh.geometry;\n\t\tconst rootData = bvh._roots;\n\t\tconst indirectBuffer = bvh._indirectBuffer;\n\t\tconst indexAttribute = geometry.getIndex();\n\t\tconst result = {\n\t\t\tversion: 1,\n\t\t\troots: null,\n\t\t\tindex: null,\n\t\t\tindirectBuffer: null,\n\t\t};\n\t\tif ( options.cloneBuffers ) {\n\n\t\t\tresult.roots = rootData.map( root => root.slice() );\n\t\t\tresult.index = indexAttribute ? indexAttribute.array.slice() : null;\n\t\t\tresult.indirectBuffer = indirectBuffer ? indirectBuffer.slice() : null;\n\n\t\t} else {\n\n\t\t\tresult.roots = rootData;\n\t\t\tresult.index = indexAttribute ? indexAttribute.array : null;\n\t\t\tresult.indirectBuffer = indirectBuffer;\n\n\t\t}\n\n\t\treturn result;\n\n\t}\n\n\t/**\n\t * Returns a new MeshBVH instance from the serialized data. `geometry` is the geometry used\n\t * to generate the original BVH `data` was derived from. The root buffers stored in `data`\n\t * are set directly on the new BVH so the memory is shared.\n\t *\n\t * @static\n\t * @param {SerializedBVH} data - Serialized BVH data.\n\t * @param {BufferGeometry} geometry - The geometry the BVH was originally built from.\n\t * @param {Object} [options]\n\t * @param {boolean} [options.setIndex=true] - If `true`, sets `geometry.index` from the\n\t * serialized index buffer (creating one if none exists).\n\t * @returns {MeshBVH}\n\t */\n\tstatic deserialize( data, geometry, options = {} ) {\n\n\t\toptions = {\n\t\t\tsetIndex: true,\n\t\t\tindirect: Boolean( data.indirectBuffer ),\n\t\t\t...options,\n\t\t};\n\n\t\tconst { index, roots, indirectBuffer } = data;\n\n\t\t// handle backwards compatibility by fixing up the buffer roots\n\t\t// see issue gkjohnson/three-mesh-bvh#759\n\t\tif ( ! data.version ) {\n\n\t\t\tconsole.warn(\n\t\t\t\t'MeshBVH.deserialize: Serialization format has been changed and will be fixed up. ' +\n\t\t\t\t'It is recommended to regenerate any stored serialized data.'\n\t\t\t);\n\t\t\tfixupVersion0( roots );\n\n\t\t}\n\n\t\tconst bvh = new MeshBVH( geometry, { ...options, [ SKIP_GENERATION ]: true } );\n\t\tbvh._roots = roots;\n\t\tbvh._indirectBuffer = indirectBuffer || null;\n\n\t\tif ( options.setIndex ) {\n\n\t\t\tconst indexAttribute = geometry.getIndex();\n\t\t\tif ( indexAttribute === null ) {\n\n\t\t\t\tconst newIndex = new BufferAttribute( data.index, 1, false );\n\t\t\t\tgeometry.setIndex( newIndex );\n\n\t\t\t} else if ( indexAttribute.array !== index ) {\n\n\t\t\t\tindexAttribute.array.set( index );\n\t\t\t\tindexAttribute.needsUpdate = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn bvh;\n\n\t\t// convert version 0 serialized data (uint32 indices) to version 1 (node indices)\n\t\tfunction fixupVersion0( roots ) {\n\n\t\t\tfor ( let rootIndex = 0; rootIndex < roots.length; rootIndex ++ ) {\n\n\t\t\t\tconst root = roots[ rootIndex ];\n\t\t\t\tconst uint32Array = new Uint32Array( root );\n\t\t\t\tconst uint16Array = new Uint16Array( root );\n\n\t\t\t\t// iterate over nodes and convert right child offsets\n\t\t\t\tfor ( let node = 0, l = root.byteLength / BYTES_PER_NODE; node < l; node ++ ) {\n\n\t\t\t\t\tconst node32Index = UINT32_PER_NODE * node;\n\t\t\t\t\tconst node16Index = 2 * node32Index;\n\t\t\t\t\tif ( ! IS_LEAF( node16Index, uint16Array ) ) {\n\n\t\t\t\t\t\t// convert absolute right child offset to relative offset\n\t\t\t\t\t\tuint32Array[ node32Index + 6 ] = uint32Array[ node32Index + 6 ] / UINT32_PER_NODE - node;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tget primitiveStride() {\n\n\t\treturn 3;\n\n\t}\n\n\t/**\n\t * Helper function for use when `indirect` is set to true. This function takes a triangle\n\t * index in the BVH layout and returns the associated triangle index in the geometry index\n\t * buffer or position attribute.\n\t * @type {function(number): number}\n\t * @readonly\n\t */\n\tget resolveTriangleIndex() {\n\n\t\treturn this.resolvePrimitiveIndex;\n\n\t}\n\n\tconstructor( geometry, options = {} ) {\n\n\t\tif ( options.maxLeafTris ) {\n\n\t\t\tconsole.warn( 'MeshBVH: \"maxLeafTris\" option has been deprecated. Use \"targetLeafSize\", instead.' );\n\t\t\toptions = {\n\t\t\t\t...options,\n\t\t\t\ttargetLeafSize: options.maxLeafTris,\n\t\t\t};\n\n\t\t}\n\n\t\tsuper( geometry, options );\n\n\t}\n\n\t/**\n\t * Adjusts all triangle offsets stored in the BVH by the given offset. This is useful when the\n\t * triangle data has been compacted or shifted in the geometry buffers (e.g. in `BatchedMesh`\n\t * when geometries are compacted using the 'optimize' function or constructing a 'merged' BVH).\n\t * This function only adjusts the BVH to point to different triangles in the geometry. The\n\t * geometry's index buffer and/or position attributes must be updated separately to match.\n\t *\n\t * @param {number} offset\n\t * @returns {void}\n\t */\n\t// implement abstract methods from BVH base class\n\tshiftTriangleOffsets( offset ) {\n\n\t\treturn super.shiftPrimitiveOffsets( offset );\n\n\t}\n\n\t// write primitive bounds to the buffer - used only for validateBounds at the moment\n\twritePrimitiveBounds( i, targetBuffer, baseIndex ) {\n\n\t\tconst geometry = this.geometry;\n\t\tconst indirectBuffer = this._indirectBuffer;\n\t\tconst posAttr = geometry.attributes.position;\n\t\tconst index = geometry.index ? geometry.index.array : null;\n\n\t\tconst tri = indirectBuffer ? indirectBuffer[ i ] : i;\n\t\tconst tri3 = tri * 3;\n\n\t\tlet ai = tri3 + 0;\n\t\tlet bi = tri3 + 1;\n\t\tlet ci = tri3 + 2;\n\n\t\tif ( index ) {\n\n\t\t\tai = index[ ai ];\n\t\t\tbi = index[ bi ];\n\t\t\tci = index[ ci ];\n\n\t\t}\n\n\t\tfor ( let el = 0; el < 3; el ++ ) {\n\n\t\t\tconst a = posAttr[ _getters[ el ] ]( ai );\n\t\t\tconst b = posAttr[ _getters[ el ] ]( bi );\n\t\t\tconst c = posAttr[ _getters[ el ] ]( ci );\n\n\t\t\tlet min = a;\n\t\t\tif ( b < min ) min = b;\n\t\t\tif ( c < min ) min = c;\n\n\t\t\tlet max = a;\n\t\t\tif ( b > max ) max = b;\n\t\t\tif ( c > max ) max = c;\n\n\t\t\t// Write in min/max format [minx, miny, minz, maxx, maxy, maxz]\n\t\t\ttargetBuffer[ baseIndex + el ] = min;\n\t\t\ttargetBuffer[ baseIndex + el + 3 ] = max;\n\n\t\t}\n\n\t\treturn targetBuffer;\n\n\t}\n\n\t// precomputes the bounding box for each triangle; required for quickly calculating tree splits.\n\t// result is an array of size count * 6 where triangle i maps to a\n\t// [x_center, x_delta, y_center, y_delta, z_center, z_delta] tuple starting at index (i - offset) * 6,\n\t// representing the center and half-extent in each dimension of triangle i\n\tcomputePrimitiveBounds( offset, count, targetBuffer ) {\n\n\t\tconst geometry = this.geometry;\n\t\tconst indirectBuffer = this._indirectBuffer;\n\t\tconst posAttr = geometry.attributes.position;\n\t\tconst index = geometry.index ? geometry.index.array : null;\n\t\tconst normalized = posAttr.normalized;\n\n\t\tif ( offset < 0 || count + offset - targetBuffer.offset > targetBuffer.length / 6 ) {\n\n\t\t\tthrow new Error( 'MeshBVH: compute triangle bounds range is invalid.' );\n\n\t\t}\n\n\t\t// used for non-normalized positions\n\t\tconst posArr = posAttr.array;\n\n\t\t// support for an interleaved position buffer\n\t\tconst bufferOffset = posAttr.offset || 0;\n\t\tlet stride = 3;\n\t\tif ( posAttr.isInterleavedBufferAttribute ) {\n\n\t\t\tstride = posAttr.data.stride;\n\n\t\t}\n\n\t\t// used for normalized positions\n\t\tconst getters = [ 'getX', 'getY', 'getZ' ];\n\t\tconst writeOffset = targetBuffer.offset;\n\n\t\t// iterate over the triangle range\n\t\tfor ( let i = offset, l = offset + count; i < l; i ++ ) {\n\n\t\t\tconst tri = indirectBuffer ? indirectBuffer[ i ] : i;\n\t\t\tconst tri3 = tri * 3;\n\t\t\tconst boundsIndexOffset = ( i - writeOffset ) * 6;\n\n\t\t\tlet ai = tri3 + 0;\n\t\t\tlet bi = tri3 + 1;\n\t\t\tlet ci = tri3 + 2;\n\n\t\t\tif ( index ) {\n\n\t\t\t\tai = index[ ai ];\n\t\t\t\tbi = index[ bi ];\n\t\t\t\tci = index[ ci ];\n\n\t\t\t}\n\n\t\t\t// we add the stride and offset here since we access the array directly\n\t\t\t// below for the sake of performance\n\t\t\tif ( ! normalized ) {\n\n\t\t\t\tai = ai * stride + bufferOffset;\n\t\t\t\tbi = bi * stride + bufferOffset;\n\t\t\t\tci = ci * stride + bufferOffset;\n\n\t\t\t}\n\n\t\t\tfor ( let el = 0; el < 3; el ++ ) {\n\n\t\t\t\tlet a, b, c;\n\n\t\t\t\tif ( normalized ) {\n\n\t\t\t\t\ta = posAttr[ getters[ el ] ]( ai );\n\t\t\t\t\tb = posAttr[ getters[ el ] ]( bi );\n\t\t\t\t\tc = posAttr[ getters[ el ] ]( ci );\n\n\t\t\t\t} else {\n\n\t\t\t\t\ta = posArr[ ai + el ];\n\t\t\t\t\tb = posArr[ bi + el ];\n\t\t\t\t\tc = posArr[ ci + el ];\n\n\t\t\t\t}\n\n\t\t\t\tlet min = a;\n\t\t\t\tif ( b < min ) min = b;\n\t\t\t\tif ( c < min ) min = c;\n\n\t\t\t\tlet max = a;\n\t\t\t\tif ( b > max ) max = b;\n\t\t\t\tif ( c > max ) max = c;\n\n\t\t\t\t// Increase the bounds size by float32 epsilon to avoid precision errors when\n\t\t\t\t// converting to 32 bit float. Scale the epsilon by the size of the numbers being\n\t\t\t\t// worked with.\n\t\t\t\tconst halfExtents = ( max - min ) / 2;\n\t\t\t\tconst el2 = el * 2;\n\t\t\t\ttargetBuffer[ boundsIndexOffset + el2 + 0 ] = min + halfExtents;\n\t\t\t\ttargetBuffer[ boundsIndexOffset + el2 + 1 ] = halfExtents + ( Math.abs( min ) + halfExtents ) * FLOAT32_EPSILON;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn targetBuffer;\n\n\t}\n\n\t/**\n\t * A convenience function for performing a raycast based on a mesh. Results are formed like\n\t * three.js raycast results in world frame.\n\t *\n\t * @param {Object3D} object\n\t * @param {Raycaster} raycaster\n\t * @param {Array<Intersection>} [intersects=[]]\n\t * @returns {Array<Intersection>}\n\t */\n\traycastObject3D( object, raycaster, intersects = [] ) {\n\n\t\tconst { material } = object;\n\t\tif ( material === undefined ) {\n\n\t\t\treturn;\n\n\t\t}\n\n\t\t_inverseMatrix.copy( object.matrixWorld ).invert();\n\t\t_ray.copy( raycaster.ray ).applyMatrix4( _inverseMatrix );\n\n\t\t_worldScale.setFromMatrixScale( object.matrixWorld );\n\t\t_direction.copy( _ray.direction ).multiply( _worldScale );\n\n\t\tconst scaleFactor = _direction.length();\n\t\tconst near = raycaster.near / scaleFactor;\n\t\tconst far = raycaster.far / scaleFactor;\n\n\t\tif ( raycaster.firstHitOnly === true ) {\n\n\t\t\tlet hit = this.raycastFirst( _ray, material, near, far );\n\t\t\thit = convertRaycastIntersect( hit, object, raycaster );\n\t\t\tif ( hit ) {\n\n\t\t\t\tintersects.push( hit );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tconst hits = this.raycast( _ray, material, near, far );\n\t\t\tfor ( let i = 0, l = hits.length; i < l; i ++ ) {\n\n\t\t\t\tconst hit = convertRaycastIntersect( hits[ i ], object, raycaster );\n\t\t\t\tif ( hit ) {\n\n\t\t\t\t\tintersects.push( hit );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn intersects;\n\n\t}\n\n\t/**\n\t * Refit the node bounds to the current triangle positions. This is quicker than regenerating\n\t * a new BVH but will not be optimal after significant changes to the vertices. `nodeIndices`\n\t * is a set of node indices (provided by the `shapecast` function) that need to be refit\n\t * including all internal nodes.\n\t *\n\t * @param {Set<number>|Array<number>|null} [nodeIndices=null]\n\t */\n\trefit( nodeIndices = null ) {\n\n\t\tconst refitFunc = this.indirect ? refit_indirect : refit;\n\t\treturn refitFunc( this, nodeIndices );\n\n\t}\n\n\t/* Core Cast Functions */\n\n\t/**\n\t * Returns all raycast triangle hits in unsorted order. It is expected that `ray` is in the\n\t * frame of the BVH already. Likewise the returned results are also provided in the local\n\t * frame of the BVH. The `side` identifier is used to determine the side to check when\n\t * raycasting or a material with the given side field can be passed. If an array of materials\n\t * is provided then it is expected that the geometry has groups and the appropriate material\n\t * side is used per group.\n\t *\n\t * Note that unlike three.js' Raycaster results the points and distances in the intersections\n\t * returned from this function are relative to the local frame of the MeshBVH. When using the\n\t * `acceleratedRaycast` function as an override for `Mesh.raycast` they are transformed into\n\t * world space to be consistent with three's results.\n\t *\n\t * @param {Ray} ray\n\t * @param {number|Material|Array<Material>} [materialOrSide=FrontSide]\n\t * @param {number} [near=0]\n\t * @param {number} [far=Infinity]\n\t * @returns {Array<Intersection>}\n\t */\n\traycast( ray, materialOrSide = FrontSide, near = 0, far = Infinity ) {\n\n\t\tconst roots = this._roots;\n\t\tconst intersects = [];\n\t\tconst raycastFunc = this.indirect ? raycast_indirect : raycast;\n\t\tfor ( let i = 0, l = roots.length; i < l; i ++ ) {\n\n\t\t\traycastFunc( this, i, materialOrSide, ray, intersects, near, far );\n\n\t\t}\n\n\t\treturn intersects;\n\n\t}\n\n\t/**\n\t * Returns the first raycast hit in the model. This is typically much faster than returning\n\t * all hits. See `raycast` for information on the side and material options as well as the\n\t * frame of the returned intersections.\n\t *\n\t * @param {Ray} ray\n\t * @param {number|Material|Array<Material>} [materialOrSide=FrontSide]\n\t * @param {number} [near=0]\n\t * @param {number} [far=Infinity]\n\t * @returns {Intersection|null}\n\t */\n\traycastFirst( ray, materialOrSide = FrontSide, near = 0, far = Infinity ) {\n\n\t\tconst roots = this._roots;\n\t\tlet closestResult = null;\n\n\t\tconst raycastFirstFunc = this.indirect ? raycastFirst_indirect : raycastFirst;\n\t\tfor ( let i = 0, l = roots.length; i < l; i ++ ) {\n\n\t\t\tconst result = raycastFirstFunc( this, i, materialOrSide, ray, near, far );\n\t\t\tif ( result != null && ( closestResult == null || result.distance < closestResult.distance ) ) {\n\n\t\t\t\tclosestResult = result;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn closestResult;\n\n\t}\n\n\t/**\n\t * Returns whether or not the mesh intersects the given geometry.\n\t *\n\t * The `geometryToBvh` parameter is the transform of the geometry in the BVH's local frame.\n\t *\n\t * Performance improves considerably if the provided geometry also has a `boundsTree`.\n\t *\n\t * @param {BufferGeometry} otherGeometry\n\t * @param {Matrix4} geometryToBvh - Transform of `otherGeometry` into the local space of\n\t * this BVH.\n\t * @returns {boolean}\n\t */\n\tintersectsGeometry( otherGeometry, geomToMesh ) {\n\n\t\tlet result = false;\n\t\tconst roots = this._roots;\n\t\tconst intersectsGeometryFunc = this.indirect ? intersectsGeometry_indirect : intersectsGeometry;\n\t\tfor ( let i = 0, l = roots.length; i < l; i ++ ) {\n\n\t\t\tresult = intersectsGeometryFunc( this, i, otherGeometry, geomToMesh );\n\n\t\t\tif ( result ) {\n\n\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn result;\n\n\t}\n\n\t/**\n\t * A generalized cast function that can be used to implement intersection logic for custom\n\t * shapes. This is used internally for `intersectsBox`, `intersectsSphere`, and more. The\n\t * function returns as soon as a triangle has been reported as intersected and returns `true`\n\t * if a triangle has been intersected.\n\t *\n\t * @param {Object} callbacks\n\t * @param {IntersectsBoundsCallback} callbacks.intersectsBounds\n\t * @param {IntersectsTriangleCallback} [callbacks.intersectsTriangle]\n\t * @param {IntersectsRangeCallback} [callbacks.intersectsRange]\n\t * @param {BoundsTraverseOrderCallback} [callbacks.boundsTraverseOrder]\n\t * @returns {boolean}\n\t */\n\tshapecast( callbacks ) {\n\n\t\tconst triangle = ExtendedTrianglePool.getPrimitive();\n\t\tconst result = super.shapecast(\n\t\t\t{\n\t\t\t\t...callbacks,\n\t\t\t\tintersectsPrimitive: callbacks.intersectsTriangle,\n\t\t\t\tscratchPrimitive: triangle,\n\n\t\t\t\t// TODO: is the performance significant enough for the added complexity here?\n\t\t\t\t// can we just use one function?\n\t\t\t\titerate: this.indirect ? iterateOverTriangles_indirect : iterateOverTriangles,\n\t\t\t}\n\t\t);\n\t\tExtendedTrianglePool.releasePrimitive( triangle );\n\n\t\treturn result;\n\n\t}\n\n\t/**\n\t * A generalized cast function that traverses two BVH structures simultaneously to perform\n\t * intersection tests between them. This is used internally by `intersectsGeometry`. The\n\t * function returns `true` as soon as a triangle pair has been reported as intersected by\n\t * the callbacks.\n\t *\n\t * `matrixToLocal` is a Matrix4 that transforms `otherBvh` into the local space of this BVH.\n\t * The other BVH's triangles are transformed by this matrix before intersection tests.\n\t *\n\t * @param {MeshBVH} otherBvh\n\t * @param {Matrix4} matrixToLocal - Transforms `otherBvh` into the local space of this BVH.\n\t * @param {Object} callbacks\n\t * @param {IntersectsRangesCallback} [callbacks.intersectsRanges]\n\t * @param {IntersectsTrianglesCallback} [callbacks.intersectsTriangles]\n\t * @returns {boolean}\n\t */\n\tbvhcast( otherBvh, matrixToLocal, callbacks ) {\n\n\t\tlet {\n\t\t\tintersectsRanges,\n\t\t\tintersectsTriangles,\n\t\t} = callbacks;\n\n\t\tconst triangle1 = ExtendedTrianglePool.getPrimitive();\n\t\tconst indexAttr1 = this.geometry.index;\n\t\tconst positionAttr1 = this.geometry.attributes.position;\n\t\tconst assignTriangle1 = this.indirect ?\n\t\t\ti1 => {\n\n\n\t\t\t\tconst ti = this.resolveTriangleIndex( i1 );\n\t\t\t\tsetTriangle( triangle1, ti * 3, indexAttr1, positionAttr1 );\n\n\t\t\t} :\n\t\t\ti1 => {\n\n\t\t\t\tsetTriangle( triangle1, i1 * 3, indexAttr1, positionAttr1 );\n\n\t\t\t};\n\n\t\tconst triangle2 = ExtendedTrianglePool.getPrimitive();\n\t\tconst indexAttr2 = otherBvh.geometry.index;\n\t\tconst positionAttr2 = otherBvh.geometry.attributes.position;\n\t\tconst assignTriangle2 = otherBvh.indirect ?\n\t\t\ti2 => {\n\n\t\t\t\tconst ti2 = otherBvh.resolveTriangleIndex( i2 );\n\t\t\t\tsetTriangle( triangle2, ti2 * 3, indexAttr2, positionAttr2 );\n\n\t\t\t} :\n\t\t\ti2 => {\n\n\t\t\t\tsetTriangle( triangle2, i2 * 3, indexAttr2, positionAttr2 );\n\n\t\t\t};\n\n\t\t// generate triangle callback if needed\n\t\tif ( intersectsTriangles ) {\n\n\t\t\tif ( ! ( otherBvh instanceof MeshBVH ) ) {\n\n\t\t\t\tthrow new Error( 'MeshBVH: \"intersectsTriangles\" callback can only be used with another MeshBVH.' );\n\n\t\t\t}\n\n\t\t\tconst iterateOverDoubleTriangles = ( offset1, count1, offset2, count2, depth1, nodeIndex1, depth2, nodeIndex2 ) => {\n\n\t\t\t\tfor ( let i2 = offset2, l2 = offset2 + count2; i2 < l2; i2 ++ ) {\n\n\t\t\t\t\tassignTriangle2( i2 );\n\n\t\t\t\t\ttriangle2.a.applyMatrix4( matrixToLocal );\n\t\t\t\t\ttriangle2.b.applyMatrix4( matrixToLocal );\n\t\t\t\t\ttriangle2.c.applyMatrix4( matrixToLocal );\n\t\t\t\t\ttriangle2.needsUpdate = true;\n\n\t\t\t\t\tfor ( let i1 = offset1, l1 = offset1 + count1; i1 < l1; i1 ++ ) {\n\n\t\t\t\t\t\tassignTriangle1( i1 );\n\n\t\t\t\t\t\ttriangle1.needsUpdate = true;\n\n\t\t\t\t\t\tif ( intersectsTriangles( triangle1, triangle2, i1, i2, depth1, nodeIndex1, depth2, nodeIndex2 ) ) {\n\n\t\t\t\t\t\t\treturn true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\n\t\t\t};\n\n\t\t\tif ( intersectsRanges ) {\n\n\t\t\t\tconst originalIntersectsRanges = intersectsRanges;\n\t\t\t\tintersectsRanges = function ( offset1, count1, offset2, count2, depth1, nodeIndex1, depth2, nodeIndex2 ) {\n\n\t\t\t\t\tif ( ! originalIntersectsRanges( offset1, count1, offset2, count2, depth1, nodeIndex1, depth2, nodeIndex2 ) ) {\n\n\t\t\t\t\t\treturn iterateOverDoubleTriangles( offset1, count1, offset2, count2, depth1, nodeIndex1, depth2, nodeIndex2 );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t};\n\n\t\t\t} else {\n\n\t\t\t\tintersectsRanges = iterateOverDoubleTriangles;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn super.bvhcast( otherBvh, matrixToLocal, { intersectsRanges } );\n\n\t}\n\n\n\t/* Derived Cast Functions */\n\n\t/**\n\t * Returns whether or not the mesh intersects the given box.\n\t *\n\t * The `boxToBvh` parameter is the transform of the box in the meshes frame.\n\t *\n\t * @param {Box3} box\n\t * @param {Matrix4} boxToBvh - Transform of the box in the local space of this BVH.\n\t * @returns {boolean}\n\t */\n\tintersectsBox( box, boxToMesh ) {\n\n\t\t_obb.set( box.min, box.max, boxToMesh );\n\t\t_obb.needsUpdate = true;\n\n\t\treturn this.shapecast(\n\t\t\t{\n\t\t\t\tintersectsBounds: box => _obb.intersectsBox( box ),\n\t\t\t\tintersectsTriangle: tri => _obb.intersectsTriangle( tri )\n\t\t\t}\n\t\t);\n\n\t}\n\n\t/**\n\t * Returns whether or not the mesh intersects the given sphere.\n\t *\n\t * @param {Sphere} sphere\n\t * @returns {boolean}\n\t */\n\tintersectsSphere( sphere ) {\n\n\t\treturn this.shapecast(\n\t\t\t{\n\t\t\t\tintersectsBounds: box => sphere.intersectsBox( box ),\n\t\t\t\tintersectsTriangle: tri => tri.intersectsSphere( sphere )\n\t\t\t}\n\t\t);\n\n\t}\n\n\t/**\n\t * Computes the closest distance from the geometry to the mesh and puts the closest point on\n\t * the mesh in `target1` (in the frame of the BVH) and the closest point on the other\n\t * geometry in `target2` (in the geometry frame). If `target1` is not provided a new Object\n\t * is created and returned from the function.\n\t *\n\t * The `geometryToBvh` parameter is the transform of the geometry in the BVH's local frame.\n\t *\n\t * If a point is found that is closer than `minThreshold` then the function will return that\n\t * result early. Any triangles or points outside of `maxThreshold` are ignored. If no point\n\t * is found within the min / max thresholds then `null` is returned and the target objects\n\t * are not modified.\n\t *\n\t * The returned faceIndex in `target1` and `target2` can be used with the standalone function\n\t * `getTriangleHitPointInfo` to obtain more information like UV coordinates, triangle normal\n\t * and materialIndex.\n\t *\n\t * _Note that this function can be very slow if `geometry` does not have a\n\t * `geometry.boundsTree` computed._\n\t *\n\t * @param {BufferGeometry} otherGeometry\n\t * @param {Matrix4} geometryToBvh - Transform of `otherGeometry` into the local space of\n\t * this BVH.\n\t * @param {HitPointInfo} [target1={}]\n\t * @param {HitPointInfo} [target2={}]\n\t * @param {number} [minThreshold=0]\n\t * @param {number} [maxThreshold=Infinity]\n\t * @returns {HitPointInfo|null}\n\t */\n\tclosestPointToGeometry( otherGeometry, geometryToBvh, target1 = { }, target2 = { }, minThreshold = 0, maxThreshold = Infinity ) {\n\n\t\tconst closestPointToGeometryFunc = this.indirect ? closestPointToGeometry_indirect : closestPointToGeometry;\n\t\treturn closestPointToGeometryFunc(\n\t\t\tthis,\n\t\t\totherGeometry,\n\t\t\tgeometryToBvh,\n\t\t\ttarget1,\n\t\t\ttarget2,\n\t\t\tminThreshold,\n\t\t\tmaxThreshold,\n\t\t);\n\n\t}\n\n\t/**\n\t * Computes the closest distance from the point to the mesh and gives additional information\n\t * in `target`. The target can be left undefined to default to a new object which is\n\t * ultimately returned by the function.\n\t *\n\t * If a point is found that is closer than `minThreshold` then the function will return that\n\t * result early. Any triangles or points outside of `maxThreshold` are ignored. If no point\n\t * is found within the min / max thresholds then `null` is returned and the `target` object\n\t * is not modified.\n\t *\n\t * The returned faceIndex can be used with the standalone function `getTriangleHitPointInfo`\n\t * to obtain more information like UV coordinates, triangle normal and materialIndex.\n\t *\n\t * @param {Vector3} point\n\t * @param {HitPointInfo} [target={}]\n\t * @param {number} [minThreshold=0]\n\t * @param {number} [maxThreshold=Infinity]\n\t * @returns {HitPointInfo|null}\n\t */\n\tclosestPointToPoint( point, target = { }, minThreshold = 0, maxThreshold = Infinity ) {\n\n\t\treturn closestPointToPoint(\n\t\t\tthis,\n\t\t\tpoint,\n\t\t\ttarget,\n\t\t\tminThreshold,\n\t\t\tmaxThreshold,\n\t\t);\n\n\t}\n\n}\n","/** @import { BufferAttribute } from 'three' */\nimport {\n\tDataTexture,\n\tFloatType,\n\tIntType,\n\tUnsignedIntType,\n\tByteType,\n\tUnsignedByteType,\n\tShortType,\n\tUnsignedShortType,\n\n\tRedFormat,\n\tRGFormat,\n\tRGBAFormat,\n\n\tRedIntegerFormat,\n\tRGIntegerFormat,\n\tRGBAIntegerFormat,\n\n\tNearestFilter,\n} from 'three';\n\nfunction countToStringFormat( count ) {\n\n\tswitch ( count ) {\n\n\t\tcase 1: return 'R';\n\t\tcase 2: return 'RG';\n\t\tcase 3: return 'RGBA';\n\t\tcase 4: return 'RGBA';\n\n\t}\n\n\tthrow new Error();\n\n}\n\nfunction countToFormat( count ) {\n\n\tswitch ( count ) {\n\n\t\tcase 1: return RedFormat;\n\t\tcase 2: return RGFormat;\n\t\tcase 3: return RGBAFormat;\n\t\tcase 4: return RGBAFormat;\n\n\t}\n\n}\n\nfunction countToIntFormat( count ) {\n\n\tswitch ( count ) {\n\n\t\tcase 1: return RedIntegerFormat;\n\t\tcase 2: return RGIntegerFormat;\n\t\tcase 3: return RGBAIntegerFormat;\n\t\tcase 4: return RGBAIntegerFormat;\n\n\t}\n\n}\n\n/**\n * Float, Uint, and Int VertexAttributeTexture implementations are designed to simplify the\n * efficient packing of a three.js BufferAttribute into a texture. An instance can be treated as a\n * texture and when passing as a uniform to a shader they should be used as a `sampler2d`,\n * `usampler2d`, and `isampler2d` when using the Float, Uint, and Int texture types respectively.\n *\n * _extends THREE.DataTexture_\n *\n * @section Shader and Texture Packing API\n */\nexport class VertexAttributeTexture extends DataTexture {\n\n\tconstructor() {\n\n\t\tsuper();\n\t\tthis.minFilter = NearestFilter;\n\t\tthis.magFilter = NearestFilter;\n\t\tthis.generateMipmaps = false;\n\n\t\t/**\n\t\t * Treats `BufferAttribute.itemSize` as though it were set to this value when packing the\n\t\t * buffer attribute texture. Throws an error if the value does not divide evenly into the\n\t\t * length of the BufferAttribute buffer (`count * itemSize % overrideItemSize`).\n\t\t *\n\t\t * Specifically used to pack geometry indices into an RGB texture rather than an Red texture.\n\t\t * @type {number}\n\t\t */\n\t\tthis.overrideItemSize = null;\n\t\tthis._forcedType = null;\n\n\t}\n\n\t/**\n\t * Updates the texture to have the data contained in the passed BufferAttribute using the\n\t * BufferAttribute `itemSize` field, `normalized` field, and TypedArray layout to determine\n\t * the appropriate texture layout, format, and type. The texture dimensions will always be\n\t * square. Because these are intended to be sampled as 1D arrays the width of the texture must\n\t * be taken into account to derive a sampling uv. See `texelFetch1D` in shaderFunctions.\n\t *\n\t * @param {BufferAttribute} attribute\n\t * @returns {void}\n\t */\n\tupdateFrom( attr ) {\n\n\t\tconst overrideItemSize = this.overrideItemSize;\n\t\tconst originalItemSize = attr.itemSize;\n\t\tconst originalCount = attr.count;\n\t\tif ( overrideItemSize !== null ) {\n\n\t\t\tif ( ( originalItemSize * originalCount ) % overrideItemSize !== 0.0 ) {\n\n\t\t\t\tthrow new Error( 'VertexAttributeTexture: overrideItemSize must divide evenly into buffer length.' );\n\n\t\t\t}\n\n\t\t\tattr.itemSize = overrideItemSize;\n\t\t\tattr.count = originalCount * originalItemSize / overrideItemSize;\n\n\t\t}\n\n\t\tconst itemSize = attr.itemSize;\n\t\tconst count = attr.count;\n\t\tconst normalized = attr.normalized;\n\t\tconst originalBufferCons = attr.array.constructor;\n\t\tconst byteCount = originalBufferCons.BYTES_PER_ELEMENT;\n\t\tlet targetType = this._forcedType;\n\t\tlet finalStride = itemSize;\n\n\t\t// derive the type of texture this should be in the shader\n\t\tif ( targetType === null ) {\n\n\t\t\tswitch ( originalBufferCons ) {\n\n\t\t\t\tcase Float32Array:\n\t\t\t\t\ttargetType = FloatType;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase Uint8Array:\n\t\t\t\tcase Uint16Array:\n\t\t\t\tcase Uint32Array:\n\t\t\t\t\ttargetType = UnsignedIntType;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase Int8Array:\n\t\t\t\tcase Int16Array:\n\t\t\t\tcase Int32Array:\n\t\t\t\t\ttargetType = IntType;\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// get the target format to store the texture as\n\t\tlet type, format, normalizeValue, targetBufferCons;\n\t\tlet internalFormat = countToStringFormat( itemSize );\n\t\tswitch ( targetType ) {\n\n\t\t\tcase FloatType:\n\t\t\t\tnormalizeValue = 1.0;\n\t\t\t\tformat = countToFormat( itemSize );\n\n\t\t\t\tif ( normalized && byteCount === 1 ) {\n\n\t\t\t\t\ttargetBufferCons = originalBufferCons;\n\t\t\t\t\tinternalFormat += '8';\n\n\t\t\t\t\tif ( originalBufferCons === Uint8Array ) {\n\n\t\t\t\t\t\ttype = UnsignedByteType;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttype = ByteType;\n\t\t\t\t\t\tinternalFormat += '_SNORM';\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\ttargetBufferCons = Float32Array;\n\t\t\t\t\tinternalFormat += '32F';\n\t\t\t\t\ttype = FloatType;\n\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t\tcase IntType:\n\t\t\t\tinternalFormat += byteCount * 8 + 'I';\n\t\t\t\tnormalizeValue = normalized ? Math.pow( 2, originalBufferCons.BYTES_PER_ELEMENT * 8 - 1 ) : 1.0;\n\t\t\t\tformat = countToIntFormat( itemSize );\n\n\t\t\t\tif ( byteCount === 1 ) {\n\n\t\t\t\t\ttargetBufferCons = Int8Array;\n\t\t\t\t\ttype = ByteType;\n\n\t\t\t\t} else if ( byteCount === 2 ) {\n\n\t\t\t\t\ttargetBufferCons = Int16Array;\n\t\t\t\t\ttype = ShortType;\n\n\t\t\t\t} else {\n\n\t\t\t\t\ttargetBufferCons = Int32Array;\n\t\t\t\t\ttype = IntType;\n\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t\tcase UnsignedIntType:\n\t\t\t\tinternalFormat += byteCount * 8 + 'UI';\n\t\t\t\tnormalizeValue = normalized ? Math.pow( 2, originalBufferCons.BYTES_PER_ELEMENT * 8 - 1 ) : 1.0;\n\t\t\t\tformat = countToIntFormat( itemSize );\n\n\t\t\t\tif ( byteCount === 1 ) {\n\n\t\t\t\t\ttargetBufferCons = Uint8Array;\n\t\t\t\t\ttype = UnsignedByteType;\n\n\t\t\t\t} else if ( byteCount === 2 ) {\n\n\t\t\t\t\ttargetBufferCons = Uint16Array;\n\t\t\t\t\ttype = UnsignedShortType;\n\n\t\t\t\t} else {\n\n\t\t\t\t\ttargetBufferCons = Uint32Array;\n\t\t\t\t\ttype = UnsignedIntType;\n\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t}\n\n\t\t// there will be a mismatch between format length and final length because\n\t\t// RGBFormat and RGBIntegerFormat was removed\n\t\tif ( finalStride === 3 && ( format === RGBAFormat || format === RGBAIntegerFormat ) ) {\n\n\t\t\tfinalStride = 4;\n\n\t\t}\n\n\t\t// copy the data over to the new texture array\n\t\tconst dimension = Math.ceil( Math.sqrt( count ) ) || 1;\n\t\tconst length = finalStride * dimension * dimension;\n\t\tconst dataArray = new targetBufferCons( length );\n\n\t\t// temporarily set the normalized state to false since we have custom normalization logic\n\t\tconst originalNormalized = attr.normalized;\n\t\tattr.normalized = false;\n\t\tfor ( let i = 0; i < count; i ++ ) {\n\n\t\t\tconst ii = finalStride * i;\n\t\t\tdataArray[ ii ] = attr.getX( i ) / normalizeValue;\n\n\t\t\tif ( itemSize >= 2 ) {\n\n\t\t\t\tdataArray[ ii + 1 ] = attr.getY( i ) / normalizeValue;\n\n\t\t\t}\n\n\t\t\tif ( itemSize >= 3 ) {\n\n\t\t\t\tdataArray[ ii + 2 ] = attr.getZ( i ) / normalizeValue;\n\n\t\t\t\tif ( finalStride === 4 ) {\n\n\t\t\t\t\tdataArray[ ii + 3 ] = 1.0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( itemSize >= 4 ) {\n\n\t\t\t\tdataArray[ ii + 3 ] = attr.getW( i ) / normalizeValue;\n\n\t\t\t}\n\n\t\t}\n\n\t\tattr.normalized = originalNormalized;\n\n\t\tthis.internalFormat = internalFormat;\n\t\tthis.format = format;\n\t\tthis.type = type;\n\t\tthis.image.width = dimension;\n\t\tthis.image.height = dimension;\n\t\tthis.image.data = dataArray;\n\t\tthis.needsUpdate = true;\n\t\tthis.dispose();\n\n\t\tattr.itemSize = originalItemSize;\n\t\tattr.count = originalCount;\n\n\t}\n\n}\n\n/**\n * A VertexAttributeTexture that forces the unsigned integer texture type.\n * @extends VertexAttributeTexture\n * @section Shader and Texture Packing API\n */\nexport class UIntVertexAttributeTexture extends VertexAttributeTexture {\n\n\tconstructor() {\n\n\t\tsuper();\n\t\tthis._forcedType = UnsignedIntType;\n\n\t}\n\n}\n\n/**\n * A VertexAttributeTexture that forces the signed integer texture type.\n * @extends VertexAttributeTexture\n * @section Shader and Texture Packing API\n */\nexport class IntVertexAttributeTexture extends VertexAttributeTexture {\n\n\tconstructor() {\n\n\t\tsuper();\n\t\tthis._forcedType = IntType;\n\n\t}\n\n\n}\n\n/**\n * A VertexAttributeTexture that forces the float texture type.\n * @extends VertexAttributeTexture\n * @section Shader and Texture Packing API\n */\nexport class FloatVertexAttributeTexture extends VertexAttributeTexture {\n\n\tconstructor() {\n\n\t\tsuper();\n\t\tthis._forcedType = FloatType;\n\n\t}\n\n}\n","/** @import { MeshBVH } from '../core/MeshBVH.js' */\nimport {\n\tDataTexture,\n\tFloatType,\n\tUnsignedIntType,\n\tRGBAFormat,\n\tRGIntegerFormat,\n\tNearestFilter,\n\tBufferAttribute,\n} from 'three';\nimport {\n\tFloatVertexAttributeTexture,\n\tUIntVertexAttributeTexture,\n} from './VertexAttributeTexture.js';\nimport { BYTES_PER_NODE, LEAFNODE_MASK_32 } from '../core/Constants.js';\nimport {\n\tBOUNDING_DATA_INDEX,\n\tCOUNT,\n\tIS_LEAF,\n\tOFFSET,\n\tSPLIT_AXIS,\n} from '../core/utils/nodeBufferUtils.js';\nimport { getIndexArray, getVertexCount } from '../core/build/geometryUtils.js';\n\n/**\n * A shader uniform object corresponding to the `BVH` shader struct defined in shaderStructs. The\n * object contains four textures containing information about the BVH and geometry so it can be\n * queried in a shader using the bvh intersection functions defined in shaderFunctions. This object\n * is intended to be used as a shader uniform and read in the shader as a `BVH` struct.\n *\n * @section Shader and Texture Packing API\n */\nexport class MeshBVHUniformStruct {\n\n\tconstructor() {\n\n\t\tthis.index = new UIntVertexAttributeTexture();\n\t\tthis.position = new FloatVertexAttributeTexture();\n\t\tthis.bvhBounds = new DataTexture();\n\t\tthis.bvhContents = new DataTexture();\n\t\tthis._cachedIndexAttr = null;\n\n\t\tthis.index.overrideItemSize = 3;\n\n\t}\n\n\t/**\n\t * Updates the object and associated textures with data from the provided BVH.\n\t *\n\t * @param {MeshBVH} bvh\n\t * @returns {void}\n\t */\n\tupdateFrom( bvh ) {\n\n\t\tconst { geometry } = bvh;\n\t\tbvhToTextures( bvh, this.bvhBounds, this.bvhContents );\n\n\t\tthis.position.updateFrom( geometry.attributes.position );\n\n\t\t// dereference a new index attribute if we're using indirect storage\n\t\tif ( bvh.indirect ) {\n\n\t\t\tconst indirectBuffer = bvh._indirectBuffer;\n\t\t\tif (\n\t\t\t\tthis._cachedIndexAttr === null ||\n\t\t\t\tthis._cachedIndexAttr.count !== indirectBuffer.length\n\t\t\t) {\n\n\t\t\t\tif ( geometry.index ) {\n\n\t\t\t\t\tthis._cachedIndexAttr = geometry.index.clone();\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconst array = getIndexArray( getVertexCount( geometry ) );\n\t\t\t\t\tthis._cachedIndexAttr = new BufferAttribute( array, 1, false );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tdereferenceIndex( geometry, indirectBuffer, this._cachedIndexAttr );\n\t\t\tthis.index.updateFrom( this._cachedIndexAttr );\n\n\t\t} else {\n\n\t\t\tthis.index.updateFrom( geometry.index );\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Dispose of the associated textures.\n\t *\n\t * @returns {void}\n\t */\n\tdispose() {\n\n\t\tconst { index, position, bvhBounds, bvhContents } = this;\n\n\t\tif ( index ) index.dispose();\n\t\tif ( position ) position.dispose();\n\t\tif ( bvhBounds ) bvhBounds.dispose();\n\t\tif ( bvhContents ) bvhContents.dispose();\n\n\t}\n\n}\n\nfunction dereferenceIndex( geometry, indirectBuffer, target ) {\n\n\tconst unpacked = target.array;\n\tconst indexArray = geometry.index ? geometry.index.array : null;\n\tfor ( let i = 0, l = indirectBuffer.length; i < l; i ++ ) {\n\n\t\tconst i3 = 3 * i;\n\t\tconst v3 = 3 * indirectBuffer[ i ];\n\t\tfor ( let c = 0; c < 3; c ++ ) {\n\n\t\t\tunpacked[ i3 + c ] = indexArray ? indexArray[ v3 + c ] : v3 + c;\n\n\t\t}\n\n\t}\n\n}\n\nfunction bvhToTextures( bvh, boundsTexture, contentsTexture ) {\n\n\tconst roots = bvh._roots;\n\n\tif ( roots.length !== 1 ) {\n\n\t\tthrow new Error( 'MeshBVHUniformStruct: Multi-root BVHs not supported.' );\n\n\t}\n\n\tconst root = roots[ 0 ];\n\tconst uint16Array = new Uint16Array( root );\n\tconst uint32Array = new Uint32Array( root );\n\tconst float32Array = new Float32Array( root );\n\n\t// Both bounds need two elements per node so compute the height so it's twice as long as\n\t// the width so we can expand the row by two and still have a square texture\n\tconst nodeCount = root.byteLength / BYTES_PER_NODE;\n\tconst boundsDimension = 2 * Math.ceil( Math.sqrt( nodeCount / 2 ) );\n\tconst boundsArray = new Float32Array( 4 * boundsDimension * boundsDimension );\n\n\tconst contentsDimension = Math.ceil( Math.sqrt( nodeCount ) );\n\tconst contentsArray = new Uint32Array( 2 * contentsDimension * contentsDimension );\n\n\tfor ( let i = 0; i < nodeCount; i ++ ) {\n\n\t\tconst nodeIndex32 = i * BYTES_PER_NODE / 4;\n\t\tconst nodeIndex16 = nodeIndex32 * 2;\n\t\tconst boundsIndex = BOUNDING_DATA_INDEX( nodeIndex32 );\n\t\tfor ( let b = 0; b < 3; b ++ ) {\n\n\t\t\tboundsArray[ 8 * i + 0 + b ] = float32Array[ boundsIndex + 0 + b ];\n\t\t\tboundsArray[ 8 * i + 4 + b ] = float32Array[ boundsIndex + 3 + b ];\n\n\t\t}\n\n\t\tif ( IS_LEAF( nodeIndex16, uint16Array ) ) {\n\n\t\t\tconst count = COUNT( nodeIndex16, uint16Array );\n\t\t\tconst offset = OFFSET( nodeIndex32, uint32Array );\n\n\t\t\tconst mergedLeafCount = LEAFNODE_MASK_32 | count;\n\t\t\tcontentsArray[ i * 2 + 0 ] = mergedLeafCount;\n\t\t\tcontentsArray[ i * 2 + 1 ] = offset;\n\n\t\t} else {\n\n\t\t\tconst rightNodeIndex = uint32Array[ nodeIndex32 + 6 ];\n\t\t\tconst splitAxis = SPLIT_AXIS( nodeIndex32, uint32Array );\n\n\t\t\tcontentsArray[ i * 2 + 0 ] = splitAxis;\n\t\t\tcontentsArray[ i * 2 + 1 ] = rightNodeIndex;\n\n\t\t}\n\n\t}\n\n\tboundsTexture.image.data = boundsArray;\n\tboundsTexture.image.width = boundsDimension;\n\tboundsTexture.image.height = boundsDimension;\n\tboundsTexture.format = RGBAFormat;\n\tboundsTexture.type = FloatType;\n\tboundsTexture.internalFormat = 'RGBA32F';\n\tboundsTexture.minFilter = NearestFilter;\n\tboundsTexture.magFilter = NearestFilter;\n\tboundsTexture.generateMipmaps = false;\n\tboundsTexture.needsUpdate = true;\n\tboundsTexture.dispose();\n\n\tcontentsTexture.image.data = contentsArray;\n\tcontentsTexture.image.width = contentsDimension;\n\tcontentsTexture.image.height = contentsDimension;\n\tcontentsTexture.format = RGIntegerFormat;\n\tcontentsTexture.type = UnsignedIntType;\n\tcontentsTexture.internalFormat = 'RG32UI';\n\tcontentsTexture.minFilter = NearestFilter;\n\tcontentsTexture.magFilter = NearestFilter;\n\tcontentsTexture.generateMipmaps = false;\n\tcontentsTexture.needsUpdate = true;\n\tcontentsTexture.dispose();\n\n}\n","/**\n * Set of shader functions used for interacting with the packed BVH in a shader and sampling\n * VertexAttributeTextures. Provides common utility functions including `texelFetch1D`. See\n * [src/webgl/glsl](https://github.com/gkjohnson/three-mesh-bvh/tree/master/src/webgl/glsl)\n * for full implementations and declarations.\n *\n * Accessed as `BVHShaderGLSL.common_functions`.\n *\n * @section Shader and Texture Packing API\n * @type {string}\n */\nexport const common_functions = /* glsl */`\n\n// A stack of uint32 indices can can store the indices for\n// a perfectly balanced tree with a depth up to 31. Lower stack\n// depth gets higher performance.\n//\n// However not all trees are balanced. Best value to set this to\n// is the trees max depth.\n#ifndef BVH_STACK_DEPTH\n#define BVH_STACK_DEPTH 60\n#endif\n\n#ifndef INFINITY\n#define INFINITY 1e20\n#endif\n\n// Utilities\nuvec4 uTexelFetch1D( usampler2D tex, uint index ) {\n\n\tuint width = uint( textureSize( tex, 0 ).x );\n\tuvec2 uv;\n\tuv.x = index % width;\n\tuv.y = index / width;\n\n\treturn texelFetch( tex, ivec2( uv ), 0 );\n\n}\n\nivec4 iTexelFetch1D( isampler2D tex, uint index ) {\n\n\tuint width = uint( textureSize( tex, 0 ).x );\n\tuvec2 uv;\n\tuv.x = index % width;\n\tuv.y = index / width;\n\n\treturn texelFetch( tex, ivec2( uv ), 0 );\n\n}\n\nvec4 texelFetch1D( sampler2D tex, uint index ) {\n\n\tuint width = uint( textureSize( tex, 0 ).x );\n\tuvec2 uv;\n\tuv.x = index % width;\n\tuv.y = index / width;\n\n\treturn texelFetch( tex, ivec2( uv ), 0 );\n\n}\n\nvec4 textureSampleBarycoord( sampler2D tex, vec3 barycoord, uvec3 faceIndices ) {\n\n\treturn\n\t\tbarycoord.x * texelFetch1D( tex, faceIndices.x ) +\n\t\tbarycoord.y * texelFetch1D( tex, faceIndices.y ) +\n\t\tbarycoord.z * texelFetch1D( tex, faceIndices.z );\n\n}\n\nvoid ndcToCameraRay(\n\tvec2 coord, mat4 cameraWorld, mat4 invProjectionMatrix,\n\tout vec3 rayOrigin, out vec3 rayDirection\n) {\n\n\t// get camera look direction and near plane for camera clipping\n\tvec4 lookDirection = cameraWorld * vec4( 0.0, 0.0, - 1.0, 0.0 );\n\tvec4 nearVector = invProjectionMatrix * vec4( 0.0, 0.0, - 1.0, 1.0 );\n\tfloat near = abs( nearVector.z / nearVector.w );\n\n\t// get the camera direction and position from camera matrices\n\tvec4 origin = cameraWorld * vec4( 0.0, 0.0, 0.0, 1.0 );\n\tvec4 direction = invProjectionMatrix * vec4( coord, 0.5, 1.0 );\n\tdirection /= direction.w;\n\tdirection = cameraWorld * direction - origin;\n\n\t// slide the origin along the ray until it sits at the near clip plane position\n\torigin.xyz += direction.xyz * near / dot( direction, lookDirection );\n\n\trayOrigin = origin.xyz;\n\trayDirection = direction.xyz;\n\n}\n`;\n","/**\n * Set of shader functions used for interacting with the packed BVH in a shader and sampling\n * VertexAttributeTextures. Provides ray intersection functions. See\n * [src/webgl/glsl](https://github.com/gkjohnson/three-mesh-bvh/tree/master/src/webgl/glsl)\n * for full implementations and declarations.\n *\n * Accessed as `BVHShaderGLSL.bvh_ray_functions`.\n *\n * @section Shader and Texture Packing API\n * @type {string}\n */\nexport const bvh_ray_functions = /* glsl */`\n\n#ifndef TRI_INTERSECT_EPSILON\n#define TRI_INTERSECT_EPSILON 1e-5\n#endif\n\n// Raycasting\nbool intersectsBounds( vec3 rayOrigin, vec3 rayDirection, vec3 boundsMin, vec3 boundsMax, out float dist ) {\n\n\t// https://www.reddit.com/r/opengl/comments/8ntzz5/fast_glsl_ray_box_intersection/\n\t// https://tavianator.com/2011/ray_box.html\n\tvec3 invDir = 1.0 / rayDirection;\n\n\t// find intersection distances for each plane\n\tvec3 tMinPlane = invDir * ( boundsMin - rayOrigin );\n\tvec3 tMaxPlane = invDir * ( boundsMax - rayOrigin );\n\n\t// get the min and max distances from each intersection\n\tvec3 tMinHit = min( tMaxPlane, tMinPlane );\n\tvec3 tMaxHit = max( tMaxPlane, tMinPlane );\n\n\t// get the furthest hit distance\n\tvec2 t = max( tMinHit.xx, tMinHit.yz );\n\tfloat t0 = max( t.x, t.y );\n\n\t// get the minimum hit distance\n\tt = min( tMaxHit.xx, tMaxHit.yz );\n\tfloat t1 = min( t.x, t.y );\n\n\t// set distance to 0.0 if the ray starts inside the box\n\tdist = max( t0, 0.0 );\n\n\treturn t1 >= dist;\n\n}\n\nbool intersectsTriangle(\n\tvec3 rayOrigin, vec3 rayDirection, vec3 a, vec3 b, vec3 c,\n\tout vec3 barycoord, out vec3 norm, out float dist, out float side\n) {\n\n\t// https://stackoverflow.com/questions/42740765/intersection-between-line-and-triangle-in-3d\n\tvec3 edge1 = b - a;\n\tvec3 edge2 = c - a;\n\tnorm = cross( edge1, edge2 );\n\n\tfloat det = - dot( rayDirection, norm );\n\tfloat invdet = 1.0 / det;\n\n\tvec3 AO = rayOrigin - a;\n\tvec3 DAO = cross( AO, rayDirection );\n\n\tvec4 uvt;\n\tuvt.x = dot( edge2, DAO ) * invdet;\n\tuvt.y = - dot( edge1, DAO ) * invdet;\n\tuvt.z = dot( AO, norm ) * invdet;\n\tuvt.w = 1.0 - uvt.x - uvt.y;\n\n\t// set the hit information\n\tbarycoord = uvt.wxy; // arranged in A, B, C order\n\tdist = uvt.z;\n\tside = sign( det );\n\tnorm = side * normalize( norm );\n\n\t// add an epsilon to avoid misses between triangles\n\tuvt += vec4( TRI_INTERSECT_EPSILON );\n\n\treturn all( greaterThanEqual( uvt, vec4( 0.0 ) ) );\n\n}\n\nbool intersectTriangles(\n\t// geometry info and triangle range\n\tsampler2D positionAttr, usampler2D indexAttr, uint offset, uint count,\n\n\t// ray\n\tvec3 rayOrigin, vec3 rayDirection,\n\n\t// outputs\n\tinout float minDistance, inout uvec4 faceIndices, inout vec3 faceNormal, inout vec3 barycoord,\n\tinout float side, inout float dist\n) {\n\n\tbool found = false;\n\tvec3 localBarycoord, localNormal;\n\tfloat localDist, localSide;\n\tfor ( uint i = offset, l = offset + count; i < l; i ++ ) {\n\n\t\tuvec3 indices = uTexelFetch1D( indexAttr, i ).xyz;\n\t\tvec3 a = texelFetch1D( positionAttr, indices.x ).rgb;\n\t\tvec3 b = texelFetch1D( positionAttr, indices.y ).rgb;\n\t\tvec3 c = texelFetch1D( positionAttr, indices.z ).rgb;\n\n\t\tif (\n\t\t\tintersectsTriangle( rayOrigin, rayDirection, a, b, c, localBarycoord, localNormal, localDist, localSide )\n\t\t\t&& localDist < minDistance\n\t\t) {\n\n\t\t\tfound = true;\n\t\t\tminDistance = localDist;\n\n\t\t\tfaceIndices = uvec4( indices.xyz, i );\n\t\t\tfaceNormal = localNormal;\n\n\t\t\tside = localSide;\n\t\t\tbarycoord = localBarycoord;\n\t\t\tdist = localDist;\n\n\t\t}\n\n\t}\n\n\treturn found;\n\n}\n\nbool intersectsBVHNodeBounds( vec3 rayOrigin, vec3 rayDirection, sampler2D bvhBounds, uint currNodeIndex, out float dist ) {\n\n\tuint cni2 = currNodeIndex * 2u;\n\tvec3 boundsMin = texelFetch1D( bvhBounds, cni2 ).xyz;\n\tvec3 boundsMax = texelFetch1D( bvhBounds, cni2 + 1u ).xyz;\n\treturn intersectsBounds( rayOrigin, rayDirection, boundsMin, boundsMax, dist );\n\n}\n\n// use a macro to hide the fact that we need to expand the struct into separate fields\n#define\\\n\tbvhIntersectFirstHit(\\\n\t\tbvh,\\\n\t\trayOrigin, rayDirection, faceIndices, faceNormal, barycoord, side, dist\\\n\t)\\\n\t_bvhIntersectFirstHit(\\\n\t\tbvh.position, bvh.index, bvh.bvhBounds, bvh.bvhContents,\\\n\t\trayOrigin, rayDirection, faceIndices, faceNormal, barycoord, side, dist\\\n\t)\n\nbool _bvhIntersectFirstHit(\n\t// bvh info\n\tsampler2D bvh_position, usampler2D bvh_index, sampler2D bvh_bvhBounds, usampler2D bvh_bvhContents,\n\n\t// ray\n\tvec3 rayOrigin, vec3 rayDirection,\n\n\t// output variables split into separate variables due to output precision\n\tinout uvec4 faceIndices, inout vec3 faceNormal, inout vec3 barycoord,\n\tinout float side, inout float dist\n) {\n\n\t// stack needs to be twice as long as the deepest tree we expect because\n\t// we push both the left and right child onto the stack every traversal\n\tint pointer = 0;\n\tuint stack[ BVH_STACK_DEPTH ];\n\tstack[ 0 ] = 0u;\n\n\tfloat triangleDistance = INFINITY;\n\tbool found = false;\n\twhile ( pointer > - 1 && pointer < BVH_STACK_DEPTH ) {\n\n\t\tuint currNodeIndex = stack[ pointer ];\n\t\tpointer --;\n\n\t\t// check if we intersect the current bounds\n\t\tfloat boundsHitDistance;\n\t\tif (\n\t\t\t! intersectsBVHNodeBounds( rayOrigin, rayDirection, bvh_bvhBounds, currNodeIndex, boundsHitDistance )\n\t\t\t|| boundsHitDistance > triangleDistance\n\t\t) {\n\n\t\t\tcontinue;\n\n\t\t}\n\n\t\tuvec2 boundsInfo = uTexelFetch1D( bvh_bvhContents, currNodeIndex ).xy;\n\t\tbool isLeaf = bool( boundsInfo.x & 0xffff0000u );\n\n\t\tif ( isLeaf ) {\n\n\t\t\tuint count = boundsInfo.x & 0x0000ffffu;\n\t\t\tuint offset = boundsInfo.y;\n\n\t\t\tfound = intersectTriangles(\n\t\t\t\tbvh_position, bvh_index, offset, count,\n\t\t\t\trayOrigin, rayDirection, triangleDistance,\n\t\t\t\tfaceIndices, faceNormal, barycoord, side, dist\n\t\t\t) || found;\n\n\t\t} else {\n\n\t\t\tuint leftIndex = currNodeIndex + 1u;\n\t\t\tuint splitAxis = boundsInfo.x & 0x0000ffffu;\n\t\t\tuint rightIndex = currNodeIndex + boundsInfo.y;\n\n\t\t\tbool leftToRight = rayDirection[ splitAxis ] >= 0.0;\n\t\t\tuint c1 = leftToRight ? leftIndex : rightIndex;\n\t\t\tuint c2 = leftToRight ? rightIndex : leftIndex;\n\n\t\t\t// set c2 in the stack so we traverse it later. We need to keep track of a pointer in\n\t\t\t// the stack while we traverse. The second pointer added is the one that will be\n\t\t\t// traversed first\n\t\t\tpointer ++;\n\t\t\tstack[ pointer ] = c2;\n\n\t\t\tpointer ++;\n\t\t\tstack[ pointer ] = c1;\n\n\t\t}\n\n\t}\n\n\treturn found;\n\n}\n`;\n","// Note that a struct cannot be used for the hit record including faceIndices, faceNormal, barycoord,\n// side, and dist because on some mobile GPUS (such as Adreno) numbers are afforded less precision specifically\n// when in a struct leading to inaccurate hit results. See KhronosGroup/WebGL#3351 for more details.\n\n/**\n * Set of shader structs and defined constants used for interacting with the packed BVH in a\n * shader. See [src/webgl/glsl/bvh_struct_definitions.glsl.js](https://github.com/gkjohnson/three-mesh-bvh/blob/master/src/webgl/glsl/bvh_struct_definitions.glsl.js)\n * for full implementations and declarations.\n *\n * Accessed as `BVHShaderGLSL.bvh_struct_definitions`.\n *\n * @section Shader and Texture Packing API\n * @type {string}\n */\nexport const bvh_struct_definitions = /* glsl */`\nstruct BVH {\n\n\tusampler2D index;\n\tsampler2D position;\n\n\tsampler2D bvhBounds;\n\tusampler2D bvhContents;\n\n};\n`;\n","export * from './core/BVH.js';\nexport * from './core/GeometryBVH.js';\nexport * from './core/MeshBVH.js';\nexport * from './core/LineBVH.js';\nexport * from './core/PointsBVH.js';\nexport * from './core/ObjectBVH.js';\nexport * from './core/SkinnedMeshBVH.js';\nexport * from './objects/BVHHelper.js';\nexport { CENTER, AVERAGE, SAH, NOT_INTERSECTED, INTERSECTED, CONTAINED, SKIP_GENERATION } from './core/Constants.js';\nexport { getBVHExtremes, estimateMemoryInBytes, getJSONStructure, validateBounds } from './debug/Debug.js';\nexport * from './utils/ExtensionUtilities.js';\nexport { getTriangleHitPointInfo } from './utils/TriangleUtilities.js';\nexport * from './math/ExtendedTriangle.js';\nexport * from './math/OrientedBox.js';\nexport * from './webgl/MeshBVHUniformStruct.js';\nexport * from './webgl/VertexAttributeTexture.js';\nexport * from './utils/StaticGeometryGenerator.js';\nexport * as BVHShaderGLSL from './webgl/BVHShaderGLSL.js';\n\n// backwards compatibility\nimport * as BVHShaderGLSL from './webgl/BVHShaderGLSL.js';\nexport const shaderStructs = BVHShaderGLSL.bvh_struct_definitions;\nexport const shaderDistanceFunction = BVHShaderGLSL.bvh_distance_functions;\nexport const shaderIntersectFunction = `\n\t${ BVHShaderGLSL.common_functions }\n\t${ BVHShaderGLSL.bvh_ray_functions }\n`;\n","import { shaderStructs, shaderIntersectFunction } from 'three-mesh-bvh'\n\n// Bake shaders kept for compatibility\nexport const DIAMOND_BAKE_VERT = /* glsl */ `\nuniform vec3 uCentroid;\nuniform float uRadius;\nattribute vec4 aFacet;\nvarying vec4 vFacet;\n\nvoid main() {\n vFacet = aFacet;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n`\n\nexport const DIAMOND_BAKE_FRAG = /* glsl */ `\nvarying vec4 vFacet;\n\nvoid main() {\n gl_FragColor = vFacet;\n}\n`\n\n// BVH Raytraced Diamond Vertex Shader (GLSL 3.00)\nexport const DIAMOND_RAYMARCH_VERT = /* glsl */ `\nvarying vec3 vWorldPos;\nvarying vec3 vLocalPos;\nvarying vec3 vLocalNormal;\nvarying vec3 vLocalCameraPos;\nvarying mat3 vModelRotation;\n\nuniform vec3 cameraPos;\n\nvoid main() {\n vLocalPos = position;\n #ifdef USE_NORMAL\n vLocalNormal = normal;\n #else\n vLocalNormal = vec3(0.0, 1.0, 0.0);\n #endif\n vec4 worldPosition = modelMatrix * vec4(position, 1.0);\n vWorldPos = worldPosition.xyz;\n vModelRotation = mat3(modelMatrix);\n vLocalCameraPos = (inverse(modelMatrix) * vec4(cameraPos, 1.0)).xyz;\n gl_Position = projectionMatrix * viewMatrix * worldPosition;\n}\n`\n\n// BVH Raytraced Diamond Fragment Shader (GLSL 3.00)\nexport const DIAMOND_RAYMARCH_FRAG = /* glsl */ `\nprecision highp float;\nprecision highp int;\nprecision highp usampler2D;\nprecision highp isampler2D;\n\nout highp vec4 pc_fragColor;\n#define gl_FragColor pc_fragColor\n\n#ifdef USE_CUBE_ENV\n uniform samplerCube envMap;\n#else\n uniform sampler2D envMap;\n#endif\n\nuniform mat3 envRotationMatrix;\nuniform vec3 cameraPos;\nuniform float ior;\nuniform float dispersion;\nuniform float absorption;\nuniform float envIntensity;\nuniform float gamma;\nuniform vec3 color;\nuniform vec3 rgbBoost;\nuniform float transmission;\nuniform float reflectivity;\nuniform float facetSharpness;\nuniform int rayBounces;\nuniform float uRadius;\n\n${shaderStructs}\n${shaderIntersectFunction}\nuniform BVH bvh;\n\nvarying vec3 vWorldPos;\nvarying vec3 vLocalPos;\nvarying vec3 vLocalNormal;\nvarying vec3 vLocalCameraPos;\nvarying mat3 vModelRotation;\n\n#define PI 3.14159265359\n\nvec3 aces(vec3 col) {\n const float a = 2.51;\n const float b = 0.03;\n const float c = 2.43;\n const float d = 0.59;\n const float e = 0.14;\n return clamp((col * (a * col + b)) / (col * (c * col + d) + e), 0.0, 1.0);\n}\n\nfloat schlick(float cosTheta, float f0) {\n return clamp(f0 + (1.0 - f0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0), 0.0, 0.95);\n}\n\nvec3 sampleEnv(vec3 direction) {\n vec3 dir = normalize(envRotationMatrix * direction);\n #ifdef USE_CUBE_ENV\n return texture(envMap, dir).rgb;\n #else\n float v = asin(clamp(dir.y, -0.9999, 0.9999)) / PI + 0.5;\n float u = fract(atan(dir.z, dir.x) / (2.0 * PI) + 0.5);\n return textureLod(envMap, vec2(u, v), 0.0).rgb;\n #endif\n}\n\nvec3 sampleChromaticEnv(vec3 localR, vec3 localG, vec3 localB) {\n vec3 worldR = normalize(vModelRotation * localR);\n vec3 worldG = normalize(vModelRotation * localG);\n vec3 worldB = normalize(vModelRotation * localB);\n return vec3(sampleEnv(worldR).r, sampleEnv(worldG).g, sampleEnv(worldB).b);\n}\n\nvec3 traceDiamondBVH(vec3 localIncident, vec3 localNormal, float baseIor, float fire, int bounces) {\n vec3 entryRay = refract(localIncident, localNormal, 1.0 / baseIor);\n if (length(entryRay) < 0.001) entryRay = reflect(localIncident, localNormal);\n\n vec3 ray = normalize(entryRay);\n vec3 position = vLocalPos + ray * 0.0001;\n float weight = 1.0;\n float totalDistance = 0.0;\n float normRadius = max(uRadius, 0.01);\n\n vec3 targetColor = clamp(color, vec3(0.005), vec3(1.0));\n float density = max(absorption, 0.5);\n vec3 sigma = -log(targetColor) * density;\n\n // Dispersion per-channel refractive indices\n float delta = fire * 1.5;\n#ifdef CORRECT_DISPERSION_SIGN\n // Physical: red lower IOR, blue higher IOR\n float iorR = baseIor - delta;\n float iorG = baseIor;\n float iorB = baseIor + delta;\n#else\n // Reference quirk: inverted dispersion (red higher IOR, blue lower IOR)\n float iorR = baseIor + delta;\n float iorG = baseIor;\n float iorB = baseIor - delta;\n#endif\n\n // Critical angle for Total Internal Reflection (gem -> air)\n float critSinSq = max(0.0, 1.0 - 1.0 / (baseIor * baseIor));\n vec3 accumulated = vec3(0.0);\n\n for (int bounce = 0; bounce < 8; bounce++) {\n if (bounce >= bounces) break;\n\n uvec4 faceIndices;\n vec3 faceNormal;\n vec3 barycoord;\n float side;\n float distance;\n bool hit = bvhIntersectFirstHit(bvh, position, ray, faceIndices, faceNormal, barycoord, side, distance);\n if (!hit) break;\n\n vec3 hitPosition = position + ray * distance;\n totalDistance += distance;\n if (dot(faceNormal, ray) > 0.0) faceNormal = -faceNormal;\n\n float cosI = clamp(dot(-ray, faceNormal), 0.0, 1.0);\n float cosSq = cosI * cosI;\n\n if (cosSq <= critSinSq) {\n // Total Internal Reflection (TIR) — 100% of ray energy bounces internally\n#ifdef ACCUMULATE_TIR\n vec3 worldRay = normalize(vModelRotation * ray);\n vec3 envVal = sampleEnv(worldRay);\n vec3 beer = exp(-sigma * (totalDistance / normRadius));\n accumulated += weight * envVal * beer;\n#endif\n ray = reflect(ray, faceNormal);\n position = hitPosition + ray * 0.0001;\n } else {\n // Partial transmission and reflection via Snell & Fresnel\n float sinTransSq = baseIor * baseIor * (1.0 - cosSq);\n float cosT = sqrt(max(1.0 - sinTransSq, 0.0));\n float rParallel = (cosI - baseIor * cosT) / (cosI + baseIor * cosT);\n float rPerp = (baseIor * cosI - cosT) / (baseIor * cosI + cosT);\n float R = clamp(0.5 * (rParallel * rParallel + rPerp * rPerp), 0.0, 0.96);\n float T = 1.0 - R;\n\n // Chromatic exit refraction for each wavelength\n vec3 exitR = refract(ray, faceNormal, iorR);\n vec3 exitG = refract(ray, faceNormal, iorG);\n vec3 exitB = refract(ray, faceNormal, iorB);\n\n if (length(exitG) > 0.001 && weight * T > 0.002) {\n vec3 eR = length(exitR) > 0.001 ? exitR : exitG;\n vec3 eB = length(exitB) > 0.001 ? exitB : exitG;\n vec3 envVal = sampleChromaticEnv(eR, exitG, eB);\n vec3 beer = exp(-sigma * (totalDistance / normRadius));\n accumulated += weight * T * envVal * beer;\n }\n\n // Continue internal reflection with remaining weight\n ray = reflect(ray, faceNormal);\n position = hitPosition + ray * 0.0001;\n weight *= R;\n }\n\n if (weight < 0.005) break;\n }\n\n // Smooth exhaustion tail: sample final escaped direction\n if (weight > 0.005) {\n vec3 worldRay = normalize(vModelRotation * ray);\n vec3 envVal = sampleEnv(worldRay);\n vec3 beer = exp(-sigma * (totalDistance / normRadius));\n accumulated += weight * envVal * beer * 0.6;\n }\n\n return accumulated;\n}\n\nvoid main() {\n vec3 flatFacetNormal = normalize(cross(dFdx(vLocalPos), dFdy(vLocalPos)));\n #ifdef USE_NORMAL\n if (dot(flatFacetNormal, vLocalNormal) < 0.0) flatFacetNormal = -flatFacetNormal;\n vec3 localNormal = normalize(mix(vLocalNormal, flatFacetNormal, clamp(facetSharpness, 0.0, 1.0)));\n #else\n vec3 localNormal = flatFacetNormal;\n #endif\n\n vec3 localView = normalize(vLocalCameraPos - vLocalPos);\n vec3 localIncident = -localView;\n if (dot(localNormal, localIncident) > 0.0) localNormal = -localNormal;\n\n vec3 worldNormal = normalize(vModelRotation * localNormal);\n vec3 view = normalize(cameraPos - vWorldPos);\n vec3 incident = -view;\n if (dot(worldNormal, incident) > 0.0) worldNormal = -worldNormal;\n\n // External Fresnel (dielectric surface reflection)\n float cosTheta = clamp(dot(view, worldNormal), 0.0, 1.0);\n float r0 = pow((ior - 1.0) / (ior + 1.0), 2.0);\n#ifdef USE_CORRECT_FRESNEL\n // Physical: cosI from incident angle (DIAMOND_PLAN §3 physics fix)\n float fresnel = schlick(abs(dot(-incident, worldNormal)), r0);\n#else\n // Reference quirk: cosT (transmitted angle) — reproduces RMJ visual\n vec3 entryRefracted = refract(incident, worldNormal, 1.0 / ior);\n float fresnel = schlick(abs(dot(entryRefracted, -worldNormal)), r0);\n#endif\n vec3 externalReflection = sampleEnv(reflect(incident, worldNormal));\n\n // BVH ray-traced internal transmission with true multi-channel dispersion\n vec3 internalTransmission = traceDiamondBVH(localIncident, localNormal, ior, dispersion, rayBounces);\n internalTransmission = pow(max(internalTransmission, vec3(0.0)), vec3(max(gamma, 0.01)));\n internalTransmission *= rgbBoost * envIntensity;\n\n float bvhMaxC = max(max(color.r, color.g), color.b);\n float bvhMinC = min(min(color.r, color.g), color.b);\n float bvhChroma = bvhMaxC - bvhMinC;\n float bvhLum = dot(color, vec3(0.299, 0.587, 0.114));\n\n // External surface reflection:\n // For black/dark stones, provide full adamantine luster & ambient reflection so 3D faceting is never lost\n // For colored stones, tint specular highlight with gem color to prevent washed out white blowout\n vec3 bvhReflTint = (bvhChroma >= 0.05 && bvhLum >= 0.15 && bvhMaxC > 0.001)\n ? mix(vec3(1.0), color / bvhMaxC, 0.70)\n : vec3(1.0);\n float reflScale = (bvhLum < 0.2) ? 1.3 : 0.45;\n vec3 surfaceReflection = externalReflection * (fresnel * reflectivity * envIntensity * reflScale) * bvhReflTint;\n if (bvhLum < 0.2) {\n surfaceReflection += externalReflection * r0 * 0.45;\n }\n\n // Subtle inner facet-edge accents at grazing angles\n float innerGlintAngle = 1.0 - cosTheta;\n float innerGlint = pow(clamp(innerGlintAngle * 1.4, 0.0, 1.0), 6.0) * 0.35;\n vec3 innerGlintColor = externalReflection * bvhReflTint * innerGlint * envIntensity * reflectivity;\n\n vec3 hdrColor = internalTransmission * (1.0 - fresnel * reflectivity * 0.25)\n + surfaceReflection\n + innerGlintColor;\n\n if (transmission > 0.001) {\n vec3 directTransmission = refract(incident, worldNormal, 1.0 / ior);\n if (length(directTransmission) < 0.001) directTransmission = reflect(incident, worldNormal);\n vec3 tColor = clamp(color, vec3(0.005), vec3(1.0));\n vec3 sigma2 = -log(tColor) * max(absorption, 0.5);\n vec3 directTransBeer = exp(-sigma2 * 0.5);\n hdrColor = mix(hdrColor, sampleEnv(directTransmission) * envIntensity * directTransBeer, transmission);\n }\n\n pc_fragColor = vec4(aces(hdrColor), 1.0);\n}\n`\n","import * as THREE from 'three'\nimport {\n analyzeGeometry,\n buildFacetAttribute,\n hashGeometry,\n type BakeHandle,\n type GemAnalysis,\n} from './gem-geometry'\nimport { DIAMOND_BAKE_VERT, DIAMOND_BAKE_FRAG } from './diamond-shaders'\nimport { getOrCreateDiamondBVH } from './diamond-bvh'\n\nexport type { BakeHandle }\n\nexport interface CacheEntry {\n handle: BakeHandle\n renderTarget: THREE.WebGLCubeRenderTarget\n refCount: number\n disposalTimer: ReturnType<typeof setTimeout> | null\n geometryRef: WeakRef<THREE.BufferGeometry>\n resolution: 128 | 256 | 512\n analysis: GemAnalysis\n}\n\nexport class DiamondNormalBaker {\n private cache = new Map<string, CacheEntry>()\n\n get cacheSize(): number {\n return this.cache.size\n }\n\n getEntry(key: string): CacheEntry | undefined {\n return this.cache.get(key)\n }\n\n acquire(\n g: THREE.BufferGeometry,\n renderer: THREE.WebGLRenderer,\n opts?: { resolution?: 128 | 256 | 512 }\n ): BakeHandle | null {\n const analysis = analyzeGeometry(g)\n if (!analysis.isBakeable) {\n return null\n }\n\n const res: 128 | 256 | 512 = opts?.resolution ?? 256\n // Include resolution in cache key so tier changes re-bake at requested resolution\n const key = `${hashGeometry(g, analysis)}_${res}`\n const existing = this.cache.get(key)\n if (existing) {\n if (existing.disposalTimer !== null) {\n clearTimeout(existing.disposalTimer)\n existing.disposalTimer = null\n }\n existing.refCount++\n return existing.handle\n }\n\n return this.bake(g, analysis, key, renderer, res)\n }\n\n private bake(\n g: THREE.BufferGeometry,\n analysis: GemAnalysis,\n key: string,\n renderer: THREE.WebGLRenderer,\n res: 128 | 256 | 512\n ): BakeHandle {\n const isUnorm = !renderer.capabilities?.isWebGL2\n const renderTarget = new THREE.WebGLCubeRenderTarget(res, {\n type: isUnorm ? THREE.UnsignedByteType : THREE.HalfFloatType,\n format: THREE.RGBAFormat,\n depthBuffer: true,\n generateMipmaps: false,\n minFilter: THREE.NearestFilter,\n magFilter: THREE.NearestFilter,\n })\n\n this.renderToTarget(g, analysis, renderer, renderTarget, isUnorm)\n\n const handle: BakeHandle = {\n key,\n texture: renderTarget.texture,\n centroid: analysis.centroid.clone(),\n radius: analysis.radius,\n encoding: isUnorm ? 'unorm' : 'signed',\n }\n\n this.cache.set(key, {\n handle,\n renderTarget,\n refCount: 1,\n disposalTimer: null,\n geometryRef: new WeakRef(g),\n resolution: res,\n analysis,\n })\n\n return handle\n }\n\n private renderToTarget(\n g: THREE.BufferGeometry,\n analysis: GemAnalysis,\n renderer: THREE.WebGLRenderer,\n renderTarget: THREE.WebGLCubeRenderTarget,\n isUnorm: boolean\n ): void {\n const facetData = buildFacetAttribute(g, analysis)\n const bakeGeo = g.getIndex() ? g.toNonIndexed() : g.clone()\n bakeGeo.setAttribute('aFacet', new THREE.BufferAttribute(facetData, 4))\n\n console.log('[DiamondBaker] renderToTarget called', {\n isUnorm,\n triangleCount: analysis.triangleCount,\n centroid: analysis.centroid.toArray(),\n radius: analysis.radius,\n facetDataLength: facetData.length,\n facetSample: Array.from(facetData.slice(0, 8)), // first 2 floats of first 2 vertices\n bakeGeoVertexCount: bakeGeo.getAttribute('position').count,\n rendererCapabilities: renderer.capabilities?.isWebGL2,\n })\n\n const bakeMat = new THREE.ShaderMaterial({\n vertexShader: DIAMOND_BAKE_VERT,\n fragmentShader: DIAMOND_BAKE_FRAG,\n side: THREE.DoubleSide,\n blending: THREE.NoBlending,\n transparent: false,\n depthTest: true,\n depthWrite: true,\n toneMapped: false,\n defines: isUnorm ? { GEM_NORMALS_UNORM: 1 } : {},\n uniforms: {\n uCentroid: { value: analysis.centroid },\n uRadius: { value: analysis.radius },\n },\n })\n\n const scene = new THREE.Scene()\n const mesh = new THREE.Mesh(bakeGeo, bakeMat)\n scene.add(mesh)\n\n const near = Math.max(0.001, analysis.radius * 0.001)\n const far = Math.max(2.5, analysis.radius * 3.0)\n const camera = new THREE.CubeCamera(near, far, renderTarget)\n camera.position.copy(analysis.centroid)\n\n const prevRenderTarget = renderer.getRenderTarget?.() ?? null\n const prevAutoClear = renderer.autoClear\n const prevToneMapping = renderer.toneMapping\n const prevClearColor = new THREE.Color()\n if (renderer.getClearColor) {\n renderer.getClearColor(prevClearColor)\n }\n const prevClearAlpha = renderer.getClearAlpha ? renderer.getClearAlpha() : 1\n\n renderer.toneMapping = THREE.NoToneMapping\n renderer.autoClear = true\n if (renderer.setClearColor) {\n renderer.setClearColor(0x000000, 0)\n }\n\n // Check for pre-existing GL errors if context is available\n const gl = renderer.getContext?.()\n if (gl) {\n const preError = gl.getError()\n if (preError !== 0) console.warn('[DiamondBaker] GL error BEFORE camera.update:', preError)\n }\n\n camera.update(renderer, scene)\n\n // Check for GL errors after the bake render\n if (gl) {\n const postError = gl.getError()\n if (postError !== 0) {\n console.error('[DiamondBaker] GL error AFTER camera.update:', postError, '— bake likely failed!')\n }\n }\n\n if (renderer.setRenderTarget) {\n renderer.setRenderTarget(prevRenderTarget)\n }\n renderer.autoClear = prevAutoClear\n renderer.toneMapping = prevToneMapping\n if (renderer.setClearColor) {\n renderer.setClearColor(prevClearColor, prevClearAlpha)\n }\n\n bakeGeo.dispose()\n bakeMat.dispose()\n }\n\n release(handle: BakeHandle): void {\n const entry = this.cache.get(handle.key)\n if (!entry) return\n\n entry.refCount--\n if (entry.refCount <= 0) {\n entry.refCount = 0\n if (entry.disposalTimer !== null) {\n clearTimeout(entry.disposalTimer)\n }\n entry.disposalTimer = setTimeout(() => {\n entry.renderTarget.dispose()\n this.cache.delete(handle.key)\n }, 1000)\n }\n }\n\n clearCache(): void {\n for (const entry of this.cache.values()) {\n if (entry.disposalTimer !== null) {\n clearTimeout(entry.disposalTimer)\n entry.disposalTimer = null\n }\n entry.renderTarget.dispose()\n }\n this.cache.clear()\n }\n\n onContextRestored(renderer: THREE.WebGLRenderer): void {\n for (const [key, entry] of this.cache.entries()) {\n const geo = entry.geometryRef.deref()\n if (!geo) {\n if (entry.disposalTimer !== null) {\n clearTimeout(entry.disposalTimer)\n entry.disposalTimer = null\n }\n entry.renderTarget.dispose()\n this.cache.delete(key)\n continue\n }\n\n const isUnorm = !renderer.capabilities?.isWebGL2\n entry.renderTarget.dispose()\n const newTarget = new THREE.WebGLCubeRenderTarget(entry.resolution, {\n type: isUnorm ? THREE.UnsignedByteType : THREE.HalfFloatType,\n format: THREE.RGBAFormat,\n depthBuffer: true,\n generateMipmaps: false,\n minFilter: THREE.NearestFilter,\n magFilter: THREE.NearestFilter,\n })\n entry.renderTarget = newTarget\n entry.handle.texture = newTarget.texture\n entry.handle.encoding = isUnorm ? 'unorm' : 'signed'\n\n this.renderToTarget(geo, entry.analysis, renderer, newTarget, isUnorm)\n }\n }\n}\n\nexport const globalDiamondBaker = new DiamondNormalBaker()\n","import * as THREE from 'three'\nimport { MeshBVHUniformStruct } from 'three-mesh-bvh'\nimport type { BakeHandle } from './gem-geometry'\nimport { DIAMOND_RAYMARCH_VERT, DIAMOND_RAYMARCH_FRAG } from './diamond-shaders'\nimport type { StonePreset } from './presets'\n\nconst _invMat = new THREE.Matrix4()\n\nexport interface PhysicalModeOptions {\n useCorrectFresnel?: boolean // use cosI (physical) at entry instead of cosT (reference quirk)\n correctDispersionSign?: boolean // iorR=n-delta, iorB=n+delta (physical direction)\n accumulateTIR?: boolean // accumulate TIR contribution at every bounce, not just last\n}\n\nexport class DiamondMaterial extends THREE.ShaderMaterial {\n bakeHandle: BakeHandle\n onBeforeRender: (\n renderer: THREE.WebGLRenderer,\n scene: THREE.Scene,\n camera: THREE.Camera,\n geometry: THREE.BufferGeometry,\n object: THREE.Object3D,\n ) => void\n\n constructor(handle: BakeHandle, envMap: THREE.Texture, preset: StonePreset, physOpts: PhysicalModeOptions = {}) {\n const bvhValue = handle.bvh ?? new MeshBVHUniformStruct()\n\n super({\n vertexShader: DIAMOND_RAYMARCH_VERT,\n fragmentShader: DIAMOND_RAYMARCH_FRAG,\n glslVersion: THREE.GLSL3,\n defines: {\n USE_CUBE_ENV: 1,\n MAX_BOUNCES: 5,\n ...(handle.encoding === 'unorm' ? { GEM_NORMALS_UNORM: 1 } : {}),\n ...(physOpts.useCorrectFresnel ? { USE_CORRECT_FRESNEL: 1 } : {}),\n ...(physOpts.correctDispersionSign ? { CORRECT_DISPERSION_SIGN: 1 } : {}),\n ...(physOpts.accumulateTIR ? { ACCUMULATE_TIR: 1 } : {}),\n },\n uniforms: {\n bvh: { value: bvhValue },\n envMap: { value: envMap },\n envRotationMatrix: { value: new THREE.Matrix3() },\n cameraPos: { value: new THREE.Vector3() },\n ior: { value: preset.ior ?? 2.417 },\n dispersion: { value: preset.dispersion ?? 0.012 },\n absorption: { value: 1.0 + (preset.absorptionFactor ?? 0.0) * 2.0 },\n envIntensity: { value: preset.envMapIntensity ?? 2.2 },\n gamma: { value: 1.0 },\n color: { value: new THREE.Color(preset.hex) },\n rgbBoost: { value: new THREE.Vector3(...(preset.boostFactors ?? [1.3, 1.3, 1.3])) },\n transmission: { value: 0.0 },\n reflectivity: { value: 0.46 },\n facetSharpness: { value: 1.0 },\n rayBounces: { value: 8 }, // More bounces for richer internal facet patterns\n\n // Retain previous uniforms for tests and compatibility:\n tCubeMapNormals: { value: handle.texture },\n uEnvFlip: { value: (envMap as any)?.isRenderTargetTexture ? 1.0 : -1.0 },\n uCentroid: { value: handle.centroid ? handle.centroid.clone() : new THREE.Vector3() },\n uRadius: { value: handle.radius ?? 1.0 },\n uCamLocal: { value: new THREE.Vector3() },\n refractiveIndex: { value: preset.ior ?? 2.417 },\n rIndexDelta: { value: preset.dispersion ?? 0.012 },\n absorptionFactor: { value: preset.absorptionFactor ?? 0.0 },\n gemColor: { value: new THREE.Color(preset.hex) },\n uExhaustionResidual: { value: 0.5 },\n bounces: { value: 5 },\n uSplitBounces: { value: 2 },\n uDebugMode: { value: 0 },\n },\n side: THREE.FrontSide,\n transparent: false,\n depthTest: true,\n depthWrite: true,\n toneMapped: true,\n extensions: {\n derivatives: true,\n },\n })\n\n this.bakeHandle = handle\n\n this.onBeforeRender = (_renderer, _scene, camera, _geometry, object) => {\n ;(this.uniforms.cameraPos.value as THREE.Vector3).copy(camera.position)\n _invMat.copy(object.matrixWorld).invert()\n ;(this.uniforms.uCamLocal.value as THREE.Vector3).copy(camera.position).applyMatrix4(_invMat)\n }\n }\n\n updatePreset(preset: StonePreset): void {\n if (this.uniforms.color) {\n ;(this.uniforms.color.value as THREE.Color).set(preset.hex)\n }\n if (this.uniforms.gemColor) {\n ;(this.uniforms.gemColor.value as THREE.Color).set(preset.hex)\n }\n if (this.uniforms.ior) {\n this.uniforms.ior.value = preset.ior ?? 2.417\n }\n if (this.uniforms.refractiveIndex) {\n this.uniforms.refractiveIndex.value = preset.ior ?? 2.417\n }\n if (this.uniforms.dispersion) {\n this.uniforms.dispersion.value = preset.dispersion ?? 0.012\n }\n if (this.uniforms.rIndexDelta) {\n this.uniforms.rIndexDelta.value = preset.dispersion ?? 0.012\n }\n if (this.uniforms.absorption) {\n this.uniforms.absorption.value = 1.0 + (preset.absorptionFactor ?? 0.0) * 2.0\n }\n if (this.uniforms.absorptionFactor) {\n this.uniforms.absorptionFactor.value = preset.absorptionFactor ?? 0.0\n }\n if (this.uniforms.rgbBoost) {\n const [r, g, b] = preset.boostFactors ?? [2.0, 2.0, 2.0]\n ;(this.uniforms.rgbBoost.value as THREE.Vector3).set(r, g, b)\n }\n this.uniformsNeedUpdate = true\n }\n}\n\ninterface CacheEntry {\n material: DiamondMaterial\n refCount: number\n}\n\nconst materialCache = new Map<string, CacheEntry>()\n\nexport function acquireDiamondMaterial(\n handle: BakeHandle,\n envMap: THREE.Texture,\n preset: StonePreset,\n physOpts: PhysicalModeOptions = {},\n): DiamondMaterial {\n const optSuffix = `${physOpts.useCorrectFresnel ? '_cf' : ''}${physOpts.correctDispersionSign ? '_cd' : ''}${physOpts.accumulateTIR ? '_at' : ''}`\n const key = `${handle.key}_${preset.id}_${preset.hex}${optSuffix}`\n const existing = materialCache.get(key)\n if (existing) {\n existing.refCount++\n return existing.material\n }\n\n const material = new DiamondMaterial(handle, envMap, preset, physOpts)\n materialCache.set(key, { material, refCount: 1 })\n return material\n}\n\nexport function releaseDiamondMaterial(mat: DiamondMaterial): void {\n for (const [key, entry] of materialCache.entries()) {\n if (entry.material === mat) {\n entry.refCount--\n if (entry.refCount <= 0) {\n mat.dispose()\n materialCache.delete(key)\n }\n return\n }\n }\n}\n\nexport function getDiamondMaterialCacheSize(): number {\n return materialCache.size\n}\n\nexport function clearDiamondMaterialCache(): void {\n for (const entry of materialCache.values()) {\n entry.material.dispose()\n }\n materialCache.clear()\n}\n","import * as THREE from 'three'\nimport { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js'\n\n/**\n * Procedural luxury jewelry photography light tent environment.\n * Generates a complete 360° studio lighting dome with an overhead softbox,\n * bilateral key/fill light panels, linear rim highlight strips, bottom reflector,\n * and subtle dark contrast flags for crisp metallic edge definition.\n */\nexport class JewelryStudioEnvironment extends THREE.Scene {\n constructor() {\n super()\n\n // 1. Studio Light Tent Dome:\n // Bright studio diffuser enclosure providing high-key ambient light so metallic bodies retain\n // their true, rich, saturated color while softbox panels provide specular gleam.\n const domeGeo = new THREE.SphereGeometry(30, 32, 16)\n const domeMat = new THREE.MeshBasicMaterial({\n color: 0x9098a6,\n side: THREE.BackSide,\n })\n const dome = new THREE.Mesh(domeGeo, domeMat)\n this.add(dome)\n\n // 2. Overhead Key Softbox:\n // Large diffuser panel directly above illuminating gemstone tables and ring crowns.\n const topGeo = new THREE.PlaneGeometry(16, 16)\n const topMat = new THREE.MeshBasicMaterial({\n color: 0xffffff,\n side: THREE.DoubleSide,\n })\n topMat.color.setScalar(4.0) // Brilliant catchlight\n const topPanel = new THREE.Mesh(topGeo, topMat)\n topPanel.position.set(0, 14, 0)\n topPanel.rotation.x = Math.PI / 2\n this.add(topPanel)\n\n // 3. Front-Left Key Softbox:\n // High-radiance softbox casting broad, soft highlights across the left shanks and facets.\n const leftSoftboxGeo = new THREE.PlaneGeometry(12, 16)\n const leftSoftboxMat = new THREE.MeshBasicMaterial({\n color: 0xffffff,\n side: THREE.DoubleSide,\n })\n leftSoftboxMat.color.setScalar(3.0)\n const leftSoftbox = new THREE.Mesh(leftSoftboxGeo, leftSoftboxMat)\n leftSoftbox.position.set(-10, 8, 10)\n leftSoftbox.lookAt(0, 0, 0)\n this.add(leftSoftbox)\n\n // 4. Front-Right Fill Softbox:\n // Balanced fill softbox preventing harsh asymmetric falloff on right surfaces.\n const rightSoftboxGeo = new THREE.PlaneGeometry(12, 16)\n const rightSoftboxMat = new THREE.MeshBasicMaterial({\n color: 0xffffff,\n side: THREE.DoubleSide,\n })\n rightSoftboxMat.color.setScalar(2.8)\n const rightSoftbox = new THREE.Mesh(rightSoftboxGeo, rightSoftboxMat)\n rightSoftbox.position.set(10, 8, 10)\n rightSoftbox.lookAt(0, 0, 0)\n this.add(rightSoftbox)\n\n // 5. Bilateral Rim Glint Strips:\n // Narrow vertical light panels creating signature sleek, razor-sharp specular streaks\n // along the outer polished curvature of the shank.\n const rimGeo = new THREE.PlaneGeometry(2, 22)\n const rimMat = new THREE.MeshBasicMaterial({\n color: 0xffffff,\n side: THREE.DoubleSide,\n })\n rimMat.color.setScalar(4.5)\n\n const leftRim = new THREE.Mesh(rimGeo, rimMat)\n leftRim.position.set(-14, 2, -2)\n leftRim.lookAt(0, 0, 0)\n this.add(leftRim)\n\n const rightRim = new THREE.Mesh(rimGeo, rimMat)\n rightRim.position.set(14, 2, -2)\n rightRim.lookAt(0, 0, 0)\n this.add(rightRim)\n\n // 6. Ground Bounce Reflector:\n // Upward-facing reflector preventing under-prongs and bottom band from going dark.\n const groundGeo = new THREE.PlaneGeometry(24, 24)\n const groundMat = new THREE.MeshBasicMaterial({\n color: 0xf5f7fa,\n side: THREE.DoubleSide,\n })\n groundMat.color.setScalar(1.2)\n const ground = new THREE.Mesh(groundGeo, groundMat)\n ground.position.set(0, -12, 0)\n ground.rotation.x = -Math.PI / 2\n this.add(ground)\n\n // 7. Dark Contrast Accent Flags (Studio Black Cards):\n // In professional photography, narrow black cards create crisp reflection horizon lines,\n // giving precious metals physical depth, liquid sheen, and facet definition without flat wash.\n const flagGeo = new THREE.PlaneGeometry(1.2, 16)\n const flagMat = new THREE.MeshBasicMaterial({\n color: 0x121216,\n side: THREE.DoubleSide,\n })\n const leftFlag = new THREE.Mesh(flagGeo, flagMat)\n leftFlag.position.set(-5, 4, -9)\n leftFlag.lookAt(0, 0, 0)\n this.add(leftFlag)\n\n const rightFlag = new THREE.Mesh(flagGeo, flagMat)\n rightFlag.position.set(5, 4, -9)\n rightFlag.lookAt(0, 0, 0)\n this.add(rightFlag)\n }\n\n dispose(): void {\n const resources = new Set<THREE.BufferGeometry | THREE.Material>()\n this.traverse((obj) => {\n if (obj instanceof THREE.Mesh) {\n if (obj.geometry) resources.add(obj.geometry)\n if (obj.material) {\n if (Array.isArray(obj.material)) {\n obj.material.forEach((m) => resources.add(m))\n } else {\n resources.add(obj.material)\n }\n }\n }\n })\n for (const res of resources) {\n res.dispose()\n }\n this.clear()\n }\n}\n\n/**\n * Generates a JewelryStudioEnvironment PMREMTexture and sets it on the scene.\n * Call once after WebGLRenderer is created.\n */\nexport function setupEnvironment(\n scene: THREE.Scene,\n renderer: THREE.WebGLRenderer,\n): THREE.Texture {\n const pmremGenerator = new THREE.PMREMGenerator(renderer)\n pmremGenerator.compileEquirectangularShader()\n\n const studioEnv = new JewelryStudioEnvironment()\n const env = pmremGenerator.fromScene(studioEnv).texture\n scene.environment = env\n studioEnv.dispose()\n pmremGenerator.dispose()\n\n return env\n}\n\n/**\n * Procedural gem lighting environment dome.\n * Generates an enclosing dark dome with 7 high-radiance pinpoint emitter panels\n * optimized for multi-bounce total internal reflection and scintillation in gemstones.\n */\nexport class JewelryGemEnvironment extends THREE.Scene {\n constructor() {\n super()\n\n // 1. Studio Photography Tent Dome:\n // Soft photography diffuser enclosure providing realistic white/silver ambient fill\n // so diamond facets reflect bright, clean light with crisp contrast.\n const domeGeo = new THREE.SphereGeometry(30, 32, 16)\n const domeMat = new THREE.MeshBasicMaterial({\n color: 0xa0a8b5,\n side: THREE.BackSide,\n })\n const dome = new THREE.Mesh(domeGeo, domeMat)\n this.add(dome)\n\n // 2. Baffled Overhead Softbox Array (arranged around zenith, NOT directly on zenith):\n // Positioned at 40°-50° angles around the zenith to illuminate the crown facets and pump light\n // into the pavilion without placing a blinding direct glare on the flat table facet.\n const upperSoftboxes: Array<{ pos: [number, number, number]; size: [number, number]; intensity: number }> = [\n { pos: [0, 15, 8], size: [10, 8], intensity: 4.5 }, // Front-top key\n { pos: [0, 15, -8], size: [10, 8], intensity: 4.0 }, // Back-top rim\n { pos: [-9, 14, 0], size: [8, 10], intensity: 4.0 }, // Left-top fill\n { pos: [9, 14, 0], size: [8, 10], intensity: 4.0 }, // Right-top fill\n ]\n\n for (const p of upperSoftboxes) {\n const geo = new THREE.PlaneGeometry(p.size[0], p.size[1])\n const mat = new THREE.MeshBasicMaterial({ color: 0xffffff, side: THREE.DoubleSide })\n mat.color.setScalar(p.intensity)\n const mesh = new THREE.Mesh(geo, mat)\n mesh.position.set(p.pos[0], p.pos[1], p.pos[2])\n mesh.lookAt(0, 0, 0)\n this.add(mesh)\n }\n\n // 3. Lateral Wing Softboxes (Profile & Pavé/Side Stone Illumination):\n const lateralSoftboxes: Array<{ pos: [number, number, number]; size: [number, number]; intensity: number }> = [\n { pos: [-13, 8, 6], size: [8, 9], intensity: 3.5 },\n { pos: [13, 8, 6], size: [8, 9], intensity: 3.5 },\n { pos: [0, 8, 14], size: [10, 7], intensity: 3.8 },\n { pos: [0, 8, -14], size: [10, 7], intensity: 3.2 },\n ]\n\n for (const p of lateralSoftboxes) {\n const geo = new THREE.PlaneGeometry(p.size[0], p.size[1])\n const mat = new THREE.MeshBasicMaterial({ color: 0xffffff, side: THREE.DoubleSide })\n mat.color.setScalar(p.intensity)\n const mesh = new THREE.Mesh(geo, mat)\n mesh.position.set(p.pos[0], p.pos[1], p.pos[2])\n mesh.lookAt(0, 0, 0)\n this.add(mesh)\n }\n\n // 4. Center Zenith Camera Body Baffle:\n // Simulates the camera card overhead for contrast definition without a black void.\n const zenithBaffleGeo = new THREE.PlaneGeometry(5.0, 5.0)\n const zenithBaffleMat = new THREE.MeshBasicMaterial({\n color: 0x404550,\n side: THREE.DoubleSide,\n })\n const zenithBaffle = new THREE.Mesh(zenithBaffleGeo, zenithBaffleMat)\n zenithBaffle.position.set(0, 18, 0)\n zenithBaffle.rotation.x = Math.PI / 2\n this.add(zenithBaffle)\n\n // 5. Ground Plane:\n // Studio ground bounce preventing downward rays from turning black.\n const groundGeo = new THREE.PlaneGeometry(24, 24)\n const groundMat = new THREE.MeshBasicMaterial({\n color: 0x505662,\n side: THREE.DoubleSide,\n })\n const ground = new THREE.Mesh(groundGeo, groundMat)\n ground.position.set(0, -12, 0)\n ground.rotation.x = -Math.PI / 2\n this.add(ground)\n\n // 6. Geometric Contrast Flags (Soft charcoal cards for subtle facet definition without pitch-black triangles):\n const flagGeo = new THREE.PlaneGeometry(1.4, 15)\n const flagMat = new THREE.MeshBasicMaterial({\n color: 0x383e4a,\n side: THREE.DoubleSide,\n })\n const flagPositions: [number, number, number][] = [\n [7, 11, 7],\n [-7, 11, 7],\n [7, 11, -7],\n [-7, 11, -7],\n ]\n for (const [fx, fy, fz] of flagPositions) {\n const flag = new THREE.Mesh(flagGeo, flagMat)\n flag.position.set(fx, fy, fz)\n flag.lookAt(0, 0, 0)\n this.add(flag)\n }\n\n // 7. 10 High-Radiance Pinpoint Emitter Panels for Dispersion Fire & Scintillation:\n const emitterPositions: [number, number, number][] = [\n [10, 13, 7],\n [-10, 13, 7],\n [10, 13, -7],\n [-10, 13, -7],\n [14, 6, 9],\n [-14, 6, 9],\n [14, 6, -9],\n [-14, 6, -9],\n [0, 6, 17],\n [7, -6, 8],\n ]\n\n for (const [x, y, z] of emitterPositions) {\n const panelGeo = new THREE.PlaneGeometry(2.6, 2.6)\n const panelMat = new THREE.MeshBasicMaterial({\n color: 0xffffff,\n side: THREE.DoubleSide,\n })\n panelMat.color.setScalar(45.0)\n const panel = new THREE.Mesh(panelGeo, panelMat)\n panel.position.set(x, y, z)\n panel.lookAt(0, 0, 0)\n this.add(panel)\n }\n }\n\n dispose(): void {\n const resources = new Set<THREE.BufferGeometry | THREE.Material>()\n this.traverse((obj) => {\n if (obj instanceof THREE.Mesh) {\n if (obj.geometry) resources.add(obj.geometry)\n if (obj.material) {\n if (Array.isArray(obj.material)) {\n obj.material.forEach((m) => resources.add(m))\n } else {\n resources.add(obj.material)\n }\n }\n }\n })\n for (const res of resources) {\n res.dispose()\n }\n this.clear()\n }\n}\n\n/**\n * Generates high-radiance gem HDR cubemap texture via CubeCamera.\n */\nexport function setupGemEnvironment(\n renderer: THREE.WebGLRenderer,\n source?: THREE.Scene,\n size = 512,\n): THREE.Texture {\n const cubeTarget = new THREE.WebGLCubeRenderTarget(size, {\n format: THREE.RGBAFormat,\n type: THREE.HalfFloatType,\n generateMipmaps: false,\n minFilter: THREE.LinearFilter,\n magFilter: THREE.LinearFilter,\n })\n\n const cubeCamera = new THREE.CubeCamera(0.1, 100, cubeTarget)\n const gemEnv = source ?? new JewelryGemEnvironment()\n\n const prevTarget = renderer?.getRenderTarget ? renderer.getRenderTarget() : null\n\n cubeCamera.update(renderer, gemEnv)\n\n if (renderer?.setRenderTarget) {\n renderer.setRenderTarget(prevTarget)\n }\n\n if (!source && gemEnv instanceof JewelryGemEnvironment) {\n gemEnv.dispose()\n }\n\n return cubeTarget.texture\n}\n\nimport { EXRLoader } from 'three/examples/jsm/loaders/EXRLoader.js'\n\nexport interface HdrEnvironmentHandle {\n renderTarget: THREE.WebGLRenderTarget\n texture: THREE.Texture\n gemRenderTarget?: THREE.WebGLCubeRenderTarget\n gemTexture?: THREE.Texture\n dispose: () => void\n}\n\n/**\n * Loads an HDR or EXR equirectangular environment and converts it to:\n * 1. A PMREM-filtered texture for scene.environment (PBR metals)\n * 2. A true WebGLCubeRenderTarget cubemap for DiamondMaterial\n */\nexport async function loadHdrEnvironment(\n urlOrData: string | ArrayBuffer,\n renderer: THREE.WebGLRenderer,\n): Promise<HdrEnvironmentHandle> {\n const pmremGenerator = new THREE.PMREMGenerator(renderer)\n pmremGenerator.compileEquirectangularShader()\n\n function processDataTexture(dataTexture: THREE.DataTexture): HdrEnvironmentHandle {\n const renderTarget = pmremGenerator.fromEquirectangular(dataTexture)\n let gemRenderTarget: THREE.WebGLCubeRenderTarget | undefined\n try {\n gemRenderTarget = new THREE.WebGLCubeRenderTarget(512, {\n format: THREE.RGBAFormat,\n type: THREE.HalfFloatType,\n generateMipmaps: true,\n minFilter: THREE.LinearMipmapLinearFilter,\n magFilter: THREE.LinearFilter,\n })\n gemRenderTarget.fromEquirectangularTexture(renderer, dataTexture)\n } catch {\n // Graceful fallback for mock environments or tests\n }\n dataTexture.dispose()\n pmremGenerator.dispose()\n\n return {\n renderTarget,\n texture: renderTarget.texture,\n gemRenderTarget,\n gemTexture: gemRenderTarget ? gemRenderTarget.texture : renderTarget.texture,\n dispose: () => {\n renderTarget.dispose()\n gemRenderTarget?.dispose()\n },\n }\n }\n\n const isExr = typeof urlOrData === 'string'\n ? urlOrData.toLowerCase().includes('.exr')\n : (urlOrData instanceof ArrayBuffer && urlOrData.byteLength >= 4 &&\n new Uint8Array(urlOrData, 0, 4)[0] === 0x76 &&\n new Uint8Array(urlOrData, 0, 4)[1] === 0x2f)\n\n if (urlOrData instanceof ArrayBuffer) {\n try {\n if (isExr) {\n const res = new EXRLoader().parse(urlOrData)\n const dataTex = new THREE.DataTexture(res.data, res.width, res.height, res.format, res.type)\n dataTex.needsUpdate = true\n return processDataTexture(dataTex)\n } else {\n const dataTexture = new RGBELoader().parse(urlOrData) as unknown as THREE.DataTexture\n return processDataTexture(dataTexture)\n }\n } catch (err) {\n pmremGenerator.dispose()\n throw err\n }\n }\n\n return new Promise<HdrEnvironmentHandle>((resolve, reject) => {\n if (isExr) {\n new EXRLoader().load(\n urlOrData,\n (dataTex) => {\n try {\n resolve(processDataTexture(dataTex as unknown as THREE.DataTexture))\n } catch (err) {\n dataTex.dispose()\n pmremGenerator.dispose()\n reject(err)\n }\n },\n undefined,\n (err) => {\n pmremGenerator.dispose()\n reject(err)\n },\n )\n } else {\n new RGBELoader().load(\n urlOrData,\n (hdrTexture) => {\n try {\n resolve(processDataTexture(hdrTexture as unknown as THREE.DataTexture))\n } catch (err) {\n hdrTexture.dispose()\n pmremGenerator.dispose()\n reject(err)\n }\n },\n undefined,\n (err) => {\n pmremGenerator.dispose()\n reject(err)\n },\n )\n }\n })\n}\n\n\n","import * as THREE from 'three'\nimport { MeshBVH, MeshBVHUniformStruct, SAH } from 'three-mesh-bvh'\n\nconst bvhCache = new WeakMap<THREE.BufferGeometry, MeshBVHUniformStruct>()\n\n/**\n * Builds or retrieves the GPU MeshBVH acceleration structure for a diamond geometry.\n * Handles geometries with multi-groups gracefully by ensuring a single-root tree.\n */\nexport function getOrCreateDiamondBVH(geometry: THREE.BufferGeometry): MeshBVHUniformStruct {\n const cached = bvhCache.get(geometry)\n if (cached) return cached\n\n let targetGeom = geometry\n if (geometry.groups && geometry.groups.length > 1) {\n targetGeom = geometry.clone()\n targetGeom.clearGroups()\n }\n\n const boundsTree = (targetGeom as any).boundsTree ?? new MeshBVH(targetGeom, {\n strategy: SAH,\n setBoundingBox: false,\n })\n ;(targetGeom as any).boundsTree = boundsTree\n\n const bvhStruct = new MeshBVHUniformStruct()\n bvhStruct.updateFrom(boundsTree)\n\n bvhCache.set(geometry, bvhStruct)\n return bvhStruct\n}\n","import * as THREE from 'three'\nimport type { StonePreset } from './presets'\nimport { DiamondMaterial, acquireDiamondMaterial } from './diamond-material'\nimport type { BakeHandle } from './gem-geometry'\n\nexport interface PmatJson {\n type: string\n name?: string\n color: number | string\n roughness: number\n metalness: number\n clearcoat?: number\n clearcoatRoughness?: number\n sheen?: number\n sheenColor?: number | string\n sheenRoughness?: number\n specularIntensity?: number\n specularColor?: number | string\n iridescence?: number\n iridescenceIOR?: number\n anisotropy?: number\n envMapIntensity?: number\n reflectivity?: number\n transmission?: number\n thickness?: number\n attenuationDistance?: number\n attenuationColor?: number | string\n side?: number\n [key: string]: unknown\n}\n\nexport interface DmatJson {\n type: string\n name?: string\n color: number | string\n refractiveIndex?: number\n dispersion?: number\n rayBounces?: number\n squashFactor?: number\n geometryFactor?: number\n gammaFactor?: number\n absorptionFactor?: number\n reflectivity?: number\n envMapIntensity?: number\n boostFactors?: { x: number; y: number; z: number; isVector3?: boolean }\n transmission?: number\n [key: string]: unknown\n}\n\nfunction parseJson<T>(input: string | T): T {\n if (typeof input === 'string') {\n return JSON.parse(input) as T\n }\n return input\n}\n\nfunction toColorHex(value: number | string): string {\n if (typeof value === 'string') {\n return value.startsWith('#') ? value : `#${value}`\n }\n return '#' + (value >>> 0).toString(16).padStart(6, '0')\n}\n\n/**\n * Parses a RenderMyJewelry .pmat JSON export into a Three.js MeshPhysicalMaterial.\n */\nexport function loadPmat(input: string | PmatJson): THREE.MeshPhysicalMaterial {\n const json = parseJson<PmatJson>(input)\n\n const side = json.side === 2\n ? THREE.DoubleSide\n : json.side === 1\n ? THREE.BackSide\n : THREE.FrontSide\n\n const mat = new THREE.MeshPhysicalMaterial({\n name: json.name ?? 'pmat-metal',\n color: new THREE.Color(toColorHex(json.color)),\n roughness: json.roughness ?? 0.0,\n metalness: json.metalness ?? 1.0,\n envMapIntensity: json.envMapIntensity ?? 1.0,\n clearcoat: json.clearcoat ?? 0.0,\n clearcoatRoughness: json.clearcoatRoughness ?? 0.0,\n side,\n })\n\n if (json.specularColor !== undefined) {\n mat.specularColor = new THREE.Color(toColorHex(json.specularColor))\n }\n if (json.specularIntensity !== undefined) {\n mat.specularIntensity = json.specularIntensity\n }\n if (json.reflectivity !== undefined) {\n mat.reflectivity = json.reflectivity\n }\n\n return mat\n}\n\n/**\n * Parses a RenderMyJewelry .dmat JSON export into a calibrated StonePreset object.\n */\nexport function loadDmatPreset(input: string | DmatJson): StonePreset {\n const json = parseJson<DmatJson>(input)\n const hex = toColorHex(json.color ?? 0xffffff)\n const bf = json.boostFactors ?? { x: 1, y: 1, z: 1 }\n\n return {\n id: json.name ? `dmat-${json.name.toLowerCase().replace(/\\s+/g, '-')}` : 'dmat-custom',\n label: json.name ?? 'Custom Diamond',\n hex,\n ior: json.refractiveIndex ?? 2.6,\n dispersion: json.dispersion ?? 0.01,\n absorptionFactor: json.absorptionFactor ?? 0.0,\n roughness: 0.0,\n transmission: json.transmission ?? 0.0,\n boostFactors: [bf.x, bf.y, bf.z],\n category: 'diamond',\n ...(json.squashFactor !== undefined ? { squashFactor: json.squashFactor } : {}),\n ...(json.geometryFactor !== undefined ? { geometryFactor: json.geometryFactor } : {}),\n ...(json.gammaFactor !== undefined ? { gammaFactor: json.gammaFactor } : {}),\n }\n}\n\n/**\n * Instantiates or acquires a DiamondMaterial from a .dmat JSON definition.\n */\nexport function loadDmatMaterial(\n input: string | DmatJson,\n handle: BakeHandle,\n envMap: THREE.Texture,\n): DiamondMaterial {\n const preset = loadDmatPreset(input)\n return acquireDiamondMaterial(handle, envMap, preset)\n}\n","/**\n * diamond-reference-shaders.ts\n *\n * Clean-room GLSL 3.00 es shaders for ReferenceDiamondMaterial.\n * Algorithm derived from DIAMOND_PLAN.md §3.2 pseudocode.\n * BRDF: Lazarov/Karis, Siggraph 2014 \"Getting More Physical in Call of Duty\".\n * DO NOT incorporate text from rendermyjewelry_research/shaders/diamond.frag.glsl.\n */\n\nexport const DIAMOND_REF_VERT = /* glsl */ `\nprecision highp float;\n\nout vec3 vWorldNormal;\nout vec3 vWorldPosition;\n\nvoid main() {\n vec4 worldPos = modelMatrix * vec4(position, 1.0);\n vWorldPosition = worldPos.xyz;\n vWorldNormal = normalize(mat3(modelMatrix) * normal);\n gl_Position = projectionMatrix * viewMatrix * worldPos;\n}\n`\n\n// Compile-time defines injected by ReferenceDiamondMaterial:\n// RAY_BOUNCES — int (3/5/6/8)\n// ENV_MAP_TYPE — 0=samplerCube, 1=sampler2D equirect\n// DIA_ORIENT_ENVMAP — 0=apply modelOffset, 1=skip\n// HAS_GEM_INCLUSIONS — 0 (MVP always 0)\n// GEM_NORMALS_UNORM — 0=signed HalfFloat, 1=unorm 8-bit\n\nexport const DIAMOND_REF_FRAG = /* glsl */ `\nprecision highp float;\nprecision highp sampler2D;\nprecision highp samplerCube;\n\nuniform mat4 modelOffsetMatrix;\nuniform mat4 modelOffsetMatrixInv;\nuniform mat4 viewMatrixUniform;\n\nuniform samplerCube tCubeMapNormals;\nuniform float radius;\nuniform vec3 centerOffset;\n\n#if ENV_MAP_TYPE == 0\n uniform samplerCube envMap;\n#else\n uniform sampler2D envMap;\n#endif\nuniform float envMapRotation;\nuniform float envMapIntensity;\n\nuniform float refractiveIndex;\nuniform float rIndexDelta;\nuniform float absorptionFactor;\nuniform float squashFactor;\nuniform float geometryFactor;\nuniform float gammaFactor;\nuniform float ambientFloor;\nuniform float reflectivity;\nuniform vec3 boostFactors;\nuniform vec3 color;\nuniform vec3 colorCorrection;\nuniform float transmission;\nuniform bool clampHDR;\nuniform bool useInclusion;\n\nin vec3 vWorldNormal;\nin vec3 vWorldPosition;\nout vec4 fragColor;\n\n// Lazarov/Karis 2014 BRDF (Siggraph, published constants — safe to reproduce)\nvec3 brdfGGXEnv(vec3 viewDir, vec3 normal, vec3 f0, float roughness) {\n float dotNV = abs(dot(normal, viewDir));\n vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);\n vec4 c1 = vec4( 1.0, 0.0425, 1.04, -0.04);\n vec4 r = roughness * c0 + c1;\n float a004 = min(r.x * r.x, exp2(-9.28 * dotNV)) * r.x + r.y;\n vec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;\n return f0 * AB.x + AB.y;\n}\n\nvec3 rotateY(vec3 d, float a) {\n float c = cos(a), s = sin(a);\n return vec3(c*d.x + s*d.z, d.y, -s*d.x + c*d.z);\n}\n\nvec4 sampleEnvMap(vec3 dir, float roughness) {\n dir = rotateY(dir, envMapRotation);\n dir = -dir; // full negate per reference algorithm (DIAMOND_PLAN §3.4 step 6)\n#if ENV_MAP_TYPE == 0\n return envMapIntensity * textureLod(envMap, dir, roughness * 8.0);\n#else\n float u = atan(dir.z, dir.x) / (2.0 * 3.14159265) + 0.5;\n float v = asin(clamp(dir.y, -1.0, 1.0)) / 3.14159265 + 0.5;\n return envMapIntensity * textureLod(envMap, vec2(u, v), roughness * 8.0);\n#endif\n}\n\n// Internal bounce: apply modelOffset + view-space + xz-flip (DIAMOND_PLAN §3.4)\nvec4 sampleInternalEnv(vec3 dir, float roughness) {\n#if DIA_ORIENT_ENVMAP < 1\n dir = mat3(modelOffsetMatrix) * dir;\n#endif\n dir = (viewMatrixUniform * vec4(dir, 0.0)).xyz;\n dir = normalize(dir);\n dir.x *= -1.0;\n dir.z *= -1.0;\n vec4 sharpLight = sampleEnvMap(dir, roughness);\n if (ambientFloor > 0.0) {\n vec4 diffuseLight = sampleEnvMap(dir, 0.85);\n return max(sharpLight, diffuseLight * ambientFloor);\n }\n return sharpLight;\n}\n\n// Front surface: only viewMatrix (DIAMOND_PLAN §10.6)\nvec4 sampleFrontEnv(vec3 dir, float roughness) {\n dir = (viewMatrixUniform * vec4(dir, 0.0)).xyz;\n return sampleEnvMap(dir, roughness);\n}\n\n// Line-plane intersection with divide-by-zero guard (DIAMOND_PLAN §10.1)\nvec3 linePlaneIntersect(vec3 p, vec3 d, vec3 pp, vec3 pn) {\n float denom = dot(pn, d);\n if (abs(denom) < 1e-6) return p; // ray parallel to plane\n return p + d * (dot(pn, pp - p) / denom);\n}\n\n// Sphere intersect with squash and sphere-miss guard (DIAMOND_PLAN §2.2, §6)\n// Returns vec3(0) on miss — caller checks length < 1e-6\nvec3 intersectSphere(vec3 origin, vec3 dir) {\n vec3 o = origin - centerOffset;\n float savedY = dir.y;\n dir.y /= squashFactor;\n float A = dot(dir, dir);\n float B = 2.0 * dot(o, dir);\n float C = dot(o, o) - radius * radius;\n float disc = B*B - 4.0*A*C;\n if (disc <= 0.0) return vec3(0.0); // miss\n float sqrtDisc = sqrt(disc);\n float t = max((-B + sqrtDisc) * geometryFactor / A,\n (-B - sqrtDisc) * geometryFactor / A);\n dir.y = savedY;\n return origin + dir * t; // origin + dir * t (rayOrigin preserved)\n}\n\nstruct HitResult { vec3 point; vec3 normal; };\n\n// Facet normal decoding respecting GEM_NORMALS_UNORM define\nvec3 decodeFacetNormal(vec3 raw) {\n#if GEM_NORMALS_UNORM == 1\n return -normalize(raw * 2.0 - 1.0);\n#else\n return -normalize(raw);\n#endif\n}\n\nHitResult doIntersect(vec3 origin, vec3 dir) {\n vec3 sphereHit = intersectSphere(origin, dir);\n if (length(sphereHit) < 1e-6) {\n return HitResult(origin, vec3(0.0, 1.0, 0.0)); // miss sentinel\n }\n // Stage 2: first facet (nd.a is perpendicular plane distance D in radius units; pn is -normal)\n vec3 d1 = normalize(sphereHit - centerOffset);\n vec4 nd1 = texture(tCubeMapNormals, d1);\n vec3 pn1 = decodeFacetNormal(nd1.rgb);\n vec3 hp1 = linePlaneIntersect(origin, dir, centerOffset - pn1 * (nd1.a * radius), pn1);\n // Stage 3: second facet\n vec3 d2 = normalize(hp1 - centerOffset);\n vec4 nd2 = texture(tCubeMapNormals, d2);\n vec3 pn2 = decodeFacetNormal(nd2.rgb);\n vec3 hp2 = linePlaneIntersect(origin, dir, centerOffset - pn2 * (nd2.a * radius), pn2);\n return HitResult(hp2, pn2);\n}\n\nvec3 getRefractionColor(vec3 worldOrigin, vec3 viewDir, vec3 surfaceNormal, vec3 f0) {\n float ior = refractiveIndex;\n vec3 entryRefracted = refract(viewDir, surfaceNormal, 1.0 / ior);\n if (dot(entryRefracted, entryRefracted) < 1e-4) return vec3(0.0);\n\n vec3 brdfEntry = brdfGGXEnv(entryRefracted, -surfaceNormal, f0, 0.0);\n vec3 attenuation = vec3(1.0) - brdfEntry;\n\n vec3 origin = (modelOffsetMatrixInv * vec4(worldOrigin, 1.0)).xyz;\n vec3 dir = normalize((modelOffsetMatrixInv * vec4(entryRefracted, 0.0)).xyz);\n\n vec3 outColor = vec3(0.0);\n\n for (int i = 0; i < RAY_BOUNCES; i++) {\n HitResult hit = doIntersect(origin, dir);\n // Sphere-miss: hit.point == origin (sentinel) — break after first iteration\n if (i > 0 && length(hit.point - origin) < 1e-6) break;\n\n // Third cube lookup for mapped normal (DIAMOND_PLAN §2.3)\n vec3 d3 = normalize(hit.point - centerOffset);\n vec4 nd3 = texture(tCubeMapNormals, d3);\n vec3 mappedNormal = decodeFacetNormal(nd3.rgb);\n\n // Beer-Lambert (DIAMOND_PLAN §2.4)\n float r = length(hit.point - origin) / radius * absorptionFactor;\n attenuation *= exp(-r * (vec3(1.0) - color));\n\n origin = hit.point;\n vec3 oldDir = dir;\n dir = refract(oldDir, mappedNormal, ior / 1.0);\n\n if (dot(dir, dir) < 1e-4) {\n // TIR — DIAMOND_PLAN §2.7 + §10.5 correction: use -oldDir for BRDF\n dir = reflect(oldDir, mappedNormal);\n if (i == RAY_BOUNCES - 1) {\n vec3 brdfTIR = brdfGGXEnv(-oldDir, mappedNormal, f0, 0.0);\n vec4 envS = sampleInternalEnv(oldDir, 0.0);\n outColor += envS.rgb * (vec3(1.0) - brdfTIR) * attenuation * colorCorrection * boostFactors;\n }\n } else {\n // Exit — dispersed RGB (wavelength-dependent refraction)\n vec3 dir0 = dir;\n vec3 dir1 = refract(oldDir, mappedNormal, (ior + rIndexDelta) / 1.0);\n vec3 dir2 = refract(oldDir, mappedNormal, (ior - rIndexDelta) / 1.0);\n\n vec3 brdfExit = vec3(1.0) - min(vec3(1.0), brdfGGXEnv(dir0, -mappedNormal, f0, 0.0));\n vec3 envRGB = vec3(\n dot(dir1, dir1) > 1e-4 ? sampleInternalEnv(dir1, 0.0).r : 0.0,\n dot(dir0, dir0) > 1e-4 ? sampleInternalEnv(dir0, 0.0).g : 0.0,\n dot(dir2, dir2) > 1e-4 ? sampleInternalEnv(dir2, 0.0).b : 0.0\n );\n outColor += envRGB * brdfExit * attenuation * colorCorrection * boostFactors;\n\n dir = reflect(oldDir, mappedNormal);\n attenuation *= brdfGGXEnv(dir, mappedNormal, f0, 0.0) * boostFactors; // §2.8 compounding\n }\n }\n return outColor;\n}\n\nvoid main() {\n vec3 N = normalize(vWorldNormal);\n vec3 V = normalize(vWorldPosition - cameraPosition);\n float ior = refractiveIndex;\n float f0s = pow((ior - 1.0) / (ior + 1.0), 2.0);\n vec3 f0 = vec3(f0s);\n\n vec3 reflDir = reflect(V, N);\n vec3 brdfFront = brdfGGXEnv(reflDir, N, f0, 0.0);\n\n // Tint specular shine for colored gems, keep pure white for black & colorless stones\n float maxC = max(max(color.r, color.g), color.b);\n float minC = min(min(color.r, color.g), color.b);\n float chroma = maxC - minC;\n float lum = dot(color, vec3(0.299, 0.587, 0.114));\n\n vec3 reflTint = vec3(1.0);\n if (chroma >= 0.05 && lum >= 0.15 && maxC > 0.001) {\n vec3 gemHue = color / maxC;\n reflTint = mix(vec3(1.0), gemHue, 0.70);\n }\n\n vec3 rawEnv = sampleFrontEnv(reflDir, 0.0).rgb;\n vec3 reflectionColor = rawEnv * brdfFront * reflectivity * 2.0 * reflTint;\n\n // Subtle ambient surface luster so facets never drop to harsh pitch black\n if (ambientFloor > 0.0 || lum < 0.2) {\n vec3 ambientEnv = sampleFrontEnv(reflDir, 0.7).rgb;\n float luster = (lum < 0.2) ? 0.6 : (ambientFloor * 2.0);\n reflectionColor += ambientEnv * f0 * luster;\n }\n\n vec3 refractionColor = getRefractionColor(vWorldPosition, V, N, f0);\n vec3 outColor = reflectionColor + refractionColor;\n\n if (gammaFactor != 1.0) {\n outColor = pow(max(outColor, vec3(0.0)), vec3(gammaFactor));\n }\n if (clampHDR) outColor = min(outColor, vec3(1.0));\n\n fragColor = vec4(outColor, 1.0);\n#define gl_FragColor fragColor\n #include <colorspace_fragment>\n}\n`\n","import * as THREE from 'three'\nimport { DIAMOND_REF_VERT, DIAMOND_REF_FRAG } from './diamond-reference-shaders'\nimport type { BakeHandle } from './gem-geometry'\nimport type { StonePreset } from './presets'\n\nexport type DiamondMode = 'reference' | 'physical'\n\nexport type DiamondQuality = 'low' | 'medium' | 'high' | 'ultra'\n\n/** Maps a quality tier to compile-time bounce count and cube-map resolution.\n * DIAMOND_PLAN.md §5.3 Phase 4 table. */\nexport function resolveQualityTier(q: DiamondQuality): { rayBounces: number; cubeResolution: 128 | 256 | 512 } {\n switch (q) {\n case 'low': return { rayBounces: 3, cubeResolution: 128 }\n case 'medium':return { rayBounces: 5, cubeResolution: 256 }\n case 'high': return { rayBounces: 6, cubeResolution: 256 }\n case 'ultra': return { rayBounces: 8, cubeResolution: 512 }\n }\n}\n\nexport interface ReferenceDiamondMaterialOptions {\n rayBounces?: number // explicit bounce count — overridden by quality when both are set\n quality?: DiamondQuality // auto-sets rayBounces; quality wins over explicit rayBounces\n orientEnvMap?: boolean // DIA_ORIENT_ENVMAP, default: false\n}\n\nconst _invMat = new THREE.Matrix4()\n\nexport class ReferenceDiamondMaterial extends THREE.ShaderMaterial {\n bakeHandle: BakeHandle\n preset: StonePreset\n onBeforeRender: (\n renderer: THREE.WebGLRenderer,\n scene: THREE.Scene,\n camera: THREE.Camera,\n geometry: THREE.BufferGeometry,\n object: THREE.Object3D,\n ) => void\n\n constructor(\n handle: BakeHandle,\n envMap: THREE.Texture,\n preset: StonePreset,\n opts: ReferenceDiamondMaterialOptions = {},\n ) {\n // quality wins over explicit rayBounces\n const resolvedBounces = opts.quality\n ? resolveQualityTier(opts.quality).rayBounces\n : (opts.rayBounces ?? 5)\n const rayBounces = resolvedBounces\n const isCube = (envMap as any).isCubeTexture === true\n const bf = preset.boostFactors ?? [1.0, 1.0, 1.0]\n const [bfR, bfG, bfB] = bf\n\n super({\n vertexShader: DIAMOND_REF_VERT,\n fragmentShader: DIAMOND_REF_FRAG,\n glslVersion: THREE.GLSL3,\n defines: {\n RAY_BOUNCES: rayBounces,\n ENV_MAP_TYPE: isCube ? 0 : 1,\n DIA_ORIENT_ENVMAP: opts.orientEnvMap ? 1 : 0,\n HAS_GEM_INCLUSIONS: 0,\n GEM_NORMALS_UNORM: handle.encoding === 'unorm' ? 1 : 0,\n },\n uniforms: {\n // Per-frame (set in onBeforeRender)\n modelOffsetMatrix: { value: new THREE.Matrix4() },\n modelOffsetMatrixInv: { value: new THREE.Matrix4() },\n viewMatrixUniform: { value: new THREE.Matrix4() },\n cameraPosition: { value: new THREE.Vector3() },\n // Gem geometry\n tCubeMapNormals: { value: handle.texture },\n radius: { value: handle.radius ?? 1.0 },\n centerOffset: { value: handle.centroid ? handle.centroid.clone() : new THREE.Vector3() },\n // Environment\n envMap: { value: envMap },\n envMapRotation: { value: 0.0 },\n envMapIntensity: { value: preset.envMapIntensity ?? 1.0 },\n // Material\n refractiveIndex: { value: preset.ior ?? 2.6 },\n rIndexDelta: { value: preset.dispersion ?? 0.012 },\n absorptionFactor:{ value: preset.absorptionFactor ?? 1.0 },\n squashFactor: { value: preset.squashFactor ?? 0.98 },\n geometryFactor: { value: preset.geometryFactor ?? 0.5 },\n gammaFactor: { value: preset.gammaFactor ?? 1.0 },\n ambientFloor: { value: preset.ambientFloor ?? 0.05 },\n reflectivity: { value: 0.5 },\n boostFactors: { value: new THREE.Vector3(bfR, bfG, bfB) },\n color: { value: new THREE.Color(preset.hex) },\n colorCorrection: { value: new THREE.Vector3(1, 1, 1) },\n transmission: { value: 0.0 },\n clampHDR: { value: false },\n useInclusion: { value: false },\n },\n side: THREE.FrontSide,\n transparent: false,\n depthTest: true,\n depthWrite: true,\n toneMapped: true,\n })\n\n this.bakeHandle = handle\n this.preset = { ...preset }\n\n this.onBeforeRender = (\n _r: THREE.WebGLRenderer,\n _s: THREE.Scene,\n camera: THREE.Camera,\n _g: THREE.BufferGeometry,\n object: THREE.Object3D,\n ) => {\n camera.getWorldPosition(this.uniforms.cameraPosition.value as THREE.Vector3)\n ;(this.uniforms.modelOffsetMatrix.value as THREE.Matrix4).copy(object.matrixWorld)\n _invMat.copy(object.matrixWorld).invert()\n ;(this.uniforms.modelOffsetMatrixInv.value as THREE.Matrix4).copy(_invMat)\n ;(this.uniforms.viewMatrixUniform.value as THREE.Matrix4).copy(camera.matrixWorldInverse)\n }\n }\n\n updatePreset(preset: StonePreset): void {\n this.preset = { ...this.preset, ...preset }\n this.uniforms.refractiveIndex.value = preset.ior ?? 2.6\n this.uniforms.rIndexDelta.value = preset.dispersion ?? 0.012\n this.uniforms.absorptionFactor.value = preset.absorptionFactor ?? 1.0\n ;(this.uniforms.color.value as THREE.Color).set(preset.hex)\n if (preset.squashFactor !== undefined) this.uniforms.squashFactor.value = preset.squashFactor\n if (preset.geometryFactor !== undefined) this.uniforms.geometryFactor.value = preset.geometryFactor\n if (preset.gammaFactor !== undefined) this.uniforms.gammaFactor.value = preset.gammaFactor\n if (preset.envMapIntensity !== undefined) this.uniforms.envMapIntensity.value = preset.envMapIntensity\n if (preset.ambientFloor !== undefined) this.uniforms.ambientFloor.value = preset.ambientFloor\n if (preset.boostFactors) {\n const [r, g, b] = preset.boostFactors\n ;(this.uniforms.boostFactors.value as THREE.Vector3).set(r, g, b)\n }\n this.uniformsNeedUpdate = true\n }\n\n setEnvMap(tex: THREE.Texture): void {\n this.uniforms.envMap.value = tex\n const isCube = (tex as any).isCubeTexture === true\n const newType = isCube ? 0 : 1\n if (this.defines['ENV_MAP_TYPE'] !== newType) {\n this.defines['ENV_MAP_TYPE'] = newType\n this.needsUpdate = true\n }\n }\n\n clone(): this {\n const cloned = new ReferenceDiamondMaterial(\n this.bakeHandle,\n this.uniforms.envMap.value,\n this.preset,\n {\n orientEnvMap: this.defines['DIA_ORIENT_ENVMAP'] === 1,\n rayBounces: this.defines['RAY_BOUNCES'],\n },\n ) as this\n cloned.name = this.name\n if (this.uniforms.color?.value) {\n ;(cloned.uniforms.color.value as THREE.Color).copy(this.uniforms.color.value as THREE.Color)\n }\n return cloned\n }\n}\n\n// ── Material cache ────────────────────────────────────────────────────────\n\ninterface CacheEntry { material: ReferenceDiamondMaterial; refCount: number }\nconst materialCache = new Map<string, CacheEntry>()\n\nexport function acquireReferenceDiamondMaterial(\n handle: BakeHandle,\n envMap: THREE.Texture,\n preset: StonePreset,\n opts: ReferenceDiamondMaterialOptions = {},\n): ReferenceDiamondMaterial {\n const qualityKey = opts.quality ?? `b${opts.rayBounces ?? 5}`\n const orientKey = opts.orientEnvMap ? '_o1' : '_o0'\n const key = `ref_${handle.key}_${preset.id}_${preset.hex}_${qualityKey}${orientKey}`\n const existing = materialCache.get(key)\n if (existing) { existing.refCount++; return existing.material }\n const mat = new ReferenceDiamondMaterial(handle, envMap, preset, opts)\n materialCache.set(key, { material: mat, refCount: 1 })\n return mat\n}\n\nexport function releaseReferenceDiamondMaterial(mat: ReferenceDiamondMaterial): void {\n for (const [key, entry] of materialCache.entries()) {\n if (entry.material === mat) {\n entry.refCount--\n if (entry.refCount <= 0) { mat.dispose(); materialCache.delete(key) }\n return\n }\n }\n}\n","import * as THREE from 'three'\nimport {\n METAL_PRESETS,\n STONE_PRESETS,\n PHYSICALLY_BASED_METAL_PRESETS,\n DIAMOND_PRESETS,\n GEMSTONE_PRESETS,\n ALL_METAL_PRESETS,\n ALL_STONE_PRESETS,\n} from './presets'\nimport { globalDiamondBaker, type BakeHandle } from './diamond-baker'\nimport { DiamondMaterial, acquireDiamondMaterial, releaseDiamondMaterial } from './diamond-material'\nimport { setupGemEnvironment, JewelryGemEnvironment, setupEnvironment, loadHdrEnvironment, type HdrEnvironmentHandle } from './environment'\nimport { getOrCreateDiamondBVH } from './diamond-bvh'\nimport { loadPmat, loadDmatPreset, loadDmatMaterial, type PmatJson, type DmatJson } from './format-loaders'\nimport {\n ReferenceDiamondMaterial,\n acquireReferenceDiamondMaterial,\n releaseReferenceDiamondMaterial,\n resolveQualityTier,\n type DiamondMode,\n type DiamondQuality,\n} from './diamond-reference-material'\n\nexport { setupEnvironment, setupGemEnvironment, JewelryGemEnvironment, loadHdrEnvironment }\nexport type { HdrEnvironmentHandle }\nexport { globalDiamondBaker, DiamondMaterial, acquireDiamondMaterial, releaseDiamondMaterial }\nexport type { BakeHandle }\nexport { loadPmat, loadDmatPreset, loadDmatMaterial }\nexport type { PmatJson, DmatJson }\n\nexport function applyMetalMaterial(mesh: THREE.Mesh, hexOrPresetId: string, slotIndex?: number): void {\n const preset =\n ALL_METAL_PRESETS.find((p) => p.id === hexOrPresetId) ??\n METAL_PRESETS.find((p) => p.id === hexOrPresetId)\n\n const materials = Array.isArray(mesh.material)\n ? slotIndex !== undefined\n ? mesh.material[slotIndex]\n ? [mesh.material[slotIndex]]\n : []\n : mesh.material\n : slotIndex === undefined || slotIndex === 0\n ? mesh.material\n ? [mesh.material]\n : []\n : []\n\n for (const mat of materials) {\n if (!mat) continue\n // Spec §4.3: metal uses MeshPhysicalMaterial; MeshStandardMaterial is its base so\n // instanceof MeshStandardMaterial catches both — guard specifically for physical.\n if (!(mat instanceof THREE.MeshStandardMaterial)) continue\n mat.color.set(preset ? preset.hex : hexOrPresetId)\n mat.metalness = preset?.metalness ?? mat.metalness ?? 1.0\n mat.roughness = preset?.roughness ?? mat.roughness\n mat.envMapIntensity = 1.2\n if (mat instanceof THREE.MeshPhysicalMaterial) {\n mat.clearcoat = 0.0\n if (preset?.specularColor) {\n mat.specularColor = new THREE.Color(preset.specularColor)\n }\n if (preset?.ior) {\n mat.ior = preset.ior\n }\n }\n mat.needsUpdate = true\n }\n}\n\nexport function applyStoneMaterial(mesh: THREE.Mesh, hexOrPresetId: string, slotIndex?: number): void {\n const preset =\n ALL_STONE_PRESETS.find((p) => p.id === hexOrPresetId) ??\n STONE_PRESETS.find((p) => p.id === hexOrPresetId)\n\n const materials = Array.isArray(mesh.material)\n ? slotIndex !== undefined\n ? mesh.material[slotIndex]\n ? [mesh.material[slotIndex]]\n : []\n : mesh.material\n : slotIndex === undefined || slotIndex === 0\n ? mesh.material\n ? [mesh.material]\n : []\n : []\n\n for (const mat of materials) {\n if (!mat) continue\n if (mat instanceof ReferenceDiamondMaterial) {\n if (preset) {\n mat.updatePreset(preset)\n } else {\n // Raw hex tint: update color without flattening diamond physics/dispersion\n ;(mat.uniforms.color.value as THREE.Color).set(hexOrPresetId)\n mat.uniformsNeedUpdate = true\n }\n } else if (mat instanceof DiamondMaterial) {\n if (preset) {\n const oldHandle = mat.bakeHandle\n const newMat = acquireDiamondMaterial(\n oldHandle,\n mat.uniforms.envMap.value,\n preset,\n )\n if (newMat !== mat) {\n releaseDiamondMaterial(mat)\n if (Array.isArray(mesh.material)) {\n const idx = mesh.material.indexOf(mat)\n if (idx !== -1) mesh.material[idx] = newMat\n } else {\n mesh.material = newMat\n }\n } else {\n mat.updatePreset(preset)\n }\n } else {\n ;(mat.uniforms.color.value as THREE.Color).set(hexOrPresetId)\n mat.uniformsNeedUpdate = true\n }\n } else if (mat instanceof THREE.MeshPhysicalMaterial) {\n mat.color.set(preset ? preset.hex : hexOrPresetId)\n if (preset) {\n mat.ior = preset.ior\n mat.roughness = preset.roughness\n if (preset.specularColor) {\n mat.specularColor = new THREE.Color(preset.specularColor)\n }\n if (preset.attenuationColor) {\n mat.attenuationColor = new THREE.Color(preset.attenuationColor)\n mat.attenuationDistance = preset.attenuationDistance ?? 0.5\n }\n }\n mat.transmission = 0.0\n mat.transparent = false\n mat.envMapIntensity = 3.0\n mat.needsUpdate = true\n }\n }\n}\n\n/**\n * Ensures a mesh has the correct material class for its part type.\n * When renderer is provided and geometry is bakeable, equips DiamondMaterial.\n * Otherwise falls back to opaque MeshPhysicalMaterial with transmission: 0.\n */\nexport function ensureMaterial(\n mesh: THREE.Mesh,\n type: 'metal' | 'stone',\n renderer?: THREE.WebGLRenderer,\n envMap?: THREE.Texture,\n diamondMode: DiamondMode = 'reference',\n): void {\n const existing = Array.isArray(mesh.material) ? mesh.material[0] : mesh.material\n const isPhysical = existing instanceof THREE.MeshPhysicalMaterial\n const isDiamond = existing instanceof DiamondMaterial\n const isMetal = isPhysical && (existing as THREE.MeshPhysicalMaterial).metalness > 0.5\n\n if (type === 'metal') {\n if (!isPhysical || !isMetal) {\n const prev = existing as THREE.Material | null\n const metal = new THREE.MeshPhysicalMaterial({\n color: prev instanceof THREE.MeshStandardMaterial ? prev.color.clone() : new THREE.Color('#C0C0C0'),\n metalness: 1.0,\n roughness: 0.0,\n clearcoat: 0.0,\n envMapIntensity: 1.0,\n side: THREE.DoubleSide,\n })\n if (existing instanceof DiamondMaterial) {\n releaseDiamondMaterial(existing)\n } else if (existing instanceof ReferenceDiamondMaterial) {\n releaseReferenceDiamondMaterial(existing)\n } else {\n prev?.dispose()\n }\n if (prev?.name) metal.name = prev.name\n if (prev?.userData) metal.userData = { ...prev.userData, ...metal.userData }\n mesh.material = metal\n }\n return\n }\n\n // type === 'stone'\n const isRefDiamond = existing instanceof ReferenceDiamondMaterial\n if (isDiamond || isRefDiamond) {\n if (envMap) {\n if (isRefDiamond) {\n (existing as ReferenceDiamondMaterial).setEnvMap(envMap)\n } else {\n (existing as DiamondMaterial).uniforms.envMap.value = envMap\n }\n }\n return\n }\n\n if (renderer) {\n let handle = globalDiamondBaker.acquire(mesh.geometry, renderer)\n if (!handle) {\n const triCount = (mesh.geometry.index ? mesh.geometry.index.count : mesh.geometry.attributes.position?.count ?? 0) / 3\n if (triCount < 5000) {\n if (!mesh.geometry.boundingSphere) {\n mesh.geometry.computeBoundingSphere()\n }\n const bvh = getOrCreateDiamondBVH(mesh.geometry)\n const resolvedEnv = envMap ?? setupGemEnvironment(renderer)\n handle = {\n key: `bvh_${mesh.geometry.id}`,\n texture: (resolvedEnv instanceof THREE.CubeTexture ? resolvedEnv : new THREE.WebGLCubeRenderTarget(1).texture) as any,\n centroid: mesh.geometry.boundingSphere?.center ? mesh.geometry.boundingSphere.center.clone() : new THREE.Vector3(),\n radius: mesh.geometry.boundingSphere?.radius ?? 1.0,\n encoding: 'signed',\n bvh,\n }\n }\n }\n\n if (handle) {\n const resolvedEnv = envMap ?? setupGemEnvironment(renderer)\n let mat: THREE.Material\n if (diamondMode === 'reference' && !handle.key.startsWith('bvh_')) {\n mat = acquireReferenceDiamondMaterial(handle, resolvedEnv, STONE_PRESETS[0]!)\n } else {\n mat = acquireDiamondMaterial(handle, resolvedEnv, STONE_PRESETS[0]!)\n }\n const prev = existing as THREE.Material | null\n prev?.dispose()\n if (prev?.name) mat.name = prev.name\n if (prev?.userData) mat.userData = { ...prev.userData, ...mat.userData }\n mesh.material = mat\n return\n }\n }\n\n // Fallback: MeshPhysicalMaterial with transmission: 0.0\n if (!isPhysical || isMetal) {\n const prev = existing as THREE.Material | null\n const stone = new THREE.MeshPhysicalMaterial({\n color: prev instanceof THREE.MeshStandardMaterial ? prev.color.clone() : new THREE.Color('#FFFFFF'),\n metalness: 0,\n transmission: 0.0,\n ior: 2.417,\n roughness: 0.0,\n thickness: 0.5,\n envMapIntensity: 3.0,\n transparent: false,\n })\n prev?.dispose()\n if (prev?.name) stone.name = prev.name\n if (prev?.userData) stone.userData = { ...prev.userData, ...stone.userData }\n mesh.material = stone\n }\n}\n\nexport {\n METAL_PRESETS,\n STONE_PRESETS,\n PHYSICALLY_BASED_METAL_PRESETS,\n DIAMOND_PRESETS,\n GEMSTONE_PRESETS,\n ALL_METAL_PRESETS,\n ALL_STONE_PRESETS,\n}\nexport type { MetalPreset, StonePreset } from './presets'\nexport {\n ReferenceDiamondMaterial,\n acquireReferenceDiamondMaterial,\n releaseReferenceDiamondMaterial,\n resolveQualityTier,\n}\nexport type { DiamondMode, DiamondQuality }\n\n","import * as THREE from 'three'\nimport type { ViewerOptions } from '../types'\n\nexport interface RendererHandle {\n renderer: THREE.WebGLRenderer\n setQuality: (quality: 'low' | 'medium' | 'high') => void\n dispose: () => void\n}\n\nexport function createRenderer(\n container: HTMLElement,\n camera: THREE.PerspectiveCamera,\n antialias?: boolean | ViewerOptions,\n): RendererHandle\nexport function createRenderer(\n container: HTMLElement,\n antialiasOrOptions?: boolean | ViewerOptions,\n): RendererHandle\nexport function createRenderer(\n container: HTMLElement,\n cameraOrOptions?: THREE.PerspectiveCamera | boolean | ViewerOptions,\n antialiasOrOptions: boolean | ViewerOptions = true,\n): RendererHandle {\n let camera: THREE.PerspectiveCamera | undefined\n let aa = true\n let initialQuality: 'low' | 'medium' | 'high' = 'high'\n\n if (cameraOrOptions instanceof THREE.PerspectiveCamera) {\n camera = cameraOrOptions\n if (typeof antialiasOrOptions === 'boolean') {\n aa = antialiasOrOptions\n } else if (antialiasOrOptions && typeof antialiasOrOptions === 'object') {\n aa = antialiasOrOptions.antialias ?? true\n if (antialiasOrOptions.quality) {\n initialQuality = antialiasOrOptions.quality\n }\n }\n } else if (typeof cameraOrOptions === 'boolean') {\n aa = cameraOrOptions\n } else if (cameraOrOptions && typeof cameraOrOptions === 'object') {\n aa = cameraOrOptions.antialias ?? true\n if (cameraOrOptions.quality) {\n initialQuality = cameraOrOptions.quality\n }\n }\n\n const renderer = new THREE.WebGLRenderer({ antialias: aa, alpha: false })\n renderer.outputColorSpace = THREE.SRGBColorSpace\n renderer.toneMapping = THREE.ACESFilmicToneMapping\n renderer.toneMappingExposure = 1.0\n renderer.setSize(container.clientWidth, container.clientHeight)\n renderer.shadowMap.enabled = false\n container.appendChild(renderer.domElement)\n\n function setQuality(quality: 'low' | 'medium' | 'high'): void {\n const dpr = typeof window !== 'undefined' ? window.devicePixelRatio : 1\n let targetDpr = 1.0\n if (quality === 'low') {\n targetDpr = 1.0\n } else if (quality === 'medium') {\n targetDpr = Math.min(dpr, 1.5)\n } else if (quality === 'high') {\n targetDpr = Math.min(dpr, 2.0)\n }\n renderer.setPixelRatio(targetDpr)\n }\n\n setQuality(initialQuality)\n\n // Single ResizeObserver handles both renderer size AND camera aspect —\n // avoids a second observer in viewer/index.ts (Gap 3 fix).\n let ro: ResizeObserver | null = null\n if (typeof ResizeObserver !== 'undefined') {\n ro = new ResizeObserver(() => {\n const w = container.clientWidth\n const h = container.clientHeight\n renderer.setSize(w, h)\n if (camera) {\n camera.aspect = h > 0 ? w / h : 1\n camera.updateProjectionMatrix()\n }\n })\n ro.observe(container)\n }\n\n return {\n renderer,\n setQuality,\n dispose: () => {\n ro?.disconnect()\n renderer.dispose()\n renderer.domElement.remove()\n },\n }\n}\n","import * as THREE from 'three'\n\nexport interface SceneHandle {\n scene: THREE.Scene\n camera: THREE.PerspectiveCamera\n dispose: () => void\n}\n\nexport function createScene(\n background: string | number = 0x1a1a1a,\n fov = 25,\n): SceneHandle {\n const scene = new THREE.Scene()\n const bgColor: THREE.ColorRepresentation = background === 'studio' ? 0x161618 : background\n scene.background = new THREE.Color(bgColor)\n\n const camera = new THREE.PerspectiveCamera(\n fov,\n 1, // aspect updated on resize\n 0.01,\n 1000,\n )\n camera.position.set(0, 0, 3)\n\n // Studio lighting\n const keyLight = new THREE.DirectionalLight('#ffffff', 1.0)\n keyLight.position.set(5, 8, 5)\n scene.add(keyLight)\n\n const fillLight = new THREE.DirectionalLight('#e0e8ff', 0.4)\n fillLight.position.set(-5, 3, -5)\n scene.add(fillLight)\n\n // ResizeObserver aspect update is handled by whoever owns the renderer.\n // The viewer/index.ts calls camera.aspect = w/h; camera.updateProjectionMatrix().\n\n return {\n scene,\n camera,\n dispose: () => {\n scene.clear()\n },\n }\n}\n\nexport function updateCameraAspect(\n camera: THREE.PerspectiveCamera,\n width: number,\n height: number,\n): void {\n camera.aspect = height > 0 ? width / height : 1\n camera.updateProjectionMatrix()\n}\n","import * as THREE from 'three'\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'\nimport type { ViewerOptions } from '../types'\n\nexport interface ControlsHandle {\n controls: OrbitControls\n initialPosition: THREE.Vector3\n initialTarget: THREE.Vector3\n resetCamera: () => void\n dispose: () => void\n}\n\nexport function createControls(\n camera: THREE.PerspectiveCamera,\n domElement: HTMLElement,\n options: ViewerOptions = {},\n): ControlsHandle {\n const controls = new OrbitControls(camera, domElement)\n controls.enableDamping = true\n controls.dampingFactor = 0.05\n controls.screenSpacePanning = false\n controls.autoRotate = options.autoRotate ?? false\n controls.autoRotateSpeed = options.autoRotateSpeed ?? 2.0\n\n const initialPosition = camera.position.clone()\n const initialTarget = controls.target.clone()\n\n function resetCamera(): void {\n camera.position.copy(initialPosition)\n controls.target.copy(initialTarget)\n controls.update()\n }\n\n return {\n controls,\n initialPosition,\n initialTarget,\n resetCamera,\n dispose: () => {\n controls.dispose()\n },\n }\n}\n\nexport function fitCameraToScene(\n root: THREE.Object3D,\n camera: THREE.PerspectiveCamera,\n controlsOrHandle: OrbitControls | ControlsHandle,\n options: ViewerOptions = {},\n): void {\n const controls = 'controls' in controlsOrHandle ? controlsOrHandle.controls : controlsOrHandle\n const box = new THREE.Box3().setFromObject(root)\n const sphere = box.getBoundingSphere(new THREE.Sphere())\n const r = sphere.radius > 0 ? sphere.radius : 1\n\n const fovRad = THREE.MathUtils.degToRad(camera.fov)\n const distance = (r / Math.tan(fovRad / 2)) * 1.15\n\n controls.target.copy(sphere.center)\n camera.position.set(sphere.center.x, sphere.center.y, sphere.center.z + distance)\n camera.near = r * 0.01\n camera.far = r * 100\n camera.updateProjectionMatrix()\n\n controls.minDistance = options.minZoom ?? r * 0.5\n controls.maxDistance = options.maxZoom ?? r * 6\n controls.update()\n}\n","import * as THREE from 'three'\nimport type { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'\nimport type { TypedEmitter } from '../events'\nimport type { ViewerEvents, PartInfo } from '../types'\n\nexport interface InteractionHandle {\n dispose: () => void\n}\n\nexport interface InteractionOptions {\n /** Whether to apply white emissive highlight on hover. Defaults to true for standalone interaction. */\n hoverHighlight?: boolean\n}\n\nexport function createInteraction(\n renderer: THREE.WebGLRenderer,\n scene: THREE.Scene,\n camera: THREE.PerspectiveCamera,\n controls: OrbitControls,\n emitter: TypedEmitter<ViewerEvents>,\n getParts: () => PartInfo[] = () => [],\n options?: InteractionOptions,\n): InteractionHandle {\n const raycaster = new THREE.Raycaster()\n const pointer = new THREE.Vector2()\n let hoveredMesh: THREE.Mesh | null = null\n let hoveredSlotIndex: number | undefined\n const hoveredOriginalEmissive = new THREE.Color()\n let hoveredOriginalIntensity = 0\n let isDragging = false\n let pointerDownPos = { x: 0, y: 0 }\n\n const enableHighlight = options?.hoverHighlight ?? false\n\n function getMeshes(): THREE.Mesh[] {\n const meshes: THREE.Mesh[] = []\n scene.traverse((obj) => {\n if ((obj as THREE.Mesh).isMesh) meshes.push(obj as THREE.Mesh)\n })\n return meshes\n }\n\n function getMaterial(mesh: THREE.Mesh): THREE.MeshStandardMaterial | null {\n const mat = Array.isArray(mesh.material) ? mesh.material[0] : mesh.material\n return mat instanceof THREE.MeshStandardMaterial ? mat : null\n }\n\n function setHover(mesh: THREE.Mesh | null, materialIndex?: number): void {\n if (mesh === hoveredMesh && materialIndex === hoveredSlotIndex) return\n\n // Restore previous\n if (hoveredMesh) {\n if (enableHighlight) {\n const mat = getMaterial(hoveredMesh)\n if (mat) {\n mat.emissive.copy(hoveredOriginalEmissive)\n mat.emissiveIntensity = hoveredOriginalIntensity\n }\n }\n }\n\n hoveredMesh = mesh\n hoveredSlotIndex = materialIndex\n\n if (mesh) {\n if (enableHighlight) {\n const mat = getMaterial(mesh)\n if (mat) {\n hoveredOriginalEmissive.copy(mat.emissive)\n hoveredOriginalIntensity = mat.emissiveIntensity\n mat.emissive.set(0xffffff)\n mat.emissiveIntensity = 0.3\n }\n }\n\n if (renderer.domElement?.style) {\n renderer.domElement.style.cursor = 'pointer'\n }\n\n const part = getParts().find((p) => p.meshId === mesh.uuid)\n if (part) {\n const slotIdx =\n materialIndex !== undefined && part.slots[materialIndex] !== undefined\n ? materialIndex\n : 0\n const slot = part.slots[slotIdx]\n emitter.emit('partHover', {\n meshId: part.meshId,\n partId: part.partId,\n type: part.type,\n slotIndex: slotIdx,\n slotId: slot?.slotId,\n materialName: slot?.materialName ?? part.materialName,\n })\n } else {\n emitter.emit('partHover', null)\n }\n } else {\n if (renderer.domElement?.style) {\n renderer.domElement.style.cursor = 'default'\n }\n emitter.emit('partHover', null)\n }\n }\n\n function onPointerMove(e: PointerEvent): void {\n if (isDragging) return\n const rect = renderer.domElement.getBoundingClientRect()\n if (rect.width === 0 || rect.height === 0) return\n pointer.x = ((e.clientX - rect.left) / rect.width) * 2 - 1\n pointer.y = -((e.clientY - rect.top) / rect.height) * 2 + 1\n\n raycaster.setFromCamera(pointer, camera)\n const hits = raycaster.intersectObjects(getMeshes(), false)\n const firstHit = hits[0]\n setHover(firstHit ? (firstHit.object as THREE.Mesh) : null, firstHit?.face?.materialIndex)\n }\n\n function onPointerLeave(): void {\n setHover(null, undefined)\n }\n\n function onPointerDown(e: PointerEvent): void {\n pointerDownPos = { x: e.clientX, y: e.clientY }\n }\n\n function onPointerUp(e: PointerEvent): void {\n const dx = e.clientX - pointerDownPos.x\n const dy = e.clientY - pointerDownPos.y\n const dist = Math.sqrt(dx * dx + dy * dy)\n if (dist < 4) {\n let targetMesh = hoveredMesh\n let clickedSlotIndex = hoveredSlotIndex\n if (!targetMesh) {\n const rect = renderer.domElement.getBoundingClientRect()\n if (rect.width > 0 && rect.height > 0) {\n pointer.x = ((e.clientX - rect.left) / rect.width) * 2 - 1\n pointer.y = -((e.clientY - rect.top) / rect.height) * 2 + 1\n raycaster.setFromCamera(pointer, camera)\n const hits = raycaster.intersectObjects(getMeshes(), false)\n if (hits.length > 0) {\n targetMesh = hits[0]!.object as THREE.Mesh\n clickedSlotIndex = hits[0]!.face?.materialIndex\n }\n }\n }\n if (targetMesh) {\n const part = getParts().find((p) => p.meshId === targetMesh!.uuid)\n if (part) {\n const slotIdx =\n clickedSlotIndex !== undefined && part.slots[clickedSlotIndex] !== undefined\n ? clickedSlotIndex\n : 0\n const slot = part.slots[slotIdx]\n emitter.emit('partSelected', {\n meshId: part.meshId,\n partId: part.partId,\n type: part.type,\n slotIndex: slotIdx,\n slotId: slot?.slotId,\n materialName: slot?.materialName ?? part.materialName,\n })\n }\n }\n }\n }\n\n function onDragStart(): void {\n isDragging = true\n }\n\n function onDragEnd(): void {\n isDragging = false\n }\n\n const el = renderer.domElement\n el.addEventListener('pointermove', onPointerMove as EventListener)\n el.addEventListener('pointerdown', onPointerDown as EventListener)\n el.addEventListener('pointerup', onPointerUp as EventListener)\n el.addEventListener('pointerleave', onPointerLeave as EventListener)\n controls.addEventListener('start', onDragStart)\n controls.addEventListener('end', onDragEnd)\n\n return {\n dispose: () => {\n el.removeEventListener('pointermove', onPointerMove as EventListener)\n el.removeEventListener('pointerdown', onPointerDown as EventListener)\n el.removeEventListener('pointerup', onPointerUp as EventListener)\n el.removeEventListener('pointerleave', onPointerLeave as EventListener)\n controls.removeEventListener('start', onDragStart)\n controls.removeEventListener('end', onDragEnd)\n setHover(null)\n if (el?.style) {\n el.style.cursor = 'default'\n }\n },\n }\n}\n","import * as THREE from 'three'\nimport type { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'\nimport type { ViewerState, PartType, StateRestoreResult } from '../types'\n\nexport function buildState(\n metalColor: string,\n stoneColor: string,\n partOverrides: Record<string, PartType>,\n camera: THREE.PerspectiveCamera,\n controls: OrbitControls,\n materialColors?: Record<string, string>,\n partColors?: Record<string, string>,\n modelId?: string,\n): ViewerState {\n const state: ViewerState = {\n metalColor,\n stoneColor,\n parts: { ...partOverrides },\n cameraState: {\n position: camera.position.toArray() as [number, number, number],\n target: controls.target.toArray() as [number, number, number],\n },\n }\n\n if (modelId) {\n state.modelId = modelId\n }\n\n if (materialColors && Object.keys(materialColors).length > 0) {\n state.materialColors = { ...materialColors }\n }\n\n if (partColors && Object.keys(partColors).length > 0) {\n state.partColors = { ...partColors }\n }\n\n return state\n}\n\nexport interface RestoreStateOptions {\n setMaterialColor?: (slotIdOrName: string, color: string) => void\n setPartColor?: (partIdOrMeshId: string, color: string, slotIndex?: number) => void\n availablePartIds?: Set<string>\n availableSlotIds?: Set<string>\n availableMaterialNames?: Set<string>\n}\n\nexport function restoreState(\n state: ViewerState,\n applyMetalColor: (hex: string) => void,\n applyStoneColor: (hex: string) => void,\n setPartType: (partIdOrMeshId: string, type: PartType) => void,\n camera: THREE.PerspectiveCamera,\n controls: OrbitControls,\n options?: RestoreStateOptions,\n): StateRestoreResult {\n const unresolvedParts: string[] = []\n const unresolvedMaterials: string[] = []\n const warnings: string[] = []\n\n // 1. Global defaults\n applyMetalColor(state.metalColor)\n applyStoneColor(state.stoneColor)\n\n // 2. Part type overrides\n for (const [partIdOrMeshId, type] of Object.entries(state.parts || {})) {\n if (options?.availablePartIds && !options.availablePartIds.has(partIdOrMeshId)) {\n unresolvedParts.push(partIdOrMeshId)\n warnings.push(`Part type override target '${partIdOrMeshId}' not found in model`)\n console.warn(`[3d-viewer] Part type override target '${partIdOrMeshId}' not found in loaded model`)\n }\n setPartType(partIdOrMeshId, type)\n }\n\n // 3. Material slot overrides\n if (state.materialColors && options?.setMaterialColor) {\n for (const [slotIdOrName, color] of Object.entries(state.materialColors)) {\n const isKnown =\n (!options.availableSlotIds && !options.availableMaterialNames) ||\n options.availableSlotIds?.has(slotIdOrName) ||\n options.availableMaterialNames?.has(slotIdOrName)\n\n if (!isKnown) {\n unresolvedMaterials.push(slotIdOrName)\n warnings.push(`Material slot '${slotIdOrName}' not found in model`)\n console.warn(`[3d-viewer] Material slot '${slotIdOrName}' not found in loaded model`)\n }\n options.setMaterialColor(slotIdOrName, color)\n }\n }\n\n // 4. Part overrides (supports whole-part 'partId' and part-slot 'partId:slotIndex')\n if (state.partColors && options?.setPartColor) {\n for (const [partTarget, color] of Object.entries(state.partColors)) {\n let partId = partTarget\n let slotIndex: number | undefined = undefined\n\n const colonIdx = partTarget.lastIndexOf(':')\n if (colonIdx > 0 && !isNaN(Number(partTarget.slice(colonIdx + 1)))) {\n partId = partTarget.slice(0, colonIdx)\n slotIndex = Number(partTarget.slice(colonIdx + 1))\n }\n\n if (options.availablePartIds && !options.availablePartIds.has(partId)) {\n unresolvedParts.push(partId)\n warnings.push(`Part '${partId}' not found in model`)\n console.warn(`[3d-viewer] Part '${partId}' not found in loaded model`)\n }\n options.setPartColor(partId, color, slotIndex)\n }\n }\n\n // 5. Camera & controls\n if (state.cameraState) {\n camera.position.fromArray(state.cameraState.position)\n controls.target.fromArray(state.cameraState.target)\n controls.update()\n }\n\n return {\n success: true,\n unresolvedParts: unresolvedParts.length > 0 ? unresolvedParts : undefined,\n unresolvedMaterials: unresolvedMaterials.length > 0 ? unresolvedMaterials : undefined,\n warnings: warnings.length > 0 ? warnings : undefined,\n }\n}\n","import * as THREE from 'three'\n\nexport interface ContactShadowHandle {\n mesh: THREE.Mesh\n setVisible: (visible: boolean) => void\n setScale: (scale: number) => void\n dispose: () => void\n}\n\nexport function createContactShadowPlane(scene: THREE.Scene, radius = 1.2): ContactShadowHandle {\n let texture: THREE.Texture\n\n if (typeof document !== 'undefined' && typeof document.createElement === 'function') {\n const canvas = document.createElement('canvas')\n canvas.width = 256\n canvas.height = 256\n const ctx = canvas.getContext ? canvas.getContext('2d') : null\n if (ctx) {\n const gradient = ctx.createRadialGradient(128, 128, 0, 128, 128, 128)\n gradient.addColorStop(0, 'rgba(0, 0, 0, 0.65)')\n gradient.addColorStop(0.3, 'rgba(0, 0, 0, 0.4)')\n gradient.addColorStop(0.7, 'rgba(0, 0, 0, 0.15)')\n gradient.addColorStop(1, 'rgba(0, 0, 0, 0)')\n ctx.fillStyle = gradient\n ctx.fillRect(0, 0, 256, 256)\n }\n\n const canvasTexture = new THREE.CanvasTexture(canvas)\n canvasTexture.needsUpdate = true\n texture = canvasTexture\n } else {\n // Headless / SSR environment fallback\n texture = new THREE.Texture()\n texture.needsUpdate = true\n }\n\n const geometry = new THREE.PlaneGeometry(radius * 2, radius * 2)\n geometry.rotateX(-Math.PI / 2)\n\n const material = new THREE.MeshBasicMaterial({\n map: texture,\n transparent: true,\n opacity: 0.85,\n depthWrite: false,\n })\n\n const mesh = new THREE.Mesh(geometry, material)\n mesh.position.y = -0.5\n mesh.renderOrder = -1\n scene.add(mesh)\n\n return {\n mesh,\n setVisible: (visible) => {\n mesh.visible = visible\n },\n setScale: (scale) => {\n mesh.scale.setScalar(scale)\n },\n dispose: () => {\n scene.remove(mesh)\n geometry.dispose()\n material.dispose()\n texture.dispose()\n },\n }\n}\n","import * as THREE from 'three'\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'\nimport { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'\nimport { DEFAULT_DRACO_DECODER_PATH } from '../converter/loaders'\nimport { TypedEmitter } from '../events'\nimport { convert, normalizeScene } from '../converter'\nimport { classifyParts, extractMaterialSlots } from '../parts'\nimport {\n applyMetalMaterial,\n applyStoneMaterial,\n ensureMaterial,\n setupEnvironment,\n setupGemEnvironment,\n loadHdrEnvironment,\n globalDiamondBaker,\n DiamondMaterial,\n type HdrEnvironmentHandle,\n} from '../materials'\nimport {\n ReferenceDiamondMaterial,\n acquireReferenceDiamondMaterial,\n releaseReferenceDiamondMaterial,\n resolveQualityTier,\n type DiamondQuality,\n} from '../materials/diamond-reference-material'\nimport {\n METAL_PRESETS,\n STONE_PRESETS,\n ALL_METAL_PRESETS,\n ALL_STONE_PRESETS,\n} from '../materials/presets'\nimport { createRenderer } from './renderer'\nimport { createScene, updateCameraAspect } from './scene'\nimport { createControls, fitCameraToScene } from './controls'\nimport { createInteraction } from './interaction'\nimport { buildState, restoreState } from './state'\nimport { createContactShadowPlane } from './shadow'\nimport type {\n ModelSource,\n LoadOptions,\n ViewerOptions,\n ViewerEvents,\n ViewerState,\n PartInfo,\n PartType,\n MaterialSlotInfo,\n MeshMaterialSlot,\n StateRestoreResult,\n Viewer,\n} from '../types'\n\nexport type { Viewer } from '../types'\n\nfunction disposeModel(model: THREE.Object3D): void {\n model.traverse((obj) => {\n if (obj instanceof THREE.Mesh) {\n obj.geometry?.dispose()\n const mats = Array.isArray(obj.material) ? obj.material : [obj.material]\n mats.forEach((m) => {\n // Spec §4.4 Dispose: geometry, material, AND texture disposal required\n if (m instanceof THREE.MeshStandardMaterial) {\n m.map?.dispose()\n m.normalMap?.dispose()\n m.roughnessMap?.dispose()\n m.metalnessMap?.dispose()\n m.envMap?.dispose()\n }\n m.dispose()\n })\n }\n })\n}\n\nexport function createViewer(\n container: HTMLElement,\n options: ViewerOptions = {},\n): Viewer {\n const emitter = new TypedEmitter<ViewerEvents>()\n const sceneHandle = createScene(options.background ?? 0xffffff, options.fov ?? 25)\n const { scene, camera, dispose: disposeScene } = sceneHandle\n const rendererHandle = createRenderer(\n container,\n camera,\n options,\n )\n const { renderer } = rendererHandle\n const controlsHandle = createControls(camera, renderer.domElement, options)\n const controls = controlsHandle.controls\n\n // Contact shadow plane\n const shadowHandle = createContactShadowPlane(scene)\n if (options.shadows === false) {\n shadowHandle.setVisible(false)\n }\n\n // Environment (Dual Lighting)\n setupEnvironment(scene, renderer)\n let gemEnv: THREE.Texture | undefined\n try {\n gemEnv = setupGemEnvironment(renderer)\n } catch {\n // Graceful fallback if mock or test renderer lacks WebGLCubeRenderTarget support\n }\n\n let metalHdrHandle: HdrEnvironmentHandle | null = null\n let gemHdrHandle: HdrEnvironmentHandle | null = null\n\n /**\n * Detects mobile devices and caps quality to 'medium'.\n * Heuristic: user agent contains \"Mobi\" AND devicePixelRatio is not high-end.\n * Only applies if the user did not explicitly request 'high' or 'ultra'.\n */\n function applyMobileCap(requested: DiamondQuality): DiamondQuality {\n const isMobile =\n typeof navigator !== 'undefined' &&\n /Mobi/i.test(navigator.userAgent) &&\n (typeof window === 'undefined' || window.devicePixelRatio <= 2)\n if (!isMobile) return requested\n // Cap: mobile max is 'medium'\n const mobileMax: DiamondQuality = 'medium'\n const order: DiamondQuality[] = ['low', 'medium', 'high', 'ultra']\n return order.indexOf(requested) <= order.indexOf(mobileMax) ? requested : mobileMax\n }\n\n // Diamond quality state\n let currentDiamondQuality: DiamondQuality = applyMobileCap(\n (options.diamondQuality as DiamondQuality | undefined) ?? 'medium'\n )\n let qualityDebounceTimer: ReturnType<typeof setTimeout> | null = null\n\n async function setMetalEnvironment(urlOrData: string | ArrayBuffer): Promise<void> {\n try {\n const handle = await loadHdrEnvironment(urlOrData, renderer)\n metalHdrHandle?.dispose()\n metalHdrHandle = handle\n scene.environment = handle.texture\n\n // If no dedicated gem environment was configured, bind this HDR to diamonds as well\n if (!options.gemEnvUrl) {\n gemEnv = handle.gemTexture ?? handle.texture\n currentModel?.traverse((obj) => {\n if (!(obj instanceof THREE.Mesh)) return\n if (obj.material instanceof ReferenceDiamondMaterial) {\n obj.material.setEnvMap(gemEnv!)\n } else if (obj.material instanceof DiamondMaterial) {\n obj.material.uniforms.envMap.value = gemEnv\n }\n })\n }\n } catch (err) {\n emitter.emit('error', err instanceof Error ? err : new Error(String(err)))\n throw err\n }\n }\n\n async function setGemEnvironment(urlOrData: string | ArrayBuffer): Promise<void> {\n try {\n const handle = await loadHdrEnvironment(urlOrData, renderer)\n gemHdrHandle?.dispose()\n gemHdrHandle = handle\n gemEnv = handle.gemTexture ?? handle.texture\n currentModel?.traverse((obj) => {\n if (!(obj instanceof THREE.Mesh)) return\n if (obj.material instanceof ReferenceDiamondMaterial) {\n obj.material.setEnvMap(gemEnv!)\n } else if (obj.material instanceof DiamondMaterial) {\n obj.material.uniforms.envMap.value = gemEnv\n }\n })\n } catch (err) {\n emitter.emit('error', err instanceof Error ? err : new Error(String(err)))\n throw err\n }\n }\n\n if (options.metalEnvUrl) {\n setMetalEnvironment(options.metalEnvUrl).catch(() => {})\n }\n if (options.gemEnvUrl) {\n setGemEnvironment(options.gemEnvUrl).catch(() => {})\n }\n\n // WebGL context restoration\n const canvas = renderer.domElement\n const handleContextRestored = () => {\n globalDiamondBaker.onContextRestored(renderer)\n }\n canvas.addEventListener?.('webglcontextrestored', handleContextRestored)\n\n // Model state\n let currentModel: THREE.Group | null = null\n let partInfos: PartInfo[] = []\n let materialSlots: MaterialSlotInfo[] = []\n let partOverrides: Record<string, PartType> = {}\n let materialOverrides: Record<string, string> = {}\n let partColorOverrides: Record<string, string> = {}\n let metalColor = METAL_PRESETS[0]!.hex\n let stoneColor = STONE_PRESETS[0]!.hex\n let abortController: AbortController | null = null\n\n // Camera aspect on resize\n let ro: ResizeObserver | null = null\n if (typeof ResizeObserver !== 'undefined') {\n ro = new ResizeObserver(() => {\n updateCameraAspect(camera, container.clientWidth, container.clientHeight)\n })\n ro.observe(container)\n }\n\n // Render loop\n let rafId = 0\n let paused = false\n\n function render(): void {\n controls.update()\n renderer.render(scene, camera)\n if (!paused && typeof requestAnimationFrame !== 'undefined') {\n rafId = requestAnimationFrame(render)\n }\n }\n\n function onVisibility(): void {\n const wasPaused = paused\n paused = typeof document !== 'undefined' ? document.hidden : false\n if (wasPaused && !paused && typeof requestAnimationFrame !== 'undefined') {\n rafId = requestAnimationFrame(render)\n }\n }\n\n if (typeof document !== 'undefined') {\n document.addEventListener('visibilitychange', onVisibility)\n }\n if (typeof requestAnimationFrame !== 'undefined') {\n rafId = requestAnimationFrame(render)\n }\n\n // Interaction\n const interaction = createInteraction(\n renderer,\n scene,\n camera,\n controls,\n emitter,\n () => partInfos,\n { hoverHighlight: options.hoverHighlight ?? false },\n )\n\n // ── Public API ──────────────────────────────────────────────────────────\n\n function getEffectiveModel(): THREE.Group | null {\n if (typeof (viewer as any)?.__getCurrentModel === 'function') {\n const mock = (viewer as any).__getCurrentModel()\n if (mock) return mock\n }\n return currentModel\n }\n\n function resolveMeshSlotColor(\n part: PartInfo,\n slotIndex: number,\n slot?: MeshMaterialSlot,\n ): { color: string; isOverridden: boolean } {\n // 1. Part-slot override: 'partId:slotIndex' or 'meshId:slotIndex'\n const partSlotKey = `${part.partId}:${slotIndex}`\n if (partColorOverrides[partSlotKey]) {\n return { color: partColorOverrides[partSlotKey]!, isOverridden: true }\n }\n const meshSlotKey = `${part.meshId}:${slotIndex}`\n if (partColorOverrides[meshSlotKey]) {\n return { color: partColorOverrides[meshSlotKey]!, isOverridden: true }\n }\n\n // 2. Whole-part override: 'partId' or 'meshId'\n if (partColorOverrides[part.partId]) {\n return { color: partColorOverrides[part.partId]!, isOverridden: true }\n }\n if (partColorOverrides[part.meshId]) {\n return { color: partColorOverrides[part.meshId]!, isOverridden: true }\n }\n\n // 3. Pinpoint slot override: 'slotId'\n if (slot?.slotId && materialOverrides[slot.slotId]) {\n return { color: materialOverrides[slot.slotId]!, isOverridden: true }\n }\n\n // 4. Bulk slot name override: 'materialName'\n if (slot?.materialName && materialOverrides[slot.materialName]) {\n return { color: materialOverrides[slot.materialName]!, isOverridden: true }\n }\n if (part.materialName && materialOverrides[part.materialName]) {\n return { color: materialOverrides[part.materialName]!, isOverridden: true }\n }\n\n // 5. Global default\n const globalDefault = part.type === 'metal' ? metalColor : stoneColor\n return { color: globalDefault, isOverridden: false }\n }\n\n function ensureUniqueMeshMaterial(mesh: THREE.Mesh, model: THREE.Group): void {\n if (Array.isArray(mesh.material)) {\n mesh.material = mesh.material.map((m) => {\n let count = 0\n model.traverse((o) => {\n if (o instanceof THREE.Mesh) {\n if (Array.isArray(o.material) ? o.material.includes(m) : o.material === m) count++\n }\n })\n if (count > 1 && typeof m.clone === 'function') {\n const cloned = m.clone()\n cloned.name = m.name\n return cloned\n }\n return m\n })\n } else if (mesh.material) {\n let count = 0\n model.traverse((o) => {\n if (o instanceof THREE.Mesh) {\n if (Array.isArray(o.material) ? o.material.includes(mesh.material) : o.material === mesh.material) count++\n }\n })\n if (count > 1 && typeof mesh.material.clone === 'function') {\n const cloned = mesh.material.clone()\n cloned.name = mesh.material.name\n mesh.material = cloned\n }\n }\n }\n\n function applyColorsToMesh(mesh: THREE.Mesh, part: PartInfo): void {\n const model = getEffectiveModel()\n if (model) {\n let anyOverridden = false\n if (Array.isArray(mesh.material)) {\n mesh.material.forEach((_, idx) => {\n const slot = part.slots[idx]\n if (resolveMeshSlotColor(part, idx, slot).isOverridden) anyOverridden = true\n })\n } else {\n const slot = part.slots[0]\n if (resolveMeshSlotColor(part, 0, slot).isOverridden) anyOverridden = true\n }\n if (anyOverridden) {\n ensureUniqueMeshMaterial(mesh, model)\n }\n }\n\n if (Array.isArray(mesh.material)) {\n mesh.material.forEach((_, idx) => {\n const slot = part.slots[idx]\n const { color } = resolveMeshSlotColor(part, idx, slot)\n if (part.type === 'metal') applyMetalMaterial(mesh, color, idx)\n else applyStoneMaterial(mesh, color, idx)\n })\n } else {\n const slot = part.slots[0]\n const { color } = resolveMeshSlotColor(part, 0, slot)\n if (part.type === 'metal') applyMetalMaterial(mesh, color)\n else applyStoneMaterial(mesh, color)\n }\n }\n\n async function load(\n source: ModelSource,\n opts: LoadOptions = {},\n ): Promise<void> {\n // Cancel any in-flight load\n abortController?.abort()\n abortController = new AbortController()\n const currentAbort = abortController\n\n if (opts.signal) {\n if (opts.signal.aborted) {\n currentAbort.abort()\n } else {\n opts.signal.addEventListener('abort', () => currentAbort.abort(), { once: true })\n }\n }\n const signal = currentAbort.signal\n\n emitter.emit('loading', { progress: 0 })\n\n try {\n const dracoDecoderPath = opts.dracoDecoderPath ?? options.dracoDecoderPath ?? DEFAULT_DRACO_DECODER_PATH\n const converted = await convert(\n source,\n signal,\n (p) => {\n emitter.emit('loading', { progress: p * 0.8 })\n },\n { dracoDecoderPath },\n )\n\n if (signal.aborted) return\n\n emitter.emit('loading', { progress: 0.85 })\n\n // Parse to Three.js scene\n const loader = new GLTFLoader()\n const dracoLoader = new DRACOLoader()\n dracoLoader.setDecoderPath(dracoDecoderPath)\n loader.setDRACOLoader(dracoLoader)\n\n let gltf: { scene: THREE.Group }\n try {\n gltf = await new Promise<{ scene: THREE.Group }>((resolve, reject) => {\n loader.parse(converted.glb, '', resolve, reject)\n })\n } finally {\n dracoLoader.dispose()\n }\n\n if (signal.aborted) return\n\n emitter.emit('loading', { progress: 0.9 })\n\n // Remove old model\n if (currentModel) {\n scene.remove(currentModel)\n disposeModel(currentModel)\n currentModel = null\n }\n\n currentModel = gltf.scene\n normalizeScene(currentModel)\n scene.add(currentModel)\n\n // Classify parts and extract material slots\n partInfos = classifyParts(currentModel, partOverrides)\n materialSlots = extractMaterialSlots(partInfos)\n\n // Apply materials\n currentModel.traverse((obj) => {\n if (!(obj instanceof THREE.Mesh)) return\n const part = partInfos.find((p) => p.meshId === obj.uuid)\n const type = part?.type ?? 'metal'\n ensureMaterial(obj, type, renderer, gemEnv, options.diamondMode ?? 'reference')\n if (part) applyColorsToMesh(obj, part)\n else if (type === 'metal') applyMetalMaterial(obj, metalColor)\n else applyStoneMaterial(obj, stoneColor)\n })\n\n // Apply initial diamond quality (no-op if 'medium'/default — materials already at 5 bounces/256px)\n if (currentDiamondQuality !== 'medium') {\n setDiamondQuality(currentDiamondQuality)\n }\n\n // Fit camera\n fitCameraToScene(currentModel, camera, controls, options)\n updateCameraAspect(camera, container.clientWidth, container.clientHeight)\n\n // Position contact shadow plane beneath the model\n const box = new THREE.Box3().setFromObject(currentModel)\n const sphere = box.getBoundingSphere(new THREE.Sphere())\n const r = sphere.radius > 0 ? sphere.radius : 1\n shadowHandle.mesh.position.y = box.min.y\n shadowHandle.setScale(r)\n\n emitter.emit('loading', { progress: 1 })\n emitter.emit('loaded', { parts: partInfos, materials: materialSlots })\n } catch (err) {\n if ((err as Error).name === 'AbortError' || signal.aborted) return // silently cancel\n emitter.emit('error', err instanceof Error ? err : new Error(String(err)))\n }\n }\n\n function setMetalColor(hexOrPresetId: string): void {\n metalColor =\n ALL_METAL_PRESETS.find((p) => p.id === hexOrPresetId)?.hex ??\n METAL_PRESETS.find((p) => p.id === hexOrPresetId)?.hex ??\n hexOrPresetId\n const model = getEffectiveModel()\n if (!model) return\n model.traverse((obj: THREE.Object3D) => {\n if (!(obj instanceof THREE.Mesh)) return\n const part = partInfos.find((p) => p.meshId === obj.uuid)\n if ((part?.type ?? 'metal') !== 'metal') return\n if (part) {\n if (Array.isArray(obj.material)) {\n obj.material.forEach((_, idx) => {\n const slot = part.slots[idx]\n const { isOverridden } = resolveMeshSlotColor(part, idx, slot)\n if (!isOverridden) applyMetalMaterial(obj, metalColor, idx)\n })\n } else {\n const slot = part.slots[0]\n const { isOverridden } = resolveMeshSlotColor(part, 0, slot)\n if (!isOverridden) applyMetalMaterial(obj, metalColor)\n }\n } else {\n applyMetalMaterial(obj, metalColor)\n }\n })\n emitter.emit('change', getState())\n }\n\n function setStoneColor(hexOrPresetId: string): void {\n stoneColor =\n ALL_STONE_PRESETS.find((p) => p.id === hexOrPresetId)?.hex ??\n STONE_PRESETS.find((p) => p.id === hexOrPresetId)?.hex ??\n hexOrPresetId\n const model = getEffectiveModel()\n if (!model) return\n model.traverse((obj: THREE.Object3D) => {\n if (!(obj instanceof THREE.Mesh)) return\n const part = partInfos.find((p) => p.meshId === obj.uuid)\n if (part?.type !== 'stone') return\n if (part) {\n if (Array.isArray(obj.material)) {\n obj.material.forEach((_, idx) => {\n const slot = part.slots[idx]\n const { isOverridden } = resolveMeshSlotColor(part, idx, slot)\n if (!isOverridden) applyStoneMaterial(obj, stoneColor, idx)\n })\n } else {\n const slot = part.slots[0]\n const { isOverridden } = resolveMeshSlotColor(part, 0, slot)\n if (!isOverridden) applyStoneMaterial(obj, stoneColor)\n }\n } else {\n applyStoneMaterial(obj, stoneColor)\n }\n })\n emitter.emit('change', getState())\n }\n\n function setPartType(meshIdOrPartId: string, type: PartType): void {\n const part = partInfos.find((p) => p.meshId === meshIdOrPartId || p.partId === meshIdOrPartId)\n const targetKey = part ? part.partId : meshIdOrPartId\n partOverrides[targetKey] = type\n\n const model = getEffectiveModel()\n if (model) {\n partInfos = classifyParts(model, partOverrides)\n materialSlots = extractMaterialSlots(partInfos)\n model.traverse((obj: THREE.Object3D) => {\n if (!(obj instanceof THREE.Mesh)) return\n const p = partInfos.find((pi) => pi.meshId === obj.uuid)\n if (!p || (p.partId !== targetKey && p.meshId !== meshIdOrPartId)) return\n ensureMaterial(obj, type, renderer, gemEnv, options.diamondMode ?? 'reference')\n applyColorsToMesh(obj, p)\n })\n if (type === 'stone' && currentDiamondQuality !== 'medium') {\n setDiamondQuality(currentDiamondQuality)\n }\n }\n emitter.emit('change', getState())\n }\n\n function setMaterialColor(slotIdOrName: string, colorOrPresetId: string): void {\n const matchingSlots = materialSlots.filter(\n (s) => s.slotId === slotIdOrName || s.name === slotIdOrName,\n )\n if (matchingSlots.length > 0) {\n for (const slot of matchingSlots) {\n materialOverrides[slot.slotId] = colorOrPresetId\n }\n }\n materialOverrides[slotIdOrName] = colorOrPresetId\n\n const model = getEffectiveModel()\n if (model) {\n model.traverse((obj: THREE.Object3D) => {\n if (!(obj instanceof THREE.Mesh)) return\n const part = partInfos.find((p) => p.meshId === obj.uuid)\n if (!part) return\n applyColorsToMesh(obj, part)\n })\n }\n emitter.emit('change', getState())\n }\n\n function setPartColor(partIdOrMeshId: string, colorOrPresetId: string, slotIndex?: number): void {\n const key = slotIndex !== undefined ? `${partIdOrMeshId}:${slotIndex}` : partIdOrMeshId\n partColorOverrides[key] = colorOrPresetId\n\n const model = getEffectiveModel()\n if (model) {\n model.traverse((obj: THREE.Object3D) => {\n if (!(obj instanceof THREE.Mesh)) return\n const part = partInfos.find((p) => p.meshId === obj.uuid)\n if (!part) return\n if (part.partId === partIdOrMeshId || part.meshId === partIdOrMeshId) {\n applyColorsToMesh(obj, part)\n }\n })\n }\n emitter.emit('change', getState())\n }\n\n function clearMaterialColor(slotIdOrName: string): void {\n delete materialOverrides[slotIdOrName]\n for (const slot of materialSlots) {\n if (slot.slotId === slotIdOrName || slot.name === slotIdOrName) {\n delete materialOverrides[slot.slotId]\n delete materialOverrides[slot.name]\n }\n }\n const model = getEffectiveModel()\n if (model) {\n model.traverse((obj: THREE.Object3D) => {\n if (!(obj instanceof THREE.Mesh)) return\n const part = partInfos.find((p) => p.meshId === obj.uuid)\n if (!part) return\n applyColorsToMesh(obj, part)\n })\n }\n emitter.emit('change', getState())\n }\n\n function clearPartColor(partIdOrMeshId: string, slotIndex?: number): void {\n if (slotIndex !== undefined) {\n delete partColorOverrides[`${partIdOrMeshId}:${slotIndex}`]\n } else {\n delete partColorOverrides[partIdOrMeshId]\n for (const k of Object.keys(partColorOverrides)) {\n if (k.startsWith(`${partIdOrMeshId}:`)) {\n delete partColorOverrides[k]\n }\n }\n }\n const model = getEffectiveModel()\n if (model) {\n model.traverse((obj: THREE.Object3D) => {\n if (!(obj instanceof THREE.Mesh)) return\n const part = partInfos.find((p) => p.meshId === obj.uuid)\n if (!part) return\n if (part.partId === partIdOrMeshId || part.meshId === partIdOrMeshId) {\n applyColorsToMesh(obj, part)\n }\n })\n }\n emitter.emit('change', getState())\n }\n\n function clearOverrides(): void {\n materialOverrides = {}\n partColorOverrides = {}\n const model = getEffectiveModel()\n if (model) {\n model.traverse((obj: THREE.Object3D) => {\n if (!(obj instanceof THREE.Mesh)) return\n const part = partInfos.find((p) => p.meshId === obj.uuid)\n if (!part) return\n applyColorsToMesh(obj, part)\n })\n }\n emitter.emit('change', getState())\n }\n\n function getMaterials(): MaterialSlotInfo[] {\n return [...materialSlots]\n }\n\n function getParts(): PartInfo[] {\n return [...partInfos]\n }\n\n function getState(): ViewerState {\n return buildState(\n metalColor,\n stoneColor,\n partOverrides,\n camera,\n controls,\n materialOverrides,\n partColorOverrides,\n )\n }\n\n function setState(state: ViewerState): StateRestoreResult {\n partOverrides = {}\n materialOverrides = {}\n partColorOverrides = {}\n\n const availablePartIds = new Set(partInfos.map((p) => p.partId))\n const availableSlotIds = new Set(materialSlots.map((s) => s.slotId))\n const availableMaterialNames = new Set(materialSlots.map((s) => s.name))\n\n const result = restoreState(\n state,\n setMetalColor,\n setStoneColor,\n setPartType,\n camera,\n controls,\n {\n setMaterialColor,\n setPartColor,\n availablePartIds,\n availableSlotIds,\n availableMaterialNames,\n },\n )\n return result\n }\n\n // Restore initial state if passed in options\n if (options.initialState) {\n setState(options.initialState)\n controlsHandle.initialPosition.copy(camera.position)\n controlsHandle.initialTarget.copy(controls.target)\n }\n\n function on<K extends keyof ViewerEvents>(\n event: K,\n cb: (data: ViewerEvents[K]) => void,\n ): () => void {\n return emitter.on(event, cb)\n }\n\n function dispose(): void {\n if (qualityDebounceTimer !== null) {\n clearTimeout(qualityDebounceTimer)\n qualityDebounceTimer = null\n }\n abortController?.abort()\n if (typeof cancelAnimationFrame !== 'undefined') {\n cancelAnimationFrame(rafId)\n }\n if (typeof document !== 'undefined') {\n document.removeEventListener('visibilitychange', onVisibility)\n }\n canvas.removeEventListener?.('webglcontextrestored', handleContextRestored)\n globalDiamondBaker.clearCache()\n ro?.disconnect()\n shadowHandle.dispose()\n interaction.dispose()\n controlsHandle.dispose()\n if (currentModel) {\n scene.remove(currentModel)\n disposeModel(currentModel)\n currentModel = null\n }\n metalHdrHandle?.dispose()\n gemHdrHandle?.dispose()\n disposeScene()\n rendererHandle.dispose()\n emitter.clear()\n }\n\n function toggleRotation(speed?: number): boolean {\n if (speed !== undefined) {\n controls.autoRotateSpeed = speed\n }\n controls.autoRotate = !controls.autoRotate\n return controls.autoRotate\n }\n\n function startRotation(speed?: number): void {\n if (speed !== undefined) {\n controls.autoRotateSpeed = speed\n }\n controls.autoRotate = true\n }\n\n function stopRotation(): void {\n controls.autoRotate = false\n }\n\n function isRotating(): boolean {\n return controls.autoRotate\n }\n\n function resetCamera(): void {\n controlsHandle.resetCamera()\n }\n\n function fitToScene(): void {\n if (currentModel) {\n fitCameraToScene(currentModel, camera, controls, options)\n }\n }\n\n async function captureSnapshot(\n snapshotOptions?: { format?: 'image/png' | 'image/jpeg'; quality?: number },\n ): Promise<string> {\n const format = snapshotOptions?.format ?? 'image/png'\n const quality = snapshotOptions?.quality ?? 0.95\n renderer.render(scene, camera)\n return renderer.domElement.toDataURL(format, quality)\n }\n\n function setQuality(quality: 'low' | 'medium' | 'high'): void {\n rendererHandle.setQuality(quality)\n }\n\n function setShadowsEnabled(enabled: boolean): void {\n shadowHandle.setVisible(enabled)\n }\n\n function unload(): void {\n abortController?.abort()\n if (currentModel) {\n scene.remove(currentModel)\n disposeModel(currentModel)\n currentModel = null\n }\n partInfos = []\n partOverrides = {}\n materialSlots = []\n materialOverrides = {}\n partColorOverrides = {}\n shadowHandle.mesh.position.y = 0\n shadowHandle.setScale(1)\n }\n\n function setDiamondQuality(quality: DiamondQuality): void {\n const capped = applyMobileCap(quality)\n\n // Debounce: shader recompile is expensive; ignore rapid calls, apply last value\n if (qualityDebounceTimer !== null) {\n clearTimeout(qualityDebounceTimer)\n }\n qualityDebounceTimer = setTimeout(() => {\n qualityDebounceTimer = null\n currentDiamondQuality = capped\n if (!currentModel) return\n\n const { rayBounces, cubeResolution } = resolveQualityTier(capped)\n\n currentModel.traverse((obj) => {\n if (!(obj instanceof THREE.Mesh)) return\n const part = partInfos.find((p) => p.meshId === obj.uuid)\n if (part?.type !== 'stone') return\n\n const mat = obj.material\n if (!(mat instanceof ReferenceDiamondMaterial)) return\n\n // Re-acquire handle at new resolution, then swap material\n const oldHandle = mat.bakeHandle\n const newHandle = globalDiamondBaker.acquire(obj.geometry, renderer, { resolution: cubeResolution })\n if (!newHandle) return // not bakeable\n globalDiamondBaker.release(oldHandle)\n\n const envTex = (mat.uniforms.envMap?.value as THREE.Texture | undefined) ?? gemEnv\n // Use mat.preset to preserve stone identity and prevent cross-mesh cache collisions\n const newMat = acquireReferenceDiamondMaterial(\n newHandle,\n envTex!,\n mat.preset,\n { rayBounces, quality: capped, orientEnvMap: mat.defines['DIA_ORIENT_ENVMAP'] === 1 },\n )\n\n releaseReferenceDiamondMaterial(mat)\n obj.material = newMat\n })\n }, 300) // 300 ms debounce\n }\n\n const viewer: Viewer = {\n load,\n unload,\n setMetalColor,\n setStoneColor,\n setPartType,\n setMaterialColor,\n setPartColor,\n clearMaterialColor,\n clearPartColor,\n clearOverrides,\n getMaterials,\n getParts,\n getState,\n setState,\n on,\n dispose,\n toggleRotation,\n startRotation,\n stopRotation,\n isRotating,\n resetCamera,\n fitToScene,\n captureSnapshot,\n setQuality,\n setShadowsEnabled,\n setMetalEnvironment,\n setGemEnvironment,\n setDiamondQuality,\n }\n\n if (typeof window !== 'undefined') {\n ;(viewer as any).__scene = scene\n ;(viewer as any).__getCurrentModel = () => currentModel\n }\n\n return viewer\n}\n","// Public API for @3d-viewer/core\n\nexport { createViewer } from './viewer'\nexport type { Viewer } from './types'\n\nexport {\n METAL_PRESETS,\n STONE_PRESETS,\n PHYSICALLY_BASED_METAL_PRESETS,\n DIAMOND_PRESETS,\n GEMSTONE_PRESETS,\n ALL_METAL_PRESETS,\n ALL_STONE_PRESETS,\n CANONICAL_METAL_PRESETS,\n CANONICAL_STONE_PRESETS,\n getMetalPreset,\n getStonePreset,\n} from './materials/presets'\nexport type {\n MetalPreset,\n StonePreset,\n StandardMetalId,\n StandardStoneId,\n MetalColorProp,\n StoneColorProp,\n} from './materials/presets'\n\nexport type {\n ModelSource,\n ViewerSourceInput,\n LoadOptions,\n SupportedFormat,\n ConvertedModel,\n PartType,\n PartInfo,\n MaterialSlotInfo,\n MeshMaterialSlot,\n StateRestoreResult,\n ViewerState,\n ViewerEvents,\n ViewerOptions,\n DiamondQuality,\n} from './types'\n\nexport { resolveQualityTier } from './materials'\nexport { UnsupportedFormatError, CorruptFileError, NetworkError } from './converter/errors'\nexport { convert, normalizeModelSource, inferFormatFromUrl } from './converter'\nexport { DEFAULT_DRACO_DECODER_PATH } from './converter/loaders'\nexport { loadHdrEnvironment } from './materials/environment'\nexport type { HdrEnvironmentHandle } from './materials/environment'\nexport { loadPmat, loadDmatPreset, loadDmatMaterial } from './materials/format-loaders'\nexport type { PmatJson, DmatJson } from './materials/format-loaders'\nexport const VERSION = '1.0.0'\n"],"names":["UnsupportedFormatError","format","__publicField","CorruptFileError","message","cause","NetworkError","status","url","normalizeScene","scene","box","THREE","center","size","maxDim","scale","DEFAULT_DRACO_DECODER_PATH","NodeFileReader","blob","buf","_a","_b","err","nodeBuffer","base64","SIZE_WARN_BYTES","parseToScene","fetched","dracoDecoderPath","warnings","parseGltf","parseStl","parseObj","loader","GLTFLoader","dracoLoader","DRACOLoader","gltf","resolve","reject","STLLoader","geometry","material","mesh","materials","mtlLoader","MTLLoader","mtlText","objLoader","OBJLoader","text","exportToGlb","exporter","GLTFExporter","result","bytes","TypedEmitter","event","cb","data","EXT_TO_FORMAT","MIME_TO_FORMAT","inferFormatFromUrl","pathname","dot","ext","inferFormatFromMime","mime","base","inferFormatFromBuffer","buffer","decompressIfGzip","ds","stream","decompressed","fetchSource","source","signal","mtlData","response","ct","mtlRes","SUPPORTED_FORMATS","normalizeModelSource","trimmed","convert","onProgress","options","glb","meshCount","obj","STONE_KEYWORDS","METAL_KEYWORDS","hasKeyword","keywords","lower","kw","sanitizeName","name","getStablePartId","usedIds","id","clean","path","curr","uniquePath","counter","getMeshMaterialSlots","mat","idx","_c","classifyByName","materialName","combined","isStone","isMetal","classifyParts","overrides","parts","partId","slots","primaryMaterialName","allMaterialNames","s","isOverridden","overriddenType","extractMaterialSlots","map","part","slot","existing","METAL_PRESETS","STONE_PRESETS","ALL_METAL_PRESETS","ALL_STONE_PRESETS","PHYSICALLY_BASED_METAL_PRESETS","m","DIAMOND_PRESETS","GEMSTONE_PRESETS","LEGACY_METAL_ALIAS_IDS","LEGACY_STONE_ALIAS_IDS","CANONICAL_METAL_PRESETS","CANONICAL_STONE_PRESETS","getMetalPreset","idOrHex","query","getStonePreset","hashMap","analyzeGeometry","g","centroid","rawRadius","radius","posAttr","index","triangleCount","totalArea","failureArea","signedVolume","p0","p1","p2","e1","e2","normal","crossP1P2","i","i0","i1","i2","doubleArea","area","D","starConvexFailureArea","flippedWinding","buildFacetAttribute","a","vertexCount","facetData","windingSign","len","v","hashGeometry","cached","hash","fnv1a","val","p","CENTER","AVERAGE","SAH","CONTAINED","PRIMITIVE_INTERSECT_COST","TRAVERSAL_COST","BYTES_PER_NODE","UINT32_PER_NODE","IS_LEAFNODE_FLAG","LEAFNODE_MASK_32","FLOAT32_EPSILON","SKIP_GENERATION","DEFAULT_OPTIONS","arrayToBox","nodeIndex32","array","target","getLongestEdgeIndex","bounds","splitDimIdx","splitDist","dist","copyBounds","unionBounds","b","aVal","bVal","d","d3","expandByPrimitiveBounds","startIndex","primitiveBounds","tCenter","tHalf","tMin","tMax","computeSurfaceArea","d0","d1","d2","IS_LEAF","n16","uint16Array","OFFSET","n32","uint32Array","COUNT","LEFT_NODE","RIGHT_NODE","relativeOffset","SPLIT_AXIS","getBounds","offset","count","centroidTarget","minx","miny","minz","maxx","maxy","maxz","cminx","cminy","cminz","cmaxx","cmaxy","cmaxz","boundsOffset","end","cx","hx","lx","rx","cy","hy","ly","ry","cz","hz","lz","rz","BIN_COUNT","binsSort","sahBins","leftBounds","getOptimalSplit","nodeBoundingData","centroidBoundingData","strategy","axis","pos","getAverage","rootSurfaceArea","bestCost","cStart","cEnd","axisLeft","binWidth","truncatedBins","c","bin","leftCacheBounds","rightCacheBounds","splitCount","bi","leftCount","rightCount","rightBounds","leftProb","rightProb","cost","binIndex","lastBin","nextBin","binCount","avg","BVHNode","partition","stride","split","left","right","axisOffset","t0","r","tb","float32Array","uint8Array","MAX_POINTER","countNodes","node","populateBuffer","byteOffset","_populateBuffer","node32Index","node16Index","isLeaf","boundingData","splitAxis","leftByteOffset","rightByteOffset","currentNodeIndex","relativeRightIndex","buildTree","bvh","loadRange","maxDepth","verbose","targetLeafSize","_strictLeafSize","partitionBuffer","partitionStride","cacheCentroidBoundingData","reachedMaxDepth","root","splitNode","triggerProgress","primitivesProcessed","depth","mustSplit","splitOffset","lstart","lcount","rstart","rcount","buildPackedTree","BufferConstructor","rootRanges","firstRange","lastRange","fullRange","range","nodeCount","PrimitivePool","getNewPrimitive","primitives","primitive","_BufferStack","stack","prevBuffer","BufferStack","_box1","_box2","boxStack","boxPool","Box3","shapecast","intersectsBounds","intersectsRange","boundsTraverseOrder","nodeOffset","shapecastTraverse","length","intersectsBoundsFunc","intersectsRangeFunc","nodeScoreFunc","nodeIndexOffset","nodeIndex16","getLeftOffset","getRightEndOffset","c1","c2","score1","score2","box1","box2","temp","isC1Leaf","c1Intersection","c1StopTraversal","isC2Leaf","c2Intersection","c2StopTraversal","_bufferStack1","_bufferStack2","_boxPool","_leftBox1","_rightBox1","_leftBox2","_rightBox2","_active","bvhcast","otherBvh","matrixToLocal","intersectsRanges","roots","otherRoots","nodeOffset1","nodeOffset2","invMat","Matrix4","il","localBox","j","jl","_traverse","node1Index32","node2Index32","matrix2to1","matrix1to2","intersectsRangesFunc","node1IndexOffset","node2IndexOffset","depth1","depth2","currBox","reversed","bufferStack1","bufferStack2","float32Array1","uint32Array1","uint16Array1","float32Array2","uint32Array2","uint16Array2","node1Index16","node2Index16","isLeaf1","isLeaf2","newBox","cl1","cr1","intersectCl1","intersectCr1","cl2","cr2","leftIntersects","rightIntersects","BVHTraversalHelper","traversing","walk","callback","_tempBox","_tempBuffer","BVH","targetBuffer","baseIndex","minX","minY","minZ","maxX","maxY","maxZ","indirectBuffer","l","rootIndex","totalNodes","rootCount","nodeIndex","leftMin","leftMax","rightMin","rightMax","callbacks","intersectsPrimitive","scratchPrimitive","iterate","originalIntersectsRange","contained","shapecastFunc","isSharedArrayBufferSupported","getVertexCount","geo","getTriCount","getIndexArray","ensureIndex","BufferAttribute","getFullPrimitiveRange","primitiveCount","drawRange","start","getPrimitiveGroupRanges","group","getRootPrimitiveRanges","primitiveRanges","ranges","drawRangeStart","drawRangeEnd","events","groupStart","groupCount","groupEnd","activeGroups","lastPos","newPos","generateIndirectBuffer","useSharedArrayBuffer","useUint32","acc","byteCount","GeometryBVH","primitiveStride","SeparatingAxisBounds","points","field","min","max","other","Vector3","boxMin","boxMax","x","y","z","closestPointLineToLine","dir1","dir2","v02","l1","l2","v0","v10","v2","v32","d0232","d3210","d3232","d0210","denom","closestPointsSegmentToSegment","paramResult","Vector2","temp1","temp2","target1","target2","closestPoint","closestPoint2","sphereIntersectTriangle","closestPointTemp","projectedPointTemp","planeTemp","Plane","lineTemp","Line3","sphere","triangle","plane","pp","componentKeys","ZERO_EPSILON","ZERO_EPSILON_SQR","isNearZero","value","ExtendedTriangle","Triangle","args","satAxes","satBounds","axis0","sab0","axis1","sab1","axis2","sab2","axis3","sab3","lengthAB","lengthBC","lengthCA","point1","point2","edge","segment","distSq","closestDistanceSq","nexti","saTri2","cachedSatBounds","cachedSatBounds2","tmpVec","tempDir","edge1","edge2","tempPoint","bounds1","bounds2","coplanarIntersectsTriangle","self","suppressLog","planeNormal","satBounds1","satAxes1","sb","sa","satBounds2","satAxes2","findSingleBounds","aProj","bProj","cProj","aDist","bDist","cDist","t","findIntersectionLineBounds","abDist","acDist","intersectTriangleSegment","degenerateTriangle","startDist","endDist","intersectTrianglePoint","point","intersectSegmentPoint","segmentTri","pointTri","handleDegenerateCases","segment1","segment2","delta1","delta2","startDelta","u","z1","z2","res","plane1","plane2","a1Dist","b1Dist","c1Dist","a1b1Dist","a1c1Dist","a2Dist","b2Dist","c2Dist","a2b2Dist","a2c2Dist","intersectionLine","componentIndex","maxComponent","comp1","key","a1Proj","b1Proj","c1Proj","a2Proj","b2Proj","c2Proj","tmp","cornerFields","line1","line2","lineTarget","otherVec","thisVec","f11","f12","f21","f22","OrientedBox","matrix","minVec","pi","alignedSatBounds","aabbBounds","saTri","pointsArr","cachedAxis","triSatBounds","triSatAxes","sa1","sa2","xyzFields","segments1","segments2","threshold","threshold2","nextIndex","nextIndex2","index2","f1","f2","f3","ExtendedTrianglePoolBase","ExtendedTrianglePool","closestPointToPoint","minThreshold","maxThreshold","minThresholdSq","maxThresholdSq","closestDistanceTriIndex","score","tri","triIndex","closestDistance","IS_GT_REVISION_169","REVISION","IS_LT_REVISION_161","_vA","_vB","_vC","_uvA","_uvB","_uvC","_normalA","_normalB","_normalC","_intersectionPoint","checkIntersection","ray","pA","pB","pC","side","near","far","intersect","BackSide","DoubleSide","distance","checkBufferGeometryIntersection","position","uv","uv1","intersection","face","barycoord","getSide","materialOrSide","intersectTri","intersections","triOffset","groups","firstIndex","materialIndex","setTriangle","ta","tc","intersectTris","_indirectBuffer","intersectClosestTri","iterateOverTriangles","intersectsTriangleFunc","refit","nodeIndices","indexArr","force","forceChildren","includesLeft","includesRight","leftNodeId","rightNodeId","traverseLeft","traverseRight","leftChange","rightChange","didChange","left_i","right_i","minLeftValue","maxLeftValue","minRightValue","maxRightValue","intersectsNodeBounds","tmin","tmax","tymin","tymax","tzmin","tzmax","invdirx","invdiry","invdirz","ox","oy","oz","intersectTris_indirect","vi","intersectClosestTri_indirect","iterateOverTriangles_indirect","raycast","intersects","_raycast","leftIndex","rightIndex","_xyzFields","raycastFirst","_raycastFirst","xyzAxis","leftToRight","c1Result","c2Result","boundingBox","triangle2","invertedMat","obb","obb2","intersectsGeometry","otherGeometry","geometryToBvh","_intersectsGeometry","cachedObb","thisGeometry","thisIndex","thisPos","otherIndex","otherPos","otherTriangleCount","tempMatrix","temp3","temp4","closestPointToGeometry","tempTarget1","tempTargetDest1","tempTarget2","tempTargetDest2","closestDistanceOtherTriIndex","otherOffset","otherCount","triCount","refit_indirect","raycast_indirect","raycastFirst_indirect","intersectsGeometry_indirect","ti","closestPointToGeometry_indirect","ti2","convertRaycastIntersect","hit","object","raycaster","_obb","_ray","Ray","_direction","_inverseMatrix","_worldScale","_getters","MeshBVH","rootData","indexAttribute","fixupVersion0","newIndex","tri3","ai","ci","el","normalized","posArr","bufferOffset","getters","writeOffset","boundsIndexOffset","halfExtents","el2","scaleFactor","hits","FrontSide","raycastFunc","closestResult","raycastFirstFunc","geomToMesh","intersectsGeometryFunc","intersectsTriangles","triangle1","indexAttr1","positionAttr1","assignTriangle1","indexAttr2","positionAttr2","assignTriangle2","iterateOverDoubleTriangles","offset1","count1","offset2","count2","nodeIndex1","nodeIndex2","originalIntersectsRanges","boxToMesh","countToStringFormat","countToFormat","RedFormat","RGFormat","RGBAFormat","countToIntFormat","RedIntegerFormat","RGIntegerFormat","RGBAIntegerFormat","VertexAttributeTexture","DataTexture","NearestFilter","attr","overrideItemSize","originalItemSize","originalCount","itemSize","originalBufferCons","targetType","finalStride","FloatType","UnsignedIntType","IntType","type","normalizeValue","targetBufferCons","internalFormat","UnsignedByteType","ByteType","ShortType","UnsignedShortType","dimension","dataArray","originalNormalized","ii","UIntVertexAttributeTexture","FloatVertexAttributeTexture","MeshBVHUniformStruct","bvhToTextures","dereferenceIndex","bvhBounds","bvhContents","unpacked","indexArray","i3","v3","boundsTexture","contentsTexture","boundsDimension","boundsArray","contentsDimension","contentsArray","boundsIndex","mergedLeafCount","rightNodeIndex","common_functions","bvh_ray_functions","bvh_struct_definitions","shaderStructs","BVHShaderGLSL.bvh_struct_definitions","shaderIntersectFunction","BVHShaderGLSL.common_functions","BVHShaderGLSL.bvh_ray_functions","DIAMOND_BAKE_VERT","DIAMOND_BAKE_FRAG","DIAMOND_RAYMARCH_VERT","DIAMOND_RAYMARCH_FRAG","DiamondNormalBaker","renderer","opts","analysis","isUnorm","renderTarget","handle","bakeGeo","bakeMat","camera","prevRenderTarget","prevAutoClear","prevToneMapping","prevClearColor","prevClearAlpha","gl","preError","postError","entry","newTarget","globalDiamondBaker","_invMat","DiamondMaterial","envMap","preset","physOpts","bvhValue","_renderer","_scene","_geometry","materialCache","acquireDiamondMaterial","optSuffix","releaseDiamondMaterial","JewelryStudioEnvironment","domeGeo","domeMat","dome","topGeo","topMat","topPanel","leftSoftboxGeo","leftSoftboxMat","leftSoftbox","rightSoftboxGeo","rightSoftboxMat","rightSoftbox","rimGeo","rimMat","leftRim","rightRim","groundGeo","groundMat","ground","flagGeo","flagMat","leftFlag","rightFlag","resources","setupEnvironment","pmremGenerator","studioEnv","env","JewelryGemEnvironment","upperSoftboxes","lateralSoftboxes","zenithBaffleGeo","zenithBaffleMat","zenithBaffle","flagPositions","fx","fy","fz","flag","emitterPositions","panelGeo","panelMat","panel","setupGemEnvironment","cubeTarget","cubeCamera","gemEnv","prevTarget","loadHdrEnvironment","urlOrData","processDataTexture","dataTexture","gemRenderTarget","isExr","EXRLoader","dataTex","RGBELoader","hdrTexture","bvhCache","getOrCreateDiamondBVH","targetGeom","boundsTree","bvhStruct","parseJson","input","toColorHex","loadPmat","json","loadDmatPreset","hex","bf","loadDmatMaterial","DIAMOND_REF_VERT","DIAMOND_REF_FRAG","resolveQualityTier","q","ReferenceDiamondMaterial","rayBounces","isCube","bfR","bfG","bfB","_r","_s","_g","tex","newType","cloned","acquireReferenceDiamondMaterial","qualityKey","orientKey","releaseReferenceDiamondMaterial","applyMetalMaterial","hexOrPresetId","slotIndex","applyStoneMaterial","oldHandle","newMat","ensureMaterial","diamondMode","isPhysical","isDiamond","prev","metal","isRefDiamond","resolvedEnv","stone","createRenderer","container","cameraOrOptions","antialiasOrOptions","aa","initialQuality","setQuality","quality","dpr","targetDpr","ro","w","h","createScene","background","fov","bgColor","keyLight","fillLight","updateCameraAspect","width","height","createControls","domElement","controls","OrbitControls","initialPosition","initialTarget","resetCamera","fitCameraToScene","controlsOrHandle","fovRad","createInteraction","emitter","getParts","pointer","hoveredMesh","hoveredSlotIndex","hoveredOriginalEmissive","hoveredOriginalIntensity","isDragging","pointerDownPos","enableHighlight","getMeshes","meshes","getMaterial","setHover","slotIdx","onPointerMove","e","rect","firstHit","onPointerLeave","onPointerDown","onPointerUp","dx","dy","targetMesh","clickedSlotIndex","onDragStart","onDragEnd","buildState","metalColor","stoneColor","partOverrides","materialColors","partColors","modelId","state","restoreState","applyMetalColor","applyStoneColor","setPartType","unresolvedParts","unresolvedMaterials","partIdOrMeshId","slotIdOrName","color","partTarget","colonIdx","createContactShadowPlane","texture","canvas","ctx","gradient","canvasTexture","visible","disposeModel","model","_d","_e","createViewer","sceneHandle","disposeScene","rendererHandle","controlsHandle","shadowHandle","metalHdrHandle","gemHdrHandle","applyMobileCap","requested","mobileMax","order","currentDiamondQuality","qualityDebounceTimer","setMetalEnvironment","currentModel","setGemEnvironment","handleContextRestored","partInfos","materialSlots","materialOverrides","partColorOverrides","abortController","rafId","paused","render","onVisibility","wasPaused","interaction","getEffectiveModel","viewer","mock","resolveMeshSlotColor","partSlotKey","meshSlotKey","ensureUniqueMeshMaterial","o","applyColorsToMesh","anyOverridden","_","load","currentAbort","converted","setDiamondQuality","setMetalColor","getState","setStoneColor","meshIdOrPartId","targetKey","setMaterialColor","colorOrPresetId","matchingSlots","setPartColor","clearMaterialColor","clearPartColor","k","clearOverrides","getMaterials","setState","availablePartIds","availableSlotIds","availableMaterialNames","on","dispose","toggleRotation","speed","startRotation","stopRotation","isRotating","fitToScene","captureSnapshot","snapshotOptions","setShadowsEnabled","enabled","unload","capped","cubeResolution","newHandle","envTex","VERSION"],"mappings":"kiCAAO,MAAMA,WAA+B,KAAM,CAGhD,YAAYC,EAAgB,CAC1B,MAAM,wBAAwBA,CAAM,GAAG,EAHhCC,GAAA,eAIP,KAAK,KAAO,yBACZ,KAAK,OAASD,EACd,OAAO,eAAe,KAAMD,GAAuB,SAAS,CAC9D,CACF,CAEO,MAAMG,WAAyB,KAAM,CAG1C,YAAYC,EAAiBC,EAAiB,CAC5C,MAAMD,CAAO,EAHGF,GAAA,cAIhB,KAAK,KAAO,mBACZ,KAAK,MAAQG,EACb,OAAO,eAAe,KAAMF,GAAiB,SAAS,CACxD,CACF,CAEO,MAAMG,WAAqB,KAAM,CAItC,YAAYF,EAAiBG,EAAiBC,EAAc,CAC1D,MAAMJ,CAAO,EAJNF,GAAA,eACAA,GAAA,YAIP,KAAK,KAAO,eACZ,KAAK,OAASK,EACd,KAAK,IAAMC,EACX,OAAO,eAAe,KAAMF,GAAa,SAAS,CACpD,CACF,CC1BO,SAASG,GAAeC,EAA0B,CACvDA,EAAM,SAAS,IAAI,EAAG,EAAG,CAAC,EAC1BA,EAAM,MAAM,IAAI,EAAG,EAAG,CAAC,EACvBA,EAAM,kBAAkB,EAAI,EAE5B,MAAMC,EAAM,IAAIC,EAAM,KAAA,EAAO,cAAcF,CAAK,EAC1CG,EAASF,EAAI,UAAU,IAAIC,EAAM,OAAS,EAC1CE,EAAOH,EAAI,QAAQ,IAAIC,EAAM,OAAS,EAEtCG,EAAS,KAAK,IAAID,EAAK,EAAGA,EAAK,EAAGA,EAAK,CAAC,EACxCE,EAAQD,EAAS,EAAI,EAAIA,EAAS,EAGxCL,EAAM,MAAM,UAAUM,CAAK,EAE3BN,EAAM,SAAS,IAAIG,EAAO,eAAeG,CAAK,CAAC,EAE/CN,EAAM,kBAAkB,EAAI,CAC9B,CCjBO,MAAMO,GAA6B,0DAM1C,GAAI,OAAO,WAAW,WAAe,IAAa,CAChD,MAAMC,CAAe,CAArB,cACEhB,GAAA,cAAsC,MACtCA,GAAA,iBAAiC,MACjCA,GAAA,cAA8B,MAC9BA,GAAA,eAA2C,MAE3C,kBAAkBiB,EAAY,CAC5BA,EAAK,cAAc,KAChBC,GAAQ,SACP,KAAK,OAASA,GACdC,EAAA,KAAK,SAAL,MAAAA,EAAA,YACAC,EAAA,KAAK,YAAL,MAAAA,EAAA,UACF,EACCC,GAAQ,UACPF,EAAA,KAAK,UAAL,MAAAA,EAAA,UAAeE,IACfD,EAAA,KAAK,YAAL,MAAAA,EAAA,UACF,CAAA,CAEJ,CAEA,cAAcH,EAAY,CACxBA,EAAK,cAAc,KAChBC,GAAQ,SACP,MAAMI,EAAc,WAAyG,OACvHC,EAASD,EAAaA,EAAW,KAAKJ,CAAG,EAAE,SAAS,QAAQ,EAAI,GACtE,KAAK,OAAS,QAAQD,EAAK,IAAI,WAAWM,CAAM,IAChDJ,EAAA,KAAK,SAAL,MAAAA,EAAA,YACAC,EAAA,KAAK,YAAL,MAAAA,EAAA,UACF,EACCC,GAAQ,UACPF,EAAA,KAAK,UAAL,MAAAA,EAAA,UAAeE,IACfD,EAAA,KAAK,YAAL,MAAAA,EAAA,UACF,CAAA,CAEJ,CAAA,CAEA,WAAgE,WAAaJ,CACjF,CAEA,MAAMQ,GAAkB,GAAK,KAAO,KAOpC,eAAsBC,GACpBC,EACAC,EACsB,CACtB,MAAMC,EAAqB,CAAA,EAM3B,OAJIF,EAAQ,KAAK,WAAaF,IAC5BI,EAAS,KAAK,iDAAiD,EAGzDF,EAAQ,OAAA,CACd,IAAK,MACL,IAAK,OACH,OAAOG,GAAUH,EAASE,EAAUD,CAAgB,EACtD,IAAK,MACH,OAAOG,GAASJ,EAASE,CAAQ,EACnC,IAAK,MACH,OAAOG,GAASL,EAASE,CAAQ,CAAA,CAEvC,CAEA,eAAeC,GACbH,EACAE,EACAD,EACsB,CACtB,MAAMK,EAAS,IAAIC,cACbC,EAAc,IAAIC,eACxBD,EAAY,eAAeP,GAAoBZ,EAA0B,EACzEiB,EAAO,eAAeE,CAAW,EAEjC,GAAI,CACF,MAAME,EAAO,MAAM,IAAI,QAAgC,CAACC,EAASC,IAAW,CAC1EN,EAAO,MACLN,EAAQ,KACR,GACAW,EACAC,CAAA,CAEJ,CAAC,EACD,OAAAJ,EAAY,QAAA,EACZ3B,GAAe6B,EAAK,KAAK,EAClB,CAAE,MAAOA,EAAK,MAAO,SAAAR,CAAA,CAC9B,OAASP,EAAK,CACZ,MAAAa,EAAY,QAAA,EACN,IAAIjC,GAAiB,2BAA4BoB,CAAG,CAC5D,CACF,CAEA,SAASS,GAASJ,EAAwBE,EAAiC,CACzE,MAAMI,EAAS,IAAIO,aACnB,IAAIC,EACJ,GAAI,CACFA,EAAWR,EAAO,MAAMN,EAAQ,IAAI,CACtC,OAASL,EAAK,CACZ,MAAM,IAAIpB,GAAiB,sBAAuBoB,CAAG,CACvD,CAEA,MAAMoB,EAAW,IAAI/B,EAAM,qBAAqB,CAC9C,KAAM,QACN,MAAO,SACP,UAAW,EACX,UAAW,GACX,gBAAiB,CAAA,CAClB,EACKgC,EAAO,IAAIhC,EAAM,KAAK8B,EAAUC,CAAQ,EAC9CC,EAAK,KAAO,QACZ,MAAMlC,EAAQ,IAAIE,EAAM,MACxB,OAAAF,EAAM,IAAIkC,CAAI,EACdnC,GAAeC,CAAK,EACb,CAAE,MAAAA,EAAO,SAAAoB,CAAA,CAClB,CAEA,eAAeG,GAASL,EAAwBE,EAA0C,CACnFF,EAAQ,SACXE,EAAS,KAAK,qDAAqD,EAGrE,IAAIe,EAEJ,GAAIjB,EAAQ,QAAS,CACnB,MAAMkB,EAAY,IAAIC,aAChBC,EAAU,IAAI,YAAA,EAAc,OAAOpB,EAAQ,OAAO,EACxD,GAAI,CACFiB,EAAYC,EAAU,MAAME,EAAS,EAAE,EACvCH,EAAU,QAAA,CACZ,MAAQ,CACNf,EAAS,KAAK,oDAAoD,EAClEe,EAAY,MACd,CACF,CAEA,MAAMI,EAAY,IAAIC,aAClBL,GACFI,EAAU,aAAaJ,CAAS,EAGlC,IAAInC,EACJ,GAAI,CACF,MAAMyC,EAAO,IAAI,YAAA,EAAc,OAAOvB,EAAQ,IAAI,EAClDlB,EAAQuC,EAAU,MAAME,CAAI,CAC9B,OAAS5B,EAAK,CACZ,MAAM,IAAIpB,GAAiB,sBAAuBoB,CAAG,CACvD,CAEA,OAAAd,GAAeC,CAAK,EACb,CAAE,MAAAA,EAAO,SAAAoB,CAAA,CAClB,CAEA,eAAsBsB,GAAY1C,EAA0C,CAC1E,MAAM2C,EAAW,IAAIC,gBACrB,OAAO,IAAI,QAAqB,CAACf,EAASC,IAAW,CACnDa,EAAS,MACP3C,EACC6C,GAAW,CACV,GAAIA,aAAkB,YACpBhB,EAAQgB,CAAM,MACT,CAEL,MAAMJ,EAAO,KAAK,UAAUI,CAAM,EAC5BC,EAAQ,IAAI,cAAc,OAAOL,CAAI,EAC3CZ,EAAQiB,EAAM,MAAM,CACtB,CACF,EACAhB,EACA,CAAE,OAAQ,EAAA,CAAK,CAEnB,CAAC,CACH,CC3LO,MAAMiB,EAAoC,CAA1C,cACYvD,GAAA,sBAAiB,KAKlC,GACEwD,EACAC,EACY,CACZ,OAAK,KAAK,WAAW,IAAID,CAAK,GAC5B,KAAK,WAAW,IAAIA,EAAO,IAAI,GAAK,EAEtC,KAAK,WAAW,IAAIA,CAAK,EAAG,IAAIC,CAAuB,EAChD,IAAM,KAAK,IAAID,EAAOC,CAAE,CACjC,CAEA,IAA4BD,EAAUC,EAA+B,QACnEtC,EAAA,KAAK,WAAW,IAAIqC,CAAK,IAAzB,MAAArC,EAA4B,OAAOsC,EACrC,CAEA,KAA6BD,EAAUE,EAAuB,QAC5DvC,EAAA,KAAK,WAAW,IAAIqC,CAAK,IAAzB,MAAArC,EAA4B,QAASsC,GAAO,CAC1C,GAAI,CACFA,EAAGC,CAAI,CACT,OAASrC,EAAK,CACZ,QAAQ,MAAM,2CAA2C,OAAOmC,CAAK,CAAC,KAAMnC,CAAG,CACjF,CACF,EACF,CAEA,OAAc,CACZ,KAAK,WAAW,MAAA,CAClB,CACF,CCjCA,MAAMsC,GAAiD,CACrD,OAAQ,MACR,OAAQ,MACR,OAAQ,MACR,QAAS,MACX,EAEMC,GAAkD,CACtD,oBAAqB,MACrB,kBAAmB,MACrB,EAEO,SAASC,GAAmBvD,EAAqC,CACtE,GAAI,CACF,MAAMwD,EAAW,IAAI,IAAIxD,EAAK,cAAc,EAAE,SACxCyD,EAAMD,EAAS,YAAY,GAAG,EACpC,GAAIC,IAAQ,GAAI,OAAO,KACvB,MAAMC,EAAMF,EAAS,MAAMC,CAAG,EAAE,YAAA,EAChC,OAAOJ,GAAcK,CAAG,GAAK,IAC/B,MAAQ,CACN,OAAO,IACT,CACF,CAEO,SAASC,GAAoBC,EAAsC,CACxE,MAAMC,EAAOD,EAAK,MAAM,GAAG,EAAE,CAAC,EAAE,KAAA,EAAO,YAAA,EACvC,OAAON,GAAeO,CAAI,GAAK,IACjC,CAEO,SAASC,GAAsBC,EAA6C,CACjF,GAAIA,EAAO,WAAa,EAAG,OAAO,KAClC,MAAMf,EAAQ,IAAI,WAAWe,EAAQ,EAAG,KAAK,IAAIA,EAAO,WAAY,EAAE,CAAC,EAEvE,OAAIf,EAAM,CAAC,IAAM,KAAQA,EAAM,CAAC,IAAM,KAAQA,EAAM,CAAC,IAAM,IAAQA,EAAM,CAAC,IAAM,GACvE,MAGLA,EAAM,CAAC,IAAM,IACR,OAGM,OAAO,aAAa,GAAGA,EAAM,MAAM,EAAG,CAAC,CAAC,EAAE,YAAA,IAC1C,QACN,MAEF,IACT,CAEA,eAAsBgB,GAAiBD,EAA2C,CAChF,MAAMf,EAAQ,IAAI,WAAWe,CAAM,EACnC,GAAIf,EAAM,QAAU,GAAKA,EAAM,CAAC,IAAM,IAAQA,EAAM,CAAC,IAAM,KACrD,OAAO,oBAAwB,IACjC,GAAI,CACF,MAAMiB,EAAK,IAAI,oBAAoB,MAAM,EACnCC,EAAS,IAAI,KAAK,CAACH,CAAM,CAAC,EAAE,OAAA,EAAS,YAAYE,CAAE,EACnDE,EAAe,MAAM,IAAI,SAASD,CAAM,EAAE,YAAA,EAChD,GAAIC,EAAa,WAAa,EAC5B,OAAOA,CAEX,OAASpD,EAAK,CACZ,QAAQ,KAAK,uEAAwEA,CAAG,CAC1F,CAGJ,OAAOgD,CACT,CAQA,eAAsBK,GACpBC,EACAC,EACwB,CAExB,GAAI,SAAUD,EAAQ,CACpB,IAAIjB,EACFiB,EAAO,gBAAgB,KAAO,MAAMA,EAAO,KAAK,cAAgBA,EAAO,KACzEjB,EAAO,MAAMY,GAAiBZ,CAAI,EAClC,MAAMmB,EACJF,EAAO,mBAAmB,KACtB,MAAMA,EAAO,QAAQ,cACrBA,EAAO,QACP5E,EAAS4E,EAAO,QAAUP,GAAsBV,CAAI,GAAK,MAC/D,MAAO,CAAE,KAAAA,EAAM,QAAAmB,EAAS,OAAA9E,CAAAA,CAC1B,CAGA,IAAIA,EAA6C4E,EAAO,QAAUd,GAAmBc,EAAO,GAAG,EAE/F,MAAMG,EAAW,MAAM,MAAMH,EAAO,IAAK,CACvC,QAASA,EAAO,QAChB,OAAAC,CAAA,CACD,EAAE,MAAOvD,GAAiB,CACzB,MAAKA,EAAc,OAAS,aAAoBA,EAC1C,IAAIjB,GACR,iBAAkBiB,EAAc,OAAO,GACvC,OACAsD,EAAO,GAAA,CAEX,CAAC,EAED,GAAI,CAACG,EAAS,GACZ,MAAM,IAAI1E,GAAa,QAAQ0E,EAAS,MAAM,GAAIA,EAAS,OAAQH,EAAO,GAAG,EAG/E,GAAI,CAAC5E,EAAQ,CACX,MAAMgF,EAAKD,EAAS,QAAQ,IAAI,cAAc,GAAK,GACnD/E,EAASkE,GAAoBc,CAAE,CACjC,CAEA,IAAIrB,EAAO,MAAMoB,EAAS,YAAA,EAO1B,GANApB,EAAO,MAAMY,GAAiBZ,CAAI,EAE7B3D,IACHA,EAASqE,GAAsBV,CAAI,GAGjC,CAAC3D,EACH,MAAM,IAAID,GAAuB,SAAS,EAG5C,IAAI+E,EACJ,GAAIF,EAAO,OAAQ,CACjB,MAAMK,EAAS,MAAM,MAAML,EAAO,OAAQ,CACxC,QAASA,EAAO,QAChB,OAAAC,CAAA,CACD,EACGI,EAAO,KACTH,EAAU,MAAMG,EAAO,YAAA,EAE3B,CAEA,MAAO,CAAE,KAAAtB,EAAM,QAAAmB,EAAS,OAAA9E,CAAA,CAC1B,CC1IA,MAAMkF,GAAgD,CAAC,MAAO,OAAQ,MAAO,KAAK,EAM3E,SAASpB,GAAmBvD,EAA8B,OAE/D,MAAM0D,GAAM7C,EADKb,EAAI,MAAM,GAAG,EAAE,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC,EAC1B,MAAM,GAAG,EAAE,IAAA,IAApB,YAAAa,EAA2B,cACvC,OAAI6C,GAAQiB,GAAwC,SAASjB,CAAG,EACvDA,EAEF,KACT,CAMO,SAASkB,GAAqBP,EAA+C,CAClF,GAAI,CAACA,EAAQ,OAAO,KAEpB,GAAI,OAAOA,GAAW,SAAU,CAC9B,MAAMQ,EAAUR,EAAO,KAAA,EACvB,OAAKQ,EACE,CACL,IAAKA,EACL,OAAQtB,GAAmBsB,CAAO,CAAA,EAHf,IAKvB,CAGA,OAAOR,CACT,CC5BA,eAAsBS,GACpBT,EACAC,EACAS,EACAC,EACyB,CACzBD,GAAA,MAAAA,EAAa,GAEb,MAAM3D,EAAU,MAAMgD,GAAYC,EAAQC,CAAM,EAEhDS,GAAA,MAAAA,EAAa,IAEb,KAAM,CAAE,MAAA7E,EAAO,SAAAoB,CAAA,EAAa,MAAMH,GAAaC,EAAS4D,GAAA,YAAAA,EAAS,gBAAgB,EAEjFD,GAAA,MAAAA,EAAa,IAEb,MAAME,EAAM7D,EAAQ,SAAW,MAAQA,EAAQ,KAAO,MAAMwB,GAAY1C,CAAK,EAE7E6E,GAAA,MAAAA,EAAa,GAGb,IAAIG,EAAY,EAChB,OAAAhF,EAAM,SAAUiF,GAAQ,CACjBA,EAA6B,QAAQD,GAC5C,CAAC,EAEM,CACL,IAAAD,EACA,aAAc7D,EAAQ,OACtB,UAAA8D,EACA,SAAA5D,CAAA,CAEJ,CCvCO,MAAM8D,GAAiB,CAAC,QAAS,UAAW,MAAO,QAAS,SAAS,EAC/DC,GAAiB,CAAC,QAAS,OAAQ,SAAU,WAAY,OAAQ,OAAQ,QAAS,OAAO,ECGtG,SAASC,GAAW3C,EAAc4C,EAA6B,CAC7D,MAAMC,EAAQ7C,EAAK,YAAA,EACnB,OAAO4C,EAAS,KAAME,GAAOD,EAAM,SAASC,CAAE,CAAC,CACjD,CAEA,SAASC,GAAaC,EAAsB,CAC1C,OAAOA,EAAK,KAAA,EAAO,QAAQ,kBAAmB,GAAG,CACnD,CAEO,SAASC,GACdxD,EACAlC,EACA2F,EACQ,SAER,GAAI,QAAOhF,EAAAuB,EAAK,WAAL,YAAAvB,EAAe,SAAW,UAAYuB,EAAK,SAAS,OAAO,OAAQ,CAC5E,MAAM0D,EAAK1D,EAAK,SAAS,OAAO,KAAA,EAChC,OAAAyD,EAAQ,IAAIC,CAAE,EACPA,CACT,CACA,GAAI,QAAOhF,EAAAsB,EAAK,WAAL,YAAAtB,EAAe,KAAO,UAAYsB,EAAK,SAAS,GAAG,OAAQ,CACpE,MAAM0D,EAAK1D,EAAK,SAAS,GAAG,KAAA,EAC5B,OAAAyD,EAAQ,IAAIC,CAAE,EACPA,CACT,CAGA,GAAI1D,EAAK,MAAQA,EAAK,KAAK,OAAQ,CACjC,MAAM2D,EAAQ3D,EAAK,KAAK,KAAA,EACxB,GAAI,CAACyD,EAAQ,IAAIE,CAAK,EACpB,OAAAF,EAAQ,IAAIE,CAAK,EACVA,CAEX,CAGA,IAAIC,EAAO5D,EAAK,KAAOA,EAAK,KAAK,OAAS,OACtC6D,EAA8B7D,EAAK,OACvC,KAAO6D,GAAQA,IAAS/F,GAClB+F,EAAK,MAAQA,EAAK,KAAK,SACzBD,EAAO,GAAGC,EAAK,KAAK,MAAM,IAAID,CAAI,IAEpCC,EAAOA,EAAK,OAGd,IAAIC,EAAaF,EACbG,EAAU,EACd,KAAON,EAAQ,IAAIK,CAAU,GAC3BA,EAAa,GAAGF,CAAI,IAAIG,GAAS,GAEnC,OAAAN,EAAQ,IAAIK,CAAU,EACfA,CACT,CAEO,SAASE,GAAqBhE,EAAsC,WACzE,GAAI,MAAM,SAAQvB,EAAAuB,EAAK,WAAL,YAAAvB,EAAe,aAAa,GAAKuB,EAAK,SAAS,cAAc,OAAS,EACtF,OAAOA,EAAK,SAAS,cAGvB,GAAI,MAAM,QAAQA,EAAK,QAAQ,EAC7B,OAAOA,EAAK,SAAS,IAAI,CAACiE,EAAKC,IAAQ,SACrC,MAAMX,IAAOU,EAAAA,GAAAA,YAAAA,EAAK,OAALA,YAAAA,EAAW,SAAU,YAAYC,CAAG,GAIjD,MAAO,CACL,OAHC,QAAOD,EAAAA,GAAAA,YAAAA,EAAK,WAALA,YAAAA,EAAe,SAAW,UAAYA,EAAI,SAAS,QAC3D,QAAQC,CAAG,IAAIZ,GAAaC,CAAI,CAAC,GAGjC,aAAcA,EACd,MAAOW,CAAA,CAEX,CAAC,EAGH,MAAMD,EAAMjE,EAAK,SACXuD,IAAO7E,EAAAuF,GAAA,YAAAA,EAAK,OAAL,YAAAvF,EAAW,UAAWsB,EAAK,KAAO,GAAGA,EAAK,IAAI,OAAS,WAKpE,MAAO,CACL,CACE,OALD,QAAOmE,EAAAF,GAAA,YAAAA,EAAK,WAAL,YAAAE,EAAe,SAAW,UAAYF,EAAI,SAAS,QAC3D,UAAUX,GAAaC,CAAI,CAAC,GAK1B,aAAcA,EACd,MAAO,CAAA,CACT,CAEJ,CAEA,SAASa,GAAeb,EAAcc,EAAgC,CACpE,MAAMC,EAAW,GAAGf,CAAI,IAAIc,CAAY,GAClCE,EAAUrB,GAAWoB,EAAUtB,EAAc,EAC7CwB,EAAUtB,GAAWoB,EAAUrB,EAAc,EAEnD,OAAIsB,EAAgB,QACA,OAEtB,CAEO,SAASE,GACd3G,EACA4G,EACY,CACZ,MAAMC,EAAoB,CAAA,EACpBlB,MAAc,IAEpB,OAAA3F,EAAM,SAAUiF,GAAQ,OACtB,GAAI,EAAEA,aAAe/E,EAAM,MAAO,OAElC,MAAMgC,EAAO+C,EACP6B,EAASpB,GAAgBxD,EAAMlC,EAAO2F,CAAO,EACnDzD,EAAK,SAAS,OAAS4E,EAEvB,MAAMC,EAAQb,GAAqBhE,CAAI,EACvCA,EAAK,SAAS,cAAgB6E,EAE9B,MAAMC,IAAsBrG,EAAAoG,EAAM,CAAC,IAAP,YAAApG,EAAU,eAAgB,GACtDuB,EAAK,SAAS,qBAAuB8E,EAErC,MAAMC,EAAmBF,EAAM,IAAKG,GAAMA,EAAE,YAAY,EAAE,KAAK,GAAG,EAG5DC,EAAejF,EAAK,QAAQ0E,GAAaE,KAAUF,EACnDQ,EAAiBR,EAAUE,CAAM,GAAKF,EAAU1E,EAAK,IAAI,EAE3DiF,GAAgBC,EAClBP,EAAM,KAAK,CACT,OAAQ3E,EAAK,KACb,OAAA4E,EACA,SAAU5E,EAAK,KACf,aAAc8E,EACd,MAAAD,EACA,KAAMK,EACN,WAAY,EAAA,CACb,EAEDP,EAAM,KAAK,CACT,OAAQ3E,EAAK,KACb,OAAA4E,EACA,SAAU5E,EAAK,KACf,aAAc8E,EACd,MAAAD,EACA,KAAMT,GAAepE,EAAK,KAAM+E,CAAgB,EAChD,WAAY,EAAA,CACb,CAEL,CAAC,EAEMJ,CACT,CAEO,SAASQ,GAAqBR,EAAuC,CAC1E,MAAMS,MAAU,IAEhB,UAAWC,KAAQV,EACjB,UAAWW,KAAQD,EAAK,MAAO,CAC7B,MAAME,EAAWH,EAAI,IAAIE,EAAK,MAAM,EAChCC,GACGA,EAAS,QAAQ,SAASF,EAAK,MAAM,GACxCE,EAAS,QAAQ,KAAKF,EAAK,MAAM,EAE9BE,EAAS,QAAQ,SAASF,EAAK,MAAM,GACxCE,EAAS,QAAQ,KAAKF,EAAK,MAAM,EAG/BE,EAAS,OAAS,SAAWF,EAAK,OAAS,UAC7CE,EAAS,KAAO,UAGlBH,EAAI,IAAIE,EAAK,OAAQ,CACnB,OAAQA,EAAK,OACb,KAAMA,EAAK,aACX,KAAMD,EAAK,KACX,QAAS,CAACA,EAAK,MAAM,EACrB,QAAS,CAACA,EAAK,MAAM,CAAA,CACtB,CAEL,CAGF,OAAO,MAAM,KAAKD,EAAI,OAAA,CAAQ,CAChC,CCzIO,MAAMI,GAA+B,CAE1C,CAAE,GAAI,kBAAmB,MAAO,kBAAmB,IAAK,UAAW,UAAW,EAAK,UAAW,IAAM,SAAU,OAAQ,cAAe,UAAW,QAAS,MAAO,UAAW,iCAAA,EAC3K,CAAE,GAAI,kBAAmB,MAAO,kBAAmB,IAAK,UAAW,UAAW,EAAK,UAAW,IAAM,SAAU,OAAQ,cAAe,UAAW,QAAS,MAAO,UAAW,iCAAA,EAC3K,CAAE,GAAI,gBAAiB,MAAO,gBAAiB,IAAK,UAAW,UAAW,EAAK,UAAW,IAAM,SAAU,OAAQ,cAAe,UAAW,QAAS,MAAO,OAAQ,4BAA6B,UAAW,+BAAA,EAC5M,CAAE,GAAI,gBAAiB,MAAO,gBAAiB,IAAK,UAAW,UAAW,EAAK,UAAW,IAAM,SAAU,OAAQ,cAAe,UAAW,QAAS,MAAO,UAAW,+BAAA,EACvK,CAAE,GAAI,gBAAiB,MAAO,gBAAiB,IAAK,UAAW,UAAW,EAAK,UAAW,IAAM,SAAU,OAAQ,cAAe,UAAW,QAAS,MAAO,UAAW,+BAAA,EACvK,CAAE,GAAI,iBAAkB,MAAO,iBAAkB,IAAK,UAAW,UAAW,EAAK,UAAW,IAAM,SAAU,OAAQ,cAAe,UAAW,QAAS,MAAO,UAAW,gCAAA,EACzK,CAAE,GAAI,eAAgB,MAAO,eAAgB,IAAK,UAAW,UAAW,EAAK,UAAW,IAAM,SAAU,kBAAmB,cAAe,UAAW,QAAS,MAAO,OAAQ,gCAAiC,UAAW,8BAAA,EACzN,CAAE,GAAI,aAAc,MAAO,sBAAuB,IAAK,UAAW,UAAW,EAAK,UAAW,IAAM,SAAU,kBAAmB,cAAe,UAAW,QAAS,MAAO,OAAQ,8BAA+B,UAAW,4BAAA,EAC5N,CAAE,GAAI,WAAY,MAAO,WAAY,IAAK,UAAW,UAAW,EAAK,UAAW,GAAM,SAAU,cAAe,cAAe,UAAW,QAAS,KAAM,OAAQ,gCAAiC,UAAW,0BAAA,EAC5M,CAAE,GAAI,kBAAmB,MAAO,kBAAmB,IAAK,UAAW,UAAW,IAAM,UAAW,IAAM,SAAU,cAAe,cAAe,UAAW,QAAS,MAAO,UAAW,iCAAA,EAGnL,CAAE,GAAI,yBAA0B,MAAO,yBAA0B,IAAK,UAAW,UAAW,EAAK,UAAW,EAAM,SAAU,OAAQ,cAAe,UAAW,IAAK,IAAK,OAAQ,0BAA2B,UAAW,wCAAA,EACtN,CAAE,GAAI,uBAAwB,MAAO,uBAAwB,IAAK,UAAW,UAAW,EAAK,UAAW,EAAM,SAAU,OAAQ,cAAe,UAAW,IAAK,IAAK,OAAQ,0BAA2B,UAAW,sCAAA,EAClN,CAAE,GAAI,0BAA2B,MAAO,0BAA2B,IAAK,UAAW,UAAW,EAAK,UAAW,EAAM,SAAU,OAAQ,cAAe,UAAW,IAAK,IAAK,OAAQ,0BAA2B,UAAW,yCAAA,EACxN,CAAE,GAAI,oBAAqB,MAAO,0BAA2B,IAAK,UAAW,UAAW,EAAK,UAAW,EAAM,SAAU,OAAQ,cAAe,UAAW,IAAK,IAAK,OAAQ,0BAA2B,UAAW,mCAAA,EAClN,CAAE,GAAI,yBAA0B,MAAO,yBAA0B,IAAK,UAAW,UAAW,EAAK,UAAW,EAAM,SAAU,OAAQ,cAAe,UAAW,IAAK,IAAK,OAAQ,0BAA2B,UAAW,wCAAA,EACtN,CAAE,GAAI,eAAgB,MAAO,eAAgB,IAAK,UAAW,UAAW,EAAK,UAAW,EAAM,SAAU,OAAQ,cAAe,UAAW,IAAK,IAAK,OAAQ,0BAA2B,UAAW,8BAAA,EAClM,CAAE,GAAI,eAAgB,MAAO,eAAgB,IAAK,UAAW,UAAW,EAAK,UAAW,EAAM,SAAU,OAAQ,cAAe,UAAW,IAAK,IAAK,OAAQ,0BAA2B,UAAW,8BAAA,EAClM,CAAE,GAAI,eAAgB,MAAO,cAAe,IAAK,UAAW,UAAW,EAAK,UAAW,EAAM,SAAU,OAAQ,cAAe,UAAW,IAAK,IAAK,OAAQ,0BAA2B,UAAW,8BAAA,EACjM,CAAE,GAAI,sBAAuB,MAAO,sBAAuB,IAAK,UAAW,UAAW,EAAK,UAAW,GAAM,SAAU,kBAAmB,cAAe,UAAW,IAAK,IAAK,OAAQ,0BAA2B,UAAW,qCAAA,EAC3N,CAAE,GAAI,wBAAyB,MAAO,wBAAyB,IAAK,UAAW,UAAW,EAAK,UAAW,EAAM,SAAU,kBAAmB,cAAe,UAAW,IAAK,IAAK,OAAQ,0BAA2B,UAAW,uCAAA,EAG/N,CAAE,GAAI,cAAe,MAAO,cAAe,IAAK,UAAW,UAAW,EAAK,UAAW,IAAM,UAAW,6BAAA,EACvG,CAAE,GAAI,YAAa,MAAO,YAAa,IAAK,UAAW,UAAW,EAAK,UAAW,IAAM,UAAW,2BAAA,EACnG,CAAE,GAAI,aAAc,MAAO,aAAc,IAAK,UAAW,UAAW,EAAK,UAAW,IAAM,UAAW,4BAAA,EACrG,CAAE,GAAI,WAAY,MAAO,WAAY,IAAK,UAAW,UAAW,EAAK,UAAW,IAAM,UAAW,0BAAA,EACjG,CAAE,GAAI,SAAU,MAAO,SAAU,IAAK,UAAW,UAAW,EAAK,UAAW,IAAM,UAAW,wBAAA,CAC/F,EAKaC,GAA+B,CAE1C,CAAE,GAAI,YAAa,MAAO,gBAAiB,IAAK,UAAW,IAAK,MAAO,aAAc,IAAM,UAAW,EAAK,SAAU,UAAW,MAAO,gBAAiB,WAAY,KAAO,iBAAkB,EAAM,aAAc,IAAM,OAAQ,+BAAgC,UAAW,2BAAA,EAC1Q,CAAE,GAAI,aAAc,MAAO,yBAA0B,IAAK,UAAW,IAAK,MAAO,aAAc,IAAM,UAAW,EAAK,SAAU,UAAW,MAAO,qBAAsB,WAAY,KAAO,iBAAkB,EAAM,aAAc,IAAM,UAAW,4BAAA,EACjP,CAAE,GAAI,uBAAwB,MAAO,iBAAkB,IAAK,UAAW,IAAK,MAAO,aAAc,IAAM,UAAW,EAAK,SAAU,UAAW,MAAO,eAAgB,WAAY,IAAO,iBAAkB,IAAM,UAAW,sCAAA,EACzN,CAAE,GAAI,qBAAsB,MAAO,eAAgB,IAAK,UAAW,IAAK,MAAO,aAAc,IAAM,UAAW,EAAK,SAAU,UAAW,MAAO,aAAc,WAAY,IAAO,iBAAkB,IAAM,UAAW,oCAAA,EACnN,CAAE,GAAI,qBAAsB,MAAO,eAAgB,IAAK,UAAW,IAAK,MAAO,aAAc,IAAM,UAAW,EAAK,SAAU,UAAW,MAAO,aAAc,WAAY,IAAO,iBAAkB,IAAM,UAAW,oCAAA,EACnN,CAAE,GAAI,sBAAuB,MAAO,gBAAiB,IAAK,UAAW,IAAK,MAAO,aAAc,IAAM,UAAW,EAAK,SAAU,UAAW,MAAO,cAAe,WAAY,IAAO,iBAAkB,IAAM,UAAW,qCAAA,EACtN,CAAE,GAAI,0BAA2B,MAAO,oBAAqB,IAAK,UAAW,IAAK,MAAO,aAAc,IAAM,UAAW,EAAK,SAAU,UAAW,MAAO,kBAAmB,WAAY,IAAO,iBAAkB,IAAM,UAAW,yCAAA,EAClO,CAAE,GAAI,sBAAuB,MAAO,gBAAiB,IAAK,UAAW,IAAK,MAAO,aAAc,EAAM,UAAW,IAAM,SAAU,UAAW,MAAO,cAAe,WAAY,EAAO,iBAAkB,EAAM,UAAW,qCAAA,EAGvN,CAAE,GAAI,OAAQ,MAAO,OAAQ,IAAK,UAAW,IAAK,KAAO,aAAc,IAAM,UAAW,IAAM,SAAU,WAAY,WAAY,EAAO,iBAAkB,GAAM,UAAW,sBAAA,EAC1K,CAAE,GAAI,WAAY,MAAO,WAAY,IAAK,UAAW,IAAK,KAAO,aAAc,IAAM,UAAW,IAAM,SAAU,WAAY,WAAY,EAAO,iBAAkB,IAAM,OAAQ,gCAAiC,UAAW,0BAAA,EAC3N,CAAE,GAAI,UAAW,MAAO,UAAW,IAAK,UAAW,IAAK,KAAO,aAAc,GAAM,UAAW,IAAM,SAAU,WAAY,WAAY,EAAO,iBAAkB,GAAM,UAAW,yBAAA,EAChL,CAAE,GAAI,aAAc,MAAO,aAAc,IAAK,UAAW,IAAK,MAAO,aAAc,IAAM,UAAW,EAAM,SAAU,WAAY,WAAY,EAAO,iBAAkB,GAAM,UAAW,4BAAA,EACtL,CAAE,GAAI,WAAY,MAAO,WAAY,IAAK,UAAW,IAAK,MAAO,aAAc,IAAM,UAAW,EAAM,SAAU,WAAY,WAAY,EAAO,iBAAkB,IAAM,OAAQ,8BAA+B,UAAW,0BAAA,EACzN,CAAE,GAAI,YAAa,MAAO,YAAa,IAAK,UAAW,IAAK,MAAO,aAAc,GAAM,UAAW,EAAM,SAAU,WAAY,WAAY,EAAO,iBAAkB,IAAM,UAAW,2BAAA,EAGpL,CAAE,GAAI,0BAA2B,MAAO,0BAA2B,IAAK,UAAW,IAAK,IAAO,aAAc,IAAM,UAAW,EAAK,SAAU,UAAW,WAAY,KAAO,iBAAkB,EAAK,aAAc,CAAC,EAAK,EAAK,CAAG,EAAG,OAAQ,0BAA2B,UAAW,yCAAA,EAC/Q,CAAE,GAAI,aAAc,MAAO,aAAc,IAAK,UAAW,IAAK,KAAO,aAAc,IAAM,UAAW,EAAK,SAAU,WAAY,WAAY,EAAO,iBAAkB,IAAK,aAAc,CAAC,IAAK,IAAM,EAAG,EAAG,OAAQ,0BAA2B,UAAW,4BAAA,EACvP,CAAE,GAAI,gBAAiB,MAAO,gBAAiB,IAAK,UAAW,IAAK,MAAO,aAAc,GAAM,UAAW,EAAK,SAAU,WAAY,WAAY,KAAO,iBAAkB,EAAK,aAAc,CAAC,KAAO,KAAO,IAAK,EAAG,OAAQ,0BAA2B,UAAW,+BAAA,EAClQ,CAAE,GAAI,0BAA2B,MAAO,0BAA2B,IAAK,UAAW,IAAK,KAAO,aAAc,IAAM,UAAW,EAAK,SAAU,WAAY,WAAY,EAAO,iBAAkB,KAAM,aAAc,CAAC,EAAK,EAAK,CAAG,EAAG,OAAQ,0BAA2B,UAAW,yCAAA,EACjR,CAAE,GAAI,qBAAsB,MAAO,qBAAsB,IAAK,UAAW,IAAK,IAAO,aAAc,IAAM,UAAW,EAAK,SAAU,UAAW,WAAY,KAAO,iBAAkB,EAAK,aAAc,CAAC,IAAK,EAAK,CAAG,EAAG,OAAQ,0BAA2B,UAAW,oCAAA,EACrQ,CAAE,GAAI,uBAAwB,MAAO,uBAAwB,IAAK,UAAW,IAAK,IAAO,aAAc,IAAM,UAAW,EAAK,SAAU,UAAW,WAAY,KAAO,iBAAkB,IAAK,aAAc,CAAC,EAAK,EAAK,CAAG,EAAG,OAAQ,0BAA2B,UAAW,sCAAA,EACzQ,CAAE,GAAI,qBAAsB,MAAO,qBAAsB,IAAK,UAAW,IAAK,IAAO,aAAc,IAAM,UAAW,EAAK,SAAU,UAAW,WAAY,KAAO,iBAAkB,EAAK,aAAc,CAAC,GAAK,EAAK,CAAG,EAAG,OAAQ,0BAA2B,UAAW,oCAAA,EAGrQ,CAAE,GAAI,UAAW,MAAO,gBAAiB,IAAK,UAAW,IAAK,MAAO,aAAc,IAAM,UAAW,IAAM,WAAY,KAAO,iBAAkB,EAAM,aAAc,IAAM,UAAW,2BAAA,EACpL,CAAE,GAAI,iBAAkB,MAAO,iBAAkB,IAAK,UAAW,IAAK,KAAO,aAAc,IAAM,UAAW,IAAM,WAAY,IAAO,iBAAkB,IAAM,UAAW,sCAAA,EACxK,CAAE,GAAI,eAAgB,MAAO,eAAgB,IAAK,UAAW,IAAK,KAAO,aAAc,IAAM,UAAW,IAAM,WAAY,IAAO,iBAAkB,IAAM,UAAW,oCAAA,EACpK,CAAE,GAAI,eAAgB,MAAO,eAAgB,IAAK,UAAW,IAAK,KAAO,aAAc,IAAM,UAAW,IAAM,WAAY,IAAO,iBAAkB,IAAM,UAAW,oCAAA,EACpK,CAAE,GAAI,gBAAiB,MAAO,gBAAiB,IAAK,UAAW,IAAK,KAAO,aAAc,EAAM,UAAW,IAAM,WAAY,EAAO,iBAAkB,EAAM,UAAW,qCAAA,CACxK,EAKaC,GAAmCF,GACnCG,GAAmCF,GAEnCG,GAAgDJ,GAAc,OACxEK,GAAMA,EAAE,WAAa,QAAa,CAACA,EAAE,GAAG,WAAW,MAAM,CAC5D,EACqDL,GAAc,OAChEK,GAAMA,EAAE,GAAG,WAAW,MAAM,CAC/B,EAEO,MAAMC,GAAiCL,GAAc,OACzDT,GAAMA,EAAE,WAAa,WAAa,CAACA,EAAE,GAAG,WAAW,MAAM,GAAKA,EAAE,GAAG,WAAW,UAAU,CAC3F,EACae,GAAkCN,GAAc,OAC1DT,GAAMA,EAAE,WAAa,YAAc,CAACA,EAAE,GAAG,WAAW,MAAM,CAC7D,EACmDS,GAAc,OAC9DT,GAAMA,EAAE,GAAG,WAAW,MAAM,CAC/B,EAGA,MAAMgB,OAA6B,IAAI,CAAC,cAAe,YAAa,aAAc,WAAY,QAAQ,CAAC,EACjGC,OAA6B,IAAI,CAAC,UAAW,iBAAkB,eAAgB,eAAgB,eAAe,CAAC,EAExGC,GAAyCV,GAAc,OACjEK,GAAM,CAACG,GAAuB,IAAIH,EAAE,EAAE,CACzC,EAEaM,GAAyCV,GAAc,OACjET,GAAM,CAACiB,GAAuB,IAAIjB,EAAE,EAAE,CACzC,EAqEO,SAASoB,GAAeC,EAA0C,CACvE,GAAI,CAACA,EAAS,OACd,MAAMC,EAAQD,EAAQ,YAAA,EAAc,KAAA,EACpC,OAAOb,GAAc,KAAMK,GAAMA,EAAE,GAAG,YAAA,IAAkBS,GAAST,EAAE,IAAI,YAAA,IAAkBS,CAAK,CAChG,CAEO,SAASC,GAAeF,EAA0C,CACvE,GAAI,CAACA,EAAS,OACd,MAAMC,EAAQD,EAAQ,YAAA,EAAc,KAAA,EACpC,OAAOZ,GAAc,KAAMT,GAAMA,EAAE,GAAG,YAAA,IAAkBsB,GAAStB,EAAE,IAAI,YAAA,IAAkBsB,CAAK,CAChG,CCnNA,MAAME,OAAc,QAEb,SAASC,GAAgBC,EAAsC,SAC/DA,EAAE,gBACLA,EAAE,sBAAA,EAEJ,MAAMC,GAAWlI,EAAAiI,EAAE,iBAAF,MAAAjI,EAAkB,OAASiI,EAAE,eAAe,OAAO,MAAA,EAAU,IAAI1I,EAAM,QAClF4I,IAAYlI,EAAAgI,EAAE,iBAAF,YAAAhI,EAAkB,SAAU,EACxCmI,EAAS,KAAK,IAAID,EAAW,GAAI,EAEjCE,EAAUJ,EAAE,aAAa,UAAU,EACzC,GAAI,CAACI,GAAWA,EAAQ,QAAU,EAChC,MAAO,CACL,SAAAH,EACA,OAAAE,EACA,cAAe,EACf,sBAAuB,EACvB,WAAY,GACZ,eAAgB,EAAA,EAIpB,MAAME,EAAQL,EAAE,SAAA,EACVM,EAAgBD,EAAQA,EAAM,MAAQ,EAAID,EAAQ,MAAQ,EAEhE,IAAIG,EAAY,EACZC,EAAc,EACdC,EAAe,EAEnB,MAAMC,EAAK,IAAIpJ,EAAM,QACfqJ,EAAK,IAAIrJ,EAAM,QACfsJ,EAAK,IAAItJ,EAAM,QACfuJ,EAAK,IAAIvJ,EAAM,QACfwJ,EAAK,IAAIxJ,EAAM,QACfyJ,EAAS,IAAIzJ,EAAM,QACnB0J,EAAY,IAAI1J,EAAM,QAE5B,QAAS2J,EAAI,EAAGA,EAAIX,EAAeW,IAAK,CACtC,MAAMC,EAAKb,EAAQA,EAAM,KAAKY,EAAI,CAAC,EAAIA,EAAI,EACrCE,EAAKd,EAAQA,EAAM,KAAKY,EAAI,EAAI,CAAC,EAAIA,EAAI,EAAI,EAC7CG,EAAKf,EAAQA,EAAM,KAAKY,EAAI,EAAI,CAAC,EAAIA,EAAI,EAAI,EAEnDP,EAAG,oBAAoBN,EAASc,CAAE,EAAE,IAAIjB,CAAQ,EAAE,aAAaE,CAAM,EACrEQ,EAAG,oBAAoBP,EAASe,CAAE,EAAE,IAAIlB,CAAQ,EAAE,aAAaE,CAAM,EACrES,EAAG,oBAAoBR,EAASgB,CAAE,EAAE,IAAInB,CAAQ,EAAE,aAAaE,CAAM,EAErEU,EAAG,WAAWF,EAAID,CAAE,EACpBI,EAAG,WAAWF,EAAIF,CAAE,EACpBK,EAAO,aAAaF,EAAIC,CAAE,EAC1B,MAAMO,EAAaN,EAAO,OAAA,EAC1B,GAAIM,EAAa,MAAO,SAExB,MAAMC,EAAOD,EAAa,GAC1Bd,GAAae,EAEbP,EAAO,aAAaM,CAAU,EAC9B,MAAME,EAAIb,EAAG,IAAIK,CAAM,EAGvBC,EAAU,aAAaL,EAAIC,CAAE,EAC7BH,GAAgBC,EAAG,IAAIM,CAAS,EAAI,EAEhCO,GAAK,OACPf,GAAec,EAEnB,CAEA,MAAME,EAAwBjB,EAAY,EAAIC,EAAcD,EAAY,EAClEkB,EAAiBhB,EAAe,EAEtC,MAAO,CACL,SAAAR,EACA,OAAAE,EACA,cAAAG,EACA,sBAAAkB,EACA,WAAYA,GAAyB,MAAS,CAAC,MAAMjB,CAAS,GAAKA,EAAY,EAC/E,eAAAkB,CAAA,CAEJ,CAEO,SAASC,GAAoB1B,EAAyB2B,EAA8B,CAEzF,MAAMvB,GADaJ,EAAE,SAAA,EAAaA,EAAE,aAAA,EAAiBA,EAAE,MAAA,GAC5B,aAAa,UAAU,EAC5C4B,EAAcxB,EAAQ,MACtByB,EAAY,IAAI,aAAaD,EAAc,CAAC,EAE5ClB,EAAK,IAAIpJ,EAAM,QACfqJ,EAAK,IAAIrJ,EAAM,QACfsJ,EAAK,IAAItJ,EAAM,QACfuJ,EAAK,IAAIvJ,EAAM,QACfwJ,EAAK,IAAIxJ,EAAM,QACfyJ,EAAS,IAAIzJ,EAAM,QAEnBwK,EAAcH,EAAE,eAAiB,GAAK,EAE5C,QAASV,EAAI,EAAGA,EAAIW,EAAaX,GAAK,EAAG,CACvCP,EAAG,oBAAoBN,EAASa,CAAC,EAAE,IAAIU,EAAE,QAAQ,EAAE,aAAaA,EAAE,MAAM,EACxEhB,EAAG,oBAAoBP,EAASa,EAAI,CAAC,EAAE,IAAIU,EAAE,QAAQ,EAAE,aAAaA,EAAE,MAAM,EAC5Ef,EAAG,oBAAoBR,EAASa,EAAI,CAAC,EAAE,IAAIU,EAAE,QAAQ,EAAE,aAAaA,EAAE,MAAM,EAE5Ed,EAAG,WAAWF,EAAID,CAAE,EACpBI,EAAG,WAAWF,EAAIF,CAAE,EACpBK,EAAO,aAAaF,EAAIC,CAAE,EAAE,eAAegB,CAAW,EAEtD,MAAMC,EAAMhB,EAAO,OAAA,EACfgB,EAAM,MACRhB,EAAO,aAAagB,CAAG,EAEvBhB,EAAO,IAAI,EAAG,EAAG,CAAC,EAGpB,MAAMQ,EAAIb,EAAG,IAAIK,CAAM,EAEvB,QAASiB,EAAI,EAAGA,EAAI,EAAGA,IAAK,CAC1B,MAAMxE,GAAOyD,EAAIe,GAAK,EACtBH,EAAUrE,CAAG,EAAIuD,EAAO,EACxBc,EAAUrE,EAAM,CAAC,EAAIuD,EAAO,EAC5Bc,EAAUrE,EAAM,CAAC,EAAIuD,EAAO,EAC5Bc,EAAUrE,EAAM,CAAC,EAAI+D,CACvB,CACF,CAEA,OAAOM,CACT,CAEO,SAASI,GAAajC,EAAyB2B,EAAwB,CAC5E,MAAMO,EAASpC,GAAQ,IAAIE,CAAC,EAC5B,GAAIkC,EAAQ,OAAOA,EAEnB,MAAM9B,EAAUJ,EAAE,aAAa,UAAU,EACnCK,EAAQL,EAAE,SAAA,EAChB,IAAImC,EAAO,WAEX,MAAMC,EAASC,GAAgB,CAC7BF,GAAQE,EAAM,IACdF,EAAO,KAAK,KAAKA,EAAM,QAAU,EACjCA,GAASE,GAAO,EAAK,IACrBF,EAAO,KAAK,KAAKA,EAAM,QAAU,EACjCA,GAASE,GAAO,GAAM,IACtBF,EAAO,KAAK,KAAKA,EAAM,QAAU,EACjCA,GAASE,GAAO,GAAM,IACtBF,EAAO,KAAK,KAAKA,EAAM,QAAU,CACnC,EAGA,GADAC,EAAMT,EAAE,aAAa,EACjBtB,EACF,QAASY,EAAI,EAAGA,EAAIZ,EAAM,MAAOY,IAC/BmB,EAAM/B,EAAM,KAAKY,CAAC,CAAC,EAIvB,MAAMqB,EAAI,IAAIhL,EAAM,QACpB,QAAS2J,EAAI,EAAGA,EAAIb,EAAQ,MAAOa,IACjCqB,EAAE,oBAAoBlC,EAASa,CAAC,EAAE,IAAIU,EAAE,QAAQ,EAAE,aAAaA,EAAE,MAAM,EACvES,EAAM,KAAK,MAAME,EAAE,EAAI,GAAK,CAAC,EAC7BF,EAAM,KAAK,MAAME,EAAE,EAAI,GAAK,CAAC,EAC7BF,EAAM,KAAK,MAAME,EAAE,EAAI,GAAK,CAAC,EAG/B,MAAMrI,GAAUkI,IAAS,GAAG,SAAS,EAAE,EACvC,OAAArC,GAAQ,IAAIE,EAAG/F,CAAM,EACdA,CACT,CC9KO,MAAMsI,GAAS,EASTC,GAAU,EAWVC,GAAM,EAoBNC,GAAY,EAOZC,GAA2B,KAC3BC,GAAiB,EAIjBC,EAAiB,EAAI,EAAI,EAAI,EAC7BC,EAAkBD,EAAiB,EACnCE,GAAmB,MAGnBC,GAAmBD,IAAoB,GAIvCE,GAAkB,KAAK,IAAK,EAAG,GAAI,EAEnCC,GAAkB,OAAQ,iBAAiB,EAE3CC,GAAkB,CAC9B,SAAUZ,GACV,SAAU,GACV,eAAgB,GAChB,qBAAsB,GACtB,eAAgB,GAChB,WAAY,KACZ,SAAU,GACV,QAAS,GACT,MAAO,KACP,CAAEW,EAAe,EAAI,EACtB,ECpFO,SAASE,EAAYC,EAAaC,EAAOC,EAAS,CAExD,OAAAA,EAAO,IAAI,EAAID,EAAOD,CAAW,EACjCE,EAAO,IAAI,EAAID,EAAOD,EAAc,CAAC,EACrCE,EAAO,IAAI,EAAID,EAAOD,EAAc,CAAC,EAErCE,EAAO,IAAI,EAAID,EAAOD,EAAc,CAAC,EACrCE,EAAO,IAAI,EAAID,EAAOD,EAAc,CAAC,EACrCE,EAAO,IAAI,EAAID,EAAOD,EAAc,CAAC,EAE9BE,CAER,CASO,SAASC,GAAqBC,EAAS,CAE7C,IAAIC,EAAc,GACdC,EAAY,KAEhB,QAAU,EAAI,EAAG,EAAI,EAAG,IAAO,CAE9B,MAAMC,EAAOH,EAAQ,EAAI,CAAC,EAAKA,EAAQ,CAAC,EACnCG,EAAOD,IAEXA,EAAYC,EACZF,EAAc,EAIhB,CAEA,OAAOA,CAER,CAGO,SAASG,GAAYtI,EAAQgI,EAAS,CAE5CA,EAAO,IAAKhI,CAAM,CAEnB,CAGO,SAASuI,GAAanC,EAAGoC,EAAGR,EAAS,CAE3C,IAAIS,EAAMC,EACV,QAAUC,EAAI,EAAGA,EAAI,EAAGA,IAAO,CAE9B,MAAMC,EAAKD,EAAI,EAGfF,EAAOrC,EAAGuC,CAAC,EACXD,EAAOF,EAAGG,CAAC,EACXX,EAAQW,CAAC,EAAKF,EAAOC,EAAOD,EAAOC,EAGnCD,EAAOrC,EAAGwC,CAAE,EACZF,EAAOF,EAAGI,CAAE,EACZZ,EAAQY,CAAE,EAAKH,EAAOC,EAAOD,EAAOC,CAErC,CAED,CAGO,SAASG,GAAyBC,EAAYC,EAAiBb,EAAS,CAE9E,QAAUS,EAAI,EAAGA,EAAI,EAAGA,IAAO,CAE9B,MAAMK,EAAUD,EAAiBD,EAAa,EAAIH,CAAC,EAC7CM,EAAQF,EAAiBD,EAAa,EAAIH,EAAI,CAAC,EAE/CO,EAAOF,EAAUC,EACjBE,EAAOH,EAAUC,EAElBC,EAAOhB,EAAQS,KAEnBT,EAAQS,CAAC,EAAKO,GAIVC,EAAOjB,EAAQS,EAAI,CAAC,IAExBT,EAAQS,EAAI,CAAC,EAAKQ,EAIpB,CAED,CAGO,SAASC,GAAoBlB,EAAS,CAE5C,MAAMmB,EAAKnB,EAAQ,CAAC,EAAKA,EAAQ,CAAC,EAC5BoB,EAAKpB,EAAQ,CAAC,EAAKA,EAAQ,CAAC,EAC5BqB,EAAKrB,EAAQ,CAAC,EAAKA,EAAQ,CAAC,EAElC,MAAO,IAAMmB,EAAKC,EAAKA,EAAKC,EAAKA,EAAKF,EAEvC,CCzGO,SAASG,EAASC,EAAKC,EAAc,CAE3C,OAAOA,EAAaD,EAAM,EAAE,IAAOjC,EAEpC,CAEO,SAASmC,EAAQC,EAAKC,EAAc,CAE1C,OAAOA,EAAaD,EAAM,CAAC,CAE5B,CAEO,SAASE,EAAOL,EAAKC,EAAc,CAEzC,OAAOA,EAAaD,EAAM,EAAE,CAE7B,CAGO,SAASM,EAAWH,EAAM,CAEhC,OAAOA,EAAMrC,CAEd,CAGO,SAASyC,EAAYJ,EAAKC,EAAc,CAG9C,MAAMI,EAAiBJ,EAAaD,EAAM,CAAC,EAC3C,OAAOA,EAAMK,EAAiB1C,CAE/B,CAEO,SAAS2C,GAAYN,EAAKC,EAAc,CAE9C,OAAOA,EAAaD,EAAM,CAAC,CAE5B,CCrCO,SAASO,GAAWpB,EAAiBqB,EAAQC,EAAOrC,EAAQsC,EAAiB,CAEnF,IAAIC,EAAO,IACPC,EAAO,IACPC,EAAO,IACPC,EAAO,KACPC,EAAO,KACPC,EAAO,KAEPC,EAAQ,IACRC,EAAQ,IACRC,EAAQ,IACRC,EAAQ,KACRC,EAAQ,KACRC,EAAQ,KAEZ,MAAMC,EAAepC,EAAgB,QAAU,EAC/C,QAAUrD,GAAM0E,EAASe,GAAiB,EAAGC,GAAQhB,EAASC,EAAQc,GAAiB,EAAGzF,EAAI0F,EAAK1F,GAAK,EAAI,CAE3G,MAAM2F,EAAKtC,EAAiBrD,EAAI,CAAC,EAC3B4F,EAAKvC,EAAiBrD,EAAI,CAAC,EAC3B6F,EAAKF,EAAKC,EACVE,EAAKH,EAAKC,EACXC,EAAKhB,IAAOA,EAAOgB,GACnBC,EAAKd,IAAOA,EAAOc,GACnBH,EAAKR,IAAQA,EAAQQ,GACrBA,EAAKL,IAAQA,EAAQK,GAE1B,MAAMI,EAAK1C,EAAiBrD,EAAI,CAAC,EAC3BgG,EAAK3C,EAAiBrD,EAAI,CAAC,EAC3BiG,EAAKF,EAAKC,EACVE,EAAKH,EAAKC,EACXC,EAAKnB,IAAOA,EAAOmB,GACnBC,EAAKjB,IAAOA,EAAOiB,GACnBH,EAAKX,IAAQA,EAAQW,GACrBA,EAAKR,IAAQA,EAAQQ,GAE1B,MAAMI,EAAK9C,EAAiBrD,EAAI,CAAC,EAC3BoG,EAAK/C,EAAiBrD,EAAI,CAAC,EAC3BqG,EAAKF,EAAKC,EACVE,EAAKH,EAAKC,EACXC,EAAKtB,IAAOA,EAAOsB,GACnBC,EAAKpB,IAAOA,EAAOoB,GACnBH,EAAKd,IAAQA,EAAQc,GACrBA,EAAKX,IAAQA,EAAQW,EAE3B,CAEA7D,EAAQ,CAAC,EAAKuC,EACdvC,EAAQ,CAAC,EAAKwC,EACdxC,EAAQ,CAAC,EAAKyC,EAEdzC,EAAQ,CAAC,EAAK0C,EACd1C,EAAQ,CAAC,EAAK2C,EACd3C,EAAQ,CAAC,EAAK4C,EAEdN,EAAgB,CAAC,EAAKO,EACtBP,EAAgB,CAAC,EAAKQ,EACtBR,EAAgB,CAAC,EAAKS,EAEtBT,EAAgB,CAAC,EAAKU,EACtBV,EAAgB,CAAC,EAAKW,EACtBX,EAAgB,CAAC,EAAKY,CAEvB,CChEA,MAAMe,GAAY,GACZC,GAAW,CAAE9F,EAAGoC,IAAOpC,EAAE,UAAYoC,EAAE,UACvC2D,GAA0B,IAAI,MAAOF,EAAS,EAAG,KAAI,EAAG,IAAK,KAE3D,CAEN,MAAO,EACP,OAAQ,IAAI,aAAc,CAAC,EAC3B,iBAAkB,IAAI,aAAc,CAAC,EACrC,gBAAiB,IAAI,aAAc,CAAC,EACpC,UAAW,CAEb,EAEC,EACKG,GAA6B,IAAI,aAAc,CAAC,EAE/C,SAASC,GAAiBC,EAAkBC,EAAsBxD,EAAiBqB,EAAQC,EAAOmC,EAAW,CAEnH,IAAIC,EAAO,GACPC,EAAM,EAGV,GAAKF,IAAaxF,GAEjByF,EAAOxE,GAAqBsE,CAAoB,EAC3CE,IAAS,KAEbC,GAAQH,EAAsBE,CAAI,EAAKF,EAAsBE,EAAO,CAAC,GAAO,WAIlED,IAAavF,GAExBwF,EAAOxE,GAAqBqE,CAAgB,EACvCG,IAAS,KAEbC,EAAMC,GAAY5D,EAAiBqB,EAAQC,EAAOoC,CAAI,WAI5CD,IAAatF,GAAM,CAE9B,MAAM0F,EAAkBxD,GAAoBkD,CAAgB,EAC5D,IAAIO,EAAWzF,GAA2BiD,EAG1C,MAAMc,EAAepC,EAAgB,QAAU,EACzC+D,GAAW1C,EAASe,GAAiB,EACrC4B,GAAS3C,EAASC,EAAQc,GAAiB,EACjD,QAAU/E,EAAI,EAAGA,EAAI,EAAGA,IAAO,CAE9B,MAAM4G,EAAWT,EAAsBnG,CAAC,EAGlC6G,GAFYV,EAAsBnG,EAAI,CAAC,EACd4G,GACDf,GAI9B,GAAK5B,EAAQ4B,GAAY,EAAI,CAG5B,MAAMiB,EAAgB,CAAE,GAAGf,EAAO,EAClCe,EAAc,OAAS7C,EAGvB,IAAI7B,EAAI,EACR,QAAU2E,EAAIL,EAAQK,EAAIJ,EAAMI,GAAK,EAAG3E,IAAO,CAE9C,MAAM4E,EAAMF,EAAe1E,CAAC,EAC5B4E,EAAI,UAAYrE,EAAiBoE,EAAI,EAAI/G,CAAC,EAC1CgH,EAAI,MAAQ,EAEZ,KAAM,CACL,OAAAlF,EACA,gBAAAmF,EACA,iBAAAC,CACN,EAASF,EACJ,QAAUzE,EAAI,EAAGA,EAAI,EAAGA,IAEvB2E,EAAkB3E,CAAC,EAAK,IACxB2E,EAAkB3E,EAAI,CAAC,EAAK,KAE5B0E,EAAiB1E,CAAC,EAAK,IACvB0E,EAAiB1E,EAAI,CAAC,EAAK,KAE3BT,EAAQS,CAAC,EAAK,IACdT,EAAQS,EAAI,CAAC,EAAK,KAInBE,GAAyBsE,EAAGpE,EAAiBb,CAAM,CAEpD,CAEAgF,EAAc,KAAMhB,EAAQ,EAG5B,IAAIqB,EAAalD,EACjB,QAAUmD,EAAK,EAAGA,EAAKD,EAAYC,IAAQ,CAE1C,MAAMJ,EAAMF,EAAeM,CAAE,EAC7B,KAAQA,EAAK,EAAID,GAAcL,EAAeM,EAAK,GAAI,YAAcJ,EAAI,WAExEF,EAAc,OAAQM,EAAK,EAAG,CAAC,EAC/BD,GAIF,CAGA,QAAUJ,EAAIL,EAAQK,EAAIJ,EAAMI,GAAK,EAAI,CAExC,MAAMnR,EAAS+M,EAAiBoE,EAAI,EAAI/G,CAAC,EACzC,QAAUoH,EAAK,EAAGA,EAAKD,EAAYC,IAAQ,CAE1C,MAAMJ,EAAMF,EAAeM,CAAE,EACxBxR,GAAUoR,EAAI,UAElBvE,GAAyBsE,EAAGpE,EAAiBqE,EAAI,gBAAgB,GAIjEvE,GAAyBsE,EAAGpE,EAAiBqE,EAAI,eAAe,EAChEA,EAAI,QAIN,CAED,CAGA,QAAUI,EAAK,EAAGA,EAAKD,EAAYC,IAAQ,CAE1C,MAAMJ,EAAMF,EAAeM,CAAE,EACvBC,EAAYL,EAAI,MAChBM,EAAarD,EAAQ+C,EAAI,MAGzBhB,EAAagB,EAAI,gBACjBO,EAAcP,EAAI,iBAExB,IAAIQ,EAAW,EACVH,IAAc,IAElBG,EAAWxE,GAAoBgD,CAAU,EAAKQ,GAI/C,IAAIiB,EAAY,EACXH,IAAe,IAEnBG,EAAYzE,GAAoBuE,CAAW,EAAKf,GAIjD,MAAMkB,EAAOzG,GAAiBD,IAC7BwG,EAAWH,EAAYI,EAAYH,GAG/BI,EAAOjB,IAEXJ,EAAOrG,EACPyG,EAAWiB,EACXpB,EAAMU,EAAI,UAIZ,CAED,KAAO,CAGN,QAAU1H,EAAI,EAAGA,EAAIuG,GAAWvG,IAAO,CAEtC,MAAM0H,EAAMjB,GAASzG,CAAC,EACtB0H,EAAI,MAAQ,EACZA,EAAI,UAAYJ,EAAWC,EAAWvH,EAAIuH,EAE1C,MAAM/E,EAASkF,EAAI,OACnB,QAAUzE,EAAI,EAAGA,EAAI,EAAGA,IAEvBT,EAAQS,CAAC,EAAK,IACdT,EAAQS,EAAI,CAAC,EAAK,IAIpB,CAGA,QAAUwE,EAAIL,EAAQK,EAAIJ,EAAMI,GAAK,EAAI,CAOxC,IAAIY,EAAW,CAAE,GALChF,EAAiBoE,EAAI,EAAI/G,CAAC,EACT4G,GAIGC,GACjCc,GAAY9B,KAAY8B,EAAW9B,GAAY,GAEpD,MAAMmB,EAAMjB,GAAS4B,CAAQ,EAC7BX,EAAI,QAEJvE,GAAyBsE,EAAGpE,EAAiBqE,EAAI,MAAM,CAExD,CAGA,MAAMY,EAAU7B,GAASF,GAAY,CAAC,EACtC3D,GAAY0F,EAAQ,OAAQA,EAAQ,gBAAgB,EACpD,QAAUtI,EAAIuG,GAAY,EAAGvG,GAAK,EAAGA,IAAO,CAE3C,MAAM0H,EAAMjB,GAASzG,CAAC,EAChBuI,EAAU9B,GAASzG,EAAI,CAAC,EAC9B6C,GAAa6E,EAAI,OAAQa,EAAQ,iBAAkBb,EAAI,gBAAgB,CAExE,CAEA,IAAIK,EAAY,EAChB,QAAU/H,EAAI,EAAGA,EAAIuG,GAAY,EAAGvG,IAAO,CAE1C,MAAM0H,EAAMjB,GAASzG,CAAC,EAChBwI,EAAWd,EAAI,MACflF,EAASkF,EAAI,OAGbO,EADUxB,GAASzG,EAAI,CAAC,EACF,iBAGvBwI,IAAa,IAEZT,IAAc,EAElBnF,GAAYJ,EAAQkE,EAAU,EAI9B7D,GAAaL,EAAQkE,GAAYA,EAAU,GAM7CqB,GAAaS,EAGb,IAAIN,EAAW,EACXC,EAAY,EAEXJ,IAAc,IAElBG,EAAWxE,GAAoBgD,EAAU,EAAKQ,GAI/C,MAAMc,EAAarD,EAAQoD,EACtBC,IAAe,IAEnBG,EAAYzE,GAAoBuE,CAAW,EAAKf,GAIjD,MAAMkB,EAAOzG,GAAiBD,IAC7BwG,EAAWH,EAAYI,EAAYH,GAG/BI,EAAOjB,IAEXJ,EAAOrG,EACPyG,EAAWiB,EACXpB,EAAMU,EAAI,UAIZ,CAED,CAED,CAED,MAEC,QAAQ,KAAM,qCAAsCZ,CAAQ,QAAS,EAItE,MAAO,CAAE,KAAAC,EAAM,IAAAC,CAAG,CAEnB,CAGA,SAASC,GAAY5D,EAAiBqB,EAAQC,EAAOoC,EAAO,CAE3D,IAAI0B,EAAM,EACV,MAAMhD,EAAepC,EAAgB,OACrC,QAAUrD,EAAI0E,EAAQgB,EAAMhB,EAASC,EAAO3E,EAAI0F,EAAK1F,IAEpDyI,GAAOpF,GAAmBrD,EAAIyF,GAAiB,EAAIsB,EAAO,CAAC,EAI5D,OAAO0B,EAAM9D,CAEd,CCpTO,MAAM+D,EAAQ,CAEpB,aAAc,CAKb,KAAK,aAAe,IAAI,aAAc,CAAC,CAExC,CAED,CCRO,SAASC,GAAW3O,EAAQ4O,EAAQvF,EAAiBqB,EAAQC,EAAOkE,EAAQ,CAElF,IAAIC,EAAOpE,EACPqE,EAAQrE,EAASC,EAAQ,EAC7B,MAAMqC,EAAM6B,EAAM,IACZG,EAAaH,EAAM,KAAO,EAC1BpD,EAAepC,EAAgB,QAAU,EAG/C,OAAe,CAEd,KAAQyF,GAAQC,GAAS1F,GAAmByF,EAAOrD,GAAiB,EAAIuD,CAAU,EAAKhC,GAEtF8B,IAKD,KAAQA,GAAQC,GAAS1F,GAAmB0F,EAAQtD,GAAiB,EAAIuD,CAAU,GAAMhC,GAExF+B,IAID,GAAKD,EAAOC,EAAQ,CAInB,QAAU/I,EAAI,EAAGA,EAAI4I,EAAQ5I,IAAO,CAEnC,IAAIiJ,EAAKjP,EAAQ8O,EAAOF,EAAS5I,CAAC,EAClChG,EAAQ8O,EAAOF,EAAS5I,CAAC,EAAKhG,EAAQ+O,EAAQH,EAAS5I,CAAC,EACxDhG,EAAQ+O,EAAQH,EAAS5I,CAAC,EAAKiJ,CAEhC,CAGA,QAAUjJ,EAAI,EAAGA,EAAI,EAAGA,IAAO,CAE9B,MAAM,EAAI8I,EAAOrD,EACXyD,EAAIH,EAAQtD,EACZ0D,EAAK9F,EAAiB,EAAI,EAAIrD,CAAC,EACrCqD,EAAiB,EAAI,EAAIrD,CAAC,EAAKqD,EAAiB6F,EAAI,EAAIlJ,CAAC,EACzDqD,EAAiB6F,EAAI,EAAIlJ,CAAC,EAAKmJ,CAEhC,CAEAL,IACAC,GAED,KAEC,QAAOD,CAIT,CAED,CC3DA,IAAIM,GAAcjF,GAAaH,GAAaqF,GAC5C,MAAMC,GAAc,KAAK,IAAK,EAAG,EAAE,EAE5B,SAASC,GAAYC,EAAO,CAElC,MAAK,UAAWA,EAER,EAIA,EAAID,GAAYC,EAAK,IAAI,EAAKD,GAAYC,EAAK,KAAK,CAI7D,CAEO,SAASC,GAAgBC,EAAYF,EAAMxP,EAAS,CAE1D,OAAAoP,GAAe,IAAI,aAAcpP,CAAM,EACvCmK,GAAc,IAAI,YAAanK,CAAM,EACrCgK,GAAc,IAAI,YAAahK,CAAM,EACrCqP,GAAa,IAAI,WAAYrP,CAAM,EAE5B2P,GAAiBD,EAAYF,CAAI,CAEzC,CAMA,SAASG,GAAiBD,EAAYF,EAAO,CAE5C,MAAMI,EAAcF,EAAa,EAC3BG,EAAcH,EAAa,EAC3BI,EAAS,UAAWN,EACpBO,EAAeP,EAAK,aAC1B,QAAUxJ,EAAI,EAAGA,EAAI,EAAGA,IAEvBoJ,GAAcQ,EAAc5J,GAAM+J,EAAc/J,CAAC,EAIlD,GAAK8J,EAEJ,OAAKN,EAAK,QAETH,GAAW,IAAK,IAAI,WAAYG,EAAK,MAAM,EAAIE,CAAU,EAClDA,EAAaF,EAAK,OAAO,aAIhCrF,GAAayF,EAAc,CAAC,EAAKJ,EAAK,OACtCxF,GAAa6F,EAAc,EAAE,EAAKL,EAAK,MACvCxF,GAAa6F,EAAc,EAAE,EAAK/H,GAC3B4H,EAAa9H,GAIf,CAEN,KAAM,CAAE,KAAAkH,EAAM,MAAAC,EAAO,UAAAiB,CAAS,EAAKR,EAG7BS,EAAiBP,EAAa9H,EACpC,IAAIsI,EAAkBP,GAAiBM,EAAgBnB,CAAI,EAG3D,MAAMqB,EAAmBT,EAAa9H,EAEhCwI,EADiBF,EAAkBtI,EACGuI,EAG5C,GAAKC,EAAqBd,GAEzB,MAAM,IAAI,MAAO,wEAAwE,EAK1F,OAAAnF,GAAayF,EAAc,CAAC,EAAKQ,EACjCjG,GAAayF,EAAc,CAAC,EAAKI,EAG1BL,GAAiBO,EAAiBnB,CAAK,CAE/C,CAED,CClFO,SAASsB,GAAWC,EAAKjH,EAAiBqB,EAAQC,EAAO1J,EAASsP,EAAY,CAGpF,KAAM,CACL,SAAAC,EACA,QAAAC,EACA,eAAAC,EACA,gBAAAC,EAAkB,IAClB,SAAA7D,EACA,WAAA9L,CACF,EAAKC,EAEE2P,EAAkBN,EAAI,gBACtBO,EAAkBP,EAAI,sBAGtBQ,EAA4B,IAAI,aAAc,CAAC,EACrD,IAAIC,EAAkB,GAEtB,MAAMC,EAAO,IAAItC,GACjB,OAAAjE,GAAWpB,EAAiBqB,EAAQC,EAAOqG,EAAK,aAAcF,CAAyB,EACvFG,EAAWD,EAAMtG,EAAQC,EAAOmG,CAAyB,EAClDE,EAEP,SAASE,EAAiBC,EAAsB,CAE1CnQ,GAEJA,GAAcmQ,EAAsBZ,EAAU,QAAWA,EAAU,KAAK,CAI1E,CAIA,SAASU,EAAWzB,EAAM9E,EAAQC,EAAOkC,EAAuB,KAAMuE,EAAQ,EAAI,CAE5E,CAAEL,GAAmBK,GAASZ,IAElCO,EAAkB,GACbN,GAEJ,QAAQ,KAAM,qBAAsBD,CAAQ,6DAA8D,GAQ5G,MAAMa,EAAY1G,EAAQgG,EAG1B,GAAOhG,GAAS+F,GAAkB,CAAEW,GAAeD,GAASZ,EAE3D,OAAAU,EAAiBxG,EAASC,CAAK,EAC/B6E,EAAK,OAAS9E,EACd8E,EAAK,MAAQ7E,EACN6E,EAKR,MAAMX,EAAQlC,GAAiB6C,EAAK,aAAc3C,EAAsBxD,EAAiBqB,EAAQC,EAAOmC,CAAQ,EAChH,IAAIwE,EAAczC,EAAM,OAAS,GAAM,GAAMF,GAAWiC,EAAiBC,EAAiBxH,EAAiBqB,EAAQC,EAAOkE,CAAK,EAK/H,GAAKA,EAAM,OAAS,IAAOyC,IAAgB5G,GAAU4G,IAAgB5G,EAASC,EAAQ,CAErF,GAAK,CAAE0G,EAEN,OAAAH,EAAiBxG,EAASC,CAAK,EAC/B6E,EAAK,OAAS9E,EACd8E,EAAK,MAAQ7E,EACN6E,EAIRX,EAAM,KAAO,KAAK,IAAK,EAAGtG,GAAqBiH,EAAK,aAAc,EAClE8B,EAAc5G,EAAS,KAAK,IAAK,EAAG,KAAK,MAAOC,EAAQ,EAAG,CAE5D,CAGA6E,EAAK,UAAYX,EAAM,KAGvB,MAAMC,EAAO,IAAIJ,GACX6C,EAAS7G,EACT8G,EAASF,EAAc5G,EAC7B8E,EAAK,KAAOV,EAEZrE,GAAWpB,EAAiBkI,EAAQC,EAAQ1C,EAAK,aAAcgC,CAAyB,EACxFG,EAAWnC,EAAMyC,EAAQC,EAAQV,EAA2BM,EAAQ,CAAC,EAGrE,MAAMrC,EAAQ,IAAIL,GACZ+C,EAASH,EACTI,EAAS/G,EAAQ6G,EACvB,OAAAhC,EAAK,MAAQT,EAEbtE,GAAWpB,EAAiBoI,EAAQC,EAAQ3C,EAAM,aAAc+B,CAAyB,EACzFG,EAAWlC,EAAO0C,EAAQC,EAAQZ,EAA2BM,EAAQ,CAAC,EAE/D5B,CAER,CAED,CAEO,SAASmC,GAAiBrB,EAAKrP,EAAU,CAE/C,MAAM2Q,EAAoB3Q,EAAQ,qBAAuB,kBAAoB,YAGvE4Q,EAAavB,EAAI,cAAerP,EAAQ,KAAK,EAC7C6Q,EAAaD,EAAY,CAAC,EAC1BE,EAAYF,EAAYA,EAAW,OAAS,CAAC,EAC7CG,EAAY,CACjB,OAAQF,EAAW,OACnB,MAAOC,EAAU,OAASA,EAAU,MAAQD,EAAW,MACzD,EAGOzI,EAAkB,IAAI,aAAc,EAAI2I,EAAU,KAAK,EAC7D3I,EAAgB,OAAS2I,EAAU,OACnC1B,EAAI,uBAAwB0B,EAAU,OAAQA,EAAU,MAAO3I,CAAe,EAG9EiH,EAAI,OAASuB,EAAW,IAAKI,GAAS,CAErC,MAAMjB,EAAOX,GAAWC,EAAKjH,EAAiB4I,EAAM,OAAQA,EAAM,MAAOhR,EAAS+Q,CAAS,EACrFE,EAAY3C,GAAYyB,CAAI,EAC5BhR,EAAS,IAAI4R,EAAmBhK,EAAiBsK,CAAS,EAChE,OAAAzC,GAAgB,EAAGuB,EAAMhR,CAAM,EACxBA,CAER,CAAC,CAEF,CCvJO,MAAMmS,EAAc,CAE1B,YAAaC,EAAkB,CAE9B,KAAK,iBAAmBA,EACxB,KAAK,YAAc,CAAA,CAEpB,CAEA,cAAe,CAEd,MAAMC,EAAa,KAAK,YACxB,OAAKA,EAAW,SAAW,EAEnB,KAAK,iBAAgB,EAIrBA,EAAW,IAAG,CAIvB,CAEA,iBAAkBC,EAAY,CAE7B,KAAK,YAAY,KAAMA,CAAS,CAEjC,CAED,CC9BA,MAAMC,EAAa,CAElB,aAAc,CAEb,KAAK,aAAe,KACpB,KAAK,YAAc,KACnB,KAAK,YAAc,KAEnB,MAAMC,EAAQ,CAAA,EACd,IAAIC,EAAa,KACjB,KAAK,UAAYzS,GAAU,CAErByS,GAEJD,EAAM,KAAMC,CAAU,EAIvBA,EAAazS,EACb,KAAK,aAAe,IAAI,aAAcA,CAAM,EAC5C,KAAK,YAAc,IAAI,YAAaA,CAAM,EAC1C,KAAK,YAAc,IAAI,YAAaA,CAAM,CAE3C,EAEA,KAAK,YAAc,IAAM,CAExByS,EAAa,KACb,KAAK,aAAe,KACpB,KAAK,YAAc,KACnB,KAAK,YAAc,KAEdD,EAAM,SAAW,GAErB,KAAK,UAAWA,EAAM,KAAK,CAI7B,CAED,CAED,CAEO,MAAME,EAA8B,IAAIH,GCrC/C,IAAII,GAAOC,GACX,MAAMC,GAAW,CAAA,EACXC,GAA0B,IAAIX,GAAe,IAAM,IAAIY,EAAAA,IAAM,EAE5D,SAASC,GAAW1C,EAAKU,EAAMiC,EAAkBC,EAAiBC,EAAqBC,EAAa,CAG1GT,GAAQG,GAAQ,aAAY,EAC5BF,GAAQE,GAAQ,aAAY,EAC5BD,GAAS,KAAMF,GAAOC,EAAK,EAC3BF,EAAY,UAAWpC,EAAI,OAAQU,CAAI,CAAE,EAEzC,MAAMhS,EAASqU,GAAmB,EAAG/C,EAAI,SAAU2C,EAAkBC,EAAiBC,EAAqBC,CAAU,EAGrHV,EAAY,YAAW,EACvBI,GAAQ,iBAAkBH,EAAK,EAC/BG,GAAQ,iBAAkBF,EAAK,EAC/BC,GAAS,IAAG,EACZA,GAAS,IAAG,EAEZ,MAAMS,EAAST,GAAS,OACxB,OAAKS,EAAS,IAEbV,GAAQC,GAAUS,EAAS,CAAC,EAC5BX,GAAQE,GAAUS,EAAS,CAAC,GAItBtU,CAER,CAEA,SAASqU,GACRjL,EACAjK,EACAoV,EACAC,EACAC,EAAgB,KAChBC,EAAkB,EAClBtC,EAAQ,EACP,CAED,KAAM,CAAE,aAAAhC,EAAc,YAAApF,EAAa,YAAAG,CAAW,EAAKuI,EACnD,IAAIiB,EAAcvL,EAAc,EAGhC,GADe0B,EAAS6J,EAAa3J,CAAW,EAClC,CAEb,MAAMU,EAAST,EAAQ7B,EAAa+B,CAAW,EACzCQ,EAAQP,EAAOuJ,EAAa3J,CAAW,EAC7C,OAAA7B,EAAiCC,EAAegH,EAAcuD,EAAK,EAC5Da,EAAqB9I,EAAQC,EAAO,GAAOyG,EAAOsC,EAAkBtL,EAAcP,EAAiB8K,EAAK,CAEhH,KAAO,CAkHN,IAASiB,EAAT,SAAwBxL,EAAc,CAErC,KAAM,CAAE,YAAA4B,EAAa,YAAAG,CAAW,EAAKuI,EACrC,IAAIiB,EAAcvL,EAAc,EAGhC,KAAQ,CAAE0B,EAAS6J,EAAa3J,IAE/B5B,EAAciC,EAAWjC,CAAW,EACpCuL,EAAcvL,EAAc,EAI7B,OAAO6B,EAAQ7B,EAAa+B,CAAW,CAExC,EAES0J,EAAT,SAA4BzL,EAAc,CAEzC,KAAM,CAAE,YAAA4B,EAAa,YAAAG,CAAW,EAAKuI,EACrC,IAAIiB,EAAcvL,EAAc,EAGhC,KAAQ,CAAE0B,EAAS6J,EAAa3J,IAG/B5B,EAAckC,EAAYlC,EAAa+B,CAAW,EAClDwJ,EAAcvL,EAAc,EAK7B,OAAO6B,EAAQ7B,EAAa+B,CAAW,EAAKC,EAAOuJ,EAAa3J,CAAW,CAE5E,EAlJA,MAAM8E,EAAOzE,EAAWjC,CAAW,EAC7B2G,EAAQzE,EAAYlC,EAAa+B,CAAW,EAClD,IAAI2J,EAAKhF,EACLiF,EAAKhF,EAELiF,EAAQC,EACRC,EAAMC,EACV,GAAKV,IAEJS,EAAOvB,GACPwB,EAAOvB,GAGPzK,EAAiC2L,EAAM1E,EAAc8E,CAAI,EACzD/L,EAAiC4L,EAAM3E,EAAc+E,CAAI,EAEzDH,EAASP,EAAeS,CAAI,EAC5BD,EAASR,EAAeU,CAAI,EAEvBF,EAASD,GAAS,CAEtBF,EAAK/E,EACLgF,EAAKjF,EAEL,MAAMsF,EAAOJ,EACbA,EAASC,EACTA,EAASG,EAETF,EAAOC,CAGR,CAKMD,IAENA,EAAOvB,GACPxK,EAAiC2L,EAAM1E,EAAc8E,CAAI,GAI1D,MAAMG,EAAWvK,EAASgK,EAAK,EAAG9J,CAAW,EACvCsK,EAAiBf,EAAsBW,EAAMG,EAAUL,EAAQ5C,EAAQ,EAAGsC,EAAkBI,EAAKjM,CAAe,EAEtH,IAAI0M,EACJ,GAAKD,IAAmB7M,GAAY,CAEnC,MAAMiD,EAASkJ,EAAeE,CAAE,EAE1BnJ,EADMkJ,EAAmBC,CAAE,EACbpJ,EAEpB6J,EAAkBf,EAAqB9I,EAAQC,EAAO,GAAMyG,EAAQ,EAAGsC,EAAkBI,EAAKjM,EAAiBqM,CAAI,CAEpH,MAECK,EACCD,GACAjB,GACCS,EACA3V,EACAoV,EACAC,EACAC,EACAC,EACAtC,EAAQ,CACb,EAIE,GAAKmD,EAAkB,MAAO,GAI9BJ,EAAOvB,GACPzK,EAAiC4L,EAAM3E,EAAc+E,CAAI,EAEzD,MAAMK,EAAW1K,EAASiK,EAAK,EAAG/J,CAAW,EACvCyK,EAAiBlB,EAAsBY,EAAMK,EAAUP,EAAQ7C,EAAQ,EAAGsC,EAAkBK,EAAKlM,CAAe,EAEtH,IAAI6M,EACJ,GAAKD,IAAmBhN,GAAY,CAEnC,MAAMiD,EAASkJ,EAAeG,CAAE,EAE1BpJ,EADMkJ,EAAmBE,CAAE,EACbrJ,EAEpBgK,EAAkBlB,EAAqB9I,EAAQC,EAAO,GAAMyG,EAAQ,EAAGsC,EAAkBK,EAAKlM,EAAiBsM,CAAI,CAEpH,MAECO,EACCD,GACApB,GACCU,EACA5V,EACAoV,EACAC,EACAC,EACAC,EACAtC,EAAQ,CACb,EAIE,MAAK,EAAAsD,CA0CN,CAED,CC9MA,MAAMC,GAAgC,IAAIjC,EAAY,YAChDkC,GAAgC,IAAIlC,EAAY,YAChDmC,GAA2B,IAAI1C,GAAe,IAAM,IAAIY,EAAAA,IAAM,EAC9D+B,GAA4B,IAAI/B,EAAAA,KAChCgC,GAA6B,IAAIhC,EAAAA,KAEjCiC,GAA4B,IAAIjC,EAAAA,KAChCkC,GAA6B,IAAIlC,EAAAA,KAEvC,IAAImC,GAAU,GAEP,SAASC,GAAS7E,EAAK8E,EAAUC,EAAeC,EAAmB,CAEzE,GAAKJ,GAEJ,MAAM,IAAI,MAAO,oDAAoD,EAItEA,GAAU,GAEV,MAAMK,EAAQjF,EAAI,OACZkF,EAAaJ,EAAS,OAC5B,IAAIpW,EACAyW,EAAc,EACdC,EAAc,EAClB,MAAMC,EAAS,IAAIC,EAAAA,QAAO,EAAG,KAAMP,CAAa,EAAG,OAAM,EAGzD,QAAUrP,EAAI,EAAG6P,EAAKN,EAAM,OAAQvP,EAAI6P,EAAI7P,IAAO,CAElD2O,GAAc,UAAWY,EAAOvP,EAAG,EACnC0P,EAAc,EAGd,MAAMI,EAAWjB,GAAS,aAAY,EACtC1M,EAAiC,EAAKwM,GAAc,aAAcmB,CAAQ,EAC1EA,EAAS,aAAcH,CAAM,EAG7B,QAAUI,EAAI,EAAGC,EAAKR,EAAW,OAAQO,EAAIC,IAE5CpB,GAAc,UAAWY,EAAYO,EAAG,EAExC/W,EAASiX,GACR,EAAG,EAAGZ,EAAeM,EAAQL,EAC7BG,EAAaC,EAAa,EAAG,EAC7BI,CACJ,EAEGlB,GAAc,YAAW,EACzBc,GAAeF,EAAYO,CAAC,EAAG,WAAanO,EAEvC,CAAA5I,GAb2C+W,IAahD,CAaD,GAJAlB,GAAS,iBAAkBiB,CAAQ,EACnCnB,GAAc,YAAW,EACzBc,GAAeF,EAAOvP,CAAC,EAAG,WAAa4B,EAElC5I,EAEJ,KAIF,CAEA,OAAAkW,GAAU,GACHlW,CAER,CAEA,SAASiX,GACRC,EACAC,EACAC,EACAC,EACAC,EAGAC,EAAmB,EACnBC,EAAmB,EAGnBC,EAAS,EACTC,EAAS,EAETC,EAAU,KACVC,EAAW,GAEV,CAGD,IAAIC,EAAcC,EACbF,GAEJC,EAAejC,GACfkC,EAAenC,KAIfkC,EAAelC,GACfmC,EAAelC,IAKhB,MACCmC,EAAgBF,EAAa,aAC7BG,EAAeH,EAAa,YAC5BI,EAAeJ,EAAa,YAC5BK,EAAgBJ,EAAa,aAC7BK,EAAeL,EAAa,YAC5BM,EAAeN,EAAa,YAEvBO,EAAenB,EAAe,EAC9BoB,EAAenB,EAAe,EAC9BoB,EAAUzN,EAASuN,EAAcJ,CAAY,EAC7CO,EAAU1N,EAASwN,EAAcF,CAAY,EACnD,IAAIpY,EAAS,GACb,GAAKwY,GAAWD,EAKVX,EAEJ5X,EAASsX,EACRrM,EAAQkM,EAAcgB,CAAY,EAAI/M,EAAO+L,EAAe,EAAGiB,CAAY,EAC3EnN,EAAQiM,EAAcc,CAAY,EAAI5M,EAAO8L,EAAe,EAAGe,CAAY,EAC3EP,EAAQF,EAAmBL,EAAetO,EAC1C4O,EAAQF,EAAmBL,EAAerO,CAC9C,EAIG7I,EAASsX,EACRrM,EAAQiM,EAAcc,CAAY,EAAI5M,EAAO8L,EAAe,EAAGe,CAAY,EAC3EhN,EAAQkM,EAAcgB,CAAY,EAAI/M,EAAO+L,EAAe,EAAGiB,CAAY,EAC3EX,EAAQF,EAAmBL,EAAerO,EAC1C6O,EAAQF,EAAmBL,EAAetO,CAC9C,UAIa2P,EAAU,CAOrB,MAAMC,EAAS5C,GAAS,aAAY,EACpC1M,EAAiCgO,EAAgBe,EAAeO,CAAM,EACtEA,EAAO,aAAcrB,CAAU,EAG/B,MAAMsB,EAAMrN,EAAW6L,CAAY,EAC7ByB,EAAMrN,EAAY4L,EAAcc,CAAY,EAClD7O,EAAiCuP,EAAOX,EAAejC,EAAS,EAChE3M,EAAiCwP,EAAOZ,EAAehC,EAAU,EAGjE,MAAM6C,EAAeH,EAAO,cAAe3C,EAAS,EAC9C+C,EAAeJ,EAAO,cAAe1C,EAAU,EACrD/V,EACC4Y,GAAgB3B,GACfE,EAAcuB,EAAKrB,EAAYD,EAAYE,EAC3CE,EAAkBD,EAAkBG,EAAQD,EAAS,EACrDgB,EAAQ,CAAEb,CACd,GAEGiB,GAAgB5B,GACfE,EAAcwB,EAAKtB,EAAYD,EAAYE,EAC3CE,EAAkBD,EAAkBG,EAAQD,EAAS,EACrDgB,EAAQ,CAAEb,CACd,EAGE/B,GAAS,iBAAkB4C,CAAM,CAElC,KAAO,CAMN,MAAMK,EAAMzN,EAAW8L,CAAY,EAC7B4B,EAAMzN,EAAY6L,EAAcgB,CAAY,EAClDhP,EAAiC2P,EAAOZ,EAAelC,EAAS,EAChE7M,EAAiC4P,EAAOb,EAAejC,EAAU,EAEjE,MAAM+C,EAAiBrB,EAAQ,cAAe3B,EAAS,EACjDiD,EAAkBtB,EAAQ,cAAe1B,EAAU,EACzD,GAAK+C,GAAkBC,EAGtBjZ,EAASiX,GACRC,EAAc4B,EAAK1B,EAAYC,EAAYC,EAC3CC,EAAkBC,EAAkBC,EAAQC,EAAS,EACrDC,EAASC,CACb,GAAQX,GACJC,EAAc6B,EAAK3B,EAAYC,EAAYC,EAC3CC,EAAkBC,EAAkBC,EAAQC,EAAS,EACrDC,EAASC,CACb,UAEcoB,EAEX,GAAKT,EAGJvY,EAASiX,GACRC,EAAc4B,EAAK1B,EAAYC,EAAYC,EAC3CC,EAAkBC,EAAkBC,EAAQC,EAAS,EACrDC,EAASC,CACd,MAEU,CAIN,MAAMa,EAAS5C,GAAS,aAAY,EACpC4C,EAAO,KAAMzC,IAAY,aAAcoB,CAAU,EAEjD,MAAMsB,EAAMrN,EAAW6L,CAAY,EAC7ByB,EAAMrN,EAAY4L,EAAcc,CAAY,EAClD7O,EAAiCuP,EAAOX,EAAejC,EAAS,EAChE3M,EAAiCwP,EAAOZ,EAAehC,EAAU,EAGjE,MAAM6C,EAAeH,EAAO,cAAe3C,EAAS,EAC9C+C,EAAeJ,EAAO,cAAe1C,EAAU,EACrD/V,EACC4Y,GAAgB3B,GACf6B,EAAKJ,EAAKrB,EAAYD,EAAYE,EAClCE,EAAkBD,EAAkBG,EAAQD,EAAS,EACrDgB,EAAQ,CAAEb,CAChB,GAEKiB,GAAgB5B,GACf6B,EAAKH,EAAKtB,EAAYD,EAAYE,EAClCE,EAAkBD,EAAkBG,EAAQD,EAAS,EACrDgB,EAAQ,CAAEb,CAChB,EAGI/B,GAAS,iBAAkB4C,CAAM,CAElC,SAEWQ,EAEX,GAAKV,EAGJvY,EAASiX,GACRC,EAAc6B,EAAK3B,EAAYC,EAAYC,EAC3CC,EAAkBC,EAAkBC,EAAQC,EAAS,EACrDC,EAASC,CACd,MAEU,CAIN,MAAMa,EAAS5C,GAAS,aAAY,EACpC4C,EAAO,KAAMxC,IAAa,aAAcmB,CAAU,EAElD,MAAMsB,EAAMrN,EAAW6L,CAAY,EAC7ByB,EAAMrN,EAAY4L,EAAcc,CAAY,EAClD7O,EAAiCuP,EAAOX,EAAejC,EAAS,EAChE3M,EAAiCwP,EAAOZ,EAAehC,EAAU,EAGjE,MAAM6C,EAAeH,EAAO,cAAe3C,EAAS,EAC9C+C,EAAeJ,EAAO,cAAe1C,EAAU,EACrD/V,EACC4Y,GAAgB3B,GACf8B,EAAKL,EAAKrB,EAAYD,EAAYE,EAClCE,EAAkBD,EAAkBG,EAAQD,EAAS,EACrDgB,EAAQ,CAAEb,CAChB,GAEKiB,GAAgB5B,GACf8B,EAAKJ,EAAKtB,EAAYD,EAAYE,EAClCE,EAAkBD,EAAkBG,EAAQD,EAAS,EACrDgB,EAAQ,CAAEb,CAChB,EAGI/B,GAAS,iBAAkB4C,CAAM,CAElC,CAIF,CAEA,OAAOzY,CAER,CCzTO,MAAMkZ,GAAqB,IAAM,KAAM,CAE7C,aAAc,CAEb,IAAIlY,EAAS,KACTmK,EAAc,KACdH,EAAc,KACdmO,EAAa,GAEjB,KAAK,KAAO,KACZ,KAAK,OAAS,KACd,KAAK,YAAc,KACnB,KAAK,YAAc,KAEnB,KAAK,OAAS,CAAE7H,EAAKU,IAAU,CAE9B,GAAKmH,EAEJ,MAAM,IAAI,MAAO,oEAAoE,EAItF,KAAK,KAAOnH,EACZ,KAAK,OAAShR,EAASsQ,EAAI,OAAQU,CAAI,EACvC,KAAK,YAAchH,EAAc,IAAI,YAAahK,CAAM,EACxD,KAAK,YAAcmK,EAAc,IAAI,YAAanK,CAAM,CAEzD,EAEA,KAAK,MAAQ,IAAM,CAElB,KAAK,KAAO,KACZ,KAAK,OAASA,EAAS,KACvB,KAAK,YAAcgK,EAAc,KACjC,KAAK,YAAcG,EAAc,IAElC,EAEA,KAAK,cAAgByF,GAAe,CAEnC,IAAIC,EAAcD,EAAc,EAChC,KAAQ,CAAE9F,EAAS+F,EAAa7F,IAE/B4F,EAAcvF,EAAWuF,CAAW,EACpCC,EAAcD,EAAc,EAI7B,OAAO3F,EAAQ2F,EAAazF,CAAW,CAExC,EAEA,KAAK,YAAcyF,GAAe,CAEjC,IAAIC,EAAcD,EAAc,EAChC,KAAQ,CAAE9F,EAAS+F,EAAa7F,IAE/B4F,EAActF,EAAYsF,EAAazF,CAAW,EAClD0F,EAAcD,EAAc,EAI7B,OAAO3F,EAAQ2F,EAAazF,CAAW,EAAKC,EAAOyF,EAAa7F,CAAW,CAE5E,EAGA,MAAMoO,EAAO,CAAEC,EAAUzI,EAAawB,IAAW,CAEhD,MAAMvB,EAAcD,EAAc,EAC5BE,EAAShG,EAAS+F,EAAa7F,CAAW,EAEhD,GAAK,CADiBqO,EAAUjH,EAAOtB,EAAQF,CAAW,GAClC,CAAEE,EAAS,CAElC,MAAMhB,EAAOzE,EAAWuF,CAAW,EAC7Bb,EAAQzE,EAAYsF,EAAazF,CAAW,EAClDiO,EAAMC,EAAUvJ,EAAMsC,EAAQ,CAAC,EAC/BgH,EAAMC,EAAUtJ,EAAOqC,EAAQ,CAAC,CAEjC,CAED,EAEA,KAAK,eAAiBiH,GAAY,CAEjC,GAAKF,EAEJ,MAAM,IAAI,MAAO,0EAA0E,EAI5FA,EAAa,GACb,GAAI,CAEHC,EAAMC,EAAU,EAAG,CAAC,CAErB,QAAC,CAEAF,EAAa,EAEd,CAED,EAEA,KAAK,SAAWE,GAAY,CAE3B,KAAK,eAAgB,CAAEjH,EAAOtB,EAAQF,IAAiB,CAEtD,GAAKE,EAAS,CAEb,MAAMD,EAAcD,EAAc,EAC5BlF,EAASP,EAAayF,EAAc,CAAC,EACrCjF,EAAQX,EAAa6F,EAAc,EAAE,EAC3C,OAAOwI,EAAUjH,EAAOtB,EAAQ,IAAI,aAAc9P,EAAQ4P,EAAc,EAAG,GAAKlF,EAAQC,CAAK,CAE9F,KAAO,CAEN,MAAMqF,EAAYxF,GAAYoF,EAAazF,CAAW,EACtD,OAAOkO,EAAUjH,EAAOtB,EAAQ,IAAI,aAAc9P,EAAQ4P,EAAc,EAAG,CAAC,EAAII,CAAS,CAE1F,CAED,CAAC,CAEF,CAED,CAED,ECxHMsI,GAA2B,IAAIvF,EAAAA,KAC/BwF,GAA8B,IAAI,aAAc,CAAC,EA+ChD,MAAMC,EAAI,CAEhB,aAAc,CAEb,KAAK,OAAS,KACd,KAAK,gBAAkB,KACvB,KAAK,sBAAwB,IAE9B,CAEA,KAAMvX,EAAU,CAEfA,EAAU,CACT,GAAGiH,GACH,GAAGjH,CACN,EAEO,gBAAiBA,IAErB,QAAQ,KAAM,+EAA+E,EAC7FA,EAAU,CACT,GAAGA,EACH,eAAgBA,EAAQ,WAC5B,GAIE0Q,GAAiB,KAAM1Q,CAAO,CAE/B,CAEA,eAA6B,CAG5B,MAAM,IAAI,MAAO,sCAAsC,CAExD,CAIA,sBAAqD,CAEpD,MAAM,IAAI,MAAO,6CAA6C,CAE/D,CAIA,0BAA2ByJ,EAAQC,EAAO8N,EAAcC,EAAY,CAGnE,IAAIC,EAAO,IACPC,EAAO,IACPC,EAAO,IACPC,EAAO,KACPC,EAAO,KACPC,EAAO,KAGX,QAAUhT,EAAI0E,EAAQgB,EAAMhB,EAASC,EAAO3E,EAAI0F,EAAK1F,IAAO,CAE3D,KAAK,qBAAsBA,EAAGuS,GAAa,CAAC,EAG5C,KAAM,CAAE1M,EAAII,EAAII,EAAIP,EAAII,EAAII,CAAE,EAAKiM,GAC9B1M,EAAK8M,IAAOA,EAAO9M,GACnBC,EAAKgN,IAAOA,EAAOhN,GACnBG,EAAK2M,IAAOA,EAAO3M,GACnBC,EAAK6M,IAAOA,EAAO7M,GACnBG,EAAKwM,IAAOA,EAAOxM,GACnBC,EAAK0M,IAAOA,EAAO1M,EAEzB,CAGA,OAAAmM,EAAcC,EAAY,CAAC,EAAKC,EAChCF,EAAcC,EAAY,CAAC,EAAKE,EAChCH,EAAcC,EAAY,CAAC,EAAKG,EAChCJ,EAAcC,EAAY,CAAC,EAAKI,EAChCL,EAAcC,EAAY,CAAC,EAAKK,EAChCN,EAAcC,EAAY,CAAC,EAAKM,EAEzBP,CAER,CAEA,uBAAwB/N,EAAQC,EAAO8N,EAAe,CAErD,MAAMhN,EAAegN,EAAa,QAAU,EAC5C,QAAUzS,EAAI0E,EAAQgB,EAAMhB,EAASC,EAAO3E,EAAI0F,EAAK1F,IAAO,CAE3D,KAAK,qBAAsBA,EAAGuS,GAAa,CAAC,EAG5C,KAAM,CAAE1M,EAAII,EAAII,EAAIP,EAAII,EAAII,CAAE,EAAKiM,GAE7B5M,GAAOE,EAAKC,GAAO,EACnBC,GAAOE,EAAKC,GAAO,EACnBC,GAAOE,EAAKC,GAAO,EAEnBV,GAAOE,EAAKD,GAAO,EACnBG,GAAOE,EAAKD,GAAO,EACnBG,GAAOE,EAAKD,GAAO,EAEnBqM,GAAc1S,EAAIyF,GAAiB,EACzCgN,EAAcC,EAAY,CAAC,EAAK/M,EAChC8M,EAAcC,EAAY,CAAC,EAAK9M,GAAO,KAAK,IAAKD,GAAOC,GAAO5D,GAC/DyQ,EAAcC,EAAY,CAAC,EAAK3M,EAChC0M,EAAcC,EAAY,CAAC,EAAK1M,GAAO,KAAK,IAAKD,GAAOC,GAAOhE,GAC/DyQ,EAAcC,EAAY,CAAC,EAAKvM,EAChCsM,EAAcC,EAAY,CAAC,EAAKtM,GAAO,KAAK,IAAKD,GAAOC,GAAOpE,EAEhE,CAEA,OAAOyQ,CAER,CAOA,sBAAuB/N,EAAS,CAE/B,MAAMuO,EAAiB,KAAK,gBAC5B,GAAKA,EAGJ,QAAU,EAAI,EAAGC,EAAID,EAAe,OAAQ,EAAIC,EAAG,IAElDD,EAAgB,CAAC,GAAMvO,MAIlB,CAGN,MAAM6K,EAAQ,KAAK,OACnB,QAAU4D,EAAY,EAAGA,EAAY5D,EAAM,OAAQ4D,IAAe,CAEjE,MAAMnI,EAAOuE,EAAO4D,CAAS,EACvBhP,EAAc,IAAI,YAAa6G,CAAI,EACnChH,EAAc,IAAI,YAAagH,CAAI,EACnCoI,EAAapI,EAAK,WAAapJ,EACrC,QAAU4H,EAAO,EAAGA,EAAO4J,EAAY5J,IAAU,CAEhD,MAAMI,EAAc/H,EAAkB2H,EAChCK,EAAc,EAAID,EACnB9F,EAAS+F,EAAa7F,KAG1BG,EAAayF,EAAc,CAAC,GAAMlF,EAIpC,CAED,CAED,CAED,CAYA,SAAU2N,EAAUc,EAAY,EAAI,CAEnCjB,GAAmB,OAAQ,KAAMiB,CAAS,EAC1CjB,GAAmB,SAAUG,CAAQ,EACrCH,GAAmB,MAAK,CAEzB,CAMA,OAAkC,CASjC,MAAM3C,EAAQ,KAAK,OACnB,QAAU4D,EAAY,EAAGE,EAAY9D,EAAM,OAAQ4D,EAAYE,EAAWF,IAAe,CAExF,MAAMnZ,EAASuV,EAAO4D,CAAS,EACzBhP,EAAc,IAAI,YAAanK,CAAM,EACrCgK,EAAc,IAAI,YAAahK,CAAM,EACrCoP,EAAe,IAAI,aAAcpP,CAAM,EACvCoZ,EAAapZ,EAAO,WAAa4H,EAGvC,QAAU0R,EAAYF,EAAa,EAAGE,GAAa,EAAGA,IAAe,CAEpE,MAAMlR,EAAckR,EAAYzR,EAC1B8L,EAAcvL,EAAc,EAGlC,GAFe0B,EAAS6J,EAAa3J,CAAW,EAElC,CAGb,MAAMU,EAAST,EAAQ7B,EAAa+B,CAAW,EACzCQ,EAAQP,EAAOuJ,EAAa3J,CAAW,EAC7C,KAAK,0BAA2BU,EAAQC,EAAO4N,GAAa,CAAC,EAG7DnJ,EAAa,IAAKmJ,GAAanQ,CAAW,CAE3C,KAAO,CAEN,MAAM0G,EAAOzE,EAAWjC,CAAW,EAC7B2G,EAAQzE,EAAYlC,EAAa+B,CAAW,EAGlD,QAAUnE,EAAI,EAAGA,EAAI,EAAGA,IAAO,CAE9B,MAAMuT,EAAUnK,EAAcN,EAAO9I,CAAC,EAChCwT,EAAUpK,EAAcN,EAAO9I,EAAI,CAAC,EACpCyT,EAAWrK,EAAcL,EAAQ/I,CAAC,EAClC0T,EAAWtK,EAAcL,EAAQ/I,EAAI,CAAC,EAE5CoJ,EAAchH,EAAcpC,CAAC,EAAKuT,EAAUE,EAAWF,EAAUE,EACjErK,EAAchH,EAAcpC,EAAI,CAAC,EAAKwT,EAAUE,EAAWF,EAAUE,CAEtE,CAED,CAED,CAED,CAED,CAOA,eAAgBpR,EAAS,CAExB,OAAAA,EAAO,UAAS,EAEF,KAAK,OACb,QAAStI,GAAU,CAExBmI,EAAY,EAAG,IAAI,aAAcnI,CAAM,EAAIsY,EAAQ,EACnDhQ,EAAO,MAAOgQ,EAAQ,CAEvB,CAAC,EAEMhQ,CAER,CAiBA,UAAWqR,EAAY,CAGtB,GAAI,CACH,oBAAAxG,EACA,iBAAAF,EACA,gBAAAC,EACA,oBAAA0G,EACA,iBAAAC,EACA,QAAAC,CACH,EAAMH,EAGJ,GAAKzG,GAAmB0G,EAAsB,CAE7C,MAAMG,EAA0B7G,EAChCA,EAAkB,CAAExI,EAAQC,EAAOqP,EAAW5I,EAAOkI,IAE7CS,EAAyBrP,EAAQC,EAAOqP,EAAW5I,EAAOkI,GAM1D,GAJCQ,EAASpP,EAAQC,EAAO,KAAMiP,EAAqBI,EAAW5I,EAAOyI,CAAgB,CAQ/F,MAAc3G,IAER0G,EAEJ1G,EAAkB,CAAExI,EAAQC,EAAOqP,EAAW5I,IAEtC0I,EAASpP,EAAQC,EAAO,KAAMiP,EAAqBI,EAAW5I,EAAOyI,CAAgB,EAM7F3G,EAAkB,CAAExI,EAAQC,EAAOqP,IAE3BA,GASV,IAAIhb,EAAS,GACToU,EAAa,EACjB,MAAMmC,EAAQ,KAAK,OACnB,QAAUvP,EAAI,EAAG,EAAIuP,EAAM,OAAQvP,EAAI,EAAGA,IAAO,CAEhD,MAAMgL,EAAOuE,EAAOvP,CAAC,EAGrB,GAFAhH,EAASib,GAAe,KAAMjU,EAAGiN,EAAkBC,EAAiBC,EAAqBC,CAAU,EAE9FpU,EAEJ,MAIDoU,GAAcpC,EAAK,WAAapJ,CAEjC,CAEA,OAAO5I,CAER,CAaA,QAASoW,EAAUC,EAAesE,EAAY,CAE7C,GAAI,CAAE,iBAAArE,CAAgB,EAAKqE,EAC3B,OAAOxE,GAAS,KAAMC,EAAUC,EAAeC,CAAgB,CAGhE,CAED,CCjbO,SAAS4E,IAA+B,CAE9C,OAAO,OAAO,kBAAsB,GAErC,CCFO,SAASC,GAAgBC,EAAM,CAErC,OAAOA,EAAI,MAAQA,EAAI,MAAM,MAAQA,EAAI,WAAW,SAAS,KAE9D,CAEO,SAASC,GAAaD,EAAM,CAElC,OAAOD,GAAgBC,CAAG,EAAK,CAEhC,CAEO,SAASE,GAAe3T,EAAaiL,EAAoB,YAAc,CAE7E,OAAKjL,EAAc,MAEX,IAAI,YAAa,IAAIiL,EAAmB,EAAIjL,CAAW,CAAE,EAIzD,IAAI,YAAa,IAAIiL,EAAmB,EAAIjL,CAAW,CAAE,CAIlE,CAGO,SAAS4T,GAAaH,EAAKnZ,EAAU,CAE3C,GAAK,CAAEmZ,EAAI,MAAQ,CAElB,MAAMzT,EAAcyT,EAAI,WAAW,SAAS,MACtCxI,EAAoB3Q,EAAQ,qBAAuB,kBAAoB,YACvEmE,EAAQkV,GAAe3T,EAAaiL,CAAiB,EAC3DwI,EAAI,SAAU,IAAII,EAAAA,gBAAiBpV,EAAO,CAAC,CAAE,EAE7C,QAAUY,EAAI,EAAGA,EAAIW,EAAaX,IAEjCZ,EAAOY,CAAC,EAAKA,CAIf,CAED,CAaA,SAASyU,GAAuBL,EAAKnI,EAAOrD,EAAS,CAEpD,MAAM8L,EAAiBP,GAAgBC,CAAG,EAAKxL,EACzC+L,EAAY1I,GAAgBmI,EAAI,UAChCQ,EAAQD,EAAU,MAAQ/L,EAC1BlD,GAAQiP,EAAU,MAAQA,EAAU,OAAU/L,EAE9ClE,EAAS,KAAK,IAAK,EAAGkQ,CAAK,EAC3BjQ,EAAQ,KAAK,IAAK+P,EAAgBhP,CAAG,EAAKhB,EAChD,MAAO,CACN,OAAQ,KAAK,MAAOA,CAAM,EAC1B,MAAO,KAAK,MAAOC,CAAK,CAC1B,CAEA,CAEA,SAASkQ,GAAyBT,EAAKxL,EAAS,CAE/C,OAAOwL,EAAI,OAAO,IAAKU,IAAW,CACjC,OAAQA,EAAM,MAAQlM,EACtB,MAAOkM,EAAM,MAAQlM,CACvB,EAAI,CAEJ,CAIO,SAASmM,GAAwBX,EAAKnI,EAAOrD,EAAS,CAE5D,MAAM+L,EAAYF,GAAuBL,EAAKnI,EAAOrD,CAAM,EACrDoM,EAAkBH,GAAyBT,EAAKxL,CAAM,EAC5D,GAAK,CAAEoM,EAAgB,OAEtB,MAAO,CAAEL,CAAS,EAInB,MAAMM,EAAS,CAAA,EACTC,EAAiBP,EAAU,OAC3BQ,EAAeR,EAAU,OAASA,EAAU,MAG5CD,EAAiBP,GAAgBC,CAAG,EAAKxL,EACzCwM,EAAS,CAAA,EACf,UAAYN,KAASE,EAAkB,CAGtC,KAAM,CAAE,OAAAtQ,EAAQ,MAAAC,CAAK,EAAKmQ,EACpBO,EAAa3Q,EACb4Q,EAAa,SAAU3Q,CAAK,EAAKA,EAAU+P,EAAiBhQ,EAC5D6Q,EAAa7Q,EAAS4Q,EAGvBD,EAAaF,GAAgBI,EAAWL,IAE5CE,EAAO,KAAM,CAAE,IAAK,KAAK,IAAKF,EAAgBG,CAAU,EAAI,QAAS,GAAM,EAC3ED,EAAO,KAAM,CAAE,IAAK,KAAK,IAAKD,EAAcI,CAAQ,EAAI,QAAS,GAAO,EAI1E,CAGAH,EAAO,KAAM,CAAE1U,EAAGoC,IAEZpC,EAAE,MAAQoC,EAAE,IAETpC,EAAE,IAAMoC,EAAE,IAIVpC,EAAE,OAAS,MAAQ,GAAM,CAIjC,EAGD,IAAI8U,EAAe,EACfC,EAAU,KACd,UAAYtc,KAASic,EAAS,CAE7B,MAAMM,EAASvc,EAAM,IAChBqc,IAAiB,GAAKE,IAAWD,GAErCR,EAAO,KAAM,CACZ,OAAQQ,EACR,MAAOC,EAASD,CACpB,CAAI,EAIFD,GAAgBrc,EAAM,QAAU,EAAI,GACpCsc,EAAUC,CAEX,CAEA,OAAOT,CAER,CCtJO,SAASU,GAAwBV,EAAQW,EAAuB,CAEtE,MAAM7J,EAAYkJ,EAAQA,EAAO,OAAS,CAAC,EACrCY,EAAY9J,EAAU,OAASA,EAAU,MAAQ,GAAK,GAGtDuB,EAAS2H,EAAO,OAAQ,CAAEa,EAAK1U,IAAS0U,EAAM1U,EAAI,MAAO,CAAC,EAC1D2U,EAAYF,EAAY,EAAI,EAC5B7b,EAAS4b,EAAuB,IAAI,kBAAmBtI,EAASyI,CAAS,EAAK,IAAI,YAAazI,EAASyI,CAAS,EACjH9C,EAAiB4C,EAAY,IAAI,YAAa7b,GAAW,IAAI,YAAaA,CAAM,EAGtF,IAAIoF,EAAQ,EACZ,QAAU8J,EAAI,EAAGA,EAAI+L,EAAO,OAAQ/L,IAAO,CAE1C,KAAM,CAAE,OAAAxE,EAAQ,MAAAC,GAAUsQ,EAAQ/L,CAAC,EACnC,QAAUlJ,EAAI,EAAGA,EAAI2E,EAAO3E,IAE3BiT,EAAgB7T,EAAQY,CAAC,EAAK0E,EAAS1E,EAIxCZ,GAASuF,CAEV,CAEA,OAAOsO,CAER,CAuBO,MAAM+C,WAAoBxD,EAAI,CAOpC,IAAI,UAAW,CAEd,MAAO,CAAE,CAAE,KAAK,eAEjB,CAEA,IAAI,iBAAkB,CAErB,OAAO,IAER,CAEA,IAAI,uBAAwB,CAE3B,OAAO,KAAK,SAAW,EAAI,KAAK,eAEjC,CACA,IAAI,sBAAuBzR,EAAI,CAAC,CAEhC,IAAI,iBAAkB,CAErB,OAAO,KAAK,SAAW,KAAK,gBAAkB,KAAK,SAAS,MAAM,KAEnE,CACA,IAAI,gBAAiBA,EAAI,CAAC,CAE1B,YAAa5I,EAAU8C,EAAU,GAAK,CAErC,GAAO9C,EAAS,kBAIT,GAAKA,EAAS,OAASA,EAAS,MAAM,6BAE5C,MAAM,IAAI,MAAO,2EAA2E,MAJ5F,OAAM,IAAI,MAAO,2CAA2C,EAQ7D,GAAK8C,EAAQ,sBAAwB,CAAEiZ,KAEtC,MAAM,IAAI,MAAO,0CAA0C,EAI5D,MAAK,EAUL,KAAK,SAAW/b,EAChB,KAAK,sBAAwB8C,EAAQ,SAAW,GAAK,KAAK,gBAAiB,GAAM,GAAK,EACtF,KAAK,gBAAkB,KACvB,KAAK,sBAAwB,KAC7B,KAAK,gBAAkB,KAEvBA,EAAU,CACT,GAAGiH,GACH,GAAGjH,CACN,EAGSA,EAASgH,KAEf,KAAK,KAAMhH,CAAO,CAIpB,CAEA,KAAMA,EAAU,CAEf,KAAM,CAAE,SAAA9C,EAAU,gBAAA8d,CAAe,EAAK,KAEtC,GAAKhb,EAAQ,SAAW,CAGvB,MAAMga,EAASF,GAAwB5c,EAAU8C,EAAQ,MAAOgb,CAAe,EACzEhD,EAAiB0C,GAAwBV,EAAQha,EAAQ,oBAAoB,EACnF,KAAK,gBAAkBgY,CAExB,MAECsB,GAAapc,EAAU8C,CAAO,EAI/B,MAAM,KAAMA,CAAO,EAEd,CAAE9C,EAAS,aAAe8C,EAAQ,iBAEtC9C,EAAS,YAAc,KAAK,eAAgB,IAAI4U,EAAAA,IAAM,EAIxD,CAGA,cAAed,EAAQ,CAGtB,OAAK,KAAK,SAEF,CAAE,CAAE,OAAQ,EAAG,MAAO,KAAK,gBAAgB,OAAQ,EAKnD8I,GAAwB,KAAK,SAAU9I,EAAO,KAAK,eAAe,CAI3E,CAEA,iBAA4D,CAE3D,MAAM,IAAI,MAAO,wCAAwC,CAE1D,CAED,CC5LO,MAAMiK,EAAqB,CAEjC,aAAc,CAEb,KAAK,IAAM,IACX,KAAK,IAAM,IAEZ,CAEA,mBAAoBC,EAAQC,EAAQ,CAEnC,IAAIC,EAAM,IACNC,EAAM,KACV,QAAUtW,EAAI,EAAGkT,EAAIiD,EAAO,OAAQnW,EAAIkT,EAAGlT,IAAO,CAGjD,MAAMoB,EADI+U,EAAQnW,CAAC,EACJoW,CAAK,EACpBC,EAAMjV,EAAMiV,EAAMjV,EAAMiV,EACxBC,EAAMlV,EAAMkV,EAAMlV,EAAMkV,CAEzB,CAEA,KAAK,IAAMD,EACX,KAAK,IAAMC,CAEZ,CAEA,cAAevP,EAAMoP,EAAS,CAE7B,IAAIE,EAAM,IACNC,EAAM,KACV,QAAUtW,EAAI,EAAGkT,EAAIiD,EAAO,OAAQnW,EAAIkT,EAAGlT,IAAO,CAEjD,MAAMqB,EAAI8U,EAAQnW,CAAC,EACboB,EAAM2F,EAAK,IAAK1F,CAAC,EACvBgV,EAAMjV,EAAMiV,EAAMjV,EAAMiV,EACxBC,EAAMlV,EAAMkV,EAAMlV,EAAMkV,CAEzB,CAEA,KAAK,IAAMD,EACX,KAAK,IAAMC,CAEZ,CAEA,YAAaC,EAAQ,CAEpB,OAAO,KAAK,IAAMA,EAAM,KAAOA,EAAM,IAAM,KAAK,GAEjD,CAED,CAEAL,GAAqB,UAAU,WAAe,UAAY,CAEzD,MAAM7U,EAAoB,IAAImV,UAC9B,OAAO,SAAqBzP,EAAM3Q,EAAM,CAEvC,MAAMqgB,EAASrgB,EAAI,IACbsgB,EAAStgB,EAAI,IACnB,IAAIigB,EAAM,IACNC,EAAM,KACV,QAAUK,EAAI,EAAGA,GAAK,EAAGA,IAExB,QAAUC,EAAI,EAAGA,GAAK,EAAGA,IAExB,QAAUC,EAAI,EAAGA,GAAK,EAAGA,IAAO,CAE/BxV,EAAE,EAAIoV,EAAO,EAAIE,EAAID,EAAO,GAAM,EAAIC,GACtCtV,EAAE,EAAIoV,EAAO,EAAIG,EAAIF,EAAO,GAAM,EAAIE,GACtCvV,EAAE,EAAIoV,EAAO,EAAII,EAAIH,EAAO,GAAM,EAAIG,GAEtC,MAAMzV,EAAM2F,EAAK,IAAK1F,CAAC,EACvBgV,EAAM,KAAK,IAAKjV,EAAKiV,CAAG,EACxBC,EAAM,KAAK,IAAKlV,EAAKkV,CAAG,CAEzB,CAMF,KAAK,IAAMD,EACX,KAAK,IAAMC,CAEZ,CAED,EAAC,ECvFM,MAAMQ,GAA2B,UAAY,CAGnD,MAAMC,EAAuB,IAAIP,UAC3BQ,EAAuB,IAAIR,UAC3BS,EAAsB,IAAIT,UAChC,OAAO,SAAiCU,EAAIC,EAAIne,EAAS,CAExD,MAAMoe,EAAKF,EAAG,MACRG,EAAMN,EACNO,EAAKH,EAAG,MACRI,EAAMP,EAEZC,EAAI,WAAYG,EAAIE,CAAE,EACtBP,EAAK,WAAYG,EAAG,IAAKA,EAAG,KAAK,EACjCF,EAAK,WAAYG,EAAG,IAAKA,EAAG,KAAK,EAGjC,MAAMK,EAAQP,EAAI,IAAKM,CAAG,EAGpBE,EAAQF,EAAI,IAAKF,CAAG,EAGpBK,EAAQH,EAAI,IAAKA,CAAG,EAGpBI,EAAQV,EAAI,IAAKI,CAAG,EAMpBO,EAHQP,EAAI,IAAKA,CAAG,EAGJK,EAAQD,EAAQA,EAEtC,IAAIxU,EAAGY,EACF+T,IAAU,EAEd3U,GAAMuU,EAAQC,EAAQE,EAAQD,GAAUE,EAIxC3U,EAAI,EAILY,GAAO2T,EAAQvU,EAAIwU,GAAUC,EAE7B1e,EAAO,EAAIiK,EACXjK,EAAO,EAAI6K,CAEZ,CAED,EAAC,EAEYgU,GAAkC,UAAY,CAG1D,MAAMC,EAA8B,IAAIC,UAClCC,EAAwB,IAAIxB,UAC5ByB,EAAwB,IAAIzB,UAClC,OAAO,SAAwCU,EAAIC,EAAIe,EAASC,EAAU,CAEzErB,GAAwBI,EAAIC,EAAIW,CAAW,EAE3C,IAAI7U,EAAI6U,EAAY,EAChBjU,EAAKiU,EAAY,EACrB,GAAK7U,GAAK,GAAKA,GAAK,GAAKY,GAAM,GAAKA,GAAM,EAAI,CAE7CqT,EAAG,GAAIjU,EAAGiV,CAAO,EACjBf,EAAG,GAAItT,EAAIsU,CAAO,EAElB,MAED,SAAYlV,GAAK,GAAKA,GAAK,EAAI,CAGzBY,EAAK,EAETsT,EAAG,GAAI,EAAGgB,CAAO,EAIjBhB,EAAG,GAAI,EAAGgB,CAAO,EAIlBjB,EAAG,oBAAqBiB,EAAS,GAAMD,CAAO,EAC9C,MAED,SAAYrU,GAAM,GAAKA,GAAM,EAAI,CAG3BZ,EAAI,EAERiU,EAAG,GAAI,EAAGgB,CAAO,EAIjBhB,EAAG,GAAI,EAAGgB,CAAO,EAIlBf,EAAG,oBAAqBe,EAAS,GAAMC,CAAO,EAC9C,MAED,KAAO,CAGN,IAAI9W,EACC4B,EAAI,EAER5B,EAAI6V,EAAG,MAIP7V,EAAI6V,EAAG,IAIR,IAAIvX,EACCkE,EAAK,EAETlE,EAAKwX,EAAG,MAIRxX,EAAKwX,EAAG,IAIT,MAAMiB,EAAeJ,EACfK,EAAgBJ,EAItB,GAHAf,EAAG,oBAAqBvX,EAAI,GAAMqY,CAAK,EACvCb,EAAG,oBAAqB9V,EAAG,GAAM4W,CAAK,EAEjCG,EAAa,kBAAmBzY,CAAE,GAAM0Y,EAAc,kBAAmBhX,GAAM,CAEnF6W,EAAQ,KAAME,CAAY,EAC1BD,EAAQ,KAAMxY,CAAE,EAChB,MAED,KAAO,CAENuY,EAAQ,KAAM7W,CAAC,EACf8W,EAAQ,KAAME,CAAa,EAC3B,MAED,CAED,CAED,CAED,EAAC,EAGYC,GAA4B,UAAY,CAGpD,MAAMC,EAAmC,IAAI/B,UACvCgC,EAAqC,IAAIhC,UACzCiC,EAA4B,IAAIC,QAChCC,EAA2B,IAAIC,QACrC,OAAO,SAAkCC,EAAQC,EAAW,CAE3D,KAAM,CAAE,OAAA5Z,EAAQ,OAAA5I,CAAM,EAAKuiB,EACrB,CAAE,EAAAnY,EAAG,EAAAoC,EAAG,EAAA2E,CAAC,EAAKqR,EAgBpB,GAbAH,EAAS,MAAQjY,EACjBiY,EAAS,IAAM7V,EACO6V,EAAS,oBAAqBriB,EAAQ,GAAMiiB,CAAgB,EAC/D,WAAYjiB,CAAM,GAAM4I,IAE3CyZ,EAAS,MAAQjY,EACjBiY,EAAS,IAAMlR,EACOkR,EAAS,oBAAqBriB,EAAQ,GAAMiiB,CAAgB,EAC/D,WAAYjiB,CAAM,GAAM4I,KAE3CyZ,EAAS,MAAQ7V,EACjB6V,EAAS,IAAMlR,EACOkR,EAAS,oBAAqBriB,EAAQ,GAAMiiB,CAAgB,EAC/D,WAAYjiB,CAAM,GAAM4I,GAAS,MAAO,GAG3D,MAAM6Z,EAAQD,EAAS,SAAUL,CAAS,EAE1C,GADW,KAAK,IAAKM,EAAM,gBAAiBziB,EAAQ,GACzC4I,EAAS,CAEnB,MAAM8Z,EAAKD,EAAM,aAAcziB,EAAQkiB,CAAkB,EAEzD,GADWM,EAAS,cAAeE,CAAE,EAC3B,MAAO,EAElB,CAEA,MAAO,EAER,CAED,EAAC,ECrMKC,GAAgB,CAAE,IAAK,IAAK,GAAG,EAC/BC,GAAe,MACfC,GAAmBD,GAAeA,GACxC,SAASE,GAAYC,EAAQ,CAE5B,OAAO,KAAK,IAAKA,CAAK,EAAKH,EAE5B,CAQO,MAAMI,WAAyBC,EAAAA,QAAS,CAE9C,eAAgBC,EAAO,CAEtB,MAAO,GAAGA,CAAI,EAEd,KAAK,mBAAqB,GAC1B,KAAK,QAAU,IAAI,MAAO,CAAC,EAAG,KAAI,EAAG,IAAK,IAAM,IAAIhD,EAAAA,OAAS,EAC7D,KAAK,UAAY,IAAI,MAAO,CAAC,EAAG,KAAI,EAAG,IAAK,IAAM,IAAIN,EAAsB,EAC5E,KAAK,OAAS,CAAE,KAAK,EAAG,KAAK,EAAG,KAAK,CAAC,EACtC,KAAK,MAAQ,IAAIwC,QACjB,KAAK,wBAA0B,GAC/B,KAAK,sBAAwB,GAC7B,KAAK,kBAAoB,IAAIE,QAQ7B,KAAK,YAAc,EAEpB,CAOA,iBAAkBC,EAAS,CAE1B,OAAOP,GAAyBO,EAAQ,IAAI,CAE7C,CAEA,QAAS,CAER,MAAMnY,EAAI,KAAK,EACToC,EAAI,KAAK,EACT2E,EAAI,KAAK,EACT0O,EAAS,KAAK,OAEdsD,EAAU,KAAK,QACfC,EAAY,KAAK,UAEjBC,EAAQF,EAAS,CAAC,EAClBG,EAAOF,EAAW,CAAC,EACzB,KAAK,UAAWC,CAAK,EACrBC,EAAK,cAAeD,EAAOxD,CAAM,EAEjC,MAAM0D,EAAQJ,EAAS,CAAC,EAClBK,EAAOJ,EAAW,CAAC,EACzBG,EAAM,WAAYnZ,EAAGoC,CAAC,EACtBgX,EAAK,cAAeD,EAAO1D,CAAM,EAEjC,MAAM4D,EAAQN,EAAS,CAAC,EAClBO,EAAON,EAAW,CAAC,EACzBK,EAAM,WAAYjX,EAAG2E,CAAC,EACtBuS,EAAK,cAAeD,EAAO5D,CAAM,EAEjC,MAAM8D,EAAQR,EAAS,CAAC,EAClBS,EAAOR,EAAW,CAAC,EACzBO,EAAM,WAAYxS,EAAG/G,CAAC,EACtBwZ,EAAK,cAAeD,EAAO9D,CAAM,EAEjC,MAAMgE,EAAWN,EAAM,OAAM,EACvBO,EAAWL,EAAM,OAAM,EACvBM,EAAWJ,EAAM,OAAM,EAE7B,KAAK,sBAAwB,GAC7B,KAAK,wBAA0B,GAE1BE,EAAWjB,GAEVkB,EAAWlB,IAAgBmB,EAAWnB,GAE1C,KAAK,sBAAwB,IAI7B,KAAK,wBAA0B,GAC/B,KAAK,kBAAkB,MAAM,KAAMxY,CAAC,EACpC,KAAK,kBAAkB,IAAI,KAAM+G,CAAC,GAIxB2S,EAAWlB,GAEjBmB,EAAWnB,GAEf,KAAK,sBAAwB,IAI7B,KAAK,wBAA0B,GAC/B,KAAK,kBAAkB,MAAM,KAAMpW,CAAC,EACpC,KAAK,kBAAkB,IAAI,KAAMpC,CAAC,GAIxB2Z,EAAWnB,KAEtB,KAAK,wBAA0B,GAC/B,KAAK,kBAAkB,MAAM,KAAMzR,CAAC,EACpC,KAAK,kBAAkB,IAAI,KAAM3E,CAAC,GAInC,KAAK,MAAM,8BAA+B6W,EAAOjZ,CAAC,EAElD,KAAK,YAAc,EAEpB,CAED,CAWA4Y,GAAiB,UAAU,sBAA0B,UAAY,CAEhE,MAAMgB,EAAyB,IAAI9D,UAC7B+D,EAAyB,IAAI/D,UAC7BgE,EAAuB,IAAI5B,QAEjC,OAAO,SAA4B6B,EAASvC,EAAU,KAAMC,EAAU,KAAO,CAE5E,KAAM,CAAE,MAAAvD,EAAO,IAAAlP,CAAG,EAAK+U,EACjBtE,EAAS,KAAK,OACpB,IAAIuE,EACAC,EAAoB,IAGxB,QAAU3a,EAAI,EAAGA,EAAI,EAAGA,IAAO,CAE9B,MAAM4a,GAAU5a,EAAI,GAAM,EAC1Bwa,EAAK,MAAM,KAAMrE,EAAQnW,CAAC,CAAE,EAC5Bwa,EAAK,IAAI,KAAMrE,EAAQyE,CAAK,CAAE,EAE9B/C,GAA+B2C,EAAMC,EAASH,EAAQC,CAAM,EAE5DG,EAASJ,EAAO,kBAAmBC,CAAM,EACpCG,EAASC,IAEbA,EAAoBD,EACfxC,GAAUA,EAAQ,KAAMoC,CAAM,EAC9BnC,GAAUA,EAAQ,KAAMoC,CAAM,EAIrC,CAGA,YAAK,oBAAqB3F,EAAO0F,CAAM,EACvCI,EAAS9F,EAAM,kBAAmB0F,CAAM,EACnCI,EAASC,IAEbA,EAAoBD,EACfxC,GAAUA,EAAQ,KAAMoC,CAAM,EAC9BnC,GAAUA,EAAQ,KAAMvD,CAAK,GAInC,KAAK,oBAAqBlP,EAAK4U,CAAM,EACrCI,EAAShV,EAAI,kBAAmB4U,CAAM,EACjCI,EAASC,IAEbA,EAAoBD,EACfxC,GAAUA,EAAQ,KAAMoC,CAAM,EAC9BnC,GAAUA,EAAQ,KAAMzS,CAAG,GAI1B,KAAK,KAAMiV,CAAiB,CAEpC,CAED,EAAC,EAWDrB,GAAiB,UAAU,mBAAuB,UAAY,CAE7D,MAAMuB,EAAyB,IAAIvB,GAC7BwB,EAAkC,IAAI5E,GACtC6E,EAAmC,IAAI7E,GACvC8E,EAAyB,IAAIxE,UAC7BO,EAAuB,IAAIP,UAC3BQ,EAAuB,IAAIR,UAC3ByE,EAA0B,IAAIzE,UAC9B0E,EAAwB,IAAItC,QAC5BuC,EAAwB,IAAIvC,QAC5BwC,EAA4B,IAAI5E,UAChC6E,EAA0B,IAAItD,UAC9BuD,EAA0B,IAAIvD,UAEpC,SAASwD,EAA4BC,EAAMjF,EAAOjU,EAAQmZ,EAAc,CAKvE,MAAMC,EAAcV,EACf,CAAEQ,EAAK,uBAAyB,CAAEA,EAAK,wBAE3CE,EAAY,KAAMF,EAAK,MAAM,MAAM,EAInCE,EAAY,KAAMnF,EAAM,MAAM,MAAM,EAIrC,MAAMoF,EAAaH,EAAK,UAClBI,EAAWJ,EAAK,QACtB,QAAUxb,EAAI,EAAGA,EAAI,EAAGA,IAAO,CAE9B,MAAM6b,EAAKF,EAAY3b,CAAC,EAClB8b,EAAKF,EAAU5b,CAAC,EAOtB,GANA8a,EAAgB,cAAegB,EAAIvF,EAAM,MAAM,EAC1CsF,EAAG,YAAaf,CAAe,IAEpCG,EAAQ,KAAMS,GAAc,MAAOI,CAAE,EACrChB,EAAgB,cAAeG,EAASO,EAAK,MAAM,EACnDT,EAAiB,cAAeE,EAAS1E,EAAM,MAAM,EAChDuE,EAAgB,YAAaC,CAAgB,GAAK,MAAO,EAE/D,CAEA,MAAMgB,EAAaxF,EAAM,UACnByF,EAAWzF,EAAM,QACvB,QAAUvW,EAAI,EAAGA,EAAI,EAAGA,IAAO,CAE9B,MAAM6b,EAAKE,EAAY/b,CAAC,EAClB8b,EAAKE,EAAUhc,CAAC,EAOtB,GANA8a,EAAgB,cAAegB,EAAIN,EAAK,MAAM,EACzCK,EAAG,YAAaf,CAAe,IAEpCG,EAAQ,aAAcS,EAAaI,CAAE,EACrChB,EAAgB,cAAeG,EAASO,EAAK,MAAM,EACnDT,EAAiB,cAAeE,EAAS1E,EAAM,MAAM,EAChDuE,EAAgB,YAAaC,CAAgB,GAAK,MAAO,EAE/D,CAEA,OAAKzY,IAGGmZ,GAEN,QAAQ,KAAM,6HAA6H,EAI5InZ,EAAO,MAAM,IAAK,EAAG,EAAG,CAAC,EACzBA,EAAO,IAAI,IAAK,EAAG,EAAG,CAAC,GAIjB,EAER,CAEA,SAAS2Z,EAAkBvb,EAAGoC,EAAG2E,EAAGyU,EAAOC,EAAOC,EAAOC,EAAOC,EAAOC,EAAO/Z,EAAQgY,EAAO,CAE5F,IAAIgC,EAAIH,GAAUA,EAAQC,GAC1B9Z,EAAO,EAAI0Z,GAAUC,EAAQD,GAAUM,EACvChC,EAAK,MAAM,WAAY1X,EAAGpC,GAAI,eAAgB8b,CAAC,EAAG,IAAK9b,CAAC,EAExD8b,EAAIH,GAAUA,EAAQE,GACtB/Z,EAAO,EAAI0Z,GAAUE,EAAQF,GAAUM,EACvChC,EAAK,IAAI,WAAY/S,EAAG/G,GAAI,eAAgB8b,CAAC,EAAG,IAAK9b,CAAC,CAEvD,CAQA,SAAS+b,EAA4BjB,EAAMU,EAAOC,EAAOC,EAAOM,EAAQC,EAAQN,EAAOC,EAAOC,EAAO/Z,EAAQgY,EAAO,CAEnH,GAAKkC,EAAS,EAGbT,EAAkBT,EAAK,EAAGA,EAAK,EAAGA,EAAK,EAAGY,EAAOF,EAAOC,EAAOI,EAAOF,EAAOC,EAAO9Z,EAAQgY,CAAI,UAErFmC,EAAS,EAEpBV,EAAkBT,EAAK,EAAGA,EAAK,EAAGA,EAAK,EAAGW,EAAOD,EAAOE,EAAOE,EAAOD,EAAOE,EAAO/Z,EAAQgY,CAAI,UAErF8B,EAAQC,EAAQ,GAAKF,GAAS,EAEzCJ,EAAkBT,EAAK,EAAGA,EAAK,EAAGA,EAAK,EAAGU,EAAOC,EAAOC,EAAOC,EAAOC,EAAOC,EAAO/Z,EAAQgY,CAAI,UAErF8B,GAAS,EAEpBL,EAAkBT,EAAK,EAAGA,EAAK,EAAGA,EAAK,EAAGW,EAAOD,EAAOE,EAAOE,EAAOD,EAAOE,EAAO/Z,EAAQgY,CAAI,UAErF+B,GAAS,EAEpBN,EAAkBT,EAAK,EAAGA,EAAK,EAAGA,EAAK,EAAGY,EAAOF,EAAOC,EAAOI,EAAOF,EAAOC,EAAO9Z,EAAQgY,CAAI,MAIhG,OAAO,GAIR,MAAO,EAER,CAEA,SAASoC,EAA0B9D,EAAU+D,EAAoBva,EAAQmZ,EAAc,CAEtF,MAAMhB,EAAUoC,EAAmB,kBAC7BC,EAAYhE,EAAS,MAAM,gBAAiB2B,EAAQ,KAAK,EACzDsC,EAAUjE,EAAS,MAAM,gBAAiB2B,EAAQ,GAAG,EAC3D,OAAKrB,GAAY0D,GAEX1D,GAAY2D,GAETxB,EAA4BzC,EAAU+D,EAAoBva,EAAQmZ,CAAW,GAK/EnZ,IAEJA,EAAO,MAAM,KAAMmY,EAAQ,KAAK,EAChCnY,EAAO,IAAI,KAAMmY,EAAQ,KAAK,GAIxB3B,EAAS,cAAe2B,EAAQ,KAAK,GAIlCrB,GAAY2D,IAElBza,IAEJA,EAAO,MAAM,KAAMmY,EAAQ,GAAG,EAC9BnY,EAAO,IAAI,KAAMmY,EAAQ,GAAG,GAItB3B,EAAS,cAAe2B,EAAQ,GAAG,GAIrC3B,EAAS,MAAM,cAAe2B,EAASO,CAAM,GAAM,MAElD1Y,IAEJA,EAAO,MAAM,KAAM0Y,CAAM,EACzB1Y,EAAO,IAAI,KAAM0Y,CAAM,GAIjBlC,EAAS,cAAekC,CAAM,GAI9B,EAMV,CAEA,SAASgC,EAAwBlE,EAAU+D,EAAoBva,EAAS,CAEvE,MAAM2a,EAAQJ,EAAmB,EAEjC,OAAKzD,GAAYN,EAAS,MAAM,gBAAiBmE,CAAK,CAAE,GAAMnE,EAAS,cAAemE,IAEhF3a,IAEJA,EAAO,MAAM,KAAM2a,CAAK,EACxB3a,EAAO,IAAI,KAAM2a,CAAK,GAIhB,IAIA,EAIT,CAEA,SAASC,EAAuBC,EAAYC,EAAU9a,EAAS,CAE9D,MAAMmY,EAAU0C,EAAW,kBACrBF,EAAQG,EAAS,EAIvB,OAFA3C,EAAQ,oBAAqBwC,EAAO,GAAMjC,CAAM,EAE3CiC,EAAM,kBAAmBjC,CAAM,EAAK7B,IAEnC7W,IAEJA,EAAO,MAAM,KAAM2a,CAAK,EACxB3a,EAAO,IAAI,KAAM2a,CAAK,GAIhB,IAIA,EAIT,CAEA,SAASI,EAAuB7B,EAAMjF,EAAOjU,EAAQmZ,EAAc,CAElE,GAAKD,EAAK,wBAET,GAAKjF,EAAM,wBAA0B,CAGpC,MAAM+G,EAAW9B,EAAK,kBAChB+B,EAAWhH,EAAM,kBACjBiH,EAASzG,EACT0G,EAASzG,EACfsG,EAAS,MAAOE,CAAM,EACtBD,EAAS,MAAOE,CAAM,EACtB,MAAMC,EAAa1C,EAAO,WAAYuC,EAAS,MAAOD,EAAS,KAAK,EAE9D1F,EAAQ4F,EAAO,EAAIC,EAAO,EAAID,EAAO,EAAIC,EAAO,EACtD,GAAKrE,GAAYxB,GAEhB,MAAO,GAIR,MAAM4E,GAAMkB,EAAW,EAAID,EAAO,EAAIC,EAAW,EAAID,EAAO,GAAM7F,EAC5D+F,EAAI,EAAIH,EAAO,EAAIE,EAAW,EAAIF,EAAO,EAAIE,EAAW,GAAM9F,EAEpE,GAAK4E,EAAI,GAAKA,EAAI,GAAKmB,EAAI,GAAKA,EAAI,EAEnC,MAAO,GAIR,MAAMC,EAAKN,EAAS,MAAM,EAAIE,EAAO,EAAIhB,EACnCqB,EAAKN,EAAS,MAAM,EAAIE,EAAO,EAAIE,EAEzC,OAAKvE,GAAYwE,EAAKC,IAEhBvb,IAEJA,EAAO,MAAM,KAAMgb,EAAS,KAAK,EAAG,gBAAiBE,EAAQhB,CAAC,EAC9Dla,EAAO,IAAI,KAAMgb,EAAS,KAAK,EAAG,gBAAiBE,EAAQhB,CAAC,GAItD,IAIA,EAIT,KAAO,QAAKjG,EAAM,sBAEV2G,EAAuB1B,EAAMjF,EAAOjU,CAAM,EAI1Csa,EAA0BrG,EAAOiF,EAAMlZ,EAAQmZ,CAAW,MAI5D,IAAKD,EAAK,sBAEhB,OAAKjF,EAAM,sBAELA,EAAM,EAAE,kBAAmBiF,EAAK,CAAC,EAAKrC,IAErC7W,IAEJA,EAAO,MAAM,KAAMkZ,EAAK,CAAC,EACzBlZ,EAAO,IAAI,KAAMkZ,EAAK,CAAC,GAIjB,IAIA,GAIGjF,EAAM,wBAEV2G,EAAuB3G,EAAOiF,EAAMlZ,CAAM,EAI1C0a,EAAwBzG,EAAOiF,EAAMlZ,CAAM,EAMnD,GAAKiU,EAAM,sBAEV,OAAOyG,EAAwBxB,EAAMjF,EAAOjU,CAAM,EAE5C,GAAKiU,EAAM,wBAEjB,OAAOqG,EAA0BpB,EAAMjF,EAAOjU,EAAQmZ,CAAW,EAMpE,CAUA,OAAO,SAA6BlF,EAAOjU,EAAS,KAAMmZ,EAAc,GAAQ,CAE1E,KAAK,aAET,KAAK,OAAM,EAILlF,EAAM,mBAMDA,EAAM,aAEjBA,EAAM,OAAM,GANZsE,EAAO,KAAMtE,CAAK,EAClBsE,EAAO,OAAM,EACbtE,EAAQsE,GAQT,MAAMiD,EAAMT,EAAuB,KAAM9G,EAAOjU,EAAQmZ,CAAW,EACnE,GAAKqC,IAAQ,OAEZ,OAAOA,EAIR,MAAMC,EAAS,KAAK,MACdC,EAASzH,EAAM,MAErB,IAAI0H,EAASD,EAAO,gBAAiB,KAAK,CAAC,EACvCE,EAASF,EAAO,gBAAiB,KAAK,CAAC,EACvCG,EAASH,EAAO,gBAAiB,KAAK,CAAC,EAEtC5E,GAAY6E,CAAM,IACtBA,EAAS,GAEL7E,GAAY8E,CAAM,IACtBA,EAAS,GAEL9E,GAAY+E,CAAM,IACtBA,EAAS,GAEV,MAAMC,EAAWH,EAASC,EACpBG,EAAWJ,EAASE,EAC1B,GAAKC,EAAW,GAAKC,EAAW,EAE/B,MAAO,GAIR,IAAIC,EAASP,EAAO,gBAAiBxH,EAAM,CAAC,EACxCgI,EAASR,EAAO,gBAAiBxH,EAAM,CAAC,EACxCiI,EAAST,EAAO,gBAAiBxH,EAAM,CAAC,EAEvC6C,GAAYkF,CAAM,IACtBA,EAAS,GAELlF,GAAYmF,CAAM,IACtBA,EAAS,GAELnF,GAAYoF,CAAM,IACtBA,EAAS,GAEV,MAAMC,GAAWH,EAASC,EACpBG,GAAWJ,EAASE,EAC1B,GAAKC,GAAW,GAAKC,GAAW,EAE/B,MAAO,GAIR3H,EAAK,KAAMgH,EAAO,MAAM,EACxB/G,EAAK,KAAMgH,EAAO,MAAM,EACxB,MAAMW,GAAmB5H,EAAK,MAAOC,CAAI,EAEzC,IAAI4H,GAAiB,EACjBC,GAAe,KAAK,IAAKF,GAAiB,CAAC,EAC/C,MAAMG,GAAQ,KAAK,IAAKH,GAAiB,CAAC,EACrCG,GAAQD,KAEZA,GAAeC,GACfF,GAAiB,GAIJ,KAAK,IAAKD,GAAiB,CAAC,EAC7BE,KAEZD,GAAiB,GAIlB,MAAMG,GAAM9F,GAAe2F,EAAc,EACnCI,GAAS,KAAK,EAAGD,EAAG,EACpBE,GAAS,KAAK,EAAGF,EAAG,EACpBG,GAAS,KAAK,EAAGH,EAAG,EAEpBI,GAAS5I,EAAM,EAAGwI,EAAG,EACrBK,GAAS7I,EAAM,EAAGwI,EAAG,EACrBM,GAAS9I,EAAM,EAAGwI,EAAG,EAE3B,GAAKtC,EAA4B,KAAMuC,GAAQC,GAAQC,GAAQd,EAAUC,EAAUJ,EAAQC,EAAQC,EAAQ9C,EAASH,CAAK,EAExH,OAAOK,EAA4B,KAAMhF,EAAOjU,EAAQmZ,CAAW,EAIpE,GAAKgB,EAA4BlG,EAAO4I,GAAQC,GAAQC,GAAQZ,GAAUC,GAAUJ,EAAQC,EAAQC,EAAQlD,EAASH,CAAK,EAEzH,OAAOI,EAA4B,KAAMhF,EAAOjU,EAAQmZ,CAAW,EAIpE,GAAKJ,EAAQ,EAAIA,EAAQ,EAAI,CAE5B,MAAMiE,GAAMjE,EAAQ,EACpBA,EAAQ,EAAIA,EAAQ,EACpBA,EAAQ,EAAIiE,GAEZlE,EAAU,KAAMF,EAAM,KAAK,EAC3BA,EAAM,MAAM,KAAMA,EAAM,GAAG,EAC3BA,EAAM,IAAI,KAAME,CAAS,CAE1B,CAEA,GAAKE,EAAQ,EAAIA,EAAQ,EAAI,CAE5B,MAAMgE,GAAMhE,EAAQ,EACpBA,EAAQ,EAAIA,EAAQ,EACpBA,EAAQ,EAAIgE,GAEZlE,EAAU,KAAMD,EAAM,KAAK,EAC3BA,EAAM,MAAM,KAAMA,EAAM,GAAG,EAC3BA,EAAM,IAAI,KAAMC,CAAS,CAE1B,CAEA,OAAKC,EAAQ,EAAIC,EAAQ,GAAKA,EAAQ,EAAID,EAAQ,EAE1C,IAIH/Y,IAECgZ,EAAQ,EAAID,EAAQ,EAExB/Y,EAAO,MAAM,KAAM6Y,EAAM,KAAK,EAI9B7Y,EAAO,MAAM,KAAM4Y,EAAM,KAAK,EAI1BI,EAAQ,EAAID,EAAQ,EAExB/Y,EAAO,IAAI,KAAM6Y,EAAM,GAAG,EAI1B7Y,EAAO,IAAI,KAAM4Y,EAAM,GAAG,GAMrB,GAER,CAED,EAAC,EASD5B,GAAiB,UAAU,gBAAoB,UAAY,CAE1D,MAAMhX,EAAyB,IAAIkU,UACnC,OAAO,SAA0ByG,EAAQ,CAExC,YAAK,oBAAqBA,EAAO3a,CAAM,EAChC2a,EAAM,WAAY3a,CAAM,CAEhC,CAED,EAAC,EAWDgX,GAAiB,UAAU,mBAAuB,UAAY,CAE7D,MAAM2D,EAAwB,IAAIzG,UAC5B+D,EAAyB,IAAI/D,UAC7B+I,EAAe,CAAE,IAAK,IAAK,GAAG,EAC9BC,EAAwB,IAAI5G,QAC5B6G,EAAwB,IAAI7G,QAElC,OAAO,SAA6BrC,EAAO2B,EAAU,KAAMC,EAAU,KAAO,CAE3E,MAAMuH,EAAaxH,GAAWC,EAAUqH,EAAQ,KAKhD,GAAK,KAAK,mBAAoBjJ,EAAOmJ,EAAY,EAAI,EAEpD,OAAKxH,GAAWC,KAEVD,GAAUwH,EAAW,UAAWxH,CAAO,EACvCC,GAAUuH,EAAW,UAAWvH,CAAO,GAItC,EAIR,IAAIwC,EAAoB,IAGxB,QAAU3a,EAAI,EAAGA,EAAI,EAAGA,IAAO,CAE9B,IAAI2C,EACJ,MAAMyT,EAAQmJ,EAAcvf,CAAC,EACvB2f,EAAWpJ,EAAOH,CAAK,EAC7B,KAAK,oBAAqBuJ,EAAU1C,CAAK,EAEzCta,EAAOgd,EAAS,kBAAmB1C,CAAK,EAEnCta,EAAOgY,IAEXA,EAAoBhY,EACfuV,GAAUA,EAAQ,KAAM+E,CAAK,EAC7B9E,GAAUA,EAAQ,KAAMwH,CAAQ,GAKtC,MAAMC,EAAU,KAAMxJ,CAAK,EAC3BG,EAAM,oBAAqBqJ,EAAS3C,CAAK,EAEzCta,EAAOid,EAAQ,kBAAmB3C,CAAK,EAElCta,EAAOgY,IAEXA,EAAoBhY,EACfuV,GAAUA,EAAQ,KAAM0H,CAAO,EAC/BzH,GAAUA,EAAQ,KAAM8E,CAAK,EAIpC,CAEA,QAAUjd,EAAI,EAAGA,EAAI,EAAGA,IAAO,CAE9B,MAAM6f,EAAMN,EAAcvf,CAAC,EACrB8f,EAAMP,GAAgBvf,EAAI,GAAM,CAAC,EACvCwf,EAAM,IAAK,KAAMK,CAAG,EAAI,KAAMC,EAAK,EACnC,QAAU3f,EAAK,EAAGA,EAAK,EAAGA,IAAQ,CAEjC,MAAM4f,EAAMR,EAAcpf,CAAE,EACtB6f,EAAMT,GAAgBpf,EAAK,GAAM,CAAC,EACxCsf,EAAM,IAAKlJ,EAAOwJ,CAAG,EAAIxJ,EAAOyJ,EAAK,EAErCnI,GAA+B2H,EAAOC,EAAOxC,EAAO1C,CAAM,EAE1D,MAAM5X,EAAOsa,EAAM,kBAAmB1C,CAAM,EACvC5X,EAAOgY,IAEXA,EAAoBhY,EACfuV,GAAUA,EAAQ,KAAM+E,CAAK,EAC7B9E,GAAUA,EAAQ,KAAMoC,CAAM,EAIrC,CAED,CAEA,OAAO,KAAK,KAAMI,CAAiB,CAEpC,CAED,EAAC,ECp1BM,MAAMsF,EAAY,CAExB,YAAa5J,EAAKC,EAAK4J,EAAS,CAE/B,KAAK,cAAgB,GAGrB,KAAK,IAAM,IAAI1J,UAGf,KAAK,IAAM,IAAIA,UAMf,KAAK,OAAS,IAAI5G,UAClB,KAAK,UAAY,IAAIA,UACrB,KAAK,OAAS,IAAI,MAAO,CAAC,EAAG,KAAI,EAAG,IAAK,IAAM,IAAI4G,EAAAA,OAAS,EAC5D,KAAK,QAAU,IAAI,MAAO,CAAC,EAAG,KAAI,EAAG,IAAK,IAAM,IAAIA,EAAAA,OAAS,EAC7D,KAAK,UAAY,IAAI,MAAO,CAAC,EAAG,KAAI,EAAG,IAAK,IAAM,IAAIN,EAAsB,EAC5E,KAAK,iBAAmB,IAAI,MAAO,CAAC,EAAG,KAAI,EAAG,IAAK,IAAM,IAAIA,EAAsB,EAOnF,KAAK,YAAc,GAEdG,GAAM,KAAK,IAAI,KAAMA,CAAG,EACxBC,GAAM,KAAK,IAAI,KAAMA,CAAG,EACxB4J,GAAS,KAAK,OAAO,KAAMA,CAAM,CAEvC,CAQA,IAAK7J,EAAKC,EAAK4J,EAAS,CAEvB,KAAK,IAAI,KAAM7J,CAAG,EAClB,KAAK,IAAI,KAAMC,CAAG,EAClB,KAAK,OAAO,KAAM4J,CAAM,EACxB,KAAK,YAAc,EAEpB,CAEA,KAAM3J,EAAQ,CAEb,KAAK,IAAI,KAAMA,EAAM,GAAG,EACxB,KAAK,IAAI,KAAMA,EAAM,GAAG,EACxB,KAAK,OAAO,KAAMA,EAAM,MAAM,EAC9B,KAAK,YAAc,EAEpB,CAED,CAEA0J,GAAY,UAAU,OAAW,UAAY,CAE5C,OAAO,UAAkB,CAExB,MAAMC,EAAS,KAAK,OACd7J,EAAM,KAAK,IACXC,EAAM,KAAK,IAEXH,EAAS,KAAK,OACpB,QAAUQ,EAAI,EAAGA,GAAK,EAAGA,IAExB,QAAUC,EAAI,EAAGA,GAAK,EAAGA,IAExB,QAAUC,EAAI,EAAGA,GAAK,EAAGA,IAAO,CAE/B,MAAM7W,EAAQ,EAAW2W,EAAU,EAAWC,EAAU,EAAWC,EAC7D9V,EAAIoV,EAAQnW,CAAC,EACnBe,EAAE,EAAI4V,EAAIL,EAAI,EAAID,EAAI,EACtBtV,EAAE,EAAI6V,EAAIN,EAAI,EAAID,EAAI,EACtBtV,EAAE,EAAI8V,EAAIP,EAAI,EAAID,EAAI,EAEtBtV,EAAE,aAAcmf,CAAM,CAEvB,CAMF,MAAMxG,EAAY,KAAK,UACjBD,EAAU,KAAK,QACf0G,EAAShK,EAAQ,CAAC,EACxB,QAAUnW,EAAI,EAAGA,EAAI,EAAGA,IAAO,CAE9B,MAAM+G,EAAO0S,EAASzZ,CAAC,EACjB6b,EAAKnC,EAAW1Z,CAAC,EACjBZ,EAAQ,GAAKY,EACbogB,EAAKjK,EAAQ/W,CAAK,EAExB2H,EAAK,WAAYoZ,EAAQC,CAAE,EAC3BvE,EAAG,cAAe9U,EAAMoP,CAAM,CAE/B,CAEA,MAAMkK,EAAmB,KAAK,iBAC9BA,EAAkB,CAAC,EAAG,mBAAoBlK,EAAQ,GAAG,EACrDkK,EAAkB,CAAC,EAAG,mBAAoBlK,EAAQ,GAAG,EACrDkK,EAAkB,CAAC,EAAG,mBAAoBlK,EAAQ,GAAG,EAErD,KAAK,UAAU,KAAM,KAAK,MAAM,EAAG,OAAM,EACzC,KAAK,YAAc,EAEpB,CAED,EAAC,EAQD8J,GAAY,UAAU,cAAkB,UAAY,CAEnD,MAAMK,EAA6B,IAAIpK,GACvC,OAAO,SAAwB9f,EAAM,CAG/B,KAAK,aAET,KAAK,OAAM,EAIZ,MAAMigB,EAAMjgB,EAAI,IACVkgB,EAAMlgB,EAAI,IACVsjB,EAAY,KAAK,UACjBD,EAAU,KAAK,QACf4G,EAAmB,KAAK,iBAY9B,GAVAC,EAAW,IAAMjK,EAAI,EACrBiK,EAAW,IAAMhK,EAAI,EAChB+J,EAAkB,CAAC,EAAG,YAAaC,CAAU,IAElDA,EAAW,IAAMjK,EAAI,EACrBiK,EAAW,IAAMhK,EAAI,EAChB+J,EAAkB,CAAC,EAAG,YAAaC,CAAU,KAElDA,EAAW,IAAMjK,EAAI,EACrBiK,EAAW,IAAMhK,EAAI,EAChB+J,EAAkB,CAAC,EAAG,YAAaC,CAAU,GAAK,MAAO,GAE9D,QAAUtgB,EAAI,EAAGA,EAAI,EAAGA,IAAO,CAE9B,MAAM+G,EAAO0S,EAASzZ,CAAC,EACjB6b,EAAKnC,EAAW1Z,CAAC,EAEvB,GADAsgB,EAAW,WAAYvZ,EAAM3Q,CAAG,EAC3BylB,EAAG,YAAayE,CAAU,EAAK,MAAO,EAE5C,CAEA,MAAO,EAER,CAED,EAAC,EAQDL,GAAY,UAAU,mBAAuB,UAAY,CAExD,MAAMM,EAAwB,IAAIjH,GAC5BkH,EAA4B,IAAI,MAAO,CAAC,EACxC1F,EAAkC,IAAI5E,GACtC6E,EAAmC,IAAI7E,GACvCuK,EAA6B,IAAIjK,UACvC,OAAO,SAA6BsC,EAAW,CAEzC,KAAK,aAET,KAAK,OAAM,EAILA,EAAS,mBAMJA,EAAS,aAEpBA,EAAS,OAAM,GANfyH,EAAM,KAAMzH,CAAQ,EACpByH,EAAM,OAAM,EACZzH,EAAWyH,GAQZ,MAAM7G,EAAY,KAAK,UACjBD,EAAU,KAAK,QAErB+G,EAAW,GAAM1H,EAAS,EAC1B0H,EAAW,GAAM1H,EAAS,EAC1B0H,EAAW,GAAM1H,EAAS,EAE1B,QAAU9Y,EAAI,EAAGA,EAAI,EAAGA,IAAO,CAE9B,MAAM6b,EAAKnC,EAAW1Z,CAAC,EACjB8b,EAAKrC,EAASzZ,CAAC,EAErB,GADA8a,EAAgB,cAAegB,EAAI0E,CAAS,EACvC3E,EAAG,YAAaf,CAAe,EAAK,MAAO,EAEjD,CAEA,MAAM4F,EAAe5H,EAAS,UACxB6H,EAAa7H,EAAS,QACtB3C,EAAS,KAAK,OACpB,QAAUnW,EAAI,EAAGA,EAAI,EAAGA,IAAO,CAE9B,MAAM6b,EAAK6E,EAAc1gB,CAAC,EACpB8b,EAAK6E,EAAY3gB,CAAC,EAExB,GADA8a,EAAgB,cAAegB,EAAI3F,CAAM,EACpC0F,EAAG,YAAaf,CAAe,EAAK,MAAO,EAEjD,CAGA,QAAU9a,EAAI,EAAGA,EAAI,EAAGA,IAAO,CAE9B,MAAM4gB,EAAMnH,EAASzZ,CAAC,EACtB,QAAUG,EAAK,EAAGA,EAAK,EAAGA,IAAQ,CAEjC,MAAM0gB,EAAMF,EAAYxgB,CAAE,EAI1B,GAHAsgB,EAAW,aAAcG,EAAKC,CAAG,EACjC/F,EAAgB,cAAe2F,EAAYD,CAAS,EACpDzF,EAAiB,cAAe0F,EAAYtK,CAAM,EAC7C2E,EAAgB,YAAaC,CAAgB,EAAK,MAAO,EAE/D,CAED,CAEA,MAAO,EAER,CAED,EAAC,EAUDkF,GAAY,UAAU,oBAAwB,UAAY,CAEzD,OAAO,SAA8BhD,EAAO/E,EAAU,CAErD,OAAK,KAAK,aAET,KAAK,OAAM,EAIZA,EACE,KAAM+E,CAAK,EACX,aAAc,KAAK,SAAS,EAC5B,MAAO,KAAK,IAAK,KAAK,GAAG,EACzB,aAAc,KAAK,MAAM,EAEpB/E,CAER,CAED,EAAC,EAQD+H,GAAY,UAAU,gBAAoB,UAAY,CAErD,MAAM3d,EAAS,IAAIkU,UACnB,OAAO,SAA0ByG,EAAQ,CAExC,YAAK,oBAAqBA,EAAO3a,CAAM,EAChC2a,EAAM,WAAY3a,CAAM,CAEhC,CAED,EAAC,EAaD2d,GAAY,UAAU,cAAkB,UAAY,CAEnD,MAAMa,EAAY,CAAE,IAAK,IAAK,GAAG,EAC3BC,EAA4B,IAAI,MAAO,EAAE,EAAG,KAAI,EAAG,IAAK,IAAM,IAAInI,EAAAA,KAAO,EACzEoI,EAA4B,IAAI,MAAO,EAAE,EAAG,KAAI,EAAG,IAAK,IAAM,IAAIpI,EAAAA,KAAO,EAEzE0B,EAAyB,IAAI9D,UAC7B+D,EAAyB,IAAI/D,UAGnC,OAAO,SAAwBpgB,EAAK6qB,EAAY,EAAG/I,EAAU,KAAMC,EAAU,KAAO,CAQnF,GANK,KAAK,aAET,KAAK,OAAM,EAIP,KAAK,cAAe/hB,GAExB,OAAK8hB,GAAWC,KAEf/hB,EAAI,UAAWmkB,CAAM,EACrB,KAAK,oBAAqBA,EAAQD,CAAM,EACxClkB,EAAI,oBAAqBkkB,EAAQC,CAAM,EAElCrC,GAAUA,EAAQ,KAAMoC,CAAM,EAC9BnC,GAAUA,EAAQ,KAAMoC,CAAM,GAI7B,EAIR,MAAM2G,EAAaD,EAAYA,EACzB5K,EAAMjgB,EAAI,IACVkgB,EAAMlgB,EAAI,IACV+f,EAAS,KAAK,OAIpB,IAAIwE,EAAoB,IAGxB,QAAU3a,EAAI,EAAGA,EAAI,EAAGA,IAAO,CAE9B,MAAMqB,EAAI8U,EAAQnW,CAAC,EACnBua,EAAO,KAAMlZ,CAAC,EAAG,MAAOgV,EAAKC,CAAG,EAEhC,MAAM3T,EAAOtB,EAAE,kBAAmBkZ,CAAM,EACxC,GAAK5X,EAAOgY,IAEXA,EAAoBhY,EACfuV,GAAUA,EAAQ,KAAM7W,CAAC,EACzB8W,GAAUA,EAAQ,KAAMoC,CAAM,EAE9B5X,EAAOue,GAAa,OAAO,KAAK,KAAMve,CAAI,CAIjD,CAGA,IAAIgC,EAAQ,EACZ,QAAU3E,EAAI,EAAGA,EAAI,EAAGA,IAEvB,QAAUE,EAAK,EAAGA,GAAM,EAAGA,IAE1B,QAAUC,EAAK,EAAGA,GAAM,EAAGA,IAAQ,CAElC,MAAMghB,GAAcnhB,EAAI,GAAM,EACxBohB,GAAephB,EAAI,GAAM,EAGzBZ,EAAQc,GAAMihB,EAAYhhB,GAAMihB,EAChCC,EAAS,GAAKrhB,EAAIE,GAAMihB,EAAYhhB,GAAMihB,EAC1C1hB,EAAKyW,EAAQ/W,CAAK,EAClBO,EAAKwW,EAAQkL,CAAM,EACXN,EAAWpc,CAAK,EACxB,IAAKjF,EAAIC,CAAE,EAIjB,MAAM2hB,EAAKR,EAAW9gB,CAAC,EACjBuhB,EAAKT,EAAWK,CAAS,EACzBK,EAAKV,EAAWM,CAAU,EAC1B3B,EAAQuB,EAAWrc,CAAK,EACxBiQ,EAAQ6K,EAAM,MACd/Z,EAAM+Z,EAAM,IAElB7K,EAAO0M,CAAE,EAAKjL,EAAKiL,CAAE,EACrB1M,EAAO2M,CAAE,EAAKrhB,EAAKmW,EAAKkL,CAAE,EAAKjL,EAAKiL,CAAE,EACtC3M,EAAO4M,CAAE,EAAKrhB,EAAKkW,EAAKmL,CAAE,EAAKlL,EAAKiL,CAAE,EAEtC7b,EAAK4b,CAAE,EAAKhL,EAAKgL,CAAE,EACnB5b,EAAK6b,CAAE,EAAKrhB,EAAKmW,EAAKkL,CAAE,EAAKjL,EAAKiL,CAAE,EACpC7b,EAAK8b,CAAE,EAAKrhB,EAAKkW,EAAKmL,CAAE,EAAKlL,EAAKiL,CAAE,EAEpC5c,GAED,CAOF,QAAUgS,EAAI,EAAGA,GAAK,EAAGA,IAExB,QAAUC,EAAI,EAAGA,GAAK,EAAGA,IAExB,QAAUC,EAAI,EAAGA,GAAK,EAAGA,IAAO,CAE/B0D,EAAO,EAAI5D,EAAIL,EAAI,EAAID,EAAI,EAC3BkE,EAAO,EAAI3D,EAAIN,EAAI,EAAID,EAAI,EAC3BkE,EAAO,EAAI1D,EAAIP,EAAI,EAAID,EAAI,EAE3B,KAAK,oBAAqBkE,EAAQD,CAAM,EACxC,MAAM3X,EAAO4X,EAAO,kBAAmBD,CAAM,EAC7C,GAAK3X,EAAOgY,IAEXA,EAAoBhY,EACfuV,GAAUA,EAAQ,KAAMoC,CAAM,EAC9BnC,GAAUA,EAAQ,KAAMoC,CAAM,EAE9B5X,EAAOue,GAAa,OAAO,KAAK,KAAMve,CAAI,CAIjD,CAMF,QAAU3C,EAAI,EAAGA,EAAI,GAAIA,IAAO,CAE/B,MAAMkX,EAAK6J,EAAW/gB,CAAC,EACvB,QAAUG,EAAK,EAAGA,EAAK,GAAIA,IAAQ,CAElC,MAAMgX,EAAK6J,EAAW7gB,CAAE,EACxB0X,GAA+BX,EAAIC,EAAImD,EAAQC,CAAM,EACrD,MAAM5X,EAAO2X,EAAO,kBAAmBC,CAAM,EAC7C,GAAK5X,EAAOgY,IAEXA,EAAoBhY,EACfuV,GAAUA,EAAQ,KAAMoC,CAAM,EAC9BnC,GAAUA,EAAQ,KAAMoC,CAAM,EAE9B5X,EAAOue,GAAa,OAAO,KAAK,KAAMve,CAAI,CAIjD,CAED,CAEA,OAAO,KAAK,KAAMgY,CAAiB,CAEpC,CAED,EAAC,ECreD,MAAM8G,WAAiCtV,EAAc,CAEpD,aAAc,CAEb,MAAO,IAAM,IAAImN,EAAkB,CAEpC,CAED,CAEO,MAAMoI,GAAuC,IAAID,GCXlDrT,GAAuB,IAAIoI,EAAAA,QAC3BwB,GAAwB,IAAIxB,EAAAA,QAE3B,SAASmL,GACfrX,EACA2S,EACA3a,EAAS,CAAA,EACTsf,EAAe,EACfC,EAAe,IACd,CAMD,MAAMC,EAAiBF,EAAeA,EAChCG,EAAiBF,EAAeA,EACtC,IAAIlH,EAAoB,IACpBqH,EAA0B,KA8C9B,GA7CA1X,EAAI,UAEH,CAEC,oBAAqBlU,IAEpBgY,GAAK,KAAM6O,GAAQ,MAAO7mB,EAAI,IAAKA,EAAI,GAAG,EACnCgY,GAAK,kBAAmB6O,CAAK,GAIrC,iBAAkB,CAAE7mB,EAAK0T,EAAQmY,IAEzBA,EAAQtH,GAAqBsH,EAAQF,EAI7C,mBAAoB,CAAEG,EAAKC,IAAc,CAExCD,EAAI,oBAAqBjF,EAAO7O,EAAI,EACpC,MAAMsM,EAASuC,EAAM,kBAAmB7O,EAAI,EAS5C,OARKsM,EAASC,IAEb3C,GAAM,KAAM5J,EAAI,EAChBuM,EAAoBD,EACpBsH,EAA0BG,GAItBzH,EAASoH,CAUf,CAEH,CAEA,EAEMnH,IAAsB,IAAW,OAAO,KAE7C,MAAMyH,EAAkB,KAAK,KAAMzH,CAAiB,EAEpD,OAAOrY,EAAO,MACTA,EAAO,MAAM,KAAM0V,EAAK,EADP1V,EAAO,MAAQ0V,GAAM,MAAK,EAEhD1V,EAAO,SAAW8f,EAClB9f,EAAO,UAAY0f,EAEZ1f,CAER,CC3EA,MAAM+f,GAAqB,SAAUC,EAAAA,QAAQ,GAAM,IAC7CC,GAAqB,SAAUD,EAAAA,QAAQ,GAAM,IAI7CE,GAAsB,IAAIhM,EAAAA,QAC1BiM,GAAsB,IAAIjM,EAAAA,QAC1BkM,GAAsB,IAAIlM,EAAAA,QAE1BmM,GAAuB,IAAI5K,EAAAA,QAC3B6K,GAAuB,IAAI7K,EAAAA,QAC3B8K,GAAuB,IAAI9K,EAAAA,QAE3B+K,GAA2B,IAAItM,EAAAA,QAC/BuM,GAA2B,IAAIvM,EAAAA,QAC/BwM,GAA2B,IAAIxM,EAAAA,QAE/ByM,GAAqC,IAAIzM,EAAAA,QAC/C,SAAS0M,GAAmBC,EAAKC,EAAIC,EAAIC,EAAIrG,EAAOsG,EAAMC,EAAMC,EAAM,CAErE,IAAIC,EAWJ,GAVKH,IAASI,EAAAA,SAEbD,EAAYP,EAAI,kBAAmBG,EAAID,EAAID,EAAI,GAAMnG,CAAK,EAI1DyG,EAAYP,EAAI,kBAAmBC,EAAIC,EAAIC,EAAIC,IAASK,EAAAA,WAAY3G,CAAK,EAIrEyG,IAAc,KAAO,OAAO,KAEjC,MAAMG,EAAWV,EAAI,OAAO,WAAYlG,CAAK,EAE7C,OAAK4G,EAAWL,GAAQK,EAAWJ,EAAa,KAEzC,CAEN,SAAUI,EACV,MAAO5G,EAAM,MAAK,CAEpB,CAEA,CAEA,SAAS6G,GAAiCX,EAAKY,EAAUjkB,EAAQkkB,EAAIC,EAAKvjB,EAAGoC,EAAG2E,EAAG8b,EAAMC,EAAMC,EAAM,CAEpGjB,GAAI,oBAAqBuB,EAAUrjB,CAAC,EACpC+hB,GAAI,oBAAqBsB,EAAUjhB,CAAC,EACpC4f,GAAI,oBAAqBqB,EAAUtc,CAAC,EAEpC,MAAMyc,EAAehB,GAAmBC,EAAKX,GAAKC,GAAKC,GAAKO,GAAoBM,EAAMC,EAAMC,CAAG,EAE/F,GAAKS,EAAe,CAEnB,GAAKF,EAAK,CAETrB,GAAK,oBAAqBqB,EAAItjB,CAAC,EAC/BkiB,GAAK,oBAAqBoB,EAAIlhB,CAAC,EAC/B+f,GAAK,oBAAqBmB,EAAIvc,CAAC,EAE/Byc,EAAa,GAAK,IAAInM,UACtB,MAAM+F,EAAMvE,EAAAA,SAAS,iBAAkB0J,GAAoBT,GAAKC,GAAKC,GAAKC,GAAMC,GAAMC,GAAMqB,EAAa,EAAE,EACpG7B,KAEN6B,EAAa,GAAKpG,EAIpB,CAEA,GAAKmG,EAAM,CAEVtB,GAAK,oBAAqBsB,EAAKvjB,CAAC,EAChCkiB,GAAK,oBAAqBqB,EAAKnhB,CAAC,EAChC+f,GAAK,oBAAqBoB,EAAKxc,CAAC,EAEhCyc,EAAa,IAAM,IAAInM,UACvB,MAAM+F,EAAMvE,EAAAA,SAAS,iBAAkB0J,GAAoBT,GAAKC,GAAKC,GAAKC,GAAMC,GAAMC,GAAMqB,EAAa,GAAG,EACrG7B,KAEN6B,EAAa,IAAMpG,GAIfyE,KAEJ2B,EAAa,IAAMA,EAAa,IAIlC,CAEA,GAAKpkB,EAAS,CAEbgjB,GAAS,oBAAqBhjB,EAAQY,CAAC,EACvCqiB,GAAS,oBAAqBjjB,EAAQgD,CAAC,EACvCkgB,GAAS,oBAAqBljB,EAAQ2H,CAAC,EAEvCyc,EAAa,OAAS,IAAI1N,UAC1B,MAAMsH,EAAMvE,EAAAA,SAAS,iBAAkB0J,GAAoBT,GAAKC,GAAKC,GAAKI,GAAUC,GAAUC,GAAUkB,EAAa,MAAM,EACtHA,EAAa,OAAO,IAAKf,EAAI,SAAS,EAAK,GAE/Ce,EAAa,OAAO,eAAgB,EAAG,EAIjC7B,KAEN6B,EAAa,OAASpG,EAIxB,CAEA,MAAMqG,EAAO,CACZ,EAAGzjB,EACH,EAAGoC,EACH,EAAG2E,EACH,OAAQ,IAAI+O,EAAAA,QACZ,cAAe,CAClB,EAOE,GALA+C,EAAAA,SAAS,UAAWiJ,GAAKC,GAAKC,GAAKyB,EAAK,MAAM,EAE9CD,EAAa,KAAOC,EACpBD,EAAa,UAAYxjB,EAEpB2hB,GAAqB,CAEzB,MAAM+B,EAAY,IAAI5N,UACtB+C,EAAAA,SAAS,aAAc0J,GAAoBT,GAAKC,GAAKC,GAAK0B,CAAS,EAEnEF,EAAa,UAAYE,CAE1B,CAED,CAEA,OAAOF,CAER,CAEA,SAASG,GAASC,EAAiB,CAElC,OAAOA,GAAkBA,EAAe,WAAaA,EAAe,KAAOA,CAE5E,CAGO,SAASC,GAAcpsB,EAAUmsB,EAAgBnB,EAAKjB,EAAKsC,EAAehB,EAAMC,EAAM,CAE5F,MAAMgB,EAAYvC,EAAM,EACxB,IAAIxhB,EAAI+jB,EAAY,EAChB3hB,EAAI2hB,EAAY,EAChBhd,EAAIgd,EAAY,EAEpB,KAAM,CAAE,MAAArlB,EAAO,OAAAslB,CAAM,EAAKvsB,EACrBA,EAAS,QAEbuI,EAAItB,EAAM,KAAMsB,CAAC,EACjBoC,EAAI1D,EAAM,KAAM0D,CAAC,EACjB2E,EAAIrI,EAAM,KAAMqI,CAAC,GAIlB,KAAM,CAAE,SAAAsc,EAAU,OAAAjkB,EAAQ,GAAAkkB,EAAI,IAAAC,CAAG,EAAK9rB,EAAS,WAC/C,GAAK,MAAM,QAASmsB,GAAmB,CAItC,MAAMK,EAAazC,EAAM,EACzB,QAAUliB,EAAI,EAAGkT,EAAIwR,EAAO,OAAQ1kB,EAAIkT,EAAGlT,IAAO,CAEjD,KAAM,CAAE,MAAA4U,EAAO,MAAAjQ,EAAO,cAAAigB,CAAa,EAAKF,EAAQ1kB,CAAC,EACjD,GAAK2kB,GAAc/P,GAAS+P,EAAa/P,EAAQjQ,EAAQ,CAExD,MAAM4e,EAAOc,GAASC,EAAgBM,CAAa,CAAE,EAC/CV,EAAeJ,GAAiCX,EAAKY,EAAUjkB,EAAQkkB,EAAIC,EAAKvjB,EAAGoC,EAAG2E,EAAG8b,EAAMC,EAAMC,CAAG,EAC9G,GAAKS,EAKJ,GAHAA,EAAa,UAAYhC,EACzBgC,EAAa,KAAK,cAAgBU,EAE7BJ,EAEJA,EAAc,KAAMN,CAAY,MAIhC,QAAOA,CAMV,CAED,CAED,KAAO,CAGN,MAAMX,EAAOc,GAASC,CAAc,EAC9BJ,EAAeJ,GAAiCX,EAAKY,EAAUjkB,EAAQkkB,EAAIC,EAAKvjB,EAAGoC,EAAG2E,EAAG8b,EAAMC,EAAMC,CAAG,EAC9G,GAAKS,EAKJ,GAHAA,EAAa,UAAYhC,EACzBgC,EAAa,KAAK,cAAgB,EAE7BM,EAEJA,EAAc,KAAMN,CAAY,MAIhC,QAAOA,CAMV,CAEA,OAAO,IAER,CCjOO,SAASW,EAAa3C,EAAKliB,EAAGZ,EAAO4H,EAAM,CAEjD,MAAM8d,EAAK5C,EAAI,EACT/Y,EAAK+Y,EAAI,EACT6C,EAAK7C,EAAI,EAEf,IAAIjiB,EAAKD,EACLE,EAAKF,EAAI,EACTG,EAAKH,EAAI,EACRZ,IAEJa,EAAKb,EAAM,KAAMa,CAAE,EACnBC,EAAKd,EAAM,KAAMc,CAAE,EACnBC,EAAKf,EAAM,KAAMe,CAAE,GAIpB2kB,EAAG,EAAI9d,EAAI,KAAM/G,CAAE,EACnB6kB,EAAG,EAAI9d,EAAI,KAAM/G,CAAE,EACnB6kB,EAAG,EAAI9d,EAAI,KAAM/G,CAAE,EAEnBkJ,EAAG,EAAInC,EAAI,KAAM9G,CAAE,EACnBiJ,EAAG,EAAInC,EAAI,KAAM9G,CAAE,EACnBiJ,EAAG,EAAInC,EAAI,KAAM9G,CAAE,EAEnB6kB,EAAG,EAAI/d,EAAI,KAAM7G,CAAE,EACnB4kB,EAAG,EAAI/d,EAAI,KAAM7G,CAAE,EACnB4kB,EAAG,EAAI/d,EAAI,KAAM7G,CAAE,CAEpB,CC1BA,SAAS6kB,GAAe1a,EAAKga,EAAgBnB,EAAKze,EAAQC,EAAO6f,EAAehB,EAAMC,EAAM,CAE3F,KAAM,CAAE,SAAAtrB,EAAU,gBAAA8sB,CAAe,EAAK3a,EACtC,QAAUtK,EAAI0E,EAAQgB,EAAMhB,EAASC,EAAO3E,EAAI0F,EAAK1F,IAGpDukB,GAAcpsB,EAAUmsB,EAAgBnB,EAAKnjB,EAAGwkB,EAAehB,EAAMC,CAAG,CAK1E,CAEA,SAASyB,GAAqB5a,EAAKga,EAAgBnB,EAAKze,EAAQC,EAAO6e,EAAMC,EAAM,CAElF,KAAM,CAAE,SAAAtrB,EAAU,gBAAA8sB,CAAe,EAAK3a,EACtC,IAAI3H,EAAO,IACPmb,EAAM,KACV,QAAU9d,EAAI0E,EAAQgB,EAAMhB,EAASC,EAAO3E,EAAI0F,EAAK1F,IAAO,CAE3D,IAAIkkB,EAEJA,EAAeK,GAAcpsB,EAAUmsB,EAAgBnB,EAAKnjB,EAAG,KAAMwjB,EAAMC,CAAG,EAGzES,GAAgBA,EAAa,SAAWvhB,IAE5Cmb,EAAMoG,EACNvhB,EAAOuhB,EAAa,SAItB,CAEA,OAAOpG,CAER,CAEA,SAASqH,GACRzgB,EACAC,EACA2F,EACA8a,EACApR,EACA5I,EACA0N,EACC,CAED,KAAM,CAAE,SAAA3gB,CAAQ,EAAKmS,EACf,CAAE,MAAAlL,CAAK,EAAKjH,EACZ6O,EAAM7O,EAAS,WAAW,SAChC,QAAU6H,EAAI0E,EAAQwO,EAAIvO,EAAQD,EAAQ1E,EAAIkT,EAAGlT,IAAO,CAEvD,IAAIkiB,EAOJ,GALAA,EAAMliB,EAEN6kB,EAAa/L,EAAUoJ,EAAM,EAAG9iB,EAAO4H,CAAG,EAC1C8R,EAAS,YAAc,GAElBsM,EAAwBtM,EAAUoJ,EAAKlO,EAAW5I,CAAK,EAE3D,MAAO,EAIT,CAEA,MAAO,EAER,CCtEA,SAASia,GAAO/a,EAAKgb,EAAc,KAAO,CAEpCA,GAAe,MAAM,QAASA,CAAW,IAE7CA,EAAc,IAAI,IAAKA,CAAW,GAInC,MAAMntB,EAAWmS,EAAI,SACfib,EAAWptB,EAAS,MAAQA,EAAS,MAAM,MAAQ,KACnDgH,EAAUhH,EAAS,WAAW,SAEpC,IAAI6B,EAAQmK,EAAaH,EAAaoF,EAClCM,EAAa,EACjB,MAAM6F,EAAQjF,EAAI,OAClB,QAAUtK,EAAI,EAAGkT,EAAI3D,EAAM,OAAQvP,EAAIkT,EAAGlT,IAEzChG,EAASuV,EAAOvP,CAAC,EACjBmE,EAAc,IAAI,YAAanK,CAAM,EACrCgK,EAAc,IAAI,YAAahK,CAAM,EACrCoP,EAAe,IAAI,aAAcpP,CAAM,EAEvCiW,EAAW,EAAGvG,CAAU,EACxBA,GAAc1P,EAAO,WAItB,SAASiW,EAAW7N,EAAasH,EAAY8b,EAAQ,GAAQ,CAE5D,MAAM7X,EAAcvL,EAAc,EAClC,GAAK0B,EAAS6J,EAAa3J,GAAgB,CAE1C,MAAMU,EAAST,EAAQ7B,EAAa+B,CAAW,EACzCQ,EAAQP,EAAOuJ,EAAa3J,CAAW,EAE7C,IAAIa,EAAO,IACPC,EAAO,IACPC,EAAO,IACPC,EAAO,KACPC,EAAO,KACPC,EAAO,KAGX,QAAUlF,EAAI,EAAI0E,EAAQwO,EAAI,GAAMxO,EAASC,GAAS3E,EAAIkT,EAAGlT,IAAO,CAEnE,IAAIZ,EAAQmmB,EAAUvlB,CAAC,EACvB,MAAM2W,EAAIxX,EAAQ,KAAMC,CAAK,EACvBwX,EAAIzX,EAAQ,KAAMC,CAAK,EACvByX,EAAI1X,EAAQ,KAAMC,CAAK,EAExBuX,EAAI9R,IAAOA,EAAO8R,GAClBA,EAAI3R,IAAOA,EAAO2R,GAElBC,EAAI9R,IAAOA,EAAO8R,GAClBA,EAAI3R,IAAOA,EAAO2R,GAElBC,EAAI9R,IAAOA,EAAO8R,GAClBA,EAAI3R,IAAOA,EAAO2R,EAExB,CAGA,OACCzN,EAAchH,EAAc,CAAC,IAAOyC,GACpCuE,EAAchH,EAAc,CAAC,IAAO0C,GACpCsE,EAAchH,EAAc,CAAC,IAAO2C,GAEpCqE,EAAchH,EAAc,CAAC,IAAO4C,GACpCoE,EAAchH,EAAc,CAAC,IAAO6C,GACpCmE,EAAchH,EAAc,KAAQ8C,GAGpCkE,EAAchH,EAAc,CAAC,EAAKyC,EAClCuE,EAAchH,EAAc,CAAC,EAAK0C,EAClCsE,EAAchH,EAAc,CAAC,EAAK2C,EAElCqE,EAAchH,EAAc,CAAC,EAAK4C,EAClCoE,EAAchH,EAAc,CAAC,EAAK6C,EAClCmE,EAAchH,EAAc,CAAC,EAAK8C,EAE3B,IAIA,EAIT,KAAO,CAEN,MAAM4D,EAAOzE,EAAWjC,CAAW,EAC7B2G,EAAQzE,EAAYlC,EAAa+B,CAAW,EAIlD,IAAIshB,EAAgBD,EAChBE,EAAe,GACfC,EAAgB,GAEpB,GAAKL,GAIJ,GAAK,CAAEG,EAAgB,CAEtB,MAAMG,EAAa9c,EAAOjH,EAAkB6H,EAAa9H,EACnDikB,EAAc9c,EAAQlH,EAAkB6H,EAAa9H,EAC3D8jB,EAAeJ,EAAY,IAAKM,CAAU,EAC1CD,EAAgBL,EAAY,IAAKO,CAAW,EAC5CJ,EAAgB,CAAEC,GAAgB,CAAEC,CAErC,OAIAD,EAAe,GACfC,EAAgB,GAIjB,MAAMG,EAAeL,GAAiBC,EAChCK,EAAgBN,GAAiBE,EAEvC,IAAIK,EAAa,GACZF,IAEJE,EAAa/V,EAAWnH,EAAMY,EAAY+b,CAAa,GAIxD,IAAIQ,EAAc,GACbF,IAEJE,EAAchW,EAAWlH,EAAOW,EAAY+b,CAAa,GAI1D,MAAMS,EAAYF,GAAcC,EAChC,GAAKC,EAEJ,QAAUlmB,EAAI,EAAGA,EAAI,EAAGA,IAAO,CAE9B,MAAMmmB,EAASrd,EAAO9I,EAChBomB,EAAUrd,EAAQ/I,EAClBqmB,EAAejd,EAAc+c,CAAM,EACnCG,EAAeld,EAAc+c,EAAS,CAAC,EACvCI,EAAgBnd,EAAcgd,CAAO,EACrCI,EAAgBpd,EAAcgd,EAAU,CAAC,EAE/Chd,EAAchH,EAAcpC,CAAC,EAAKqmB,EAAeE,EAAgBF,EAAeE,EAChFnd,EAAchH,EAAcpC,EAAI,CAAC,EAAKsmB,EAAeE,EAAgBF,EAAeE,CAErF,CAID,OAAON,CAER,CAED,CAED,CCxKO,SAASO,GAAsBrkB,EAAaC,EAAO8gB,EAAKK,EAAMC,EAAM,CAK1E,IAAIiD,EAAMC,EAAMC,EAAOC,EAAOC,EAAOC,EAErC,MAAMC,EAAU,EAAI7D,EAAI,UAAU,EACjC8D,EAAU,EAAI9D,EAAI,UAAU,EAC5B+D,EAAU,EAAI/D,EAAI,UAAU,EAEvBgE,EAAKhE,EAAI,OAAO,EAChBiE,EAAKjE,EAAI,OAAO,EAChBkE,EAAKlE,EAAI,OAAO,EAEtB,IAAIte,EAAOxC,EAAOD,CAAW,EACzB4C,EAAO3C,EAAOD,EAAc,CAAC,EAE7B0C,EAAOzC,EAAOD,EAAc,CAAC,EAC7B6C,EAAO5C,EAAOD,EAAc,EAAI,CAAC,EAEjC2C,EAAO1C,EAAOD,EAAc,CAAC,EAC7B8C,EAAO7C,EAAOD,EAAc,EAAI,CAAC,EA4CrC,OA1CK4kB,GAAW,GAEfN,GAAS7hB,EAAOsiB,GAAOH,EACvBL,GAAS3hB,EAAOmiB,GAAOH,IAIvBN,GAAS1hB,EAAOmiB,GAAOH,EACvBL,GAAS9hB,EAAOsiB,GAAOH,GAInBC,GAAW,GAEfL,GAAU9hB,EAAOsiB,GAAOH,EACxBJ,GAAU5hB,EAAOmiB,GAAOH,IAIxBL,GAAU3hB,EAAOmiB,GAAOH,EACxBJ,GAAU/hB,EAAOsiB,GAAOH,GAIlBP,EAAOG,GAAaD,EAAQD,KAE9BC,EAAQF,GAAQ,MAAOA,CAAI,KAAKA,EAAOE,IAEvCC,EAAQF,GAAQ,MAAOA,CAAI,KAAKA,EAAOE,GAEvCK,GAAW,GAEfJ,GAAU/hB,EAAOsiB,GAAOH,EACxBH,GAAU7hB,EAAOmiB,GAAOH,IAIxBJ,GAAU5hB,EAAOmiB,GAAOH,EACxBH,GAAUhiB,EAAOsiB,GAAOH,GAIlBR,EAAOK,GAAaD,EAAQH,GAAgB,KAE9CG,EAAQJ,GAAQA,IAASA,KAAOA,EAAOI,IAEvCC,EAAQJ,GAAQA,IAASA,KAAOA,EAAOI,GAIrCL,GAAQjD,GAAOkD,GAAQnD,EAE/B,CCtEA,SAAS8D,GAAwBhd,EAAKga,EAAgBnB,EAAKze,EAAQC,EAAO6f,EAAehB,EAAMC,EAAM,CAEpG,KAAM,CAAE,SAAAtrB,EAAU,gBAAA8sB,CAAe,EAAK3a,EACtC,QAAUtK,EAAI0E,EAAQgB,EAAMhB,EAASC,EAAO3E,EAAI0F,EAAK1F,IAAO,CAE3D,IAAIunB,EAAKtC,EAAkBA,EAAiBjlB,CAAC,EAAKA,EAClDukB,GAAcpsB,EAAUmsB,EAAgBnB,EAAKoE,EAAI/C,EAAehB,EAAMC,CAAG,CAG1E,CAED,CAEA,SAAS+D,GAA8Bld,EAAKga,EAAgBnB,EAAKze,EAAQC,EAAO6e,EAAMC,EAAM,CAE3F,KAAM,CAAE,SAAAtrB,EAAU,gBAAA8sB,CAAe,EAAK3a,EACtC,IAAI3H,EAAO,IACPmb,EAAM,KACV,QAAU9d,EAAI0E,EAAQgB,EAAMhB,EAASC,EAAO3E,EAAI0F,EAAK1F,IAAO,CAE3D,IAAIkkB,EACJA,EAAeK,GAAcpsB,EAAUmsB,EAAgBnB,EAAK8B,EAAkBA,EAAiBjlB,CAAC,EAAKA,EAAG,KAAMwjB,EAAMC,CAAG,EAGlHS,GAAgBA,EAAa,SAAWvhB,IAE5Cmb,EAAMoG,EACNvhB,EAAOuhB,EAAa,SAItB,CAEA,OAAOpG,CAER,CAEA,SAAS2J,GACR/iB,EACAC,EACA2F,EACA8a,EACApR,EACA5I,EACA0N,EACC,CAED,KAAM,CAAE,SAAA3gB,CAAQ,EAAKmS,EACf,CAAE,MAAAlL,CAAK,EAAKjH,EACZ6O,EAAM7O,EAAS,WAAW,SAChC,QAAU6H,EAAI0E,EAAQwO,EAAIvO,EAAQD,EAAQ1E,EAAIkT,EAAGlT,IAAO,CAEvD,IAAIkiB,EAMJ,GALAA,EAAM5X,EAAI,qBAAsBtK,CAAC,EAEjC6kB,EAAa/L,EAAUoJ,EAAM,EAAG9iB,EAAO4H,CAAG,EAC1C8R,EAAS,YAAc,GAElBsM,EAAwBtM,EAAUoJ,EAAKlO,EAAW5I,CAAK,EAE3D,MAAO,EAIT,CAEA,MAAO,EAER,CCjEA,SAASsc,GAASpd,EAAKU,EAAMsZ,EAAgBnB,EAAKwE,EAAYnE,EAAMC,EAAM,CAEzE/W,EAAY,UAAWpC,EAAI,OAAQU,CAAI,CAAE,EACzC4c,GAAU,EAAGtd,EAAKga,EAAgBnB,EAAKwE,EAAYnE,EAAMC,CAAG,EAC5D/W,EAAY,YAAW,CAExB,CAEA,SAASkb,GAAUxlB,EAAakI,EAAKga,EAAgBnB,EAAKwE,EAAYnE,EAAMC,EAAM,CAEjF,KAAM,CAAE,aAAAra,EAAc,YAAApF,EAAa,YAAAG,CAAW,EAAKuI,EAC7CiB,EAAcvL,EAAc,EAElC,GADe0B,EAAS6J,EAAa3J,CAAW,EAClC,CAEb,MAAMU,EAAST,EAAQ7B,EAAa+B,CAAW,EACzCQ,EAAQP,EAAOuJ,EAAa3J,CAAW,EAG7CghB,GAAe1a,EAAKga,EAAgBnB,EAAKze,EAAQC,EAAOgjB,EAAYnE,EAAMC,CAAG,CAG9E,KAAO,CAEN,MAAMoE,EAAYxjB,EAAWjC,CAAW,EACnCqkB,GAAsBoB,EAAWze,EAAc+Z,EAAKK,EAAMC,IAE9DmE,GAAUC,EAAWvd,EAAKga,EAAgBnB,EAAKwE,EAAYnE,EAAMC,CAAG,EAIrE,MAAMqE,EAAaxjB,EAAYlC,EAAa+B,CAAW,EAClDsiB,GAAsBqB,EAAY1e,EAAc+Z,EAAKK,EAAMC,IAE/DmE,GAAUE,EAAYxd,EAAKga,EAAgBnB,EAAKwE,EAAYnE,EAAMC,CAAG,CAIvE,CAED,CCxCA,MAAMsE,GAAa,CAAE,IAAK,IAAK,GAAG,EAElC,SAASC,GAAc1d,EAAKU,EAAMsZ,EAAgBnB,EAAKK,EAAMC,EAAM,CAElE/W,EAAY,UAAWpC,EAAI,OAAQU,CAAI,CAAE,EACzC,MAAMhS,EAASivB,GAAe,EAAG3d,EAAKga,EAAgBnB,EAAKK,EAAMC,CAAG,EACpE,OAAA/W,EAAY,YAAW,EAEhB1T,CAER,CAEA,SAASivB,GAAe7lB,EAAakI,EAAKga,EAAgBnB,EAAKK,EAAMC,EAAM,CAE1E,KAAM,CAAE,aAAAra,EAAc,YAAApF,EAAa,YAAAG,CAAW,EAAKuI,EACnD,IAAIiB,EAAcvL,EAAc,EAGhC,GADe0B,EAAS6J,EAAa3J,CAAW,EAClC,CAEb,MAAMU,EAAST,EAAQ7B,EAAa+B,CAAW,EACzCQ,EAAQP,EAAOuJ,EAAa3J,CAAW,EAI7C,OAAOkhB,GAAqB5a,EAAKga,EAAgBnB,EAAKze,EAAQC,EAAO6e,EAAMC,CAAG,CAG/E,KAAO,CAIN,MAAMzZ,EAAYxF,GAAYpC,EAAa+B,CAAW,EAChD+jB,EAAUH,GAAY/d,CAAS,EAE/Bme,EADShF,EAAI,UAAW+E,CAAO,GACP,EAG9B,IAAIpa,EAAIC,EACHoa,GAEJra,EAAKzJ,EAAWjC,CAAW,EAC3B2L,EAAKzJ,EAAYlC,EAAa+B,CAAW,IAIzC2J,EAAKxJ,EAAYlC,EAAa+B,CAAW,EACzC4J,EAAK1J,EAAWjC,CAAW,GAK5B,MAAMgmB,EADiB3B,GAAsB3Y,EAAI1E,EAAc+Z,EAAKK,EAAMC,CAAG,EAC3CwE,GAAena,EAAIxD,EAAKga,EAAgBnB,EAAKK,EAAMC,CAAG,EAAK,KAI7F,GAAK2E,EAAW,CAIf,MAAMnL,EAAQmL,EAAS,MAAOF,CAAO,EAKrC,GAJkBC,EACjBlL,GAAS7T,EAAc2E,EAAK/D,CAAS,EACrCiT,GAAS7T,EAAc2E,EAAK/D,EAAY,CAAC,EAIzC,OAAOoe,CAIT,CAKA,MAAMC,EADiB5B,GAAsB1Y,EAAI3E,EAAc+Z,EAAKK,EAAMC,CAAG,EAC3CwE,GAAela,EAAIzD,EAAKga,EAAgBnB,EAAKK,EAAMC,CAAG,EAAK,KAE7F,OAAK2E,GAAYC,EAETD,EAAS,UAAYC,EAAS,SAAWD,EAAWC,EAIpDD,GAAYC,GAAY,IAIjC,CAED,CCtFA,MAAMC,GAA8B,IAAIvb,EAAAA,KAClC+L,GAA2B,IAAIQ,GAC/BiP,GAA4B,IAAIjP,GAChCkP,GAA8B,IAAI5Y,EAAAA,QAElC6Y,GAAsB,IAAIxI,GAC1ByI,GAAuB,IAAIzI,GAEjC,SAAS0I,GAAoBre,EAAKU,EAAM4d,EAAeC,EAAgB,CAEtEnc,EAAY,UAAWpC,EAAI,OAAQU,CAAI,CAAE,EACzC,MAAMhS,EAAS8vB,GAAqB,EAAGxe,EAAKse,EAAeC,CAAa,EACxE,OAAAnc,EAAY,YAAW,EAEhB1T,CAER,CAEA,SAAS8vB,GAAqB1mB,EAAakI,EAAKse,EAAeC,EAAeE,EAAY,KAAO,CAEhG,KAAM,CAAE,aAAA3f,EAAc,YAAApF,EAAa,YAAAG,CAAW,EAAKuI,EACnD,IAAIiB,EAAcvL,EAAc,EAgBhC,GAdK2mB,IAAc,OAEXH,EAAc,aAEpBA,EAAc,mBAAkB,EAIjCH,GAAI,IAAKG,EAAc,YAAY,IAAKA,EAAc,YAAY,IAAKC,CAAa,EACpFE,EAAYN,IAIE3kB,EAAS6J,EAAa3J,CAAW,EAClC,CAEb,MAAMglB,EAAe1e,EAAI,SACnB2e,EAAYD,EAAa,MACzBE,EAAUF,EAAa,WAAW,SAElCG,EAAaP,EAAc,MAC3BQ,EAAWR,EAAc,WAAW,SAEpClkB,EAAST,EAAQ7B,EAAa+B,CAAW,EACzCQ,EAAQP,EAAOuJ,EAAa3J,CAAW,EAO7C,GAFAwkB,GAAY,KAAMK,CAAa,EAAG,OAAM,EAEnCD,EAAc,WAGlB,OAAAzmB,EAAiCC,EAAegH,EAAcsf,EAAI,EAClEA,GAAK,OAAO,KAAMF,EAAW,EAC7BE,GAAK,YAAc,GAGPE,EAAc,WAAW,UAAW,CAE/C,iBAAkBxyB,GAAOsyB,GAAK,cAAetyB,CAAG,EAEhD,mBAAoB8rB,GAAO,CAE1BA,EAAI,EAAE,aAAc2G,CAAa,EACjC3G,EAAI,EAAE,aAAc2G,CAAa,EACjC3G,EAAI,EAAE,aAAc2G,CAAa,EACjC3G,EAAI,YAAc,GAGlB,QAAUliB,EAAI0E,EAAS,EAAGwO,GAAMvO,EAAQD,GAAW,EAAG1E,EAAIkT,EAAGlT,GAAK,EAKjE,GAFA6kB,EAAa0D,GAAWvoB,EAAGipB,EAAWC,CAAO,EAC7CX,GAAU,YAAc,GACnBrG,EAAI,mBAAoBqG,IAE5B,MAAO,GAOT,MAAO,EAER,CAEJ,CAAI,EAIK,CAGN,MAAMc,EAAqBhV,GAAauU,CAAa,EAGrD,QAAU5oB,EAAI0E,EAAS,EAAGwO,GAAMvO,EAAQD,GAAW,EAAG1E,EAAIkT,EAAGlT,GAAK,EAAI,CAGrE6kB,EAAa/L,GAAU9Y,EAAGipB,EAAWC,CAAO,EAG5CpQ,GAAS,EAAE,aAAc0P,EAAW,EACpC1P,GAAS,EAAE,aAAc0P,EAAW,EACpC1P,GAAS,EAAE,aAAc0P,EAAW,EACpC1P,GAAS,YAAc,GAEvB,QAAU3Y,EAAK,EAAGgX,EAAKkS,EAAqB,EAAGlpB,EAAKgX,EAAIhX,GAAM,EAK7D,GAHA0kB,EAAa0D,GAAWpoB,EAAIgpB,EAAYC,CAAQ,EAChDb,GAAU,YAAc,GAEnBzP,GAAS,mBAAoByP,IAEjC,MAAO,EAOV,CAGD,CAED,KAAO,CAEN,MAAMzf,EAAOzE,EAAWjC,CAAW,EAC7B2G,EAAQzE,EAAYlC,EAAa+B,CAAW,EAclD,OAZAhC,EAAiC2G,EAAQM,EAAckf,EAAW,EAEjE,GAAAS,EAAU,cAAeT,EAAW,GACpCQ,GAAqBhgB,EAAMwB,EAAKse,EAAeC,EAAeE,CAAS,IAIxE5mB,EAAiC4G,EAASK,EAAckf,EAAW,EAElES,EAAU,cAAeT,EAAW,GACpCQ,GAAqB/f,EAAOuB,EAAKse,EAAeC,EAAeE,CAAS,GAM1E,CAED,CC/JA,MAAMO,GAA6B,IAAI1Z,EAAAA,QACjC6Y,GAAsB,IAAIxI,GAC1ByI,GAAuB,IAAIzI,GAC3BjI,GAAwB,IAAIxB,EAAAA,QAC5ByB,GAAwB,IAAIzB,EAAAA,QAC5B+S,GAAwB,IAAI/S,EAAAA,QAC5BgT,GAAwB,IAAIhT,EAAAA,QAElC,SAASiT,GACRnf,EACAse,EACAC,EACA3Q,EAAU,CAAA,EACVC,EAAU,CAAA,EACVyJ,EAAe,EACfC,EAAe,IACd,CAEM+G,EAAc,aAEpBA,EAAc,mBAAkB,EAIjCH,GAAI,IAAKG,EAAc,YAAY,IAAKA,EAAc,YAAY,IAAKC,CAAa,EACpFJ,GAAI,YAAc,GAElB,MAAMtwB,EAAWmS,EAAI,SACftD,EAAM7O,EAAS,WAAW,SAC1BiH,EAAQjH,EAAS,MACjBixB,EAAWR,EAAc,WAAW,SACpCO,EAAaP,EAAc,MAC3B9P,EAAW4I,GAAqB,aAAY,EAC5C6G,EAAY7G,GAAqB,aAAY,EAEnD,IAAIgI,EAAc1R,GACd2R,EAAkB1R,GAClB2R,EAAc,KACdC,EAAkB,KAEjB1R,IAEJyR,EAAcL,GACdM,EAAkBL,IAInB,IAAIpH,EAAkB,IAClBJ,EAA0B,KAC1B8H,EAA+B,KAkKnC,OAjKAR,GAAW,KAAMT,CAAa,EAAG,OAAM,EACvCH,GAAK,OAAO,KAAMY,EAAU,EAC5Bhf,EAAI,UACH,CAEC,oBAAqBlU,GAEbqyB,GAAI,cAAeryB,CAAG,EAI9B,iBAAkB,CAAEA,EAAK0T,EAAQmY,IAE3BA,EAAQG,GAAmBH,EAAQJ,GAIlC/X,IAEJ4e,GAAK,IAAI,KAAMtyB,EAAI,GAAG,EACtBsyB,GAAK,IAAI,KAAMtyB,EAAI,GAAG,EACtBsyB,GAAK,YAAc,IAIb,IAID,GAIR,gBAAiB,CAAEhkB,EAAQC,IAAW,CAErC,GAAKikB,EAAc,WAKlB,OADiBA,EAAc,WACf,UAAW,CAC1B,oBAAqBxyB,GAEbsyB,GAAK,cAAetyB,CAAG,EAI/B,iBAAkB,CAAEA,EAAK0T,EAAQmY,IAEzBA,EAAQG,GAAmBH,EAAQJ,EAI3C,gBAAiB,CAAEkI,EAAaC,IAAgB,CAE/C,QAAU7pB,EAAK4pB,EAAa5S,EAAK4S,EAAcC,EAAY7pB,EAAKgX,EAAIhX,IAAQ,CAG3E0kB,EAAa0D,EAAW,EAAIpoB,EAAIgpB,EAAYC,CAAQ,EAEpDb,EAAU,EAAE,aAAcM,CAAa,EACvCN,EAAU,EAAE,aAAcM,CAAa,EACvCN,EAAU,EAAE,aAAcM,CAAa,EACvCN,EAAU,YAAc,GAExB,QAAUvoB,EAAI0E,EAAQwO,EAAIxO,EAASC,EAAO3E,EAAIkT,EAAGlT,IAAO,CAGvD6kB,EAAa/L,EAAU,EAAI9Y,EAAGZ,EAAO4H,CAAG,EAExC8R,EAAS,YAAc,GAEvB,MAAMnW,EAAOmW,EAAS,mBAAoByP,EAAWmB,EAAaE,CAAW,EAkB7E,GAjBKjnB,EAAOyf,IAEXuH,EAAgB,KAAMD,CAAW,EAE5BG,GAEJA,EAAgB,KAAMD,CAAW,EAIlCxH,EAAkBzf,EAClBqf,EAA0BhiB,EAC1B8pB,EAA+B3pB,GAK3BwC,EAAOif,EAEX,MAAO,EAIT,CAED,CAED,CACN,CAAM,EAEK,CAGN,MAAMqI,EAAW5V,GAAauU,CAAa,EAC3C,QAAUzoB,EAAK,EAAGgX,EAAK8S,EAAU9pB,EAAKgX,EAAIhX,IAAQ,CAEjD0kB,EAAa0D,EAAW,EAAIpoB,EAAIgpB,EAAYC,CAAQ,EACpDb,EAAU,EAAE,aAAcM,CAAa,EACvCN,EAAU,EAAE,aAAcM,CAAa,EACvCN,EAAU,EAAE,aAAcM,CAAa,EACvCN,EAAU,YAAc,GAExB,QAAUvoB,EAAI0E,EAAQwO,EAAIxO,EAASC,EAAO3E,EAAIkT,EAAGlT,IAAO,CAGvD6kB,EAAa/L,EAAU,EAAI9Y,EAAGZ,EAAO4H,CAAG,EAExC8R,EAAS,YAAc,GAEvB,MAAMnW,EAAOmW,EAAS,mBAAoByP,EAAWmB,EAAaE,CAAW,EAkB7E,GAjBKjnB,EAAOyf,IAEXuH,EAAgB,KAAMD,CAAW,EAE5BG,GAEJA,EAAgB,KAAMD,CAAW,EAIlCxH,EAAkBzf,EAClBqf,EAA0BhiB,EAC1B8pB,EAA+B3pB,GAK3BwC,EAAOif,EAEX,MAAO,EAIT,CAED,CAED,CAED,CAEH,CAEA,EAECF,GAAqB,iBAAkB5I,CAAQ,EAC/C4I,GAAqB,iBAAkB6G,CAAS,EAE3CnG,IAAoB,IAEjB,MAIDlK,EAAQ,MAMdA,EAAQ,MAAM,KAAMyR,CAAe,EAJnCzR,EAAQ,MAAQyR,EAAgB,MAAK,EAQtCzR,EAAQ,SAAWkK,EACnBlK,EAAQ,UAAY8J,EAEf7J,IAEGA,EAAQ,MACVA,EAAQ,MAAM,KAAM0R,CAAe,EADjB1R,EAAQ,MAAQ0R,EAAgB,MAAK,EAE5D1R,EAAQ,MAAM,aAAcmR,EAAU,EACtCK,EAAgB,aAAcL,EAAU,EACxCnR,EAAQ,SAAWwR,EAAgB,IAAKxR,EAAQ,KAAK,EAAG,OAAM,EAC9DA,EAAQ,UAAY2R,GAId5R,EAER,CCtPA,SAASgS,GAAgB5f,EAAKgb,EAAc,KAAO,CAE7CA,GAAe,MAAM,QAASA,CAAW,IAE7CA,EAAc,IAAI,IAAKA,CAAW,GAInC,MAAMntB,EAAWmS,EAAI,SACfib,EAAWptB,EAAS,MAAQA,EAAS,MAAM,MAAQ,KACnDgH,EAAUhH,EAAS,WAAW,SAEpC,IAAI6B,EAAQmK,EAAaH,EAAaoF,EAClCM,EAAa,EACjB,MAAM6F,EAAQjF,EAAI,OAClB,QAAUtK,EAAI,EAAGkT,EAAI3D,EAAM,OAAQvP,EAAIkT,EAAGlT,IAEzChG,EAASuV,EAAOvP,CAAC,EACjBmE,EAAc,IAAI,YAAanK,CAAM,EACrCgK,EAAc,IAAI,YAAahK,CAAM,EACrCoP,EAAe,IAAI,aAAcpP,CAAM,EAEvCiW,EAAW,EAAGvG,CAAU,EACxBA,GAAc1P,EAAO,WAItB,SAASiW,EAAW7N,EAAasH,EAAY8b,EAAQ,GAAQ,CAE5D,MAAM7X,EAAcvL,EAAc,EAClC,GAAK0B,EAAS6J,EAAa3J,GAAgB,CAE1C,MAAMU,EAAST,EAAQ7B,EAAa+B,CAAW,EACzCQ,EAAQP,EAAOuJ,EAAa3J,CAAW,EAE7C,IAAIa,EAAO,IACPC,EAAO,IACPC,EAAO,IACPC,EAAO,KACPC,EAAO,KACPC,EAAO,KAEX,QAAUlF,EAAI0E,EAAQwO,EAAIxO,EAASC,EAAO3E,EAAIkT,EAAGlT,IAAO,CAEvD,MAAMwc,EAAI,EAAIlS,EAAI,qBAAsBtK,CAAC,EACzC,QAAU+P,EAAI,EAAGA,EAAI,EAAGA,IAAO,CAE9B,IAAI3Q,EAAQod,EAAIzM,EAChB3Q,EAAQmmB,EAAWA,EAAUnmB,CAAK,EAAKA,EAEvC,MAAMuX,EAAIxX,EAAQ,KAAMC,CAAK,EACvBwX,EAAIzX,EAAQ,KAAMC,CAAK,EACvByX,EAAI1X,EAAQ,KAAMC,CAAK,EAExBuX,EAAI9R,IAAOA,EAAO8R,GAClBA,EAAI3R,IAAOA,EAAO2R,GAElBC,EAAI9R,IAAOA,EAAO8R,GAClBA,EAAI3R,IAAOA,EAAO2R,GAElBC,EAAI9R,IAAOA,EAAO8R,GAClBA,EAAI3R,IAAOA,EAAO2R,EAGxB,CAED,CAGA,OACCzN,EAAchH,EAAc,CAAC,IAAOyC,GACpCuE,EAAchH,EAAc,CAAC,IAAO0C,GACpCsE,EAAchH,EAAc,CAAC,IAAO2C,GAEpCqE,EAAchH,EAAc,CAAC,IAAO4C,GACpCoE,EAAchH,EAAc,CAAC,IAAO6C,GACpCmE,EAAchH,EAAc,KAAQ8C,GAGpCkE,EAAchH,EAAc,CAAC,EAAKyC,EAClCuE,EAAchH,EAAc,CAAC,EAAK0C,EAClCsE,EAAchH,EAAc,CAAC,EAAK2C,EAElCqE,EAAchH,EAAc,CAAC,EAAK4C,EAClCoE,EAAchH,EAAc,CAAC,EAAK6C,EAClCmE,EAAchH,EAAc,CAAC,EAAK8C,EAE3B,IAIA,EAIT,KAAO,CAEN,MAAM4D,EAAOzE,EAAWjC,CAAW,EAC7B2G,EAAQzE,EAAYlC,EAAa+B,CAAW,EAIlD,IAAIshB,EAAgBD,EAChBE,EAAe,GACfC,EAAgB,GAEpB,GAAKL,GAIJ,GAAK,CAAEG,EAAgB,CAEtB,MAAMG,EAAa9c,EAAOjH,EAAkB6H,EAAa9H,EACnDikB,EAAc9c,EAAQlH,EAAkB6H,EAAa9H,EAC3D8jB,EAAeJ,EAAY,IAAKM,CAAU,EAC1CD,EAAgBL,EAAY,IAAKO,CAAW,EAC5CJ,EAAgB,CAAEC,GAAgB,CAAEC,CAErC,OAIAD,EAAe,GACfC,EAAgB,GAIjB,MAAMG,EAAeL,GAAiBC,EAChCK,EAAgBN,GAAiBE,EAEvC,IAAIK,EAAa,GACZF,IAEJE,EAAa/V,EAAWnH,EAAMY,EAAY+b,CAAa,GAIxD,IAAIQ,EAAc,GACbF,IAEJE,EAAchW,EAAWlH,EAAOW,EAAY+b,CAAa,GAI1D,MAAMS,EAAYF,GAAcC,EAChC,GAAKC,EAEJ,QAAUlmB,EAAI,EAAGA,EAAI,EAAGA,IAAO,CAE9B,MAAMmmB,EAASrd,EAAO9I,EAChBomB,EAAUrd,EAAQ/I,EAClBqmB,EAAejd,EAAc+c,CAAM,EACnCG,EAAeld,EAAc+c,EAAS,CAAC,EACvCI,EAAgBnd,EAAcgd,CAAO,EACrCI,EAAgBpd,EAAcgd,EAAU,CAAC,EAE/Chd,EAAchH,EAAcpC,CAAC,EAAKqmB,EAAeE,EAAgBF,EAAeE,EAChFnd,EAAchH,EAAcpC,EAAI,CAAC,EAAKsmB,EAAeE,EAAgBF,EAAeE,CAErF,CAID,OAAON,CAER,CAED,CAED,CCtKA,SAASiE,GAAkB7f,EAAKU,EAAMsZ,EAAgBnB,EAAKwE,EAAYnE,EAAMC,EAAM,CAElF/W,EAAY,UAAWpC,EAAI,OAAQU,CAAI,CAAE,EACzC4c,GAAU,EAAGtd,EAAKga,EAAgBnB,EAAKwE,EAAYnE,EAAMC,CAAG,EAC5D/W,EAAY,YAAW,CAExB,CAEA,SAASkb,GAAUxlB,EAAakI,EAAKga,EAAgBnB,EAAKwE,EAAYnE,EAAMC,EAAM,CAEjF,KAAM,CAAE,aAAAra,EAAc,YAAApF,EAAa,YAAAG,CAAW,EAAKuI,EAC7CiB,EAAcvL,EAAc,EAElC,GADe0B,EAAS6J,EAAa3J,CAAW,EAClC,CAEb,MAAMU,EAAST,EAAQ7B,EAAa+B,CAAW,EACzCQ,EAAQP,EAAOuJ,EAAa3J,CAAW,EAE7CsjB,GAAwBhd,EAAKga,EAAgBnB,EAAKze,EAAQC,EAAOgjB,EAAYnE,EAAMC,CAAG,CAGvF,KAAO,CAEN,MAAMoE,EAAYxjB,EAAWjC,CAAW,EACnCqkB,GAAsBoB,EAAWze,EAAc+Z,EAAKK,EAAMC,IAE9DmE,GAAUC,EAAWvd,EAAKga,EAAgBnB,EAAKwE,EAAYnE,EAAMC,CAAG,EAIrE,MAAMqE,EAAaxjB,EAAYlC,EAAa+B,CAAW,EAClDsiB,GAAsBqB,EAAY1e,EAAc+Z,EAAKK,EAAMC,IAE/DmE,GAAUE,EAAYxd,EAAKga,EAAgBnB,EAAKwE,EAAYnE,EAAMC,CAAG,CAIvE,CAED,CCvCA,MAAMsE,GAAa,CAAE,IAAK,IAAK,GAAG,EAElC,SAASqC,GAAuB9f,EAAKU,EAAMsZ,EAAgBnB,EAAKK,EAAMC,EAAM,CAE3E/W,EAAY,UAAWpC,EAAI,OAAQU,CAAI,CAAE,EACzC,MAAMhS,EAASivB,GAAe,EAAG3d,EAAKga,EAAgBnB,EAAKK,EAAMC,CAAG,EACpE,OAAA/W,EAAY,YAAW,EAEhB1T,CAER,CAEA,SAASivB,GAAe7lB,EAAakI,EAAKga,EAAgBnB,EAAKK,EAAMC,EAAM,CAE1E,KAAM,CAAE,aAAAra,EAAc,YAAApF,EAAa,YAAAG,CAAW,EAAKuI,EACnD,IAAIiB,EAAcvL,EAAc,EAGhC,GADe0B,EAAS6J,EAAa3J,CAAW,EAClC,CAEb,MAAMU,EAAST,EAAQ7B,EAAa+B,CAAW,EACzCQ,EAAQP,EAAOuJ,EAAa3J,CAAW,EAE7C,OAAOwjB,GAA8Bld,EAAKga,EAAgBnB,EAAKze,EAAQC,EAAO6e,EAAMC,CAAG,CAGxF,KAAO,CAIN,MAAMzZ,EAAYxF,GAAYpC,EAAa+B,CAAW,EAChD+jB,EAAUH,GAAY/d,CAAS,EAE/Bme,EADShF,EAAI,UAAW+E,CAAO,GACP,EAG9B,IAAIpa,EAAIC,EACHoa,GAEJra,EAAKzJ,EAAWjC,CAAW,EAC3B2L,EAAKzJ,EAAYlC,EAAa+B,CAAW,IAIzC2J,EAAKxJ,EAAYlC,EAAa+B,CAAW,EACzC4J,EAAK1J,EAAWjC,CAAW,GAK5B,MAAMgmB,EADiB3B,GAAsB3Y,EAAI1E,EAAc+Z,EAAKK,EAAMC,CAAG,EAC3CwE,GAAena,EAAIxD,EAAKga,EAAgBnB,EAAKK,EAAMC,CAAG,EAAK,KAI7F,GAAK2E,EAAW,CAIf,MAAMnL,EAAQmL,EAAS,MAAOF,CAAO,EAKrC,GAJkBC,EACjBlL,GAAS7T,EAAc2E,EAAK/D,CAAS,EACrCiT,GAAS7T,EAAc2E,EAAK/D,EAAY,CAAC,EAIzC,OAAOoe,CAIT,CAKA,MAAMC,EADiB5B,GAAsB1Y,EAAI3E,EAAc+Z,EAAKK,EAAMC,CAAG,EAC3CwE,GAAela,EAAIzD,EAAKga,EAAgBnB,EAAKK,EAAMC,CAAG,EAAK,KAE7F,OAAK2E,GAAYC,EAETD,EAAS,UAAYC,EAAS,SAAWD,EAAWC,EAIpDD,GAAYC,GAAY,IAIjC,CAED,CCpFA,MAAMC,GAA8B,IAAIvb,EAAAA,KAClC+L,GAA2B,IAAIQ,GAC/BiP,GAA4B,IAAIjP,GAChCkP,GAA8B,IAAI5Y,EAAAA,QAElC6Y,GAAsB,IAAIxI,GAC1ByI,GAAuB,IAAIzI,GAEjC,SAASoK,GAA6B/f,EAAKU,EAAM4d,EAAeC,EAAgB,CAE/Enc,EAAY,UAAWpC,EAAI,OAAQU,CAAI,CAAE,EACzC,MAAMhS,EAAS8vB,GAAqB,EAAGxe,EAAKse,EAAeC,CAAa,EACxE,OAAAnc,EAAY,YAAW,EAEhB1T,CAER,CAEA,SAAS8vB,GAAqB1mB,EAAakI,EAAKse,EAAeC,EAAeE,EAAY,KAAO,CAEhG,KAAM,CAAE,aAAA3f,EAAc,YAAApF,EAAa,YAAAG,CAAW,EAAKuI,EACnD,IAAIiB,EAAcvL,EAAc,EAgBhC,GAdK2mB,IAAc,OAEXH,EAAc,aAEpBA,EAAc,mBAAkB,EAIjCH,GAAI,IAAKG,EAAc,YAAY,IAAKA,EAAc,YAAY,IAAKC,CAAa,EACpFE,EAAYN,IAIE3kB,EAAS6J,EAAa3J,CAAW,EAClC,CAEb,MAAMglB,EAAe1e,EAAI,SACnB2e,EAAYD,EAAa,MACzBE,EAAUF,EAAa,WAAW,SAElCG,EAAaP,EAAc,MAC3BQ,EAAWR,EAAc,WAAW,SAEpClkB,EAAST,EAAQ7B,EAAa+B,CAAW,EACzCQ,EAAQP,EAAOuJ,EAAa3J,CAAW,EAO7C,GAFAwkB,GAAY,KAAMK,CAAa,EAAG,OAAM,EAEnCD,EAAc,WAGlB,OAAAzmB,EAAiCC,EAAegH,EAAcsf,EAAI,EAClEA,GAAK,OAAO,KAAMF,EAAW,EAC7BE,GAAK,YAAc,GAGPE,EAAc,WAAW,UAAW,CAE/C,iBAAkBxyB,GAAOsyB,GAAK,cAAetyB,CAAG,EAEhD,mBAAoB8rB,GAAO,CAE1BA,EAAI,EAAE,aAAc2G,CAAa,EACjC3G,EAAI,EAAE,aAAc2G,CAAa,EACjC3G,EAAI,EAAE,aAAc2G,CAAa,EACjC3G,EAAI,YAAc,GAElB,QAAUliB,EAAI0E,EAAQwO,EAAIvO,EAAQD,EAAQ1E,EAAIkT,EAAGlT,IAKhD,GAFA6kB,EAAa0D,GAAW,EAAIje,EAAI,qBAAsBtK,CAAC,EAAIipB,EAAWC,CAAO,EAC7EX,GAAU,YAAc,GACnBrG,EAAI,mBAAoBqG,IAE5B,MAAO,GAOT,MAAO,EAER,CAEJ,CAAI,EAIK,CAGN,MAAMc,EAAqBhV,GAAauU,CAAa,EAErD,QAAU5oB,EAAI0E,EAAQwO,EAAIvO,EAAQD,EAAQ1E,EAAIkT,EAAGlT,IAAO,CAGvD,MAAMsqB,EAAKhgB,EAAI,qBAAsBtK,CAAC,EACtC6kB,EAAa/L,GAAU,EAAIwR,EAAIrB,EAAWC,CAAO,EAGjDpQ,GAAS,EAAE,aAAc0P,EAAW,EACpC1P,GAAS,EAAE,aAAc0P,EAAW,EACpC1P,GAAS,EAAE,aAAc0P,EAAW,EACpC1P,GAAS,YAAc,GAEvB,QAAU3Y,EAAK,EAAGgX,EAAKkS,EAAqB,EAAGlpB,EAAKgX,EAAIhX,GAAM,EAK7D,GAHA0kB,EAAa0D,GAAWpoB,EAAIgpB,EAAYC,CAAQ,EAChDb,GAAU,YAAc,GAEnBzP,GAAS,mBAAoByP,IAEjC,MAAO,EAMV,CAGD,CAED,KAAO,CAEN,MAAMzf,EAAOzE,EAAWjC,CAAW,EAC7B2G,EAAQzE,EAAYlC,EAAa+B,CAAW,EAclD,OAZAhC,EAAiC2G,EAAQM,EAAckf,EAAW,EAEjE,GAAAS,EAAU,cAAeT,EAAW,GACpCQ,GAAqBhgB,EAAMwB,EAAKse,EAAeC,EAAeE,CAAS,IAIxE5mB,EAAiC4G,EAASK,EAAckf,EAAW,EAElES,EAAU,cAAeT,EAAW,GACpCQ,GAAqB/f,EAAOuB,EAAKse,EAAeC,EAAeE,CAAS,GAM1E,CAED,CC7JA,MAAMO,GAA6B,IAAI1Z,EAAAA,QACjC6Y,GAAsB,IAAIxI,GAC1ByI,GAAuB,IAAIzI,GAC3BjI,GAAwB,IAAIxB,EAAAA,QAC5ByB,GAAwB,IAAIzB,EAAAA,QAC5B+S,GAAwB,IAAI/S,EAAAA,QAC5BgT,GAAwB,IAAIhT,EAAAA,QAElC,SAAS+T,GACRjgB,EACAse,EACAC,EACA3Q,EAAU,CAAA,EACVC,EAAU,CAAA,EACVyJ,EAAe,EACfC,EAAe,IACd,CAEM+G,EAAc,aAEpBA,EAAc,mBAAkB,EAIjCH,GAAI,IAAKG,EAAc,YAAY,IAAKA,EAAc,YAAY,IAAKC,CAAa,EACpFJ,GAAI,YAAc,GAElB,MAAMtwB,EAAWmS,EAAI,SACftD,EAAM7O,EAAS,WAAW,SAC1BiH,EAAQjH,EAAS,MACjBixB,EAAWR,EAAc,WAAW,SACpCO,EAAaP,EAAc,MAC3B9P,EAAW4I,GAAqB,aAAY,EAC5C6G,EAAY7G,GAAqB,aAAY,EAEnD,IAAIgI,EAAc1R,GACd2R,EAAkB1R,GAClB2R,EAAc,KACdC,EAAkB,KAEjB1R,IAEJyR,EAAcL,GACdM,EAAkBL,IAInB,IAAIpH,EAAkB,IAClBJ,EAA0B,KAC1B8H,EAA+B,KAkKnC,OAjKAR,GAAW,KAAMT,CAAa,EAAG,OAAM,EACvCH,GAAK,OAAO,KAAMY,EAAU,EAC5Bhf,EAAI,UACH,CAEC,oBAAqBlU,GAEbqyB,GAAI,cAAeryB,CAAG,EAI9B,iBAAkB,CAAEA,EAAK0T,EAAQmY,IAE3BA,EAAQG,GAAmBH,EAAQJ,GAIlC/X,IAEJ4e,GAAK,IAAI,KAAMtyB,EAAI,GAAG,EACtBsyB,GAAK,IAAI,KAAMtyB,EAAI,GAAG,EACtBsyB,GAAK,YAAc,IAIb,IAID,GAIR,gBAAiB,CAAEhkB,EAAQC,IAAW,CAErC,GAAKikB,EAAc,WAAa,CAI/B,MAAMxZ,EAAWwZ,EAAc,WAC/B,OAAOxZ,EAAS,UAAW,CAC1B,oBAAqBhZ,GAEbsyB,GAAK,cAAetyB,CAAG,EAI/B,iBAAkB,CAAEA,EAAK0T,EAAQmY,IAEzBA,EAAQG,GAAmBH,EAAQJ,EAI3C,gBAAiB,CAAEkI,EAAaC,IAAgB,CAE/C,QAAU7pB,EAAK4pB,EAAa5S,EAAK4S,EAAcC,EAAY7pB,EAAKgX,EAAIhX,IAAQ,CAE3E,MAAMqqB,EAAMpb,EAAS,qBAAsBjP,CAAE,EAC7C0kB,EAAa0D,EAAW,EAAIiC,EAAKrB,EAAYC,CAAQ,EAErDb,EAAU,EAAE,aAAcM,CAAa,EACvCN,EAAU,EAAE,aAAcM,CAAa,EACvCN,EAAU,EAAE,aAAcM,CAAa,EACvCN,EAAU,YAAc,GAExB,QAAUvoB,EAAI0E,EAAQwO,EAAIxO,EAASC,EAAO3E,EAAIkT,EAAGlT,IAAO,CAEvD,MAAMsqB,EAAKhgB,EAAI,qBAAsBtK,CAAC,EACtC6kB,EAAa/L,EAAU,EAAIwR,EAAIlrB,EAAO4H,CAAG,EAEzC8R,EAAS,YAAc,GAEvB,MAAMnW,EAAOmW,EAAS,mBAAoByP,EAAWmB,EAAaE,CAAW,EAkB7E,GAjBKjnB,EAAOyf,IAEXuH,EAAgB,KAAMD,CAAW,EAE5BG,GAEJA,EAAgB,KAAMD,CAAW,EAIlCxH,EAAkBzf,EAClBqf,EAA0BhiB,EAC1B8pB,EAA+B3pB,GAK3BwC,EAAOif,EAEX,MAAO,EAIT,CAED,CAED,CACN,CAAM,CAEF,KAAO,CAGN,MAAMqI,EAAW5V,GAAauU,CAAa,EAC3C,QAAUzoB,EAAK,EAAGgX,EAAK8S,EAAU9pB,EAAKgX,EAAIhX,IAAQ,CAEjD0kB,EAAa0D,EAAW,EAAIpoB,EAAIgpB,EAAYC,CAAQ,EACpDb,EAAU,EAAE,aAAcM,CAAa,EACvCN,EAAU,EAAE,aAAcM,CAAa,EACvCN,EAAU,EAAE,aAAcM,CAAa,EACvCN,EAAU,YAAc,GAExB,QAAUvoB,EAAI0E,EAAQwO,EAAIxO,EAASC,EAAO3E,EAAIkT,EAAGlT,IAAO,CAEvD,MAAMsqB,EAAKhgB,EAAI,qBAAsBtK,CAAC,EACtC6kB,EAAa/L,EAAU,EAAIwR,EAAIlrB,EAAO4H,CAAG,EAEzC8R,EAAS,YAAc,GAEvB,MAAMnW,EAAOmW,EAAS,mBAAoByP,EAAWmB,EAAaE,CAAW,EAkB7E,GAjBKjnB,EAAOyf,IAEXuH,EAAgB,KAAMD,CAAW,EAE5BG,GAEJA,EAAgB,KAAMD,CAAW,EAIlCxH,EAAkBzf,EAClBqf,EAA0BhiB,EAC1B8pB,EAA+B3pB,GAK3BwC,EAAOif,EAEX,MAAO,EAIT,CAED,CAED,CAED,CAEH,CAEA,EAECF,GAAqB,iBAAkB5I,CAAQ,EAC/C4I,GAAqB,iBAAkB6G,CAAS,EAE3CnG,IAAoB,IAEjB,MAIDlK,EAAQ,MAMdA,EAAQ,MAAM,KAAMyR,CAAe,EAJnCzR,EAAQ,MAAQyR,EAAgB,MAAK,EAQtCzR,EAAQ,SAAWkK,EACnBlK,EAAQ,UAAY8J,EAEf7J,IAEGA,EAAQ,MACVA,EAAQ,MAAM,KAAM0R,CAAe,EADjB1R,EAAQ,MAAQ0R,EAAgB,MAAK,EAE5D1R,EAAQ,MAAM,aAAcmR,EAAU,EACtCK,EAAgB,aAAcL,EAAU,EACxCnR,EAAQ,SAAWwR,EAAgB,IAAKxR,EAAQ,KAAK,EAAG,OAAM,EAC9DA,EAAQ,UAAY2R,GAId5R,EAER,CC3PO,SAASuS,GAAyBC,EAAKC,EAAQC,EAAY,CAEjE,OAAKF,IAAQ,KAEL,MAIRA,EAAI,MAAM,aAAcC,EAAO,WAAW,EAC1CD,EAAI,SAAWA,EAAI,MAAM,WAAYE,EAAU,IAAI,MAAM,EACzDF,EAAI,OAASC,EAEND,EAER,CCWA,MAAMG,GAAuB,IAAI5K,GAC3B6K,GAAuB,IAAIC,EAAAA,IAC3BC,GAA6B,IAAIxU,EAAAA,QACjCyU,GAAiC,IAAIrb,EAAAA,QACrCsb,GAA8B,IAAI1U,EAAAA,QAClC2U,GAAW,CAAE,OAAQ,OAAQ,MAAM,EA6DlC,MAAMC,WAAgBpV,EAAY,CAkBxC,OAAO,UAAW1L,EAAKrP,EAAU,GAAK,CAErCA,EAAU,CACT,aAAc,GACd,GAAGA,CACN,EAEE,MAAM9C,EAAWmS,EAAI,SACf+gB,EAAW/gB,EAAI,OACf2I,EAAiB3I,EAAI,gBACrBghB,EAAiBnzB,EAAS,SAAQ,EAClCa,EAAS,CACd,QAAS,EACT,MAAO,KACP,MAAO,KACP,eAAgB,IACnB,EACE,OAAKiC,EAAQ,cAEZjC,EAAO,MAAQqyB,EAAS,IAAKrgB,GAAQA,EAAK,OAAO,EACjDhS,EAAO,MAAQsyB,EAAiBA,EAAe,MAAM,MAAK,EAAK,KAC/DtyB,EAAO,eAAiBia,EAAiBA,EAAe,MAAK,EAAK,OAIlEja,EAAO,MAAQqyB,EACfryB,EAAO,MAAQsyB,EAAiBA,EAAe,MAAQ,KACvDtyB,EAAO,eAAiBia,GAIlBja,CAER,CAeA,OAAO,YAAaK,EAAMlB,EAAU8C,EAAU,CAAA,EAAK,CAElDA,EAAU,CACT,SAAU,GACV,SAAU,EAAS5B,EAAK,eACxB,GAAG4B,CACN,EAEE,KAAM,CAAE,MAAAmE,EAAO,MAAAmQ,EAAO,eAAA0D,CAAc,EAAK5Z,EAIlCA,EAAK,UAEX,QAAQ,KACP,8IAEJ,EACGkyB,EAAehc,CAAK,GAIrB,MAAMjF,EAAM,IAAI8gB,GAASjzB,EAAU,CAAE,GAAG8C,EAAS,CAAEgH,EAAe,EAAI,GAAM,EAI5E,GAHAqI,EAAI,OAASiF,EACbjF,EAAI,gBAAkB2I,GAAkB,KAEnChY,EAAQ,SAAW,CAEvB,MAAMqwB,EAAiBnzB,EAAS,SAAQ,EACxC,GAAKmzB,IAAmB,KAAO,CAE9B,MAAME,EAAW,IAAIhX,EAAAA,gBAAiBnb,EAAK,MAAO,EAAG,EAAK,EAC1DlB,EAAS,SAAUqzB,CAAQ,CAE5B,MAAYF,EAAe,QAAUlsB,IAEpCksB,EAAe,MAAM,IAAKlsB,CAAK,EAC/BksB,EAAe,YAAc,GAI/B,CAEA,OAAOhhB,EAGP,SAASihB,EAAehc,EAAQ,CAE/B,QAAU4D,EAAY,EAAGA,EAAY5D,EAAM,OAAQ4D,IAAe,CAEjE,MAAMnI,EAAOuE,EAAO4D,CAAS,EACvBhP,EAAc,IAAI,YAAa6G,CAAI,EACnChH,EAAc,IAAI,YAAagH,CAAI,EAGzC,QAAUxB,EAAO,EAAG0J,EAAIlI,EAAK,WAAapJ,EAAgB4H,EAAO0J,EAAG1J,IAAU,CAE7E,MAAMI,EAAc/H,EAAkB2H,EAChCK,EAAc,EAAID,EACjB9F,EAAS+F,EAAa7F,KAG5BG,EAAayF,EAAc,GAAMzF,EAAayF,EAAc,CAAC,EAAK/H,EAAkB2H,EAItF,CAED,CAED,CAED,CAEA,IAAI,iBAAkB,CAErB,MAAO,EAER,CASA,IAAI,sBAAuB,CAE1B,OAAO,KAAK,qBAEb,CAEA,YAAarR,EAAU8C,EAAU,GAAK,CAEhCA,EAAQ,cAEZ,QAAQ,KAAM,mFAAmF,EACjGA,EAAU,CACT,GAAGA,EACH,eAAgBA,EAAQ,WAC5B,GAIE,MAAO9C,EAAU8C,CAAO,CAEzB,CAaA,qBAAsByJ,EAAS,CAE9B,OAAO,MAAM,sBAAuBA,CAAM,CAE3C,CAGA,qBAAsB1E,EAAGyS,EAAcC,EAAY,CAElD,MAAMva,EAAW,KAAK,SAChB8a,EAAiB,KAAK,gBACtB9T,EAAUhH,EAAS,WAAW,SAC9BiH,EAAQjH,EAAS,MAAQA,EAAS,MAAM,MAAQ,KAGhDszB,GADMxY,EAAiBA,EAAgBjT,CAAC,EAAKA,GAChC,EAEnB,IAAI0rB,EAAKD,EAAO,EACZ3jB,EAAK2jB,EAAO,EACZE,EAAKF,EAAO,EAEXrsB,IAEJssB,EAAKtsB,EAAOssB,CAAE,EACd5jB,EAAK1I,EAAO0I,CAAE,EACd6jB,EAAKvsB,EAAOusB,CAAE,GAIf,QAAUC,EAAK,EAAGA,EAAK,EAAGA,IAAQ,CAEjC,MAAMlrB,EAAIvB,EAASgsB,GAAUS,CAAE,CAAE,EAAIF,CAAE,EACjC5oB,EAAI3D,EAASgsB,GAAUS,CAAE,CAAE,EAAI9jB,CAAE,EACjCL,EAAItI,EAASgsB,GAAUS,CAAE,CAAE,EAAID,CAAE,EAEvC,IAAItV,EAAM3V,EACLoC,EAAIuT,IAAMA,EAAMvT,GAChB2E,EAAI4O,IAAMA,EAAM5O,GAErB,IAAI6O,EAAM5V,EACLoC,EAAIwT,IAAMA,EAAMxT,GAChB2E,EAAI6O,IAAMA,EAAM7O,GAGrBgL,EAAcC,EAAYkZ,CAAE,EAAKvV,EACjC5D,EAAcC,EAAYkZ,EAAK,CAAC,EAAKtV,CAEtC,CAEA,OAAO7D,CAER,CAMA,uBAAwB/N,EAAQC,EAAO8N,EAAe,CAErD,MAAMta,EAAW,KAAK,SAChB8a,EAAiB,KAAK,gBACtB9T,EAAUhH,EAAS,WAAW,SAC9BiH,EAAQjH,EAAS,MAAQA,EAAS,MAAM,MAAQ,KAChD0zB,EAAa1sB,EAAQ,WAE3B,GAAKuF,EAAS,GAAKC,EAAQD,EAAS+N,EAAa,OAASA,EAAa,OAAS,EAE/E,MAAM,IAAI,MAAO,oDAAoD,EAKtE,MAAMqZ,EAAS3sB,EAAQ,MAGjB4sB,EAAe5sB,EAAQ,QAAU,EACvC,IAAIyJ,EAAS,EACRzJ,EAAQ,+BAEZyJ,EAASzJ,EAAQ,KAAK,QAKvB,MAAM6sB,EAAU,CAAE,OAAQ,OAAQ,MAAM,EAClCC,EAAcxZ,EAAa,OAGjC,QAAUzS,EAAI0E,EAAQwO,EAAIxO,EAASC,EAAO3E,EAAIkT,EAAGlT,IAAO,CAGvD,MAAMyrB,GADMxY,EAAiBA,EAAgBjT,CAAC,EAAKA,GAChC,EACbksB,GAAsBlsB,EAAIisB,GAAgB,EAEhD,IAAIP,EAAKD,EAAO,EACZ3jB,EAAK2jB,EAAO,EACZE,EAAKF,EAAO,EAEXrsB,IAEJssB,EAAKtsB,EAAOssB,CAAE,EACd5jB,EAAK1I,EAAO0I,CAAE,EACd6jB,EAAKvsB,EAAOusB,CAAE,GAMRE,IAENH,EAAKA,EAAK9iB,EAASmjB,EACnBjkB,EAAKA,EAAKc,EAASmjB,EACnBJ,EAAKA,EAAK/iB,EAASmjB,GAIpB,QAAUH,EAAK,EAAGA,EAAK,EAAGA,IAAQ,CAEjC,IAAIlrB,EAAGoC,EAAG2E,EAELokB,GAEJnrB,EAAIvB,EAAS6sB,EAASJ,CAAE,CAAE,EAAIF,CAAE,EAChC5oB,EAAI3D,EAAS6sB,EAASJ,CAAE,CAAE,EAAI9jB,CAAE,EAChCL,EAAItI,EAAS6sB,EAASJ,CAAE,CAAE,EAAID,CAAE,IAIhCjrB,EAAIorB,EAAQJ,EAAKE,CAAE,EACnB9oB,EAAIgpB,EAAQhkB,EAAK8jB,CAAE,EACnBnkB,EAAIqkB,EAAQH,EAAKC,CAAE,GAIpB,IAAIvV,EAAM3V,EACLoC,EAAIuT,IAAMA,EAAMvT,GAChB2E,EAAI4O,IAAMA,EAAM5O,GAErB,IAAI6O,EAAM5V,EACLoC,EAAIwT,IAAMA,EAAMxT,GAChB2E,EAAI6O,IAAMA,EAAM7O,GAKrB,MAAM0kB,GAAgB7V,EAAMD,GAAQ,EAC9B+V,EAAMR,EAAK,EACjBnZ,EAAcyZ,EAAoBE,EAAM,CAAC,EAAK/V,EAAM8V,EACpD1Z,EAAcyZ,EAAoBE,EAAM,GAAMD,GAAgB,KAAK,IAAK9V,CAAG,EAAK8V,GAAgBnqB,EAEjG,CAED,CAEA,OAAOyQ,CAER,CAWA,gBAAiBkY,EAAQC,EAAWjD,EAAa,CAAA,EAAK,CAErD,KAAM,CAAE,SAAAvvB,CAAQ,EAAKuyB,EACrB,GAAKvyB,IAAa,OAEjB,OAID6yB,GAAe,KAAMN,EAAO,WAAW,EAAG,OAAM,EAChDG,GAAK,KAAMF,EAAU,GAAG,EAAG,aAAcK,EAAc,EAEvDC,GAAY,mBAAoBP,EAAO,WAAW,EAClDK,GAAW,KAAMF,GAAK,SAAS,EAAG,SAAUI,EAAW,EAEvD,MAAMmB,EAAcrB,GAAW,OAAM,EAC/BxH,EAAOoH,EAAU,KAAOyB,EACxB5I,EAAMmH,EAAU,IAAMyB,EAE5B,GAAKzB,EAAU,eAAiB,GAAO,CAEtC,IAAIF,EAAM,KAAK,aAAcI,GAAM1yB,EAAUorB,EAAMC,CAAG,EACtDiH,EAAMD,GAAyBC,EAAKC,EAAQC,CAAS,EAChDF,GAEJ/C,EAAW,KAAM+C,CAAG,CAItB,KAAO,CAEN,MAAM4B,EAAO,KAAK,QAASxB,GAAM1yB,EAAUorB,EAAMC,CAAG,EACpD,QAAUzjB,EAAI,EAAGkT,EAAIoZ,EAAK,OAAQtsB,EAAIkT,EAAGlT,IAAO,CAE/C,MAAM0qB,EAAMD,GAAyB6B,EAAMtsB,CAAC,EAAI2qB,EAAQC,CAAS,EAC5DF,GAEJ/C,EAAW,KAAM+C,CAAG,CAItB,CAED,CAEA,OAAO/C,CAER,CAUA,MAAOrC,EAAc,KAAO,CAG3B,OADkB,KAAK,SAAW4E,GAAiB7E,IACjC,KAAMC,CAAW,CAEpC,CAuBA,QAASnC,EAAKmB,EAAiBiI,EAAAA,UAAW/I,EAAO,EAAGC,EAAM,IAAW,CAEpE,MAAMlU,EAAQ,KAAK,OACboY,EAAa,CAAA,EACb6E,EAAc,KAAK,SAAWrC,GAAmBzC,GACvD,QAAU1nB,EAAI,EAAGkT,EAAI3D,EAAM,OAAQvP,EAAIkT,EAAGlT,IAEzCwsB,EAAa,KAAMxsB,EAAGskB,EAAgBnB,EAAKwE,EAAYnE,EAAMC,CAAG,EAIjE,OAAOkE,CAER,CAaA,aAAcxE,EAAKmB,EAAiBiI,EAAAA,UAAW/I,EAAO,EAAGC,EAAM,IAAW,CAEzE,MAAMlU,EAAQ,KAAK,OACnB,IAAIkd,EAAgB,KAEpB,MAAMC,EAAmB,KAAK,SAAWtC,GAAwBpC,GACjE,QAAUhoB,EAAI,EAAGkT,EAAI3D,EAAM,OAAQvP,EAAIkT,EAAGlT,IAAO,CAEhD,MAAMhH,EAAS0zB,EAAkB,KAAM1sB,EAAGskB,EAAgBnB,EAAKK,EAAMC,CAAG,EACnEzqB,GAAU,OAAUyzB,GAAiB,MAAQzzB,EAAO,SAAWyzB,EAAc,YAEjFA,EAAgBzzB,EAIlB,CAEA,OAAOyzB,CAER,CAcA,mBAAoB7D,EAAe+D,EAAa,CAE/C,IAAI3zB,EAAS,GACb,MAAMuW,EAAQ,KAAK,OACbqd,EAAyB,KAAK,SAAWvC,GAA8B1B,GAC7E,QAAU3oB,EAAI,EAAGkT,EAAI3D,EAAM,OAAQvP,EAAIkT,IAEtCla,EAAS4zB,EAAwB,KAAM5sB,EAAG4oB,EAAe+D,CAAU,EAE9D,CAAA3zB,GAJoCgH,IAIzC,CAQD,OAAOhH,CAER,CAeA,UAAW2a,EAAY,CAEtB,MAAMmF,EAAW4I,GAAqB,aAAY,EAC5C1oB,EAAS,MAAM,UACpB,CACC,GAAG2a,EACH,oBAAqBA,EAAU,mBAC/B,iBAAkBmF,EAIlB,QAAS,KAAK,SAAW2O,GAAgCtC,EAC7D,CACA,EACE,OAAAzD,GAAqB,iBAAkB5I,CAAQ,EAExC9f,CAER,CAkBA,QAASoW,EAAUC,EAAesE,EAAY,CAE7C,GAAI,CACH,iBAAArE,EACA,oBAAAud,CACH,EAAMlZ,EAEJ,MAAMmZ,EAAYpL,GAAqB,aAAY,EAC7CqL,EAAa,KAAK,SAAS,MAC3BC,EAAgB,KAAK,SAAS,WAAW,SACzCC,EAAkB,KAAK,SAC5B/sB,GAAM,CAGL,MAAMoqB,EAAK,KAAK,qBAAsBpqB,CAAE,EACxC2kB,EAAaiI,EAAWxC,EAAK,EAAGyC,EAAYC,CAAa,CAE1D,EACA9sB,GAAM,CAEL2kB,EAAaiI,EAAW5sB,EAAK,EAAG6sB,EAAYC,CAAa,CAE1D,EAEKzE,EAAY7G,GAAqB,aAAY,EAC7CwL,EAAa9d,EAAS,SAAS,MAC/B+d,EAAgB/d,EAAS,SAAS,WAAW,SAC7Cge,EAAkBhe,EAAS,SAChCjP,GAAM,CAEL,MAAMqqB,EAAMpb,EAAS,qBAAsBjP,CAAE,EAC7C0kB,EAAa0D,EAAWiC,EAAM,EAAG0C,EAAYC,CAAa,CAE3D,EACAhtB,GAAM,CAEL0kB,EAAa0D,EAAWpoB,EAAK,EAAG+sB,EAAYC,CAAa,CAE1D,EAGD,GAAKN,EAAsB,CAE1B,GAAK,EAAIzd,aAAoBgc,IAE5B,MAAM,IAAI,MAAO,gFAAgF,EAIlG,MAAMiC,EAA6B,CAAEC,EAASC,EAAQC,EAASC,EAAQhd,EAAQid,EAAYhd,EAAQid,IAAgB,CAElH,QAAUxtB,EAAKqtB,EAASrW,EAAKqW,EAAUC,EAAQttB,EAAKgX,EAAIhX,IAAQ,CAE/DitB,EAAiBjtB,CAAE,EAEnBooB,EAAU,EAAE,aAAclZ,CAAa,EACvCkZ,EAAU,EAAE,aAAclZ,CAAa,EACvCkZ,EAAU,EAAE,aAAclZ,CAAa,EACvCkZ,EAAU,YAAc,GAExB,QAAUroB,EAAKotB,EAASpW,EAAKoW,EAAUC,EAAQrtB,EAAKgX,EAAIhX,IAMvD,GAJA+sB,EAAiB/sB,CAAE,EAEnB4sB,EAAU,YAAc,GAEnBD,EAAqBC,EAAWvE,EAAWroB,EAAIC,EAAIsQ,EAAQid,EAAYhd,EAAQid,GAEnF,MAAO,EAMV,CAEA,MAAO,EAER,EAEA,GAAKre,EAAmB,CAEvB,MAAMse,EAA2Bte,EACjCA,EAAmB,SAAWge,EAASC,EAAQC,EAASC,EAAQhd,EAAQid,EAAYhd,EAAQid,EAAa,CAExG,OAAOC,EAA0BN,EAASC,EAAQC,EAASC,EAAQhd,EAAQid,EAAYhd,EAAQid,GAMxF,GAJCN,EAA4BC,EAASC,EAAQC,EAASC,EAAQhd,EAAQid,EAAYhd,EAAQid,CAAU,CAM7G,CAED,MAECre,EAAmB+d,CAIrB,CAEA,OAAO,MAAM,QAASje,EAAUC,EAAe,CAAE,iBAAAC,CAAgB,CAAE,CAEpE,CAcA,cAAelZ,EAAKy3B,EAAY,CAE/B,OAAAhD,GAAK,IAAKz0B,EAAI,IAAKA,EAAI,IAAKy3B,CAAS,EACrChD,GAAK,YAAc,GAEZ,KAAK,UACX,CACC,iBAAkBz0B,GAAOy0B,GAAK,cAAez0B,CAAG,EAChD,mBAAoB8rB,GAAO2I,GAAK,mBAAoB3I,CAAG,CAC3D,CACA,CAEC,CAQA,iBAAkBrJ,EAAS,CAE1B,OAAO,KAAK,UACX,CACC,iBAAkBziB,GAAOyiB,EAAO,cAAeziB,CAAG,EAClD,mBAAoB8rB,GAAOA,EAAI,iBAAkBrJ,CAAM,CAC3D,CACA,CAEC,CA+BA,uBAAwB+P,EAAeC,EAAe3Q,EAAU,CAAA,EAAKC,EAAU,CAAA,EAAKyJ,EAAe,EAAGC,EAAe,IAAW,CAG/H,OADmC,KAAK,SAAW0I,GAAkCd,IAEpF,KACAb,EACAC,EACA3Q,EACAC,EACAyJ,EACAC,CACH,CAEC,CAqBA,oBAAqB5E,EAAO3a,EAAS,CAAA,EAAKsf,EAAe,EAAGC,EAAe,IAAW,CAErF,OAAOF,GACN,KACA1E,EACA3a,EACAsf,EACAC,CACH,CAEC,CAED,CC/1BA,SAASiM,GAAqBnpB,EAAQ,CAErC,OAASA,EAAK,CAEb,IAAK,GAAG,MAAO,IACf,IAAK,GAAG,MAAO,KACf,IAAK,GAAG,MAAO,OACf,IAAK,GAAG,MAAO,MAEjB,CAEC,MAAM,IAAI,KAEX,CAEA,SAASopB,GAAeppB,EAAQ,CAE/B,OAASA,EAAK,CAEb,IAAK,GAAG,OAAOqpB,EAAAA,UACf,IAAK,GAAG,OAAOC,EAAAA,SACf,IAAK,GAAG,OAAOC,EAAAA,WACf,IAAK,GAAG,OAAOA,EAAAA,UAEjB,CAEA,CAEA,SAASC,GAAkBxpB,EAAQ,CAElC,OAASA,EAAK,CAEb,IAAK,GAAG,OAAOypB,EAAAA,iBACf,IAAK,GAAG,OAAOC,EAAAA,gBACf,IAAK,GAAG,OAAOC,EAAAA,kBACf,IAAK,GAAG,OAAOA,EAAAA,iBAEjB,CAEA,CAYO,MAAMC,WAA+BC,EAAAA,WAAY,CAEvD,aAAc,CAEb,MAAK,EACL,KAAK,UAAYC,EAAAA,cACjB,KAAK,UAAYA,EAAAA,cACjB,KAAK,gBAAkB,GAUvB,KAAK,iBAAmB,KACxB,KAAK,YAAc,IAEpB,CAYA,WAAYC,EAAO,CAElB,MAAMC,EAAmB,KAAK,iBACxBC,EAAmBF,EAAK,SACxBG,EAAgBH,EAAK,MAC3B,GAAKC,IAAqB,KAAO,CAEhC,GAAOC,EAAmBC,EAAkBF,IAAqB,EAEhE,MAAM,IAAI,MAAO,iFAAiF,EAInGD,EAAK,SAAWC,EAChBD,EAAK,MAAQG,EAAgBD,EAAmBD,CAEjD,CAEA,MAAMG,EAAWJ,EAAK,SAChB/pB,EAAQ+pB,EAAK,MACb7C,EAAa6C,EAAK,WAClBK,EAAqBL,EAAK,MAAM,YAChC3Y,EAAYgZ,EAAmB,kBACrC,IAAIC,EAAa,KAAK,YAClBC,EAAcH,EAGlB,GAAKE,IAAe,KAEnB,OAASD,EAAkB,CAE1B,KAAK,aACJC,EAAaE,EAAAA,UACb,MAED,KAAK,WACL,KAAK,YACL,KAAK,YACJF,EAAaG,EAAAA,gBACb,MAED,KAAK,UACL,KAAK,WACL,KAAK,WACJH,EAAaI,EAAAA,QACb,KAEL,CAKE,IAAIC,EAAM35B,EAAQ45B,EAAgBC,EAC9BC,EAAiB1B,GAAqBgB,CAAQ,EAClD,OAASE,EAAU,CAElB,KAAKE,EAAAA,UACJI,EAAiB,EACjB55B,EAASq4B,GAAee,CAAQ,EAE3BjD,GAAc9V,IAAc,GAEhCwZ,EAAmBR,EACnBS,GAAkB,IAEbT,IAAuB,WAE3BM,EAAOI,EAAAA,kBAIPJ,EAAOK,EAAAA,SACPF,GAAkB,YAMnBD,EAAmB,aACnBC,GAAkB,MAClBH,EAAOH,EAAAA,WAIR,MAED,KAAKE,EAAAA,QACJI,GAAkBzZ,EAAY,EAAI,IAClCuZ,EAAiBzD,EAAa,KAAK,IAAK,EAAGkD,EAAmB,kBAAoB,EAAI,CAAC,EAAK,EAC5Fr5B,EAASy4B,GAAkBW,CAAQ,EAE9B/Y,IAAc,GAElBwZ,EAAmB,UACnBF,EAAOK,EAAAA,UAEI3Z,IAAc,GAEzBwZ,EAAmB,WACnBF,EAAOM,EAAAA,YAIPJ,EAAmB,WACnBF,EAAOD,EAAAA,SAIR,MAED,KAAKD,EAAAA,gBACJK,GAAkBzZ,EAAY,EAAI,KAClCuZ,EAAiBzD,EAAa,KAAK,IAAK,EAAGkD,EAAmB,kBAAoB,EAAI,CAAC,EAAK,EAC5Fr5B,EAASy4B,GAAkBW,CAAQ,EAE9B/Y,IAAc,GAElBwZ,EAAmB,WACnBF,EAAOI,EAAAA,kBAEI1Z,IAAc,GAEzBwZ,EAAmB,YACnBF,EAAOO,EAAAA,oBAIPL,EAAmB,YACnBF,EAAOF,EAAAA,iBAIR,KAEJ,CAIOF,IAAgB,IAAOv5B,IAAWw4B,EAAAA,YAAcx4B,IAAW44B,EAAAA,qBAE/DW,EAAc,GAKf,MAAMY,EAAY,KAAK,KAAM,KAAK,KAAMlrB,CAAK,CAAE,GAAM,EAC/C2I,EAAS2hB,EAAcY,EAAYA,EACnCC,EAAY,IAAIP,EAAkBjiB,CAAM,EAGxCyiB,EAAqBrB,EAAK,WAChCA,EAAK,WAAa,GAClB,QAAU1uB,EAAI,EAAGA,EAAI2E,EAAO3E,IAAO,CAElC,MAAMgwB,EAAKf,EAAcjvB,EACzB8vB,EAAWE,CAAE,EAAKtB,EAAK,KAAM1uB,CAAC,EAAKsvB,EAE9BR,GAAY,IAEhBgB,EAAWE,EAAK,CAAC,EAAKtB,EAAK,KAAM1uB,CAAC,EAAKsvB,GAInCR,GAAY,IAEhBgB,EAAWE,EAAK,CAAC,EAAKtB,EAAK,KAAM1uB,CAAC,EAAKsvB,EAElCL,IAAgB,IAEpBa,EAAWE,EAAK,CAAC,EAAK,IAMnBlB,GAAY,IAEhBgB,EAAWE,EAAK,CAAC,EAAKtB,EAAK,KAAM1uB,CAAC,EAAKsvB,EAIzC,CAEAZ,EAAK,WAAaqB,EAElB,KAAK,eAAiBP,EACtB,KAAK,OAAS95B,EACd,KAAK,KAAO25B,EACZ,KAAK,MAAM,MAAQQ,EACnB,KAAK,MAAM,OAASA,EACpB,KAAK,MAAM,KAAOC,EAClB,KAAK,YAAc,GACnB,KAAK,QAAO,EAEZpB,EAAK,SAAWE,EAChBF,EAAK,MAAQG,CAEd,CAED,CAOO,MAAMoB,WAAmC1B,EAAuB,CAEtE,aAAc,CAEb,MAAK,EACL,KAAK,YAAcY,EAAAA,eAEpB,CAED,CAwBO,MAAMe,WAAoC3B,EAAuB,CAEvE,aAAc,CAEb,MAAK,EACL,KAAK,YAAcW,EAAAA,SAEpB,CAED,CCjUO,MAAMiB,EAAqB,CAEjC,aAAc,CAEb,KAAK,MAAQ,IAAIF,GACjB,KAAK,SAAW,IAAIC,GACpB,KAAK,UAAY,IAAI1B,cACrB,KAAK,YAAc,IAAIA,cACvB,KAAK,iBAAmB,KAExB,KAAK,MAAM,iBAAmB,CAE/B,CAQA,WAAYlkB,EAAM,CAEjB,KAAM,CAAE,SAAAnS,CAAQ,EAAKmS,EAMrB,GALA8lB,GAAe9lB,EAAK,KAAK,UAAW,KAAK,WAAW,EAEpD,KAAK,SAAS,WAAYnS,EAAS,WAAW,QAAQ,EAGjDmS,EAAI,SAAW,CAEnB,MAAM2I,EAAiB3I,EAAI,gBAC3B,GACC,KAAK,mBAAqB,MAC1B,KAAK,iBAAiB,QAAU2I,EAAe,OAG/C,GAAK9a,EAAS,MAEb,KAAK,iBAAmBA,EAAS,MAAM,MAAK,MAEtC,CAEN,MAAMkK,EAAQiS,GAAeH,GAAgBhc,CAAQ,CAAE,EACvD,KAAK,iBAAmB,IAAIqc,EAAAA,gBAAiBnS,EAAO,EAAG,EAAK,CAE7D,CAIDguB,GAAkBl4B,EAAU8a,EAAgB,KAAK,gBAAgB,EACjE,KAAK,MAAM,WAAY,KAAK,gBAAgB,CAE7C,MAEC,KAAK,MAAM,WAAY9a,EAAS,KAAK,CAIvC,CAOA,SAAU,CAET,KAAM,CAAE,MAAAiH,EAAO,SAAA2kB,EAAU,UAAAuM,EAAW,YAAAC,CAAW,EAAK,KAE/CnxB,GAAQA,EAAM,QAAO,EACrB2kB,GAAWA,EAAS,QAAO,EAC3BuM,GAAYA,EAAU,QAAO,EAC7BC,GAAcA,EAAY,QAAO,CAEvC,CAED,CAEA,SAASF,GAAkBl4B,EAAU8a,EAAgB3Q,EAAS,CAE7D,MAAMkuB,EAAWluB,EAAO,MAClBmuB,EAAat4B,EAAS,MAAQA,EAAS,MAAM,MAAQ,KAC3D,QAAU6H,EAAI,EAAGkT,EAAID,EAAe,OAAQjT,EAAIkT,EAAGlT,IAAO,CAEzD,MAAM0wB,EAAK,EAAI1wB,EACT2wB,EAAK,EAAI1d,EAAgBjT,CAAC,EAChC,QAAUyH,EAAI,EAAGA,EAAI,EAAGA,IAEvB+oB,EAAUE,EAAKjpB,CAAC,EAAKgpB,EAAaA,EAAYE,EAAKlpB,GAAMkpB,EAAKlpB,CAIhE,CAED,CAEA,SAAS2oB,GAAe9lB,EAAKsmB,EAAeC,EAAkB,CAE7D,MAAMthB,EAAQjF,EAAI,OAElB,GAAKiF,EAAM,SAAW,EAErB,MAAM,IAAI,MAAO,sDAAsD,EAIxE,MAAMvE,EAAOuE,EAAO,CAAC,EACfvL,EAAc,IAAI,YAAagH,CAAI,EACnC7G,EAAc,IAAI,YAAa6G,CAAI,EACnC5B,EAAe,IAAI,aAAc4B,CAAI,EAIrCkB,EAAYlB,EAAK,WAAapJ,EAC9BkvB,EAAkB,EAAI,KAAK,KAAM,KAAK,KAAM5kB,EAAY,EAAG,EAC3D6kB,EAAc,IAAI,aAAc,EAAID,EAAkBA,CAAe,EAErEE,EAAoB,KAAK,KAAM,KAAK,KAAM9kB,EAAW,EACrD+kB,EAAgB,IAAI,YAAa,EAAID,EAAoBA,CAAiB,EAEhF,QAAUhxB,EAAI,EAAGA,EAAIkM,EAAWlM,IAAO,CAEtC,MAAMoC,EAAcpC,EAAI4B,EAAiB,EACnC+L,EAAcvL,EAAc,EAC5B8uB,EAAmC9uB,EACzC,QAAUU,EAAI,EAAGA,EAAI,EAAGA,IAEvBiuB,EAAa,EAAI/wB,EAAI,EAAI8C,CAAC,EAAKsG,EAAc8nB,EAAc,EAAIpuB,CAAC,EAChEiuB,EAAa,EAAI/wB,EAAI,EAAI8C,CAAC,EAAKsG,EAAc8nB,EAAc,EAAIpuB,CAAC,EAIjE,GAAKgB,EAAS6J,EAAa3J,GAAgB,CAE1C,MAAMW,EAAQP,EAAOuJ,EAAa3J,CAAW,EACvCU,EAAST,EAAQ7B,EAAa+B,CAAW,EAEzCgtB,EAAkBpvB,GAAmB4C,EAC3CssB,EAAejxB,EAAI,EAAI,CAAC,EAAKmxB,EAC7BF,EAAejxB,EAAI,EAAI,CAAC,EAAK0E,CAE9B,KAAO,CAEN,MAAM0sB,EAAiBjtB,EAAa/B,EAAc,CAAC,EAC7C4H,EAAYxF,GAAYpC,EAAa+B,CAAW,EAEtD8sB,EAAejxB,EAAI,EAAI,CAAC,EAAKgK,EAC7BinB,EAAejxB,EAAI,EAAI,CAAC,EAAKoxB,CAE9B,CAED,CAEAR,EAAc,MAAM,KAAOG,EAC3BH,EAAc,MAAM,MAAQE,EAC5BF,EAAc,MAAM,OAASE,EAC7BF,EAAc,OAAS1C,EAAAA,WACvB0C,EAAc,KAAO1B,EAAAA,UACrB0B,EAAc,eAAiB,UAC/BA,EAAc,UAAYnC,EAAAA,cAC1BmC,EAAc,UAAYnC,EAAAA,cAC1BmC,EAAc,gBAAkB,GAChCA,EAAc,YAAc,GAC5BA,EAAc,QAAO,EAErBC,EAAgB,MAAM,KAAOI,EAC7BJ,EAAgB,MAAM,MAAQG,EAC9BH,EAAgB,MAAM,OAASG,EAC/BH,EAAgB,OAASxC,EAAAA,gBACzBwC,EAAgB,KAAO1B,EAAAA,gBACvB0B,EAAgB,eAAiB,SACjCA,EAAgB,UAAYpC,EAAAA,cAC5BoC,EAAgB,UAAYpC,EAAAA,cAC5BoC,EAAgB,gBAAkB,GAClCA,EAAgB,YAAc,GAC9BA,EAAgB,QAAO,CAExB,CCtMO,MAAMQ,GAA6B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,ECA7BC,GAA8B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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","x_google_ignoreList":[11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57]}
|