@joshtol/emotive-engine 3.2.1 → 3.2.3

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.
@@ -1,2 +1,2 @@
1
- import*as e from"three";import{Vector2 as t,WebGLRenderTarget as i,HalfFloatType as n,RGBAFormat as a,LinearFilter as s,ShaderMaterial as o,Vector3 as r,AdditiveBlending as l,Color as h,MeshBasicMaterial as c}from"three";import{EffectComposer as u}from"three/examples/jsm/postprocessing/EffectComposer.js";import{RenderPass as d}from"three/examples/jsm/postprocessing/RenderPass.js";import{Pass as m,FullScreenQuad as p}from"three/examples/jsm/postprocessing/Pass.js";import{OrbitControls as g}from"three/examples/jsm/controls/OrbitControls.js";import{OBJLoader as f}from"three/examples/jsm/loaders/OBJLoader.js";new t(.5,.5),new t(.5,.5);class y extends m{constructor(e,u,d,m){super(),this.strength=void 0!==u?u:1,this.radius=d,this.threshold=m,this.resolution=void 0!==e?new t(e.x,e.y):new t(256,256);const g={minFilter:s,magFilter:s,format:a,type:n};this.renderTargetsHorizontal=[],this.renderTargetsVertical=[],this.nMips=5;let f=Math.round(.75*this.resolution.x),y=Math.round(.75*this.resolution.y);this.renderTargetBright=new i(f,y,g),this.renderTargetBright.texture.name="UnrealBloomPassAlpha.bright",this.renderTargetBright.texture.generateMipmaps=!1;for(let e=0;e<this.nMips;e++){const t=new i(f,y,g);t.texture.name=`UnrealBloomPassAlpha.h${e}`,t.texture.generateMipmaps=!1,this.renderTargetsHorizontal.push(t);const n=new i(f,y,g);n.texture.name=`UnrealBloomPassAlpha.v${e}`,n.texture.generateMipmaps=!1,this.renderTargetsVertical.push(n),f=Math.round(f/2),y=Math.round(y/2)}this.highPassUniforms={tDiffuse:{value:null},luminosityThreshold:{value:m},smoothWidth:{value:.01}},this.materialHighPassFilter=new o({uniforms:this.highPassUniforms,vertexShader:"\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }",fragmentShader:"\n uniform sampler2D tDiffuse;\n uniform float luminosityThreshold;\n uniform float smoothWidth;\n varying vec2 vUv;\n\n void main() {\n vec4 texel = texture2D(tDiffuse, vUv);\n vec3 luma = vec3(0.299, 0.587, 0.114);\n float v = dot(texel.xyz, luma);\n float alpha = smoothstep(luminosityThreshold, luminosityThreshold + smoothWidth, v);\n\n // CRITICAL: Preserve original alpha, only filter by luminosity\n gl_FragColor = vec4(texel.rgb * alpha, texel.a);\n }"}),this.separableBlurMaterials=[];const v=[3,5,7,9,11];f=Math.round(.75*this.resolution.x),y=Math.round(.75*this.resolution.y);for(let e=0;e<this.nMips;e++)this.separableBlurMaterials.push(this.getSeperableBlurMaterial(v[e])),this.separableBlurMaterials[e].uniforms.texSize.value=new t(f,y),f=Math.round(f/2),y=Math.round(y/2);this.compositeMaterial=this.getCompositeMaterial(this.nMips),this.compositeMaterial.uniforms.blurTexture1.value=this.renderTargetsVertical[0].texture,this.compositeMaterial.uniforms.blurTexture2.value=this.renderTargetsVertical[1].texture,this.compositeMaterial.uniforms.blurTexture3.value=this.renderTargetsVertical[2].texture,this.compositeMaterial.uniforms.blurTexture4.value=this.renderTargetsVertical[3].texture,this.compositeMaterial.uniforms.blurTexture5.value=this.renderTargetsVertical[4].texture,this.compositeMaterial.uniforms.bloomStrength.value=u,this.compositeMaterial.uniforms.bloomRadius.value=.1,this.compositeMaterial.uniforms.bloomFactors.value=[1,.8,.6,.4,.2],this.bloomTintColors=[new r(1,1,1),new r(1,1,1),new r(1,1,1),new r(1,1,1),new r(1,1,1)],this.compositeMaterial.uniforms.bloomTintColors.value=this.bloomTintColors,this.materialCopy=new o({uniforms:{tDiffuse:{value:null}},vertexShader:"\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }",fragmentShader:"\n uniform sampler2D tDiffuse;\n varying vec2 vUv;\n void main() {\n gl_FragColor = texture2D(tDiffuse, vUv);\n }",blending:l,depthTest:!1,depthWrite:!1,transparent:!0}),this.enabled=!0,this.needsSwap=!1,this._oldClearColor=new h,this.oldClearAlpha=1,this.clearColor=new h(0,0,0),this.basic=new c({transparent:!0,depthTest:!1,depthWrite:!1}),this.fsQuad=new p(null)}dispose(){if(this.renderTargetsHorizontal)for(let e=0;e<this.renderTargetsHorizontal.length;e++)this.renderTargetsHorizontal[e]?.dispose();if(this.renderTargetsVertical)for(let e=0;e<this.renderTargetsVertical.length;e++)this.renderTargetsVertical[e]?.dispose();if(this.renderTargetBright?.dispose(),this.separableBlurMaterials)for(let e=0;e<this.separableBlurMaterials.length;e++)this.separableBlurMaterials[e]?.dispose();this.compositeMaterial?.dispose(),this.blendMaterial?.dispose(),this.basic?.dispose(),this.fsQuad?.dispose()}clearBloomBuffers(e){const t=e.getRenderTarget(),i=e.getClearColor(this._oldClearColor),n=e.getClearAlpha();e.setClearColor(0,0),e.setRenderTarget(this.renderTargetBright),e.clear();for(let t=0;t<this.renderTargetsHorizontal.length;t++)e.setRenderTarget(this.renderTargetsHorizontal[t]),e.clear();for(let t=0;t<this.renderTargetsVertical.length;t++)e.setRenderTarget(this.renderTargetsVertical[t]),e.clear();e.setRenderTarget(t),e.setClearColor(i,n)}setSize(e,i){let n=Math.round(.75*e),a=Math.round(.75*i);this.renderTargetBright.setSize(n,a);for(let e=0;e<this.nMips;e++)this.renderTargetsHorizontal[e].setSize(n,a),this.renderTargetsVertical[e].setSize(n,a),this.separableBlurMaterials[e].uniforms.texSize.value=new t(n,a),n=Math.round(n/2),a=Math.round(a/2)}render(e,t,i,n,a){e.getClearColor(this._oldClearColor),this.oldClearAlpha=e.getClearAlpha();const s=e.autoClear;e.autoClear=!1,e.setClearColor(this.clearColor,0),a&&e.state.buffers.stencil.setTest(!1),this.renderToScreen&&!this.skipBaseCopy&&(this.fsQuad.material=this.basic,this.basic.map=i.texture,e.setRenderTarget(null),this.fsQuad.render(e)),this.highPassUniforms.tDiffuse.value=i.texture,this.highPassUniforms.luminosityThreshold.value=this.threshold,this.fsQuad.material=this.materialHighPassFilter,e.setRenderTarget(this.renderTargetBright),e.clear(),this.fsQuad.render(e);let o=this.renderTargetBright;for(let t=0;t<this.nMips;t++)this.fsQuad.material=this.separableBlurMaterials[t],this.separableBlurMaterials[t].uniforms.colorTexture.value=o.texture,this.separableBlurMaterials[t].uniforms.direction.value=y.BlurDirectionX,e.setRenderTarget(this.renderTargetsHorizontal[t]),e.clear(),this.fsQuad.render(e),this.separableBlurMaterials[t].uniforms.colorTexture.value=this.renderTargetsHorizontal[t].texture,this.separableBlurMaterials[t].uniforms.direction.value=y.BlurDirectionY,e.setRenderTarget(this.renderTargetsVertical[t]),e.clear(),this.fsQuad.render(e),o=this.renderTargetsVertical[t];this.fsQuad.material=this.compositeMaterial,this.compositeMaterial.uniforms.bloomStrength.value=this.strength,this.compositeMaterial.uniforms.bloomRadius.value=this.radius,this.compositeMaterial.uniforms.bloomTintColors.value=this.bloomTintColors,e.setRenderTarget(this.renderTargetsHorizontal[0]),e.clear(),this.fsQuad.render(e),this.fsQuad.material=this.materialCopy,this.materialCopy.uniforms.tDiffuse.value=this.renderTargetsHorizontal[0].texture,a&&e.state.buffers.stencil.setTest(!0),this.renderToScreen?(e.setRenderTarget(null),this.fsQuad.render(e)):(e.setRenderTarget(i),this.fsQuad.render(e)),e.setClearColor(this._oldClearColor,this.oldClearAlpha),e.autoClear=s}getSeperableBlurMaterial(e){return new o({defines:{MAX_RADIUS:e},uniforms:{colorTexture:{value:null},texSize:{value:new t(.5,.5)},direction:{value:new t(.5,.5)},kernelRadius:{value:1}},vertexShader:"\n varying vec2 vUv;\n\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n }",fragmentShader:"\n #include <common>\n varying vec2 vUv;\n uniform sampler2D colorTexture;\n uniform vec2 texSize;\n uniform vec2 direction;\n uniform float kernelRadius;\n\n float gaussianPdf(in float x, in float sigma) {\n return 0.39894 * exp( -0.5 * x * x / ( sigma * sigma ) ) / sigma;\n }\n\n void main() {\n vec2 invSize = 1.0 / texSize;\n float sigma = kernelRadius / 2.0;\n float weightSum = gaussianPdf(0.0, sigma);\n\n // CRITICAL: Accumulate RGB and alpha SEPARATELY\n // Include center pixel for BOTH RGB and alpha\n vec4 centerPixel = texture2D(colorTexture, vUv);\n vec3 diffuseSum = centerPixel.rgb * weightSum;\n float alphaSum = centerPixel.a * weightSum;\n\n vec2 delta = direction * invSize * kernelRadius / float(MAX_RADIUS);\n\n for( int i = 1; i < MAX_RADIUS; i ++ ) {\n float x = kernelRadius * float(i) / float(MAX_RADIUS);\n float w = gaussianPdf(x, sigma);\n\n vec2 uvOffset = delta * float(i);\n vec4 sample1 = texture2D(colorTexture, vUv + uvOffset);\n vec4 sample2 = texture2D(colorTexture, vUv - uvOffset);\n\n // Accumulate RGB and alpha separately\n diffuseSum += (sample1.rgb + sample2.rgb) * w;\n alphaSum += (sample1.a + sample2.a) * w;\n weightSum += 2.0 * w;\n }\n\n // Output with separately normalized alpha\n gl_FragColor = vec4(diffuseSum / weightSum, alphaSum / weightSum);\n }"})}getCompositeMaterial(e){return new o({uniforms:{blurTexture1:{value:null},blurTexture2:{value:null},blurTexture3:{value:null},blurTexture4:{value:null},blurTexture5:{value:null},bloomStrength:{value:1},bloomFactors:{value:null},bloomTintColors:{value:null},bloomRadius:{value:0}},vertexShader:"\n varying vec2 vUv;\n\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n }",fragmentShader:"\n varying vec2 vUv;\n uniform sampler2D blurTexture1;\n uniform sampler2D blurTexture2;\n uniform sampler2D blurTexture3;\n uniform sampler2D blurTexture4;\n uniform sampler2D blurTexture5;\n uniform float bloomStrength;\n uniform float bloomRadius;\n uniform float bloomFactors[5];\n uniform vec3 bloomTintColors[5];\n\n float lerpBloomFactor(const in float factor) {\n float mirrorFactor = 1.2 - factor;\n return mix(factor, mirrorFactor, bloomRadius);\n }\n\n void main() {\n // ALPHA PRESERVATION: Sample all textures and preserve their alpha\n vec4 sample1 = texture2D(blurTexture1, vUv);\n vec4 sample2 = texture2D(blurTexture2, vUv);\n vec4 sample3 = texture2D(blurTexture3, vUv);\n vec4 sample4 = texture2D(blurTexture4, vUv);\n vec4 sample5 = texture2D(blurTexture5, vUv);\n\n // Apply tint to RGB only, preserve alpha from samples\n vec4 color = bloomStrength * (\n lerpBloomFactor(bloomFactors[0]) * vec4(sample1.rgb * bloomTintColors[0], sample1.a) +\n lerpBloomFactor(bloomFactors[1]) * vec4(sample2.rgb * bloomTintColors[1], sample2.a) +\n lerpBloomFactor(bloomFactors[2]) * vec4(sample3.rgb * bloomTintColors[2], sample3.a) +\n lerpBloomFactor(bloomFactors[3]) * vec4(sample4.rgb * bloomTintColors[3], sample4.a) +\n lerpBloomFactor(bloomFactors[4]) * vec4(sample5.rgb * bloomTintColors[4], sample5.a)\n );\n\n gl_FragColor = color;\n }"})}}function v(e,t=.5){const[i,n,a]=e,s=e=>e<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4),o=s(i),r=s(n),l=s(a),h=.2126*o+.7152*r+.0722*l,c=t/Math.max(h,.001);let u=o*c,d=r*c,m=l*c;const p=Math.max(u,d,m);p>1&&(u/=p,d/=p,m/=p);const g=e=>e<=.0031308?12.92*e:1.055*Math.pow(e,1/2.4)-.055;return{r:Math.min(1,Math.max(0,g(u))),g:Math.min(1,Math.max(0,g(d))),b:Math.min(1,Math.max(0,g(m)))}}function b(e,t=0,i="glow"){const n=function(e){const t=parseInt(e.slice(1,3),16)/255,i=parseInt(e.slice(3,5),16)/255,n=parseInt(e.slice(5,7),16)/255,a=e=>e<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4);return.2126*a(t)+.7152*a(i)+.0722*a(n)}(e),a=(.5+t)/Math.max(n,.05);return Math.max(.3,Math.min(10,a))}y.BlurDirectionX=new t(1,0),y.BlurDirectionY=new t(0,1);class w{constructor(t){this.renderer=t,this.glowAmount=0,this.targetGlowAmount=0,this.glowColor=new e.Color(1,1,1),this.targetGlowColor=new e.Color(1,1,1),this.worldPosition=new e.Vector3(0,0,0),this.time=0,this.ringPhase=0,this.scene=new e.Scene,this.camera=new e.OrthographicCamera(-1,1,1,-1,.1,10),this.camera.position.z=1,this.createGlowMesh(),this._tempVector=new e.Vector3,this._tempColor=new e.Color}createGlowMesh(){const t=new e.PlaneGeometry(2,2),i=new e.ShaderMaterial({uniforms:{glowAmount:{value:0},glowColor:{value:new e.Color(1,1,1)},centerUV:{value:new e.Vector2(.5,.5)},time:{value:0},ringPhase:{value:0},aspectRatio:{value:1}},vertexShader:"\n varying vec2 vUv;\n\n void main() {\n vUv = uv;\n gl_Position = vec4(position.xy, 0.0, 1.0);\n }\n ",fragmentShader:"\n uniform float glowAmount;\n uniform vec3 glowColor;\n uniform vec2 centerUV;\n uniform float time;\n uniform float ringPhase;\n uniform float aspectRatio;\n\n varying vec2 vUv;\n\n void main() {\n // Aspect-correct UV coordinates - apply aspect to Y instead\n // This prevents horizontal clipping on wide screens\n vec2 centeredUV = vUv - centerUV;\n // Don't multiply by aspect - let glow be circular in screen space\n\n float dist = length(centeredUV);\n\n // Ring parameters that evolve with ringPhase\n // MUCH LARGER radii to prevent clipping - glow can extend to screen edges\n // At ringPhase=0: tight ring close to center\n // At ringPhase=1: expanded ring that can fill most of screen\n float innerRadius = mix(0.02, 0.08, ringPhase);\n float outerRadius = mix(0.15, 1.2, ringPhase); // Can extend beyond screen!\n float peakRadius = mix(0.06, 0.25, ringPhase);\n\n // Create soft ring falloff\n // Inner falloff: 0 at center, 1 at peak\n float innerFalloff = smoothstep(innerRadius * 0.3, peakRadius, dist);\n\n // Outer falloff: 1 at peak, 0 at outer edge (very gradual fade)\n float outerFalloff = 1.0 - smoothstep(peakRadius, outerRadius, dist);\n\n // Combine for ring shape\n float ringIntensity = innerFalloff * outerFalloff;\n\n // Add subtle shimmer/undulation\n float shimmer = 0.9 + 0.1 * sin(time * 3.0 + dist * 20.0);\n\n // Final intensity with glow amount control\n float intensity = ringIntensity * glowAmount * shimmer;\n\n // Soft glow color with intensity\n // Use HDR values (>1.0) for bloom pickup\n vec3 color = glowColor * intensity * 2.0;\n\n // Alpha for blending\n float alpha = intensity * 0.6;\n\n gl_FragColor = vec4(color, alpha);\n }\n ",transparent:!0,blending:e.AdditiveBlending,depthTest:!1,depthWrite:!1});this.glowMesh=new e.Mesh(t,i),this.scene.add(this.glowMesh)}setGlow(e,t,i){this.targetGlowAmount=Math.max(0,e),t&&(Array.isArray(t)?this.targetGlowColor.setRGB(t[0],t[1],t[2]):this.targetGlowColor.copy(t)),i&&this.worldPosition.copy(i)}update(e,t){const i=e/1e3;this.time+=i,this.glowAmount+=(this.targetGlowAmount-this.glowAmount)*Math.min(1,8*i),this.glowColor.lerp(this.targetGlowColor,Math.min(1,8*i));const n=Math.min(1,this.glowAmount);if(this.ringPhase+=(n-this.ringPhase)*Math.min(1,4*i),t){this._tempVector.copy(this.worldPosition),this._tempVector.project(t);const e=(this._tempVector.x+1)/2,i=(this._tempVector.y+1)/2;this.glowMesh.material.uniforms.centerUV.value.set(e,i)}this.glowMesh.material.uniforms.glowAmount.value=this.glowAmount,this.glowMesh.material.uniforms.glowColor.value.copy(this.glowColor),this.glowMesh.material.uniforms.time.value=this.time,this.glowMesh.material.uniforms.ringPhase.value=this.ringPhase;const a=this.renderer.domElement;this.glowMesh.material.uniforms.aspectRatio.value=a.width/a.height}render(e){if(this.glowAmount<.001)return;const{autoClear:t}=e;e.autoClear=!1,e.render(this.scene,this.camera),e.autoClear=t}isActive(){return this.glowAmount>.001||this.targetGlowAmount>0}dispose(){this.glowMesh&&(this.glowMesh.geometry.dispose(),this.glowMesh.material.dispose(),this.scene.remove(this.glowMesh),this.glowMesh=null),this.scene=null,this.camera=null,this._tempVector=null,this._tempColor=null}}class M{constructor(t,i={}){this.canvas=t,this.options=i,this._destroyed=!1,this.scene=new e.Scene,this.scene.background=null,this.renderer=new e.WebGLRenderer({canvas:t,alpha:!0,premultipliedAlpha:!1,antialias:!0,powerPreference:"high-performance",preserveDrawingBuffer:!1,precision:"highp",logarithmicDepthBuffer:!1,stencil:!1}),this.renderer.outputColorSpace=e.SRGBColorSpace,this.renderer.toneMapping=e.NoToneMapping,this.renderer.toneMappingExposure=1,this.renderer.setClearColor(0,0),this.renderer.autoClear=!1,this.renderer.setPixelRatio(Math.min(window.devicePixelRatio,1.5)),this.renderer.setSize(t.width,t.height,!1),i.enableShadows&&(this.renderer.shadowMap.enabled=!0,this.renderer.shadowMap.type=e.PCFSoftShadowMap),this._contextLost=!1,this._boundHandleContextLost=this.handleContextLost.bind(this),this._boundHandleContextRestored=this.handleContextRestored.bind(this),t.addEventListener("webglcontextlost",this._boundHandleContextLost,!1),t.addEventListener("webglcontextrestored",this._boundHandleContextRestored,!1);const n=void 0!==i.fov?i.fov:45;this.camera=new e.PerspectiveCamera(n,t.width/t.height,.1,100),this.cameraDistance=void 0!==i.cameraDistance?i.cameraDistance:3,this.camera.position.set(0,0,this.cameraDistance),this.camera.lookAt(0,0,0),!1!==i.enableControls&&this.setupCameraControls(),this.setupLights(),!1!==i.enablePostProcessing&&this.setupPostProcessing(),this.coreMesh=null,this.materialMode="glow",this.glowMaterial=null,this.glassMaterial=null,this.mixer=null,this.clock=new e.Clock,this._tempColor=new e.Color,this._tempColor2=new e.Color,this._white=new e.Color(1,1,1),this._tempQuat=new e.Quaternion,this._tempEuler=new e.Euler,this._quatX=new e.Quaternion,this._quatY=new e.Quaternion,this._quatZ=new e.Quaternion,this._rollQuat=new e.Quaternion,this._meshQuat=new e.Quaternion,this._xAxis=new e.Vector3(1,0,0),this._yAxis=new e.Vector3(0,1,0),this._zAxis=new e.Vector3(0,0,1),this._cameraToMesh=new e.Vector3,this._cameraDir=new e.Vector3}setupCameraControls(){this.controls=new g(this.camera,this.renderer.domElement),this.controls.enableDamping=!0,this.controls.dampingFactor=.1;const e=void 0!==this.options.minZoom?this.options.minZoom:.5*this.cameraDistance,t=void 0!==this.options.maxZoom?this.options.maxZoom:2*this.cameraDistance;this.controls.minDistance=e,this.controls.maxDistance=t,this.controls.enablePan=!1,this.controls.autoRotate=!0===this.options.autoRotate,this.controls.autoRotateSpeed=void 0!==this.options.autoRotateSpeed?this.options.autoRotateSpeed:.5,this.controls.minPolarAngle=.2*Math.PI,this.controls.maxPolarAngle=.8*Math.PI,this.controls.rotateSpeed=.8,this.controls.zoomSpeed=1.5,("ontouchstart"in window||navigator.maxTouchPoints>0)&&(this.controls.rotateSpeed=1,this.controls.zoomSpeed=1.2),this.renderer.domElement.style.touchAction="none";const i=()=>{this.controls&&this.controls.update()};this.renderer.domElement.addEventListener("pointermove",i,{passive:!0}),this.renderer.domElement.addEventListener("pointerdown",i,{passive:!0})}setupLights(){this.ambientLight=new e.AmbientLight(16777215,.3),this.ambientLight.name="ambientLight",this.scene.add(this.ambientLight),this.keyLight=new e.DirectionalLight(16777215,.8),this.keyLight.position.set(2,2,2),this.keyLight.name="keyLight",this.options.enableShadows&&(this.keyLight.castShadow=!0,this.keyLight.shadow.mapSize.width=1024,this.keyLight.shadow.mapSize.height=1024,this.keyLight.shadow.camera.near=.5,this.keyLight.shadow.camera.far=10),this.scene.add(this.keyLight),this.fillLight=new e.DirectionalLight(16777215,.5),this.fillLight.position.set(-2,1,1),this.fillLight.name="fillLight",this.scene.add(this.fillLight),this.rimLight=new e.DirectionalLight(16777215,.7),this.rimLight.position.set(0,1,-2),this.rimLight.name="rimLight",this.scene.add(this.rimLight),this.accentLight1=new e.PointLight(54527,.3,10),this.accentLight1.position.set(-3,0,1),this.accentLight1.name="accentLight1",this.scene.add(this.accentLight1),this.accentLight2=new e.PointLight(16716947,.2,10),this.accentLight2.position.set(3,0,1),this.accentLight2.name="accentLight2",this.scene.add(this.accentLight2),this.accentLight3=new e.PointLight(16739125,.2,10),this.accentLight3.position.set(0,3,-1),this.accentLight3.name="accentLight3",this.scene.add(this.accentLight3),this.createEnvironmentMap()}async createEnvironmentMap(){if(this._destroyed)return;try{const{RGBELoader:t}=await import("three/examples/jsm/loaders/RGBELoader.js");if(this._destroyed)return;const i=new e.PMREMGenerator(this.renderer);i.compileEquirectangularShader();try{const n=new t,a=(this.options.assetBasePath||"/assets").replace("/assets",""),s=await n.loadAsync(`${a}/hdri/studio_1k.hdr`);if(!s||!s.image)throw new Error("HDR texture loaded but image data is missing");return this._destroyed?(s.dispose(),void i.dispose()):(s.mapping=e.EquirectangularReflectionMapping,this.envMap=i.fromEquirectangular(s).texture,s.dispose(),i.dispose(),void console.log("[Emotive] HDRI environment map loaded"))}catch(e){i.dispose()}}catch(e){}if(this._destroyed)return;const t=new e.WebGLCubeRenderTarget(512),i=new e.Scene,n=new e.Color(5609983),a=new e.Color(16739229),s=new e.Color(1710638),o=new e.HemisphereLight(n,s,1.5);i.add(o);const r=new e.PointLight(54527,2,20);r.position.set(-5,2,-5),i.add(r);const l=new e.PointLight(16716947,2,20);l.position.set(5,2,-5),i.add(l);const h=new e.PointLight(16755200,1.5,20);h.position.set(0,5,0),i.add(h),i.background=a;const c=new e.CubeCamera(.1,100,t);c.update(this.renderer,i),this.envMap=t.texture,this._envCubeRenderTarget=t,this._envScene=i,this._envCubeCamera=c}setupPostProcessing(){const t=new e.Vector2;this.renderer.getDrawingBufferSize(t);const i=new e.WebGLRenderTarget(t.x,t.y,{format:e.RGBAFormat,type:e.HalfFloatType,minFilter:e.LinearFilter,magFilter:e.LinearFilter,stencilBuffer:!1,depthBuffer:!0});this.composer=new u(this.renderer,i);const n=new d(this.scene,this.camera);n.clearColor=new e.Color(0),n.clearAlpha=0,this.composer.addPass(n);const a="ontouchstart"in window||navigator.maxTouchPoints>0?.5:1,s=new e.Vector2(Math.floor(t.x*a),Math.floor(t.y*a));this.bloomPass=new y(s,1.2,.8,.3),this.bloomPass.name="bloomPass",this.bloomPass.enabled=!0,this.bloomPass.renderToScreen=!0,this.composer.addPass(this.bloomPass),this.particleRenderTarget=new e.WebGLRenderTarget(t.x,t.y,{format:e.RGBAFormat,type:e.HalfFloatType,minFilter:e.LinearFilter,magFilter:e.LinearFilter,stencilBuffer:!1,depthBuffer:!0}),this.particleBloomPass=new y(s,.5,.4,.3),this.particleBloomPass.name="particleBloomPass",this.particleBloomPass.enabled=!0,this.particleBloomPass.clearColor=new e.Color(1,1,1),this.particleBloomPass.skipBaseCopy=!0,this.soulRenderTarget=new e.WebGLRenderTarget(t.x,t.y,{format:e.RGBAFormat,type:e.HalfFloatType,minFilter:e.LinearFilter,magFilter:e.LinearFilter,stencilBuffer:!1,depthBuffer:!0}),this.particleCompositeShader={uniforms:{tDiffuse:{value:null},tParticles:{value:null}},vertexShader:"\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n ",fragmentShader:"\n uniform sampler2D tDiffuse;\n uniform sampler2D tParticles;\n varying vec2 vUv;\n\n void main() {\n vec4 base = texture2D(tDiffuse, vUv);\n vec4 particles = texture2D(tParticles, vUv);\n\n // Alpha-preserving composite: particles over base\n // Use particle alpha to blend\n vec3 blended = mix(base.rgb, particles.rgb, particles.a);\n float alpha = base.a + particles.a * (1.0 - base.a);\n\n gl_FragColor = vec4(blended, alpha);\n }\n "},this.glowLayer=new w(this.renderer)}handleContextLost(e){e.preventDefault(),this._contextLost=!0,console.warn("⚠️ WebGL context lost - rendering paused"),this.cameraAnimationId&&(cancelAnimationFrame(this.cameraAnimationId),this.cameraAnimationId=null)}handleContextRestored(){this._contextLost=!1,this.recreateResources()}recreateResources(){this.createEnvironmentMap(),"glow"===this.materialMode?(this.glowMaterial=this.createGlowMaterial(),this.coreMesh&&(this.coreMesh.material=this.glowMaterial)):"glass"===this.materialMode&&(this.glassMaterial=this.createGlassMaterial(),this.coreMesh&&(this.coreMesh.material=this.glassMaterial),this.coreMesh&&this.createInnerCore())}createCoreMesh(t,i=null){if(this.coreMesh&&(this.scene.remove(this.coreMesh),this.coreMesh.isGroup?this.coreMesh.traverse(e=>{e.geometry&&e.geometry.dispose(),e.material&&this.disposeMaterial(e.material)}):(this.coreMesh.geometry&&this.coreMesh.geometry.dispose(),this.coreMesh.material&&this.disposeMaterial(this.coreMesh.material)),this.coreMesh=null),t.isGroup)return this.coreMesh=t,this.coreMesh.name="coreMascot",this.options.enableShadows&&this.coreMesh.traverse(e=>{e.isMesh&&(e.castShadow=!0,e.receiveShadow=!0)}),this.scene.add(this.coreMesh),this.coreMesh;let n;return i?n=i:(this.glowMaterial||(this.glowMaterial=this.createGlowMaterial()),n="glass"===this.materialMode?this.glassMaterial||this.createGlassMaterial():this.glowMaterial),this.coreMesh=new e.Mesh(t,n),this.coreMesh.name="coreMascot",this.options.enableShadows&&(this.coreMesh.castShadow=!0,this.coreMesh.receiveShadow=!0),this.scene.add(this.coreMesh),"glass"===this.materialMode&&this.createInnerCore(),this.coreMesh}swapGeometry(t,i=null){if(!this.coreMesh)return;this.bloomPass&&this.bloomPass.clearBloomBuffers(this.renderer),this.particleBloomPass&&this.particleBloomPass.clearBloomBuffers(this.renderer);const n=this.coreMesh.geometry;if(n&&n.dispose(),this.coreMesh.geometry=t,i){if(this.coreMesh.material&&this.coreMesh.material!==this.glowMaterial&&this.coreMesh.material!==this.glassMaterial&&this.disposeMaterial(this.coreMesh.material),this.coreMesh.material=i,i.uniforms?.resolution){const t=this.renderer.getDrawingBufferSize(new e.Vector2);i.uniforms.resolution.value.set(t.x,t.y)}}else{const e="glass"===this.materialMode?this.glassMaterial||this.createGlassMaterial():this.glowMaterial;this.coreMesh.material!==e&&(this.coreMesh.material&&this.coreMesh.material!==this.glowMaterial&&this.coreMesh.material!==this.glassMaterial&&this.disposeMaterial(this.coreMesh.material),this.coreMesh.material=e)}"glass"!==this.materialMode||i||this.createInnerCore()}createGlowMaterial(){return new e.ShaderMaterial({uniforms:{glowColor:{value:new e.Color(1,1,1)},glowIntensity:{value:1},coreColor:{value:new e.Color(1,1,1)},fresnelPower:{value:3}},vertexShader:"\n varying vec3 vNormal;\n varying vec3 vViewPosition;\n\n void main() {\n // Transform normal to view space\n vNormal = normalize(normalMatrix * normal);\n\n // Calculate view space position\n vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);\n vViewPosition = -mvPosition.xyz;\n\n // Output clip space position\n gl_Position = projectionMatrix * mvPosition;\n }\n ",fragmentShader:"\n uniform vec3 glowColor;\n uniform vec3 coreColor;\n uniform float glowIntensity;\n uniform float fresnelPower;\n\n varying vec3 vNormal;\n varying vec3 vViewPosition;\n\n void main() {\n // Fresnel effect: edges glow more than center\n vec3 viewDir = normalize(vViewPosition);\n float fresnel = pow(1.0 - abs(dot(vNormal, viewDir)), fresnelPower);\n\n // Combine white core with colored glow\n // Both core and glow respect glowIntensity for proper on/off toggle\n vec3 finalColor = (coreColor * glowIntensity) + (glowColor * glowIntensity * fresnel);\n\n gl_FragColor = vec4(finalColor, 1.0);\n }\n ",transparent:!1,side:e.FrontSide})}createGlassMaterial(){this.glassEmissiveMultiplier=.6;const t=new e.MeshPhysicalMaterial({transmission:1,thickness:2.7,roughness:.37,metalness:0,ior:1.5,reflectivity:.5,envMapIntensity:1.2,side:e.DoubleSide,transparent:!0,opacity:1,color:16777215,emissive:16777215,emissiveIntensity:.6,clearcoat:.8,clearcoatRoughness:.05,iridescence:.4,iridescenceIOR:1.3,iridescenceThicknessRange:[100,400]});return this.envMap&&(t.envMap=this.envMap),t}createInnerCore(){if(this.innerCore&&(this.coreMesh&&this.coreMesh.remove(this.innerCore),this.innerCore.geometry.dispose(),this.disposeMaterial(this.innerCore.material),this.innerCore=null,this.innerCoreMaterial=null),!this.coreMesh||!this.coreMesh.geometry)return;const t=this.coreMesh.geometry;let i;if("TorusGeometry"===t.type||void 0!==t.parameters?.tube){const n=t.parameters,a=n.radius||1,s=.25*(n.tube||.4),o=n.radialSegments||16,r=n.tubularSegments||100;i=new e.TorusGeometry(a,s,o,r)}else if("SphereGeometry"===t.type){const n=.2*(t.parameters.radius||1);i=new e.SphereGeometry(n,32,32)}else if("BoxGeometry"===t.type){const n=t.parameters,a=.2*(n.width||1),s=.2*(n.height||1),o=.2*(n.depth||1);i=new e.BoxGeometry(a,s,o)}else if("IcosahedronGeometry"===t.type||"OctahedronGeometry"===t.type){const n=t.parameters,a=.2*(n.radius||1),s=n.detail||2;i="IcosahedronGeometry"===t.type?new e.IcosahedronGeometry(a,s):new e.OctahedronGeometry(a,s)}else i=new e.IcosahedronGeometry(.2,2);const n=t.userData?.geometryType,a="IcosahedronGeometry"===t.type||"OctahedronGeometry"===t.type||"crystal"===n||"diamond"===n,s=new e.MeshStandardMaterial({emissive:16777215,emissiveIntensity:a?3.5:2,color:16777215,transparent:!1,opacity:1});this.innerCoreMaterial=s,this.innerCore=new e.Mesh(i,s),this.innerCore.name="innerCore",this.coreMesh.add(this.innerCore)}setMaterialMode(e){if(!this.coreMesh)return console.warn("Cannot set material mode: core mesh not created yet"),void(this.materialMode=e);if(e===this.materialMode)return;this.materialMode=e,"glass"!==e||this.glassMaterial?"glow"!==e||this.glowMaterial||(this.glowMaterial=this.createGlowMaterial()):this.glassMaterial=this.createGlassMaterial();const t="glass"===e?this.glassMaterial:this.glowMaterial;this.coreMesh.material=t,"glass"===e?this.createInnerCore():this.innerCore&&(this.coreMesh.remove(this.innerCore),this.innerCore.geometry.dispose(),this.disposeMaterial(this.innerCore.material),this.innerCore=null,this.innerCoreMaterial=null)}updateGlassProperties(e){this.glassMaterial&&(void 0!==e.transmission&&(this.glassMaterial.transmission=e.transmission,this.glassMaterial.needsUpdate=!0),void 0!==e.thickness&&(this.glassMaterial.thickness=e.thickness,this.glassMaterial.needsUpdate=!0),void 0!==e.roughness&&(this.glassMaterial.roughness=e.roughness,this.glassMaterial.needsUpdate=!0),void 0!==e.emissiveMultiplier&&(this.glassEmissiveMultiplier=e.emissiveMultiplier))}updateLighting(e,t,i=.15){if(!t||!t.visual)return;const n=t.visual.glowColor||"#FFFFFF";this._tempColor.set(n);const a=t.visual.glowIntensity||1;if(this.keyLight&&(this.keyLight.color.lerp(this._tempColor,i),this.keyLight.intensity+=(.8*a-this.keyLight.intensity)*i),this.fillLight&&(this._tempColor2.copy(this._tempColor).lerp(this._white,.7),this.fillLight.color.lerp(this._tempColor2,.5*i),this.fillLight.intensity+=(.3*a-this.fillLight.intensity)*i),this.ambientLight){const e=.4*a;this.ambientLight.intensity+=(e-this.ambientLight.intensity)*i}}normalizeIntensity(e){return.8+Math.log(e+1)/Math.log(11)*.4}calculateColorLuminance(e,t,i){const n=e=>e<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4);return.2126*n(e)+.7152*n(t)+.0722*n(i)}updateBloom(e,t=.1,i=null){if(this.bloomPass){const n=this.normalizeIntensity(e);let a,s,o;"sun"===i?(s=1.5,o=.4,a=.3):"crystal"===i||"rough"===i||"heart"===i?(s=1.8,o=.7,a=.35):"glass"===this.materialMode?(s=.3,o=.2,a=.85):(s=1+.8*n,o=.4,a=.85),this.bloomPass.strength+=(s-this.bloomPass.strength)*t,this.bloomPass.threshold+=(a-this.bloomPass.threshold)*t,this.bloomPass.radius=o}}setCameraPreset(t,i=1e3,n=!1){if(!this.controls)return;const a=this.cameraDistance,s={front:{x:0,y:0,z:a},side:{x:a,y:0,z:0},top:{x:0,y:a,z:0},angle:{x:.67*a,y:.5*a,z:.67*a},back:{x:0,y:0,z:-a},bottom:{x:0,y:-a,z:0}}[t];if(!s)return void console.warn(`Unknown camera preset: ${t}`);const o=n?this.controls.target.clone():null;if(0===i)return this.controls.reset(),this.camera.position.set(s.x,s.y,s.z),o?(this.controls.target.copy(o),this.camera.lookAt(o)):(this.controls.target.set(0,0,0),this.camera.lookAt(0,0,0)),void this.controls.update();n||this.controls.target.set(0,0,0);const r=this.camera.position.clone(),l=new e.Vector3(s.x,s.y,s.z),h=performance.now(),c=e=>{const t=e-h,n=Math.min(t/i,1),a=1-Math.pow(1-n,3);this.camera.position.lerpVectors(r,l,a),this.camera.lookAt(0,0,0),this.controls.update(),this.cameraAnimationId=n<1?requestAnimationFrame(c):null};this.cameraAnimationId=requestAnimationFrame(c)}resetCamera(){this.setCameraPreset("front",1e3)}toggleAutoRotate(e){this.controls&&(this.controls.autoRotate=void 0!==e?e:!this.controls.autoRotate)}isAutoRotateEnabled(){return!!this.controls&&this.controls.autoRotate}render(t={}){if(this._destroyed)return void console.log("[ThreeRenderer] render() BLOCKED - destroyed");if(!this.scene||!this.camera||!this.renderer)return void console.log(`[ThreeRenderer] render() BLOCKED - scene=${!!this.scene}, camera=${!!this.camera}, renderer=${!!this.renderer}`);const i=(e,t)=>{if(!e||!e.children)return!0;for(let n=0;n<e.children.length;n++){const a=e.children[n];null!=a?null!==a.visible&&void 0!==a.visible?i(a,`${t}.children[${n}]`):(console.error(`[ThreeRenderer] child.visible is NULL at ${t}.children[${n}] name=${a.name} - REMOVING!`),e.children.splice(n,1),n--):(console.error(`[ThreeRenderer] NULL CHILD at ${t}.children[${n}] - REMOVING!`),e.children.splice(n,1),n--)}return!0};i(this.scene,"scene");const{position:n=[0,0,0],rotation:a=[0,0,0],scale:s=1,glowColor:o=[1,1,1],glowIntensity:r=1,glowColorHex:l=null,hasActiveGesture:h=!1,calibrationRotation:c=[0,0,0],cameraRoll:u=0,solarEclipse:d=null,deltaTime:m=0,morphProgress:p=null}=t;if(this.controls&&this.controls.update(),this.coreMesh){if(this.coreMesh.position.set(...n),this._tempEuler.set(a[0],a[1],a[2],"XYZ"),this._tempQuat.setFromEuler(this._tempEuler),this._quatX.setFromAxisAngle(this._xAxis,c[0]),this._quatY.setFromAxisAngle(this._yAxis,c[1]),this._cameraToMesh.subVectors(this.coreMesh.position,this.camera.position).normalize(),this._quatZ.setFromAxisAngle(this._cameraToMesh,c[2]),this._tempQuat.multiply(this._quatX),this._tempQuat.multiply(this._quatY),this._tempQuat.multiply(this._quatZ),this.coreMesh.rotation.setFromQuaternion(this._tempQuat),0!==u&&(this._cameraDir.subVectors(this.coreMesh.position,this.camera.position).normalize(),this._rollQuat.setFromAxisAngle(this._cameraDir,u),this._meshQuat.setFromEuler(this.coreMesh.rotation),this._meshQuat.premultiply(this._rollQuat),this.coreMesh.rotation.setFromQuaternion(this._meshQuat)),this.coreMesh.scale.setScalar(s),d&&d.update(this.camera,this.coreMesh,m,p),this.coreMesh.material&&this.coreMesh.material.uniforms){if(this.coreMesh.material.uniforms.glowColor&&(this._tempColor.setRGB(...o),this.coreMesh.material.uniforms.glowColor.value.lerp(this._tempColor,.15)),this.coreMesh.material.uniforms.glowIntensity){let e;e=0===r?0:h?r:this.normalizeIntensity(r);const t=this.coreMesh.material.uniforms.glowIntensity.value,i=h?.5:.15;this.coreMesh.material.uniforms.glowIntensity.value+=(e-t)*i}}else if(this.coreMesh.material&&this.coreMesh.material.emissive){this._tempColor.setRGB(...o),this.coreMesh.material.emissive.lerp(this._tempColor,.15);const e=.15*r,t=this.coreMesh.material.emissiveIntensity,i=h?.5:.15;this.coreMesh.material.emissiveIntensity+=(e-t)*i,this.coreMesh.material.color.lerp(this._white,.15)}this.innerCore&&(this.innerCore.visible=r>0,this.innerCoreMaterial&&(this._tempColor.setRGB(...o),this.innerCoreMaterial.emissive.lerp(this._tempColor,.15)))}if(this.mixer){const e=this.clock.getDelta();this.mixer.update(e)}if(this.renderer.clear(),this.composer){if(this.soulRenderTarget){let e=null;if(this.scene.traverse(t=>{"crystalSoul"===t.name&&(e=t)}),this.renderer.setRenderTarget(this.soulRenderTarget),this.renderer.setClearColor(0,0),this.renderer.clear(),this.camera.layers.set(2),this.renderer.render(this.scene,this.camera),this.coreMesh?.material?.uniforms?.soulTexture&&(this.coreMesh.material.uniforms.soulTexture.value=this.soulRenderTarget.texture,this.coreMesh.material.uniforms.soulTextureSize&&this.coreMesh.material.uniforms.soulTextureSize.value.set(this.soulRenderTarget.width,this.soulRenderTarget.height),this.coreMesh.material.uniforms.soulScreenCenter&&e)){const t=e.position.clone().project(this.camera),i=.5*(t.x+1),n=.5*(t.y+1);this.coreMesh.material.uniforms.soulScreenCenter.value.set(i,n)}this.renderer.setRenderTarget(null),this.renderer.setClearColor(0,0)}if(this.camera.layers.set(0),this.composer.render(),this.particleRenderTarget&&this.particleBloomPass){this.renderer.setRenderTarget(this.particleRenderTarget),this.renderer.setClearColor(16777215,0),this.renderer.clear(),this.camera.layers.set(0);const t=this._depthOnlyMaterial||(this._depthOnlyMaterial=new e.MeshBasicMaterial({colorWrite:!1,depthWrite:!0}));this.scene.overrideMaterial=t,this.renderer.render(this.scene,this.camera),this.scene.overrideMaterial=null,this.camera.layers.set(1),this.renderer.render(this.scene,this.camera);const i=this.particleRenderTarget;this.particleBloomPass.renderToScreen=!0,this.particleBloomPass.render(this.renderer,null,i,0,!1),this.renderer.setClearColor(0,0),this.renderer.setRenderTarget(null)}else this.camera.layers.set(1),this.renderer.render(this.scene,this.camera);this.camera.layers.enableAll(),this.glowLayer&&this.glowLayer.isActive()&&this.glowLayer.render(this.renderer)}else this.renderer.render(this.scene,this.camera),this.glowLayer&&this.glowLayer.isActive()&&this.glowLayer.render(this.renderer)}updateGlowLayer(e,t,i,n){this.glowLayer&&(this.glowLayer.setGlow(e,t,i),this.glowLayer.update(n,this.camera))}resize(t,i){if(this.camera.aspect=t/i,this.camera.updateProjectionMatrix(),this.renderer.setSize(t,i,!1),this.composer){const t=new e.Vector2;this.renderer.getDrawingBufferSize(t),this.composer.setSize(t.x,t.y),this.bloomPass&&this.bloomPass.resolution&&this.bloomPass.resolution.set(t.x,t.y),this.particleRenderTarget&&this.particleRenderTarget.setSize(t.x,t.y),this.particleBloomPass&&this.particleBloomPass.setSize(t.x,t.y),this.soulRenderTarget&&this.soulRenderTarget.setSize(t.x,t.y),this.coreMesh?.material?.uniforms?.resolution&&this.coreMesh.material.uniforms.resolution.value.set(t.x,t.y)}}disposeMaterial(e){e&&(["map","lightMap","bumpMap","normalMap","specularMap","envMap","alphaMap","aoMap","displacementMap","emissiveMap","gradientMap","metalnessMap","roughnessMap"].forEach(t=>{e[t]&&e[t].dispose()}),e.uniforms&&Object.values(e.uniforms).forEach(e=>{e.value&&(e.value.isTexture?(e.value.dispose(),e.value=null):(e.value.isColor||e.value.isVector2||e.value.isVector3||e.value.isVector4)&&(e.value=null))}),e.dispose())}destroy(){console.log(`[ThreeRenderer] destroy() CALLED, scene children=${this.scene?.children?.length}`),this._destroyed=!0,this.canvas&&(this.canvas.removeEventListener("webglcontextlost",this._boundHandleContextLost,!1),this.canvas.removeEventListener("webglcontextrestored",this._boundHandleContextRestored,!1)),this.cameraAnimationId&&(cancelAnimationFrame(this.cameraAnimationId),this.cameraAnimationId=null),this.innerCore&&(this.coreMesh&&this.coreMesh.remove(this.innerCore),this.innerCore.geometry.dispose(),this.disposeMaterial(this.innerCore.material),this.innerCore=null,this.innerCoreMaterial=null),this.coreMesh&&(this.scene.remove(this.coreMesh),this.coreMesh.geometry.dispose(),this.disposeMaterial(this.coreMesh.material),this.coreMesh=null),this.glowMaterial&&(this.disposeMaterial(this.glowMaterial),this.glowMaterial=null),this.glassMaterial&&(this.disposeMaterial(this.glassMaterial),this.glassMaterial=null),this.composer&&(this.composer.dispose(),this.composer=null),this.particleRenderTarget&&(this.particleRenderTarget.dispose(),this.particleRenderTarget=null),this.particleBloomPass&&(this.particleBloomPass.dispose(),this.particleBloomPass=null),this.soulRenderTarget&&(this.soulRenderTarget.dispose(),this.soulRenderTarget=null),this.glowLayer&&(this.glowLayer.dispose(),this.glowLayer=null),this.controls&&(this.controls.dispose(),this.controls=null),this.keyLight?.shadow?.map&&this.keyLight.shadow.map.dispose(),this.fillLight?.shadow?.map&&this.fillLight.shadow.map.dispose(),this.rimLight?.shadow?.map&&this.rimLight.shadow.map.dispose(),this.keyLight=null,this.fillLight=null,this.rimLight=null,this.ambientLight=null,this.accentLight1=null,this.accentLight2=null,this.accentLight3=null,this.envMap&&(this.envMap.dispose(),this.envMap=null),this._envCubeRenderTarget&&(this._envCubeRenderTarget.dispose(),this._envCubeRenderTarget=null),this._envScene&&(this._envScene.traverse(e=>{e.geometry&&e.geometry.dispose(),e.material&&this.disposeMaterial(e.material)}),this._envScene.clear(),this._envScene=null),this._envCubeCamera&&(this._envCubeCamera=null),this.renderer&&(this.renderer.dispose(),this.renderer=null),this.scene.clear(),this.mixer&&(this.mixer.stopAllAction(),this.mixer=null),this.clock=null,this.camera=null,this._tempColor=null,this._tempColor2=null,this._white=null,this._tempQuat=null,this._tempEuler=null,this._quatX=null,this._quatY=null,this._quatZ=null,this._rollQuat=null,this._meshQuat=null,this._xAxis=null,this._yAxis=null,this._zAxis=null,this._cameraToMesh=null,this._cameraDir=null}}const S="\n/**\n * Apply a single blend mode to two colors\n * @param base - Base color (RGB, 0.0-1.0 range)\n * @param blend - Blend color (RGB, 0.0-1.0 range)\n * @param mode - Blend mode index (0-17)\n * @return Blended color (RGB, 0.0-1.0 range)\n *\n * Blend Mode Reference:\n * 0 = Multiply (darkening)\n * 1 = Linear Burn (darkening, linear)\n * 2 = Color Burn (darkening, intense)\n * 3 = Color Dodge (brightening, intense)\n * 4 = Screen (brightening)\n * 5 = Overlay (contrast, screen/multiply hybrid)\n * 6 = Add (brightening, additive glow)\n * 7 = Soft Light (contrast, gentle)\n * 8 = Hard Light (contrast, strong)\n * 9 = Vivid Light (contrast, saturation boost)\n * 10 = Linear Light (contrast, linear)\n * 11 = Difference (inversion)\n * 12 = Exclusion (soft inversion)\n * 13 = Darken (comparison, darker)\n * 14 = Lighten (comparison, lighter)\n * 15 = Subtract (darkening, deep shadows)\n * 16 = Divide (brightening, ethereal glow)\n * 17 = Pin Light (posterization)\n */\nvec3 applyBlendMode(vec3 base, vec3 blend, int mode) {\n if (mode == 0) {\n // MULTIPLY: base * blend\n return base * blend;\n } else if (mode == 1) {\n // LINEAR BURN: base + blend - 1\n return max(base + blend - vec3(1.0), vec3(0.0));\n } else if (mode == 2) {\n // COLOR BURN: (blend==0.0) ? 0.0 : max((1.0-((1.0-base)/blend)), 0.0)\n return vec3(\n blend.r == 0.0 ? 0.0 : max(1.0 - ((1.0 - base.r) / blend.r), 0.0),\n blend.g == 0.0 ? 0.0 : max(1.0 - ((1.0 - base.g) / blend.g), 0.0),\n blend.b == 0.0 ? 0.0 : max(1.0 - ((1.0 - base.b) / blend.b), 0.0)\n );\n } else if (mode == 3) {\n // COLOR DODGE: (blend==1.0) ? 1.0 : min(base/(1.0-blend), 1.0)\n return vec3(\n blend.r == 1.0 ? 1.0 : min(base.r / (1.0 - blend.r), 1.0),\n blend.g == 1.0 ? 1.0 : min(base.g / (1.0 - blend.g), 1.0),\n blend.b == 1.0 ? 1.0 : min(base.b / (1.0 - blend.b), 1.0)\n );\n } else if (mode == 4) {\n // SCREEN: 1 - (1 - base) * (1 - blend)\n return vec3(1.0) - (vec3(1.0) - base) * (vec3(1.0) - blend);\n } else if (mode == 5) {\n // OVERLAY: base < 0.5 ? (2 * base * blend) : (1 - 2 * (1 - base) * (1 - blend))\n return vec3(\n base.r < 0.5 ? (2.0 * base.r * blend.r) : (1.0 - 2.0 * (1.0 - base.r) * (1.0 - blend.r)),\n base.g < 0.5 ? (2.0 * base.g * blend.g) : (1.0 - 2.0 * (1.0 - base.g) * (1.0 - blend.g)),\n base.b < 0.5 ? (2.0 * base.b * blend.b) : (1.0 - 2.0 * (1.0 - base.b) * (1.0 - blend.b))\n );\n } else if (mode == 6) {\n // ADD (LINEAR DODGE): base + blend\n return min(base + blend, vec3(1.0));\n } else if (mode == 7) {\n // SOFT LIGHT: blend < 0.5 ? (2*base*blend + base^2*(1-2*blend)) : (sqrt(base)*(2*blend-1) + 2*base*(1-blend))\n return vec3(\n blend.r < 0.5 ? (2.0 * base.r * blend.r + base.r * base.r * (1.0 - 2.0 * blend.r)) : (sqrt(base.r) * (2.0 * blend.r - 1.0) + 2.0 * base.r * (1.0 - blend.r)),\n blend.g < 0.5 ? (2.0 * base.g * blend.g + base.g * base.g * (1.0 - 2.0 * blend.g)) : (sqrt(base.g) * (2.0 * blend.g - 1.0) + 2.0 * base.g * (1.0 - blend.g)),\n blend.b < 0.5 ? (2.0 * base.b * blend.b + base.b * base.b * (1.0 - 2.0 * blend.b)) : (sqrt(base.b) * (2.0 * blend.b - 1.0) + 2.0 * base.b * (1.0 - blend.b))\n );\n } else if (mode == 8) {\n // HARD LIGHT: blend < 0.5 ? (2 * base * blend) : (1 - 2 * (1 - base) * (1 - blend))\n return vec3(\n blend.r < 0.5 ? (2.0 * base.r * blend.r) : (1.0 - 2.0 * (1.0 - base.r) * (1.0 - blend.r)),\n blend.g < 0.5 ? (2.0 * base.g * blend.g) : (1.0 - 2.0 * (1.0 - base.g) * (1.0 - blend.g)),\n blend.b < 0.5 ? (2.0 * base.b * blend.b) : (1.0 - 2.0 * (1.0 - base.b) * (1.0 - blend.b))\n );\n } else if (mode == 9) {\n // VIVID LIGHT: blend < 0.5 ? ColorBurn(base, 2*blend) : ColorDodge(base, 2*(blend-0.5))\n return vec3(\n blend.r < 0.5 ? (blend.r == 0.0 ? 0.0 : max(1.0 - ((1.0 - base.r) / (2.0 * blend.r)), 0.0)) : (blend.r == 1.0 ? 1.0 : min(base.r / (2.0 * (1.0 - blend.r)), 1.0)),\n blend.g < 0.5 ? (blend.g == 0.0 ? 0.0 : max(1.0 - ((1.0 - base.g) / (2.0 * blend.g)), 0.0)) : (blend.g == 1.0 ? 1.0 : min(base.g / (2.0 * (1.0 - blend.g)), 1.0)),\n blend.b < 0.5 ? (blend.b == 0.0 ? 0.0 : max(1.0 - ((1.0 - base.b) / (2.0 * blend.b)), 0.0)) : (blend.b == 1.0 ? 1.0 : min(base.b / (2.0 * (1.0 - blend.b)), 1.0))\n );\n } else if (mode == 10) {\n // LINEAR LIGHT: blend < 0.5 ? LinearBurn(base, 2*blend) : LinearDodge(base, 2*(blend-0.5))\n return vec3(\n blend.r < 0.5 ? max(base.r + 2.0 * blend.r - 1.0, 0.0) : min(base.r + 2.0 * (blend.r - 0.5), 1.0),\n blend.g < 0.5 ? max(base.g + 2.0 * blend.g - 1.0, 0.0) : min(base.g + 2.0 * (blend.g - 0.5), 1.0),\n blend.b < 0.5 ? max(base.b + 2.0 * blend.b - 1.0, 0.0) : min(base.b + 2.0 * (blend.b - 0.5), 1.0)\n );\n } else if (mode == 11) {\n // DIFFERENCE: abs(base - blend)\n return abs(base - blend);\n } else if (mode == 12) {\n // EXCLUSION: base + blend - 2 * base * blend\n return base + blend - 2.0 * base * blend;\n } else if (mode == 13) {\n // DARKEN: min(base, blend)\n return min(base, blend);\n } else if (mode == 14) {\n // LIGHTEN: max(base, blend)\n return max(base, blend);\n } else if (mode == 15) {\n // SUBTRACT: max(base - blend, 0)\n return max(base - blend, vec3(0.0));\n } else if (mode == 16) {\n // DIVIDE: base / (blend + epsilon)\n return min(base / (blend + vec3(0.001)), vec3(1.0));\n } else {\n // PIN LIGHT (mode 17): Replaces colors based on blend brightness\n float blendLum = (blend.r + blend.g + blend.b) / 3.0;\n if (blendLum > 0.5) {\n // Lighten: replace pixels darker than blend\n return max(base, 2.0 * blend - vec3(1.0));\n } else {\n // Darken: replace pixels lighter than blend\n return min(base, 2.0 * blend);\n }\n }\n}\n",x=["Multiply","Linear Burn","Color Burn","Color Dodge","Screen","Overlay","Add","Soft Light","Hard Light","Vivid Light","Linear Light","Difference","Exclusion","Darken","Lighten","Subtract","Divide","Pin Light"];function C(e){return x[e]||"Unknown"}function D(e){const t=x.indexOf(e);return-1!==t?t:0}const P=`\n/**\n * Moon Fragment Shader with Blend Layers\n *\n * Supports up to 4 sequential blend mode layers for complex color grading\n * using universal Photoshop-style blend modes\n */\n\nuniform sampler2D colorMap;\nuniform sampler2D normalMap;\nuniform vec2 shadowOffset;\nuniform float shadowCoverage;\nuniform float shadowSoftness;\nuniform vec3 glowColor;\nuniform float glowIntensity;\nuniform float opacity;\n\n// Lunar Eclipse (Blood Moon) uniforms\nuniform float eclipseProgress;\nuniform float eclipseIntensity;\nuniform vec3 bloodMoonColor;\nuniform float emissiveStrength;\nuniform vec2 eclipseShadowPos; // Shadow center position (-2 to 1)\nuniform float eclipseShadowRadius; // Shadow radius\n\n// Eclipse Color Grading (from color pickers)\nuniform vec3 eclipseShadowColor;\nuniform vec3 eclipseMidtoneColor;\nuniform vec3 eclipseHighlightColor;\nuniform vec3 eclipseGlowColor;\n\n// Brightness model toggle (0 = centeredness-based, 1 = edge-based)\nuniform float eclipseBrightnessModel;\n\n// Shadow darkness control (0.0 = no darkening, 1.0 = maximum darkening)\nuniform float shadowDarkness;\n\n// Blend Layer Uniforms (up to 4 layers)\nuniform float layer1Mode;\nuniform float layer1Strength;\nuniform float layer1Enabled;\n\nuniform float layer2Mode;\nuniform float layer2Strength;\nuniform float layer2Enabled;\n\nuniform float layer3Mode;\nuniform float layer3Strength;\nuniform float layer3Enabled;\n\nuniform float layer4Mode;\nuniform float layer4Strength;\nuniform float layer4Enabled;\n\nvarying vec3 vPosition;\nvarying vec3 vWorldPosition;\nvarying vec3 vViewNormal;\nvarying vec3 vViewPosition;\nvarying vec2 vUv;\n\n// ═══════════════════════════════════════════════════════════════════════════\n// UNIVERSAL BLEND MODES (injected from utils/blendModes.js)\n// ═══════════════════════════════════════════════════════════════════════════\n${S}\n\nvoid main() {\n // DIRECTIONAL SHADOW in VIEW SPACE - camera-relative moon phase\n // Shadow stays fixed relative to screen; rotating moon doesn't change which side is lit\n vec3 viewNormal = normalize(vViewNormal);\n\n float lightX = shadowOffset.x;\n float lightY = shadowOffset.y;\n float offsetMagnitude = length(vec2(lightX, lightY));\n float lightZ = 1.0 - pow(offsetMagnitude, 1.5);\n vec3 lightDir = normalize(vec3(lightX, lightY, lightZ));\n\n // Light direction is in view space (camera-relative)\n float facing = dot(viewNormal, lightDir);\n float edgeWidth = max(fwidth(facing) * 4.0, shadowSoftness * 3.0);\n float shadowFactor = smoothstep(-edgeWidth, edgeWidth, facing);\n\n // Sample moon surface texture\n vec4 texColor = texture2D(colorMap, vUv);\n float brightness = texColor.r + texColor.g + texColor.b;\n if (brightness < 0.03) {\n texColor = vec4(0.5, 0.5, 0.5, 1.0);\n }\n\n // VIEW DIRECTION (for eclipse rim effects only, NOT for general lighting)\n vec3 viewDir = normalize(-vViewPosition);\n float rimFactor = dot(viewNormal, viewDir);\n\n // EARTHSHINE - faint blue glow on shadowed side\n vec3 earthshine = texColor.rgb * 0.01 * vec3(0.35, 0.4, 0.6);\n\n // Apply shadow transition (moon phase only - NOT camera-based)\n // The moon texture is uniformly visible; only the phase shadow creates darkness\n float litFactor = pow(shadowFactor, 2.0);\n vec3 detailEnhanced = texColor.rgb * 1.08;\n float textureLuminance = dot(texColor.rgb, vec3(0.299, 0.587, 0.114));\n detailEnhanced = mix(texColor.rgb * 0.95, texColor.rgb * 1.12, smoothstep(0.3, 0.7, textureLuminance));\n\n // Lit areas show texture; shadowed areas show earthshine\n // NO camera-based limb darkening - moon rotates, texture stays uniformly lit\n vec3 shadowedColor = mix(earthshine, detailEnhanced, litFactor);\n\n vec3 emissive = vec3(0.02, 0.02, 0.02) * shadowFactor;\n vec3 emotionGlow = glowColor * glowIntensity * 0.02 * shadowFactor;\n vec3 finalColor = shadowedColor + emissive + emotionGlow;\n\n // ═══════════════════════════════════════════════════════════════════════════\n // LUNAR ECLIPSE EFFECT (Earth's Shadow Sweep)\n // Shadow position drives everything - automatically transitions from dark sharp shadow to red glow\n // ═══════════════════════════════════════════════════════════════════════════\n // Only apply eclipse if shadow is actually near the moon (shadowX > -1.5)\n if (eclipseProgress > 0.001 && eclipseShadowPos.x > -1.5) {\n // Eclipse progress is now pre-modulated by UI based on shadow position\n // No need for shader-side modulation\n float effectiveProgress = eclipseProgress;\n\n // Calculate distance from shadow center using VIEW-SPACE position (3D spherical)\n // This creates a proper circular shadow on the sphere, not a flat UV-based cutoff\n // viewNormal.xy ranges -1 to 1, scale to match UV range (0 to 0.5 from center)\n vec2 shadowCenter = vec2(eclipseShadowPos.x, eclipseShadowPos.y);\n vec2 spherePos = viewNormal.xy * 0.5; // Scale to UV-equivalent range\n float distFromShadow = length(spherePos - shadowCenter);\n\n // TOTALITY FACTOR: Based on how centered the shadow is on the moon\n // When shadowX near 0.0 (centered), we're at totality - brightens and reddens\n // When shadowX far from 0.0 (off to side), we're partial - stays dark and diffuse\n float shadowCenteredness = 1.0 - smoothstep(0.0, 0.6, abs(eclipseShadowPos.x));\n float totalityFactor = shadowCenteredness;\n\n // Earth's umbra (full shadow) - DIFFUSE at partials, sharper at totality\n float umbraRadius = eclipseShadowRadius * 0.7;\n // Edge softness: very diffuse at partials (0.25), sharp at totality (0.05)\n float umbraEdge = mix(0.25, 0.05, totalityFactor);\n float umbra = 1.0 - smoothstep(umbraRadius - umbraEdge, umbraRadius + umbraEdge, distFromShadow);\n\n // Earth's penumbra (partial shadow) - wider and softer\n // Penumbra extends further at partials, tighter at totality\n float penumbraRadius = eclipseShadowRadius * mix(1.4, 1.1, totalityFactor);\n float penumbraEdge = mix(0.3, 0.15, totalityFactor);\n float penumbra = 1.0 - smoothstep(penumbraRadius - penumbraEdge, penumbraRadius + penumbraEdge, distFromShadow);\n\n // UMBRA DARKENING: Much darker at partials, lighter at totality\n // Partials: 85% darkening (very dark shadow)\n // Totality: 30% darkening (blood moon glow visible)\n float baseDarkening = mix(0.85, 0.30, totalityFactor);\n float umbraDarkeningAmount = baseDarkening * shadowDarkness;\n float umbraDarkening = umbra * effectiveProgress;\n\n // Apply base darkening first\n finalColor *= (1.0 - umbraDarkening * umbraDarkeningAmount);\n\n // PENUMBRA: Darker gradient at partials, lighter at totality\n float penumbraDarkening = (penumbra - umbra) * effectiveProgress;\n float penumbraDarkenAmount = mix(0.50, 0.20, totalityFactor); // 50% at partials, 20% at totality\n finalColor *= (1.0 - penumbraDarkening * penumbraDarkenAmount);\n\n // BLOOD MOON COLOR: Applied throughout entire eclipse, not just totality\n // Matches real lunar eclipse behavior - color present at all phases\n // Use totality factor to control BRIGHTNESS, not color presence\n float colorStrength = umbra; // Color appears wherever umbra shadow is present\n vec3 bloodMoonTint = mix(vec3(1.0), eclipseMidtoneColor, colorStrength);\n finalColor *= bloodMoonTint;\n\n // REALISTIC ECLIPSE PROGRESSION (corrected):\n // Shadow sweeps LEFT → RIGHT but NEVER fully covers moon during partials\n // A bright crescent ALWAYS remains visible (shadow stops before covering moon)\n // Just before totality: shadow nearly covers moon, blood moon glow appears\n // The glow spreads FROM the visible bright crescent INTO the shadowed area\n // During totality: shadow finally covers entire moon, full blood moon\n\n // Use view-space normal for spherical position (not UV)\n // Scale to match UV range\n float pixelX = viewNormal.x * 0.5;\n\n // THE LIT CRESCENT: Always visible during partial phases\n // During partials, the moon is partially lit (outside umbra)\n // Only during totality does the shadow fully cover the moon\n\n // Where is the bright crescent? Opposite side from shadow\n // Approaching (shadowX < 0): crescent on RIGHT (positive X)\n // Leaving (shadowX > 0): crescent on LEFT (negative X)\n float crescentSide = -sign(eclipseShadowPos.x);\n\n // CRESCENT EDGE: Where shadow meets lit surface\n // This is always VISIBLE during partials - never goes to zero\n float umbraEdgeX = eclipseShadowPos.x + (umbraRadius * crescentSide);\n\n // Distance from this pixel to the lit crescent edge\n // Positive = inside shadow, negative = in lit crescent\n float distFromLitEdge = (pixelX - umbraEdgeX) * crescentSide;\n\n // GRADIENT: Blood moon glow spreads from the LIT CRESCENT\n // Only pixels INSIDE the shadow get the gradient\n // Gradient is strongest at the umbra edge (where crescent is)\n float crescentGradient = smoothstep(0.5, 0.0, distFromLitEdge);\n\n // BRIGHTNESS CONTROL: Glow only appears near totality\n // When shadow is far from center: stays dark\n // When shadow approaches center: glow spreads from crescent\n float brightnessControl = umbra * crescentGradient * totalityFactor;\n\n // During full totality (shadowX ≈ 0), switch to uniform brightness\n brightnessControl = mix(brightnessControl, umbra * totalityFactor, totalityFactor);\n\n // EMISSIVE GLOW: Blood moon color spreading from crescent\n float glowStrength = mix(0.0, 1.0, brightnessControl);\n vec3 atmosphereGlow = eclipseMidtoneColor * emissiveStrength * glowStrength * umbra;\n finalColor += atmosphereGlow;\n\n // RIM GLOW: Atmospheric limb brightening\n float limbGlowStrength = mix(0.0, 1.5, brightnessControl);\n float limbGlow = pow(1.0 - rimFactor, 3.0) * umbra;\n vec3 rimColor = mix(eclipseGlowColor, eclipseHighlightColor, 0.5);\n finalColor += rimColor * limbGlow * emissiveStrength * limbGlowStrength;\n\n // ═══════════════════════════════════════════════════════════════════════════\n // ECLIPSE BLEND LAYERS (Applied AFTER blood moon color)\n // Applied throughout eclipse wherever umbra is present\n // Strength modulated by totality factor for smooth brightness transitions\n // ═══════════════════════════════════════════════════════════════════════════\n\n // Layer 1: Linear Burn @ 0.634\n if (layer1Enabled > 0.5 && effectiveProgress > 0.1) {\n vec3 blendColor1 = vec3(min(layer1Strength, 1.0));\n int mode1 = int(layer1Mode + 0.5);\n vec3 blended1 = clamp(applyBlendMode(finalColor, blendColor1, mode1), 0.0, 1.0);\n // Apply at FULL strength wherever umbra exists\n finalColor = clamp(mix(finalColor, blended1, umbra), 0.0, 1.0);\n }\n\n // Layer 2: Multiply @ 3.086 - Brightness enhancement\n if (layer2Enabled > 0.5 && effectiveProgress > 0.1) {\n // Apply full brightness boost wherever umbra exists\n vec3 brightened = clamp(finalColor * min(layer2Strength, 5.0), 0.0, 1.0);\n finalColor = mix(finalColor, brightened, umbra);\n }\n\n // Layer 3: Hard Light @ 0.351\n if (layer3Enabled > 0.5 && effectiveProgress > 0.1) {\n vec3 blendColor3 = vec3(min(layer3Strength, 1.0));\n int mode3 = int(layer3Mode + 0.5);\n vec3 blended3 = clamp(applyBlendMode(finalColor, blendColor3, mode3), 0.0, 1.0);\n // Apply at FULL strength wherever umbra exists\n finalColor = clamp(mix(finalColor, blended3, umbra), 0.0, 1.0);\n }\n\n // Layer 4: Manual UI layer\n if (layer4Enabled > 0.5 && effectiveProgress > 0.1) {\n vec3 blendColor4 = vec3(min(layer4Strength, 1.0));\n int mode4 = int(layer4Mode + 0.5);\n vec3 blended4 = clamp(applyBlendMode(finalColor, blendColor4, mode4), 0.0, 1.0);\n finalColor = clamp(mix(finalColor, blended4, umbra), 0.0, 1.0);\n }\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // UNIVERSAL BLEND MODE LAYERS (Only applied when eclipse is OFF)\n // These are manual UI-driven color grading tools\n // NOTE: These are DISABLED by default - they're NEVER used since the multiplexer\n // demo doesn't enable them. This section exists for potential future manual control.\n // ═══════════════════════════════════════════════════════════════════════════\n // INTENTIONALLY COMMENTED OUT - these would interfere with eclipse blend layers\n // if (eclipseProgress < 0.001) {\n // // Layer 1 - manual UI control only\n // if (layer1Enabled > 0.5) {\n // vec3 blendColor1 = vec3(layer1Strength);\n // int mode1 = int(layer1Mode + 0.5);\n // finalColor = applyBlendMode(finalColor, blendColor1, mode1);\n // }\n // }\n\n gl_FragColor = vec4(finalColor, opacity);\n}\n`,B=55.5,k=-85,T=-60.5,E={enabled:!0,strength:1,lockedFace:[0,0,1],lerpSpeed:10},I={new:{x:200,y:0,coverage:0},"waxing-crescent":{x:1.5,y:0,coverage:.25},"first-quarter":{x:1,y:0,coverage:.5},"waxing-gibbous":{x:.7,y:0,coverage:.75},full:{x:0,y:0,coverage:1},"waning-gibbous":{x:-.7,y:0,coverage:.75},"last-quarter":{x:-1,y:0,coverage:.5},"waning-crescent":{x:-1.5,y:0,coverage:.25}};function A(){return Object.keys(I)}function R(e){const t=(e%1+1)%1;let i;if(t<=.5){const e=2*t;i=10*Math.pow(1-e,2.5)}else{const e=2*(t-.5);if(e<=.25)i=e/.25*-.3;else if(e<=.5)i=-.3-(e-.25)/.25*.7;else if(e<=.75)i=-1-(e-.5)/.25*2;else{const t=(e-.75)/.25;i=13*Math.pow(t,.4)-3}}return{x:i,y:0,coverage:1-2*Math.abs(t-.5)}}function z(t=64,i=64){const n=new e.SphereGeometry(.5,t,i);return n.userData.tracked=!0,n}function _(e){if(e&&(e.geometry&&e.geometry.dispose(),e.material)){const{material:t}=e;t.userData&&t.userData.pendingTextures&&(t.userData.pendingTextures.forEach(({texture:e})=>{e&&e.dispose()}),t.userData.pendingTextures.clear()),t.map&&t.map.dispose(),t.normalMap&&t.normalMap.dispose(),t.uniforms&&(t.uniforms.colorMap&&t.uniforms.colorMap.value&&t.uniforms.colorMap.value.dispose(),t.uniforms.normalMap&&t.uniforms.normalMap.value&&t.uniforms.normalMap.value.dispose()),t.dispose()}}function O(t,i={}){const n=i.resolution||"2k",a=i.assetBasePath||"/assets",s=`${a}/textures/Moon/moon-color-${n}.jpg`,o=`${a}/textures/Moon/moon-normal-${n}.jpg`,r=new Map;r.set(s,{texture:null});const l=t.load(s,e=>{const t=r.get(s);t&&(t.texture=e),r.delete(s)},void 0,e=>{console.error(`❌ Failed to load moon color texture (${n}):`,e),r.delete(s)});r.set(o,{texture:null});const h=t.load(o,e=>{const t=r.get(o);t&&(t.texture=e),r.delete(o)},void 0,e=>{console.error(`❌ Failed to load moon normal map (${n}):`,e),r.delete(o)});l.wrapS=l.wrapT=e.RepeatWrapping,h.wrapS=h.wrapT=e.RepeatWrapping,l.anisotropy=16,h.anisotropy=16;const c=new e.MeshStandardMaterial({map:l,normalMap:h,normalScale:new e.Vector2(1.5,1.5),roughness:.7,metalness:0,emissive:new e.Color(.3,.3,.3),emissiveIntensity:.5,transparent:!1,side:e.FrontSide});return c.userData.pendingTextures=r,c}function F(t=new e.Color(16777215),i=0){return new e.MeshStandardMaterial({color:15263976,roughness:.9,metalness:0,emissive:t,emissiveIntensity:i})}function L(t,i={}){const n=i.resolution||"2k",a=i.glowColor||new e.Color(1,1,1),s=i.glowIntensity||1,o=i.shadowType||"crescent",r=i.assetBasePath||"/assets";let l,h;if(void 0!==i.shadowOffsetX)({shadowOffsetX:l}=i),h=void 0!==i.shadowOffsetY?i.shadowOffsetY:0;else if(void 0!==i.moonPhase){let e;"string"==typeof i.moonPhase?([e]=[I[i.moonPhase]],e||(console.warn(`Unknown moon phase: ${i.moonPhase}, using waxing-crescent`),e=I["waxing-crescent"])):e="number"==typeof i.moonPhase?R(i.moonPhase):I["waxing-crescent"],l=e.x,h=e.y}else{const e=I["waxing-crescent"];l=e.x,h=e.y}const c=void 0!==i.shadowCoverage?i.shadowCoverage:.85,u=`${r}/textures/Moon/moon-color-${n}.jpg`,d=`${r}/textures/Moon/moon-normal-${n}.jpg`,{vertexShader:m,fragmentShader:p}=function(e){return"crescent"===e||console.warn(`Unknown shadow type: ${e}, defaulting to crescent`),{vertexShader:"\n/**\n * Moon Crescent Vertex Shader\n * Passes world-space normal to fragment shader for realistic lighting\n */\n\nvarying vec3 vPosition; // LOCAL position\nvarying vec3 vWorldPosition;\nvarying vec3 vWorldNormal; // WORLD SPACE normal (rotates with moon)\nvarying vec3 vViewPosition;\nvarying vec2 vUv;\n\nvoid main() {\n vUv = uv;\n vPosition = position;\n\n // Transform normal to WORLD space (not view space)\n // This makes the shadow rotate with the moon geometry\n vWorldNormal = normalize(mat3(modelMatrix) * normal);\n\n vec4 worldPosition = modelMatrix * vec4(position, 1.0);\n vWorldPosition = worldPosition.xyz;\n vec4 viewPosition = viewMatrix * worldPosition;\n vViewPosition = viewPosition.xyz;\n gl_Position = projectionMatrix * viewPosition;\n}\n",fragmentShader:"\n/**\n * Moon Crescent Fragment Shader\n *\n * Uses directional half-space test in WORLD SPACE to create realistic terminator:\n * - Light direction fixed in world space (like the sun)\n * - Normals rotate with moon geometry (in world space)\n * - dot(normal, lightDir) < 0 = shadow side\n * - dot(normal, lightDir) > 0 = lit side\n * - Smooth terminator with earthshine on dark side\n */\n\nuniform sampler2D colorMap;\nuniform sampler2D normalMap;\nuniform vec2 shadowOffset; // Controls light direction (x=horizontal, y=vertical)\nuniform float shadowCoverage; // Unused for directional shadow\nuniform float shadowSoftness; // Terminator edge softness (default: 0.05)\nuniform vec3 glowColor;\nuniform float glowIntensity;\nuniform float opacity; // Fade in opacity (0-1) to prevent gray flash during texture load\n\n// Lunar Eclipse (Blood Moon) uniforms\nuniform float eclipseProgress; // 0.0 = no eclipse, 1.0 = totality\nuniform float eclipseIntensity; // Darkening strength (0.0-1.0)\nuniform vec3 bloodMoonColor; // Deep reddish-orange for total eclipse\nuniform float blendMode; // 0=Multiply, 1=LinearBurn, 2=ColorBurn, 3=ColorDodge, 4=Screen, 5=Overlay\nuniform float blendStrength; // Blend strength multiplier (0.0-5.0)\nuniform float emissiveStrength; // Emissive glow strength (0.0-1.0)\n\nvarying vec3 vPosition;\nvarying vec3 vWorldPosition;\nvarying vec3 vWorldNormal; // WORLD SPACE normal (rotates with moon)\nvarying vec3 vViewPosition;\nvarying vec2 vUv;\n\nvoid main() {\n // DIRECTIONAL SHADOW in WORLD SPACE - realistic moon phase lighting\n // Light direction is fixed in world space, shadow rotates with moon\n\n // Use world-space normal (rotates with moon geometry)\n vec3 worldNormal = normalize(vWorldNormal);\n\n // Light direction in WORLD SPACE\n // shadowOffset.x controls horizontal angle (left/right)\n // shadowOffset.y controls vertical angle (up/down)\n // For thin crescents, we need extreme angles (light from the side or behind)\n\n float lightX = shadowOffset.x;\n float lightY = shadowOffset.y;\n\n // Adaptive Z component with LOGARITHMIC scaling for wider angular range\n // Goal: Spread phases across full 0° to 180° instead of plateauing at 135°\n //\n // Target angles after normalization:\n // - Full moon (x=0): 0° (light from front)\n // - Quarter moon (x=1): 90° (light from side)\n // - Crescent (x=3): 120° (thin crescent)\n // - New moon (x=10): 170° (nearly behind)\n\n float offsetMagnitude = length(vec2(lightX, lightY));\n\n // Use exponential decay for Z to spread angular range\n // Formula: Z = 1.0 - offsetMagnitude^1.5 for better distribution\n float lightZ = 1.0 - pow(offsetMagnitude, 1.5);\n\n // Normalize the light direction vector\n vec3 lightDir = normalize(vec3(lightX, lightY, lightZ));\n\n // Calculate how much this fragment faces the light source\n float facing = dot(worldNormal, lightDir);\n\n // Smooth transition at terminator (shadow boundary)\n // Softer edge for realistic lunar terminator (like real moon photography)\n // Use fwidth() for automatic screen-space anti-aliasing\n float edgeWidth = max(fwidth(facing) * 4.0, shadowSoftness * 3.0);\n float shadowFactor = smoothstep(-edgeWidth, edgeWidth, facing);\n\n // Sample moon surface texture\n vec4 texColor = texture2D(colorMap, vUv);\n\n // Fallback to gray if texture not loaded yet\n float brightness = texColor.r + texColor.g + texColor.b;\n if (brightness < 0.03) {\n texColor = vec4(0.5, 0.5, 0.5, 1.0);\n }\n\n // LIMB DARKENING: Moon gets darker at edges (spherical falloff)\n vec3 viewDir = normalize(-vViewPosition);\n float rimFactor = dot(worldNormal, viewDir);\n float limbDarkening = smoothstep(0.0, 0.6, rimFactor); // Subtle edge darkening\n\n // DIFFUSE LIGHTING: Vary brightness across lit surface (not uniform)\n // More realistic Lambertian diffuse reflection\n float diffuse = max(facing, 0.0);\n float diffuseLighting = mix(0.7, 1.0, diffuse); // Subtle variation\n\n // EARTHSHINE: Almost invisible (~1% for ultimate realism)\n vec3 earthshine = texColor.rgb * 0.01 * vec3(0.35, 0.4, 0.6);\n\n // Apply dramatic shadow transition with maximum contrast\n float litFactor = pow(shadowFactor, 2.0); // Maximum contrast\n\n // TEXTURE ENHANCEMENT: Boost surface detail contrast\n // Slightly darken dark areas, brighten bright areas of texture\n vec3 detailEnhanced = texColor.rgb * 1.08; // Subtle boost\n float textureLuminance = dot(texColor.rgb, vec3(0.299, 0.587, 0.114));\n detailEnhanced = mix(texColor.rgb * 0.95, texColor.rgb * 1.12, smoothstep(0.3, 0.7, textureLuminance));\n\n // Combine enhanced texture with diffuse lighting\n vec3 litColor = detailEnhanced * diffuseLighting;\n vec3 shadowedColor = mix(earthshine, litColor, litFactor);\n\n // Apply limb darkening (slightly stronger for more depth)\n shadowedColor *= mix(0.6, 1.0, limbDarkening);\n\n // Nearly zero emissive for pure realism\n vec3 emissive = vec3(0.02, 0.02, 0.02) * shadowFactor;\n\n // Emotion glow (almost invisible)\n vec3 emotionGlow = glowColor * glowIntensity * 0.02 * shadowFactor;\n\n // Combine all lighting components\n vec3 finalColor = shadowedColor + emissive + emotionGlow;\n\n // ═══════════════════════════════════════════════════════════════════════════\n // LUNAR ECLIPSE (BLOOD MOON) EFFECT\n // ═══════════════════════════════════════════════════════════════════════════\n // Simulates Earth's umbral shadow with Rayleigh scattering (reddish glow)\n if (eclipseProgress > 0.001) {\n // Calculate gradient from lit edge to dark center\n // Use rim factor (view angle) to create radial gradient\n float gradientFactor = rimFactor; // 1.0 at edges, 0.0 at center\n\n // Darken the moon (Earth's shadow)\n float darkeningFactor = 1.0 - eclipseIntensity;\n finalColor *= darkeningFactor;\n\n // ═══════════════════════════════════════════════════════════════════\n // PHOTOSHOP-STYLE BLEND MODES: Multiple modes for deep saturation control\n // ═══════════════════════════════════════════════════════════════════\n\n // Define blood moon gradient colors\n vec3 deepRed = vec3(0.6, 0.2, 0.12); // Dark burnt red-orange (center)\n vec3 brightOrange = vec3(0.95, 0.45, 0.22); // Bright burnt orange (edges)\n\n // Create radial gradient from center (dark) to edge (bright)\n vec3 bloodGradient = mix(deepRed, brightOrange, pow(gradientFactor, 1.8));\n\n // Apply blend strength multiplier\n vec3 blendColor = bloodGradient * blendStrength;\n\n // Calculate all blend modes\n vec3 finalBlend;\n int mode = int(blendMode + 0.5); // Round to nearest int\n\n if (mode == 0) {\n // MULTIPLY: base * blend\n finalBlend = finalColor * blendColor;\n } else if (mode == 1) {\n // LINEAR BURN: base + blend - 1\n finalBlend = max(finalColor + blendColor - vec3(1.0), vec3(0.0));\n } else if (mode == 2) {\n // COLOR BURN: (blend==0.0) ? 0.0 : max((1.0-((1.0-base)/blend)), 0.0)\n finalBlend = vec3(\n blendColor.r == 0.0 ? 0.0 : max(1.0 - ((1.0 - finalColor.r) / blendColor.r), 0.0),\n blendColor.g == 0.0 ? 0.0 : max(1.0 - ((1.0 - finalColor.g) / blendColor.g), 0.0),\n blendColor.b == 0.0 ? 0.0 : max(1.0 - ((1.0 - finalColor.b) / blendColor.b), 0.0)\n );\n } else if (mode == 3) {\n // COLOR DODGE: (blend==1.0) ? 1.0 : min(base/(1.0-blend), 1.0)\n finalBlend = vec3(\n blendColor.r == 1.0 ? 1.0 : min(finalColor.r / (1.0 - blendColor.r), 1.0),\n blendColor.g == 1.0 ? 1.0 : min(finalColor.g / (1.0 - blendColor.g), 1.0),\n blendColor.b == 1.0 ? 1.0 : min(finalColor.b / (1.0 - blendColor.b), 1.0)\n );\n } else if (mode == 4) {\n // SCREEN: 1 - (1 - base) * (1 - blend)\n finalBlend = vec3(1.0) - (vec3(1.0) - finalColor) * (vec3(1.0) - blendColor);\n } else {\n // OVERLAY: base < 0.5 ? (2 * base * blend) : (1 - 2 * (1 - base) * (1 - blend))\n finalBlend = vec3(\n finalColor.r < 0.5 ? (2.0 * finalColor.r * blendColor.r) : (1.0 - 2.0 * (1.0 - finalColor.r) * (1.0 - blendColor.r)),\n finalColor.g < 0.5 ? (2.0 * finalColor.g * blendColor.g) : (1.0 - 2.0 * (1.0 - finalColor.g) * (1.0 - blendColor.g)),\n finalColor.b < 0.5 ? (2.0 * finalColor.b * blendColor.b) : (1.0 - 2.0 * (1.0 - finalColor.b) * (1.0 - blendColor.b))\n );\n }\n\n // Apply blood moon effect\n finalColor = mix(finalColor, finalBlend, eclipseProgress);\n\n // Add emissive glow for visibility\n finalColor += bloodGradient * emissiveStrength * eclipseProgress;\n\n // Add bright rim glow during totality (refracted atmosphere light)\n if (eclipseProgress > 0.7) {\n float rimIntensity = pow(gradientFactor, 2.5); // Sharp falloff from edge\n vec3 rimGlow = brightOrange * rimIntensity * (eclipseProgress - 0.7) * 2.5;\n finalColor += rimGlow;\n }\n }\n\n // Apply fade-in opacity to prevent gray flash during texture load\n gl_FragColor = vec4(finalColor, opacity);\n}\n"}}(o),g=new e.ShaderMaterial({uniforms:{colorMap:{value:null},normalMap:{value:null},shadowOffset:{value:new e.Vector2(l,h)},shadowCoverage:{value:c},shadowSoftness:{value:.05},glowColor:{value:a},glowIntensity:{value:s},opacity:{value:0},eclipseProgress:{value:0},eclipseIntensity:{value:0},bloodMoonColor:{value:[.85,.18,.08]},blendMode:{value:0},blendStrength:{value:2},emissiveStrength:{value:.39},eclipseShadowPos:{value:[-2,0]},eclipseShadowRadius:{value:1.2},eclipseShadowColor:{value:[.85,.08,.02]},eclipseMidtoneColor:{value:[1,.12,.03]},eclipseHighlightColor:{value:[1,.35,.08]},eclipseGlowColor:{value:[1,.4,.1]}},vertexShader:m,fragmentShader:p,transparent:!0,side:e.FrontSide}),f=new Map;f.set(u,{texture:null});const y=t.load(u,e=>{g.uniforms.colorMap.value=e;const t=performance.now(),i=()=>{const e=performance.now()-t,n=Math.min(e/300,1);g.uniforms.opacity.value=n,g.needsUpdate=!0,n<1&&requestAnimationFrame(i)};i();const n=f.get(u);n&&(n.texture=e),f.delete(u)},void 0,e=>{console.error("❌ Failed to load moon crescent color texture:",e),f.delete(u)});f.set(d,{texture:null});const v=t.load(d,e=>{g.uniforms.normalMap.value=e,g.needsUpdate=!0;const t=f.get(d);t&&(t.texture=e),f.delete(d)},void 0,e=>{console.error("❌ Failed to load moon crescent normal map:",e),f.delete(d)});return y.wrapS=y.wrapT=e.RepeatWrapping,v.wrapS=v.wrapT=e.RepeatWrapping,y.anisotropy=16,v.anisotropy=16,g.userData.pendingTextures=f,g}function G(e,t={}){return L(e,{...t,shadowType:"crescent"})}function V(e,t){if(!e.uniforms||!e.uniforms.shadowOffset)return console.warn("Material does not have shadowOffset uniform"),!1;let i;if("string"==typeof t){if(i=I[t],!i)return console.warn(`Unknown moon phase: ${t}`),!1}else{if("number"!=typeof t)return console.warn("Phase must be a string or number"),!1;i=R(t)}return e.uniforms.shadowOffset.value.set(i.x,i.y),!0}function q(e,t,i=2e3){let n=null,a=!1;const s=new Promise((s,o)=>{if(!e.uniforms||!e.uniforms.shadowOffset)return void o(new Error("Material does not have shadowOffset uniform"));let r;if("string"==typeof t){if(r=I[t],!r)return void o(new Error(`Unknown moon phase: ${t}`))}else{if("number"!=typeof t)return void o(new Error("Phase must be a string or number"));r=R(t)}const l=e.uniforms.shadowOffset.value.x,h=e.uniforms.shadowOffset.value.y,c=r.x,u=r.y,d=Date.now(),m=()=>{if(a)return void s({cancelled:!0});const t=Date.now()-d,o=Math.min(t/i,1),r=o<.5?4*o*o*o:1-Math.pow(-2*o+2,3)/2,p=l+(c-l)*r,g=h+(u-h)*r;e.uniforms.shadowOffset.value.set(p,g),o<1?n=requestAnimationFrame(m):s({cancelled:!1})};m()});return{promise:s,cancel:()=>{a=!0,null!==n&&(cancelAnimationFrame(n),n=null)}}}function N(e,t,i){e.emissive&&(e.emissive.copy(t),e.emissiveIntensity=i),e.uniforms&&e.uniforms.glowColor&&(e.uniforms.glowColor.value.copy(t),e.uniforms.glowIntensity.value=i)}function j(e,t,i,n){e.uniforms&&e.uniforms.shadowOffset&&(e.uniforms.shadowOffset.value.set(t,i),e.uniforms.shadowCoverage.value=n)}function U(t,i={}){const{resolution:n="2k",glowColor:a=new e.Color(16777215),glowIntensity:s=1,assetBasePath:o="/assets"}=i,{vertexShader:r,fragmentShader:l}={vertexShader:"\n/**\n * Moon Vertex Shader\n * Passes view-space normal for camera-relative moon phase shadows\n */\n\nvarying vec3 vPosition; // LOCAL position (object space)\nvarying vec3 vWorldPosition;\nvarying vec3 vViewNormal; // VIEW SPACE normal (fixed relative to camera)\nvarying vec3 vViewPosition;\nvarying vec2 vUv;\n\nvoid main() {\n vUv = uv;\n vPosition = position;\n\n // Transform normal to VIEW space (camera-relative)\n // This keeps the moon phase shadow fixed relative to camera view\n // When you rotate the moon, the texture rotates but the phase shadow stays put\n vViewNormal = normalize(normalMatrix * normal);\n\n vec4 worldPosition = modelMatrix * vec4(position, 1.0);\n vWorldPosition = worldPosition.xyz;\n vec4 viewPosition = viewMatrix * worldPosition;\n vViewPosition = viewPosition.xyz;\n gl_Position = projectionMatrix * viewPosition;\n}\n",fragmentShader:P},h=new e.ShaderMaterial({uniforms:{colorMap:{value:null},normalMap:{value:null},shadowOffset:{value:new e.Vector2(0,0)},shadowCoverage:{value:.5},shadowSoftness:{value:.05},glowColor:{value:a},glowIntensity:{value:s},opacity:{value:0},eclipseProgress:{value:0},eclipseIntensity:{value:0},bloodMoonColor:{value:[.85,.18,.08]},emissiveStrength:{value:.39},eclipseShadowPos:{value:[-2,0]},eclipseShadowRadius:{value:1.2},eclipseShadowColor:{value:[1,.58,0]},eclipseMidtoneColor:{value:[.71,.43,.03]},eclipseHighlightColor:{value:[1,.28,.1]},eclipseGlowColor:{value:[.09,.09,.09]},eclipseBrightnessModel:{value:0},shadowDarkness:{value:.53},layer1Mode:{value:9},layer1Strength:{value:.322},layer1Enabled:{value:1},layer2Mode:{value:0},layer2Strength:{value:2.785},layer2Enabled:{value:1},layer3Mode:{value:7},layer3Strength:{value:.199},layer3Enabled:{value:1},layer4Mode:{value:0},layer4Strength:{value:0},layer4Enabled:{value:0}},vertexShader:r,fragmentShader:l,transparent:!0,depthWrite:!0,side:e.FrontSide}),c=`${o}/textures/Moon/moon-color-${n}.jpg`,u=`${o}/textures/Moon/moon-normal-${n}.jpg`;return t.load(c,e=>{h.uniforms.colorMap.value=e;const t=performance.now(),i=()=>{const e=performance.now()-t,n=Math.min(e/300,1);h.uniforms.opacity.value=n,h.needsUpdate=!0,n<1&&requestAnimationFrame(i)};i()}),t.load(u,e=>{h.uniforms.normalMap.value=e}),h}const H=`\n/**\n * Sun Fragment Shader with Blend Layers and Solar Eclipse\n *\n * Supports solar eclipse effects with moon's shadow darkening the sun\n * and up to 4 sequential blend mode layers for eclipse appearance adjustment\n */\n\nuniform float time;\nuniform sampler2D colorMap;\nuniform sampler2D normalMap;\nuniform vec3 baseColor;\nuniform float emissiveIntensity;\nuniform vec2 shadowOffset;\nuniform float shadowCoverage;\nuniform float shadowSoftness;\nuniform float opacity;\n\n// Solar Eclipse uniforms (moon's shadow covering sun)\nuniform float eclipseProgress; // Eclipse progress (0 = no eclipse, 1 = totality)\nuniform vec2 eclipseShadowPos; // Shadow center position in UV space\nuniform float eclipseShadowRadius; // Moon's shadow radius\nuniform float shadowDarkness; // How much to darken the sun (0-1)\n\n// Blend Layer Uniforms (up to 4 layers)\nuniform float layer1Mode;\nuniform float layer1Strength;\nuniform float layer1Enabled;\n\nuniform float layer2Mode;\nuniform float layer2Strength;\nuniform float layer2Enabled;\n\nuniform float layer3Mode;\nuniform float layer3Strength;\nuniform float layer3Enabled;\n\nuniform float layer4Mode;\nuniform float layer4Strength;\nuniform float layer4Enabled;\n\nvarying vec2 vUv;\nvarying vec3 vNormal;\nvarying vec3 vPosition;\nvarying vec3 vWorldPosition;\nvarying vec3 vViewPosition; // View-space position (camera-relative)\n\n// ═══════════════════════════════════════════════════════════════════════════\n// UNIVERSAL BLEND MODES (injected from utils/blendModes.js)\n// ═══════════════════════════════════════════════════════════════════════════\n${S}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// SIMPLEX NOISE (for fire animation - from original sun shader)\n// ═══════════════════════════════════════════════════════════════════════════\nvec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }\nvec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }\nvec4 permute(vec4 x) { return mod289(((x*34.0)+1.0)*x); }\nvec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; }\n\nfloat snoise(vec3 v) {\n const vec2 C = vec2(1.0/6.0, 1.0/3.0);\n const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);\n\n vec3 i = floor(v + dot(v, C.yyy));\n vec3 x0 = v - i + dot(i, C.xxx);\n\n vec3 g = step(x0.yzx, x0.xyz);\n vec3 l = 1.0 - g;\n vec3 i1 = min(g.xyz, l.zxy);\n vec3 i2 = max(g.xyz, l.zxy);\n\n vec3 x1 = x0 - i1 + C.xxx;\n vec3 x2 = x0 - i2 + C.yyy;\n vec3 x3 = x0 - D.yyy;\n\n i = mod289(i);\n vec4 p = permute(permute(permute(\n i.z + vec4(0.0, i1.z, i2.z, 1.0))\n + i.y + vec4(0.0, i1.y, i2.y, 1.0))\n + i.x + vec4(0.0, i1.x, i2.x, 1.0));\n\n float n_ = 0.142857142857;\n vec3 ns = n_ * D.wyz - D.xzx;\n\n vec4 j = p - 49.0 * floor(p * ns.z * ns.z);\n\n vec4 x_ = floor(j * ns.z);\n vec4 y_ = floor(j - 7.0 * x_);\n\n vec4 x = x_ *ns.x + ns.yyyy;\n vec4 y = y_ *ns.x + ns.yyyy;\n vec4 h = 1.0 - abs(x) - abs(y);\n\n vec4 b0 = vec4(x.xy, y.xy);\n vec4 b1 = vec4(x.zw, y.zw);\n\n vec4 s0 = floor(b0)*2.0 + 1.0;\n vec4 s1 = floor(b1)*2.0 + 1.0;\n vec4 sh = -step(h, vec4(0.0));\n\n vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy;\n vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww;\n\n vec3 p0 = vec3(a0.xy, h.x);\n vec3 p1 = vec3(a0.zw, h.y);\n vec3 p2 = vec3(a1.xy, h.z);\n vec3 p3 = vec3(a1.zw, h.w);\n\n vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2,p2), dot(p3,p3)));\n p0 *= norm.x;\n p1 *= norm.y;\n p2 *= norm.z;\n p3 *= norm.w;\n\n vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);\n m = m * m;\n return 42.0 * dot(m*m, vec4(dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3)));\n}\n\nvoid main() {\n // ═══════════════════════════════════════════════════════════════════════════\n // BASE SUN RENDERING (photosphere texture + fire animation)\n // ═══════════════════════════════════════════════════════════════════════════\n\n // Sample base photosphere texture\n vec4 texColor = texture2D(colorMap, vUv);\n\n // Optimized single-octave noise for subtle fire\n vec3 noiseCoord = vPosition * 30.0 + vec3(0.0, time * 0.025, 0.0);\n float fireNoise = snoise(noiseCoord);\n\n // Simple threshold - fire appears only in specific noise ranges\n float fireMask = fireNoise * 0.5 + 0.5; // Remap -1..1 to 0..1\n fireMask = step(0.45, fireMask) * (1.0 - step(0.55, fireMask)); // Only 0.45-0.55 range\n\n // Almost imperceptible warmth shift\n vec3 fireColor = vec3(1.01, 1.0, 0.99);\n\n // Microscopic blending\n vec3 finalColor = mix(texColor.rgb, fireColor, fireMask * 0.008);\n\n // Apply base color tinting\n finalColor *= baseColor;\n\n // Apply emissive intensity for HDR bloom\n finalColor *= emissiveIntensity;\n\n // ═══════════════════════════════════════════════════════════════════════════\n // LIMB DARKENING (realistic solar effect - edges appear darker than center)\n // ═══════════════════════════════════════════════════════════════════════════\n\n // Calculate distance from center (0 at center, 1 at edge)\n float distFromCenterLimb = length(vWorldPosition.xy) / 0.5; // normalize by sun radius (0.5)\n distFromCenterLimb = clamp(distFromCenterLimb, 0.0, 1.0);\n\n // Limb darkening formula: I(μ) = 1 - u*(1-μ) where μ = cos(viewing angle)\n // Simplified using distance: darker at edges, brighter at center\n float mu = sqrt(1.0 - distFromCenterLimb * distFromCenterLimb); // cos approximation\n // EXTREME limb darkening for visibility\n float limbDarkeningCoeff = 0.98; // 98% darkening at edges\n float limbBrightness = 1.0 - limbDarkeningCoeff * (1.0 - mu);\n limbBrightness = pow(limbBrightness, 0.4); // Very aggressive power curve\n\n // Clamp to prevent over-darkening\n limbBrightness = max(limbBrightness, 0.02); // Edges at least 2% brightness\n\n // Apply limb darkening (BEFORE bloom processing)\n finalColor *= limbBrightness;\n\n // ═══════════════════════════════════════════════════════════════════════════\n // SOLAR ECLIPSE EFFECT (Moon Occulting Sun)\n // ═══════════════════════════════════════════════════════════════════════════\n // Solar eclipse: Moon passes BETWEEN viewer and sun, blocking our view\n // The moon appears as a dark circular disk that covers parts of the sun\n // From Earth, moon and sun appear same angular size (0.5°)\n\n // Only apply eclipse if there's a moon to occlude (radius > 0)\n if (eclipseShadowRadius > 0.01) {\n // Only occlude FRONT-FACING parts of the sun (vViewPosition.z < 0 faces camera in view space)\n // Back of sun should not be affected by moon\n if (vViewPosition.z < 0.1) {\n // Project to screen space - camera-relative, independent of sun rotation\n // vViewPosition.xy is already in camera space, just normalize to sun radius\n // Sun radius in view space is approximately 0.5 at typical camera distance\n vec2 screenPos = vViewPosition.xy;\n\n // Moon center position in screen space (same coordinate system)\n vec2 moonCenter = eclipseShadowPos;\n\n // Distance from this sun point to moon center (2D screen space)\n float distToMoon = length(screenPos - moonCenter);\n\n // Moon's angular size (appears same size as sun from Earth)\n // In normalized screen space, sun radius = 1.0, moon radius = 1.0 for total eclipse\n float moonRadius = eclipseShadowRadius;\n float moonEdge = 0.01; // Sharp edge for moon silhouette\n\n // Check if moon blocks this point (moon is in front of sun)\n float moonOcclusion = 1.0 - smoothstep(moonRadius - moonEdge, moonRadius + moonEdge, distToMoon);\n\n // Only apply if moon is actually occluding something\n if (moonOcclusion > 0.001) {\n // Moon completely blocks sun where it overlaps (no light gets through)\n finalColor *= (1.0 - moonOcclusion);\n\n // Subtle penumbra around moon edge (diffraction)\n float penumbraRadius = moonRadius * 1.02;\n float penumbraEdge = 0.03;\n float penumbra = 1.0 - smoothstep(penumbraRadius - penumbraEdge, penumbraRadius + penumbraEdge, distToMoon);\n float penumbraBlocking = (penumbra - moonOcclusion) * 0.2;\n finalColor *= (1.0 - penumbraBlocking);\n }\n }\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // BLEND LAYERS (Applied globally to entire sun)\n // These allow adjusting the appearance of the sun\n // ═══════════════════════════════════════════════════════════════════════════\n\n // Layer 1\n if (layer1Enabled > 0.5) {\n vec3 blendColor1 = vec3(min(layer1Strength, 1.0));\n int mode1 = int(layer1Mode + 0.5);\n vec3 blended1 = clamp(applyBlendMode(finalColor, blendColor1, mode1), 0.0, 1.0);\n finalColor = clamp(blended1, 0.0, 1.0);\n }\n\n // Layer 2\n if (layer2Enabled > 0.5) {\n vec3 blendColor2 = vec3(min(layer2Strength, 1.0));\n int mode2 = int(layer2Mode + 0.5);\n vec3 blended2 = clamp(applyBlendMode(finalColor, blendColor2, mode2), 0.0, 1.0);\n finalColor = clamp(blended2, 0.0, 1.0);\n }\n\n // Layer 3\n if (layer3Enabled > 0.5) {\n vec3 blendColor3 = vec3(min(layer3Strength, 1.0));\n int mode3 = int(layer3Mode + 0.5);\n vec3 blended3 = clamp(applyBlendMode(finalColor, blendColor3, mode3), 0.0, 1.0);\n finalColor = clamp(blended3, 0.0, 1.0);\n }\n\n // Layer 4\n if (layer4Enabled > 0.5) {\n vec3 blendColor4 = vec3(min(layer4Strength, 1.0));\n int mode4 = int(layer4Mode + 0.5);\n vec3 blended4 = clamp(applyBlendMode(finalColor, blendColor4, mode4), 0.0, 1.0);\n finalColor = clamp(blended4, 0.0, 1.0);\n }\n\n // Apply fade-in opacity to prevent texture flash during load\n gl_FragColor = vec4(finalColor, opacity);\n}\n`,W={baseSpeed:.01,axes:[0,1,0]};function X(t,i={}){const n=i.resolution||"4k",a=i.glowColor||[1,1,1],s=i.glowIntensity||1,o=i.materialVariant||null,r=i.assetBasePath||"/assets",l=`${r}/textures/Sun/sun-photosphere-${n}.jpg`,h=`${r}/textures/Sun/sun-photosphere-normal-${n}.jpg`,c=1+2*s,u=new e.Color(c*a[0],c*a[1],c*a[2]*.95),d=new Map;d.set(l,{texture:null});const m=t.load(l,e=>{v.uniforms?.opacity&&(v.uniforms.opacity.value=1);const t=d.get(l);t&&(t.texture=e),d.delete(l)},void 0,e=>{console.warn(`⚠️ Failed to load sun texture (${n}), using color fallback:`,e),d.delete(l)});d.set(h,{texture:null});const p=t.load(h,e=>{const t=d.get(h);t&&(t.texture=e),d.delete(h)},void 0,e=>{console.warn(`⚠️ Sun normal map not found (${n}), continuing without surface detail:`,e),d.delete(h)});let g,f;m.wrapS=m.wrapT=e.RepeatWrapping,p.wrapS=p.wrapT=e.RepeatWrapping,m.anisotropy=16,p.anisotropy=16;let y={};if("multiplexer"===o){const{vertexShader:e,fragmentShader:t}={vertexShader:"\n/**\n * Sun Vertex Shader\n * Passes view-space position for camera-relative eclipse shadow calculations\n */\n\nvarying vec2 vUv;\nvarying vec3 vNormal;\nvarying vec3 vPosition;\nvarying vec3 vWorldPosition;\nvarying vec3 vViewPosition; // View-space position (camera-relative)\n\nvoid main() {\n vUv = uv;\n vNormal = normalize(normalMatrix * normal);\n vPosition = position;\n vWorldPosition = (modelMatrix * vec4(position, 1.0)).xyz;\n\n // Calculate view-space position (camera-relative, always faces camera)\n vec4 viewPos = modelViewMatrix * vec4(position, 1.0);\n vViewPosition = viewPos.xyz;\n\n gl_Position = projectionMatrix * viewPos;\n}\n",fragmentShader:H};g=e,f=t,y={eclipseProgress:{value:0},eclipseShadowPos:{value:[-2,0]},eclipseShadowRadius:{value:.882},shadowDarkness:{value:1},layer1Mode:{value:0},layer1Strength:{value:.23},layer1Enabled:{value:1},layer2Mode:{value:0},layer2Strength:{value:0},layer2Enabled:{value:0},layer3Mode:{value:0},layer3Strength:{value:0},layer3Enabled:{value:0},layer4Mode:{value:0},layer4Strength:{value:0},layer4Enabled:{value:0}}}else g="\n varying vec2 vUv;\n varying vec3 vNormal;\n varying vec3 vPosition;\n varying vec3 vWorldPosition;\n\n void main() {\n vUv = uv;\n vNormal = normalize(normalMatrix * normal);\n vPosition = position;\n vWorldPosition = (modelMatrix * vec4(position, 1.0)).xyz;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n ",f="\n uniform float time;\n uniform sampler2D colorMap;\n uniform sampler2D normalMap;\n uniform vec3 baseColor;\n uniform float emissiveIntensity;\n uniform vec2 shadowOffset;\n uniform float shadowCoverage;\n uniform float shadowSoftness;\n uniform float opacity; // Fade in opacity (0-1) to prevent texture flash\n\n varying vec2 vUv;\n varying vec3 vNormal;\n varying vec3 vPosition;\n varying vec3 vWorldPosition;\n\n // Simplex noise for fire animation (Ashima Arts)\n vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }\n vec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }\n vec4 permute(vec4 x) { return mod289(((x*34.0)+1.0)*x); }\n vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; }\n\n float snoise(vec3 v) {\n const vec2 C = vec2(1.0/6.0, 1.0/3.0);\n const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);\n\n vec3 i = floor(v + dot(v, C.yyy));\n vec3 x0 = v - i + dot(i, C.xxx);\n\n vec3 g = step(x0.yzx, x0.xyz);\n vec3 l = 1.0 - g;\n vec3 i1 = min(g.xyz, l.zxy);\n vec3 i2 = max(g.xyz, l.zxy);\n\n vec3 x1 = x0 - i1 + C.xxx;\n vec3 x2 = x0 - i2 + C.yyy;\n vec3 x3 = x0 - D.yyy;\n\n i = mod289(i);\n vec4 p = permute(permute(permute(\n i.z + vec4(0.0, i1.z, i2.z, 1.0))\n + i.y + vec4(0.0, i1.y, i2.y, 1.0))\n + i.x + vec4(0.0, i1.x, i2.x, 1.0));\n\n float n_ = 0.142857142857;\n vec3 ns = n_ * D.wyz - D.xzx;\n\n vec4 j = p - 49.0 * floor(p * ns.z * ns.z);\n\n vec4 x_ = floor(j * ns.z);\n vec4 y_ = floor(j - 7.0 * x_);\n\n vec4 x = x_ *ns.x + ns.yyyy;\n vec4 y = y_ *ns.x + ns.yyyy;\n vec4 h = 1.0 - abs(x) - abs(y);\n\n vec4 b0 = vec4(x.xy, y.xy);\n vec4 b1 = vec4(x.zw, y.zw);\n\n vec4 s0 = floor(b0)*2.0 + 1.0;\n vec4 s1 = floor(b1)*2.0 + 1.0;\n vec4 sh = -step(h, vec4(0.0));\n\n vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy;\n vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww;\n\n vec3 p0 = vec3(a0.xy, h.x);\n vec3 p1 = vec3(a0.zw, h.y);\n vec3 p2 = vec3(a1.xy, h.z);\n vec3 p3 = vec3(a1.zw, h.w);\n\n vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2,p2), dot(p3,p3)));\n p0 *= norm.x;\n p1 *= norm.y;\n p2 *= norm.z;\n p3 *= norm.w;\n\n vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);\n m = m * m;\n return 42.0 * dot(m*m, vec4(dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3)));\n }\n\n void main() {\n // Sample base photosphere texture\n vec4 texColor = texture2D(colorMap, vUv);\n\n // Optimized single-octave noise for subtle fire (was 2 FBM calls with 3 octaves each)\n // Using position-based noise with time offset for animation\n vec3 noiseCoord = vPosition * 30.0 + vec3(0.0, time * 0.025, 0.0);\n float fireNoise = snoise(noiseCoord);\n\n // Simple threshold - fire appears only in specific noise ranges\n // Using step functions instead of smoothstep for performance\n float fireMask = fireNoise * 0.5 + 0.5; // Remap -1..1 to 0..1\n fireMask = step(0.45, fireMask) * (1.0 - step(0.55, fireMask)); // Only 0.45-0.55 range\n\n // Almost imperceptible warmth shift (same visual as before)\n vec3 fireColor = vec3(1.01, 1.0, 0.99);\n\n // Microscopic blending - nearly invisible (same blend factor)\n vec3 finalColor = mix(texColor.rgb, fireColor, fireMask * 0.008);\n\n // Apply base color tinting\n finalColor *= baseColor;\n\n // Apply emissive intensity for HDR bloom\n finalColor *= emissiveIntensity;\n\n // ═══════════════════════════════════════════════════════════════════════════\n // LIMB DARKENING (realistic solar effect - edges appear darker than center)\n // ═══════════════════════════════════════════════════════════════════════════\n\n // Calculate distance from center (0 at center, 1 at edge)\n float distFromCenterLimb = length(vWorldPosition.xy) / 0.5; // normalize by sun radius (0.5)\n distFromCenterLimb = clamp(distFromCenterLimb, 0.0, 1.0);\n\n // Limb darkening formula: I(μ) = 1 - u*(1-μ) where μ = cos(viewing angle)\n // Simplified using distance: darker at edges, brighter at center\n float mu = sqrt(1.0 - distFromCenterLimb * distFromCenterLimb); // cos approximation\n float limbDarkeningCoeff = 0.6; // NASA solar data: ~60% darkening at limb\n float limbBrightness = 1.0 - limbDarkeningCoeff * (1.0 - mu);\n\n // Apply limb darkening (preserves bright core for bloom)\n finalColor *= limbBrightness;\n\n // ═══════════════════════════════════════════════════════════════════════════\n // SHADOW DARKENING (applied AFTER bloom intensity so it doesn't affect bloom)\n // ═══════════════════════════════════════════════════════════════════════════\n\n // Sun sphere center (world space origin)\n float sunRadius = 0.5; // Matches geometry radius\n\n // Shadow sphere center (offset from sun center)\n vec3 shadowCenter = vec3(shadowOffset.x, shadowOffset.y, 0.0);\n\n // Calculate distance from fragment to shadow sphere center\n float distToShadow = distance(vWorldPosition, shadowCenter);\n\n // Shadow threshold (shadow sphere radius adjusted by coverage)\n float shadowRadius = sunRadius * shadowCoverage;\n\n // Calculate shadow factor (0 = full shadow, 1 = no shadow)\n float shadowFactor = smoothstep(shadowRadius - shadowSoftness, shadowRadius + shadowSoftness, distToShadow);\n\n // Darken ONLY the final color output (not the bloom calculation)\n float shadowDarkness = 0.05; // How dark the shadow gets (5% brightness)\n finalColor *= mix(shadowDarkness, 1.0, shadowFactor);\n\n // ═══════════════════════════════════════════════════════════════════════════\n // RADIAL CORONA WAVES (applied AFTER shadow, visible around eclipse edge)\n // ═══════════════════════════════════════════════════════════════════════════\n\n // Calculate angle from sun center in world space XY plane\n float angle = atan(vWorldPosition.y, vWorldPosition.x);\n\n // Create radial wave pattern (16 petals for finer detail, rotating slowly)\n float wave = sin(angle * 16.0 + time * 0.3) * 0.5 + 0.5;\n\n // Apply waves to visible (non-shadowed) edges\n float distFromCenter = length(vWorldPosition.xy);\n\n // Edge factor: strong at sun's edge where bloom will amplify it\n float edgeFactor = smoothstep(0.35, 0.5, distFromCenter);\n\n // Only apply waves to non-shadowed areas (visible during eclipse)\n // Combine with shadow factor so waves appear around shadow edge\n float waveStrength = edgeFactor * shadowFactor;\n\n // Very strong modulation (2x variation) for dramatic eclipse corona\n float coronaModulation = 1.0 + (wave * 2.0 - 1.0) * waveStrength;\n finalColor *= coronaModulation;\n\n // Apply fade-in opacity to prevent texture flash during load\n gl_FragColor = vec4(finalColor, opacity);\n }\n ";const v=new e.ShaderMaterial({uniforms:{time:{value:0},colorMap:{value:m},normalMap:{value:p},baseColor:{value:u},emissiveIntensity:{value:1.2},glowColor:{value:new e.Color(1,1,1)},glowIntensity:{value:1},shadowOffset:{value:new e.Vector2(200,0)},shadowCoverage:{value:.5},shadowSoftness:{value:.1},opacity:{value:0},...y},vertexShader:g,fragmentShader:f,transparent:!0,toneMapped:!1});return v.userData.uniforms=v.uniforms,v.userData.pendingTextures=d,v}function Y(t=null,i={}){const n=i.glowColor||[1,1,1],a=i.glowIntensity||1,s=i.resolution||"4k",o=i.materialVariant||null,r=new e.SphereGeometry(.5,128,128);let l;if(r.userData.tracked=!0,t)l=X(t,{glowColor:n,glowIntensity:a,resolution:s,materialVariant:o});else{const t=1+2*a,i=new e.Color(t*n[0],t*n[1],t*n[2]*.95);l=new e.MeshBasicMaterial({color:i,toneMapped:!1})}const h=new e.Mesh(r,l);return h.castShadow=!1,h.receiveShadow=!1,h}function $(e,t,i=1,n=0){if(!e||!e.material)return;const{material:a}=e;if(a.uniforms&&a.uniforms.baseColor){const{uniforms:e}=a;n>0&&(e.time.value=(e.time.value+n)%(2*Math.PI));const t=1+2*i;e.baseColor.value.setRGB(t,t,.95*t),e.emissiveIntensity.value=1.2}else if(a.color){const e=1+2*i;a.color.setRGB(e,e,.95*e)}}function Q(e){if(e&&(e.geometry&&e.geometry.dispose(),e.material)){const{material:t}=e;t.userData&&t.userData.pendingTextures&&(t.userData.pendingTextures.forEach(({texture:e})=>{e&&e.dispose()}),t.userData.pendingTextures.clear()),t.uniforms&&(t.uniforms.colorMap&&t.uniforms.colorMap.value&&t.uniforms.colorMap.value.dispose(),t.uniforms.normalMap&&t.uniforms.normalMap.value&&t.uniforms.normalMap.value.dispose()),t.map&&t.map.dispose(),t.normalMap&&t.normalMap.dispose(),t.dispose()}}function Z(){const t=new e.SphereGeometry(.5,32,32),i=t.attributes.position;for(let e=0;e<i.count;e++){let t=i.getX(e);const n=i.getY(e);let a=i.getZ(e);const s=1+.3*Math.max(0,n);if(t*=s,a*=.8*s,n<-.3){const e=(-n-.3)/.2;t*=1-.8*e,a*=1-.8*e}i.setXYZ(e,t,n,a)}return t.computeVertexNormals(),t}function J(){const t=new e.DodecahedronGeometry(.5,0);return t.computeVertexNormals(),t}function K(){const t=new e.BufferGeometry,i=[],n=[];i.push(0,2.3,0);for(let e=0;e<6;e++){const t=e/6*Math.PI*2;i.push(1*Math.cos(t),1.5,1*Math.sin(t))}for(let e=0;e<6;e++){const t=e/6*Math.PI*2;i.push(1*Math.cos(t),-1.5,1*Math.sin(t))}i.push(0,-2.3,0);for(let e=0;e<6;e++){const t=(e+1)%6;n.push(0,1+e,1+t)}for(let e=0;e<6;e++){const t=(e+1)%6;n.push(1+e,7+e,1+t),n.push(1+t,7+e,7+t)}for(let e=0;e<6;e++){const t=(e+1)%6;n.push(13,7+t,7+e)}t.setAttribute("position",new e.Float32BufferAttribute(i,3)),t.setIndex(n);const a=1.6/4.6;return t.scale(a,a,a),t.computeVertexNormals(),t}function ee(t=.4,i=.15,n=32,a=64){return new e.TorusGeometry(t,i,n,a)}function te(t=.5,i=1){return new e.IcosahedronGeometry(t,i)}const ie={sphere:{geometry:function(t=64,i=64){return new e.SphereGeometry(.5,t,i)}(64,64),blink:{type:"vertical-squish",duration:150,scaleAxis:[1,.3,1],curve:"sine",playful:{anticipation:.03,overshoot:.05}}},torus:{geometry:ee(),blink:{type:"vertical-squish",duration:150,scaleAxis:[1,.4,1],rotation:[0,0,Math.PI/8],curve:"sine"}},icosahedron:{geometry:te(.5,1),blink:{type:"geometric-pulse",duration:130,scaleAxis:[.7,.7,.7],curve:"sine"}},octahedron:{geometry:function(t=.5,i=0){return new e.OctahedronGeometry(t,i)}(.5,0),blink:{type:"geometric-pulse",duration:130,scaleAxis:[.7,.7,.7],curve:"sine"}},tetrahedron:{geometry:function(t=.5,i=0){return new e.TetrahedronGeometry(t,i)}(.5,0),blink:{type:"geometric-pulse",duration:110,scaleAxis:[.75,.75,.75],rotation:[Math.PI/6,0,0],curve:"sine"}},dodecahedron:{geometry:function(t=.5,i=0){return new e.DodecahedronGeometry(t,i)}(.5,0),blink:{type:"facet-flash",duration:140,scaleAxis:[.75,.75,.75],glowBoost:.4,curve:"sine"}},"smooth-icosahedron":{geometry:te(.5,2),blink:{type:"geometric-pulse",duration:140,scaleAxis:[.75,.75,.75],curve:"sine"}},"faceted-icosahedron":{geometry:te(.5,0),blink:{type:"facet-flash",duration:120,scaleAxis:[.7,.7,.7],glowBoost:.3,curve:"sine"}},ring:{geometry:ee(.4,.1,16,64),blink:{type:"vertical-squish",duration:140,scaleAxis:[1,.5,1],curve:"sine"}},moon:{geometry:z(64,64),material:"custom",blink:{type:"gentle-pulse",duration:180,scaleAxis:[.95,.95,.95],glowBoost:.2,curve:"sine"},particleRadiusMultiplier:1.4},sun:{geometry:new e.SphereGeometry(.5,64,64),material:"emissive",blink:{type:"radial-pulse",duration:200,scaleAxis:[1.05,1.05,1.05],glowBoost:.5,curve:"sine"},particleRadiusMultiplier:1.5},crystal:{geometry:null,geometryLoader:function(t="/assets"){return new Promise((i,n)=>{(new f).load(`${t}/models/Crystal/crystal.obj`,t=>{let n=null;if(t.traverse(e=>{e.isMesh&&e.geometry&&({geometry:n}=e)}),n){n.computeBoundingBox();const t=new e.Vector3;n.boundingBox.getCenter(t),n.translate(-t.x,-t.y,-t.z);const a=new e.Vector3;n.boundingBox.getSize(a);const s=1.6/Math.max(a.x,a.y,a.z);n.scale(s,s,s),n.attributes.normal||n.computeVertexNormals(),n.computeBoundingBox();const o=new e.Vector3;n.boundingBox.getSize(o);let r=n;r.computeVertexNormals(),i(r)}else{console.warn("💎 [CRYSTAL] No mesh in OBJ, using fallback");const e=K();i(e)}},e=>{},e=>{console.warn("💎 [CRYSTAL] OBJ load FAILED:",e);const t=K();i(t)})})},material:"custom",blink:{type:"facet-flash",duration:160,scaleAxis:[.95,.95,.95],glowBoost:.4,curve:"sine"},particleRadiusMultiplier:1.4},rough:{geometry:null,geometryLoader:function(t="/assets"){return new Promise(i=>{(new f).load(`${t}/models/Crystal/rough.obj`,t=>{let n=null;if(t.traverse(e=>{e.isMesh&&e.geometry&&({geometry:n}=e)}),n){n.computeBoundingBox();const t=new e.Vector3;n.boundingBox.getCenter(t),n.translate(-t.x,-t.y,-t.z);const a=new e.Vector3;n.boundingBox.getSize(a);const s=1.6/Math.max(a.x,a.y,a.z);n.scale(s,s,s),n.computeVertexNormals(),n.computeBoundingBox(),i(n)}else console.warn("💎 [ROUGH] No mesh in OBJ, using fallback sphere"),i(new e.SphereGeometry(.5,32,32))},void 0,t=>{console.warn("💎 [ROUGH] OBJ load failed:",t),i(new e.SphereGeometry(.5,32,32))})})},material:"custom",blink:{type:"facet-flash",duration:150,scaleAxis:[.95,.95,.95],glowBoost:.5,curve:"sine"},particleRadiusMultiplier:1.3},heart:{geometry:null,geometryLoader:function(t="/assets"){return new Promise(i=>{(new f).load(`${t}/models/Crystal/heart.obj`,t=>{let n=null;if(t.traverse(e=>{e.isMesh&&e.geometry&&({geometry:n}=e)}),n){n.computeBoundingBox();const t=new e.Vector3;n.boundingBox.getCenter(t),n.translate(-t.x,-t.y,-t.z);const a=new e.Vector3;n.boundingBox.getSize(a);const s=1.2/Math.max(a.x,a.y,a.z);n.scale(s,s,s),n.computeVertexNormals(),n.computeBoundingBox(),n.attributes.uv||function(t){t.computeBoundingBox();const i=t.boundingBox,n=t.attributes.position,a=new Float32Array(2*n.count),s=i.max.x-i.min.x,o=i.max.y-i.min.y;for(let e=0;e<n.count;e++){const t=n.getX(e),r=n.getY(e);a[2*e]=(t-i.min.x)/s,a[2*e+1]=(r-i.min.y)/o}t.setAttribute("uv",new e.BufferAttribute(a,2))}(n),i(n)}else console.warn("💗 [HEART] No mesh in OBJ, using fallback"),i(Z())},void 0,e=>{console.warn("💗 [HEART] OBJ load failed:",e),i(Z())})})},material:"custom",blink:{type:"gentle-pulse",duration:180,scaleAxis:[.92,.92,.92],glowBoost:.6,curve:"sine"},particleRadiusMultiplier:1.3},star:{geometry:null,geometryLoader:function(t="/assets"){return new Promise(i=>{(new f).load(`${t}/models/Crystal/star.obj`,t=>{let n=null;if(t.traverse(e=>{e.isMesh&&e.geometry&&({geometry:n}=e)}),n){n.computeBoundingBox();const t=new e.Vector3;n.boundingBox.getCenter(t),n.translate(-t.x,-t.y,-t.z);const a=new e.Vector3;n.boundingBox.getSize(a);const s=1.4/Math.max(a.x,a.y,a.z);n.scale(s,s,s),n.computeVertexNormals(),n.computeBoundingBox(),n.attributes.uv||function(t){t.computeBoundingBox();const i=t.boundingBox,n=t.attributes.position,a=new Float32Array(2*n.count),s=i.max.x-i.min.x,o=i.max.y-i.min.y;for(let e=0;e<n.count;e++){const t=n.getX(e),r=n.getY(e);a[2*e]=(t-i.min.x)/s,a[2*e+1]=(r-i.min.y)/o}t.setAttribute("uv",new e.BufferAttribute(a,2))}(n),i(n)}else console.warn("⭐ [STAR] No mesh in OBJ, using fallback"),i(J())},void 0,e=>{console.warn("⭐ [STAR] OBJ load failed:",e),i(J())})})},material:"custom",blink:{type:"facet-flash",duration:150,scaleAxis:[.93,.93,.93],glowBoost:.5,curve:"sine"},particleRadiusMultiplier:1.4}};class ne{constructor(){this.currentAnimation=null,this.animations=[],this.time=0}playEmotion(e,t={}){const i=this.createEmotionAnimation(e);this.startAnimation(i,t)}playGesture(e,t={}){const i=this.createGestureAnimation(e);this.startAnimation(i,t)}playMorph(e,t,i={}){const n=this.createMorphAnimation(e,t);this.startAnimation(n,i)}update(e){this.time+=e;for(let e=this.animations.length-1;e>=0;e--){const t=this.animations[e],i=t.duration;Math.min((this.time-t.startTime)/i,1)>=1&&(t.callbacks&&t.callbacks.onComplete&&t.callbacks.onComplete(),this.animations.splice(e,1))}}createEmotionAnimation(e){const t={joy:{duration:.6,evaluate:e=>({scale:1+.15*Math.sin(e*Math.PI),glowIntensity:1+.15*Math.sin(e*Math.PI)})},love:{duration:1.2,evaluate:e=>({scale:1+.08*Math.sin(e*Math.PI*2),glowIntensity:1+.1*Math.sin(e*Math.PI*2)})},curiosity:{duration:.8,evaluate:e=>({rotation:[0,.1*Math.sin(e*Math.PI*4),0],scale:1+.05*Math.sin(e*Math.PI),glowIntensity:1})},sadness:{duration:1.5,evaluate:e=>({scale:1-.1*e,glowIntensity:1-.15*Math.sin(e*Math.PI)})},anger:{duration:.4,evaluate:e=>{const t=.15*Math.sin(e*Math.PI*8);return{rotation:[t,t,0],scale:1.1+.1*Math.sin(e*Math.PI),glowIntensity:1+.15*Math.sin(e*Math.PI*8)}}},fear:{duration:.5,evaluate:e=>{const t=.08*Math.sin(e*Math.PI*10);return{scale:.9+t,rotation:[t,0,t],glowIntensity:1+.1*Math.sin(e*Math.PI*10)}}},surprise:{duration:.4,evaluate:e=>({scale:1+.25*(1-Math.cos(e*Math.PI)),glowIntensity:1+.2*(1-Math.cos(e*Math.PI))})},neutral:{duration:.5,evaluate:e=>({scale:1,glowIntensity:1})}};return t[e]||t.neutral}createGestureAnimation(e){const t={bounce:{duration:.8,evaluate:e=>{const t=Math.abs(Math.sin(e*Math.PI));return{position:[0,.5*t,0],scale:1+.1*t}}},pulse:{duration:.6,evaluate:e=>{const t=Math.sin(e*Math.PI);return{scale:1+.2*t,glowIntensity:1+.5*t}}},spin:{duration:1,evaluate:e=>({rotation:[0,e*Math.PI*2,0]})},wobble:{duration:1,evaluate:e=>{const t=Math.sin(e*Math.PI*3);return{rotation:[.3*t,0,.2*t]}}},float:{duration:2,evaluate:e=>({position:[0,.3*Math.sin(e*Math.PI),0]})},shake:{duration:.5,evaluate:e=>{const t=Math.sin(e*Math.PI*6)*(1-e);return{position:[.2*t,0,0],rotation:[0,0,.1*t]}}},nod:{duration:.8,evaluate:e=>({rotation:[.3*Math.sin(e*Math.PI*2),0,0]})}};return t[e]||t.pulse}createMorphAnimation(e,t){return{duration:1,fromShape:e,toShape:t,evaluate:e=>({morphProgress:e,scale:1+.1*Math.sin(e*Math.PI),rotation:[0,e*Math.PI*.5,0]})}}startAnimation(e,t){this.animations.push({...e,startTime:this.time,callbacks:t||{}}),this.currentAnimation=e}stopAll(){this.animations=[],this.currentAnimation=null}destroy(){this.stopAll(),this.animations=null,this.currentAnimation=null,this.time=0}easeInOutCubic(e){return e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2}getIdleAnimation(){return{duration:3,loop:!0,evaluate:e=>{const t=Math.sin(e*Math.PI*2),i=Math.sin(e*Math.PI);return{scale:1+.02*t,position:[.05*i,.03*t,0],rotation:[0,.05*i,0],glowIntensity:1+.1*t}}}}isPlaying(){return this.animations.length>0}}class ae{constructor(){this.breathingSpeed=1,this.breathingDepth=.03,this.breathingPhase=0,this.breathRate=1,this.breathDepth=.03,this.breathRateMult=1,this.breathDepthMult=1,this.emotionBreathPatterns={happy:{rate:1.1,depth:1.2},sad:{rate:.8,depth:.7},angry:{rate:1.4,depth:1.3},calm:{rate:.7,depth:.9},excited:{rate:1.5,depth:1.4},focused:{rate:.9,depth:.6},neutral:{rate:1,depth:1},love:{rate:1.2,depth:1.3},surprised:{rate:1.3,depth:1.1},confused:{rate:1.1,depth:.9},amused:{rate:1.2,depth:1.1},bored:{rate:.6,depth:.8},tired:{rate:.5,depth:1.2},anxious:{rate:1.6,depth:.9},determined:{rate:1.1,depth:1},proud:{rate:.9,depth:1.3},content:{rate:.8,depth:1},hopeful:{rate:1,depth:1.1},zen:{rate:.4,depth:1.5},intrigued:{rate:1.1,depth:.8},embarrassed:{rate:1.3,depth:.7},grateful:{rate:.9,depth:1.1},inspired:{rate:1,depth:1.3},silly:{rate:1.4,depth:1.2},sleepy:{rate:.3,depth:1.4}}}update(e,t,i=null){const n=this.emotionBreathPatterns[t]||{rate:1,depth:1};i&&i["3d"]&&i["3d"].scale?(this.breathRateMult=i["3d"].scale.breathRateMultiplier||1,this.breathDepthMult=i["3d"].scale.breathDepthMultiplier||1):(this.breathRateMult=1,this.breathDepthMult=1),this.breathRate=n.rate*this.breathRateMult,this.breathDepth=this.breathingDepth*n.depth*this.breathDepthMult;const a=this.breathingSpeed*this.breathRate*(e/1e3);this.breathingPhase+=a,this.breathingPhase>2*Math.PI&&(this.breathingPhase-=2*Math.PI)}getBreathingScale(){return 1+Math.sin(this.breathingPhase)*this.breathDepth}setEmotion(e,t=null){const i=this.emotionBreathPatterns[e]||{rate:1,depth:1};t&&t["3d"]&&t["3d"].scale?(this.breathRateMult=t["3d"].scale.breathRateMultiplier||1,this.breathDepthMult=t["3d"].scale.breathDepthMultiplier||1):(this.breathRateMult=1,this.breathDepthMult=1),this.breathRate=i.rate*this.breathRateMult,this.breathDepth=this.breathingDepth*i.depth*this.breathDepthMult}reset(){this.breathingPhase=0,this.breathRate=1,this.breathDepth=this.breathingDepth,this.breathRateMult=1,this.breathDepthMult=1}getBreathingInfo(){return{phase:this.breathingPhase,rate:this.breathRate,depth:this.breathDepth,scale:this.getBreathingScale(),rateMult:this.breathRateMult,depthMult:this.breathDepthMult}}destroy(){this.emotionBreathPatterns=null}}class se{constructor(){this.tempEuler=new e.Euler,this.tempQuat=new e.Quaternion,this.accumulatedRotationQuat=new e.Quaternion,this.finalQuaternion=new e.Quaternion}blend(e,t,i,n,a){this.accumulatedRotationQuat.identity();const s={position:[0,0,0],rotationQuat:this.accumulatedRotationQuat,scale:1,glowIntensity:1,glowBoost:0};for(const i of e)if(i.evaluate){const e=t-i.startTime,n=i.duration,a=Math.min(e/n,1),o=i.evaluate(a);o&&(o.position&&(s.position[0]+=o.position[0],s.position[1]+=o.position[1],s.position[2]+=o.position[2]),o.rotation&&(this.tempEuler.set(o.rotation[0],o.rotation[1],o.rotation[2],"XYZ"),this.tempQuat.setFromEuler(this.tempEuler),s.rotationQuat.multiply(this.tempQuat)),void 0!==o.scale&&(s.scale*=o.scale),void 0!==o.glowIntensity&&(s.glowIntensity*=o.glowIntensity),void 0!==o.glowBoost&&(s.glowBoost+=o.glowBoost))}this.finalQuaternion.copy(i).multiply(s.rotationQuat),this.tempEuler.setFromQuaternion(this.finalQuaternion,"XYZ");const o=[this.tempEuler.x,this.tempEuler.y,this.tempEuler.z],r=n*s.scale,l=a*s.glowIntensity;return{position:s.position,rotation:o,scale:r,glowIntensity:l,glowBoost:s.glowBoost,gestureQuaternion:s.rotationQuat}}destroy(){this.tempEuler=null,this.tempQuat=null,this.accumulatedRotationQuat=null,this.finalQuaternion=null}}const oe=new Map;var re=function(e){return oe.get(e)||null},le=function(){return Array.from(oe.keys())},he={name:"suspicion",emoji:"🤨",description:"Paranoid watchfulness with surveillance scanning",visual:{glowColor:"#6B46C1",particleRate:4,minParticles:6,maxParticles:12,particleBehavior:"surveillance",particleSpeed:.2,breathRate:.6,breathDepth:.04,coreJitter:.02,blinkRate:1.1,blinkSpeed:1,particleColors:[{color:"#6B46C1",weight:30},{color:"#4A5568",weight:25},{color:"#8B4789",weight:20},{color:"#9F7AEA",weight:15},{color:"#2D3748",weight:10}],threatLevel:0,getGlowIntensity(){return.3+.7*this.threatLevel},getParticleSpeed(){return.2+.8*this.threatLevel},getGlowColor(){const e=this.threatLevel||0,t=Math.round(107+113*e),i=Math.round(70+-32*e),n=Math.round(193+-66*e),a=e=>e.toString(16).padStart(2,"0");return`#${a(t)}${a(i)}${a(n)}`}},modifiers:{speed:.4,amplitude:.6,intensity:1.2,smoothness:.3,regularity:.2,focus:1.5,addWobble:!0},typicalGestures:["scan","twitch","peek","tilt","hold"],transitions:{duration:500,easing:"linear",priority:4},special:{coreSquint:.6,scanInterval:2e3,scanDuration:1200,scanAngle:60,twitchChance:.02,peekInterval:4e3,maxThreatDistance:300,alertThreshold:.7},"3d":{rotation:{type:"suspicious",speed:1,axes:[0,0,0],musicSync:!1},glow:{color:"#6B46C1",intensity:.85,pulse:{speed:.6,range:[.7,1]}},scale:{base:1,breathe:{enabled:!0,depth:.04,rate:.6}}},soulAnimation:{driftSpeed:.9,shimmerSpeed:1.8,turbulence:.4}},ce={name:"calm",emoji:"😌",description:"Serene, peaceful state with gentle movements",visual:{glowColor:"#66D9CC",particleRate:6,minParticles:10,maxParticles:50,particleBehavior:"zen",breathRate:.4,breathDepth:.12,coreJitter:!1,blinkRate:.8,blinkSpeed:1,particleColors:[{color:"#66D9CC",weight:35},{color:"#99E6D9",weight:25},{color:"#40BFB3",weight:20},{color:"#B3F2E6",weight:15},{color:"#339980",weight:5}]},modifiers:{speed:.5,amplitude:.3,intensity:.4,smoothness:2,regularity:1.5,addWeight:!1,floatHeight:.2,swayAmount:.15,duration:1.5},typicalGestures:["breathe","float","drift","idle"],transitions:{duration:800,easing:"easeInOutSine",priority:1},movement:{floatPattern:"sine_slow",floatPeriod:6e3,floatAmplitude:8,swayPattern:"gentle",swayPeriod:8e3,swayAmplitude:5,microMovements:!1},getCoreParams(e){const t=e.time||Date.now(),i=.5*Math.sin(6e-4*t)+.5;return{scaleX:1-.02*i,scaleY:1-.02*i,eyeOpenness:.85,eyeExpression:"serene",pupilOffset:{x:2*Math.sin(3e-4*t),y:1*Math.cos(4e-4*t)},glowPulse:.95+.05*i}},updateParticle(e,t){e.x+=.1*Math.sin(.001*e.life),e.y-=.02*t,e.opacity=.3*Math.sin(.002*e.life)+.2,e.size=e.baseSize*(1+.2*Math.sin(.001*e.life))},renderCore:(e,t,i,n)=>!1,"3d":{rotation:{type:"gentle",speed:.5,axes:[0,.3,0],musicSync:!0},glow:{color:"#66D9CC",intensity:.6,pulse:{speed:.4,range:[.5,.7]}},scale:{base:1,breathe:{enabled:!0,depth:.12,rate:.4}}},soulAnimation:{driftSpeed:.3,shimmerSpeed:.4,turbulence:.1}};const ue=new Map,de={happy:"joy",peaceful:"calm",curious:"surprise",frustrated:"anger",sad:"sadness",excitement:"excited"};function me(e){const t=de[e]||e,i=ue.get(t);if(i)return i;return re(t)||null}function pe(e){const t=me(e);if(!t)return me("neutral").visual;if(!t.visual)return{};const{visual:i}=t,n={};for(const e in i)"function"!=typeof i[e]&&(n[e]=i[e]);return"function"==typeof i.getGlowIntensity&&(n.glowIntensity=i.getGlowIntensity()),"function"==typeof i.getParticleSpeed&&(n.particleSpeed=i.getParticleSpeed()),"function"==typeof i.getParticleRate&&(n.particleRate=i.getParticleRate()),"function"==typeof i.getGlowColor&&(n.glowColor=i.getGlowColor()),n}function ge(e){const t=me(e);return t?t.modifiers:me("neutral").modifiers}function fe(e,t){const i=me(e),n=me(t);return i&&n?n.transitions&&n.transitions[e]?n.transitions[e]:{duration:1e3,easing:"ease-in-out",gesture:n.transitions?.defaultGesture||null}:{duration:1e3,easing:"ease-in-out"}}[{name:"neutral",emoji:"😐",description:"Calm, balanced emotional state",visual:{glowColor:"#00BCD4",particleRate:2,minParticles:8,maxParticles:10,particleBehavior:"ambient",breathRate:1,breathDepth:.08,coreJitter:!1,blinkRate:1,blinkSpeed:1,particleColors:[{color:"#00BCD4",weight:25},{color:"#00ACC1",weight:20},{color:"#26C6DA",weight:15},{color:"#B2EBF2",weight:15},{color:"#0097A7",weight:10},{color:"#80DEEA",weight:10},{color:"#E0F7FA",weight:5}]},modifiers:{speed:1,amplitude:1,intensity:1,smoothness:1,regularity:1},typicalGestures:["breathe","float","idle","blink"],transitions:{duration:500,easing:"easeInOut",priority:0},getCoreParams:e=>({scaleX:1,scaleY:1,eyeOpenness:1,eyeExpression:"neutral",pupilOffset:{x:0,y:0}}),renderCore:(e,t,i,n)=>!1,"3d":{rotation:{type:"gentle",speed:1,axes:[0,.3,0],musicSync:!1},glow:{color:"#00BCD4",intensity:.9,pulse:{speed:1,range:[.8,1]}},scale:{base:1,breathe:{enabled:!0,depth:.08,rate:1}}},soulAnimation:{driftSpeed:.5,shimmerSpeed:.5,turbulence:.2}},{name:"joy",emoji:"😊",description:"Playful happiness and celebration",visual:{glowColor:"#FFEB3B",particleRate:8,minParticles:0,maxParticles:50,particleBehavior:"popcorn",breathRate:1.5,breathDepth:.1,coreJitter:!1,blinkRate:1.3,blinkSpeed:1.1,particleColors:[{color:"#FFEB3B",weight:25},{color:"#FFC107",weight:20},{color:"#FFFF00",weight:15},{color:"#FFD700",weight:15},{color:"#FFF59D",weight:10},{color:"#FF9800",weight:10},{color:"#FFFDE7",weight:5}]},modifiers:{speed:1.8,amplitude:1.9,intensity:1.1,smoothness:1,regularity:.9,addBounce:!0},typicalGestures:["bounce","spin","wave","expand","shake","float"],transitions:{duration:400,easing:"easeOutBack",priority:5,burstOnEntry:!0},getCoreParams:e=>({scaleX:1,scaleY:1,eyeOpenness:1,eyeExpression:"happy",pupilOffset:{x:0,y:-.1},sparkle:!0}),"3d":{rotation:{type:"rhythmic",speed:1.8,axes:[0,.3,0],musicSync:!0},glow:{color:"#FFEB3B",intensity:1.6,pulse:{speed:1.5,range:[1.2,1.8]}},scale:{base:1,breathe:{enabled:!0,depth:.1,rate:1.5}}},soulAnimation:{driftSpeed:1.2,shimmerSpeed:1.5,turbulence:.3}},{name:"sadness",emoji:"😢",description:"Deep melancholic sorrow",visual:{glowColor:"#4169E1",particleRate:6,minParticles:0,maxParticles:50,particleBehavior:"falling",breathRate:.6,breathDepth:.12,coreJitter:!1,blinkRate:.6,blinkSpeed:.8,particleColors:[{color:"#4169E1",weight:25},{color:"#1E90FF",weight:20},{color:"#6495ED",weight:15},{color:"#B0C4DE",weight:15},{color:"#191970",weight:10},{color:"#87CEEB",weight:10},{color:"#2F4F4F",weight:5}]},modifiers:{speed:.7,amplitude:.6,intensity:.8,smoothness:1.3,regularity:1.1,addGravity:!0},typicalGestures:["droop","sway","contract","drift","sink"],transitions:{duration:800,easing:"easeInOut",priority:3},"3d":{rotation:{type:"gentle",speed:.7,axes:[0,.2,0],musicSync:!1},glow:{color:"#4169E1",intensity:.65,pulse:{speed:.6,range:[.5,.8]}},scale:{base:1,breathe:{enabled:!0,depth:.12,rate:.6}}},soulAnimation:{driftSpeed:.2,shimmerSpeed:.3,turbulence:.1}},{name:"anger",emoji:"😠",description:"Intense rage and aggression",visual:{glowColor:"#DC143C",particleRate:8,minParticles:8,maxParticles:50,particleBehavior:"aggressive",breathRate:2.2,breathDepth:.15,coreJitter:!0,blinkRate:1.6,blinkSpeed:1.3,particleColors:[{color:"#DC143C",weight:25},{color:"#FF0000",weight:20},{color:"#B22222",weight:15},{color:"#FF4500",weight:15},{color:"#8B0000",weight:10},{color:"#FF6347",weight:10},{color:"#660000",weight:5}]},modifiers:{speed:1.5,amplitude:1.4,intensity:1.3,smoothness:.3,regularity:.7,addShake:!0},typicalGestures:["shake","vibrate","expand","pulse","flicker","strike"],transitions:{duration:300,easing:"easeOutExpo",priority:8,shakeOnEntry:!0},special:{screenShake:!0,particleTrails:"fire",glowPulse:!0,temperatureEffect:"hot"},"3d":{rotation:{type:"unstable",speed:1.5,axes:[0,.3,0],shake:{amplitude:.02,frequency:7},eruption:{enabled:!0,interval:3e3,speedMultiplier:3.5,duration:400},musicSync:!1},glow:{color:"#DC143C",intensity:1.8,pulse:{speed:2.2,range:[.8,2]}},scale:{base:1,breathe:{enabled:!0,depth:.15,rate:2.2}}},soulAnimation:{driftSpeed:2,shimmerSpeed:.8,turbulence:.8}},{name:"fear",emoji:"😨",description:"Anxious state with fleeing particles",visual:{glowColor:"#8A2BE2",particleRate:8,minParticles:8,maxParticles:50,particleBehavior:"scattering",breathRate:2.5,breathDepth:.06,coreJitter:!0,blinkRate:1.7,blinkSpeed:1.4,particleColors:[{color:"#8A2BE2",weight:25},{color:"#4B0082",weight:20},{color:"#9400D3",weight:15},{color:"#6B46C1",weight:15},{color:"#9932CC",weight:10},{color:"#E6E6FA",weight:8},{color:"#301934",weight:7}]},modifiers:{speed:1.4,amplitude:.8,intensity:1.2,smoothness:.5,regularity:.5,addJitter:!0},typicalGestures:["shake","vibrate","contract","flicker","retreat"],transitions:{duration:400,easing:"easeOut",priority:7},"3d":{rotation:{type:"unstable",speed:1.4,axes:[0,.3,0],shake:{amplitude:.015,frequency:3.5},musicSync:!1},glow:{color:"#8A2BE2",intensity:.9,pulse:{speed:2.5,range:[.6,1.2]}},scale:{base:1,breathe:{enabled:!0,depth:.06,rate:2.5}}},soulAnimation:{driftSpeed:1.8,shimmerSpeed:2.5,turbulence:.6}},{name:"surprise",emoji:"😲",description:"Sudden shock with explosive particles",visual:{glowColor:"#FFD700",particleRate:5,minParticles:0,maxParticles:15,particleBehavior:"burst",breathRate:.3,breathDepth:.18,coreJitter:!1,blinkRate:1.4,blinkSpeed:1.2,particleColors:[{color:"#FFD700",weight:25},{color:"#FFA500",weight:20},{color:"#FFFF00",weight:15},{color:"#FF6347",weight:15},{color:"#FFE4B5",weight:10},{color:"#FF4500",weight:10},{color:"#FFFACD",weight:5}]},modifiers:{speed:1.6,amplitude:1.5,intensity:1.4,smoothness:.7,regularity:.8,addPop:!0},typicalGestures:["expand","bounce","flash","pulse","pop"],transitions:{duration:200,easing:"easeOutBack",priority:6},"3d":{rotation:{type:"unstable",speed:1.6,axes:[0,.45,0],shake:{amplitude:.01,frequency:3},musicSync:!1},glow:{color:"#FFD700",intensity:1.8,pulse:{speed:.3,range:[1,2.2]}},scale:{base:1,breathe:{enabled:!0,depth:.18,rate:.3}}},soulAnimation:{driftSpeed:1.5,shimmerSpeed:2,turbulence:.5}},{name:"disgust",emoji:"🤢",description:"Revulsion with repelling particles",visual:{glowColor:"#9ACD32",particleRate:4,minParticles:5,maxParticles:12,particleBehavior:"repelling",breathRate:.7,breathDepth:.04,coreJitter:!1,blinkRate:.9,blinkSpeed:.9,particleColors:[{color:"#9ACD32",weight:25},{color:"#ADFF2F",weight:20},{color:"#7FFF00",weight:15},{color:"#BDB76B",weight:15},{color:"#6B8E23",weight:10},{color:"#CCFF00",weight:8},{color:"#556B2F",weight:7}]},modifiers:{speed:.9,amplitude:.7,intensity:.9,smoothness:.8,regularity:1,addRecoil:!0},typicalGestures:["contract","shake","recoil","wobble"],transitions:{duration:600,easing:"easeIn",priority:4},"3d":{rotation:{type:"gentle",speed:.9,axes:[0,.25,0],musicSync:!1},glow:{color:"#9ACD32",intensity:1,pulse:{speed:.7,range:[.7,1.2]}},scale:{base:1,breathe:{enabled:!0,depth:.04,rate:.7}}},soulAnimation:{driftSpeed:.4,shimmerSpeed:.6,turbulence:.35}},{name:"love",emoji:"💕",description:"Warm affection with orbiting particles",visual:{glowColor:"#FF1493",particleRate:6,minParticles:15,maxParticles:50,particleBehavior:"orbiting",breathRate:.75,breathDepth:.15,coreJitter:!1,blinkRate:1.2,blinkSpeed:1,particleColors:[{color:"#FF1493",weight:30},{color:"#FF69B4",weight:25},{color:"#FF007F",weight:15},{color:"#FFB6C1",weight:10},{color:"#FF45A0",weight:10},{color:"#E91E63",weight:5},{color:"#FFC0CB",weight:5}]},modifiers:{speed:.9,amplitude:1.1,intensity:1.2,smoothness:1.4,regularity:1.2,addWarmth:!0},typicalGestures:["pulse","sway","orbit","glow","breathe","float"],transitions:{duration:700,easing:"easeInOut",priority:5},"3d":{rotation:{type:"gentle",speed:.9,axes:[0,.28,0],musicSync:!0},glow:{color:"#FF1493",intensity:1.8,pulse:{speed:.75,range:[1.3,2]}},scale:{base:1,breathe:{enabled:!0,depth:.15,rate:.75}}},soulAnimation:{driftSpeed:.8,shimmerSpeed:1.2,turbulence:.2}},he,{name:"excited",emoji:"🤩",description:"High energy with rapid particles",visual:{glowColor:"#FF6B35",particleRate:8,minParticles:10,maxParticles:50,particleBehavior:"burst",breathRate:2,breathDepth:.14,coreJitter:!0,blinkRate:1.5,blinkSpeed:1.2,particleColors:[{color:"#FF6B35",weight:25},{color:"#FF1744",weight:20},{color:"#FFC107",weight:15},{color:"#FF9100",weight:15},{color:"#FFEB3B",weight:10},{color:"#FF5722",weight:10},{color:"#FFF59D",weight:5}]},modifiers:{speed:1.4,amplitude:1.3,intensity:1.3,smoothness:.8,regularity:.7,addVibration:!0},typicalGestures:["bounce","spin","vibrate","expand","shake","pulse"],transitions:{duration:300,easing:"easeOutElastic",priority:6},"3d":{rotation:{type:"unstable",speed:1.4,axes:[0,.4,0],shake:{amplitude:.01,frequency:4},musicSync:!1},glow:{color:"#FF6B35",intensity:1.5,pulse:{speed:2,range:[1,1.8]}},scale:{base:1,breathe:{enabled:!0,depth:.14,rate:2}}},soulAnimation:{driftSpeed:1.5,shimmerSpeed:2,turbulence:.5}},{name:"resting",emoji:"😴",description:"Deep relaxation with slow drift",visual:{glowColor:"#9370DB",particleRate:1,minParticles:3,maxParticles:5,particleBehavior:"resting",breathRate:.8,breathDepth:.12,coreJitter:!1,blinkRate:.4,blinkSpeed:.7,particleColors:[{color:"#9370DB",weight:30},{color:"#A591C4",weight:20},{color:"#B366FF",weight:20},{color:"#B8A1E6",weight:15},{color:"#674D9B",weight:15}]},modifiers:{speed:.5,amplitude:.4,intensity:.5,smoothness:1.4,regularity:.9,addWeight:!0},typicalGestures:["breathe","drift","sway","float"],transitions:{duration:1e3,easing:"easeInOut",priority:2},"3d":{rotation:{type:"gentle",speed:.5,axes:[0,.15,0],musicSync:!1},glow:{color:"#9370DB",intensity:.8,pulse:{speed:.8,range:[.6,1]}},scale:{base:1,breathe:{enabled:!0,depth:.12,rate:.8}}},soulAnimation:{driftSpeed:.15,shimmerSpeed:.1,turbulence:.05}},{name:"euphoria",emoji:"🌟",description:"Radiant hope and new beginnings",visual:{glowColor:"#FFB6C1",particleRate:6,minParticles:15,maxParticles:30,particleBehavior:"radiant",breathRate:1.3,breathDepth:.25,coreJitter:!1,blinkRate:1.4,blinkSpeed:1.1,particleColors:[{color:"#FFB6C1",weight:20},{color:"#FFD700",weight:18},{color:"#87CEEB",weight:15},{color:"#DDA0DD",weight:15},{color:"#98FB98",weight:12},{color:"#FFA07A",weight:10},{color:"#E6E6FA",weight:8},{color:"#FFFFFF",weight:2}]},modifiers:{speed:1.4,amplitude:1.5,intensity:1.6,smoothness:1.3,regularity:.8,addWarmth:!0,addLift:!0},typicalGestures:["expand","radiate","pulse","glow","float","bloom"],transitions:{duration:600,easing:"easeOutExpo",priority:8},"3d":{rotation:{type:"rhythmic",speed:1.4,axes:[0,.35,0],musicSync:!0},glow:{color:"#FFB6C1",intensity:1.2,pulse:{speed:1.3,range:[.9,1.5]}},scale:{base:1,breathe:{enabled:!0,depth:.25,rate:1.3}}},soulAnimation:{driftSpeed:1.8,shimmerSpeed:2.5,turbulence:.7}},{name:"focused",emoji:"🎯",description:"Intense concentration with directed flow",visual:{glowColor:"#00CED1",particleRate:4,minParticles:5,maxParticles:12,particleBehavior:"directed",breathRate:1.2,breathDepth:.08,coreJitter:!0,blinkRate:.7,blinkSpeed:1,particleColors:[{color:"#00CED1",weight:30},{color:"#4A9FA0",weight:20},{color:"#00FFFF",weight:20},{color:"#5FE5E7",weight:15},{color:"#006B6D",weight:15}],eyeOpenness:.7,microAdjustments:!0},modifiers:{speed:1,amplitude:.9,intensity:1.1,smoothness:1.1,regularity:1.2,addPrecision:!0},typicalGestures:["track","lock","scan","pulse","vibrate"],transitions:{duration:400,easing:"easeIn",priority:5},getCoreParams:e=>({scaleX:1.1,scaleY:.7,eyeOpenness:.7,eyeExpression:"focused",pupilOffset:{x:0,y:0},microAdjustments:!0}),"3d":{rotation:{type:"still",speed:.5,axes:[0,.1,0],musicSync:!1},glow:{color:"#00CED1",intensity:1.2,pulse:{speed:1.2,range:[1,1.3]}},scale:{base:1,breathe:{enabled:!0,depth:.08,rate:1.2}}},soulAnimation:{driftSpeed:.6,shimmerSpeed:.2,turbulence:.1}},{name:"glitch",emoji:"🌈",description:"Surprised sadness with rainbow colors and glitch wiggle",visual:{primaryColor:"#FF6B9D",glowColor:"#4169E1",glowIntensity:1.2,particleRate:5,minParticles:5,maxParticles:15,particleBehavior:"burst",particleSpeed:1,breathRate:.4,breathDepth:.15,coreJitter:!1,coreSize:1,eyeOpenness:.8,blinkRate:1.3,blinkSpeed:1.2,particleColors:[{color:"#FF0080",weight:18},{color:"#00FF80",weight:18},{color:"#8000FF",weight:18},{color:"#FF8000",weight:15},{color:"#0080FF",weight:15},{color:"#FFFF00",weight:10},{color:"#FF6B9D",weight:6}],particleGlitchWiggle:!0,glitchWiggleIntensity:.3,glitchWiggleFrequency:.1},modifiers:{speed:1.1,amplitude:1,intensity:1.1,smoothness:.8,regularity:.7,focus:.6},typicalGestures:["bounce","sway","pulse","drift","flash"],transitions:{duration:300,easing:"easeInOut",priority:5},"3d":{rotation:{type:"unstable",speed:1.1,axes:[0,.35,0],shake:{amplitude:.02,frequency:5},musicSync:!1},glow:{color:"#FF6B9D",intensity:1.2,pulse:{speed:.4,range:[.8,1.6]}},scale:{base:1,breathe:{enabled:!0,depth:.15,rate:.4}}}},ce].forEach(e=>{e&&e.name&&ue.set(e.name,e)});class ye{constructor(e,t={}){this.blinkConfig=e.blink||this.getDefaultBlinkConfig(),this.currentGeometryType=null,this.baseDuration=this.blinkConfig.duration||150,this.baseMinInterval=3e3,this.baseMaxInterval=7e3,this.emotionBlinkRate=1,this.emotionBlinkSpeed=1,this.isBlinking=!1,this.blinkTimer=0,this.nextBlinkTime=this.getRandomBlinkTime(),this.enabled=!0,this.blinkProgress=0}setEmotion(e){const t=me(e);this.emotionBlinkRate=t?.visual?.blinkRate||1,this.emotionBlinkSpeed=t?.visual?.blinkSpeed||1}setGeometry(e){this.blinkConfig=e.blink||this.getDefaultBlinkConfig(),this.baseDuration=this.blinkConfig.duration||150}update(e){if(!this.enabled)return this.getIdleState();if(this.isBlinking){this.blinkTimer+=e;const t=this.baseDuration/this.emotionBlinkSpeed;if(this.blinkTimer>=t)return this.completeBlink(),this.getIdleState();const i=this.blinkTimer/t;return this.blinkProgress=i,this.getBlinkState()}return Date.now()>=this.nextBlinkTime?(this.startBlink(),this.getBlinkState()):this.getIdleState()}startBlink(){this.enabled&&(this.isBlinking=!0,this.blinkTimer=0,this.blinkProgress=0)}completeBlink(){this.isBlinking=!1,this.blinkTimer=0,this.blinkProgress=0,this.nextBlinkTime=Date.now()+this.getRandomBlinkTime()}getRandomBlinkTime(){const e=this.baseMinInterval/this.emotionBlinkRate,t=this.baseMaxInterval/this.emotionBlinkRate;return e+Math.random()*(t-e)}getBlinkState(){const e=this.blinkConfig,t=Math.sin(this.blinkProgress*Math.PI);let i=1;if(e.playful)if(this.blinkProgress<.1){const t=this.blinkProgress/.1;i-=Math.sin(t*Math.PI)*e.playful.anticipation}else if(this.blinkProgress>.8){const t=(this.blinkProgress-.8)/.2;i+=Math.sin(t*Math.PI)*e.playful.overshoot}const n=t*i,a=[1-(1-e.scaleAxis[0])*n,1-(1-e.scaleAxis[1])*n,1-(1-e.scaleAxis[2])*n];let s=null;e.rotation&&(s=[e.rotation[0]*n,e.rotation[1]*n,e.rotation[2]*n]);let o=0;return e.glowBoost&&(o=e.glowBoost*n),{isBlinking:!0,progress:this.blinkProgress,scale:a,rotation:s,glowBoost:o}}getIdleState(){return{isBlinking:!1,progress:0,scale:[1,1,1],rotation:null,glowBoost:0}}getDefaultBlinkConfig(){return{type:"vertical-squish",duration:150,scaleAxis:[1,.3,1],curve:"sine"}}pause(){this.enabled=!1,this.isBlinking&&this.completeBlink()}resume(){this.enabled=!0,this.nextBlinkTime=Date.now()+this.getRandomBlinkTime()}getState(){return{isBlinking:this.isBlinking,enabled:this.enabled,blinkProgress:this.blinkProgress,emotionBlinkRate:this.emotionBlinkRate,emotionBlinkSpeed:this.emotionBlinkSpeed,nextBlinkTime:this.nextBlinkTime}}destroy(){this.blinkConfig=null,this.enabled=!1,this.isBlinking=!1}}let ve;"undefined"!=typeof window&&window.__emotiveRhythmEngine?ve=window.__emotiveRhythmEngine:(ve=new class{constructor(){this.bpm=120,this.timeSignature=[4,4],this.isPlaying=!1,this.startTime=0,this.currentBeat=0,this.currentBar=0,this.beatProgress=0,this.barProgress=0,this.beatDuration=6e4/this.bpm,this.barDuration=this.beatDuration*this.timeSignature[0],this.lastBeatTime=0,this.nextBeatTime=0,this.listeners=new Map,this.beatCallbacks=new Set,this.barCallbacks=new Set,this.subdivisions={sixteenth:0,eighth:0,triplet:0,swing:0},this.audioSync=null,this.syncOffset=0,this.autoSync=!1,this.intensity=1,this.groove=0,this.humanize=.05,this.patterns=new Map,this.currentPattern=null,this.initializePatterns()}initializePatterns(){this.patterns.set("4/4",{name:"4/4",description:"Common time - 4 beats per bar",timeSignature:[4,4],groove:0,accents:[1,.5,.7,.5]}),this.patterns.set("straight",{name:"straight",description:"Straight, even timing",groove:0,accents:[1,.5,.7,.5]}),this.patterns.set("swing",{name:"swing",description:"Swing/shuffle timing",groove:.67,accents:[1,.3,.8,.3]}),this.patterns.set("3/4",{name:"3/4",description:"Waltz time - 3 beats per bar",timeSignature:[3,4],accents:[1,.5,.5]}),this.patterns.set("waltz",{name:"waltz",description:"3/4 waltz timing",timeSignature:[3,4],accents:[1,.5,.5]}),this.patterns.set("6/8",{name:"6/8",description:"Compound duple time",timeSignature:[6,8],accents:[1,.3,.3,.7,.3,.3]}),this.patterns.set("5/4",{name:"5/4",description:"Complex meter - 5 beats per bar",timeSignature:[5,4],accents:[1,.5,.6,.5,.7]}),this.patterns.set("7/8",{name:"7/8",description:"Irregular meter",timeSignature:[7,8],accents:[1,.5,.5,.7,.5,.5,.6]}),this.patterns.set("dubstep",{name:"dubstep",description:"Dubstep half-time feel",accents:[.2,.2,1,.2],subdivisions:{wobble:!0}}),this.patterns.set("breakbeat",{name:"breakbeat",description:"Broken beat pattern",accents:[1,.2,.7,.9,.2,.8,.4,.2]})}start(){this.isPlaying||(this.isPlaying=!0,this.isRunning=!0,this.startTime=performance.now(),this.lastBeatTime=this.startTime,this.nextBeatTime=this.startTime+this.beatDuration,this.currentBeat=0,this.currentBar=0,this.emit("start",{bpm:this.bpm,timeSignature:this.timeSignature,pattern:this.currentPattern}),this.update())}stop(){this.isPlaying&&(this.isPlaying=!1,this.emit("stop",{totalBeats:this.currentBeat,totalBars:this.currentBar}))}update(){if(!this.isPlaying)return;const e=(performance.now()-this.startTime)/this.beatDuration,t=Math.floor(e);this.beatProgress=e%1,t>this.currentBeat&&this.onBeat(t);const i=Math.floor(t/this.timeSignature[0]);i>this.currentBar&&this.onBar(i),this.currentBeat=t,this.currentBar=i,this.barProgress=t%this.timeSignature[0]/this.timeSignature[0],this.updateSubdivisions(),this.emit("update",this.getTimeInfo()),this.isPlaying&&requestAnimationFrame(()=>this.update())}onBeat(e){const t=e%this.timeSignature[0],i=this.getAccent(t),n=this.humanize*(Math.random()-.5)*this.beatDuration,a={beat:e,beatInBar:t,bar:this.currentBar,accent:i,intensity:this.intensity*i,humanTiming:n,timestamp:performance.now()};this.emit("beat",a),this.beatCallbacks.forEach(e=>e(a)),this.lastBeatTime=performance.now(),this.nextBeatTime=this.lastBeatTime+this.beatDuration}onBar(e){const t={bar:e,timeSignature:this.timeSignature,pattern:this.currentPattern,timestamp:performance.now()};this.emit("bar",t),this.barCallbacks.forEach(e=>e(t))}updateSubdivisions(){if(this.subdivisions.sixteenth=4*this.beatProgress%1,this.subdivisions.eighth=2*this.beatProgress%1,this.subdivisions.triplet=3*this.beatProgress%1,this.groove>0){const e=.5+.17*this.groove;this.subdivisions.eighth<.5?this.subdivisions.swing=this.subdivisions.eighth/e:this.subdivisions.swing=.5+(this.subdivisions.eighth-.5)/(1-e)}else this.subdivisions.swing=this.subdivisions.eighth}getAccent(e){if(this.currentPattern&&this.patterns.has(this.currentPattern)){const t=this.patterns.get(this.currentPattern);if(t.accents&&void 0!==t.accents[e])return t.accents[e]}return 0===e?1:2===e&&4===this.timeSignature[0]?.7:.5}getTimeInfo(){return{elapsed:performance.now()-this.startTime,beat:this.currentBeat,bar:this.currentBar,beatInBar:this.currentBeat%this.timeSignature[0],beatProgress:this.beatProgress,barProgress:this.barProgress,subdivisions:{...this.subdivisions},bpm:this.bpm,beatDuration:this.beatDuration,timeSignature:[...this.timeSignature],intensity:this.intensity,groove:this.groove,pattern:this.currentPattern,nextBeatIn:this.nextBeatTime-performance.now(),accent:this.getAccent(this.currentBeat%this.timeSignature[0])}}setBPM(e){this.bpm=Math.max(20,Math.min(360,e)),this.beatDuration=6e4/this.bpm,this.barDuration=this.beatDuration*this.timeSignature[0],this.emit("tempoChange",{bpm:this.bpm})}setTimeSignature(e,t){this.timeSignature=[e,t],this.barDuration=this.beatDuration*e,this.emit("timeSignatureChange",{timeSignature:this.timeSignature})}setPattern(e){if(!this.patterns.has(e))return;const t=this.patterns.get(e);this.currentPattern=e,t.timeSignature&&this.setTimeSignature(...t.timeSignature),void 0!==t.groove&&(this.groove=t.groove),this.emit("patternChange",{pattern:e})}onBeatCallback(e){return this.beatCallbacks.add(e),()=>this.beatCallbacks.delete(e)}onBarCallback(e){return this.barCallbacks.add(e),()=>this.barCallbacks.delete(e)}emit(e,t){this.listeners.has(e)&&this.listeners.get(e).forEach(e=>e(t))}on(e,t){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t),()=>{this.listeners.has(e)&&this.listeners.get(e).delete(t)}}syncToAudio(e,t){this.audioSync={context:e,source:t}}getAdapter(){return{getTimeInfo:()=>this.getTimeInfo(),isOnBeat:(e=.1)=>this.beatProgress<e||this.beatProgress>1-e,isOnSubdivision:(e,t=.1)=>{const i=this.subdivisions[e]||0;return i<t||i>1-t},getBeatSync:(e=0,t=1,i="linear")=>{let n=this.beatProgress;switch(i){case"ease":n=.5-Math.cos(n*Math.PI)/2;break;case"bounce":n=Math.abs(Math.sin(n*Math.PI));break;case"pulse":n=Math.pow(Math.sin(n*Math.PI),2)}return e+(t-e)*n},getAccentedValue:(e,t=2)=>e*(1+(this.getAccent(this.currentBeat%this.timeSignature[0])-.5)*t),onBeat:e=>this.onBeatCallback(e),onBar:e=>this.onBarCallback(e),beatsToMs:e=>e*this.beatDuration,msToBeats:e=>e/this.beatDuration,isPlaying:()=>this.isPlaying,getBPM:()=>this.bpm,getPattern:()=>this.currentPattern}}},"undefined"!=typeof window&&(window.__emotiveRhythmEngine=ve));class be{constructor(){this.enabled=!1,this.adapter=null,this.beatProgress=0,this.barProgress=0,this.accent=.5,this.intensity=1,this.bpm=120,this.isOnBeat=!1,this.pattern=null,this.grooveEnabled=!0,this.grooveTime=0,this._lastBeatProgress=0,this._staleFrameCount=0,this.modulation={scaleMultiplier:1,glowMultiplier:1,positionMultiplier:1,rotationMultiplier:1,accentBoost:0,grooveOffset:[0,0,0],grooveScale:1,grooveRotation:[0,0,0]},this._target={scaleMultiplier:1,glowMultiplier:1,positionMultiplier:1,rotationMultiplier:1,accentBoost:0,grooveOffset:[0,0,0],grooveScale:1,grooveRotation:[0,0,0]},this.config={beatSyncStrength:.3,accentMultiplier:1.5,grooveBounceAmount:.02,grooveSwayAmount:.015,groovePulseAmount:.03,grooveRotationAmount:.02,smoothingSpeed:8,grooveSmoothingSpeed:6}}_lerp(e,t,i,n){return e+(t-e)*(1-Math.exp(-i*n))}_lerpArray(e,t,i,n){const a=1-Math.exp(-i*n);return e.map((e,i)=>e+(t[i]-e)*a)}initialize(){this.adapter=ve.getAdapter(),this.enabled=!0,this.adapter.onBeat(e=>{this.accent=e.accent,this.isOnBeat=!0,setTimeout(()=>{this.isOnBeat=!1},100)})}start(e=120,t="straight"){this.enabled||this.initialize(),e&&ve.setBPM(e),t&&ve.setPattern(t),ve.start()}stop(){ve.stop()}setBPM(e){ve.setBPM(e),this.bpm=e}setPattern(e){ve.setPattern(e),this.pattern=e}update(e){const t=e/1e3;if(this.adapter||(this.adapter=ve.getAdapter()),!this.adapter)return void this.resetModulation(t);if(!this.adapter.isPlaying())return void this.resetModulation(t);this.enabled=!0;const i=this.adapter.getTimeInfo();if(Math.abs(i.beatProgress-this._lastBeatProgress)<.001?this._staleFrameCount++:(this._staleFrameCount=0,this._lastBeatProgress=i.beatProgress),this._staleFrameCount>10){const e=(i.bpm||this.bpm||120)/60;this.grooveTime+=t,this.beatProgress=this.grooveTime*e%1,this.barProgress=this.grooveTime*e/4%1}else this.beatProgress=i.beatProgress,this.barProgress=i.barProgress,this.grooveTime+=t;this.intensity=i.intensity,this.bpm=i.bpm||this.bpm,this.pattern=i.pattern,this.computeModulation(),this.applySmoothing(t)}computeModulation(){const{beatSyncStrength:e,accentMultiplier:t}=this.config,i=this.beatProgress*Math.PI*2,n=.5*(Math.cos(i)+1);this._target.scaleMultiplier=1+n*e*.4,this._target.glowMultiplier=1+n*e*.8,this._target.positionMultiplier=1+n*e*.2,this._target.rotationMultiplier=1+n*e*.15,this._target.accentBoost=this.isOnBeat?(this.accent-.5)*t:0,this.grooveEnabled?this.computeGroove():(this._target.grooveOffset=[0,0,0],this._target.grooveScale=1,this._target.grooveRotation=[0,0,0])}computeGroove(){const{grooveBounceAmount:e,grooveSwayAmount:t,groovePulseAmount:i,grooveRotationAmount:n}=this.config,a=this.beatProgress*Math.PI*2,s=Math.sin(a)*e,o=this.barProgress*Math.PI*2,r=Math.sin(o)*t,l=1+Math.sin(a)*i,h=Math.sin(o)*n;this._target.grooveOffset=[r,s,0],this._target.grooveScale=l,this._target.grooveRotation=[0,0,h]}applySmoothing(e){const{smoothingSpeed:t,grooveSmoothingSpeed:i}=this.config;this.modulation.scaleMultiplier=this._lerp(this.modulation.scaleMultiplier,this._target.scaleMultiplier,t,e),this.modulation.glowMultiplier=this._lerp(this.modulation.glowMultiplier,this._target.glowMultiplier,t,e),this.modulation.positionMultiplier=this._lerp(this.modulation.positionMultiplier,this._target.positionMultiplier,t,e),this.modulation.rotationMultiplier=this._lerp(this.modulation.rotationMultiplier,this._target.rotationMultiplier,t,e),this.modulation.accentBoost=this._lerp(this.modulation.accentBoost,this._target.accentBoost,.5*t,e),this.modulation.grooveOffset=this._lerpArray(this.modulation.grooveOffset,this._target.grooveOffset,i,e),this.modulation.grooveScale=this._lerp(this.modulation.grooveScale,this._target.grooveScale,i,e),this.modulation.grooveRotation=this._lerpArray(this.modulation.grooveRotation,this._target.grooveRotation,i,e)}resetModulation(e=.016){this._target.scaleMultiplier=1,this._target.glowMultiplier=1,this._target.positionMultiplier=1,this._target.rotationMultiplier=1,this._target.accentBoost=0,this._target.grooveOffset=[0,0,0],this._target.grooveScale=1,this._target.grooveRotation=[0,0,0],this.modulation.scaleMultiplier=this._lerp(this.modulation.scaleMultiplier,1,4,e),this.modulation.glowMultiplier=this._lerp(this.modulation.glowMultiplier,1,4,e),this.modulation.positionMultiplier=this._lerp(this.modulation.positionMultiplier,1,4,e),this.modulation.rotationMultiplier=this._lerp(this.modulation.rotationMultiplier,1,4,e),this.modulation.accentBoost=this._lerp(this.modulation.accentBoost,0,4,e),this.modulation.grooveOffset=this._lerpArray(this.modulation.grooveOffset,[0,0,0],4,e),this.modulation.grooveScale=this._lerp(this.modulation.grooveScale,1,4,e),this.modulation.grooveRotation=this._lerpArray(this.modulation.grooveRotation,[0,0,0],4,e)}getModulation(){return this.modulation}getMusicalDuration(e,t=null){if(!this.enabled||!this.adapter||!this.adapter.isPlaying())return e;if(t?.durationSync){const e=t.durationSync;if("beats"===e.mode&&e.beats)return this.adapter.beatsToMs(e.beats);if("bars"===e.mode&&e.bars)return this.adapter.beatsToMs(4*e.bars)}return e}isOnBeatNow(e=.1){return!(!this.enabled||!this.adapter)&&this.adapter.isOnBeat(e)}isOnAccent(e=.7){return this.isOnBeat&&this.accent>=e}getBeatSync(e,t,i="pulse"){return this.enabled&&this.adapter?this.adapter.getBeatSync(e,t,i):e}getAccentedValue(e,t=2){return this.enabled&&this.adapter?this.adapter.getAccentedValue(e,t):e}setGrooveEnabled(e){this.grooveEnabled=e,e||(this._target.grooveOffset=[0,0,0],this._target.grooveScale=1,this._target.grooveRotation=[0,0,0])}setGrooveConfig(e){Object.assign(this.config,e)}setBeatSyncStrength(e){this.config.beatSyncStrength=Math.max(0,Math.min(1,e))}isPlaying(){return this.enabled&&this.adapter&&this.adapter.isPlaying()}getBPM(){return this.bpm}getPattern(){return this.pattern}destroy(){this.enabled=!1,this.adapter=null,this.resetModulation()}}const we=new be;class Me{constructor(){this.isTransitioning=!1,this.currentGeometryType=null,this.targetGeometryType=null,this.morphStartTime=0,this.morphDuration=1e3,this.morphProgress=0,this.visualProgress=0,this.hasSwappedGeometry=!1,this.isPausedAtSwap=!1,this.pausedAtTime=0,this.easing="easeInOutCubic"}startMorph(e,t,i=1e3){if(e===t&&!this.isTransitioning)return!1;if(this.isTransitioning&&this.targetGeometryType===t)return!1;if(this.isTransitioning){const e=this.calculateScaleMultiplier(this.visualProgress);if(this.hasSwappedGeometry){this.morphStartTime=Date.now(),this.morphDuration=i;const n=e>0?Math.sqrt(1-Math.min(e,1))/2:.5;this.morphProgress=n,this.visualProgress=n,this.hasSwappedGeometry=!1,this.targetGeometryType=t,this._interruptedTarget=t,this.isPausedAtSwap=!1,this.isGrowIn=!1;const a=n*i;return this.morphStartTime=Date.now()-a,!0}return this.targetGeometryType=t,this._interruptedTarget=t,!0}return this.currentGeometryType=e,this.targetGeometryType=t,this.morphStartTime=Date.now(),this.morphDuration=i,this.morphProgress=0,this.visualProgress=0,this.isTransitioning=!0,this.hasSwappedGeometry=!1,this.isPausedAtSwap=!1,this.pausedAtTime=0,this.isGrowIn=!1,this._interruptedTarget=null,!0}getInterruptedTarget(){const e=this._interruptedTarget;return this._interruptedTarget=null,e}growIn(e,t=500){return!this.isTransitioning&&(this.currentGeometryType=e,this.targetGeometryType=e,this.morphStartTime=Date.now(),this.morphDuration=t,this.morphProgress=0,this.visualProgress=0,this.isTransitioning=!0,this.hasSwappedGeometry=!0,this.isPausedAtSwap=!1,this.pausedAtTime=0,this.isGrowIn=!0,!0)}pauseAtSwap(){this.isTransitioning&&!this.isPausedAtSwap&&(this.isPausedAtSwap=!0,this.pausedAtTime=Date.now())}resumeFromSwap(){if(this.isPausedAtSwap){const e=Date.now()-this.pausedAtTime;this.morphStartTime+=e,this.isPausedAtSwap=!1,this.pausedAtTime=0}}update(e){if(!this.isTransitioning)return{isTransitioning:!1,progress:0,visualProgress:0,scaleMultiplier:1};if(this.isPausedAtSwap)return{isTransitioning:!0,progress:.5,visualProgress:.5,scaleMultiplier:0,waitingForGeometry:!0};const t=Date.now()-this.morphStartTime,i=Math.min(t/this.morphDuration,1);this.morphProgress=this.applyEasing(i),this.visualProgress=.6*this.visualProgress+.4*this.morphProgress,Math.abs(this.visualProgress-this.morphProgress)<.01&&(this.visualProgress=this.morphProgress);const n=this.calculateScaleMultiplier(this.visualProgress);let a=!1;return!this.hasSwappedGeometry&&this.morphProgress>=.5&&(this.hasSwappedGeometry=!0,a=!0),this.morphProgress>=1?(this.completeMorph(),{isTransitioning:!1,progress:1,visualProgress:1,scaleMultiplier:1,completed:!0}):{isTransitioning:!0,progress:this.morphProgress,visualProgress:this.visualProgress,scaleMultiplier:n,shouldSwapGeometry:a}}calculateScaleMultiplier(e){if(this.isGrowIn){const t=1.70158,i=1+(t+1)*Math.pow(e-1,3)+t*Math.pow(e-1,2);return Math.max(0,i)}if(e<=.5){const t=2*e;return 1-t*t}{const t=2*(e-.5);return t*(2-t)}}completeMorph(){this.currentGeometryType=this.targetGeometryType,this.targetGeometryType=null,this.isTransitioning=!1,this.morphProgress=0,this.visualProgress=0}applyEasing(e){switch(this.easing){case"linear":return e;case"easeInQuad":return e*e;case"easeOutQuad":return e*(2-e);case"easeInOutQuad":return e<.5?2*e*e:(4-2*e)*e-1;case"easeInOutSine":return-(Math.cos(Math.PI*e)-1)/2;default:return e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2}}getState(){return{isTransitioning:this.isTransitioning,currentGeometryType:this.currentGeometryType,targetGeometryType:this.targetGeometryType,progress:this.morphProgress,visualProgress:this.visualProgress}}cancel(){this.isTransitioning=!1,this.targetGeometryType=null,this.morphProgress=0,this.visualProgress=0}}class Se{constructor(e={},t=null,i=null){if(this.config=e,this.rhythmEngine=t,this.geometryRotation=i,this.type=e.type||"gentle",this.speed=e.speed||1,i&&void 0!==i.baseSpeed){const e=i.baseSpeed,t=i.axes||[0,1,0];this.axes=[t[0]*e*this.speed,t[1]*e*this.speed,t[2]*e*this.speed]}else this.axes=e.axes||[0,.01,0];this.shake=e.shake||{amplitude:0,frequency:0},this.wobbleEnabled=!0,this.eruption=e.eruption||{enabled:!1},this.eruption.enabled&&(this.eruption.interval=this.eruption.interval||3e3,this.eruption.speedMultiplier=this.eruption.speedMultiplier||3,this.eruption.duration=this.eruption.duration||400,this.eruption.nextEruptionTime=this.eruption.interval,this.eruption.eruptionStartTime=-1),this.musicSync=void 0!==e.musicSync&&e.musicSync,this.time=0,this.episodicWobble={enabled:!1,minInterval:2e3,maxInterval:5e3,amplitude:.05,duration:200,nextWobbleTime:0,wobbleStartTime:-1,wobbleTarget:[0,0,0]}}update(e,t){switch(this.time+=e,this.episodicWobble.enabled&&this.wobbleEnabled&&this._applyEpisodicWobble(e,t),this.type){case"gentle":default:return this._evaluateGentle(e,t);case"unstable":return this._evaluateUnstable(e,t);case"rhythmic":return this._evaluateRhythmic(e,t);case"orbital":return this._evaluateOrbital(e,t);case"still":return this._evaluateStill(e,t);case"suspicious":return this._evaluateSuspicious(e,t)}}_evaluateGentle(e,t){const i=.001*e;return t[0]+=this.axes[0]*this.speed*i,t[1]+=this.axes[1]*this.speed*i,t[2]+=this.axes[2]*this.speed*i,t}_evaluateUnstable(e,t){const i=.001*e;let n=1;if(this.eruption.enabled&&(this.eruption.eruptionStartTime<0&&this.time>=this.eruption.nextEruptionTime&&(this.eruption.eruptionStartTime=this.time),this.eruption.eruptionStartTime>=0)){const e=this.time-this.eruption.eruptionStartTime;if(e<this.eruption.duration){const t=e/this.eruption.duration,i=Math.sin(t*Math.PI);n=1+(this.eruption.speedMultiplier-1)*i}else this.eruption.eruptionStartTime=-1,this.eruption.nextEruptionTime=this.time+this.eruption.interval}const a=this.speed*n;if(t[0]+=this.axes[0]*a*i,t[1]+=this.axes[1]*a*i,t[2]+=this.axes[2]*a*i,this.wobbleEnabled){const e=.001*this.time,i=this.shake.frequency||8,n=this.shake.amplitude||.02,a=.02,s=Math.min(n,a),o=Math.sin(e*i*Math.PI*2)*s*.7,r=Math.sin(e*i*Math.PI*2*1.3)*s*.5,l=Math.sin(e*i*Math.PI*2*.9)*s*.8;t[0]+=o,t[1]+=r,t[2]+=l}return t}_evaluateRhythmic(e,t){const i=.001*e;if(!this.musicSync||!this.rhythmEngine)return this._evaluateGentle(e,t);{const e=60/(this.rhythmEngine.bpm||120),n=.001*this.time%e,a=1+.3*Math.sin(n/e*Math.PI*2);t[0]+=this.axes[0]*this.speed*a*i,t[1]+=this.axes[1]*this.speed*a*i,t[2]+=this.axes[2]*this.speed*a*i}return t}_evaluateOrbital(e,t){const i=.001*e,n=.001*this.time,a=.5*this.speed,s=.1*Math.sin(n*a*Math.PI*2),o=.05*Math.sin(n*a*Math.PI*2*.5);return t[0]+=s*i,t[1]+=this.axes[1]*this.speed*i,t[2]+=o*i,t}_evaluateStill(e,t){const i=.001*e;return t[0]+=.1*this.axes[0]*i,t[1]+=.1*this.axes[1]*i,t[2]+=.1*this.axes[2]*i,t}_evaluateSuspicious(e,t){const i=.001*e,n=.001*this.time,a=4/this.speed,s=n%a/a;let o;if(s<.85)o=s/.85*Math.PI;else{const e=(s-.85)/.15;o=Math.PI*(1-e)}const r=o-t[1];return t[1]+=3*r*i,t}reset(){this.time=0}_applyEpisodicWobble(e,t){const i=this.episodicWobble;if(-1===i.wobbleStartTime&&this.time>=i.nextWobbleTime){i.wobbleStartTime=this.time,i.wobbleTarget=[(Math.random()-.5)*i.amplitude,(Math.random()-.5)*i.amplitude,(Math.random()-.5)*i.amplitude];const e=i.minInterval+Math.random()*(i.maxInterval-i.minInterval);i.nextWobbleTime=this.time+e}if(-1!==i.wobbleStartTime){const e=this.time-i.wobbleStartTime,n=Math.min(e/i.duration,1);if(n<1){const e=Math.sin(n*Math.PI);t[0]+=i.wobbleTarget[0]*e,t[1]+=i.wobbleTarget[1]*e,t[2]+=i.wobbleTarget[2]*e}else i.wobbleStartTime=-1}}updateConfig(e){if(this.config=e,this.type=e.type||"gentle",this.speed=e.speed||1,this.geometryRotation&&void 0!==this.geometryRotation.baseSpeed){const e=this.geometryRotation.baseSpeed,t=this.geometryRotation.axes||[0,1,0];this.axes=[t[0]*e*this.speed,t[1]*e*this.speed,t[2]*e*this.speed]}else this.axes=e.axes||[0,.01,0];this.shake=e.shake||{amplitude:0,frequency:0},this.musicSync=void 0!==e.musicSync&&e.musicSync}applyUndertoneMultipliers(e){if(void 0!==e.speedMultiplier&&(this.speed*=e.speedMultiplier),void 0!==e.shakeMultiplier&&this.shake.amplitude&&(this.shake.amplitude*=e.shakeMultiplier),void 0!==e.enableEpisodicWobble&&(this.episodicWobble.enabled=e.enableEpisodicWobble,this.episodicWobble.enabled&&0===this.episodicWobble.nextWobbleTime)){const e=this.episodicWobble.minInterval+Math.random()*(this.episodicWobble.maxInterval-this.episodicWobble.minInterval);this.episodicWobble.nextWobbleTime=this.time+e}}setWobbleEnabled(e){this.wobbleEnabled=e}}class xe{constructor(e={}){this.config=e,this.strength=void 0!==e.strength?e.strength:.5,this.damping=void 0!==e.damping?e.damping:.8,this.centerOfMass=e.centerOfMass||[0,-.3,0],this.axes=e.axes||{pitch:!0,roll:!0,yaw:!1},this.angularVelocity={x:0,y:0,z:0}}update(e,t){if(0===this.strength)return t;const i=.001*e,n=t[0],a=t[1],s=t[2];if(this.axes.pitch){const e=-n*this.strength;this.angularVelocity.x+=e*i,this.angularVelocity.x*=1-this.damping,t[0]+=this.angularVelocity.x*i}if(this.axes.roll){const e=-s*this.strength;this.angularVelocity.z+=e*i,this.angularVelocity.z*=1-this.damping,t[2]+=this.angularVelocity.z*i}if(this.axes.yaw){const e=-a*this.strength;this.angularVelocity.y+=e*i,this.angularVelocity.y*=1-this.damping,t[1]+=this.angularVelocity.y*i}return t}reset(){this.angularVelocity={x:0,y:0,z:0}}updateConfig(e){this.config=e,this.strength=void 0!==e.strength?e.strength:this.strength,this.damping=void 0!==e.damping?e.damping:this.damping,this.centerOfMass=e.centerOfMass||this.centerOfMass,this.axes=e.axes||this.axes}applyUndertoneMultipliers(e){void 0!==e.strengthMultiplier&&(this.strength*=e.strengthMultiplier)}}class Ce{constructor(t={},i=null){this.config=t,this.camera=i,this.strength=void 0!==t.strength?t.strength:1,this.lockedFace=t.lockedFace||[0,0,1],this.calibrationRotation=t.calibrationRotation||[0,0,0],this.lerpSpeed=void 0!==t.lerpSpeed?t.lerpSpeed:1,this.tempVector=new e.Vector3,this.tempQuaternion=new e.Quaternion,this.targetQuaternion=new e.Quaternion,this.calibrationQuaternion=new e.Quaternion,this.currentQuaternion=new e.Quaternion,this._lockedFaceVec=new e.Vector3,this._targetMatrix=new e.Matrix4,this._lookAtOrigin=new e.Vector3(0,0,0),this._upVector=new e.Vector3(0,1,0),this._tempEuler=new e.Euler(0,0,0,"XYZ"),this._defaultPosition=new e.Vector3(0,0,0)}update(e,t,i){if(0===this.strength||!this.camera)return t;const n=i||this._defaultPosition,a=.001*e;this.tempVector.copy(this.camera.position).sub(n),this.tempVector.lengthSq()<1e-4&&this.tempVector.set(0,0,1),this.tempVector.normalize(),this._lockedFaceVec.set(this.lockedFace[0],this.lockedFace[1],this.lockedFace[2]).normalize(),this._targetMatrix.lookAt(this.tempVector,this._lookAtOrigin,this._upVector),this.targetQuaternion.setFromRotationMatrix(this._targetMatrix),0===this.calibrationRotation[0]&&0===this.calibrationRotation[1]&&0===this.calibrationRotation[2]||(this._tempEuler.set(this.calibrationRotation[0],this.calibrationRotation[1],this.calibrationRotation[2],"XYZ"),this.calibrationQuaternion.setFromEuler(this._tempEuler),this.targetQuaternion.multiply(this.calibrationQuaternion)),this._tempEuler.set(t[0],t[1],t[2],"XYZ"),this.currentQuaternion.setFromEuler(this._tempEuler);const s=Math.min(1,this.strength*this.lerpSpeed*a*60);return this.currentQuaternion.slerp(this.targetQuaternion,s),this._tempEuler.setFromQuaternion(this.currentQuaternion,"XYZ"),t[0]=this._tempEuler.x,t[1]=this._tempEuler.y,t[2]=this._tempEuler.z,t}setCamera(e){this.camera=e}setCalibrationRotation(e){this.calibrationRotation=e}updateConfig(e){this.config=e,this.strength=void 0!==e.strength?e.strength:this.strength,this.lockedFace=e.lockedFace||this.lockedFace,this.calibrationRotation=e.calibrationRotation||this.calibrationRotation,this.lerpSpeed=void 0!==e.lerpSpeed?e.lerpSpeed:this.lerpSpeed}dispose(){this.camera=null,this.tempVector=null,this.tempQuaternion=null,this.targetQuaternion=null,this.calibrationQuaternion=null,this.currentQuaternion=null}}const De=new Map;var Pe=function(e){return De.get(e)||null},Be={name:"bounce",emoji:"⬆️",type:"blending",description:"Vertical oscillation with smooth easing",config:{duration:800,musicalDuration:{musical:!0,beats:2},amplitude:30,frequency:2,axis:"vertical",damping:!0,easing:"sine",strength:.6,particleMotion:{type:"bounce",axis:"vertical",strength:.6,frequency:2}},rhythm:{enabled:!0,syncMode:"beat",timingSync:"nextBeat",interruptible:!0,priority:3,blendable:!0,crossfadePoint:"anyBeat",amplitudeSync:{onBeat:1.8,offBeat:.6,curve:"bounce"},frequencySync:{mode:"tempo",multiplier:1},durationSync:{mode:"beats",beats:4},accentResponse:{enabled:!0,multiplier:1.5},patternOverrides:{waltz:{frequencySync:{multiplier:.75},durationSync:{beats:3}},swing:{amplitudeSync:{onBeat:2,offBeat:.4,curve:"ease"}},dubstep:{amplitudeSync:{onBeat:1.5,dropBeat:3,curve:"pulse"}},breakbeat:{frequencySync:{multiplier:1.5},amplitudeSync:{onBeat:2.2,offBeat:.3}}}},initialize(e,t){e.gestureData||(e.gestureData={}),e.gestureData.bounce={startY:e.y,startX:e.x,startVx:e.vx,startVy:e.vy,initialized:!0}},apply(e,t,i,n,a,s){e.gestureData?.bounce?.initialized||this.initialize(e,i);const o={...this.config,...i},r=o.strength||this.config.strength||1,l=this.easeInOutCubic(t);let{frequency:h}=o;const c=i.phase||0;let u=o.amplitude*r*e.scaleFactor;i.rhythmModulation&&(u*=i.rhythmModulation.amplitudeMultiplier||1,u*=i.rhythmModulation.accentMultiplier||1,i.rhythmModulation.frequencyMultiplier&&(h*=i.rhythmModulation.frequencyMultiplier));const d=Math.sin((l+c)*Math.PI*2*h);if(o.damping&&t>.7&&(u*=1-(t-.7)/.3*.8),"vertical"===o.axis?(e.vy+=d*u*.01*n,t>.9&&(e.vx*=.98)):"horizontal"===o.axis&&(e.vx+=d*u*.01*n,t>.9&&(e.vy*=.98)),t>.9){const i=1-10*(t-.9);e.vx=e.vx*(.95+.05*i),e.vy=e.vy*(.95+.05*i)}},cleanup(e){e.gestureData?.bounce&&delete e.gestureData.bounce},easeInOutCubic:e=>e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2,"3d":{evaluate(e,t){const i=t||{},n=i.amplitude||30,a=i.frequency||2,s=.003*n*(i.strength||.6),o=(e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2)*Math.PI*a,r=Math.abs(Math.sin(o));let l=s;return e>.7&&(l*=1-(e-.7)/.3*.8),{position:[0,r*l,0],rotation:[0,0,0],scale:1+.08*r}}}},ke={name:"pulse",emoji:"💗",type:"blending",description:"Radial expansion and contraction from center",config:{duration:600,amplitude:30,frequency:1,holdPeak:.1,easing:"sine",scaleAmount:.2,glowAmount:.3,strength:.15,direction:"outward",particleMotion:{type:"pulse",strength:.15,direction:"outward",frequency:1}},rhythm:{enabled:!0,syncMode:"beat",amplitudeSync:{onBeat:1.6,offBeat:.8,curve:"pulse"},frequencySync:{mode:"locked",subdivision:"quarter"},durationSync:{mode:"beats",beats:1},accentResponse:{enabled:!0,multiplier:2},patternOverrides:{waltz:{amplitudeSync:{onBeat:2,offBeat:.5},durationSync:{beats:3}},swing:{amplitudeSync:{onBeat:1.8,offBeat:.6,curve:"ease"},frequencySync:{subdivision:"swing"}},dubstep:{amplitudeSync:{onBeat:1.2,dropBeat:4,curve:"pulse"}},breakbeat:{frequencySync:{mode:"random",range:[.5,2]},amplitudeSync:{onBeat:2.5,offBeat:.3}}}},initialize(e,t,i,n){e.gestureData||(e.gestureData={});const a=e.x-i,s=e.y-n,o=Math.sqrt(a*a+s*s),r=Math.atan2(s,a);e.gestureData.pulse={baseDistance:o,angle:r,startX:e.x,startY:e.y,initialized:!0}},apply(e,t,i,n,a,s){e.gestureData?.pulse?.initialized||this.initialize(e,i,a,s);const o=e.gestureData.pulse,r={...this.config,...i},l=i.strength||1,h=this.easeInOutSine(t);let c,{frequency:u}=r,{amplitude:d}=r;i.rhythmModulation&&(d*=i.rhythmModulation.amplitudeMultiplier||1,d*=i.rhythmModulation.accentMultiplier||1,i.rhythmModulation.frequencyMultiplier&&(u*=i.rhythmModulation.frequencyMultiplier));const m=h*u*2%2;c=r.holdPeak>0&&m>1-r.holdPeak&&m<1+r.holdPeak?1:Math.sin(h*Math.PI*2*u);const p=c*d*l*e.scaleFactor,g=o.baseDistance+p,f=a+Math.cos(o.angle)*g,y=s+Math.sin(o.angle)*g,v=.15*n;if(e.vx+=(f-e.x)*v*.1,e.vy+=(y-e.y)*v*.1,t>.9){const i=1-10*(t-.9);e.vx*=.9+.1*i,e.vy*=.9+.1*i}},cleanup(e){e.gestureData?.pulse&&delete e.gestureData.pulse},easeInOutSine:e=>-(Math.cos(Math.PI*e)-1)/2,"3d":{evaluate(e,t){const i=t||{},n=i.frequency||1,a=i.strength||.15,s=i.scaleAmount||.2,o=i.glowAmount||.3,r=-(Math.cos(Math.PI*e)-1)/2,l=Math.sin(r*Math.PI*2*n);return{position:[0,0,0],rotation:[0,0,0],scale:1+l*s*a,glowIntensity:1+Math.max(-.3,Math.min(.3,l*o*a*2)),glowBoost:Math.max(0,.8*l)}}}},Te={name:"shake",emoji:"🫨",type:"blending",description:"Random jitter movement for vibration effects",config:{duration:400,amplitude:15,frequency:15,decay:.9,smoothing:.1,axes:"both",easing:"linear",strength:3,particleMotion:{type:"shake",strength:3,frequency:15,decay:!1}},rhythm:{enabled:!0,syncMode:"subdivision",amplitudeSync:{subdivision:"sixteenth",onBeat:2.5,offBeat:.7,curve:"pulse"},frequencySync:{mode:"tempo",baseFrequency:15,scaling:"linear"},durationSync:{mode:"beats",beats:2},patternOverrides:{breakbeat:{amplitudeSync:{onBeat:3,offBeat:.2},frequencySync:{mode:"random",range:[8,20]}},dubstep:{amplitudeSync:{subdivision:"eighth",onBeat:4,dropBeat:6,curve:"pulse"}},swing:{amplitudeSync:{onBeat:1.8,offBeat:1,curve:"ease"}}}},initialize(e,t){e.gestureData||(e.gestureData={}),e.gestureData.shake={originalX:e.x,originalY:e.y,randomAngle:Math.random()*Math.PI*2,initialized:!0}},apply(e,t,i,n,a,s){e.gestureData?.shake?.initialized||this.initialize(e,i);const o=e.gestureData.shake,r={...this.config,...i},l=r.strength||this.config.strength||1;let{amplitude:h}=r,{frequency:c}=r;i.rhythmModulation&&(h*=i.rhythmModulation.amplitudeMultiplier||1,h*=i.rhythmModulation.accentMultiplier||1,i.rhythmModulation.frequencyMultiplier&&(c*=i.rhythmModulation.frequencyMultiplier));const u=r.decay?1-t:1,d=Math.sin(t*Math.PI*c)*h*u*l*e.scaleFactor,m=d*Math.cos(o.randomAngle),p=d*Math.sin(o.randomAngle);e.x=o.originalX+m,e.y=o.originalY+p},pseudoRandom(e){const t=1e4*Math.sin(e);return t-Math.floor(t)},cleanup(e){e.gestureData?.shake&&(e.x=e.gestureData.shake.originalX,e.y=e.gestureData.shake.originalY,delete e.gestureData.shake)},"3d":{evaluate(e,t){const i=t||{},n=.015*(i.amplitude||15),a=i.frequency||15,s=i.strength||1,o=i.decay?1-e:1,r=Math.sin(e*Math.PI*a)*n*o*s,l=Math.floor(e*a);return{position:[r*(1e4*Math.sin(l)%1-.5)*2,0,r*(1e4*Math.sin(1.3*l)%1-.5)*2],rotation:[0,0,r*(1e4*Math.sin(1.7*l)%1-.5)*.5],scale:1}}}},Ee={name:"nod",emoji:"🙂",type:"blending",description:"Vertical nodding motion",config:{duration:500,amplitude:15,frequency:2,easing:"sine",strength:.4,particleMotion:{type:"bounce",axis:"vertical",strength:.4,frequency:2,phase:0}},rhythm:{enabled:!0,syncMode:"beat",timingSync:"nextBeat",interruptible:!1,priority:5,blendable:!1,minDuration:"halfBar",frequencySync:{mode:"subdivision",subdivision:"half",multiplier:1},amplitudeSync:{onBeat:1.4,offBeat:.8,curve:"ease"},durationSync:{mode:"beats",beats:2},patternOverrides:{waltz:{frequencySync:{subdivision:"quarter"},amplitudeSync:{onBeat:1.6,curve:"ease"}},swing:{amplitudeSync:{onBeat:1.5,offBeat:.9}},dubstep:{amplitudeSync:{onBeat:1.2,dropBeat:3,curve:"pulse"}}}},initialize(e,t){e.gestureData||(e.gestureData={}),e.gestureData.nod={startY:e.y,initialized:!0}},apply(e,t,i,n,a,s){e.gestureData?.nod?.initialized||this.initialize(e,i);const o={...this.config,...i},r=o.strength||this.config.strength||1;let{frequency:l}=o,{amplitude:h}=o;i.rhythmModulation&&(h*=i.rhythmModulation.amplitudeMultiplier||1,h*=i.rhythmModulation.accentMultiplier||1,i.rhythmModulation.frequencyMultiplier&&(l*=i.rhythmModulation.frequencyMultiplier));const c=Math.sin(t*Math.PI*2*l);h=h*r*e.scaleFactor,e.vy+=c*h*.01*n,t>.9&&(e.vy*=.95)},cleanup(e){e.gestureData?.nod&&delete e.gestureData.nod},"3d":{evaluate(e,t){const i={...this.config,...t};let{frequency:n}=i,{amplitude:a}=i;t.rhythmModulation&&(a*=t.rhythmModulation.amplitudeMultiplier||1,a*=t.rhythmModulation.accentMultiplier||1,t.rhythmModulation.frequencyMultiplier&&(n*=t.rhythmModulation.frequencyMultiplier));const s=Math.sin(e*Math.PI),o=e>.9?.95:1;return{position:[0,0,s*(.1*a)*.015*o],rotation:[s*(.08*a)*o,0,0],scale:1}}}},Ie={name:"vibrate",emoji:"📳",type:"blending",description:"High frequency vibration",config:{duration:500,frequency:20,amplitude:8,easing:"linear",strength:2,particleMotion:{type:"shake",strength:2,frequency:20,amplitude:8}},rhythm:{enabled:!0,syncMode:"subdivision",frequencySync:{subdivision:"thirty-second",baseFrequency:20,tempoScaling:!0},amplitudeSync:{onBeat:1.5,offBeat:.8,curve:"pulse"},durationSync:{mode:"beats",beats:1},patternOverrides:{dubstep:{frequencySync:{subdivision:"sixteenth"},amplitudeSync:{onBeat:2,dropBeat:3}},breakbeat:{frequencySync:{mode:"random",range:[15,30]}}}},initialize(e,t){e.gestureData||(e.gestureData={}),e.gestureData.vibrate={timer:0,seed:1e3*Math.random(),initialized:!0}},apply(e,t,i,n,a,s){e.gestureData?.vibrate?.initialized||this.initialize(e,i);const o=e.gestureData.vibrate,r={...this.config,...i},l=r.strength||this.config.strength||1;let{amplitude:h}=r,{frequency:c}=r;i.rhythmModulation&&(h*=i.rhythmModulation.amplitudeMultiplier||1,h*=i.rhythmModulation.accentMultiplier||1,i.rhythmModulation.frequencyMultiplier&&(c*=i.rhythmModulation.frequencyMultiplier)),o.timer+=n*c;const u=(Math.random()-.5)*h*l,d=(Math.random()-.5)*h*l;if(e.vx+=.5*u*n,e.vy+=.5*d*n,e.vx*=.9,e.vy*=.9,t>.8){const i=1-5*(t-.8);e.vx*=i,e.vy*=i}},cleanup(e){e.gestureData?.vibrate&&delete e.gestureData.vibrate},"3d":{evaluate(e,t){const i={...this.config,...t};let{amplitude:n}=i;const a=i.strength||this.config.strength||1;t.rhythmModulation&&(n*=t.rhythmModulation.amplitudeMultiplier||1,n*=t.rhythmModulation.accentMultiplier||1);const s=Math.sin(e*Math.PI),o=n*a*.003*s;return{position:[(Math.random()-.5)*o,(Math.random()-.5)*o,(Math.random()-.5)*o],rotation:[.01*(Math.random()-.5)*s,.01*(Math.random()-.5)*s,.01*(Math.random()-.5)*s],scale:1+.01*(Math.random()-.5)*s}}}},Ae={name:"orbit",emoji:"🪐",description:"3D orbital motion around center",type:"override",config:{speed:1,rotations:1,zRotations:1,smoothness:.15,verticalOscillation:0,centripetal:!1},rhythm:{enabled:!0,syncMode:"bar",speedSync:{mode:"tempo",baseSpeed:1,scaling:"linear"},rotationSync:{mode:"bars",rotationsPerBar:1,zSync:!0},radiusSync:{subdivision:"quarter",pulsAmount:.1,curve:"ease"},patternOverrides:{waltz:{rotationSync:{rotationsPerBar:.75},radiusSync:{pulsAmount:.15}},swing:{speedSync:{mode:"swing",ratio:.67},verticalOscillation:.2},dubstep:{radiusSync:{subdivision:"eighth",pulsAmount:.3,dropMultiplier:2}},breakbeat:{speedSync:{mode:"random",range:[.5,2]},centripetal:!0}}},apply:function(e,t,i,n,a,s){e.gestureData||(e.gestureData={});const o=e.gestureData,r=i,l=i.amplitude||1;if(!o.initialized){o.originalX=e.x,o.originalY=e.y,o.originalZ=e.z||0,o.originalVx=e.vx||0,o.originalVy=e.vy||0;const t=e.x-a,i=e.y-s;o.radius=Math.sqrt(t*t+i*i),o.radius<50&&(o.radius=50+100*Math.random()),o.initialAngle=Math.atan2(i,t),o.orbitSpeed=r.speed*(.8+.4*Math.random()),o.orbitTilt=.3*Math.random(),o.initialized=!0}let{rotations:h}=r,c=.05;r.rhythmModulation&&(r.rhythmModulation.speedMultiplier&&(o.orbitSpeed*=r.rhythmModulation.speedMultiplier),r.rhythmModulation.rotationMultiplier&&(h*=r.rhythmModulation.rotationMultiplier),r.rhythmModulation.radiusPulse&&(c=r.rhythmModulation.radiusPulse));let u=1,d=1;t<.15?(u=t/.15,u=u*u*(3-2*u),d=u):t>.85&&(u=(1-t)/.15,u=u*u*(3-2*u),d=u);const m=o.initialAngle+t*Math.PI*2*h*u,p=1+Math.sin(t*Math.PI*4)*c*u,g=o.radius*l*p*u,f=a+Math.cos(m)*g,y=s+Math.sin(m)*g,v=m*r.zRotations;if(e.z=.8*Math.sin(v)*u+o.originalZ*(1-u),t<.15){const t=.3*u;e.x=o.originalX+(f-o.originalX)*t,e.y=o.originalY+(y-o.originalY)*t;const i=-Math.sin(m)*g*o.orbitSpeed,n=Math.cos(m)*g*o.orbitSpeed;e.vx=o.originalVx+(i-o.originalVx)*d,e.vy=o.originalVy+(n-o.originalVy)*d}else if(t>.85){e.x=f+(o.originalX-f)*(1-u),e.y=y+(o.originalY-y)*(1-u);const t=-Math.sin(m)*g*o.orbitSpeed,i=Math.cos(m)*g*o.orbitSpeed;e.vx=t*d+o.originalVx*(1-d),e.vy=i*d+o.originalVy*(1-d)}else{if(r.verticalOscillation>0){const t=Math.sin(2*m)*r.verticalOscillation*l;e.y=y+t,e.x=f}else{const t=r.smoothness||.1;e.x+=(f-e.x)*t,e.y+=(y-e.y)*t}e.vx=-Math.sin(m)*g*o.orbitSpeed,e.vy=Math.cos(m)*g*o.orbitSpeed}if(r.centripetal){const i=1+.3*(1-Math.abs(e.z)),n=o.initialAngle+t*Math.PI*2*r.rotations*i;e.x=a+Math.cos(n)*g,e.y=s+Math.sin(n)*g}},emotions:["zen","love","excited","surprise"],features:{uses3D:!0,smooth:!0,looping:!0,dramatic:!0},"3d":{evaluate(e,t){const i={...this.config,...t};let{rotations:n}=i;const{zRotations:a}=i;t.rhythmModulation&&t.rhythmModulation.rotationMultiplier&&(n*=t.rhythmModulation.rotationMultiplier);let s=1;e<.15?(s=e/.15,s=s*s*(3-2*s)):e>.85&&(s=(1-e)/.15,s=s*s*(3-2*s));const o=e*Math.PI*2*n*s,r=o*a,l=.1*Math.sin(o)*s,h=.05*Math.cos(o)*s,c=.05*Math.sin(r)*s;return{position:[0,0,.2*Math.sin(r)*s],rotation:[h,l,c],scale:1+.03*Math.sin(2*o)*s}}}},Re={name:"twitch",emoji:"⚡",type:"blending",description:"Nervous, paranoid twitching",config:{intensity:8,frequency:.08,duration:100,recovery:200,maxOffset:15,sharpness:.9},rhythm:{enabled:!0,syncMode:"subdivision",probabilitySync:{subdivision:"sixteenth",onBeat:.3,offBeat:.05,accentBoost:2},intensitySync:{onBeat:2,offBeat:.8,curve:"pulse"},patternOverrides:{breakbeat:{probabilitySync:{onBeat:.5,offBeat:.1},intensitySync:{onBeat:3,offBeat:.5}},dubstep:{intensitySync:{onBeat:1.5,dropBeat:5,curve:"pulse"}}}},apply(e,t,i,n,a,s){e.gestureData||(e.gestureData={}),e.gestureData.twitch||(e.gestureData.twitch={twitchOffset:{x:0,y:0},targetOffset:{x:0,y:0},isTwitching:!1,twitchTimer:0,cooldownTimer:0,lastTwitch:0});const o=e.gestureData.twitch,{config:r}=this;let l=i.intensity||r.intensity;i.rhythmModulation&&(l*=i.rhythmModulation.amplitudeMultiplier||1,l*=i.rhythmModulation.accentMultiplier||1,i.rhythmModulation.probabilityMultiplier);const h=Date.now();if(!o.isTwitching&&o.cooldownTimer<=0&&Math.random()<(i.frequency||r.frequency)){o.isTwitching=!0,o.twitchTimer=r.duration,o.cooldownTimer=r.recovery;const e=Math.random()*Math.PI*2,t=.5*r.maxOffset+Math.random()*(.5*r.maxOffset);o.targetOffset={x:Math.cos(e)*t*l/8,y:Math.sin(e)*t*l/8},o.lastTwitch=h}if(o.cooldownTimer>0&&(o.cooldownTimer-=16*n),o.isTwitching)if(o.twitchTimer-=16*n,o.twitchTimer>0){const{sharpness:e}=r;o.twitchOffset.x+=(o.targetOffset.x-o.twitchOffset.x)*e,o.twitchOffset.y+=(o.targetOffset.y-o.twitchOffset.y)*e}else o.isTwitching=!1;else o.twitchOffset.x*=.85,o.twitchOffset.y*=.85;e.vx+=o.twitchOffset.x*n*.5,e.vy+=o.twitchOffset.y*n*.5,Math.random()<.1&&(e.vx+=(Math.random()-.5)*l*.3,e.vy+=(Math.random()-.5)*l*.3)},cleanup(e){e.gestureData?.twitch&&delete e.gestureData.twitch},"3d":{evaluate(e,t){const i=t.config||{};let n=i.intensity||8;const a=i.maxOffset||15,s=i.frequency||.08;t.rhythmModulation&&(n*=t.rhythmModulation.amplitudeMultiplier||1,n*=t.rhythmModulation.accentMultiplier||1);const o=9999*Math.floor(10*e),r=e=>{const t=1e4*Math.sin(o+e);return t-Math.floor(t)};if(r(0)<3*s){const e=r(1)*Math.PI*2,t=a*n/8*.005;return{position:[Math.cos(e)*t*r(2),Math.sin(e)*t*r(3),(r(4)-.5)*t],rotation:[.2*(r(5)-.5),.2*(r(6)-.5),.2*(r(7)-.5)],scale:1+.1*(r(8)-.5)}}{const e=.5;return{position:[(r(10)-.5)*e,(r(11)-.5)*e,(r(12)-.5)*e],rotation:[.01*(r(13)-.5),.01*(r(14)-.5),.01*(r(15)-.5)],scale:1}}}}},ze={name:"sway",type:"blending",emoji:"🌊",description:"Gentle side-to-side swaying motion",config:{duration:2e3,amplitude:20,frequency:1,strength:.5},rhythm:{enabled:!0,syncMode:"bar",amplitudeSync:{onBeat:1.2,offBeat:.9,curve:"ease"},durationSync:{mode:"bars",bars:1},patternOverrides:{waltz:{durationSync:{bars:1},amplitudeSync:{onBeat:1.5,curve:"ease"}},swing:{amplitudeSync:{onBeat:1.3,offBeat:.7,curve:"bounce"}}}},apply(e,t,i,n,a,s){const o={...this.config,...i},r=o.amplitude||this.config.amplitude,l=o.frequency||this.config.frequency,h=o.strength||this.config.strength,c=Math.sin(t*Math.PI*2*l)*r;e.vx+=.01*c*n*h,e.vy+=.5*Math.cos(t*Math.PI*4)*n*h},cleanup(e){},"3d":{evaluate(e,t){const i={...this.config,...t};let n=i.amplitude||this.config.amplitude;const a=i.frequency||this.config.frequency,s=i.strength||this.config.strength;t.rhythmModulation&&(n*=t.rhythmModulation.amplitudeMultiplier||1,n*=t.rhythmModulation.accentMultiplier||1);const o=Math.sin(e*Math.PI*2*a),r=n*s*.3*.01,l=.15*o*s,h=.08*o*s;return{position:[o*r,.3*Math.cos(e*Math.PI*4)*r,Math.sin(e*Math.PI*a)*r*.5],rotation:[0,h,l],scale:1}}}},_e={name:"float",type:"blending",emoji:"🎈",description:"Gentle floating upward motion",config:{duration:2e3,amplitude:80,wobbleAmount:20,strength:1},rhythm:{enabled:!0,syncMode:"beat",amplitudeSync:{onBeat:1.5,offBeat:.8,curve:"bounce"},wobbleSync:{subdivision:"eighth",intensity:.7},durationSync:{mode:"bars",bars:2},accentResponse:{enabled:!0,multiplier:1.3},patternOverrides:{waltz:{wobbleSync:{subdivision:"quarter",intensity:.9}},dubstep:{amplitudeSync:{onBeat:2,curve:"pulse"}}}},apply(e,t,i,n,a,s){e.gestureData||(e.gestureData={}),e.gestureData.float||(e.gestureData.float={originalSize:e.size,originalOpacity:e.opacity||1});const o={...this.config,...i};let r=o.amplitude||this.config.amplitude,l=o.wobbleAmount||this.config.wobbleAmount;const h=o.strength||this.config.strength;i.rhythmModulation&&(r*=i.rhythmModulation.amplitudeMultiplier||1,r*=i.rhythmModulation.accentMultiplier||1,l*=i.rhythmModulation.wobbleMultiplier||1);const c=Math.sin(t*Math.PI*4)*l;e.vy-=.01*r*n*h*(1-.5*t),e.vx+=.01*c*n*h,e.size=e.baseSize*(1+.1*t),e.opacity=1-.3*t},cleanup(e){e.gestureData?.float?(e.opacity=e.gestureData.float.originalOpacity,e.size=e.gestureData.float.originalSize,delete e.gestureData.float):(e.opacity=1,e.size=e.baseSize),e.vx*=.5,e.vy*=.5},"3d":{evaluate(e,t){const i={...this.config,...t};let n=i.amplitude||this.config.amplitude,a=i.wobbleAmount||this.config.wobbleAmount;const s=i.strength||this.config.strength;t.rhythmModulation&&(n*=t.rhythmModulation.amplitudeMultiplier||1,n*=t.rhythmModulation.accentMultiplier||1,a*=t.rhythmModulation.wobbleMultiplier||1);const o=Math.sin(e*Math.PI),r=n*o*s*.005,l=Math.sin(e*Math.PI*4)*a*.3*.005,h=Math.sin(e*Math.PI)*Math.PI*.5*s,c=Math.sin(e*Math.PI);return{position:[l,r,0],rotation:[c*Math.sin(e*Math.PI*2)*.1,h,c*Math.cos(e*Math.PI*3)*.08],scale:1+.1*o}}}},Oe={name:"jitter",type:"blending",emoji:"🫨",description:"Nervous jittery movement",config:{duration:1e3,intensity:15,frequency:30,strength:1},rhythm:{enabled:!0,syncMode:"beat",amplitudeSync:{onBeat:2,offBeat:.5,curve:"pulse"},patternOverrides:{breakbeat:{amplitudeSync:{onBeat:3,offBeat:.3}},dubstep:{amplitudeSync:{onBeat:5,offBeat:.1,curve:"pulse"}}}},apply(e,t,i,n,a,s){e.gestureData||(e.gestureData={}),e.gestureData.jitter||(e.gestureData.jitter={originalSize:e.size});const o={...this.config,...i};let r=o.intensity||this.config.intensity;const l=o.strength||this.config.strength;i.rhythmModulation&&(r*=i.rhythmModulation.amplitudeMultiplier||1,r*=i.rhythmModulation.accentMultiplier||1);const h=(Math.random()-.5)*r*l,c=(Math.random()-.5)*r*l,u=1-.5*t;e.vx+=.1*h*n*u,e.vy+=.1*c*n*u,e.size=e.baseSize*(1+.1*(Math.random()-.5))},cleanup(e){e.gestureData?.jitter?(e.size=e.gestureData.jitter.originalSize,delete e.gestureData.jitter):e.size=e.baseSize,e.vx*=.7,e.vy*=.7},"3d":{evaluate(e,t){const i={...this.config,...t};let n=i.intensity||this.config.intensity;const a=i.strength||this.config.strength;t.rhythmModulation&&(n*=t.rhythmModulation.amplitudeMultiplier||1,n*=t.rhythmModulation.accentMultiplier||1);const s=Math.sin(e*Math.PI),o=n*a*.002*s;return{position:[(Math.random()-.5)*o,(Math.random()-.5)*o,(Math.random()-.5)*o],rotation:[.005*(Math.random()-.5)*s,.005*(Math.random()-.5)*s,.005*(Math.random()-.5)*s],scale:1+.02*(Math.random()-.5)*s}}}},Fe={name:"wiggle",emoji:"〰️",type:"additive",description:"Rapid side-to-side oscillation",config:{duration:600,musicalDuration:{musical:!0,beats:1},amplitude:15,frequency:6,strength:1,damping:.3,easing:"linear",particleMotion:{type:"wiggle",strength:1,amplitude:15,frequency:6}},rhythm:{enabled:!0,syncMode:"beat",frequencySync:{subdivision:"sixteenth",wigglePerBeat:4},amplitudeSync:{onBeat:1.5,offBeat:.8,curve:"bounce"},durationSync:{mode:"beats",beats:1}},apply(e,t,i,n,a,s,o){const r=(i.amplitude||this.config.amplitude)*a,l=i.frequency||this.config.frequency,h=1-n*(i.damping||this.config.damping),c=Math.sin(n*Math.PI*l)*r*h;e.vx+=.5*c;const u=Math.cos(n*Math.PI*l*2)*r*.1*h;e.vy+=.3*u},"3d":{evaluate(e,t){const i=t.config||{},n=t.strength||1,a=i.amplitude||15,s=i.frequency||6,o=i.damping||.3,r=Math.sin(e*Math.PI*s),l=1-e*o;return{position:[r*a*.008*n*l,0,0],rotation:[0,.25*r*n*l,0],scale:1}}}},Le={name:"headBob",emoji:"🎧",type:"additive",description:"Rhythmic vertical bobbing to music",config:{duration:600,musicalDuration:{musical:!0,beats:1},amplitude:12,frequency:2,strength:1,damping:.1,easing:"linear",particleMotion:{type:"headBob",strength:1,amplitude:12,frequency:2}},rhythm:{enabled:!0,syncMode:"beat",frequencySync:{subdivision:"eighth",bobsPerBeat:2},amplitudeSync:{onBeat:1.3,offBeat:1,curve:"pulse"},durationSync:{mode:"beats",beats:1}},apply(e,t,i,n,a,s,o){const r=(i.amplitude||this.config.amplitude)*a,l=i.frequency||this.config.frequency,h=1-n*(i.damping||this.config.damping),c=Math.sin(n*Math.PI*2*l)*r*h;e.vy+=.5*c;const u=Math.cos(n*Math.PI*2*l*1.5)*r*.05*h;e.vx+=.2*u},"3d":{evaluate(e,t){const i=t.config||{},n=t.strength||1,a=i.amplitude||12,s=i.frequency||2,o=i.damping||.1,r=Math.sin(e*Math.PI*2*s),l=1-e*o;return{position:[0,-r*a*.008*n*l,0],rotation:[r*(.045*a)*n*l,0,0],scale:1}}}},Ge={name:"lean",emoji:"↗️",type:"blending",description:"Diagonal tilting motion with smooth return",config:{duration:1200,musicalDuration:{musical:!0,beats:2},amplitude:10,frequency:1,direction:"right",strength:.7,particleMotion:{type:"lean",direction:"right",strength:.7,frequency:1}},rhythm:{enabled:!0,syncMode:"beat",timingSync:"nextBeat",interruptible:!0,priority:3,blendable:!0,crossfadePoint:"anyBeat",amplitudeSync:{onBeat:1.3,offBeat:.8,curve:"ease"},durationSync:{mode:"beats",beats:2},accentResponse:{enabled:!0,multiplier:1.4},patternOverrides:{waltz:{durationSync:{beats:3},amplitudeSync:{onBeat:1.5,offBeat:.6}},swing:{amplitudeSync:{onBeat:1.6,offBeat:.5,curve:"bounce"}}}},initialize(e,t){e.gestureData||(e.gestureData={}),e.gestureData.lean={startX:e.x,startY:e.y,startVx:e.vx,startVy:e.vy,initialized:!0}},apply(e,t,i,n,a,s){e.gestureData?.lean?.initialized||this.initialize(e,i);const o={...this.config,...i},r=o.strength||this.config.strength||1,l=this.easeInOutCubic(t),h=o.frequency||this.config.frequency;let c=o.amplitude*r*e.scaleFactor;i.rhythmModulation&&(c*=i.rhythmModulation.amplitudeMultiplier||1,c*=i.rhythmModulation.accentMultiplier||1);const u=Math.sin(l*Math.PI*h),d="left"===o.direction?-1:1;if(e.vx+=u*c*.015*n*d,e.vy+=u*c*.01*n*d*.5,t>.9){const i=1-10*(t-.9);e.vx=e.vx*(.95+.05*i),e.vy=e.vy*(.95+.05*i)}},cleanup(e){e.gestureData?.lean&&delete e.gestureData.lean},easeInOutCubic:e=>e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2,"3d":{evaluate(e,t){const i=t||{},n=i.amplitude||10,a=i.frequency||1,s=i.strength||.7,o=i.direction||"right",r=.003*n*s,l=e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2,h=Math.sin(l*Math.PI*a),c="left"===o?-1:1;return{position:[h*r*c,0,0],rotation:[0,0,.35*h*c],scale:1}}}},Ve={name:"point",emoji:"👉",type:"blending",description:"Directional pointing motion with forward momentum",config:{duration:1e3,musicalDuration:{musical:!0,beats:2},amplitude:15,direction:"right",strength:.8,particleMotion:{type:"point",direction:"right",strength:.8}},rhythm:{enabled:!0,syncMode:"beat",timingSync:"nextBeat",interruptible:!0,priority:4,blendable:!0,crossfadePoint:"anyBeat",amplitudeSync:{onBeat:1.5,offBeat:.7,curve:"ease"},durationSync:{mode:"beats",beats:2},accentResponse:{enabled:!0,multiplier:1.6},patternOverrides:{march:{amplitudeSync:{onBeat:2,offBeat:.5,curve:"pulse"}},swing:{amplitudeSync:{onBeat:1.4,offBeat:.8,curve:"bounce"}}}},initialize(e,t){e.gestureData||(e.gestureData={}),e.gestureData.point={startX:e.x,startY:e.y,startVx:e.vx,startVy:e.vy,initialized:!0}},apply(e,t,i,n,a,s){e.gestureData?.point?.initialized||this.initialize(e,i);const o={...this.config,...i},r=o.strength||this.config.strength||1,l=this.easeInOutCubic(t);let h=o.amplitude*r*e.scaleFactor;i.rhythmModulation&&(h*=i.rhythmModulation.amplitudeMultiplier||1,h*=i.rhythmModulation.accentMultiplier||1);const c=Math.sin(l*Math.PI);let u=0,d=0;switch(o.direction||"right"){case"right":u=1;break;case"left":u=-1;break;case"up":d=-1;break;case"down":d=1}if(e.vx+=c*h*.02*n*u,e.vy+=c*h*.02*n*d,t>.9){const i=1-10*(t-.9);e.vx=e.vx*(.95+.05*i),e.vy=e.vy*(.95+.05*i)}},cleanup(e){e.gestureData?.point&&delete e.gestureData.point},easeInOutCubic:e=>e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2,"3d":{evaluate(e,t){const i=t||{},n=i.amplitude||15,a=i.strength||.8,s=i.direction||"right",o=.005*n*a,r=e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2,l=Math.sin(r*Math.PI);let h=0,c=0;switch(s){case"right":h=l*o,c=.25*l;break;case"left":h=-l*o,c=.25*-l;break;case"up":case"down":c=0}return{position:[h,0,0],rotation:[0,c,0],scale:1}}}},qe={name:"reach",emoji:"🙌",type:"blending",description:"Upward reaching motion with scale increase",config:{duration:1400,musicalDuration:{musical:!0,beats:2},amplitude:25,strength:.9,scaleMax:1.05,particleMotion:{type:"reach",strength:.9,scaleMax:1.05}},rhythm:{enabled:!0,syncMode:"beat",timingSync:"nextBeat",interruptible:!0,priority:4,blendable:!0,crossfadePoint:"anyBeat",amplitudeSync:{onBeat:1.4,offBeat:.9,curve:"ease"},durationSync:{mode:"beats",beats:2},accentResponse:{enabled:!0,multiplier:1.5},patternOverrides:{uplifting:{amplitudeSync:{onBeat:1.8,offBeat:.7,curve:"ease"},durationSync:{beats:3}},ambient:{amplitudeSync:{onBeat:1.2,offBeat:1,curve:"linear"}}}},initialize(e,t){e.gestureData||(e.gestureData={}),e.gestureData.reach={startY:e.y,startVy:e.vy,originalSize:e.size,initialized:!0}},apply(e,t,i,n,a,s){e.gestureData?.reach?.initialized||this.initialize(e,i);const o={...this.config,...i},r=o.strength||this.config.strength||1,l=o.scaleMax||this.config.scaleMax||1.05,h=this.easeInOutCubic(t);let c=o.amplitude*r*e.scaleFactor;i.rhythmModulation&&(c*=i.rhythmModulation.amplitudeMultiplier||1,c*=i.rhythmModulation.accentMultiplier||1);const u=Math.sin(h*Math.PI);e.vy-=u*c*.015*n;const d=1+u*(l-1);if(e.size=e.baseSize*d,t>.9){const i=1-10*(t-.9);e.vy=e.vy*(.95+.05*i)}},cleanup(e){e.gestureData?.reach&&(e.gestureData.reach.originalSize?e.size=e.gestureData.reach.originalSize:e.size=e.baseSize,delete e.gestureData.reach)},easeInOutCubic:e=>e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2,"3d":{evaluate(e,t){const i=t||{},n=i.amplitude||25,a=i.strength||.9,s=i.scaleMax||1.05,o=.004*n*a,r=e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2,l=Math.sin(r*Math.PI);return{position:[0,l*o,0],rotation:[.1*l,0,0],scale:1+l*(s-1)}}}},Ne={name:"spin",emoji:"🌀",type:"override",description:"Orbital rotation around center point",config:{duration:600,musicalDuration:{musical:!0,beats:1},rotations:1,direction:"random",radiusMultiplier:1,spiralOut:!1,accelerate:!0,maintainDistance:!0,scaleAmount:.1,easing:"linear",strength:.7,particleMotion:{type:"spin",strength:.7,rotations:1,radius:1}},rhythm:{enabled:!0,syncMode:"bar",rotationSync:{mode:"bars",rotationsPerBar:1,accelerateOnBeat:!0},radiusSync:{subdivision:"quarter",expandOnBeat:1.2,contractOffBeat:.9,curve:"bounce"},durationSync:{mode:"beats",beats:4},patternOverrides:{waltz:{rotationSync:{rotationsPerBar:.75},radiusSync:{curve:"ease"}},swing:{rotationSync:{accelerateOnBeat:!1},direction:"alternating"},dubstep:{radiusSync:{subdivision:"eighth",expandOnBeat:1.5,dropMultiplier:2},spiralOut:!0},breakbeat:{rotationSync:{mode:"random",range:[.5,2]},direction:"random"}}},initialize(e,t,i,n){e.gestureData||(e.gestureData={});const a=e.x-i,s=e.y-n;let o=t.direction||this.config.direction;"random"===o&&(o=Math.random()<.5?"clockwise":"counter-clockwise"),e.gestureData.spin={startAngle:Math.atan2(s,a),startRadius:Math.sqrt(a*a+s*s)||30,originalX:e.x,originalY:e.y,originalVx:e.vx,originalVy:e.vy,direction:o,initialized:!0}},apply(e,t,i,n,a,s){e.gestureData?.spin?.initialized||this.initialize(e,i,a,s);const o=e.gestureData.spin,r={...this.config,...i},l=i.strength||1;let{rotations:h}=r,{radiusMultiplier:c}=r;i.rhythmModulation&&(i.rhythmModulation.rotationMultiplier&&(h*=i.rhythmModulation.rotationMultiplier),i.rhythmModulation.radiusMultiplier&&(c*=i.rhythmModulation.radiusMultiplier));let u=t;r.accelerate&&(u=t<.5?.5*this.easeInQuad(2*t):.5+.5*this.easeOutQuad(2*(t-.5)));const d=h*Math.PI*2*l,m="counter-clockwise"===o.direction?-1:1,p=o.startAngle+d*u*m;let g=o.startRadius;r.spiralOut&&(g*=1+.5*t),1!==c&&(g*=1+(c-1)*Math.sin(t*Math.PI));const f=a+Math.cos(p)*g,y=s+Math.sin(p)*g;if(e.x+=.25*(f-e.x),e.y+=.25*(y-e.y),e.vx=.5*(f-e.x),e.vy=.5*(y-e.y),t>.9){const i=10*(1-t);e.vx=e.vx*i+o.originalVx*(1-i),e.vy=e.vy*i+o.originalVy*(1-i)}},cleanup(e){if(e.gestureData?.spin){const t=e.gestureData.spin;e.vx=t.originalVx,e.vy=t.originalVy,delete e.gestureData.spin}},easeInQuad:e=>e*e,easeOutQuad:e=>e*(2-e),"3d":{evaluate(e,t){const{particle:i}=t;if(!i||!i.gestureData?.spin)return{position:[0,0,0],rotation:[0,0,0],scale:1};const n=i.gestureData.spin,a=t.config||{},s=t.strength||1;let o=e;a.accelerate&&(o=e<.5?e*e*4*.5:.5+(e-.5)*(2-(e-.5))*.5);const r=(a.rotations||1)*Math.PI*2*s,l="counter-clockwise"===n.direction?-1:1;return{position:[0,0,0],rotation:[0,r*Math.sin(o*Math.PI)*l,0],scale:1+(a.scaleAmount||.1)*Math.sin(e*Math.PI)*s}}}},je={name:"jump",emoji:"🦘",type:"override",description:"Squash, leap, and land with classic animation principles",config:{duration:800,jumpHeight:60,squashAmount:.8,stretchAmount:1.2,anticipation:.2,hangTime:.1,landingImpact:!0,driftOutward:!0,easing:"quad",particleMotion:{type:"jump",strength:.9,jumpHeight:60,squash:.8,stretch:1.2}},rhythm:{enabled:!0,syncMode:"beat",phaseSync:{anticipation:"eighth",jump:"beat",landing:"sixteenth"},heightSync:{onBeat:1.5,offBeat:.8,accent:2,curve:"exponential"},deformationSync:{squashOnBeat:.6,stretchOnBeat:1.4,timing:"anticipatory"},hangTimeSync:{mode:"tempo",baseDuration:.1,scaling:"inverse"},dynamics:{forte:{jumpHeight:80,stretch:1.3},piano:{jumpHeight:30,stretch:1.1}}},initialize(e,t,i,n){e.gestureData||(e.gestureData={}),e.gestureData.jump={startX:e.x,startY:e.y,startSize:e.size,originalVx:e.vx,originalVy:e.vy,driftDirection:.1*(e.x-i),initialized:!0}},apply(e,t,i,n,a,s){e.gestureData?.jump?.initialized||this.initialize(e,i,a,s);const o=e.gestureData.jump,r={...this.config,...i},l=i.strength||1,h=r.jumpHeight*l*e.scaleFactor,c=r.squashAmount,u=r.stretchAmount,d=r.anticipation,m=1-.5*r.anticipation;if(t<d){const i=t/d,n=this.easeOutQuad(i);e.size=o.startSize*(1-(1-c)*n),e.y=o.startY+5*n*e.scaleFactor,e.vx=0,e.vy=0}else if(t<m){const i=(t-d)/(m-d);let n=Math.sin(i*Math.PI);if(r.hangTime>0&&i>.4&&i<.6){const e=(i-.4)/.2;n=.95+.05*this.easeInOutCubic(e)}if(e.y=o.startY-n*h,r.driftOutward&&(e.x=o.startX+n*o.driftDirection),i<.5){const t=2*i;e.size=o.startSize*(c+(u-c)*t)}else{const t=2*(i-.5);e.size=o.startSize*(u-(u-1)*t*.8)}e.vx=.5*o.driftDirection,e.vy=-Math.cos(i*Math.PI)*h*.1}else{const i=(t-m)/(1-m),n=this.easeOutBounce(i);if(e.y=o.startY,r.landingImpact)if(i<.3){const t=i/.3;e.size=o.startSize*(1-(1-.8*c)*(1-t))}else{const t=(i-.3)/.7;e.size=o.startSize*(.8*c+(1-.8*c)*t)}else e.size=o.startSize*(c+(1-c)*n);e.vx=o.originalVx*n,e.vy=o.originalVy*n}},cleanup(e){if(e.gestureData?.jump){const t=e.gestureData.jump;e.size=t.startSize,e.vx=t.originalVx,e.vy=t.originalVy,delete e.gestureData.jump}},easeOutQuad:e=>e*(2-e),easeInOutCubic:e=>e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2,easeOutBounce(e){const t=7.5625,i=2.75;return e<1/i?t*e*e:e<2/i?t*(e-=1.5/i)*e+.75:e<2.5/i?t*(e-=2.25/i)*e+.9375:t*(e-=2.625/i)*e+.984375},"3d":{evaluate(e,t){const i=t.config||t||{},n=t.strength||1,a=.004*(i.jumpHeight||60)*n,s=i.squashAmount||.8,o=i.stretchAmount||1.2,r=i.anticipation||.2,l=1-.5*r;let h=0,c=1,u=0;if(e<r){const t=e/r,i=t*(2-t);c=1-(1-s)*i,h=.02*-i}else if(e<l){const t=(e-r)/(l-r);h=Math.sin(t*Math.PI)*a,c=t<.5?s+2*t*(o-s):o-2*(t-.5)*(o-1)*.8,u=.05*Math.sin(t*Math.PI)}else{const t=(e-l)/(1-l);if(t<.5){const e=2*t;h=-Math.sin(e*Math.PI)*a*.15}else h=0;c=!1!==i.landingImpact?t<.3?1-(1-.8*s)*(1-t/.3):.8*s+(t-.3)/.7*(1-.8*s):s+(1-s)*t}return{position:[0,h,0],rotation:[u,0,0],scale:c}}}},Ue={name:"morph",emoji:"✨",type:"override",description:"Form geometric patterns and shapes",config:{musicalDuration:{musical:!0,beats:2,minBeats:1,maxBeats:8},phases:[{name:"gather",beats:.25},{name:"form",beats:.75},{name:"hold",beats:.5},{name:"dissolve",beats:.5}],morphType:"fluid",pattern:"star",points:5,innerRadius:.4,size:80,amplitude:20,rotation:0,smooth:!0,randomizeOrder:!1,easing:"sine",strength:1.2,particleMotion:{type:"morph",pattern:"star",strength:1.2,smooth:!0,points:5}},rhythm:{enabled:!0,syncMode:"phrase",patternSync:{verse:"circle",chorus:"star",bridge:"heart",drop:"explosion"},timingSync:{formationBeat:1,holdBeats:2,dissolveBeat:4,curve:"anticipatory"},sizeSync:{onBeat:1.2,offBeat:.95,subdivision:"quarter",curve:"elastic"},rotationSync:{mode:"continuous",degreesPerBar:90,direction:"clockwise"},dynamics:{forte:{points:8,size:100},piano:{points:3,size:60}}},initialize(e,t,i,n,a){e.gestureData||(e.gestureData={});const s={...this.config,...t},o=e.x,r=e.y,l=Math.atan2(e.y-n,e.x-i),h=Math.random()<.5?1:-1;let c,u;const d=s.size*e.scaleFactor,m=(s.rotation||0)*Math.PI/180*h;switch(s.pattern){case"star":c=i,u=n,this.calculateStarPosition(e,l,d,s.points,s.innerRadius,m,i,n);break;case"heart":this.calculateHeartPosition(e,l,d,m,i,n);break;case"square":this.calculateSquarePosition(e,l,d,m,i,n);break;case"triangle":this.calculateTrianglePosition(e,l,d,m,i,n);break;default:{const e=d;c=i+Math.cos(l+m)*e,u=n+Math.sin(l+m)*e;break}}e.gestureData.morph={startX:o,startY:r,targetX:e.gestureData.morphTargetX||c,targetY:e.gestureData.morphTargetY||u,originalVx:e.vx,originalVy:e.vy,rotationDirection:h,initialized:!0}},calculateStarPosition(e,t,i,n,a,s,o,r){const l=((t+Math.PI)%(2*Math.PI)+2*Math.PI)%(2*Math.PI),h=Math.floor(l/(2*Math.PI)*10),c=h%2==0,u=Math.floor(h/2);let d;d=c?72*u*Math.PI/180:(72*u+36)*Math.PI/180,d+=s;const m=c?i:i*a;e.gestureData.morphTargetX=o+Math.cos(d)*m,e.gestureData.morphTargetY=r+Math.sin(d)*m},calculateHeartPosition(e,t,i,n,a,s){const o=(t+Math.PI)/(2*Math.PI),r=.05*i,l=16*Math.pow(Math.sin(o*Math.PI*2),3),h=-(13*Math.cos(o*Math.PI*2)-5*Math.cos(2*o*Math.PI*2)-2*Math.cos(3*o*Math.PI*2)-Math.cos(4*o*Math.PI*2)),c=Math.cos(n),u=Math.sin(n),d=l*c-h*u,m=l*u+h*c;e.gestureData.morphTargetX=a+d*r,e.gestureData.morphTargetY=s+m*r},calculateSquarePosition(e,t,i,n,a,s){const o=((t+n)%(2*Math.PI)+2*Math.PI)%(2*Math.PI);let r,l;const h=i;o<Math.PI/4||o>=7*Math.PI/4?(r=h,l=h*Math.tan(o)):o<3*Math.PI/4?(r=h/Math.tan(o),l=h):o<5*Math.PI/4?(r=-h,l=-h*Math.tan(o)):(r=-h/Math.tan(o),l=-h);const c=Math.cos(n),u=Math.sin(n),d=r*c-l*u,m=r*u+l*c;e.gestureData.morphTargetX=a+d,e.gestureData.morphTargetY=s+m},calculateTrianglePosition(e,t,i,n,a,s){const o=[{x:0,y:-i},{x:.866*-i,y:.5*i},{x:.866*i,y:.5*i}],r=Math.floor((t+Math.PI)/(2*Math.PI)*3)%3,l=(r+1)%3,h=Math.random(),c=o[r].x+(o[l].x-o[r].x)*h,u=o[r].y+(o[l].y-o[r].y)*h,d=Math.cos(n),m=Math.sin(n),p=c*d-u*m,g=c*m+u*d;e.gestureData.morphTargetX=a+p,e.gestureData.morphTargetY=s+g},apply(e,t,i,n,a,s){e.gestureData?.morph?.initialized||this.initialize(e,i,a,s);const o=e.gestureData.morph,r={...this.config,...i};let l,h,c=t;if(r.holdTime>0){const e=.5-r.holdTime/2,i=.5+r.holdTime/2;c=t<e?t/e*.5:t<i?.5:.5+(t-i)/(1-i)*.5}if(c<=.5){const e=2*c;l=o.startX+(o.targetX-o.startX)*this.easeOutQuad(e),h=o.startY+(o.targetY-o.startY)*this.easeOutQuad(e)}else{const e=2*(c-.5);l=o.targetX+(o.startX-o.targetX)*this.easeInQuad(e),h=o.targetY+(o.startY-o.targetY)*this.easeInQuad(e)}if(r.smooth){const t=.2;e.x+=(l-e.x)*t,e.y+=(h-e.y)*t}else e.x=l,e.y=h;if(e.vx=.5*(l-e.x),e.vy=.5*(h-e.y),t>.9){const i=10*(1-t);e.vx=e.vx*i+o.originalVx*(1-i),e.vy=e.vy*i+o.originalVy*(1-i)}},cleanup(e){if(e.gestureData?.morph){const t=e.gestureData.morph;e.vx=t.originalVx,e.vy=t.originalVy,delete e.gestureData.morph,delete e.gestureData.morphTargetX,delete e.gestureData.morphTargetY}},easeInOutCubic:e=>e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2,easeOutQuad:e=>e*(2-e),easeInQuad:e=>e*e,"3d":{evaluate(e,t){const i=t?.strength||1,n=Math.sin(e*Math.PI);let a;if(e<=.5){const t=2*e;a=1+t*(2-t)*.25*i}else{const t=2*(e-.5);a=1.25*i+t*t*(1-1.25*i),a=Math.max(1,a)}return{position:[0,0,0],rotation:[0,n*Math.PI*.3*i,.1*Math.sin(e*Math.PI*2)*i],scale:a,glowIntensity:1+.4*n*i,glowBoost:1.5*n*i}}}},He={name:"stretch",emoji:"↔️",type:"override",description:"Scale particles along X and Y axes",config:{duration:2e3,scaleX:1.3,scaleY:.9,alternate:!1,elastic:!0,overshoot:.1,frequency:1,easing:"sine",strength:1,particleMotion:{type:"stretch",scaleX:1.8,scaleY:.6,strength:1},centerBased:!0,preserveArea:!1},rhythm:{enabled:!0,syncMode:"beat",scaleSync:{onBeat:{x:1.5,y:.7},offBeat:{x:.8,y:1.3},subdivision:"eighth",curve:"elastic"},alternateSync:{pattern:"XYXY",beatsPerChange:1,overlap:.1},overshootSync:{normal:.1,accent:.3,downbeat:.2,curve:"spring"},preservationSync:{verse:!0,chorus:!1,bridge:!0},dynamics:{forte:{scaleX:2,scaleY:.5,overshoot:.4},piano:{scaleX:1.1,scaleY:.95,overshoot:.05}}},initialize(e,t,i,n){e.gestureData||(e.gestureData={});const a=e.x-i,s=e.y-n;e.gestureData.stretch={offsetX:a,offsetY:s,startX:e.x,startY:e.y,originalVx:e.vx,originalVy:e.vy,initialized:!0}},apply(e,t,i,n,a,s){e.gestureData?.stretch?.initialized||this.initialize(e,i,a,s);const o=e.gestureData.stretch,r={...this.config,...i},l=i.strength||1;let h,c,{scaleX:u}=r,{scaleY:d}=r;if(r.preserveArea&&1!==u&&1!==d){const e=u*d,t=Math.sqrt(1/e);u*=t,d*=t}if(r.alternate)if(t<.5){const e=2*t;u=1+(u-1)*this.getElasticProgress(e,r),d=1+(1/u-1)*(r.preserveArea?1:0)}else{const e=2*(t-.5);u+=(1-u)*this.getElasticProgress(e,r),d=1+(d-1)*this.getElasticProgress(e,r)}else{const e=this.getElasticProgress(t,r);u=1+(u-1)*e*l,d=1+(d-1)*e*l}if(r.centerBased?(h=a+o.offsetX*u,c=s+o.offsetY*d):(h=o.startX*u,c=o.startY*d),e.x=h,e.y=c,e.vx=o.offsetX*(u-1)*l*.1,e.vy=o.offsetY*(d-1)*l*.1,t>.9){const i=10*(1-t);e.vx=e.vx*i+o.originalVx*(1-i),e.vy=e.vy*i+o.originalVy*(1-i)}},getElasticProgress(e,t){if(!t.elastic)return this.easeInOutCubic(e);if(0===e)return 0;if(1===e)return 1;const i=t.overshoot||.1;if(e<.5){const t=2*e;return.5*this.easeInElastic(t,i)}{const t=2*(e-.5);return.5+.5*this.easeOutElastic(t,i)}},cleanup(e){if(e.gestureData?.stretch){const t=e.gestureData.stretch;e.vx=t.originalVx,e.vy=t.originalVy,delete e.gestureData.stretch}},easeInOutCubic:e=>e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2,easeInElastic:(e,t)=>0===e?0:1===e?1:-Math.pow(2,10*(e-1))*Math.sin((e-1-.075)*(2*Math.PI)/.3)*(1+t),easeOutElastic:(e,t)=>0===e?0:1===e?1:Math.pow(2,-10*e)*Math.sin((e-.075)*(2*Math.PI)/.3)*(1+t)+1,"3d":{evaluate(e,t){const{particle:i}=t;if(!i||!i.gestureData?.stretch)return{position:[0,0,0],rotation:[0,0,0],scale:1};const n=t.config||{},a=t.strength||1;let s,o=n.scaleX||1.3,r=n.scaleY||.9;if(n.preserveArea&&1!==o&&1!==r){const e=o*r,t=Math.sqrt(1/e);o*=t,r*=t}if(n.elastic){const t=n.overshoot||.1;if(e<.5){const i=2*e,n=.3,a=n/4;s=-Math.pow(2,10*(i-1))*Math.sin((i-1-a)*(2*Math.PI)/n)*(1+t)*.5}else{const i=2*(e-.5),n=.3,a=n/4;s=.5+.5*(Math.pow(2,-10*i)*Math.sin((i-a)*(2*Math.PI)/n)*(1+t)+1)}}else s=e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2;let l,h=1;if(e>.8){const t=(e-.8)/(1-.8);h=1-t*t*t}l=n.alternate?e<.5?2*e*.8:.8-2*(e-.5)*1.4:1*s*a;const c=1+l*h;return{position:[0,0,0],rotation:[0,0,.1*Math.sin(e*Math.PI*4)*s*h],scale:c}}}},We={name:"tilt",emoji:"🤔",type:"override",description:"Gather particles then tilt as unified group",config:{duration:500,gatherPhase:.2,tiltAngle:45,swayAmount:80,liftAmount:60,frequency:3,homeRadius:20,easing:"sine",strength:2.5,particleMotion:{type:"tilt",strength:2.5,frequency:3,swayAmount:80,liftAmount:60},smoothness:.25},rhythm:{enabled:!0,syncMode:"swing",angleSync:{onBeat:45,offBeat:-30,swing:15,subdivision:"triplet",curve:"ease-in-out"},gatherSync:{beatsBefore:.5,releaseAfter:.25,intensity:"dynamic"},swaySync:{verse:60,chorus:100,bridge:80,syncopated:!0},liftSync:{upOnTilt:!0,heightOnAccent:80,normalHeight:40,curve:"bounce"},dynamics:{forte:{tiltAngle:60,swayAmount:120,frequency:4},piano:{tiltAngle:20,swayAmount:40,frequency:2}}},initialize(e,t,i,n){e.gestureData||(e.gestureData={});const a=e.x-i,s=e.y-n,o=Math.atan2(s,a),r=Math.sqrt(a*a+s*s),l=Math.random(),h=({...this.config,...t}.homeRadius+20*Math.random())*e.scaleFactor;e.gestureData.tilt={startX:e.x,startY:e.y,originalVx:e.vx,originalVy:e.vy,angle:o,distance:r,homeRadius:h,homeX:i+Math.cos(o)*h,homeY:n+Math.sin(o)*h,role:l,initialized:!0}},apply(e,t,i,n,a,s){e.gestureData?.tilt?.initialized||this.initialize(e,i,a,s);const o=e.gestureData.tilt,r={...this.config,...i},l=i.strength||1;let h,c;if(t<r.gatherPhase){const i=t/r.gatherPhase,n=this.easeInOutCubic(i);h=o.startX+(o.homeX-o.startX)*n,c=o.startY+(o.homeY-o.startY)*n;const a=.6;e.x+=(h-e.x)*a,e.y+=(c-e.y)*a}else{const i=(t-r.gatherPhase)/(1-r.gatherPhase)*Math.PI*r.frequency,n=Math.sin(i),u=r.tiltAngle*Math.PI/180*l,d=o.angle+n*u,m=Math.abs(n)*r.liftAmount*e.scaleFactor,p=o.homeRadius+m;h=a+Math.cos(d)*p,c=s+Math.sin(d)*p-.3*m;const g=r.smoothness+.1*o.role;e.x+=(h-e.x)*g,e.y+=(c-e.y)*g;const f=-Math.sin(d),y=Math.cos(d);e.vx=f*n*2,e.vy=y*n*2}if(t<r.gatherPhase&&(e.vx=.25*(h-e.x),e.vy=.25*(c-e.y)),t>.9){const i=10*(1-t),n=o.startX+(e.x-o.startX)*i,a=o.startY+(e.y-o.startY)*i;e.x=n,e.y=a,e.vx=e.vx*i+o.originalVx*(1-i),e.vy=e.vy*i+o.originalVy*(1-i)}},cleanup(e){if(e.gestureData?.tilt){const t=e.gestureData.tilt;e.vx=t.originalVx,e.vy=t.originalVy,delete e.gestureData.tilt}},easeInOutCubic:e=>e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2,"3d":{evaluate(e,t){const i=t.config||{},n=t.strength||1,a=i.gatherPhase||.2,s=i.frequency||3,o=i.tiltAngle||45;let r=0;if(e>=a){const t=(e-a)/(1-a)*Math.PI*s;r=Math.sin(t)*(o*Math.PI/180*n*.4)}return{position:[0,0,0],rotation:[0,0,r],scale:1}}}},Xe={name:"orbital",emoji:"🪐",type:"override",description:"Orbital motion around center",config:{speed:.02,maintainRadius:!0,elliptical:!1,use3D:!0,zPhaseOffset:0,verticalOscillation:0,duration:3e3,particleMotion:{type:"orbital",strength:1}},rhythm:{enabled:!0,syncMode:"harmonic",speedSync:{tonic:.02,fifth:.03,octave:.04,third:.025,curve:"smooth"},radiusSync:{bass:150,mid:100,treble:50,scaling:"logarithmic"},depthSync:{major:{z:1,phase:0},minor:{z:-1,phase:Math.PI},diminished:{z:.5,phase:Math.PI/2},augmented:{z:.8,phase:-Math.PI/2}},phaseSync:{mode:"harmonic",intervals:[1,1.5,2],drift:.05},dynamics:{forte:{speed:.04,maintainRadius:!1},piano:{speed:.01,maintainRadius:!0}}},initialize(e,t,i,n){e.gestureData||(e.gestureData={});const a=e.x-i,s=e.y-n,o=Math.sqrt(a*a+s*s),r=Math.random()<.5?1:-1,l=Math.max(o,100+180*Math.random()),h=o<5?Math.random()*Math.PI*2:Math.atan2(s,a);e.gestureData.orbital={radius:l,targetRadius:l,angle:h,initialAngle:h,originalVx:e.vx,originalVy:e.vy,originalZ:e.z||0,zPhase:Math.random()*Math.PI*2,direction:r}},apply(e,t,i,n,a,s){e.gestureData?.orbital||this.initialize(e,i,a,s);const o=e.gestureData.orbital,r=(i.speed||this.config.speed)*(i.strength||1);o.angle+=r*n*o.direction;let{radius:l}=o;if(i.maintainRadius||(l=o.radius*(1+.1*Math.sin(t*Math.PI*2))),e.x=a+Math.cos(o.angle)*l,e.y=s+Math.sin(o.angle)*l,!1!==i.use3D){const t=o.angle+o.zPhase+(i.zPhaseOffset||0);if(e.z=.8*Math.sin(t),i.verticalOscillation){const n=Math.cos(t)*i.verticalOscillation*l*.1;e.y+=n}}if(e.vx=-Math.sin(o.angle)*l*r,e.vy=Math.cos(o.angle)*l*r,t>.9){const i=10*(1-t);e.vx=e.vx*i+o.originalVx*(1-i),e.vy=e.vy*i+o.originalVy*(1-i)}},cleanup(e){if(e.gestureData?.orbital){const t=e.gestureData.orbital;e.vx=t.originalVx,e.vy=t.originalVy,e.z=t.originalZ,delete e.gestureData.orbital}},"3d":{evaluate(e,t){const{particle:i}=t;if(!i||!i.gestureData?.orbital)return{position:[0,0,0],rotation:[0,0,0],scale:1};const n=i.gestureData.orbital;t.config;let a=1;e<.15?(a=e/.15,a=Math.sin(a*Math.PI*.5)):e>.85&&(a=(1-e)/.15,a=Math.sin(a*Math.PI*.5));const s=n.initialAngle+e*Math.PI*2*n.direction,o=.3*Math.cos(s)*a,r=.3*Math.sin(s)*a,l=(s+Math.PI/2-(n.initialAngle+Math.PI/2))*a,h=i.z||0;return{position:[o,0,r+.1*h*a],rotation:[0,l,0],scale:1+.15*h*a}}}},Ye={name:"hula",emoji:"🌀",type:"override",description:"Hula-hoop motion with vertical waves",config:{speed:.015,maintainRadius:!1,elliptical:!0,use3D:!0,zPhaseOffset:Math.PI/4,verticalOscillation:.3,wobbleAmount:.15,duration:2500,particleMotion:{type:"hula",strength:1,verticalOscillation:.3}},rhythm:{enabled:!0,syncMode:"bar",speedSync:{mode:"tempo",baseSpeed:.015,scaling:"proportional"},wobbleSync:{onBeat:.25,offBeat:.1,curve:"sine"},verticalSync:{subdivision:"quarter",amplitude:.4,phase:"sequential"},dynamics:{forte:{wobbleAmount:.3,speed:1.2},piano:{wobbleAmount:.05,speed:.8}}},initialize(e,t,i,n){e.gestureData||(e.gestureData={});const a=e.x-i,s=e.y-n,o=Math.sqrt(a*a+s*s),r=Math.random()<.5?1:-1,l=Math.max(o,100+180*Math.random()),h=o<5?Math.random()*Math.PI*2:Math.atan2(s,a);e.gestureData.hula={radius:l,angle:h,initialAngle:h,originalVx:e.vx,originalVy:e.vy,originalZ:e.z||0,zPhase:Math.random()*Math.PI*2,wobblePhase:Math.random()*Math.PI*2,direction:r}},apply(e,t,i,n,a,s){e.gestureData?.hula||this.initialize(e,i,a,s);const o=e.gestureData.hula,r=(i.speed||this.config.speed)*(i.strength||1);let l=1;t<.1?(l=t/.1,l=Math.sin(l*Math.PI*.5)):t>.9&&(l=(1-t)/.1,l=Math.sin(l*Math.PI*.5)),o.angle+=r*n*o.direction*l;const h=Math.sin(2*o.angle+o.wobblePhase)*(i.wobbleAmount||this.config.wobbleAmount)*l,c=o.radius*(1+h)*l,u=o.radius*(.7+h)*l,d=a+Math.cos(o.angle)*c,m=s+Math.sin(o.angle)*u;if(t<.1){const t=e.x-a,i=e.y-s;Math.sqrt(t*t+i*i)<50?(e.x=a+Math.cos(o.angle)*c,e.y=s+Math.sin(o.angle)*u):(e.x=e.x+(d-e.x)*l*.5,e.y=e.y+(m-e.y)*l*.5)}else e.x=d,e.y=m;const p=o.angle+o.zPhase+(i.zPhaseOffset||this.config.zPhaseOffset);e.z=.9*Math.sin(p)*l;const g=i.verticalOscillation||this.config.verticalOscillation,f=Math.cos(2*p)*g*o.radius*.2*l;e.y+=f;const y=e.z*o.radius*.1;e.y-=y;const v=-Math.sin(o.angle)*c*r,b=Math.cos(o.angle)*u*r;t<.1?(e.vx=o.originalVx+(v-o.originalVx)*l,e.vy=o.originalVy+(b-o.originalVy)*l):t>.9?(e.vx=v*l+o.originalVx*(1-l),e.vy=b*l+o.originalVy*(1-l),e.z=e.z*l+o.originalZ*(1-l)):(e.vx=v,e.vy=b)},cleanup(e){if(e.gestureData?.hula){const t=e.gestureData.hula;e.vx=t.originalVx,e.vy=t.originalVy,e.z=t.originalZ,delete e.gestureData.hula}},"3d":{evaluate(e,t){const{particle:i}=t;if(!i||!i.gestureData?.hula)return{position:[0,0,0],rotation:[0,0,0],scale:1};const n=i.gestureData.hula,a=t.config||{};let s=1;e<.15?(s=e/.15,s=Math.sin(s*Math.PI*.5)):e>.85&&(s=(1-e)/.15,s=Math.sin(s*Math.PI*.5));const o=n.initialAngle+e*Math.PI*2*n.direction,r=.25*Math.cos(o)*s,l=.25*Math.sin(o)*s,h=a.verticalOscillation||.3;return{position:[r,Math.sin(2*o+n.wobblePhase)*h*s,l],rotation:[0,(o-n.initialAngle)*s,0],scale:1+.15*Math.abs(Math.sin(o))*s}}}},$e={name:"twist",emoji:"🌀",type:"override",description:"Twisting dance motion with alternating rotation",config:{duration:1200,rotationAngle:45,contractionFactor:.8,twistFrequency:2,easing:"smooth",strength:.8,particleMotion:{type:"twist",rotationAngle:45,contractionFactor:.8,twistFrequency:2}},rhythm:{enabled:!0,syncMode:"beat",timingSync:"nextBeat",interruptible:!0,priority:4,blendable:!1,crossfadePoint:"anyBeat",amplitudeSync:{onBeat:1.5,offBeat:.7,curve:"elastic"},patternOverrides:{funk:{rotationAngle:60,contractionFactor:.7},disco:{twistFrequency:3,rotationAngle:50},latin:{rotationAngle:35,contractionFactor:.85,twistFrequency:2.5}}},initialize(e,t){e.gestureData||(e.gestureData={}),e.gestureData.twist={startX:e.x,startY:e.y,startAngle:Math.atan2(e.y-t.centerY,e.x-t.centerX),startDistance:Math.sqrt(Math.pow(e.x-t.centerX,2)+Math.pow(e.y-t.centerY,2)),initialized:!0}},apply(e,t,i,n,a,s){e.gestureData?.twist?.initialized||this.initialize(e,{...i,centerX:a,centerY:s});const o={...this.config,...i},r=e.gestureData.twist,l=o.strength||this.config.strength||1,h=t*o.twistFrequency*Math.PI*2,c=Math.sin(h)*l;let{rotationAngle:u}=o,{contractionFactor:d}=o;i.rhythmModulation&&(u*=i.rhythmModulation.amplitudeMultiplier||1,d=1-(1-d)*(i.rhythmModulation.amplitudeMultiplier||1));const m=u*Math.PI/180*c,p=1-(1-d)*Math.abs(c),g=r.startAngle+m,f=r.startDistance*p,y=a+Math.cos(g)*f,v=s+Math.sin(g)*f,b=.15*l;e.x+=(y-e.x)*b,e.y+=(v-e.y)*b,e.vx=.05*(y-e.x),e.vy=.05*(v-e.y);const w=5*Math.sin(t*Math.PI*4)*l;if(e.y+=.1*w,t>.9){const i=1-10*(t-.9);e.vx*=i,e.vy*=i}},cleanup(e){e.gestureData?.twist&&delete e.gestureData.twist},"3d":{evaluate(e,t){const{particle:i}=t;if(!i||!i.gestureData?.twist)return{position:[0,0,0],rotation:[0,0,0],scale:1};const n=i.gestureData.twist,a=t.config||{},s=a.strength||1,o=e>.85?(1-e)/.15:1,r=e*(a.twistFrequency||2)*Math.PI*2,l=Math.sin(r)*s*o,h=l*((a.rotationAngle||45)*Math.PI/180),c=n.startAngle+h,u=(a.contractionFactor||.8)*n.startDistance;return{position:[Math.cos(c)*u*.1*o*.01,0,Math.sin(c)*u*.1*o*.01],rotation:[.1*Math.cos(r)*s*o,h,.15*Math.sin(.5*r)*s*o],scale:1-(1-(a.contractionFactor||.8))*Math.abs(l)}}}},Qe={name:"wave",emoji:"🌊",type:"override",description:"Infinity pattern flow with phasing",config:{musicalDuration:{musical:!0,bars:1,minBeats:4,maxBeats:16},phases:[{name:"gather",beats:.5},{name:"rise",beats:.5},{name:"waveLeft",beats:1},{name:"waveRight",beats:1},{name:"settle",beats:1}],amplitude:40,frequency:1,phaseShift:.3,liftHeight:20,fadeInOut:!0,smoothness:.1,easing:"sine",strength:1,particleMotion:{type:"wave",strength:1,amplitude:50}},rhythm:{enabled:!0,syncMode:"wave",amplitudeSync:{onWave:65,onStatic:25,curve:"flowing"},frequencySync:{mode:"phrase",slow:.7,fast:1.8,curve:"melodic"},durationSync:{mode:"bars",adaptToPhrase:!0,sustain:!0},phaseSync:{enabled:!0,multiplier:.5,type:"ensemble"},melodicResponse:{enabled:!0,multiplier:1.4,type:"amplitude"},patternOverrides:{ambient:{amplitudeSync:{onWave:80,onStatic:40,curve:"hypnotic"},frequencySync:{slow:.5,fast:1.2},durationSync:{minBeats:16,maxBeats:64}},ocean:{amplitudeSync:{onWave:90,onStatic:20,curve:"natural"},phaseSync:{multiplier:.8},melodicResponse:{multiplier:1.8}},electronic:{amplitudeSync:{onWave:70,onStatic:30,curve:"digital"},frequencySync:{slow:.8,fast:2.5,curve:"precise"}},orchestral:{amplitudeSync:{onWave:75,onStatic:35},phaseSync:{multiplier:.7},melodicResponse:{multiplier:2}}},dynamics:{forte:{amplitudeSync:{onWave:{multiplier:1.8},onStatic:{multiplier:1.4}},frequencySync:{multiplier:1.3},melodicResponse:{multiplier:2.2}},piano:{amplitudeSync:{onWave:{multiplier:.6},onStatic:{multiplier:.4}},frequencySync:{multiplier:.7},melodicResponse:{multiplier:1.1}}}},initialize(e,t,i,n){e.gestureData||(e.gestureData={});const a=e.x-i,s=e.y-n,o=Math.atan2(s,a),r=Math.sqrt(a*a+s*s),l=Math.random()<.5?1:-1;e.gestureData.wave={startX:e.x,startY:e.y,originalVx:e.vx,originalVy:e.vy,baseOpacity:e.opacity||e.life||1,angle:o,radius:r,offset:Math.random()*Math.PI*2,role:Math.random(),direction:l,initialized:!0}},apply(e,t,i,n,a,s){e.gestureData?.wave?.initialized||this.initialize(e,i,a,s);const o=e.gestureData.wave,r={...this.config,...i},l=i.strength||1,h=this.easeInOutSine(t),c=o.role*r.phaseShift,u=Math.max(0,h-c),d=u*Math.PI*2*r.frequency*o.direction+o.offset,m=.5+o.radius/100*.5,p=r.amplitude*m*l*e.scaleFactor,g=a+Math.sin(d)*p,f=s+Math.sin(2*d)*p*.3+-Math.abs(Math.sin(h*Math.PI))*r.liftHeight*e.scaleFactor,y=r.smoothness+.12*o.role;if(e.x+=(g-e.x)*y,e.y+=(f-e.y)*y,e.vx=.3*(g-e.x),e.vy=.3*(f-e.y),r.fadeInOut){let t;t=u<.1?u/.1:u>.9?(1-u)/.1:.5+.5*Math.sin(u*Math.PI),e.opacity=o.baseOpacity*(.3+.7*t),void 0!==e.life&&(e.life=e.opacity)}if(t>=.95){const i=20*(1-t);e.vx=e.vx*i+o.originalVx*(1-i),e.vy=e.vy*i+o.originalVy*(1-i),r.fadeInOut&&(e.opacity=o.baseOpacity*i,void 0!==e.life&&(e.life=e.opacity))}},cleanup(e){if(e.gestureData?.wave){const t=e.gestureData.wave;e.vx=t.originalVx,e.vy=t.originalVy,e.opacity=t.baseOpacity,void 0!==e.life&&(e.life=t.baseOpacity),delete e.gestureData.wave}},easeInOutSine:e=>-(Math.cos(Math.PI*e)-1)/2,"3d":{evaluate(e,t){const i=t?.strength||1,n=t?.frequency||1,a=-(Math.cos(Math.PI*e)-1)/2,s=a*Math.PI*2*n,o=.12*Math.sin(s)*i,r=.06*Math.sin(2*s)*i,l=.03*Math.sin(s)*i,h=.08*Math.sin(2*s)*i,c=.05*Math.sin(s)*i,u=1+.08*Math.abs(Math.sin(a*Math.PI))*i,d=Math.abs(Math.sin(s));return{position:[o,r,l],rotation:[h,0,c],scale:u,glowIntensity:1+.3*d*i,glowBoost:.6*d*i}}}},Ze={name:"drift",emoji:"☁️",type:"override",description:"Controlled floating with fade effects",config:{duration:800,distance:50,angle:45,returnToOrigin:!0,fadeOut:!1,holdTime:.2,turbulence:.1,angleSpread:45,smoothness:.08,easing:"ease",strength:1,particleMotion:{type:"drift",strength:1,distance:60}},rhythm:{enabled:!0,syncMode:"ambient",distanceSync:{quiet:30,loud:80,crescendo:"expand",diminuendo:"contract"},angleSync:{major:45,minor:225,modulation:"smooth",cadence:"return"},holdSync:{shortPhrase:.1,longPhrase:.4,fermata:"sustain"},accentResponse:{enabled:!0,multiplier:1.3,type:"distance"},patternOverrides:{ambient:{distanceSync:{quiet:40,loud:100},holdSync:{shortPhrase:.3,longPhrase:.6}},classical:{angleSync:{major:30,minor:210},distanceSync:{quiet:25,loud:60}},jazz:{angleSync:{major:60,minor:240,swing:!0,syncopated:!0}},new_age:{distanceSync:{quiet:35,loud:70},holdSync:{shortPhrase:.4,longPhrase:.8},angleSync:{modulation:"gradual"}}},dynamics:{forte:{distanceSync:{quiet:{multiplier:1.5},loud:{multiplier:1.8}},holdSync:{multiplier:1.2},accentResponse:{multiplier:1.6}},piano:{distanceSync:{quiet:{multiplier:.6},loud:{multiplier:.8}},holdSync:{multiplier:.8},accentResponse:{multiplier:1.1}}}},initialize(e,t,i,n){e.gestureData||(e.gestureData={});const a=e.x-i,s=e.y-n;let o=Math.atan2(s,a);const r={...this.config,...t}.angleSpread*Math.PI/180,l=(Math.random()-.5)*r;o+=l;const h=30+30*Math.random();e.gestureData.drift={startX:e.x,startY:e.y,originalVx:e.vx,originalVy:e.vy,baseOpacity:e.opacity||e.life||1,driftAngle:o,angleOffset:l,homeRadius:h*e.scaleFactor,homeX:i+Math.cos(o)*h,homeY:n+Math.sin(o)*h,role:Math.random(),turbulencePhase:Math.random()*Math.PI*2,initialized:!0}},apply(e,t,i,n,a,s){e.gestureData?.drift?.initialized||this.initialize(e,i,a,s);const o=e.gestureData.drift,r={...this.config,...i},l=i.strength||1,h=this.easeInOutCubic(t),c=Math.max(0,h-.1*o.role);let u,d,m;if(r.returnToOrigin)if(c<.4){const e=c/.4,t=this.easeOutQuad(e);u=o.startX+(o.homeX-o.startX)*t,d=o.startY+(o.homeY-o.startY)*t}else if(c<.6+r.holdTime){const t=(c-.4)/(.2+r.holdTime);m=o.homeRadius+Math.sin(t*Math.PI*.5)*r.distance*l*e.scaleFactor}else{const t=(c-.6-r.holdTime)/(.4-r.holdTime);m=o.homeRadius+Math.cos(t*Math.PI*.5)*r.distance*l*e.scaleFactor}else{const t=c;m=o.homeRadius+t*r.distance*l*e.scaleFactor}if(void 0!==m){o.turbulencePhase+=r.turbulence*n;const e=Math.sin(o.turbulencePhase)*r.turbulence*10,t=Math.cos(1.3*o.turbulencePhase)*r.turbulence*10,i=o.driftAngle+o.angleOffset;u=a+Math.cos(i)*m+e,d=s+Math.sin(i)*m+t}const p=r.smoothness+.08*o.role;if(e.x+=(u-e.x)*p,e.y+=(d-e.y)*p,e.vx=.25*(u-e.x),e.vy=.25*(d-e.y),r.fadeOut){let i;i=t<.25?.3+t/.25*.7:t<.75?.7+.3*Math.sin((t-.25)*Math.PI/.5):4*(1-t),e.opacity=o.baseOpacity*i,void 0!==e.life&&(e.life=e.opacity)}t>=.99&&(e.vx=.1*o.originalVx,e.vy=.1*o.originalVy,r.fadeOut&&(e.opacity=o.baseOpacity,void 0!==e.life&&(e.life=o.baseOpacity)))},cleanup(e){if(e.gestureData?.drift){const t=e.gestureData.drift;e.vx=t.originalVx,e.vy=t.originalVy,e.opacity=t.baseOpacity,void 0!==e.life&&(e.life=t.baseOpacity),delete e.gestureData.drift}},easeInOutCubic:e=>e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2,easeOutQuad:e=>e*(2-e),"3d":{evaluate(e,t){const i={...this.config,...t},n=t.strength||1,a=(i.angle||45)*Math.PI/180,s=i.returnToOrigin?e<.5?2*e:2*(1-e):e;return{position:[Math.cos(a)*s*.3*n,Math.sin(a)*s*.3*n,.15*Math.sin(e*Math.PI)*n],rotation:[0,10*s*n,0],scale:1+.03*Math.sin(e*Math.PI),glowIntensity:1-.1*s}}}},Je={name:"flicker",emoji:"⚡",type:"blending",description:"Rapid opacity changes with motion jitter",config:{duration:800,flickerRate:15,frequency:6,minOpacity:.3,maxOpacity:1,jitterAmount:2,colorShift:!1,strobe:!1,pulseMode:!1,groupFlicker:.3,easing:"linear",strength:.7,particleMotion:{type:"flicker",strength:.7,frequency:6}},rhythm:{enabled:!0,syncMode:"subdivision",rateSync:{subdivision:"sixteenth",onBeat:30,offBeat:10,triplet:20,curve:"step"},opacitySync:{pattern:"HLMH",subdivision:"eighth",onAccent:.1,regular:.5},jitterSync:{onBeat:5,offBeat:1,accent:10,curve:"random"},strobeSync:{verse:!1,chorus:!0,drop:"intense",pattern:"XOXO"},dynamics:{forte:{flickerRate:25,jitterAmount:5,minOpacity:.1},piano:{flickerRate:8,jitterAmount:1,minOpacity:.5}}},initialize(e,t){e.gestureData||(e.gestureData={});const i={...this.config,...t},n=Math.random()<i.groupFlicker;e.gestureData.flicker={baseOpacity:e.opacity||e.life||1,baseColor:e.color,baseX:e.x,baseY:e.y,flickerTimer:0,lastFlicker:0,flickerState:!0,isGrouped:n,groupId:n?Math.floor(3*Math.random()):-1,phase:Math.random()*Math.PI*2,colorHue:0,initialized:!0}},apply(e,t,i,n,a,s){e.gestureData?.flicker?.initialized||this.initialize(e,i);const o=e.gestureData.flicker,r={...this.config,...i},l=i.strength||1;let h;if(o.flickerTimer+=n*r.flickerRate,r.strobe)h=(o.flickerTimer+o.phase)%1<.5?1:r.minOpacity;else if(r.pulseMode){const e=o.flickerTimer+o.phase;h=r.minOpacity+(r.maxOpacity-r.minOpacity)*(.5*Math.sin(e)+.5)}else{if(o.flickerTimer-o.lastFlicker>1)if(o.lastFlicker=o.flickerTimer,o.isGrouped){const e=Math.floor(o.flickerTimer)%3;o.flickerState=e===o.groupId}else o.flickerState=Math.random()>.3;const t=o.flickerState?r.maxOpacity:r.minOpacity+.3*Math.random(),i=e.opacity/o.baseOpacity;h=i+.3*(t-i)}const c=o.baseOpacity*(1+(h-1)*l);if(e.opacity=Math.max(0,Math.min(1,c)),void 0!==e.life&&(e.life=e.opacity),r.jitterAmount>0&&h>r.minOpacity){const t=r.jitterAmount*l*e.scaleFactor,i=(Math.random()-.5)*t*h,a=(Math.random()-.5)*t*h;e.vx+=.1*i*n,e.vy+=.1*a*n}if(r.colorShift&&e.color){o.colorHue+=.01*n;const t=30*Math.sin(o.colorHue);e.color=this.shiftHue(o.baseColor,t*l)}let u=1;t<.1?u=t/.1:t>.9&&(u=(1-t)/.1),e.opacity*=u,void 0!==e.life&&(e.life=e.opacity),t>.8&&(e.vx*=.95,e.vy*=.95)},shiftHue(e,t){if(!e||!e.startsWith("#"))return e;const i=e.slice(1),n=parseInt(i.substr(0,2),16)/255,a=parseInt(i.substr(2,2),16)/255,s=parseInt(i.substr(4,2),16)/255,o=t*Math.PI/180,r=Math.cos(o),l=Math.sin(o),h=n*l+a*r,c=s,u=e=>Math.max(0,Math.min(255,Math.round(255*e))).toString(16).padStart(2,"0");return`#${u(n*r-a*l)}${u(h)}${u(c)}`},cleanup(e){if(e.gestureData?.flicker){const t=e.gestureData.flicker;e.opacity=t.baseOpacity,e.color=t.baseColor,void 0!==e.life&&(e.life=t.baseOpacity),delete e.gestureData.flicker}},"3d":{evaluate(e,t){const i=t.config||{},n=t.strength||.7,a=i.flickerRate||15;i.minOpacity;const s=e*a,o=Math.sin(s*Math.PI*2),r=Math.floor(10*s),l=.3*o+.5*(Math.sin(123.456*r)+1)*.7,h=.6+.8*l,c=i.jitterAmount||2,u=.003*n*h,d=(Math.random()-.5)*c*u,m=(Math.random()-.5)*c*u,p=.03*(Math.random()-.5)*n*h;return{position:[d,m,0],rotation:[.5*p,0,p],scale:1+.08*(h-1),glowIntensity:h,glowBoost:1.2*l}}}},Ke={name:"burst",emoji:"💥",type:"blending",description:"Explosive outward burst from center",config:{decay:.5,strength:2},rhythm:{enabled:!0,syncMode:"beat",strengthSync:{onBeat:3.5,offBeat:1,curve:"explosion"},decaySync:{mode:"tempo",fast:.8,slow:.3,curve:"exponential"},durationSync:{mode:"beats",beats:.5,sustain:!1},accentResponse:{enabled:!0,multiplier:2.5,type:"strength"},patternOverrides:{rock:{strengthSync:{onBeat:4,offBeat:1.5},decaySync:{fast:.6,slow:.4}},electronic:{strengthSync:{onBeat:3.8,offBeat:.8,curve:"sharp"},decaySync:{fast:.9,slow:.7}},jazz:{strengthSync:{onBeat:2.8,offBeat:1.8,swing:!0},decaySync:{fast:.5,slow:.2}},orchestral:{strengthSync:{onBeat:3.2,offBeat:.5},accentResponse:{multiplier:3}}},dynamics:{forte:{strengthSync:{onBeat:{multiplier:2},offBeat:{multiplier:1.5}},decaySync:{multiplier:.7},accentResponse:{multiplier:3.5}},piano:{strengthSync:{onBeat:{multiplier:.6},offBeat:{multiplier:.3}},decaySync:{multiplier:1.3},accentResponse:{multiplier:1.8}}}},apply(e,t,i,n,a,s){const o=i.decay||this.config.decay,r=(i.strength||this.config.strength)*(1-t*o),l=e.x-a,h=e.y-s,c=Math.sqrt(l*l+h*h);c>1&&(e.vx+=l/c*r*2*n,e.vy+=h/c*r*2*n)},"3d":{evaluate(e,t){const i={...this.config,...t}.decay||.5,n=e<.3?.3-e:0;return{position:[0,0,0],rotation:[0,0,0],scale:1+(e<.2?5*e:1.5*(1-e))*((t.strength||2)*(1-e*i)),glowIntensity:1+Math.min(1*n,.3),glowBoost:2.5*n}}}},et={name:"directional",emoji:"➡️",type:"blending",description:"Move particles in a specific direction",config:{angle:0,returnToOrigin:!1,strength:1},rhythm:{enabled:!0,syncMode:"flow",angleSync:{verse:0,chorus:90,bridge:180,outro:270,transition:"smooth"},strengthSync:{onBeat:1.8,offBeat:.6,curve:"wave"},returnSync:{enabled:!0,onSectionChange:!0,duration:"transition",strength:1.2},accentResponse:{enabled:!0,multiplier:2,type:"strength"},patternOverrides:{march:{angleSync:{verse:0,chorus:0},strengthSync:{onBeat:2.5,offBeat:1}},waltz:{angleSync:{verse:45,chorus:135,bridge:225,outro:315,transition:"circular"}},swing:{strengthSync:{onBeat:1.6,offBeat:1.4,swing:!0}},electronic:{angleSync:{transition:"instant"},strengthSync:{onBeat:2.2,offBeat:.4,curve:"sharp"}}},dynamics:{forte:{strengthSync:{onBeat:{multiplier:1.6},offBeat:{multiplier:1.2}},angleSync:{transition:"sharp"},accentResponse:{multiplier:2.5}},piano:{strengthSync:{onBeat:{multiplier:.7},offBeat:{multiplier:.8}},angleSync:{transition:"gradual"},accentResponse:{multiplier:1.4}}}},initialize(e){e.gestureData||(e.gestureData={}),e.gestureData.directional={initialX:e.x,initialY:e.y}},apply(e,t,i,n,a,s){e.gestureData?.directional||this.initialize(e);const o=(i.angle||this.config.angle)*Math.PI/180,r=i.strength||this.config.strength;if(e.vx+=Math.cos(o)*r*.3*n,e.vy+=Math.sin(o)*r*.3*n,i.returnToOrigin&&t>.5){const i=2*(t-.5),a=e.gestureData.directional,s=a.initialX-e.x,o=a.initialY-e.y;e.vx+=s*i*.02*n,e.vy+=o*i*.02*n}},"3d":{evaluate(e,t){const i={...this.config,...t},n=(i.angle||0)*Math.PI/180,a=t.strength||1,s=i.returnToOrigin?e<.5?2*e:2*(1-e):e;return{position:[Math.cos(n)*s*.4*a,Math.sin(n)*s*.4*a,0],rotation:[0,0,0],scale:1,glowIntensity:1}}}},tt={name:"settle",emoji:"🍃",type:"blending",description:"Gradually settle particles to rest",config:{damping:.02,threshold:.01},rhythm:{enabled:!0,syncMode:"resolution",dampingSync:{onResolution:.035,onTension:.015,curve:"gradual"},thresholdSync:{mode:"dynamics",forte:.02,piano:.005,curve:"exponential"},durationSync:{mode:"phrase",minBeats:2,maxBeats:12,sustain:!0},cadenceResponse:{enabled:!0,multiplier:1.6,type:"damping"},patternOverrides:{ambient:{dampingSync:{onResolution:.025,onTension:.008,curve:"atmospheric"},durationSync:{minBeats:8,maxBeats:32}},jazz:{dampingSync:{onResolution:.04,onTension:.02},cadenceResponse:{multiplier:1.8}},classical:{dampingSync:{onResolution:.045,onTension:.012,curve:"expressive"},cadenceResponse:{multiplier:2}},minimalist:{dampingSync:{onResolution:.02,onTension:.005},durationSync:{minBeats:16,maxBeats:64}}},dynamics:{forte:{dampingSync:{onResolution:{multiplier:1.4},onTension:{multiplier:.8}},thresholdSync:{multiplier:2},cadenceResponse:{multiplier:2.2}},piano:{dampingSync:{onResolution:{multiplier:.7},onTension:{multiplier:1.2}},thresholdSync:{multiplier:.5},cadenceResponse:{multiplier:1.3}}}},apply(e,t,i,n,a,s){const o=i.damping||this.config.damping,r=i.threshold||this.config.threshold;e.vx*=Math.max(0,1-o*n*60),e.vy*=Math.max(0,1-o*n*60),Math.abs(e.vx)<r&&(e.vx=0),Math.abs(e.vy)<r&&(e.vy=0)},"3d":{evaluate(e,t){const i=1-Math.pow(1-e,2),n=.01*(1-i);return{position:[Math.sin(e*Math.PI*2)*n,Math.cos(e*Math.PI*3)*n*.5,0],rotation:[0,0,0],scale:1-.03*i,glowIntensity:1-.15*i}}}},it={name:"fade",emoji:"👻",type:"blending",description:"Fade particle opacity",config:{duration:2e3,fadeIn:!0,fadeOut:!0,minOpacity:0,maxOpacity:1},rhythm:{enabled:!0,syncMode:"dynamic",opacitySync:{onBeat:.9,offBeat:.3,subdivision:"eighth",curve:"exponential"},fadePhaseSync:{verse:{fadeIn:!0,fadeOut:!1},chorus:{fadeIn:!1,fadeOut:!1},bridge:{fadeIn:!0,fadeOut:!0},outro:{fadeIn:!1,fadeOut:!0}},pulseSync:{enabled:!0,frequency:"quarter",intensity:.2,onAccent:.4},dynamics:{forte:{minOpacity:.5,maxOpacity:1},piano:{minOpacity:0,maxOpacity:.4}}},initialize(e){e.gestureData||(e.gestureData={}),e.gestureData.fade={baseOpacity:e.opacity||e.life||1}},apply(e,t,i,n,a,s){e.gestureData?.fade||this.initialize(e);const o=e.gestureData.fade,r={...this.config,...i};let l;l=r.fadeIn&&!r.fadeOut?r.minOpacity+(r.maxOpacity-r.minOpacity)*t:r.fadeOut&&!r.fadeIn?r.maxOpacity-(r.maxOpacity-r.minOpacity)*t:t<.5?r.minOpacity+(r.maxOpacity-r.minOpacity)*(2*t):r.maxOpacity-(r.maxOpacity-r.minOpacity)*(2*(t-.5)),e.opacity=o.baseOpacity*l,void 0!==e.life&&(e.life=e.opacity)},cleanup(e){e.gestureData?.fade&&(e.opacity=e.gestureData.fade.baseOpacity,void 0!==e.life&&(e.life=e.opacity),delete e.gestureData.fade)},"3d":{evaluate(e,t){const i={...this.config,...t};let n;const a=i.minOpacity??0,s=i.maxOpacity??1;return n=i.fadeIn&&!i.fadeOut?a+(s-a)*e:i.fadeOut&&!i.fadeIn?s-(s-a)*e:e<.5?s-2*e*(s-a):a+2*(e-.5)*(s-a),{position:[0,0,0],rotation:[0,0,0],scale:1,glowIntensity:n}}}},nt={name:"hold",emoji:"⏸️",type:"override",description:"Hold particles in current position",config:{holdStrength:.95,allowDrift:!1},rhythm:{enabled:!0,syncMode:"rest",holdSync:{onRest:.98,onSound:.8,curve:"immediate"},durationSync:{mode:"rests",minBeats:.5,maxBeats:8,sustain:!0},pauseResponse:{enabled:!0,multiplier:1.5,type:"strength"},patternOverrides:{classical:{holdSync:{onRest:.99,onSound:.75,curve:"dramatic"},pauseResponse:{multiplier:2}},minimal:{holdSync:{onRest:.95,onSound:.85},durationSync:{minBeats:2,maxBeats:16}},jazz:{holdSync:{onRest:.9,onSound:.7},allowDrift:!0},electronic:{holdSync:{onRest:.99,onSound:.6,curve:"digital"},pauseResponse:{multiplier:1.2}}},dynamics:{forte:{holdSync:{onRest:{multiplier:1.02},onSound:{multiplier:.9}},pauseResponse:{multiplier:2.2}},piano:{holdSync:{onRest:{multiplier:.97},onSound:{multiplier:.85}},pauseResponse:{multiplier:1.3}}}},initialize(e){e.gestureData||(e.gestureData={}),e.gestureData.hold={holdX:e.x,holdY:e.y,originalVx:e.vx,originalVy:e.vy}},apply(e,t,i,n,a,s){e.gestureData?.hold||this.initialize(e);const o=e.gestureData.hold,r=i.holdStrength||this.config.holdStrength;if(i.allowDrift?(e.vx*=r,e.vy*=r):(e.x+=(o.holdX-e.x)*(1-r),e.y+=(o.holdY-e.y)*(1-r),e.vx=0,e.vy=0),t>.9){const i=10*(t-.9);e.vx=e.vx*(1-i)+o.originalVx*i,e.vy=e.vy*(1-i)+o.originalVy*i}},cleanup(e){if(e.gestureData?.hold){const t=e.gestureData.hold;e.vx=t.originalVx,e.vy=t.originalVy,delete e.gestureData.hold}},"3d":{evaluate:(e,t)=>({position:[0,0,0],rotation:[0,0,0],scale:1,glowIntensity:1})}},at={name:"breathe",emoji:"🫁",type:"blending",description:"Breathing rhythm with inhale and exhale",config:{musicalDuration:{musical:!0,bars:1,minBeats:2,maxBeats:16},phases:[{name:"inhale",beats:1.5},{name:"hold_in",beats:.5},{name:"exhale",beats:1.5},{name:"hold_out",beats:.5}],inhaleRadius:1.5,exhaleRadius:.3,breathRate:.3,spiralStrength:.002,scaleAmount:.25,glowAmount:.4,frequency:1,easing:"sine",strength:.8,particleMotion:{type:"breathe",strength:.8,inhaleRadius:1.5,exhaleRadius:.3}},rhythm:{enabled:!0,syncMode:"phrase",breathRateSync:{mode:"tempo",bpm:"auto",subdivision:"whole",curve:"sine"},radiusSync:{inhale:{onUpbeat:1.8,onDownbeat:1.4,curve:"ease-in"},exhale:{onUpbeat:.2,onDownbeat:.4,curve:"ease-out"}},durationSync:{mode:"phrases",phrases:2,hold:"fermata"},accentResponse:{enabled:!0,multiplier:1.5,type:"expansion"},patternOverrides:{ballad:{breathRateSync:{subdivision:"double-whole"},radiusSync:{inhale:{onUpbeat:2.2,onDownbeat:1.8},exhale:{onUpbeat:.1,onDownbeat:.2}}},uptempo:{breathRateSync:{subdivision:"half"},radiusSync:{inhale:{onUpbeat:1.4,onDownbeat:1.2},exhale:{onUpbeat:.3,onDownbeat:.4}}},ambient:{breathRateSync:{subdivision:"whole",curve:"ease"},radiusSync:{inhale:{onUpbeat:1.6,onDownbeat:1.6},exhale:{onUpbeat:.2,onDownbeat:.2}}}},dynamics:{forte:{radiusSync:{inhale:{multiplier:1.8},exhale:{multiplier:.5}},spiralStrength:.004,scaleAmount:.4},piano:{radiusSync:{inhale:{multiplier:1.2},exhale:{multiplier:.8}},spiralStrength:.001,scaleAmount:.1}}},initialize(e,t,i,n){e.gestureData||(e.gestureData={});const a=e.x-i,s=e.y-n;e.gestureData.breathe={startX:e.x,startY:e.y,angle:Math.atan2(s,a),baseRadius:Math.sqrt(a*a+s*s),phaseOffset:.2*Math.random()-.1}},apply(e,t,i,n,a,s){e.gestureData?.breathe||this.initialize(e,i,a,s);const o={...this.config,...i},r=(Math.sin(t*Math.PI*2*o.breathRate)+1)/2,l=100*(e.scaleFactor||1),h=o.inhaleRadius*l,c=o.exhaleRadius*l,u=c+(h-c)*r,d=e.x-a,m=e.y-s,p=Math.sqrt(d*d+m*m),g=u-p,f=.05*(i.strength||.8)*n;if(p>0){const t=d/p*g*f,a=m/p*g*f;e.vx+=t,e.vy+=a;const s=o.spiralStrength*n*(i.strength||1),l=-m/p,h=d/p;e.vx+=l*s*r,e.vy+=h*s*r}e.vx*=.98,e.vy*=.98},cleanup(e){e.gestureData?.breathe&&delete e.gestureData.breathe},"3d":{evaluate(e,t){const i=(t.config||{}).breathRate||.3,n=Math.sin(e*Math.PI*2*i);let a=1;if(e>.8){const t=(e-.8)/(1-.8);a=1-t*t*t}const s=.2*n*a;return{position:[0,.05*n*a,0],rotation:[0,0,0],scale:1+.35*n*a,glowIntensity:1+s,glowBoost:Math.max(0,2*s)}}}},st={name:"expand",emoji:"💫",type:"blending",description:"Radial expansion from center",config:{duration:600,scaleAmount:3,scaleTarget:3,glowAmount:.5,easing:"back",strength:3,particleMotion:{type:"pulse",strength:3,direction:"outward",persist:!0}},rhythm:{enabled:!0,syncMode:"crescendo",strengthSync:{pianissimo:1.5,fortissimo:5,crescendo:"build",sforzando:"burst"},scaleTargetSync:{verse:2,chorus:4.5,climax:6,curve:"exponential"},durationSync:{mode:"phrases",build:1.2,release:.8,sustain:"hold"},accentResponse:{enabled:!0,multiplier:2.8,type:"strength"},patternOverrides:{orchestral:{strengthSync:{pianissimo:2,fortissimo:6.5,crescendo:"dramatic"},scaleTargetSync:{climax:8}},rock:{strengthSync:{pianissimo:1.8,fortissimo:5.5,curve:"power"},accentResponse:{multiplier:3.2}},ambient:{strengthSync:{pianissimo:1.2,fortissimo:3.5,crescendo:"organic"},durationSync:{build:1.8,release:1.2}},electronic:{strengthSync:{pianissimo:1.6,fortissimo:4.8,curve:"digital"},scaleTargetSync:{curve:"linear"}}},dynamics:{forte:{strengthSync:{pianissimo:{multiplier:1.4},fortissimo:{multiplier:1.8}},scaleTargetSync:{multiplier:1.6},accentResponse:{multiplier:3.5}},piano:{strengthSync:{pianissimo:{multiplier:.8},fortissimo:{multiplier:1.2}},scaleTargetSync:{multiplier:.7},accentResponse:{multiplier:2}}}},initialize(e,t,i,n){e.gestureData||(e.gestureData={});const a=e.x-i,s=e.y-n;e.gestureData.expand={startX:e.x,startY:e.y,angle:Math.atan2(s,a),baseRadius:Math.sqrt(a*a+s*s),initialized:!0}},apply(e,t,i,n,a,s){e.gestureData?.expand?.initialized||this.initialize(e,i,a,s);const o=e.gestureData.expand,r={...this.config,...i},l=r.strength||1,h=1+(r.scaleTarget-1)*t*l,c=o.baseRadius*h,u=a+Math.cos(o.angle)*c,d=s+Math.sin(o.angle)*c,m=u-e.x,p=d-e.y;e.vx+=.8*m*n,e.vy+=.8*p*n,e.vx*=.95,e.vy*=.95},cleanup(e){e.gestureData?.expand&&delete e.gestureData.expand},"3d":{evaluate(e,t){const i={...this.config,...t},n=i.strength||3;return{position:[0,0,0],rotation:[0,0,0],scale:1+e*(i.scaleAmount||3)*(n/3),glowIntensity:1+.25*e,glowBoost:.8*e}}}},ot={name:"contract",emoji:"🌀",type:"blending",description:"Radial contraction toward center",config:{duration:600,scaleAmount:.2,scaleTarget:.2,glowAmount:-.2,easing:"cubic",strength:2.5,particleMotion:{type:"pulse",strength:2.5,direction:"inward",persist:!0}},rhythm:{enabled:!0,syncMode:"tension",strengthSync:{onTension:4,onRelease:1.5,curve:"magnetic"},scaleTargetSync:{forte:.1,piano:.4,crescendo:"gradual",diminuendo:"ease"},durationSync:{mode:"phrases",shortPhrase:.8,longPhrase:1.5,hold:"sustain"},accentResponse:{enabled:!0,multiplier:2.2,type:"strength"},patternOverrides:{classical:{strengthSync:{onTension:3.5,onRelease:1.8},scaleTargetSync:{forte:.15,piano:.35}},metal:{strengthSync:{onTension:5,onRelease:2,curve:"sharp"},scaleTargetSync:{forte:.05,piano:.25}},ambient:{strengthSync:{onTension:2.8,onRelease:1.2,curve:"ease"},durationSync:{shortPhrase:1.2,longPhrase:2}},trap:{strengthSync:{onTension:4.5,onRelease:1,dropBeat:6},scaleTargetSync:{forte:.08,piano:.3}}},dynamics:{forte:{strengthSync:{onTension:{multiplier:1.8},onRelease:{multiplier:1.4}},scaleTargetSync:{multiplier:.6},accentResponse:{multiplier:2.8}},piano:{strengthSync:{onTension:{multiplier:.7},onRelease:{multiplier:.8}},scaleTargetSync:{multiplier:1.4},accentResponse:{multiplier:1.6}}}},initialize(e,t,i,n){e.gestureData||(e.gestureData={});const a=e.x-i,s=e.y-n;e.gestureData.contract={startX:e.x,startY:e.y,angle:Math.atan2(s,a),baseRadius:Math.sqrt(a*a+s*s),initialized:!0}},apply(e,t,i,n,a,s){e.gestureData?.contract?.initialized||this.initialize(e,i,a,s);const o=e.gestureData.contract,r={...this.config,...i},l=r.strength||1,h=1-(1-r.scaleTarget)*t*l,c=o.baseRadius*h,u=a+Math.cos(o.angle)*c,d=s+Math.sin(o.angle)*c,m=u-e.x,p=d-e.y;e.vx+=.5*m*n,e.vy+=.5*p*n,e.vx*=.95,e.vy*=.95},cleanup(e){e.gestureData?.contract&&delete e.gestureData.contract},"3d":{evaluate(e,t){const i={...this.config,...t},n=i.strength||2.5,a=i.scaleTarget||.2,s=1-e*(1-a)*(n/2.5),o=1-.15*e;return{position:[0,0,0],rotation:[0,0,0],scale:Math.max(a,s),glowIntensity:o}}}},rt={name:"flash",emoji:"⚡",type:"blending",description:"Bright flash burst effect",config:{duration:400,glowAmount:2.5,glowPeak:3,scalePeak:1.1,easing:"cubic",strength:1,particleMotion:{type:"burst",strength:1,decay:.3}},rhythm:{enabled:!0,syncMode:"beat",timingSync:"immediate",interruptible:!0,priority:8,blendable:!0,intensitySync:{onBeat:3.5,offBeat:1,accent:5,subdivision:"quarter",curve:"exponential"},durationSync:{mode:"tempo",baseDuration:400,scaling:"inverse"},scaleSync:{onBeat:1.2,offBeat:1,accent:1.4,curve:"elastic"},strobeSync:{enabled:!1,pattern:"XXOX",subdivision:"sixteenth"},dynamics:{forte:{glowPeak:4,scalePeak:1.3,duration:300},piano:{glowPeak:2,scalePeak:1.05,duration:500}}},initialize(e,t){e.gestureData||(e.gestureData={}),e.gestureData.flash={originalOpacity:e.opacity,originalSize:e.size,initialized:!0}},apply(e,t,i,n,a,s){e.gestureData?.flash?.initialized||this.initialize(e,i);const o=e.gestureData.flash,r={...this.config,...i},l=r.strength||1;let h;if(h=t<.3?t/.3*r.glowPeak:r.glowPeak*(1-(t-.3)/.7),e.opacity=Math.min(1,o.originalOpacity*(1+h*l)),e.size=o.originalSize*(1+(r.scalePeak-1)*h*l*.1),t<.2){const i=(1-t/.2)*l,o=Math.atan2(e.y-s,e.x-a);e.vx+=Math.cos(o)*i*2*n,e.vy+=Math.sin(o)*i*2*n}e.vx*=1-.1*r.particleMotion.decay,e.vy*=1-.1*r.particleMotion.decay},cleanup(e){e.gestureData?.flash&&(e.opacity=e.gestureData.flash.originalOpacity,e.size=e.gestureData.flash.originalSize,delete e.gestureData.flash)},"3d":{evaluate(e,t){const i={...this.config,...t};let n;t.strength,n=e<.3?e/.3:1-(e-.3)/.7;const a=1+.4*n;return{position:[0,0,0],rotation:[0,0,0],scale:1+n*((i.scalePeak||1.1)-1),glowIntensity:a,glowBoost:2*n}}}},lt={name:"glow",emoji:"✨",type:"blending",description:"Pure luminous glow without movement",config:{duration:1500,amplitude:0,frequency:1,holdPeak:.3,easing:"sine",scaleAmount:.1,glowAmount:.8,strength:0,direction:"none",particleMotion:{type:"glow",strength:0,direction:"none",frequency:1}},rhythm:{enabled:!0,syncMode:"phrase",amplitudeSync:{onBeat:2,offBeat:1.2,curve:"smooth"},frequencySync:{mode:"phrase",subdivision:"bar"},durationSync:{mode:"bars",bars:2},accentResponse:{enabled:!0,multiplier:2.5},patternOverrides:{ambient:{amplitudeSync:{onBeat:2.5,offBeat:1.8},durationSync:{bars:4}},electronic:{amplitudeSync:{onBeat:3,offBeat:.5,curve:"sharp"},frequencySync:{subdivision:"quarter"}}}},initialize(e,t,i,n){e.gestureData||(e.gestureData={}),e.gestureData.glow={startOpacity:e.opacity,startGlow:e.glowSizeMultiplier||0,initialized:!0}},apply(e,t,i,n,a,s){e.gestureData?.glow?.initialized||this.initialize(e,i,a,s);const o={...this.config,...i},r=this.easeInOutSine(t);let l,{frequency:h}=o,{glowAmount:c}=o;i.rhythmModulation&&(c*=i.rhythmModulation.amplitudeMultiplier||1,c*=i.rhythmModulation.accentMultiplier||1,i.rhythmModulation.frequencyMultiplier&&(h*=i.rhythmModulation.frequencyMultiplier));const u=r*h*2%2;l=o.holdPeak>0&&u>1-o.holdPeak&&u<1+o.holdPeak?1:Math.sin(r*Math.PI*2*h);let d=1;t>.9&&(d=.5+.5*(1-10*(t-.9))),e.glowIntensity=1+l*c*d},cleanup(e){e.gestureData?.glow&&(e.glowIntensity=1,delete e.gestureData.glow)},easeInOutSine:e=>-(Math.cos(Math.PI*e)-1)/2,"3d":{evaluate(e,t){const i={...this.config,...t},n=-(Math.cos(Math.PI*e)-1)/2,a=Math.sin(n*Math.PI);let s=i.glowAmount||.8;t.rhythmModulation&&(s*=t.rhythmModulation.amplitudeMultiplier||1,s*=t.rhythmModulation.accentMultiplier||1);const o=1+a*s;return{position:[0,0,0],rotation:[0,0,0],scale:1+a*(i.scaleAmount||.1)*.5,glowIntensity:o,glowBoost:1.5*a}}}},ht={name:"peek",emoji:"👀",type:"effect",description:"Quick peek and hide motion",config:{peekDistance:40,peekSpeed:.15,holdDuration:200,hideSpeed:.25,stagger:!0,duration:1500},rhythm:{enabled:!0,syncMode:"accent",distanceSync:{onAccent:60,offAccent:25,curve:"quick"},speedSync:{mode:"tempo",fast:.25,slow:.1,hideMultiplier:1.8},durationSync:{mode:"subdivision",beats:.25,staggerBeats:.125,sustain:!1},syncopationResponse:{enabled:!0,multiplier:1.8,type:"distance"},patternOverrides:{funk:{distanceSync:{onAccent:70,offAccent:35,curve:"funky"},syncopationResponse:{multiplier:2.2}},latin:{speedSync:{fast:.3,slow:.12},durationSync:{beats:.5,staggerBeats:.25}},breakbeat:{distanceSync:{onAccent:55,offAccent:40},syncopationResponse:{multiplier:2.5}},classical:{distanceSync:{onAccent:45,offAccent:20,curve:"elegant"},speedSync:{fast:.18,slow:.08}}},dynamics:{forte:{distanceSync:{onAccent:{multiplier:1.6},offAccent:{multiplier:1.3}},speedSync:{multiplier:1.4},syncopationResponse:{multiplier:2.8}},piano:{distanceSync:{onAccent:{multiplier:.6},offAccent:{multiplier:.4}},speedSync:{multiplier:.7},syncopationResponse:{multiplier:1.2}}}},apply(e,t,i,n,a,s){if(e.gestureData||(e.gestureData={}),!e.gestureData.peek){const t=e.x-a,i=e.y-s,n=Math.atan2(i,t),o=Math.sqrt(t*t+i*i);e.gestureData.peek={originalX:e.x,originalY:e.y,peekAngle:n,originalDistance:o,staggerDelay:this.config.stagger?.3*Math.random():0,phase:"waiting",phaseTimer:0,peekOffset:{x:0,y:0}}}const o=e.gestureData.peek,{config:r}=this,l=Math.max(0,Math.min(1,(t-o.staggerDelay)/(1-o.staggerDelay)));0===l?o.phase="waiting":l<.3?o.phase="peeking":l<.6?o.phase="holding":l<1&&(o.phase="hiding");let h=0;switch(o.phase){case"peeking":{const e=l/.3;h=this.easeOutCubic(e)*r.peekDistance;break}case"holding":h=r.peekDistance,Math.random()<.1&&(o.peekOffset.x+=2*(Math.random()-.5),o.peekOffset.y+=2*(Math.random()-.5));break;case"hiding":{const e=(l-.6)/.4;h=(1-this.easeInCubic(e))*r.peekDistance;break}}if("waiting"!==o.phase){const t=Math.cos(o.peekAngle)*h,i=Math.sin(o.peekAngle)*h;o.peekOffset.x+=(t-o.peekOffset.x)*r.peekSpeed,o.peekOffset.y+=(i-o.peekOffset.y)*r.peekSpeed,e.x=o.originalX+o.peekOffset.x,e.y=o.originalY+o.peekOffset.y}void 0!==e.alpha&&("peeking"===o.phase||"holding"===o.phase?e.alpha=.7+.3*Math.random():e.alpha=1)},easeOutCubic:e=>1-Math.pow(1-e,3),easeInCubic:e=>e*e*e,cleanup(e){e.gestureData?.peek&&(e.x=e.gestureData.peek.originalX,e.y=e.gestureData.peek.originalY,void 0!==e.alpha&&(e.alpha=1),delete e.gestureData.peek)},"3d":{evaluate(e,t){const i=.01*({...this.config,...t}.peekDistance||40);let n=0,a=1;if(e<.3){const t=e/.3;n=(1-Math.pow(1-t,3))*i}else if(e<.6)n=i,a=.7+.3*Math.random();else{const t=(e-.6)/.4;n=(1-Math.pow(t,3))*i}return{position:[n,0,0],rotation:[0,0,0],scale:1,glowIntensity:a}}}},ct={name:"runningman",emoji:"🏃",type:"effect",description:"Hip-hop running man shuffle",config:{duration:2e3,slideDistance:30,stepHeight:15,speed:1.2,strength:.8,particleMotion:{type:"runningman",strength:.7}},rhythm:{enabled:!0,syncToBeat:!0,beatMultiplier:1,accentBeats:[1,3]},apply:(e,t,i,n,a,s)=>!1,blend:(e,t,i)=>!1,"3d":{evaluate(e,t){const i={...this.config,...t}.strength||.8;return{position:[.1*Math.sin(e*Math.PI*4)*i,.05*Math.abs(Math.sin(e*Math.PI*8))*i,0],rotation:[0,0,.035*Math.sin(e*Math.PI*4)*i],scale:1-.035*Math.abs(Math.sin(e*Math.PI*8))*i,glowIntensity:1+.25*Math.abs(Math.sin(e*Math.PI*8)),glowBoost:.35*Math.max(0,Math.abs(Math.sin(e*Math.PI*8)))}}}},ut={name:"charleston",emoji:"🕺",type:"effect",description:"Hip-hop Charleston shuffle with crisscross",config:{duration:2500,kickDistance:35,swivelRange:40,bounceHeight:12,strength:.9,particleMotion:{type:"charleston",strength:.8}},rhythm:{enabled:!0,syncToBeat:!0,beatMultiplier:2,accentBeats:[1,2.5,3,4.5]},apply:(e,t,i,n,a,s)=>!1,blend:(e,t,i)=>!1,"3d":{evaluate(e,t){const i={...this.config,...t}.strength||.9;return{position:[.12*Math.sin(e*Math.PI*8)*i,.05*Math.abs(Math.sin(e*Math.PI*8))*i,0],rotation:[0,0,.05*Math.sin(e*Math.PI*8)*i],scale:1-.04*Math.abs(Math.sin(e*Math.PI*8))*i,glowIntensity:1+.3*Math.abs(Math.sin(e*Math.PI*8)),glowBoost:.4*Math.max(0,Math.abs(Math.sin(e*Math.PI*8)))}}}};const dt=[Be,ke,Te,Ee,Ie,Ae,Re,ze,_e,Oe,{name:"sparkle",emoji:"✨",type:"blending",description:"Bright twinkling sparkle bursts",config:{duration:800,musicalDuration:{musical:!0,beats:2}},rhythm:{enabled:!0,syncMode:"beat",timingSync:"nextBeat",durationSync:{mode:"beats",beats:2},interruptible:!0,priority:5,blendable:!0},apply:(e,t,i)=>!1,blend:(e,t,i)=>!1,"3d":{evaluate(e,t){const i=t?.strength||1,n=Math.pow(Math.max(0,Math.sin(e*Math.PI*6)),3),a=Math.pow(Math.max(0,Math.sin(e*Math.PI*8+1)),3),s=Math.pow(Math.max(0,Math.sin(e*Math.PI*10+2)),3),o=Math.max(n,a,s)*Math.sin(e*Math.PI);return{position:[0,0,0],rotation:[0,0,0],scale:1+.08*o*i,glowIntensity:1+.5*o*i,glowBoost:2*o*i}}}},{name:"shimmer",emoji:"🌟",type:"particle",description:"Shimmer effect with sparkling particles",config:{duration:2e3,musicalDuration:{musical:!0,bars:1},particleMotion:"radiant"},rhythm:{enabled:!0,syncType:"beat",durationSync:{mode:"bars",bars:1},intensity:.8},override:(e,t,i)=>(e.shimmerEffect=!0,e.shimmerProgress=t,!0),blend:(e,t,i)=>!1,"3d":{evaluate(e,t){const i=t?.strength||1,n=(.4*Math.sin(e*Math.PI*4)+.35*Math.sin(e*Math.PI*6+.5)+.25*Math.sin(e*Math.PI*10+1)+1)/2;return{position:[0,0,0],rotation:[0,0,0],scale:1+.05*n*i,glowIntensity:1+.3*n*i,glowBoost:1*n*i}}}},Fe,((e,t="✨")=>({name:e,emoji:t,type:"blending",description:`${e} animation`,config:{duration:1e3,musicalDuration:{musical:!0,beats:2}},rhythm:{enabled:!0,syncMode:"beat",timingSync:"nextBeat",durationSync:{mode:"beats",beats:2},interruptible:!0,priority:3,blendable:!0,crossfadePoint:"anyBeat",maxQueue:3},apply:(e,t,i)=>!1,blend:(e,t,i)=>!1}))("groove","🎵"),Ve,Ge,qe,Le,{name:"rain",emoji:"🌧️",type:"particle",description:"Rain effect with falling particles",config:{duration:3e3,musicalDuration:{musical:!0,bars:2},particleMotion:"falling"},rhythm:{enabled:!0,syncType:"off-beat",durationSync:{mode:"bars",bars:2},intensity:.8},apply:(e,t,i)=>(e.rainEffect=!0,e.rainProgress=t,!0),blend:(e,t,i)=>!1}],mt=[Ne,je,Ue,He,We,Xe,Ye,$e],pt=[Qe,Ze,Je,Ke,et,tt,it,nt,at,st,ot,rt,lt,ht,ct,ut],gt={};function ft(e){if(gt[e])return gt[e];return Pe(e)||null}[...dt,...mt,...pt].forEach(e=>{gt[e.name]=e}),dt.map(e=>e.name),mt.map(e=>e.name),pt.map(e=>e.name);const yt={none:{speed:1,amplitude:1,intensity:1,smoothness:1,regularity:1,"3d":{rotation:{speedMultiplier:1,shakeMultiplier:1},glow:{intensityMultiplier:1,pulseSpeedMultiplier:1},scale:{breathDepthMultiplier:1,breathRateMultiplier:1},righting:{strengthMultiplier:1}}},clear:{speed:1,amplitude:1,intensity:1,smoothness:1,regularity:1,"3d":{rotation:{speedMultiplier:1,shakeMultiplier:1},glow:{intensityMultiplier:1,pulseSpeedMultiplier:1},scale:{breathDepthMultiplier:1,breathRateMultiplier:1},righting:{strengthMultiplier:1}}},nervous:{speed:1.2,amplitude:.9,intensity:1.1,smoothness:.7,regularity:.6,addFlutter:!0,addMicroShake:!0,"3d":{rotation:{speedMultiplier:1.5,shakeMultiplier:3.5,enableEpisodicWobble:!0},glow:{intensityMultiplier:1.25,pulseSpeedMultiplier:2},scale:{breathDepthMultiplier:.5,breathRateMultiplier:1.8},righting:{strengthMultiplier:.7}}},confident:{speed:.9,amplitude:1.3,intensity:1.2,smoothness:1.1,regularity:1.2,addPower:!0,addHold:!0,"3d":{rotation:{speedMultiplier:.7,shakeMultiplier:.2},glow:{intensityMultiplier:1.4,pulseSpeedMultiplier:.7},scale:{breathDepthMultiplier:1.5,breathRateMultiplier:.7},righting:{strengthMultiplier:1.6}}},tired:{speed:.7,amplitude:.7,intensity:.8,smoothness:1.3,regularity:.8,addDroop:!0,addPause:!0,"3d":{rotation:{speedMultiplier:.4,shakeMultiplier:.15},glow:{intensityMultiplier:.5,pulseSpeedMultiplier:.5},scale:{breathDepthMultiplier:1.3,breathRateMultiplier:.5},righting:{strengthMultiplier:.6}}},intense:{speed:1.3,amplitude:1.2,intensity:1.4,smoothness:.6,regularity:.9,addPulse:!0,addFocus:!0,"3d":{rotation:{speedMultiplier:1.6,shakeMultiplier:2.5},glow:{intensityMultiplier:1.8,pulseSpeedMultiplier:2.2},scale:{breathDepthMultiplier:1.6,breathRateMultiplier:1.8},righting:{strengthMultiplier:1.3}}},subdued:{speed:.8,amplitude:.8,intensity:.7,smoothness:1.2,regularity:1.1,addSoftness:!0,addFade:!0,"3d":{rotation:{speedMultiplier:.5,shakeMultiplier:.1},glow:{intensityMultiplier:.55,pulseSpeedMultiplier:.6},scale:{breathDepthMultiplier:.7,breathRateMultiplier:.6},righting:{strengthMultiplier:1.4}}}};function vt(e){return e&&""!==e&&"clear"!==e&&yt[e]||yt.clear}function bt(e){return 3===(e=e.replace("#","")).length&&(e=e.split("").map(e=>e+e).join("")),{r:parseInt(e.substr(0,2),16),g:parseInt(e.substr(2,2),16),b:parseInt(e.substr(4,2),16)}}const wt={intense:1.6,confident:1.3,nervous:1.15,clear:1,tired:.8,subdued:.5};function Mt(e,t){if(!t||"clear"===t)return e;const i=wt[t.toLowerCase()];return i&&1!==i?function(e,t){const i=bt(e),n=function(e,t,i){e/=255,t/=255,i/=255;const n=Math.max(e,t,i),a=Math.min(e,t,i),s=(n+a)/2;let o,r;if(n===a)o=r=0;else{const l=n-a;switch(r=s>.5?l/(2-n-a):l/(n+a),n){case e:o=(t-i)/l+(t<i?6:0);break;case t:o=(i-e)/l+2;break;case i:o=(e-t)/l+4}o/=6}return{h:360*o,s:100*r,l:100*s}}(i.r,i.g,i.b);n.s=Math.max(0,Math.min(100,n.s*t));const a=function(e,t,i){e/=360,i/=100;const n=(e,t,i)=>(i<0&&(i+=1),i>1&&(i-=1),i<1/6?e+6*(t-e)*i:i<.5?t:i<2/3?e+(t-e)*(2/3-i)*6:e);let a,s,o;if(0==(t/=100))a=s=o=i;else{const r=i<.5?i*(1+t):i+t-i*t,l=2*i-r;a=n(l,r,e+1/3),s=n(l,r,e),o=n(l,r,e-1/3)}return{r:Math.round(255*a),g:Math.round(255*s),b:Math.round(255*o)}}(n.h,n.s,n.l);return function(e,t,i){const n=e=>{const t=Math.round(Math.max(0,Math.min(255,e))).toString(16);return 1===t.length?`0${t}`:t};return`#${n(e)}${n(t)}${n(i)}`}(a.r,a.g,a.b)}(e,i):e}Object.fromEntries(Object.entries({neutral:"#B0B0B0",joy:"#FFD700",sadness:"#4169E1",anger:"#DC143C",fear:"#8B008B",surprise:"#FF8C00",disgust:"#9ACD32",love:"#FF69B4"}).map(([e,t])=>{const i=bt(t);return[e,`${i.r}, ${i.g}, ${i.b}`]}));const St=new class{constructor(){this.enabled=!1,this.adapter=null,this.subsystemConfigs=new Map,this.activeModulations=new Map}initialize(){this.adapter=ve.getAdapter(),this.enabled=!0,this.adapter.onBeat(this.handleBeat.bind(this)),this.adapter.onBar(this.handleBar.bind(this))}updateBPM(e){if(e>=60&&e<=220){if(window.rhythmManuallyStoppedForCurrentAudio)return;if(!ve.isRunning)return this.start(e,"straight"),void(window.rhythmSyncVisualizer&&!window.rhythmSyncVisualizer.state.active&&window.rhythmSyncVisualizer.start());ve.setBPM(e)}}registerConfig(e,t,i){if(!i.rhythm||!i.rhythm.enabled)return;const n=`${e}:${t}`;this.subsystemConfigs.set(n,{type:e,name:t,rhythmConfig:i.rhythm,originalConfig:i})}applyGestureRhythm(e,t,i,n){if(!this.enabled||!e.rhythm?.enabled)return{};const a=e.rhythm,s={};if(a.amplitudeSync){const e=a.amplitudeSync,t=this.adapter.getBeatSync(e.offBeat||.8,e.onBeat||1.5,e.curve||"linear");s.amplitudeMultiplier=t}if(a.wobbleSync){const e=a.wobbleSync;this.adapter.isOnSubdivision(e.subdivision,.1)?s.wobbleMultiplier=1+e.intensity:s.wobbleMultiplier=1}if(a.accentResponse?.enabled){const e=this.adapter.getAccentedValue(1,a.accentResponse.multiplier||1.5);s.accentMultiplier=e}const o=this.adapter.getPattern();return o&&a.patternOverrides?.[o]&&Object.assign(s,a.patternOverrides[o]),s}applyParticleRhythm(e,t){if(!this.enabled||!e.rhythm?.enabled)return{};const i=this.adapter.getTimeInfo(),n=e.rhythm,a={};if(n.particleEmission){const e=n.particleEmission;"beat"===e.syncMode&&this.adapter.isOnBeat(.1)?a.emitBurst=e.burstSize||3:void 0!==e.offBeatRate&&(a.emissionRate=e.offBeatRate)}if(n.glowSync){const e=n.glowSync,t=this.adapter.getBeatSync(e.intensityRange[0]||1,e.intensityRange[1]||2,"pulse");a.glowIntensity=t}if("bars"===n.breathSync?.mode){const e=n.breathSync,t=i.bar%e.barsPerBreath/e.barsPerBreath;a.breathPhase=t*Math.PI*2}return a}applyBehaviorRhythm(e,t,i){if(!this.enabled||!e.rhythm?.enabled)return{};const n=this.adapter.getTimeInfo(),a=e.rhythm,s={};if(a.glitchTiming){const e=a.glitchTiming;if(this.adapter.isOnSubdivision(e.subdivision,.05)&&Math.random()<e.probability){const t=this.adapter.isOnBeat()?e.intensityOnBeat:e.intensityOffBeat;s.triggerGlitch=!0,s.glitchIntensity=t}}if(a.orbitRhythm){const e=a.orbitRhythm;"tempo"===e.baseSpeed&&(s.speedMultiplier=this.adapter.getBPM()/120),e.beatAcceleration&&this.adapter.isOnBeat(.1)&&(s.speedBoost=e.beatAcceleration),e.barReset&&0===n.beatInBar&&(s.resetOrbit=!0)}if(a.stutterSync){const e=a.stutterSync,t=this.adapter.getPattern();if(t&&e.patterns?.[t]){const i=e.patterns[t];i.freezeOnDrop&&2===n.beatInBar?(s.freeze=!0,s.freezeDuration=i.dropDuration):i.randomFreeze&&Math.random()<i.randomFreeze&&(s.freeze=!0,s.freezeDuration=i.duration)}}return s}handleBeat(e){this.lastBeatInfo=e}handleBar(e){this.lastBarInfo=e}getMusicalDuration(e,t){if(!this.enabled||!e?.durationSync)return t;const i=e.durationSync;return"bars"===i.mode?this.adapter.beatsToMs(4*i.bars):"beats"===i.mode?this.adapter.beatsToMs(i.beats):t}isEnabled(){return this.enabled&&this.adapter.isPlaying()}start(e=120,t="straight"){e&&ve.setBPM(e),t&&ve.setPattern(t),ve.start(),this.enabled=!0}stop(){ve.stop(),this.enabled=!1,this.bpmLocked=!1,this.lockedBPM=null}setPattern(e){ve.setPattern(e)}setBPM(e){ve.setBPM(e),this.bpmLocked&&(this.lockedBPM=e)}resampleBPM(){this.bpmLocked=!1,this.lockedBPM=null}setTimeSignature(e){this.timeSignature=e;const t=document.getElementById("time-sig-display");t&&(t.textContent=e),"3/4"===e&&ve.getPattern()}syncToAudio(e,t){ve.syncToAudio(e,t)}},xt=new class{constructor(){this.emotionCache=new Map,this.visualParamsCache=new Map,this.modifiersCache=new Map,this.transitionCache=new Map,this.stats={hits:0,misses:0,loadTime:0,cacheSize:0},this.isInitialized=!1,this.loadStartTime=0,this.initialize()}initialize(){this.loadStartTime=performance.now();try{const e=[...Array.from(ue.keys()),...le()];e.forEach(e=>{this.cacheEmotion(e)}),this.cacheCommonTransitions(e),this.isInitialized=!0,this.stats.loadTime=performance.now()-this.loadStartTime,this.stats.cacheSize=this.emotionCache.size}catch(e){console.error("[EmotionCache] Initialization failed:",e),this.isInitialized=!1}}cacheEmotion(e){try{const t=me(e);t&&this.emotionCache.set(e,t);const i=pe(e);this.visualParamsCache.set(e,i);const n=ge(e);this.modifiersCache.set(e,n)}catch(t){console.warn(`[EmotionCache] Failed to cache emotion '${e}':`,t)}}cacheCommonTransitions(e){[["neutral","joy"],["neutral","sadness"],["neutral","anger"],["joy","sadness"],["sadness","joy"],["anger","calm"],["calm","anger"]].forEach(([t,i])=>{if(e.includes(t)&&e.includes(i))try{const e=fe(t,i),n=`${t}->${i}`;this.transitionCache.set(n,e)}catch(e){console.warn(`[EmotionCache] Failed to cache transition '${t}->${i}':`,e)}})}getEmotion(e){if(!this.isInitialized)return console.warn("[EmotionCache] Cache not initialized, falling back to direct access"),me(e);const t=this.emotionCache.get(e);return t?(this.stats.hits++,t):(this.stats.misses++,console.warn(`[EmotionCache] Cache miss for emotion '${e}', consider adding to pre-cache`),me(e))}getVisualParams(e){if(!this.isInitialized)return pe(e);const t=this.visualParamsCache.get(e);return t?(this.stats.hits++,t):(this.stats.misses++,pe(e))}getModifiers(e){if(!this.isInitialized)return ge(e);const t=this.modifiersCache.get(e);return t?(this.stats.hits++,t):(this.stats.misses++,ge(e))}getTransitionParams(e,t){if(!this.isInitialized)return fe(e,t);const i=`${e}->${t}`,n=this.transitionCache.get(i);return n?(this.stats.hits++,n):(this.stats.misses++,fe(e,t))}hasEmotion(e){return this.emotionCache.has(e)}getStats(){const e=this.stats.hits+this.stats.misses,t=e>0?(this.stats.hits/e*100).toFixed(2):0;return{isInitialized:this.isInitialized,loadTime:this.stats.loadTime,cacheSize:this.stats.cacheSize,hits:this.stats.hits,misses:this.stats.misses,hitRate:`${t}%`,emotions:this.emotionCache.size,visualParams:this.visualParamsCache.size,modifiers:this.modifiersCache.size,transitions:this.transitionCache.size}}clear(){this.emotionCache.clear(),this.visualParamsCache.clear(),this.modifiersCache.clear(),this.transitionCache.clear(),this.isInitialized=!1,this.stats={hits:0,misses:0,loadTime:0,cacheSize:0}}reinitialize(){this.clear(),this.initialize()}};function Ct(e){if(!e||0===e.length)return"#FFFFFF";let t=0,i=0;const n=[];for(const a of e)"string"==typeof a?(n.push({color:a,weight:null}),i++):a&&"object"==typeof a&&a.color&&(n.push({color:a.color,weight:a.weight||null}),a.weight?t+=a.weight:i++);const a=Math.max(0,100-t),s=i>0?a/i:0,o=[];let r=0;for(const e of n)r+=null!==e.weight?e.weight:s,o.push({color:e.color,threshold:r});const l=Math.random()*r;for(const e of o)if(l<=e.threshold)return e.color;return n[n.length-1].color}var Dt={name:"ambient",emoji:"☁️",description:"Gentle upward drift like smoke",initialize:function(e){e.vx=0,e.vy=-.04-.02*Math.random(),e.lifeDecay=.002,e.emotionColors&&e.emotionColors.length>0&&(e.color=Ct(e.emotionColors)),e.behaviorData={upwardSpeed:5e-4,waviness:0,friction:.998}},update:function(e,t,i,n){const a=e.behaviorData;e.vy*=Math.pow(a.friction,t),e.vy-=a.upwardSpeed*t,e.vx=0}};const Pt=2*Math.PI;var Bt={name:"orbiting",emoji:"💕",description:"Romantic firefly dance around the orb",initialize:function(e){e.lifeDecay=.001+.002*Math.random(),e.emotionColors&&e.emotionColors.length>0&&(e.color=Ct(e.emotionColors)),e.isSparkle="#FFE4E1"===e.color||"#FFCCCB"===e.color||"#FFC0CB"===e.color;const t=40*(e.scaleFactor||1)*(1.3+.9*Math.random());e.blinkPhase=Math.random()*Pt,e.blinkSpeed=.3+1.2*Math.random(),e.blinkIntensity=.6+.4*Math.random(),e.fadePhase=Math.random()*Pt,e.fadeSpeed=.1+.3*Math.random(),e.minOpacity=.2+.2*Math.random(),e.maxOpacity=.8+.2*Math.random(),e.isSparkle&&(e.blinkSpeed*=2,e.blinkIntensity=1,e.minOpacity=0,e.maxOpacity=1),e.behaviorData={angle:Math.random()*Pt,radius:t,baseRadius:t,angularVelocity:8e-4+.0017*Math.random(),swayAmount:3+7*Math.random(),swaySpeed:.2+.5*Math.random(),floatOffset:Math.random()*Pt,floatSpeed:.3+.7*Math.random(),floatAmount:2+6*Math.random(),twinklePhase:Math.random()*Pt,twinkleSpeed:2+3*Math.random()}},update:function(e,t,i,n){const a=e.behaviorData;a.angle+=a.angularVelocity*t;const s=Math.sin(a.angle*a.swaySpeed)*a.swayAmount,o=6*Math.sin(1.5*a.angle),r=(a.radius||a.baseRadius)+o+.2*s,l=i+Math.cos(a.angle)*r,h=n+Math.sin(a.angle)*r;a.floatOffset+=a.floatSpeed*t*.001;const c=Math.sin(a.floatOffset)*a.floatAmount;e.vx=.1*(l-e.x),e.vy=.1*(h+c-e.y),e.fadePhase+=e.fadeSpeed*t*.001;const u=.5*Math.sin(e.fadePhase)+.5,d=e.minOpacity+(e.maxOpacity-e.minOpacity)*u;let m;e.blinkPhase+=e.blinkSpeed*t*.002,e.isSparkle?(a.twinklePhase+=a.twinkleSpeed*t*.001,m=.7*Math.pow(Math.sin(a.twinklePhase),16)+.2*Math.sin(5*e.blinkPhase)+.1):m=.4*Math.sin(e.blinkPhase)+.3*Math.sin(3*e.blinkPhase)+.2*Math.sin(7*e.blinkPhase)+.1*Math.sin(11*e.blinkPhase);const p=.5*(m+1),g=.2+p*e.blinkIntensity*.8;e.opacity=e.baseOpacity*d*g,e.isSparkle?e.size=e.baseSize*(.5+1*p):e.size=e.baseSize*(.8+.3*p),e.isSparkle&&(e.tempColor=p>.85?"#FFFFFF":e.color)}},kt={name:"rising",emoji:"🎈",description:"Buoyant upward movement like balloons",initialize:function(e){e.vx=.02*(Math.random()-.5),e.vy=-.05-.03*Math.random(),e.lifeDecay=.002,e.baseOpacity=.7+.3*Math.random(),e.emotionColors&&e.emotionColors.length>0&&(e.color=Ct(e.emotionColors)),e.behaviorData={buoyancy:.001,driftAmount:.005}},update:function(e,t,i,n){const a=e.behaviorData;e.vy-=a.buoyancy*t,e.vx+=(Math.random()-.5)*a.driftAmount*t,e.vx*=Math.pow(.995,t),e.vy*=Math.pow(.998,t)}},Tt={name:"falling",emoji:"💧",description:"Heavy downward drift like tears",initialize:function(e){e.vx=0,e.vy=.04+.02*Math.random(),e.lifeDecay=.002,e.emotionColors&&e.emotionColors.length>0&&(e.color=Ct(e.emotionColors));const t=Math.random(),i=Math.random(),n=t*Math.PI*2,a=2*i-1,s=Math.sqrt(1-a*a);e.behaviorData={downwardSpeed:5e-4,friction:.998,fallingDir:{x:s*Math.cos(n),y:a,z:s*Math.sin(n)},orbitDistanceRatio:.7+.4*Math.random()}},update:function(e,t,i,n){const a=e.behaviorData;e.vy*=Math.pow(a.friction,t),e.vy+=a.downwardSpeed*t,e.vx=0}};const Et=2e3,It=3,At=8,Rt=.7;var zt={name:"popcorn",emoji:"🍿",description:"Spontaneous popping with gravity and bounces",initialize:function(e){if(e.vx=.1*(Math.random()-.5),e.vy=.1*(Math.random()-.5),e.lifeDecay=.008+.012*Math.random(),e.emotionColors&&e.emotionColors.length>0)e.color=Ct(e.emotionColors);else{const t=["#FFFFFF","#FFFACD","#FFF8DC","#FFFFE0","#FAFAD2"];e.color=Ct(t)}e.size=Math.random()<.3?(8+4*Math.random())*e.scaleFactor*e.particleSizeMultiplier:(2+4*Math.random())*e.scaleFactor*e.particleSizeMultiplier,e.baseSize=e.size,e.hasGlow=Math.random()<.2,e.glowSizeMultiplier=e.hasGlow?1.2:0,e.behaviorData={popDelay:Math.random()*Et,hasPopped:!1,popStrength:It+Math.random()*(At-It),gravity:.098,bounceDamping:Rt,bounceCount:0,maxBounces:2+Math.floor(2*Math.random()),spinRate:10*(Math.random()-.5),lifetime:0}},update:function(e,t,i,n){const a=e.behaviorData;if(a.lifetime+=16.67*t,!a.hasPopped&&a.lifetime>a.popDelay){a.hasPopped=!0;const t=Math.random()*Math.PI*2;e.vx=Math.cos(t)*a.popStrength*1.5,e.vy=Math.sin(t)*a.popStrength-.3,e.size=1.25*e.baseSize}if(a.hasPopped){e.vy+=a.gravity*t;const i=n+100*e.scaleFactor;e.y>i&&a.bounceCount<a.maxBounces&&(e.y=i,e.vy=-Math.abs(e.vy)*a.bounceDamping,e.vx*=.9,a.bounceCount++,e.size=e.baseSize*(1.5-.1*a.bounceCount)),a.bounceCount>=a.maxBounces&&(e.lifeDecay=.03+.02*Math.random(),e.size*=.95),Math.sqrt(e.vx*e.vx+e.vy*e.vy)<.5&&(e.lifeDecay*=1.5)}}},_t={name:"burst",emoji:"💥",description:"Explosive expansion from center",initialize:function(e){const t="suspicion"===e.emotion,i="surprise"===e.emotion,n="glitch"===e.emotion,a=Math.random()*Pt,s=t?1+.8*Math.random():i?7+5*Math.random():n?2+1.5*Math.random():3.5+2.5*Math.random();e.vx=Math.cos(a)*s,e.vy=Math.sin(a)*s,e.lifeDecay=t?.01:i?.006+.008*Math.random():n?.012:.015,e.emotionColors&&e.emotionColors.length>0&&(e.color=Ct(e.emotionColors)),t&&(e.size=(6+4*Math.random())*(e.scaleFactor||1)*(e.particleSizeMultiplier||1),e.baseSize=e.size,e.opacity=1,e.baseOpacity=e.opacity),e.behaviorData={isSuspicion:t,isSurprise:i,isGlitch:n,age:0,fadeStart:t?.3:.2,glitchPhase:Math.random()*Math.PI*2,glitchIntensity:n?.3:0,glitchFrequency:n?.1:0}},update:function(e,t,i,n){const a=e.behaviorData;if(a.isSurprise)if(a.age+=.016*t,a.age<.15){const i=.98;e.vx*=Math.pow(i,t),e.vy*=Math.pow(i,t)}else if(a.age<.25){const i=.85;e.vx*=Math.pow(i,t),e.vy*=Math.pow(i,t)}else{const i=.99;e.vx*=Math.pow(i,t),e.vy*=Math.pow(i,t),e.vx+=.01*(Math.random()-.5)*t,e.vy+=.01*(Math.random()-.5)*t}else{const i=a.isSuspicion?.99:a.isGlitch?.97:.95;e.vx*=Math.pow(i,t),e.vy*=Math.pow(i,t)}if(a.isSuspicion){const i=.001*Date.now();e.vx+=.01*Math.sin(2*i+e.id)*t}if(a.isGlitch){a.age+=.016*t,a.glitchPhase+=a.glitchFrequency*t;const i=Math.sin(a.glitchPhase)*a.glitchIntensity*t,n=Math.cos(1.3*a.glitchPhase)*a.glitchIntensity*t;if(e.vx+=i,e.vy+=n,Math.random()<.02){const t=Math.random()*Math.PI*2,i=.5+.5*Math.random();e.vx+=Math.cos(t)*i,e.vy+=Math.sin(t)*i}}}},Ot={name:"aggressive",emoji:"⚡",description:"Sharp, chaotic movement with violent bursts",initialize:function(e){const t=Math.random()*Pt,i=1.5+2*Math.random();e.vx=Math.cos(t)*i,e.vy=Math.sin(t)*i,e.lifeDecay=.015,e.emotionColors&&e.emotionColors.length>0&&(e.color=Ct(e.emotionColors)),e.behaviorData={acceleration:.05,jitter:.3,speedDecay:.95}},update:function(e,t,i,n){const a=e.behaviorData;if(e.vx+=(Math.random()-.5)*a.jitter*t,e.vy+=(Math.random()-.5)*a.jitter*t,e.vx*=Math.pow(a.speedDecay,t),e.vy*=Math.pow(a.speedDecay,t),Math.random()<Math.min(.05*t,.5)){const t=Math.random()*Pt;e.vx+=Math.cos(t)*a.acceleration,e.vy+=Math.sin(t)*a.acceleration}}},Ft={name:"scattering",emoji:"😨",description:"Particles flee from center in panic",initialize:function(e){e.vx=0,e.vy=0,e.lifeDecay=.008,e.emotionColors&&e.emotionColors.length>0&&(e.color=Ct(e.emotionColors)),e.behaviorData={fleeSpeed:2,panicFactor:1.2,initialized:!1}},update:function(e,t,i,n){const a=e.behaviorData;if(!a.initialized){const t=e.x-i,s=e.y-n,o=Math.sqrt(t*t+s*s);if(o>0)e.vx=t/o*a.fleeSpeed,e.vy=s/o*a.fleeSpeed;else{const t=Math.random()*Pt;e.vx=Math.cos(t)*a.fleeSpeed,e.vy=Math.sin(t)*a.fleeSpeed}a.initialized=!0}const s=e.x-i,o=e.y-n,r=Math.sqrt(s*s+o*o);r>0&&(e.vx+=s/r*a.panicFactor*.01*t,e.vy+=o/r*a.panicFactor*.01*t),e.vx+=.1*(Math.random()-.5)*t,e.vy+=.1*(Math.random()-.5)*t,e.vx*=Math.pow(.98,t),e.vy*=Math.pow(.98,t)}},Lt={name:"repelling",emoji:"🚫",description:"Particles pushed away from center, maintaining distance",initialize:function(e){e.vx=0,e.vy=0,e.lifeDecay=.01,e.emotionColors&&e.emotionColors.length>0&&(e.color=Ct(e.emotionColors)),e.behaviorData={repelStrength:.8,minDistance:50,initialized:!1}},update:function(e,t,i,n){const a=e.behaviorData,s=e.x-i,o=e.y-n,r=Math.sqrt(s*s+o*o);if(!a.initialized||r<a.minDistance){if(r>0){const i=a.repelStrength/Math.max(r,5);e.vx+=s/r*i*t,e.vy+=o/r*i*t}a.initialized=!0}e.vx*=Math.pow(.99,t),e.vy*=Math.pow(.99,t)}},Gt={name:"connecting",emoji:"🔗",description:"Chaotic movement with center attraction for social states",initialize:function(e){const t=Math.random()*Pt,i=2+5*Math.random();e.vx=Math.cos(t)*i,e.vy=Math.sin(t)*i,e.lifeDecay=.012,e.emotionColors&&e.emotionColors.length>0&&(e.color=Ct(e.emotionColors)),e.behaviorData={attractionForce:.008,chaosFactor:1,friction:.95}},update:function(e,t,i,n){const a=e.behaviorData;e.vx*=Math.pow(a.friction,t),e.vy*=Math.pow(a.friction,t);const s=(i-e.x)*a.attractionForce,o=(n-e.y)*a.attractionForce,r=(Math.random()-.5)*a.chaosFactor,l=(Math.random()-.5)*a.chaosFactor;e.vx+=s+r,e.vy+=o+l}},Vt={name:"resting",emoji:"😴",description:"Ultra-slow vertical drift for deep rest states",initialize:function(e){e.vx=0,e.vy=-.01,e.lifeDecay=.001,e.emotionColors&&e.emotionColors.length>0&&(e.color=Ct(e.emotionColors)),e.behaviorData={upwardSpeed:2e-5,friction:.999}},update:function(e,t,i,n){const a=e.behaviorData;e.vy*=Math.pow(a.friction,t),e.vy-=a.upwardSpeed*t,e.vx=0}},qt={name:"radiant",emoji:"☀️",description:"Particles radiate outward like sunbeams",initialize:function(e){const t=Math.random()*Pt,i=.8+.4*Math.random();if(e.vx=Math.cos(t)*i,e.vy=Math.sin(t)*i,e.lifeDecay=.006,e.emotionColors&&e.emotionColors.length>0)e.color=Ct(e.emotionColors);else{const t=["#FFD700","#FFB347","#FFA500","#FF69B4"];e.color=Ct(t)}e.hasGlow=Math.random()<.7,e.glowSizeMultiplier=e.hasGlow?1.5+.5*Math.random():0,e.behaviorData={radialSpeed:.02,shimmer:Math.random()*Pt,shimmerSpeed:.1,friction:.99}},update:function(e,t,i,n){const a=e.behaviorData,s=e.x-i,o=e.y-n,r=Math.sqrt(s*s+o*o);if(r>0){const i=s/r,n=o/r;e.vx+=i*a.radialSpeed*t,e.vy+=n*a.radialSpeed*t}a.shimmer+=a.shimmerSpeed*t;const l=Math.sin(a.shimmer);e.size=e.baseSize*(1+.2*l),e.opacity=e.baseOpacity*(1+.3*l),e.vx*=Math.pow(a.friction,t),e.vy*=Math.pow(a.friction,t)}};function Nt(e){e.vx=.02*(Math.random()-.5),e.vy=-.03-.02*Math.random(),e.lifeDecay=8e-4,e.size=(6+6*Math.random())*(e.scaleFactor||1)*(e.particleSizeMultiplier||1)*1.33,e.baseSize=e.size,e.baseOpacity=.2+.2*Math.random(),e.emotionColors&&e.emotionColors.length>0&&(e.color=Ct(e.emotionColors)),e.behaviorData={ascensionSpeed:3e-4,waveFactor:.5,waveFrequency:.001,friction:.998,fadeStartDistance:100}}var jt={name:"ascending",emoji:"🧘",description:"Slow steady upward float like incense smoke",initialize:Nt,update:function(e,t,i,n){const a=e.behaviorData;if(!a)return void Nt(e);e.vx*=Math.pow(a.friction,t),e.vy*=Math.pow(a.friction,t),e.vy-=a.ascensionSpeed*t;const s=Math.sin(e.age*a.waveFrequency*1e3)*a.waveFactor;e.vx+=.001*s*t,void 0===e.initialY&&(e.initialY=e.y);const o=e.initialY-e.y;if(o>a.fadeStartDistance){const t=(o-a.fadeStartDistance)/100,i=Math.max(0,1-t);e.baseOpacity*=.995,i<.5&&(e.lifeDecay*=1.02)}Math.abs(e.vx)>.05&&(e.vx*=Math.pow(.95,t)),e.vy<-.1&&(e.vy=-.1)}},Ut={name:"erratic",emoji:"😰",description:"Nervous jittery movement for anxious states",initialize:function(e){const t=Math.random()*Pt,i=.1+.15*Math.random();e.vx=Math.cos(t)*i,e.vy=Math.sin(t)*i,e.lifeDecay=.004,e.size=(2+4*Math.random())*(e.scaleFactor||1)*(e.particleSizeMultiplier||1),e.baseSize=e.size,e.baseOpacity=.4+.3*Math.random(),e.emotionColors&&e.emotionColors.length>0&&(e.color=Ct(e.emotionColors)),e.behaviorData={jitterStrength:.02,directionChangeRate:.1,speedVariation:.3,spinRate:.05+.1*Math.random()}},update:function(e,t){const i=e.behaviorData;if(e.vx+=(Math.random()-.5)*i.jitterStrength*t,e.vy+=(Math.random()-.5)*i.jitterStrength*t,Math.random()<Math.min(i.directionChangeRate*t,.5)){const t=Math.random()*Pt,i=Math.sqrt(e.vx*e.vx+e.vy*e.vy);e.vx=Math.cos(t)*i,e.vy=Math.sin(t)*i}const n=1+(Math.random()-.5)*i.speedVariation*t;e.vx*=n,e.vy*=n;const a=e.age*i.spinRate*1e3;e.size=e.baseSize*(1+.2*Math.sin(a)),e.opacity=e.baseOpacity*(.8+.4*Math.random()),e.vx*=Math.pow(.98,t),e.vy*=Math.pow(.98,t);const s=Math.sqrt(e.vx*e.vx+e.vy*e.vy);s>.5&&(e.vx=e.vx/s*.5,e.vy=e.vy/s*.5)}},Ht={name:"cautious",emoji:"🤨",description:"Slow careful movement with watchful pauses",initialize:function(e){const t=Math.random()*Pt,i=.02+.03*Math.random();e.vx=Math.cos(t)*i,e.vy=Math.sin(t)*i,e.lifeDecay=.001,e.life=1,e.size=(4+4*Math.random())*(e.scaleFactor||1)*(e.particleSizeMultiplier||1),e.baseSize=e.size,e.baseOpacity=.8+.2*Math.random(),e.opacity=e.baseOpacity,e.emotionColors&&e.emotionColors.length>0&&(e.color=Ct(e.emotionColors)),e.behaviorData={pauseTimer:2*Math.random(),pauseDuration:.5+.5*Math.random(),moveDuration:1+.5*Math.random(),isMoving:Math.random()>.5,moveTimer:0,originalVx:e.vx,originalVy:e.vy,watchRadius:50+30*Math.random()}},update:function(e,t,i,n){const a=e.behaviorData;if(a.moveTimer+=t,a.isMoving)a.moveTimer>a.moveDuration?(a.isMoving=!1,a.moveTimer=0,e.vx=0,e.vy=0):(e.vx=a.originalVx,e.vy=a.originalVy);else if(a.moveTimer>a.pauseDuration){a.isMoving=!0,a.moveTimer=0;const t=Math.random()*Pt,i=.02+.03*Math.random();e.vx=Math.cos(t)*i,e.vy=Math.sin(t)*i,a.originalVx=e.vx,a.originalVy=e.vy}const s=e.x-i,o=e.y-n,r=Math.sqrt(s*s+o*o);if(r>a.watchRadius){const i=.02;e.vx-=s/r*i*t,e.vy-=o/r*i*t}e.vx*=Math.pow(.995,t),e.vy*=Math.pow(.995,t),a.isMoving?e.opacity=e.baseOpacity:e.opacity=e.baseOpacity*(.9+.1*Math.sin(5*e.age))}},Wt={name:"surveillance",emoji:"👁️",description:"Searchlight scanning with paranoid watchfulness",initialize(e,t){e.emotionColors&&e.emotionColors.length>0&&(e.color=Ct(e.emotionColors)),e.behaviorState={scanAngle:Math.random()*Math.PI-Math.PI/2,scanDirection:Math.random()<.5?1:-1,scanSpeed:.3+.2*Math.random(),scanRange:Math.PI/3+Math.random()*Math.PI/4,scanCenter:Math.random()*Math.PI*2,pauseTimer:0,pauseDuration:500+500*Math.random(),mode:"scanning",modeTimer:0,nextModeChange:2e3+3e3*Math.random(),dartTarget:{x:0,y:0},dartSpeed:0,patrolRadius:150+100*Math.random(),patrolAngle:Math.random()*Math.PI*2,alertLevel:0,lastPosition:{x:e.x,y:e.y}};const i=Math.random();i<.7?e.behaviorState.primaryRole="scanner":i<.9?(e.behaviorState.primaryRole="patroller",e.behaviorState.mode="patrolling"):(e.behaviorState.primaryRole="watcher",e.behaviorState.mode="frozen")},update(e,t,i){const n=e.behaviorState;if(n){switch(n.modeTimer+=16*t,n.modeTimer>n.nextModeChange&&(this.changeMode(e,n,i),n.modeTimer=0,n.nextModeChange=2e3+4e3*Math.random()),n.mode){case"scanning":this.updateScanning(e,t,n,i);break;case"darting":this.updateDarting(e,t,n,i);break;case"frozen":this.updateFrozen(e,t,n,i);break;case"patrolling":this.updatePatrolling(e,t,n,i)}e.vy+=.05*t,e.x+=e.vx*t,e.y+=e.vy*t,n.lastPosition.x=e.x,n.lastPosition.y=e.y}},updateScanning(e,t,i,n){i.pauseTimer>0?(i.pauseTimer-=16*t,e.vx*=.9,e.vy*=.9):(i.scanAngle+=i.scanDirection*i.scanSpeed*t*.02,Math.abs(i.scanAngle)>i.scanRange/2&&(i.scanDirection*=-1,i.pauseTimer=i.pauseDuration,i.scanAngle=Math.sign(i.scanAngle)*i.scanRange/2));const a=i.scanCenter+i.scanAngle,s=.8+.5*i.alertLevel;e.vx=Math.cos(a)*s,e.vy=Math.sin(a)*s*.3},updateDarting(e,t,i,n){const a=i.dartTarget.x-e.x,s=i.dartTarget.y-e.y,o=Math.sqrt(a*a+s*s);o>5?(e.vx=a/o*i.dartSpeed,e.vy=s/o*i.dartSpeed):(i.mode="scanning",i.modeTimer=0)},updateFrozen(e,t,i,n){e.vx*=.95,e.vy*=.95,Math.random()<.01&&(e.vx+=.5*(Math.random()-.5),e.vy+=.5*(Math.random()-.5))},updatePatrolling(e,t,i,n){i.patrolAngle+=.01*t;const a=n.corePosition?.x??n.canvasWidth/2,s=n.corePosition?.y??n.canvasHeight/2,o=a+Math.cos(i.patrolAngle)*i.patrolRadius,r=s+Math.sin(i.patrolAngle)*i.patrolRadius,l=o-e.x,h=r-e.y;e.vx=.02*l,e.vy=.02*h},changeMode(e,t,i){const n=Math.random(),a=i?.corePosition?.x??(i?.canvasWidth/2||e.x),s=i?.corePosition?.y??(i?.canvasHeight/2||e.y);"scanner"===t.primaryRole?n<.1?(t.mode="darting",t.dartTarget={x:a+200*(Math.random()-.5),y:s+200*(Math.random()-.5)},t.dartSpeed=3+2*Math.random()):t.mode=n<.2?"frozen":"scanning":"patroller"===t.primaryRole?t.mode=n<.1?"frozen":"patrolling":t.mode=n<.3?"scanning":"frozen"}},Xt={name:"glitchy",emoji:"⚡",description:"Digital glitch with stuttering orbits and corruption",rhythm:{enabled:!0,glitchTiming:{mode:"subdivision",subdivision:"sixteenth",probability:.3,intensityOnBeat:2,intensityOffBeat:.5},stutterSync:{mode:"pattern",patterns:{dubstep:{freezeOnDrop:!0,dropDuration:100},breakbeat:{randomFreeze:.1,duration:50}}},orbitRhythm:{baseSpeed:"tempo",wobbleSync:"eighth",beatAcceleration:1.5,barReset:!0},rgbSync:{enabled:!0,amount:"intensity",direction:"beat",maxSplit:10},noiseRhythm:{trigger:"accent",duration:50,intensity:"drop"}},initialize(e,t,i,n){e.emotionColors&&e.emotionColors.length>0&&(e.color=Ct(e.emotionColors)),e.behaviorState={orbitAngle:Math.random()*Math.PI*2,orbitRadius:300+400*Math.random(),orbitSpeed:.01+.02*Math.random(),glitchTimer:0,nextGlitch:500*Math.random()+100,isGlitching:!1,glitchDuration:0,glitchOffset:{x:0,y:0},stutterTimer:0,nextStutter:200*Math.random()+50,isFrozen:!1,frozenPosition:{x:0,y:0},frozenVelocity:{x:0,y:0},hasGhost:Math.random()<.3,ghostOffset:20*Math.random()+10,ghostAngle:Math.random()*Math.PI*2,rgbSplit:Math.random()<.4,rgbPhase:Math.random()*Math.PI*2,noiseLevel:0,noiseBurst:!1,beatPhase:Math.random()*Math.PI*2,beatFrequency:.05+.03*Math.random(),dropIntensity:0},e.lifeDecay=.0015,e.hasGlow=!0,e.glowSizeMultiplier=3+2*Math.random()},update(e,t,i,n){const a=e.behaviorState;if(!a)return;a.glitchTimer+=16*t,a.stutterTimer+=16*t,a.stutterTimer>a.nextStutter&&(a.isFrozen?(a.isFrozen=!1,a.stutterTimer=0,a.nextStutter=100+300*Math.random(),Math.random()<.3&&(e.x+=60*(Math.random()-.5),e.y+=60*(Math.random()-.5))):(a.isFrozen=!0,a.frozenPosition={x:e.x,y:e.y},a.frozenVelocity={x:e.vx,y:e.vy},a.stutterTimer=0,a.nextStutter=20+40*Math.random())),a.glitchTimer>a.nextGlitch&&!a.isGlitching&&(a.isGlitching=!0,a.glitchDuration=50+100*Math.random(),a.glitchOffset={x:80*(Math.random()-.5),y:80*(Math.random()-.5)},a.glitchTimer=0,Math.random()<.5&&e.emotionColors&&(e.color=Ct(e.emotionColors))),a.isGlitching&&a.glitchTimer>a.glitchDuration&&(a.isGlitching=!1,a.glitchTimer=0,a.nextGlitch=200+800*Math.random(),a.glitchOffset={x:0,y:0}),a.beatPhase+=a.beatFrequency*t;const s=.5*Math.sin(a.beatPhase)+.5;if(a.beatPhase%(4*Math.PI)<.5*Math.PI?a.dropIntensity=Math.min(1,a.dropIntensity+.1*t):a.dropIntensity=Math.max(0,a.dropIntensity-.05*t),a.isFrozen)e.vx=.5*(Math.random()-.5),e.vy=.5*(Math.random()-.5);else{a.orbitAngle+=a.orbitSpeed*t*(1+.5*s);const o=a.orbitRadius*(1+.3*a.dropIntensity*Math.sin(4*a.beatPhase));let r=i+Math.cos(a.orbitAngle)*o,l=n+Math.sin(a.orbitAngle)*o*.6;if(a.isGlitching&&(r+=a.glitchOffset.x*Math.random()*.8,l+=a.glitchOffset.y*Math.random()*.8),a.rgbSplit){const e=3*(1+a.dropIntensity);r+=Math.sin(a.rgbPhase)*e,l+=Math.cos(a.rgbPhase)*e,a.rgbPhase+=.1*t}a.dropIntensity>.8&&Math.random()<.1&&(r+=30*(Math.random()-.5),l+=30*(Math.random()-.5));const h=a.isGlitching?.02:.03;e.vx=(r-e.x)*h,e.vy=(l-e.y)*h,e.vx+=(Math.random()-.5)*s*2,e.vy+=(Math.random()-.5)*s*2}e.x+=e.vx*t,e.y+=e.vy*t,Math.random()<.02&&(e.opacity=.1+.9*Math.random()),e.size=e.baseSize*(1+.3*s+.5*a.dropIntensity)}},Yt={name:"spaz",description:"Ultra-aggressive particles with explosive spread and chaotic motion",initialize(e,t,i,n){e.x=i,e.y=n,e.life=1,e.size=3+4*Math.random();const a=Math.random()*Math.PI*2,s=200+300*Math.random();e.vx=Math.cos(a)*s,e.vy=Math.sin(a)*s,e.behaviorState={explosionPhase:0,explosionTimer:0,explosionDuration:1e3+2e3*Math.random(),chaosTimer:0,nextChaosChange:100+200*Math.random(),chaosAngle:a,chaosSpeed:50+100*Math.random(),spazIntensity:.8+.4*Math.random(),zigzagPattern:Math.random()<.5,spiralPattern:Math.random()<.3,teleportChance:.02,sizePulse:!0,sizePulseSpeed:.1+.05*Math.random(),sizePulsePhase:Math.random()*Math.PI*2,colorShift:Math.random()<.3,colorShiftSpeed:.05+.03*Math.random()},e.lifeDecay=8e-4,e.hasGlow=!0,e.glowSizeMultiplier=4+3*Math.random(),e.glowIntensity=1.5+.5*Math.random()},update(e,t,i,n){const a=e.behaviorState;if(a.explosionTimer+=t,a.chaosTimer+=t,0===a.explosionPhase&&a.explosionTimer<500)e.vx*=.98,e.vy*=.98,Math.random()<.1&&(e.vx+=100*(Math.random()-.5),e.vy+=100*(Math.random()-.5));else if(0===a.explosionPhase&&a.explosionTimer>=500)a.explosionPhase=1,a.chaosAngle=Math.random()*Math.PI*2,a.chaosSpeed=30+70*Math.random();else if(1===a.explosionPhase){a.chaosTimer>=a.nextChaosChange&&(a.chaosAngle=Math.random()*Math.PI*2,a.chaosSpeed=20+80*Math.random(),a.nextChaosChange=50+150*Math.random(),a.chaosTimer=0);const t=Math.cos(a.chaosAngle)*a.chaosSpeed,i=Math.sin(a.chaosAngle)*a.chaosSpeed;if(e.vx=.7*e.vx+.3*t,e.vy=.7*e.vy+.3*i,a.zigzagPattern){const t=.01*a.chaosTimer;e.vx+=20*Math.sin(t),e.vy+=20*Math.cos(t)}if(a.spiralPattern){const t=.005*a.chaosTimer,i=50+30*Math.sin(.003*a.chaosTimer);e.vx+=Math.cos(t)*i*.1,e.vy+=Math.sin(t)*i*.1}}if(Math.random()<a.teleportChance){const t=Math.random()*Math.PI*2,a=200+400*Math.random();e.x=i+Math.cos(t)*a,e.y=n+Math.sin(t)*a,e.vx=200*(Math.random()-.5),e.vy=200*(Math.random()-.5)}if(e.x+=e.vx*(t/1e3),e.y+=e.vy*(t/1e3),a.sizePulse){a.sizePulsePhase+=a.sizePulseSpeed*t;const i=1+.5*Math.sin(a.sizePulsePhase);e.size=(3+4*Math.random())*i}a.colorShift&&(a.colorShiftPhase=(a.colorShiftPhase||0)+a.colorShiftSpeed*t),e.vx*=.995,e.vy*=.995,e.life-=e.lifeDecay*t,(e.life<=0||Math.abs(e.x-i)>2e3||Math.abs(e.y-n)>2e3)&&(e.life=0)},getSpawnPosition(e,t){const i=Math.random()*Math.PI*2,n=100+200*Math.random();return{x:e+Math.cos(i)*n,y:t+Math.sin(i)*n}},getVisualProperties:()=>({glowColor:"#FF00AA",glowIntensity:2,particleColors:[{color:"#FF00AA",weight:30},{color:"#00FFAA",weight:25},{color:"#FFAA00",weight:20},{color:"#AA00FF",weight:15},{color:"#00AAFF",weight:10}]})},$t={name:"directed",emoji:"🎯",description:"Focused, straight-line movement toward target",config:{speed:3,acceleration:.15,focusStrength:.8,randomness:.1,edgeBuffer:50},initialize(e,t,i,n,a){const s=t-e.x,o=i-e.y,r=Math.sqrt(s*s+o*o);if(r>0)e.vx=s/r*this.config.speed,e.vy=o/r*this.config.speed;else{const t=Math.random()*Math.PI*2;e.vx=Math.cos(t)*this.config.speed,e.vy=Math.sin(t)*this.config.speed}e.targetX=t,e.targetY=i,e.directedPhase=0},update(e,t,i,n,a,s){e.directedPhase+=.05*t;const o=e.targetX-e.x,r=e.targetY-e.y,l=Math.sqrt(o*o+r*r);if(l>10){const i=o/l*this.config.speed,n=r/l*this.config.speed;e.vx+=(i-e.vx)*this.config.acceleration*t,e.vy+=(n-e.vy)*this.config.acceleration*t,e.vx+=(Math.random()-.5)*this.config.randomness,e.vy+=(Math.random()-.5)*this.config.randomness}else{const t=Math.random()*Math.PI*2,o=100+200*Math.random();e.targetX=i+Math.cos(t)*o,e.targetY=n+Math.sin(t)*o,e.targetX=Math.max(this.config.edgeBuffer,Math.min(a-this.config.edgeBuffer,e.targetX)),e.targetY=Math.max(this.config.edgeBuffer,Math.min(s-this.config.edgeBuffer,e.targetY))}e.x+=e.vx*t,e.y+=e.vy*t,(e.x<=0||e.x>=a)&&(e.vx*=-.8,e.x=Math.max(0,Math.min(a,e.x)),e.targetX=i+300*(Math.random()-.5)),(e.y<=0||e.y>=s)&&(e.vy*=-.8,e.y=Math.max(0,Math.min(s,e.y)),e.targetY=n+300*(Math.random()-.5))},visuals:{trailLength:"medium",opacity:.9,sizeMultiplier:1,blurAmount:.2}},Qt={name:"fizzy",emoji:"🫧",description:"Bubbly, effervescent movement like carbonation",config:{baseRiseSpeed:2.5,wobbleAmplitude:30,wobbleFrequency:.15,popChance:.002,popForce:8,fizziness:.3,gravity:-.05},initialize(e,t,i,n,a){e.vx=2*(Math.random()-.5),e.vy=-this.config.baseRiseSpeed-2*Math.random(),e.wobblePhase=Math.random()*Math.PI*2,e.wobbleSpeed=this.config.wobbleFrequency*(.8+.4*Math.random()),e.bubbleSize=.5+.5*Math.random(),e.popTimer=0,e.isFizzing=!0},update(e,t,i,n,a,s){e.wobblePhase+=e.wobbleSpeed*t;const o=Math.sin(e.wobblePhase)*this.config.wobbleAmplitude;if(e.vx=.05*o+(Math.random()-.5)*this.config.fizziness,e.vy+=this.config.gravity*t,e.vy+=(Math.random()-.5)*this.config.fizziness,Math.random()<this.config.popChance){const t=Math.random()*Math.PI*2;e.vx=Math.cos(t)*this.config.popForce,e.vy=Math.sin(t)*this.config.popForce*.7,e.popTimer=1,e.bubbleSize=.3+.7*Math.random()}e.popTimer>0&&(e.popTimer-=.05*t,e.vx*=.95,e.vy*=.95),e.x+=e.vx*t,e.y+=e.vy*t,e.y<-50&&(e.y=s+50,e.x=i+300*(Math.random()-.5),e.vy=-this.config.baseRiseSpeed-2*Math.random(),e.bubbleSize=.5+.5*Math.random()),(e.x<=0||e.x>=a)&&(e.vx*=-.5,e.x=Math.max(0,Math.min(a,e.x))),e.y>s+50&&(e.y=s,e.vy=1.5*-this.config.baseRiseSpeed),e.size=e.baseSize*e.bubbleSize*(1+.1*Math.sin(2*e.wobblePhase))},visuals:{trailLength:"short",opacity:.6,sizeMultiplier:1.2,blurAmount:.5,sparkle:!0}};var Zt={name:"zen",emoji:"☯️",description:"Peaceful orbital movement like a hovering aura",initialize:function(e){e.vx=.5*(Math.random()-.5),e.vy=.5*(Math.random()-.5),e.lifeDecay=.003,e.emotionColors&&e.emotionColors.length>0&&(e.color=Ct(e.emotionColors)),e.behaviorData={orbitAngle:Math.random()*Math.PI*2,orbitRadius:40+60*Math.random(),orbitSpeed:8e-4+6e-4*Math.random(),floatOffset:Math.random()*Math.PI*2,breathingOffset:Math.random()*Math.PI*2,lifetime:0}},update:function(e,t,i,n){const a=e.behaviorData;if(!a)return;a.lifetime+=t;const s=(a.lifetime+8e3*a.breathingOffset)/8e3,o=.5*Math.sin(s*Math.PI*2)+.5;e.size=e.baseSize*(.95+.05*o),a.orbitAngle+=a.orbitSpeed*t;const r=10*Math.sin(1e-4*a.lifetime+a.floatOffset),l=a.orbitRadius+r,h=i+Math.cos(a.orbitAngle)*l,c=n+Math.sin(a.orbitAngle)*l,u=15*Math.sin(3e-4*a.lifetime+a.breathingOffset),d=h-e.x,m=c+u-e.y;e.vx=.03*d,e.vy=.03*m,e.vx+=.02*(Math.random()-.5),e.vy+=.02*(Math.random()-.5),e.vx*=.98,e.vy*=.98}};const Jt=new Map;var Kt=function(e){return Jt.get(e)||null},ei=function(){return Array.from(Jt.keys())};const ti={};function ii(e){if(ti[e])return ti[e];return Kt(e)||null}function ni(e,t){const i=ii(t);return i&&i.initialize?(i.initialize(e),!0):"ambient"!==t&&(console.warn(`⚠️ Behavior '${t}' not found, falling back to ambient`),ni(e,"ambient"))}function ai(e,t,i,n,a){const s=ii(t);return!(!s||!s.update||(s.update(e,i,n,a),0))}[Dt,$t,Qt,Bt,kt,Tt,zt,_t,Ot,Ft,Lt,Gt,Vt,qt,jt,Ut,Ht,Wt,Xt,Yt,Zt].forEach(e=>{ti[e.name]=e}),"undefined"!=typeof window&&window.DEBUG_PARTICLES&&(window.ParticleBehaviors={registry:ti,list:function(){return[...Object.values(ti).map(e=>({name:e.name,emoji:e.emoji||"🎯",description:e.description||"No description",type:"core"})),...ei().map(e=>{const t=Kt(e);return{name:t.name,emoji:t.emoji||"🔌",description:t.description||"Plugin behavior",type:"plugin"}})]},get:ii});class si{constructor(e,t,i="ambient",n=1,a=1,s=null){const o=Math.random();this.z=o<1/13?.5+.5*Math.random():.9*Math.random()-1;const r=this.z>0?(20+20*Math.random())*n:3*n,l=Math.random()*Math.PI*2;this.x=e+Math.cos(l)*r,this.y=t+Math.sin(l)*r,this.vx=0,this.vy=0,this.vz=0,this.life=0,this.maxLife=1,this.lifeDecay=.01,this.fadeInTime=.15,this.fadeOutTime=.3,this.isFadingOut=!1,this.age=0,this.scaleFactor=n,this.particleSizeMultiplier=a,this.size=(4+6*Math.random())*n*a,this.baseSize=this.size,this.emotionColors=s,this.color="#ffffff",this.opacity=1,this.hasGlow=Math.random()<.333,this.glowSizeMultiplier=this.hasGlow?1.33+.33*Math.random():0,this.isCellShaded=Math.random()<.333,this.baseOpacity=.3+.4*Math.random(),this.cachedColors=new Map,this.maxCachedColors=20,this.colorAccessOrder=[],this.lastColor=null,this.lastOpacity=-1,this.behavior=i,this.behaviorData={},this.gestureData={initialX:e,initialY:t},ni(this,i)}update(e,t,i,n=null,a=null,s=0,o=null){const r=Math.min(e,50)/16.67,l=a&&a.type&&s>0&&function(e){const t=ft(e);return!!t&&"override"===t.type}(a.type);let h,c;if(l?this.applyGestureMotion(a,s,r,t,i):"falling"===this.gestureBehavior?ai(this,"falling",r,t,i):"radiant"===this.gestureBehavior?ai(this,"radiant",r,t,i):(ai(this,this.behavior,r,t,i),a&&s>0&&this.applyGestureMotion(a,s,r,t,i)),l||(this.x+=this.vx*r,this.y+=this.vy*r),o)h=o.width,c=o.height;else{const e=document.getElementById("card-mascot")||document.getElementById("cherokee-guide-mascot")||document.querySelector("canvas");h=e?e.width:2*t,c=e?e.height:2*i}const u=t-h/2+20,d=t+h/2-20,m=i-c/2+20,p=i+c/2-20;this.x-this.size<u?(this.x=u+this.size,this.vx=.5*Math.abs(this.vx)):this.x+this.size>d&&(this.x=d-this.size,this.vx=.5*-Math.abs(this.vx)),this.y-this.size<m?(this.y=m+this.size,this.vy=.5*Math.abs(this.vy)):this.y+this.size>p&&(this.y=p-this.size,this.vy=.5*-Math.abs(this.vy)),this.age+=this.lifeDecay*r,this.age<this.fadeInTime?this.life=this.age/this.fadeInTime:this.age<1-this.fadeOutTime?this.life=1:(this.life=(1-this.age)/this.fadeOutTime,this.isFadingOut=!0,"popcorn"===this.behavior&&(this.size=this.baseSize*(.5+.5*this.life))),this.life=Math.max(0,Math.min(1,this.life)),"falling"===this.behavior?this.opacity=this.life:this.opacity=this.easeInOutCubic(this.life),"burst"===this.behavior&&this.behaviorData&&this.life<this.behaviorData.fadeStart&&(this.size=this.baseSize*(this.life/this.behaviorData.fadeStart))}applyUndertoneModifier(e,t){}applyGestureMotion(e,t,i,n,a){!function(e,t,i,n,a,s){if(!i||!i.type||n>=1)return;e.gestureData||(e.gestureData={originalVx:e.vx,originalVy:e.vy,initialX:e.x,initialY:e.y,startAngle:Math.atan2(e.y-s,e.x-a),startRadius:Math.sqrt(Math.pow(e.x-a,2)+Math.pow(e.y-s,2))});const o=ft(i.type);if(!o)return;let r=i;if(St.isEnabled()&&o.rhythm?.enabled){const a=St.applyGestureRhythm(o,e,n,t);r={...i,amplitude:(i.amplitude||1)*(a.amplitudeMultiplier||1)*(a.accentMultiplier||1),wobbleAmount:(i.wobbleAmount||0)*(a.wobbleMultiplier||1),rhythmModulation:a}}o.apply&&o.apply(e,n,r,t,a,s),n>=.99&&o.cleanup&&(o.cleanup(e),e.gestureData=null)}(this,i,e,t,n,a)}isOutOfBounds(e,t){return this.x<-50||this.x>e+50||this.y<-50||this.y>t+50}isAlive(){return this.life>0}setOutwardVelocity(e){if(this.behaviorData&&void 0!==this.behaviorData.outwardSpeed){const t=this.behaviorData.outwardSpeed;this.vx=Math.cos(e)*t,this.vy=Math.sin(e)*t+(this.behaviorData.upwardBias||0)}}getDepthAdjustedSize(){const e=1+.2*this.z;return this.size*e}getState(){return{position:{x:this.x,y:this.y,z:this.z},velocity:{x:this.vx,y:this.vy,z:this.vz},life:this.life,behavior:this.behavior,size:this.size,opacity:this.opacity}}reset(e,t,i="ambient",n=1,a=1,s=null){const o=Math.random();this.z=o<1/13?.5+.5*Math.random():.9*Math.random()-1;const r=this.z>0?(20+20*Math.random())*n:3*n,l=Math.random()*Math.PI*2;if(this.x=e+Math.cos(l)*r,this.y=t+Math.sin(l)*r,this.vx=0,this.vy=0,this.vz=0,this.life=0,this.age=0,this.scaleFactor=n,this.particleSizeMultiplier=a,this.size=(4+6*Math.random())*n*a,this.baseSize=this.size,this.emotionColors=s,this.cachedColors.clear(),this.colorAccessOrder=[],this.opacity=0,this.isFadingOut=!1,this.baseOpacity=.3+.4*Math.random(),this.color="#ffffff",this.behavior=i,this.gestureData=null,this.behaviorData)for(const e in this.behaviorData)delete this.behaviorData[e];else this.behaviorData={};ni(this,i)}getCachedColor(e,t){const i=Math.round(100*t)/100,n=`${e}_${i}`;if(this.cachedColors.has(n)){const e=this.colorAccessOrder.indexOf(n);-1!==e&&this.colorAccessOrder.splice(e,1),this.colorAccessOrder.push(n)}else{if(this.cachedColors.size>=this.maxCachedColors){const e=this.colorAccessOrder.shift();this.cachedColors.delete(e)}this.cachedColors.set(n,this.hexToRgba(e,i)),this.colorAccessOrder.push(n)}return this.cachedColors.get(n)}hexToRgba(e,t){const i=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return i?`rgba(${parseInt(i[1],16)}, ${parseInt(i[2],16)}, ${parseInt(i[3],16)}, ${t})`:`rgba(255, 255, 255, ${t})`}easeInOutCubic(e){return e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2}render(e,t="#ffffff"){if(this.life<=0)return;if(!isFinite(this.x)||!isFinite(this.y))return;const i=this.x,n=this.y,a=Math.max(.1,this.size),s=this.tempColor||this.color||t;if(e.save(),this.isCellShaded){e.strokeStyle=this.getCachedColor(s,.9*this.opacity),e.lineWidth=2,e.beginPath(),e.arc(i,n,a,0,2*Math.PI),e.stroke();const t=Math.floor(3*this.opacity)/3;e.fillStyle=this.getCachedColor(s,t*(this.baseOpacity||.5)*.5),e.beginPath(),e.arc(i,n,Math.max(.1,a-1),0,2*Math.PI),e.fill(),t>.5&&(e.fillStyle=this.getCachedColor("#FFFFFF",.3),e.beginPath(),e.arc(i-.3*a,n-.3*a,.3*a,0,2*Math.PI),e.fill())}else{const t=e.createRadialGradient(i,n,0,i,n,a);if(t.addColorStop(0,this.getCachedColor(s,this.opacity*(this.baseOpacity||.5))),t.addColorStop(.5,this.getCachedColor(s,this.opacity*(this.baseOpacity||.5)*.5)),t.addColorStop(1,this.getCachedColor(s,0)),e.fillStyle=t,e.beginPath(),e.arc(i,n,a,0,2*Math.PI),e.fill(),this.hasGlow&&this.glowSizeMultiplier>0){const t=a*this.glowSizeMultiplier,o=e.createRadialGradient(i,n,.5*a,i,n,t),r=.3,l=Math.max(r,this.opacity),h=Math.min(1,this.glowSizeMultiplier/3);o.addColorStop(0,this.getCachedColor(s,Math.max(.5,.8*l)*h)),o.addColorStop(.25,this.getCachedColor(s,Math.max(.3,.6*l)*h)),o.addColorStop(.5,this.getCachedColor(s,Math.max(.2,.4*l)*h)),o.addColorStop(.75,this.getCachedColor(s,Math.max(.1,.2*l)*h)),o.addColorStop(1,this.getCachedColor(s,0)),e.save(),e.globalCompositeOperation="screen",e.fillStyle=o,e.beginPath(),e.arc(i,n,t,0,2*Math.PI),e.fill(),e.restore()}}e.restore()}}class oi{constructor(e=50){this.poolSize=Math.min(e,50),this.pool=[],this.totalParticlesCreated=0,this.totalParticlesDestroyed=0,this.poolHits=0,this.poolMisses=0}getParticle(e,t,i,n,a,s,o,r=null){let l;return this.pool.length>0?(l=this.pool.pop(),l.reset(e,t,i,n,a,s),this.poolHits++):(l=new si(e,t,i,n,a,s),this.poolMisses++,this.totalParticlesCreated++),l.emotion=o,r&&(l.gestureBehavior=r),l}returnParticle(e){if(this.pool.length<this.poolSize){if(e.cachedGradient=null,e.cachedGradientKey=null,e.behaviorData)for(const t in e.behaviorData)delete e.behaviorData[t];this.pool.push(e)}else this.totalParticlesDestroyed++}refreshPool(){const e=this.pool.length-this.poolSize;e>0&&(this.pool.splice(this.poolSize),this.totalParticlesDestroyed+=e)}getStats(){return{poolSize:this.pool.length,poolHits:this.poolHits,poolMisses:this.poolMisses,totalCreated:this.totalParticlesCreated,totalDestroyed:this.totalParticlesDestroyed}}clear(){this.pool=[],this.poolHits=0,this.poolMisses=0,this.totalParticlesCreated=0,this.totalParticlesDestroyed=0}}class ri{constructor(){this.spawnAccumulator=0}getSpawnPosition(e,t,i,n,a,s=null){const o=Math.min(n,a)/12,r=2.5*o,l=1.1*r,h=Math.min(t-30,n-t-30),c=Math.min(i-30,a-i-30),u=Math.min(1.5*r,h,c);switch(e){case"ambient":case"resting":{const e=Math.random()*Math.PI*2,n=.9*r;return{x:t+Math.cos(e)*n,y:i+Math.sin(e)*n,angle:e}}case"rising":{const e=Math.random()*Math.PI*2,n=l+Math.random()*(u-l);return{x:t+Math.cos(e)*n,y:i+Math.sin(e)*n}}case"falling":{const e=Math.random()*Math.PI*2,n=.9*r;return{x:t+Math.cos(e)*n,y:i+Math.sin(e)*n,angle:e}}case"aggressive":{const e=Math.random()*Math.PI*2,n=r+Math.random()*o;return{x:t+Math.cos(e)*n,y:i+Math.sin(e)*n}}case"scattering":default:return{x:t,y:i};case"burst":{const e=Math.random()*Math.PI*2;if("suspicion"===s){const n=1.5*o;return{x:t+Math.cos(e)*n,y:i+Math.sin(e)*n}}if("surprise"===s){const n=1.2*o;return{x:t+Math.cos(e)*n,y:i+Math.sin(e)*n}}return{x:t,y:i}}case"repelling":{const e=Math.random()*Math.PI*2,n=.9*r;return{x:t+Math.cos(e)*n,y:i+Math.sin(e)*n}}case"orbiting":{const e=Math.random()*Math.PI*2,n=1.2*r+Math.random()*r*.5;return{x:t+Math.cos(e)*n,y:i+Math.sin(e)*n}}case"glitchy":{const e=Math.random()*Math.PI*2,n=3*r+Math.random()*r*4;return{x:t+Math.cos(e)*n,y:i+Math.sin(e)*n}}case"spaz":{const e=Math.random()*Math.PI*2,n=2*r+Math.random()*r*3;return{x:t+Math.cos(e)*n,y:i+Math.sin(e)*n}}}}clampToCanvas(e,t,i,n,a=30){return{x:Math.max(a,Math.min(i-a,e)),y:Math.max(a,Math.min(n-a,t))}}calculateSpawnRate(e,t){if(e<=0)return 0;const i=Math.min(t,50),n=e/1e3;this.spawnAccumulator+=n*i,this.spawnAccumulator=Math.min(this.spawnAccumulator,3);let a=0;for(;this.spawnAccumulator>=1;)a++,this.spawnAccumulator-=1;return a}resetAccumulator(){this.spawnAccumulator=0}}class li{render(e,t,i="#ffffff",n=null){const a=[];for(const e of t)e.life<=0||a.push(e);this._renderParticles(e,a,i,n)}renderLayer(e,t,i="#ffffff",n=!1,a=null){const s=[],o=e.canvas.width,r=e.canvas.height;for(const e of t)e.z>=0===n&&(e.x<-50||e.x>o+50||e.y<-50||e.y>r+50||e.life<=0||s.push(e));return s.sort((e,t)=>e.isCellShaded!==t.isCellShaded?e.isCellShaded?-1:1:e.hasGlow!==t.hasGlow?e.hasGlow?-1:1:0),this._renderParticles(e,s,i,a),s}_renderParticles(e,t,i,n=null){e.save();let a=null;for(const s of t)if(s.isCellShaded)s.render(e,i),a=null;else{const t=s.color||i;if(t!==a&&(e.fillStyle=t,a=t),!isFinite(s.x)||!isFinite(s.y))continue;const o=s.getDepthAdjustedSize?s.getDepthAdjustedSize():s.size;let r=Math.max(.1,o),l=1;if(n&&n.fireflyEffect){const e=(.01*s.x+.01*s.y+.1*s.size)%(2*Math.PI),t=n.fireflyTime||.001*Date.now(),i=n.particleGlow||2;l=.3+Math.max(0,Math.sin(3*t+e))*i}if(n&&n.flickerEffect){const e=(.02*s.x+.02*s.y)%(2*Math.PI),t=n.flickerTime||.001*Date.now(),i=n.particleGlow||2;l=.5+Math.sin(12*t+e)*i*.5}if(n&&n.shimmerEffect){const t=s.x-e.canvas.width/2,i=s.y-e.canvas.height/2,a=Math.sqrt(t*t+i*i)/200,o=n.shimmerTime||.001*Date.now(),r=n.shimmerWave||0,h=n.particleGlow||1.2;l=1+.15*Math.sin(3*o-a+r)*h}if(n&&n.glowEffect){const t=n.glowProgress||0,i=n.particleGlow||2,a=s.x-e.canvas.width/2,o=s.y-e.canvas.height/2,l=Math.sqrt(a*a+o*o)/300,h=Math.min(.3*l,.5),c=Math.max(0,(t-h)/(1-h)),u=Math.sin(c*Math.PI);s._originalGlow||(s._originalGlow={hasGlow:s.hasGlow,glowSizeMultiplier:s.glowSizeMultiplier||0}),s.hasGlow=!0,s.glowSizeMultiplier=Math.max(3,s._originalGlow.glowSizeMultiplier)+u*i*3,r*=1+.3*u,t>=.99&&s._originalGlow&&(s.hasGlow=s._originalGlow.hasGlow,s.glowSizeMultiplier=s._originalGlow.glowSizeMultiplier,delete s._originalGlow)}if(s.hasGlow||l>1){const t=Math.max(.1,r*(s.glowSizeMultiplier||1.5)*l),i=e.globalCompositeOperation;e.globalCompositeOperation="screen",e.globalAlpha=.15*s.opacity*l,e.beginPath(),e.arc(s.x,s.y,t,0,2*Math.PI),e.fill(),e.globalAlpha=.25*s.opacity*l,e.beginPath(),e.arc(s.x,s.y,.6*t,0,2*Math.PI),e.fill(),e.globalCompositeOperation=i}e.globalAlpha=s.opacity*(s.baseOpacity||.5)*.6*Math.min(2,l),e.beginPath(),e.arc(s.x,s.y,r,0,2*Math.PI),e.fill()}e.restore()}}class hi{constructor(e=50,t=null){this.errorBoundary=t,this.maxParticles=e,this.absoluteMaxParticles=2*e,this.particles=[],this.particlePool=new oi(e),this.particleSpawner=new ri,this.particleRenderer=new li,this.containmentBounds=null,this.stateChangeCount=0,this.lastMemoryCheck=Date.now(),this.lastLeakedCount=0,this.particleCount=0,this.cleanupTimer=0,this.cleanupInterval=5e3}get pool(){return this.particlePool.pool}get poolSize(){return this.particlePool.poolSize}get poolHits(){return this.particlePool.poolHits}get poolMisses(){return this.particlePool.poolMisses}get totalParticlesCreated(){return this.particlePool.totalParticlesCreated}get totalParticlesDestroyed(){return this.particlePool.totalParticlesDestroyed}get spawnAccumulator(){return this.particleSpawner.spawnAccumulator}set spawnAccumulator(e){this.particleSpawner.spawnAccumulator=e}getParticleFromPool(e,t,i){return this.particlePool.getParticle(e,t,i,this.scaleFactor||1,this.particleSizeMultiplier||1,this.currentEmotionColors,this.currentEmotion,this.gestureBehavior)}returnParticleToPool(e){this.particlePool.returnParticle(e)}spawn(e,t,i,n,a,s,o=null,r=0,l=10,h=1,c=1,u=null,d=null){if(this.scaleFactor=h,this.particleSizeMultiplier=c,this.errorBoundary)return this.errorBoundary.wrap(()=>{this._spawn(e,t,i,n,a,s,o,r,l,u,d)},"particle-spawn")();this._spawn(e,t,i,n,a,s,o,r,l,u,d)}resetAccumulator(){this.particleSpawner.resetAccumulator()}_spawn(e,t,i,n,a,s,o,r=0,l=10,h=null,c=null){this.currentEmotion=t,this.baseEmotionColors=h,this.currentUndertone=c,this.currentEmotionColors=h&&c?function(e,t){return e&&Array.isArray(e)&&t&&"clear"!==t?e.map(e=>"string"==typeof e?Mt(e,t):e&&"object"==typeof e&&e.color?{...e,color:Mt(e.color,t)}:e):e}(h,c):h;let u=i;if(St.isEnabled()){const i=xt&&xt.isInitialized?xt.getEmotion(t):me(t);if(i){const t=St.applyParticleRhythm(i,this);if(t.emitBurst)for(let i=0;i<t.emitBurst&&this.particles.length<l;i++)this.spawnSingleParticle(e,n,a);void 0!==t.emissionRate&&(u*=t.emissionRate)}}if(null!==o){for(let t=0;t<o&&this.particles.length<this.maxParticles;t++)this.spawnSingleParticle(e,n,a);return}if(this.skipSpawnThisFrame)return;for(;this.particles.length<r&&this.particles.length<this.maxParticles;)this.spawnSingleParticle(e,n,a);if(this.particles.length>=l)return;if(u<=0)return;const d=this.particleSpawner.calculateSpawnRate(u,s);for(let t=0;t<d&&this.particles.length<l;t++)this.spawnSingleParticle(e,n,a)}getSpawnPosition(e,t,i,n,a){return this.particleSpawner.getSpawnPosition(e,t,i,n,a,this.currentEmotion)}clampToCanvas(e,t,i,n,a=30){return this.particleSpawner.clampToCanvas(e,t,i,n,a)}spawnSingleParticle(e,t,i){if(this.particles.length>=this.absoluteMaxParticles)return;const n=this.canvasWidth||2*t,a=this.canvasHeight||2*i,s=this.particleSpawner.getSpawnPosition(e,t,i,n,a,this.currentEmotion),o=this.particleSpawner.clampToCanvas(s.x,s.y,n,a);s.x=o.x,s.y=o.y;const r=this.getParticleFromPool(s.x,s.y,e);"meditation_swirl"===e&&s.palmCenter&&(r.palmCenter=s.palmCenter,r.swirlAngle=s.swirlAngle),this.particles.push(r),this.particleCount++}update(e,t,i,n=null,a=0,s=null){if(this.errorBoundary)return this.errorBoundary.wrap((e,t,i,n,a,s)=>this._update(e,t,i,n,a,s),"particle-update")(e,t,i,n,a,s);this._update(e,t,i,n,a,s)}_update(e,t,i,n=null,a=0,s=null){for(this.particles=this.particles.filter(o=>(o.update(e,t,i,s,n,a,this.containmentBounds),o.isAlive()));this.particles.length>this.maxParticles;)this.removeParticle(0)}setGestureBehavior(e,t){this.gestureBehavior=t?e:null,t?this.particles.forEach(t=>{t.gestureBehavior=e}):this.particles.forEach(e=>{e.gestureBehavior=null})}removeParticle(e){if(e>=0&&e<this.particles.length){const t=this.particles.splice(e,1)[0];t.cachedGradient=null,t.cachedGradientKey=null,this.returnParticleToPool(t),this.particleCount=Math.max(0,this.particleCount-1)}}render(e,t="#ffffff",i=null){if(this.errorBoundary)return this.errorBoundary.wrap(()=>{this._render(e,t,i)},"particle-render")();this._render(e,t,i)}renderBackground(e,t="#ffffff",i=null){if(this.errorBoundary)return this.errorBoundary.wrap(()=>{this._renderLayer(e,t,!1,i)},"particle-render-bg")();this._renderLayer(e,t,!1,i)}renderForeground(e,t="#ffffff",i=null){if(this.errorBoundary)return this.errorBoundary.wrap(()=>{this._renderLayer(e,t,!0,i)},"particle-render-fg")();this._renderLayer(e,t,!0,i)}_renderLayer(e,t,i,n=null){this.particleRenderer.renderLayer(e,this.particles,t,i,n)}_render(e,t,i=null){this.particleRenderer.render(e,this.particles,t,i)}clear(){for(this.stateChangeCount++;this.particles.length>0;){const e=this.particles.pop();if(e.cachedColors&&e.cachedColors.clear(),e.behaviorData)for(const t in e.behaviorData)delete e.behaviorData[t];this.pool.length<this.poolSize&&!this.pool.includes(e)&&this.pool.push(e)}if(this.particles.length=0,this.particleCount=0,this.spawnAccumulator=0,this.pool.length>this.poolSize){const e=this.pool.length-this.poolSize;this.pool.splice(this.poolSize,e)}}burst(e,t,i,n){if(this.errorBoundary)return this.errorBoundary.wrap(()=>{this._burst(e,t,i,n)},"particle-burst")();this._burst(e,t,i,n)}_burst(e,t,i,n){const a=Math.min(e,this.maxParticles-this.particles.length);for(let e=0;e<a;e++)this.spawnSingleParticle(t,i,n)}performCleanup(){if(this.pool.length>this.poolSize){const e=this.pool.length-this.poolSize;for(let t=0;t<e;t++){const e=this.pool.pop();e&&(e.cachedGradient=null,e.cachedGradientKey=null,e.behaviorData=null)}}for(const e of this.particles)e.cachedGradient&&e.life<.5&&(e.cachedGradient=null,e.cachedGradientKey=null)}getStats(){return{activeParticles:this.particles.length,maxParticles:this.maxParticles,poolSize:this.pool.length,poolHits:this.poolHits,poolMisses:this.poolMisses,poolEfficiency:this.poolHits/Math.max(1,this.poolHits+this.poolMisses),spawnAccumulator:this.spawnAccumulator}}setMaxParticles(e){for(this.originalMaxParticles=this.originalMaxParticles||this.maxParticles,this.maxParticles=Math.max(1,e);this.particles.length>this.maxParticles;)this.removeParticle(0)}cleanupDeadParticles(){const e=this.particles.length;this.particles=this.particles.filter(e=>e.isAlive());const t=e-this.particles.length;return this.pool.length>20&&(this.pool.length=20),t}getParticlesByBehavior(e){return this.particles.filter(t=>t.behavior===e)}validateParticles(){for(const e of this.particles)if(!e.isAlive()||e.life<0||e.life>1)return!1;return!0}cleanup(){for(let e=this.particles.length-1;e>=0;e--)this.particles[e].isAlive()||this.removeParticle(e)}refreshPool(){this.particlePool.clear();for(const e of this.particles)e.life=0}setContainmentBounds(e){this.containmentBounds=e}destroy(){this.clear(),this.particlePool.clear()}}class ci{constructor(t={}){this.worldScale=t.worldScale||.2,this.baseRadius=t.baseRadius||.15,this.depthScale=t.depthScale||.75,this.verticalScale=t.verticalScale||1,this.coreRadius3D=t.coreRadius3D||1,this.tempVec3=new e.Vector3,this.tempVec3_2=new e.Vector3,this.behaviorTranslators=this._initBehaviorTranslators(),this.currentGestureData=null}setCoreRadius3D(e){this.coreRadius3D=e}updateRotationState(e,t,i=null){this.rotationState=e,this.deltaTime=t,this.currentGestureData=i}_initBehaviorTranslators(){return{ambient:this._translateAmbient.bind(this),orbiting:this._translateOrbiting.bind(this),rising:this._translateRising.bind(this),falling:this._translateFalling.bind(this),popcorn:this._translatePopcorn.bind(this),burst:this._translateBurst.bind(this),aggressive:this._translateAggressive.bind(this),scattering:this._translateScattering.bind(this),repelling:this._translateRepelling.bind(this),connecting:this._translateConnecting.bind(this),resting:this._translateResting.bind(this),radiant:this._translateRadiant.bind(this),ascending:this._translateAscending.bind(this),erratic:this._translateErratic.bind(this),cautious:this._translateCautious.bind(this),surveillance:this._translateSurveillance.bind(this),glitchy:this._translateGlitchy.bind(this),spaz:this._translateSpaz.bind(this),directed:this._translateDirected.bind(this),fizzy:this._translateFizzy.bind(this),zen:this._translateZen.bind(this),gravitationalAccretion:this._translateGravitationalAccretion.bind(this)}}translate2DTo3D(e,t,i){const n=(this.behaviorTranslators[e.behavior]||this._translateDefault.bind(this))(e,t,i);return this.currentGestureData&&"spin"===this.currentGestureData.gestureName?this._applySpinRotation(n,t,this.currentGestureData.progress):n}_applySpinRotation(e,t,i){const n=e.x-t.x,a=e.y-t.y,s=e.z-t.z,o=Math.sin(i*Math.PI)*Math.PI*2,r=Math.cos(o),l=Math.sin(o),h=n*r-s*l,c=n*l+s*r;return this.tempVec3.set(t.x+h,t.y+a,t.z+c)}_canvasToWorld(e,t,i,n,a,s){const o=(e-n)/n,r=-(t-a)/a,l=1+i*this.depthScale,h=o*this.worldScale*l+s.x,c=r*this.worldScale*this.verticalScale*l+s.y,u=i*this.worldScale*.5+s.z;return this.tempVec3.set(h,c,u)}_hash(e){const t=43758.5453123*Math.sin(e);return t-Math.floor(t)}_getUniformDirection3D(e){const t=e.behaviorData||{};if(t.direction3D)return t.direction3D;const i=127.1*e.x+311.7*e.y+74.7*(e.vx||0)+159.3*(e.vy||0),n=this._hash(i),a=this._hash(i+1),s=n*Math.PI*2,o=2*a-1,r=Math.sqrt(1-o*o),l=r*Math.cos(s),h=o,c=r*Math.sin(s);return t.direction3D={x:l,y:h,z:c},t.direction3D}_toSpherical(e,t,i,n){const a=e-n.x,s=t-n.y,o=i-n.z,r=Math.sqrt(a*a+s*s+o*o);return{radius:r,theta:Math.atan2(o,a),phi:Math.acos(s/(r||1))}}_toCartesian(e,t,i,n){const a=e*Math.sin(i)*Math.cos(t)+n.x,s=e*Math.cos(i)+n.y,o=e*Math.sin(i)*Math.sin(t)+n.z;return this.tempVec3_2.set(a,s,o)}_translateDefault(e,t,i){return this._canvasToWorld(e.x,e.y,e.z,i.width/2,i.height/2,t)}_translateAmbient(e,t,i){const n=this._getUniformDirection3D(e),a=i.width/2,s=i.height/2,o=e.x-a,r=e.y-s,l=Math.sqrt(o*o+r*r)/a,h=.6*this.coreRadius3D,c=h+l*(1.2*this.coreRadius3D-h),u=.5*e.age,d=.03*this.coreRadius3D,m=Math.cos(u)*d,p=Math.sin(u)*d;return this.tempVec3.set(t.x+n.x*c+m,t.y+n.y*c*this.verticalScale,t.z+n.z*c+p)}_translateOrbiting(e,t,i){const n=e.behaviorData||{};if(!n.orbitPlane){const t=e.x+.5*e.y,i=.7*e.x+e.y;n.orbitPlane={inclination:.5*(Math.sin(.1*t)+1)*Math.PI,rotation:.5*(Math.sin(.1*i)+1)*Math.PI*2}}const{inclination:a,rotation:s}=n.orbitPlane,o=n.angle||0,r=.01*(n.radius||100)*this.baseRadius*.25*(1+e.z*this.depthScale),l=Math.cos(o)*r,h=Math.sin(o)*r,c=Math.cos(a),u=Math.sin(a),d=Math.cos(s),m=Math.sin(s),p=l*d-h*c*m,g=h*u,f=l*m+h*c*d;return this.tempVec3.set(t.x+p,t.y+g*this.verticalScale,t.z+f)}_translateRising(e,t,i){const n=this._canvasToWorld(e.x,e.y,e.z,i.width/2,i.height/2,t),a=-.01*e.vy;return n.y+=a,n}_translateFalling(e,t,i){const n=this._getUniformDirection3D(e),a=i.width/2,s=i.height/2,o=e.x-a,r=e.y-s,l=Math.sqrt(o*o+r*r)/a,h=.6*this.coreRadius3D,c=h+l*(1.2*this.coreRadius3D-h),u=.6*e.age*this.coreRadius3D;return this.tempVec3.set(t.x+n.x*c,t.y+n.y*c*this.verticalScale-u,t.z+n.z*c)}_translatePopcorn(e,t,i){const n=i.width/2,a=i.height/2,s=e.behaviorData||{},o=this._getUniformDirection3D(e);if(!s.hasPopped){const e=.7*this.coreRadius3D;return this.tempVec3.set(t.x+o.x*e,t.y+o.y*e*this.verticalScale,t.z+o.z*e)}const r=e.x-n,l=e.y-a,h=Math.sqrt(r*r+l*l),c=Math.min(h/n,1.5),u=1.2*this.coreRadius3D,d=u+c*(4*this.coreRadius3D-u);return this.tempVec3.set(t.x+o.x*d,t.y+o.y*d*this.verticalScale,t.z+o.z*d)}_translateBurst(e,t,i){const n=this._getUniformDirection3D(e),a=1-e.life,s=this.coreRadius3D*(1+1*a);return this.tempVec3.set(t.x+n.x*s,t.y+n.y*s*this.verticalScale,t.z+n.z*s)}_translateAggressive(e,t,i){const n=this._getUniformDirection3D(e),a=i.width/2,s=i.height/2,o=e.x-a,r=e.y-s,l=Math.sqrt(o*o+r*r)/a,h=.3*this.coreRadius3D,c=h+l*(.55*this.coreRadius3D-h),u=.04*this.coreRadius3D,d=Math.sin(10*e.age+.1*e.x)*u,m=Math.cos(12*e.age+.1*e.y)*u,p=Math.sin(8*e.age+.1*e.vx)*u;return this.tempVec3.set(t.x+n.x*c+d,t.y+n.y*c*this.verticalScale+m,t.z+n.z*c+p)}_translateScattering(e,t,i){const n=this._getUniformDirection3D(e),a=Math.min(.8*e.age,1),s=this.coreRadius3D*(.3+.3*a);return this.tempVec3.set(t.x+n.x*s,t.y+n.y*s*this.verticalScale,t.z+n.z*s)}_translateRepelling(e,t,i){const n=this._getUniformDirection3D(e),a=Math.min(.6*e.age,1),s=this.coreRadius3D*(.3+.3*a);return this.tempVec3.set(t.x+n.x*s,t.y+n.y*s*this.verticalScale,t.z+n.z*s)}_translateConnecting(e,t,i){const n=this._canvasToWorld(e.x,e.y,e.z,i.width/2,i.height/2,t),a=.3*(1-e.life),s=this.tempVec3_2.set(t.x-n.x,t.y-n.y,t.z-n.z).normalize();return n.add(s.multiplyScalar(a)),n}_translateResting(e,t,i){const n=this._getUniformDirection3D(e),a=i.width/2,s=i.height/2,o=e.x-a,r=e.y-s,l=Math.sqrt(o*o+r*r)/a,h=.25*this.coreRadius3D,c=h+l*(.45*this.coreRadius3D-h),u=.3*e.age,d=Math.sin(u)*this.coreRadius3D*.01;return this.tempVec3.set(t.x+n.x*c,t.y+n.y*c*this.verticalScale+d,t.z+n.z*c)}_translateRadiant(e,t,i){const n=this._getUniformDirection3D(e),a=1-e.life,s=this.coreRadius3D*(1+.8*a);return this.tempVec3.set(t.x+n.x*s,t.y+n.y*s*this.verticalScale,t.z+n.z*s)}_translateAscending(e,t,i){const n=e.behaviorData||{},a=n.spiralAngle||0,s=.01*(n.spiralRadius||50)*this.coreRadius3D,o=e.age*this.coreRadius3D*.5,r=Math.cos(a)*s+t.x,l=o+t.y,h=Math.sin(a)*s+t.z;return this.tempVec3.set(r,l,h)}_translateErratic(e,t,i){const n=this._canvasToWorld(e.x,e.y,e.z,i.width/2,i.height/2,t),a=10*e.age;return n.x+=.1*Math.sin(1.1*a),n.y+=.1*Math.cos(1.3*a),n.z+=.1*Math.sin(1.7*a),n}_translateCautious(e,t,i){return this._translateAmbient(e,t,i)}_translateSurveillance(e,t,i){const n=this._getUniformDirection3D(e),a=.5*e.age,s=1.2*this.coreRadius3D,o={x:0*n.y-1*n.z,y:0*n.z-0*n.x,z:1*n.x-0*n.y},r=Math.sqrt(o.x*o.x+o.y*o.y+o.z*o.z);r>0&&(o.x/=r,o.y/=r,o.z/=r);const l=Math.cos(a)*n.x+Math.sin(a)*o.x,h=Math.cos(a)*n.y+Math.sin(a)*o.y,c=Math.cos(a)*n.z+Math.sin(a)*o.z;return this.tempVec3.set(t.x+l*s,t.y+h*s*this.verticalScale,t.z+c*s)}_translateGlitchy(e,t,i){const n=this._canvasToWorld(e.x,e.y,e.z,i.width/2,i.height/2,t);return Math.floor(10*e.age)%3==0&&(n.x+=.3*(Math.random()-.5),n.y+=.3*(Math.random()-.5),n.z+=.3*(Math.random()-.5)),n}_translateSpaz(e,t,i){const n=this._canvasToWorld(e.x,e.y,e.z,i.width/2,i.height/2,t),a=.15,s=20*e.age;return n.x+=Math.sin(2.1*s)*a,n.y+=Math.cos(2.3*s)*a,n.z+=Math.sin(2.7*s)*a,n}_translateDirected(e,t,i){const n=e.behaviorData||{};if(void 0!==n.targetX&&void 0!==n.targetY){const a=this._canvasToWorld(n.targetX,n.targetY,e.z,i.width/2,i.height/2,t),s=this._canvasToWorld(e.x,e.y,e.z,i.width/2,i.height/2,t),o=1-e.life;return this.tempVec3.lerpVectors(s,a,o)}const a=this._getUniformDirection3D(e),s=i.width/2,o=i.height/2,r=e.x-s,l=e.y-o,h=Math.sqrt(r*r+l*l)/s,c=1*this.coreRadius3D,u=c+h*(1.6*this.coreRadius3D-c);return this.tempVec3.set(t.x+a.x*u,t.y+a.y*u*this.verticalScale,t.z+a.z*u)}_translateFizzy(e,t,i){const n=this._canvasToWorld(e.x,e.y,e.z,i.width/2,i.height/2,t),a=.05*Math.sin(8*e.age);return n.x+=a,n.z+=.05*Math.cos(8*e.age),n.y+=.5*e.age,n}_translateZen(e,t,i){const n=this._getUniformDirection3D(e),a=.2*e.age,s=1.4*this.coreRadius3D,o={x:0*n.y-1*n.z,y:0*n.z-0*n.x,z:1*n.x-0*n.y},r=Math.sqrt(o.x*o.x+o.y*o.y+o.z*o.z);r>0&&(o.x/=r,o.y/=r,o.z/=r);const l=Math.cos(a)*n.x+Math.sin(a)*o.x,h=Math.cos(a)*n.y+Math.sin(a)*o.y,c=Math.cos(a)*n.z+Math.sin(a)*o.z;return this.tempVec3.set(t.x+l*s,t.y+h*s*this.verticalScale,t.z+c*s)}_translateGravitationalAccretion(e,t,i){const n=e.behaviorData||{},a=.25;if(n.orbitRadius||(e.x,e.y,n.orbitRadius=a*(2.5+5.5*Math.random()),n.orbitAngle=Math.PI+Math.random()*Math.PI,n.diskInclination=.1*(Math.random()-.5),n.angularVelocity=.5/Math.sqrt(n.orbitRadius/a),n.tidalStretch={x:1,y:1,z:1}),n.orbitRadius-=1e-4*this.baseRadius,n.angularVelocity=.5/Math.sqrt(n.orbitRadius/a),n.orbitAngle+=n.angularVelocity*(this.deltaTime||16)*.001,n.orbitAngle=n.orbitAngle%(2*Math.PI),n.orbitAngle<0&&(n.orbitAngle+=2*Math.PI),n.orbitAngle<Math.PI)return e.isAlive=!1,e.life=0,this.tempVec3.set(t.x,t.y,t.z);const s=n.orbitRadius/a;if(s<=1)e.isAlive=!1,e.life=0;else if(s<=1.5)n.tidalStretch.x=.3,n.tidalStretch.y=3,n.tidalStretch.z=.3;else if(s<=2.5){const e=(2.5-s)/1;n.tidalStretch.x=1-.7*e,n.tidalStretch.y=1+2*e,n.tidalStretch.z=1-.7*e}else n.tidalStretch.x=1,n.tidalStretch.y=1,n.tidalStretch.z=1;const o=Math.cos(n.orbitAngle)*n.orbitRadius,r=Math.sin(n.orbitAngle)*n.orbitRadius,l=.025*Math.sin(3*n.orbitAngle+e.x)*Math.sin(n.diskInclination),h=o*n.tidalStretch.x,c=l*n.tidalStretch.y,u=r*n.tidalStretch.z,d=.25;return this.tempVec3.set(t.x+h*d,t.y+c*d,t.z+u*d)}setWorldScale(e){this.worldScale=e}setBaseRadius(e){this.baseRadius=e}cleanupParticleCaches(e){for(const t of e)!t.isAlive&&t.behaviorData&&(t.behaviorData.direction3D&&(t.behaviorData.direction3D=null),t.behaviorData.orbitPlane&&(t.behaviorData.orbitPlane=null),t.behaviorData.orbitPath&&(t.behaviorData.orbitPath=null),t.behaviorData.orbitRadius&&(t.behaviorData.orbitRadius=null,t.behaviorData.orbitAngle=null,t.behaviorData.diskInclination=null,t.behaviorData.angularVelocity=null,t.behaviorData.tidalStretch=null))}dispose(){this.tempVec3=null,this.tempVec3_2=null,this.rotationState=null,this.currentGestureData=null}}let ui=null,di=null;const mi=`\n uniform float time;\n uniform vec3 emotionColor;\n uniform float energyIntensity;\n uniform float driftEnabled;\n uniform float driftSpeed;\n uniform float crossWaveEnabled;\n uniform float crossWaveSpeed;\n uniform float ghostMode; // 0.0 = solid, 1.0 = ghost (only visible through bloom)\n uniform float baseOpacity; // Base opacity when not in ghost mode (default 1.0)\n uniform float phaseOffset1; // Phase offset for primary drift (radians)\n uniform float phaseOffset2; // Phase offset for secondary drift (radians)\n uniform float phaseOffset3; // Phase offset for crosswave (radians)\n\n // Blend layer uniforms\n uniform float blendLayer1Mode;\n uniform float blendLayer1Strength;\n uniform float blendLayer1Enabled;\n uniform float blendLayer2Mode;\n uniform float blendLayer2Strength;\n uniform float blendLayer2Enabled;\n\n varying vec3 vPosition;\n varying vec3 vNormal;\n\n // Blend modes (injected from blendModesGLSL)\n ${S}\n\n // Smooth noise function\n float noise3D(vec3 p) {\n vec3 i = floor(p);\n vec3 f = fract(p);\n f = f * f * (3.0 - 2.0 * f);\n float n = i.x + i.y * 157.0 + i.z * 113.0;\n vec4 v = fract(sin(vec4(n, n+1.0, n+157.0, n+158.0)) * 43758.5453);\n return mix(mix(v.x, v.y, f.x), mix(v.z, v.w, f.x), f.y);\n }\n\n void main() {\n // Drifting energy clouds - slow, ethereal movement\n // Start with zero energy - only effects add to it\n float driftEnergy = 0.0;\n float crossWaveEnergy = 0.0;\n\n // Spatially triangulated fire bands - each owns a 120° wedge of the geometry\n // Bands can never overlap because they're physically separated\n float angle = atan(vPosition.x, vPosition.z); // -π to π\n float normalizedAngle = (angle + 3.14159) / 6.28318; // 0 to 1\n\n // Determine which zone this fragment belongs to (0, 1, or 2)\n float zone = floor(normalizedAngle * 3.0);\n float zonePos = fract(normalizedAngle * 3.0); // Position within zone (0-1)\n\n // Time-based phase for each zone (120° offset in time)\n float phaseSpeed = 0.15;\n float t = time * phaseSpeed;\n float phase1Time = sin(t + phaseOffset1) * 0.5 + 0.5;\n float phase2Time = sin(t + phaseOffset2) * 0.5 + 0.5;\n float phase3Time = sin(t + phaseOffset3) * 0.5 + 0.5;\n\n // Only ONE phase affects this fragment - the one that owns this spatial zone\n float activePhase = zone < 1.0 ? phase1Time : (zone < 2.0 ? phase2Time : phase3Time);\n\n float primaryDrift = 0.0;\n float secondaryDrift = 0.0;\n\n if (driftEnabled > 0.5) {\n float t = time * driftSpeed;\n // Primary drift - moving in one direction\n float drift1 = noise3D(vPosition * 2.0 + vec3(t, t * 0.7, t * 0.3));\n float drift2 = noise3D(vPosition * 3.0 - vec3(t * 0.5, t, t * 0.8));\n // Use max instead of multiply to avoid near-zero products\n primaryDrift = max(drift1, drift2);\n primaryDrift = max(0.0, primaryDrift - 0.4) * 2.0; // Rescale after threshold\n\n // Secondary drift - offset in opposite direction to fill gaps\n float drift3 = noise3D(vPosition * 2.5 - vec3(t * 0.8, t * 0.4, t));\n float drift4 = noise3D(vPosition * 1.8 + vec3(t * 0.6, t * 0.9, t * 0.2));\n secondaryDrift = max(drift3, drift4);\n secondaryDrift = max(0.0, secondaryDrift - 0.4) * 2.0;\n\n driftEnergy = primaryDrift + secondaryDrift;\n }\n\n // Horizontal cross wave - thin bands sweeping across\n float rawCrossWave = 0.0;\n if (crossWaveEnabled > 0.5) {\n float t = time * crossWaveSpeed;\n float wave = sin(vPosition.x * 4.0 + vPosition.z * 2.0 - t) * 0.5 + 0.5;\n // pow(4) for thin bright bands\n rawCrossWave = pow(wave, 4.0);\n crossWaveEnergy = rawCrossWave;\n }\n\n // Mix the effects - normalize to prevent blowout\n // driftEnergy can be 0-2 (two drifts), rawCrossWave is 0-1\n float normalizedDrift = min(1.0, driftEnergy * 0.5);\n float normalizedWave = rawCrossWave;\n\n // activePhase is 0-1, remap to visibility range\n // 0.53 floor (just above 0.52 threshold), 0.58 ceiling (subtle glow)\n float remappedPhase = 0.53 + activePhase * 0.05;\n\n // Effects add subtle variation (max 0.05)\n float effectContrib = (normalizedDrift * 0.03) + (normalizedWave * 0.02);\n float phasedActivity = remappedPhase + effectContrib;\n\n // Keep unclamped for visibility threshold check (ghost mode needs full range)\n float rawEffectActivity = phasedActivity;\n // Clamp for color intensity (floor: guaranteed visible, ceiling: no blowout)\n float effectActivity = clamp(phasedActivity, 0.53, 0.60);\n\n // Total energy for color calculation (reduced for subtler bloom)\n float totalEnergy = 0.25 + effectActivity * 0.55; // Base glow + effect contribution\n\n // Edge glow - adds rim lighting\n vec3 viewDir = normalize(-vPosition);\n float edgeGlow = 1.0 - abs(dot(vNormal, viewDir));\n edgeGlow = pow(edgeGlow, 2.0) * 0.4;\n\n // Final color before blend layers\n vec3 coreColor = emotionColor * totalEnergy * energyIntensity;\n coreColor += emotionColor * edgeGlow * 0.3;\n\n // Apply blend layers to the entire soul color\n if (blendLayer1Enabled > 0.5) {\n int mode = int(blendLayer1Mode + 0.5);\n vec3 blendResult = applyBlendMode(coreColor, emotionColor * blendLayer1Strength, mode);\n coreColor = mix(coreColor, blendResult, blendLayer1Strength);\n }\n if (blendLayer2Enabled > 0.5) {\n int mode = int(blendLayer2Mode + 0.5);\n vec3 blendResult = applyBlendMode(coreColor, emotionColor * blendLayer2Strength, mode);\n coreColor = mix(coreColor, blendResult, blendLayer2Strength);\n }\n\n // Ghost mode: ONLY the traveling fire bands are visible\n // Everything below the threshold is completely invisible\n float alpha = baseOpacity;\n if (ghostMode > 0.01) {\n // High threshold - only the peaks of the thin bands pass through\n float threshold = 0.4 + ghostMode * 0.4; // 0.4-0.8 range\n float visibility = smoothstep(threshold, threshold + 0.05, rawEffectActivity);\n\n // Hard cutoff - only bright fire bands visible\n alpha = visibility * baseOpacity;\n\n // Discard everything that isn't a bright fire band\n if (alpha < 0.05) {\n discard;\n }\n\n // Boost color intensity for visible fire\n coreColor *= 1.2 + visibility * 0.6;\n }\n\n // Output the computed core color\n gl_FragColor = vec4(coreColor, alpha);\n }\n`;class pi{constructor(e={}){this.radius=e.radius||.15,this.detail=e.detail||1,this.geometryType=e.geometryType||"crystal",this.renderer=e.renderer||null,this.assetBasePath=e.assetBasePath||"/assets",this.mesh=null,this.material=null,this.parentMesh=null,this.baseScale=1,this._pendingParent=null,this._disposed=!1,this._createMesh()}static _loadInclusionGeometry(t="/assets"){return ui?Promise.resolve(ui.clone()):di?di.then(e=>e.clone()):(di=new Promise(i=>{(new f).load(`${t}/models/Crystal/inclusion.obj`,t=>{let n=null;if(t.traverse(e=>{e.isMesh&&e.geometry&&({geometry:n}=e)}),n){n.computeBoundingBox();const t=new e.Vector3;n.boundingBox.getCenter(t),n.translate(-t.x,-t.y,-t.z),n.rotateX(Math.PI/2),n.computeBoundingBox();const a=new e.Vector3;n.boundingBox.getSize(a);const s=.3/Math.max(a.x,a.y,a.z);n.scale(s,s,s),n.computeVertexNormals(),ui=n,i(n.clone())}else console.warn("[🔮 SOUL] No mesh in inclusion.obj, using fallback"),i(null)},void 0,e=>{console.warn("[🔮 SOUL] Failed to load inclusion.obj:",e),i(null)})}),di)}_createMesh(){let t;console.log(`[CrystalSoul] _createMesh() START, inclusionGeometryCache=${!!ui}`),this.material=new e.ShaderMaterial({uniforms:{time:{value:0},emotionColor:{value:new e.Color(1,1,1)},energyIntensity:{value:1.5},driftEnabled:{value:1},driftSpeed:{value:.5},crossWaveEnabled:{value:1},crossWaveSpeed:{value:.4},ghostMode:{value:.36},baseOpacity:{value:1},phaseOffset1:{value:0},phaseOffset2:{value:2.094},phaseOffset3:{value:4.189},blendLayer1Mode:{value:2},blendLayer1Strength:{value:2.3},blendLayer1Enabled:{value:1},blendLayer2Mode:{value:0},blendLayer2Strength:{value:1},blendLayer2Enabled:{value:1}},vertexShader:"\n varying vec3 vPosition;\n varying vec3 vNormal;\n\n void main() {\n vPosition = position;\n vNormal = normalize(normalMatrix * normal);\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n",fragmentShader:mi,transparent:!0,depthWrite:!0,depthTest:!0,side:e.FrontSide}),t=ui?ui.clone():new e.OctahedronGeometry(this.radius,this.detail),this.mesh=new e.Mesh(t,this.material),this.mesh.name="crystalSoul",this.mesh.renderOrder=0,this.mesh.layers.set(2)}attachTo(e,t){this._disposed||(e?this.mesh?(this.mesh.parent&&this.mesh.parent.remove(this.mesh),this.parentMesh=e,this._scene=t,t&&!this.mesh.parent&&t.add(this.mesh),this._syncPosition(),this.mesh.visible=!0):console.warn("[CrystalSoul] Cannot attach - mesh is null"):console.warn("[CrystalSoul] Cannot attach to null parent"))}_syncPosition(){this.parentMesh&&this.mesh&&(this.parentMesh.getWorldPosition(this.mesh.position),this.parentMesh.getWorldQuaternion(this.mesh.quaternion))}detach(){this.mesh&&(this.mesh.visible=!1,this.parentMesh=null)}update(e,t,i=1){if(!this.material||!this.material.uniforms)return;this._syncPosition();const{uniforms:n}=this.material;n.time&&(n.time.value+=e/1e3),n.emotionColor&&t&&n.emotionColor.value.setRGB(t[0],t[1],t[2]),n.energyIntensity&&(n.energyIntensity.value=.8),this.mesh&&this.mesh.scale.setScalar(this.baseScale*i)}setSize(e){if(!this.mesh)return;const t=.05+.95*e;this.baseScale=t,this.mesh.scale.setScalar(t)}setEffects(e={}){if(!this.material||!this.material.uniforms)return;const{uniforms:t}=this.material;void 0!==e.driftEnabled&&t.driftEnabled&&(t.driftEnabled.value=e.driftEnabled?1:0),void 0!==e.driftSpeed&&t.driftSpeed&&(t.driftSpeed.value=Math.max(.1,Math.min(3,e.driftSpeed))),void 0!==e.crossWaveEnabled&&t.crossWaveEnabled&&(t.crossWaveEnabled.value=e.crossWaveEnabled?1:0),void 0!==e.crossWaveSpeed&&t.crossWaveSpeed&&(t.crossWaveSpeed.value=Math.max(.1,Math.min(3,e.crossWaveSpeed))),void 0!==e.phaseOffset1&&t.phaseOffset1&&(t.phaseOffset1.value=e.phaseOffset1),void 0!==e.phaseOffset2&&t.phaseOffset2&&(t.phaseOffset2.value=e.phaseOffset2),void 0!==e.phaseOffset3&&t.phaseOffset3&&(t.phaseOffset3.value=e.phaseOffset3)}setColor(e){this.material&&this.material.uniforms&&this.material.uniforms.emotionColor&&this.material.uniforms.emotionColor.value.setRGB(e[0],e[1],e[2])}setBlendLayers(e){if(!this.material||!this.material.uniforms)return;const t=this.material.uniforms;e[0]?(t.blendLayer1Mode&&(t.blendLayer1Mode.value=e[0].mode??0),t.blendLayer1Strength&&(t.blendLayer1Strength.value=e[0].strength??0),t.blendLayer1Enabled&&(t.blendLayer1Enabled.value=e[0].enabled?1:0)):t.blendLayer1Enabled&&(t.blendLayer1Enabled.value=0),e[1]?(t.blendLayer2Mode&&(t.blendLayer2Mode.value=e[1].mode??0),t.blendLayer2Strength&&(t.blendLayer2Strength.value=e[1].strength??0),t.blendLayer2Enabled&&(t.blendLayer2Enabled.value=e[1].enabled?1:0)):t.blendLayer2Enabled&&(t.blendLayer2Enabled.value=0)}isAttached(){return null!==this.parentMesh&&null!==this.mesh&&null!==this.mesh.parent}setVisible(e){this.mesh&&(this.mesh.visible=e)}setGhostMode(e){this.material&&this.material.uniforms&&this.material.uniforms.ghostMode&&(this.material.uniforms.ghostMode.value=e?1:0)}setBaseOpacity(e){this.material&&this.material.uniforms&&this.material.uniforms.baseOpacity&&(this.material.uniforms.baseOpacity.value=Math.max(0,Math.min(1,e)))}dispose(){if(this._disposed)return;this._disposed=!0,this.mesh&&(this.mesh.visible=!1);const e=this.mesh,t=this.material;e?.parent&&e.parent.remove(e),this.mesh=null,this.material=null,this.parentMesh=null,requestAnimationFrame(()=>{e?.geometry&&e.geometry.dispose(),t&&t.dispose()})}}class gi{constructor(e=50,t={}){this.maxParticles=e,this.options=t,this.geometry=null,this.material=null,this.points=null,this.positions=null,this.sizes=null,this.colors=null,this.alphas=null,this.glowIntensities=null,this.depths=null,this.styles=null,this.particleCount=0,this.gestureEffects={firefly:!1,flicker:!1,shimmer:!1,glow:!1,time:0},this._initGeometry(),this._initMaterial(),this._initPoints()}_initGeometry(){this.geometry=new e.BufferGeometry;const{maxParticles:t}=this;this.positions=new Float32Array(3*t),this.sizes=new Float32Array(t),this.colors=new Float32Array(3*t),this.alphas=new Float32Array(t),this.glowIntensities=new Float32Array(t),this.depths=new Float32Array(t),this.styles=new Float32Array(t),this.geometry.setAttribute("position",new e.BufferAttribute(this.positions,3)),this.geometry.setAttribute("size",new e.BufferAttribute(this.sizes,1)),this.geometry.setAttribute("customColor",new e.BufferAttribute(this.colors,3)),this.geometry.setAttribute("alpha",new e.BufferAttribute(this.alphas,1)),this.geometry.setAttribute("glowIntensity",new e.BufferAttribute(this.glowIntensities,1)),this.geometry.setAttribute("depth",new e.BufferAttribute(this.depths,1)),this.geometry.setAttribute("style",new e.BufferAttribute(this.styles,1)),this.geometry.attributes.position.setUsage(e.DynamicDrawUsage),this.geometry.attributes.size.setUsage(e.DynamicDrawUsage),this.geometry.attributes.customColor.setUsage(e.DynamicDrawUsage),this.geometry.attributes.alpha.setUsage(e.DynamicDrawUsage),this.geometry.attributes.glowIntensity.setUsage(e.DynamicDrawUsage),this.geometry.attributes.depth.setUsage(e.DynamicDrawUsage),this.geometry.attributes.style.setUsage(e.DynamicDrawUsage),this.geometry.setDrawRange(0,0)}_initMaterial(){this.material=new e.ShaderMaterial({uniforms:{coreScale:{value:1},viewportHeight:{value:600},pixelRatio:{value:1}},vertexShader:"\n/**\n * Particle Vertex Shader - Simple 2D-style particles in 3D space\n * Matches the 2D canvas particle appearance\n */\n\n// Per-particle attributes\nattribute float size;\nattribute vec3 customColor;\nattribute float alpha;\nattribute float glowIntensity;\nattribute float style; // 0.0 = solid/gradient, 1.0 = cell-shaded (ring with transparent center)\n\n// Uniforms\nuniform float coreScale;\nuniform float viewportHeight;\nuniform float pixelRatio;\n\n// Varying to fragment shader\nvarying vec3 vColor;\nvarying float vAlpha;\nvarying float vGlowIntensity;\nvarying float vStyle;\n\nvoid main() {\n // Pass attributes to fragment shader\n vColor = customColor;\n vAlpha = alpha;\n vGlowIntensity = glowIntensity;\n vStyle = style;\n\n // Calculate position in clip space\n vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);\n\n // Calculate point size with perspective scaling\n float perspectiveScale = coreScale * (75.0 / length(mvPosition.xyz)) * (viewportHeight / 600.0) / pixelRatio;\n gl_PointSize = size * perspectiveScale;\n\n // Final position\n gl_Position = projectionMatrix * mvPosition;\n}\n",fragmentShader:"\n/**\n * Particle Fragment Shader - Solid colored circles matching 2D appearance\n * Uses premultiplied alpha for proper blending\n */\n\nvarying vec3 vColor;\nvarying float vAlpha;\nvarying float vGlowIntensity;\nvarying float vStyle;\n\nvoid main() {\n // Distance from center (0 at center, 0.5 at edge)\n vec2 center = gl_PointCoord - vec2(0.5);\n float dist = length(center);\n\n // Hard circle cutoff - discard everything outside\n if (dist > 0.45) {\n discard;\n }\n\n vec3 finalColor = vColor;\n\n // Base opacity from particle (already includes baseOpacity variation)\n float alpha = vAlpha;\n\n // Gesture glow boost\n if (vGlowIntensity >= 2.0) {\n float gestureBoost = (vGlowIntensity - 2.0) / 13.0;\n finalColor *= (1.0 + gestureBoost * 0.5);\n alpha = min(alpha * (1.0 + gestureBoost * 0.3), 1.0);\n }\n\n // Cell-shaded particles are slightly more opaque\n float opacityBoost = vStyle > 0.5 ? 1.0 : 0.85;\n alpha *= opacityBoost;\n\n // Output with proper alpha for blending\n // Premultiply alpha for correct compositing\n gl_FragColor = vec4(finalColor * alpha, alpha);\n}\n",transparent:!0,blending:e.CustomBlending,blendSrc:e.OneFactor,blendDst:e.OneMinusSrcAlphaFactor,blendSrcAlpha:e.OneFactor,blendDstAlpha:e.OneMinusSrcAlphaFactor,depthWrite:!1,depthTest:!0})}_initPoints(){this.points=new e.Points(this.geometry,this.material),this.points.frustumCulled=!0}updateParticles(e,t,i,n,a,s,o,r,l){this.particleCount=Math.min(e.length,this.maxParticles),void 0!==r&&(this.material.uniforms.coreScale.value=r),n&&n.height&&(this.material.uniforms.viewportHeight.value=n.height),this.options.renderer&&(this.material.uniforms.pixelRatio.value=this.options.renderer.getPixelRatio()),this.gestureEffects.time+=.016,this.gestureEffects.time>2*Math.PI&&(this.gestureEffects.time=this.gestureEffects.time%(2*Math.PI)),a&&s&&t.updateRotationState(a,s,o);for(let a=0;a<this.particleCount;a++){const s=e[a];if(!s.isAlive()){this.alphas[a]=0;continue}const o=t.translate2DTo3D(s,i,n);if(("crystal"===l||"heart"===l||"rough"===l)&&o.z>.15){this.alphas[a]=0;continue}const r=3*a;this.positions[r+0]=o.x,this.positions[r+1]=o.y,this.positions[r+2]=o.z;const h=s.getDepthAdjustedSize?s.getDepthAdjustedSize():s.size,c="popcorn"===s.behavior?1.2:.85;this.sizes[a]=h*c;const u=this._parseColor(s.color||"#ffffff"),d=3*a;this.colors[d+0]=u.r,this.colors[d+1]=u.g,this.colors[d+2]=u.b,this.alphas[a]=s.opacity*(s.baseOpacity||1);let m=s.hasGlow?1*(s.glowSizeMultiplier||1.5):0;m=this._applyGestureEffects(s,m,a),this.glowIntensities[a]=m;const p=.5*(1-s.z);this.depths[a]=Math.max(0,Math.min(1,p)),this.styles[a]=s.isCellShaded?1:0}this.geometry.attributes.position.needsUpdate=!0,this.geometry.attributes.size.needsUpdate=!0,this.geometry.attributes.customColor.needsUpdate=!0,this.geometry.attributes.alpha.needsUpdate=!0,this.geometry.attributes.glowIntensity.needsUpdate=!0,this.geometry.attributes.depth.needsUpdate=!0,this.geometry.attributes.style.needsUpdate=!0,this.geometry.setDrawRange(0,this.particleCount)}_applyGestureEffects(e,t,i){let n=t;if(this.gestureEffects.firefly){const t=(.01*e.x+.01*e.y+.1*e.size)%(2*Math.PI),i=2+.5*(Math.sin(3*this.gestureEffects.time+t)+1)*10;n=Math.max(n,i)}if(this.gestureEffects.flicker){const t=(.02*e.x+.02*e.y)%(2*Math.PI),a=15*this.gestureEffects.time,s=.5*(Math.sin(a+t)+1),o=Math.floor(10*a+i),r=2+10*(.3*s+.5*(Math.sin(123.456*o)+1)*.7);n=Math.max(n,r)}if(this.gestureEffects.shimmer){const t=e.x-(this.gestureEffects.centerX||0),i=e.y-(this.gestureEffects.centerY||0),a=Math.sqrt(t*t+i*i)/200,s=2+.5*(Math.sin(3*this.gestureEffects.time-a)+1)*8;n=Math.max(n,s)}if(this.gestureEffects.glow){const e=this.gestureEffects.glowProgress||0,t=3+12*Math.sin(e*Math.PI);n=Math.max(n,t)}return n}_parseColor(e){const t=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return t?{r:parseInt(t[1],16)/255,g:parseInt(t[2],16)/255,b:parseInt(t[3],16)/255}:{r:1,g:1,b:1}}setGestureEffects(e){if(!e)return this.gestureEffects.firefly=!1,this.gestureEffects.flicker=!1,this.gestureEffects.shimmer=!1,void(this.gestureEffects.glow=!1);this.gestureEffects.firefly=e.fireflyEffect||!1,this.gestureEffects.flicker=e.flickerEffect||!1,this.gestureEffects.shimmer=e.shimmerEffect||!1,this.gestureEffects.glow=e.glowEffect||!1,this.gestureEffects.glowProgress=e.glowProgress,this.gestureEffects.centerX=e.centerX,this.gestureEffects.centerY=e.centerY}getPoints(){return this.points}setVisible(e){this.points.visible=e}resize(e){e!==this.maxParticles&&(this.geometry&&this.geometry.dispose(),this.maxParticles=e,this._initGeometry(),this.points&&(this.points.geometry=this.geometry))}cleanupParticleStates(e){for(const t of e)!t.isAlive()&&t.behaviorData&&(t.behaviorData.direction3D&&(t.behaviorData.direction3D=null),t.behaviorData.orbitPlane&&(t.behaviorData.orbitPlane=null),t.behaviorData.orbitPath&&(t.behaviorData.orbitPath=null),t.behaviorData=null)}dispose(){this.geometry&&this.geometry.dispose(),this.material&&this.material.dispose(),this.positions=null,this.sizes=null,this.colors=null,this.alphas=null,this.glowIntensities=null,this.depths=null,this.styles=null}}class fi{constructor(){this.cachedConfigs=new Map,this.maxCacheSize=100}calculate(e,t=null){const i=`${e}:${t||"none"}`;if(this.cachedConfigs.has(i))return this.cachedConfigs.get(i);const n=me(e);if(!n)return console.warn(`[ParticleEmotionCalculator] Unknown emotion: ${e}`),this._getDefaultConfig();const a=this._extractBaseConfig(n,e),s=this._applyUndertoneModifiers(a,t),o=this._applySpecialBehaviors(s,e);if(this.cachedConfigs.size>=this.maxCacheSize){const e=this.cachedConfigs.keys().next().value;this.cachedConfigs.delete(e)}return this.cachedConfigs.set(i,o),o}_extractBaseConfig(e,t){const i=e.visual||{};return{behavior:i.particleBehavior||"ambient",rate:i.particleRate||1,min:void 0!==i.minParticles?i.minParticles:0,max:void 0!==i.maxParticles?i.maxParticles:10,colors:i.particleColors||null,emotion:t}}_applyUndertoneModifiers(e,t){if(!t)return e;const i=vt(t);if(!i||!i.particles)return e;const n=i.particles,a={...e};return n.behaviorOverride&&(a.behavior=n.behaviorOverride),n.rateMultiplier&&(a.rate=e.rate*n.rateMultiplier,a.max=Math.floor(e.max*n.rateMultiplier)),void 0!==n.minParticles&&(a.min=n.minParticles),void 0!==n.maxParticles&&(a.max=n.maxParticles),a}_applySpecialBehaviors(e,t){return"zen"===t?{...e,specialBehavior:"zen-mixing"}:e}selectZenBehavior(){return Math.random()<.6?"falling":"orbiting"}_getDefaultConfig(){return{behavior:"ambient",rate:1,min:0,max:10,colors:null,emotion:"neutral"}}clearCache(){this.cachedConfigs.clear()}getCacheSize(){return this.cachedConfigs.size}}class yi{constructor(){this.previousGesture=null}extract(e,t){if(!e||0===e.length)return this.previousGesture=null,null;const i=e[0],n=this._calculateProgress(i,t);if(n>=1)return this.previousGesture=null,null;const a=this._extractGestureName(i);if(!a)return null;const s=this._buildGestureMotion(i,a);return this.previousGesture=a,{motion:s,progress:n,config:i.config||{},gestureName:a,animation:i}}_calculateProgress(e,t){const i=(t-e.startTime)/e.duration;return Math.max(0,Math.min(1,i))}_extractGestureName(e){return e.gestureName||e.name||e.config?.gestureName||null}_buildGestureMotion(e,t){const i=e.config||{};return{type:t,amplitude:i.amplitude||1,strength:i.strength||1,wobbleAmount:i.wobbleAmount||0,duration:e.duration}}hasGestureChanged(e){return!(!e&&!this.previousGesture||(e||!this.previousGesture)&&(!e||this.previousGesture)&&e.gestureName===this.previousGesture)}extractAll(e,t){if(!e||0===e.length)return[];const i=[];for(const n of e){const e=this._calculateProgress(n,t);if(e>=1)continue;const a=this._extractGestureName(n);if(!a)continue;const s=this._buildGestureMotion(n,a);i.push({motion:s,progress:e,config:n.config||{},gestureName:a,animation:n})}return i}reset(){this.previousGesture=null}}class vi{constructor(){this.effectMap={sparkle:this.buildFireflyEffect.bind(this),twinkle:this.buildFireflyEffect.bind(this),flicker:this.buildFlickerEffect.bind(this),shimmer:this.buildShimmerEffect.bind(this),glow:this.buildGlowEffect.bind(this),burst:this.buildGlowEffect.bind(this),flash:this.buildFlickerEffect.bind(this)}}build(e,t,i){if(!e||!e.motion)return null;const{gestureName:n}=e,a=this.effectMap[n];return a?a(e,t,i):null}buildFireflyEffect(e,t,i){const n=e.config||{};return{fireflyEffect:!0,fireflyTime:.001*Date.now(),particleGlow:n.particleGlow||2,centerX:t,centerY:i}}buildFlickerEffect(e,t,i){const n=e.config||{};return{flickerEffect:!0,flickerTime:.001*Date.now(),particleGlow:n.particleGlow||2,centerX:t,centerY:i}}buildShimmerEffect(e,t,i){const n=e.config||{},a=e.progress||0;return{shimmerEffect:!0,shimmerTime:.001*Date.now(),shimmerWave:a*Math.PI*2,particleGlow:n.particleGlow||1.2,centerX:t,centerY:i}}buildGlowEffect(e,t,i){const n=e.config||{};return{glowEffect:!0,glowProgress:e.progress||0,particleGlow:n.particleGlow||2,centerX:t,centerY:i}}registerEffect(e,t){this.effectMap[e]=t.bind(this)}hasEffect(e){return!!this.effectMap[e]}getEffectGestures(){return Object.keys(this.effectMap)}buildAll(e,t,i){if(!e||0===e.length)return[];const n=[];for(const a of e){const e=this.build(a,t,i);e&&n.push(e)}return n}mergeEffects(e){if(!e||0===e.length)return null;if(1===e.length)return e[0];const t={};for(const i of e)Object.assign(t,i);return t}destroy(){this.effectMap=null}}class bi{constructor(e,t,i){this.particleSystem=e,this.translator=t,this.renderer=i,this.emotionCalculator=new fi,this.gestureExtractor=new yi,this.effectsBuilder=new vi,this.currentEmotion=null,this.currentUndertone=null,this.currentConfig=null}update(e,t,i,n,a,s,o,r,l,h){void 0!==h&&this.translator.setCoreRadius3D(h);const c=this._updateEmotionConfig(t,i),u=this.gestureExtractor.extract(n,a);this._spawnParticles(c,e,o),this._updatePhysics(c,u,e,o,i),this._updateRendering(u,s,o,r,e,l)}_updateEmotionConfig(e,t){return this.currentEmotion===e&&this.currentUndertone===t||(this.currentEmotion=e,this.currentUndertone=t,this.currentConfig=this.emotionCalculator.calculate(e,t),this.particleSystem.clear()),this.currentConfig}_spawnParticles(e,t,i){const n=i.width/2,a=i.height/2;let s=e.behavior;"zen-mixing"===e.specialBehavior&&(s=this.emotionCalculator.selectZenBehavior()),this.particleSystem.spawn(s,e.emotion,e.rate,n,a,t,null,e.min,e.max,1,1,e.colors,this.currentUndertone)}_updatePhysics(e,t,i,n,a){const s=n.width/2,o=n.height/2,r=a?{undertone:a}:null;this.particleSystem.update(i,s,o,t?t.motion:null,t?t.progress:0,r)}_updateRendering(e,t,i,n,a,s){const o=i.width/2,r=i.height/2,l=e?this.effectsBuilder.build(e,o,r):null;this.renderer.updateParticles(this.particleSystem.particles,this.translator,t,i,n,a,e,s,this.geometryType),this.renderer.setGestureEffects(l)}setEmotion(e,t=null){this.currentEmotion=null,this.currentUndertone=null}setGeometryType(e){this.geometryType=e}clear(){this.particleSystem.clear()}setEnabled(e){this.renderer.setVisible(e),e||this.clear()}getParticleCount(){return this.particleSystem.particles.length}getCurrentConfig(){return this.currentConfig}registerEffect(e,t){this.effectsBuilder.registerEffect(e,t)}destroy(){this.particleSystem.destroy(),this.renderer.dispose(),this.translator&&(this.translator.dispose?.(),this.translator=null),this.emotionCalculator.clearCache(),this.emotionCalculator=null,this.gestureExtractor.reset(),this.gestureExtractor=null,this.effectsBuilder&&(this.effectsBuilder.destroy?.(),this.effectsBuilder=null)}}const wi="off",Mi="annular",Si="total",xi={[wi]:{shadowCoverage:0,coronaIntensity:1,coronaRaysEnabled:!1,baileyBeadsEnabled:!1,baileyBeadsCount:0,baileyBeadsSize:0},[Mi]:{shadowCoverage:.95,coronaIntensity:.8,coronaRaysEnabled:!1,baileyBeadsEnabled:!0,baileyBeadsCount:12,baileyBeadsSize:.015},[Si]:{shadowCoverage:1.019,coronaIntensity:4,coronaRaysEnabled:!0,baileyBeadsEnabled:!0,baileyBeadsCount:6,baileyBeadsSize:.025}};function Ci(e){return xi[e]||xi[wi]}class Di{constructor(t,i){this.scene=t,this.sunRadius=i,this.heroBeadCount=3,this.supportBeadCount=15,this.beadCount=this.heroBeadCount+this.supportBeadCount,this.beads=[],this.visible=!1,this._directionToCamera=new e.Vector3,this._up=new e.Vector3(0,1,0),this._right=new e.Vector3,this._upVector=new e.Vector3,this._beadOffset=new e.Vector3,this._tempColor=new e.Color,this.sharedTexture=null,this.createBeads()}createBeads(){const t=document.createElement("canvas");t.width=64,t.height=64;const i=t.getContext("2d"),n=i.createRadialGradient(32,32,0,32,32,32);n.addColorStop(0,"rgba(255, 255, 255, 1.0)"),n.addColorStop(.1,"rgba(255, 255, 255, 0.9)"),n.addColorStop(.3,"rgba(255, 240, 200, 0.6)"),n.addColorStop(.6,"rgba(255, 220, 150, 0.2)"),n.addColorStop(1,"rgba(255, 200, 100, 0.0)"),i.fillStyle=n,i.fillRect(0,0,64,64);const a=new e.CanvasTexture(t);a.needsUpdate=!0,this.sharedTexture=a;const s=this.generateLunarValleys();for(let t=0;t<this.beadCount;t++){const i=new e.Group,n=new e.SpriteMaterial({map:a.clone(),blending:e.AdditiveBlending,transparent:!0,depthWrite:!1,opacity:0,color:this._tempColor.setRGB(1,.3,.3)}),o=new e.Sprite(n);o.scale.set(.08,.08,1),i.add(o);const r=new e.SpriteMaterial({map:a.clone(),blending:e.AdditiveBlending,transparent:!0,depthWrite:!1,opacity:0,color:this._tempColor.setRGB(.8,1,.8)}),l=new e.Sprite(r);l.scale.set(.08,.08,1),i.add(l);const h=new e.SpriteMaterial({map:a,blending:e.AdditiveBlending,transparent:!0,depthWrite:!1,opacity:0,color:this._tempColor.setRGB(.3,.5,1)}),c=new e.Sprite(h);c.scale.set(.08,.08,1),i.add(c),i.userData={angle:s[t].angle,depth:s[t].depth,baseIntensity:s[t].baseIntensity,isHero:s[t].isHero,sizeMultiplier:s[t].isHero?1.5:1,targetOpacity:0,currentOpacity:0,redSprite:o,greenSprite:l,blueSprite:c},this.beads.push(i),this.scene.add(i)}}generateLunarValleys(){const e=[];let t=12345;const i=()=>(t=(9301*t+49297)%233280,t/233280),n=i()*Math.PI*2;for(let t=0;t<this.heroBeadCount;t++){const a=n+t*Math.PI*2/3;e.push({angle:a,depth:.8+.2*i(),baseIntensity:.8+.2*i(),isHero:!0})}for(let t=0;t<this.supportBeadCount;t++){const a=n+Math.floor(t/(this.supportBeadCount/3))*Math.PI*2/3,s=1.2*(i()-.5);e.push({angle:a+s,depth:.3+.5*i(),baseIntensity:.4+.4*i(),isHero:!1})}return e}update(e,t,i,n,a=1){const s=this.sunRadius*a*1,o=e.position;this._directionToCamera.subVectors(o,t).normalize(),this._right.crossVectors(this._directionToCamera,this._up).normalize(),this._upVector.crossVectors(this._right,this._directionToCamera).normalize();for(const e of this.beads){const{angle:i,redSprite:n,greenSprite:o,blueSprite:r,sizeMultiplier:l}=e.userData,h=Math.cos(i)*s,c=Math.sin(i)*s;this._beadOffset.set(0,0,0),this._beadOffset.addScaledVector(this._right,h),this._beadOffset.addScaledVector(this._upVector,c),this._beadOffset.addScaledVector(this._directionToCamera,.01*s);const u=t.x+this._beadOffset.x,d=t.y+this._beadOffset.y,m=t.z+this._beadOffset.z,p=.008*a,g=Math.cos(i)*p,f=Math.sin(i)*p;n.position.set(g,f,.001),o.position.set(0,0,0),r.position.set(-g,-f,-.001),e.position.set(u,d,m),e.updateMatrixWorld(!0);const y=.15*a*l;n.scale.set(y,y,1),o.scale.set(y,y,1),r.scale.set(y,y,1)}if(this.visible){const e=.9,t=.97,n=1;for(const a of this.beads){let s=0;if(i>=e&&i<n){const o=(i-e)/(n-e)*Math.PI*2,r=Math.abs((a.userData.angle-o+Math.PI)%(2*Math.PI)-Math.PI);let l=1;i<t&&(l=(i-e)/(t-e)),s=Math.max(0,1-r/1)*a.userData.baseIntensity*l*a.userData.depth,s*=200}a.userData.targetOpacity=s}}else for(const e of this.beads)e.userData.targetOpacity=0;for(const e of this.beads){const{redSprite:t,greenSprite:i,blueSprite:a}=e.userData,s=e.userData.targetOpacity-e.userData.currentOpacity;e.userData.currentOpacity+=3*s*(n/1e3),e.userData.currentOpacity<.001&&(e.userData.currentOpacity=0),t.material.opacity=.7*e.userData.currentOpacity,i.material.opacity=1*e.userData.currentOpacity,a.material.opacity=.7*e.userData.currentOpacity}}setVisible(e){this.visible=e}dispose(){for(const e of this.beads){const{redSprite:t,greenSprite:i,blueSprite:n}=e.userData;t.material.map&&t.material.map.dispose(),t.material.dispose(),i.material.map&&i.material.map.dispose(),i.material.dispose(),n.material.map&&n.material.map.dispose(),n.material.dispose(),this.scene.remove(e)}this.beads=[],this.sharedTexture&&(this.sharedTexture.dispose(),this.sharedTexture=null),this._directionToCamera=null,this._up=null,this._right=null,this._upVector=null,this._beadOffset=null,this._tempColor=null,this.scene=null}}class Pi{constructor(t,i,n=null){this.scene=t,this.sunRadius=i,this.sunMesh=n,this.eclipseType=wi,this.previousEclipseType=wi,this.enabled=!1,this.time=0,this.randomSeed=12345,this.isTransitioning=!1,this.transitionProgress=0,this.transitionDuration=400,this.transitionDirection="in",this.manualControl=!1,this.customShadowCoverage=void 0,this._directionToCamera=new e.Vector3,this._up=new e.Vector3(0,1,0),this._right=new e.Vector3,this._upVector=new e.Vector3,this._tempOffset=new e.Vector3,this._tempColor=new e.Color,this.createShadowDisk(),this.createCoronaDisk(),this.createCounterCoronaDisk(),this.sunMesh&&(this.scene.remove(this.coronaDisk),this.scene.remove(this.counterCoronaDisk),this.sunMesh.add(this.coronaDisk),this.sunMesh.add(this.counterCoronaDisk)),this.baileysBeads=new Di(t,i)}createShadowDisk(){const t=this.sunRadius,i=new e.CircleGeometry(t,256),n=new e.MeshBasicMaterial({color:0,transparent:!0,opacity:1,blending:e.MultiplyBlending,premultipliedAlpha:!0,side:e.DoubleSide,depthWrite:!1,depthTest:!1,fog:!1});this.shadowDisk=new e.Mesh(i,n),this.shadowDisk.renderOrder=1e4,this.shadowDisk.position.set(200,0,0),this.scene.add(this.shadowDisk)}createCoronaDisk(){const t=2.05*this.sunRadius,i=.6*this.sunRadius,n=new e.RingGeometry(i,t,256),a=new e.ShaderMaterial({uniforms:{time:{value:0},glowColor:{value:new e.Color(.9,.95,1)},intensity:{value:2.4},randomSeed:{value:this.randomSeed},uvRotation:{value:0},rayElongation:{value:1},uberHeroElongation:{value:1},isTotalEclipse:{value:0},layer1Mode:{value:11},layer1Strength:{value:2.155},layer1Enabled:{value:1},layer2Mode:{value:5},layer2Strength:{value:.695},layer2Enabled:{value:1},layer3Mode:{value:0},layer3Strength:{value:1},layer3Enabled:{value:0},layer4Mode:{value:0},layer4Strength:{value:1},layer4Enabled:{value:0}},vertexShader:"\n uniform float uvRotation;\n varying vec2 vUv;\n\n void main() {\n // Rotate UVs around center (0.5, 0.5)\n vec2 centeredUV = uv - 0.5;\n float cosRot = cos(uvRotation);\n float sinRot = sin(uvRotation);\n mat2 rotMatrix = mat2(cosRot, -sinRot, sinRot, cosRot);\n vec2 rotatedUV = rotMatrix * centeredUV;\n vUv = rotatedUV + 0.5;\n\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n ",fragmentShader:`\n uniform float time;\n uniform vec3 glowColor;\n uniform float intensity;\n uniform float randomSeed;\n uniform float rayElongation;\n uniform float uberHeroElongation;\n uniform float isTotalEclipse;\n\n // Blend Layer Uniforms (up to 4 layers)\n uniform float layer1Mode;\n uniform float layer1Strength;\n uniform float layer1Enabled;\n\n uniform float layer2Mode;\n uniform float layer2Strength;\n uniform float layer2Enabled;\n\n uniform float layer3Mode;\n uniform float layer3Strength;\n uniform float layer3Enabled;\n\n uniform float layer4Mode;\n uniform float layer4Strength;\n uniform float layer4Enabled;\n\n varying vec2 vUv;\n\n // ═══════════════════════════════════════════════════════════════════════════\n // UNIVERSAL BLEND MODES (injected from utils/blendModes.js)\n // ═══════════════════════════════════════════════════════════════════════════\n ${S}\n\n // Hash function for pseudo-random variation\n float hash(float n) {\n return fract(sin(n) * 43758.5453123);\n }\n\n // 2D hash for more variation\n float hash2(vec2 p) {\n return fract(sin(dot(p, vec2(12.9898 + randomSeed, 78.233 + randomSeed))) * 43758.5453);\n }\n\n void main() {\n // Calculate distance and angle from center\n vec2 center = vec2(0.5, 0.5);\n vec2 toCenter = vUv - center;\n float dist = length(toCenter) * 2.0; // Normalize to 0-1 range\n float angle = atan(toCenter.y, toCenter.x); // UVs are already rotated in vertex shader\n\n // Shadow edge - where corona rays start\n // Ring inner edge is at (sunRadius*0.85)/coronaRadius = 0.765/1.845 = 0.415\n // Start rays at sun's geometric edge (0.488) so they don't show inside sun\n float shadowEdge = 0.488;\n\n // Varied radial streamer pattern with artistic composition\n float rayIntensity = 0.0;\n\n // RULE OF THIRDS: Place 3 hero rays at compositionally strong points\n // Golden angles based on rule of thirds: 1/3, 2/3, and offset positions\n float heroAngles[3];\n heroAngles[0] = hash(randomSeed * 1.234) * 6.28318; // First hero ray (random rotation)\n heroAngles[1] = heroAngles[0] + 2.0944; // 120° apart (1/3 circle)\n heroAngles[2] = heroAngles[0] + 4.1888; // 240° apart (2/3 circle)\n\n // Process hero rays first (3 extra-long dramatic rays)\n for (int h = 0; h < 3; h++) {\n float rayAngle = heroAngles[h];\n float angleDiff = abs(mod(angle - rayAngle + 3.14159, 6.28318) - 3.14159);\n\n // Hero rays: extra long and prominent (fit within 0.535 normalized space)\n float baseHeroLength = 0.45 + hash(float(h) * 31.415 + randomSeed) * 0.08; // 0.45 to 0.53 (max available, longer!)\n\n // Apply UBER elongation: hero rays ALWAYS get extreme elongation (regardless of angle)\n // This creates 3 dramatic streamers that extend far in their respective directions\n float heroLength = baseHeroLength * uberHeroElongation;\n\n // Uber hero rays: keep them narrow but visible for dramatic pointy effect\n // Width scales with elongation to stay sharp but visible\n float baseHeroWidth = 0.15 + hash(float(h) * 27.183 + randomSeed) * 0.15; // 0.15 to 0.3 base width\n float narrowingFactor = mix(1.0, 0.3, (uberHeroElongation - 1.0) / max(uberHeroElongation, 1.0)); // 1.0 → 0.3 (70% narrower at max elongation)\n float heroWidth = baseHeroWidth * narrowingFactor; // Narrow when elongated = pointy!\n\n float distFromEdge = dist - shadowEdge;\n\n // Ghostly ethereal taper - very gradual falloff\n float taper = pow(1.0 - clamp(distFromEdge / max(heroLength, 0.001), 0.0, 1.0), 3.0);\n float rayWidth = heroWidth * taper;\n\n // Soft feathered edges instead of hard cutoff\n float edgeSoftness = 0.15; // Wider feather for smooth edges\n float angularMask = smoothstep(rayWidth + edgeSoftness, rayWidth - edgeSoftness, angleDiff);\n\n // Very gentle radial falloff for ethereal look\n float radialFalloff = pow(taper, 0.8);\n\n // Soft radial range with feathered ends\n float radialMask = smoothstep(-0.1, 0.05, distFromEdge) *\n smoothstep(heroLength + 0.15, heroLength - 0.05, distFromEdge);\n\n float heroIntensity = angularMask * radialFalloff * radialMask * 0.7; // Reduced intensity for ghostly effect\n rayIntensity = max(rayIntensity, heroIntensity);\n }\n\n // 20 supporting rays with rule-of-thirds-aware distribution\n for (float i = 0.0; i < 20.0; i++) {\n // Cluster more rays around hero ray positions (rule of thirds)\n float clusterTarget = mod(i, 3.0); // Which hero ray to cluster near\n float clusterAngle = heroAngles[int(clusterTarget)];\n\n // Base distribution with clustering tendency\n float spreadAngle = (i / 20.0) * 6.28318;\n float clusterPull = (hash(i * 13.579 + randomSeed) - 0.5) * 1.5; // Stronger variation\n float rayAngle = spreadAngle + clusterPull;\n\n float angleDiff = abs(mod(angle - rayAngle + 3.14159, 6.28318) - 3.14159);\n\n // Unique random values per ray\n float random1 = hash(i * 12.9898 + randomSeed);\n float random2 = hash(i * 78.233 + randomSeed);\n float random3 = hash(i * 37.719 + randomSeed);\n float random4 = hash(i * 93.989 + randomSeed);\n\n // Varied lengths following power law distribution (more short, fewer long)\n float lengthVariation = random1 * random1; // Squared for naturalistic distribution\n float baseRayLength = 0.1 + lengthVariation * 0.7; // 0.1 to 0.8\n\n // 20% chance of long streamers (supporting the hero rays)\n float isLong = step(0.80, random2);\n baseRayLength = mix(baseRayLength, 0.7 + random3 * 0.6, isLong); // 0.7 to 1.3\n\n // Apply directional elongation: rays pointing up/down (vertical) get elongated\n float verticalWeight = abs(sin(rayAngle));\n float elongationFactor = mix(1.0, rayElongation, verticalWeight);\n float rayLength = baseRayLength * elongationFactor;\n\n // EQUATORIAL ASYMMETRY (total eclipse only): rays along equator are more prominent\n // Solar minimum: streamers cluster along equatorial plane\n float equatorialWeight = abs(cos(rayAngle)); // 1.0 at horizontal, 0.0 at vertical\n float asymmetryBoost = mix(1.0, 1.0 + equatorialWeight * 0.5, isTotalEclipse);\n rayLength *= asymmetryBoost;\n\n // Varied widths with power law (more thin, fewer thick)\n float baseWidth = 0.03 + (random4 * random4) * 0.2; // 0.03 to 0.23 (naturally varied)\n\n // Taper: wide at base, narrow at tip\n float distFromEdge = dist - shadowEdge;\n\n // Ghostly ethereal taper - very gradual falloff\n float taper = pow(1.0 - clamp(distFromEdge / max(rayLength, 0.001), 0.0, 1.0), 3.5);\n float rayWidth = baseWidth * taper;\n\n // Soft feathered edges for ethereal wisps\n float edgeSoftness = 0.10; // Wider feather for smooth edges\n float angularMask = smoothstep(rayWidth + edgeSoftness, rayWidth - edgeSoftness, angleDiff);\n\n // Very gentle radial falloff for ghostly appearance\n float radialFalloff = pow(taper, 1.0);\n\n // Soft radial range with feathered ends\n float radialMask = smoothstep(-0.08, 0.03, distFromEdge) *\n smoothstep(rayLength + 0.12, rayLength - 0.03, distFromEdge);\n\n float streamerIntensity = angularMask * radialFalloff * radialMask * 0.5; // Reduced for ethereal wisps\n rayIntensity = max(rayIntensity, streamerIntensity);\n }\n\n // Base corona glow - thinner during total eclipse for realism\n float baseGlowWidth = mix(0.04, 0.015, isTotalEclipse); // Thinner during totality\n float baseGlow = smoothstep(shadowEdge - 0.01, shadowEdge, dist) *\n (1.0 - smoothstep(shadowEdge + baseGlowWidth * 0.5, shadowEdge + baseGlowWidth, dist));\n\n // Enhanced gradient: white → cool blue-white → deep blue with distance\n // Distance normalized to corona extent (0 = shadow edge, 1 = far corona)\n float coronaDist = clamp((dist - shadowEdge) / 0.6, 0.0, 1.0);\n\n // ═══════════════════════════════════════════════════════════════════════════\n // TOTAL ECLIPSE ENHANCEMENTS (scaled continuously by isTotalEclipse 0.0-1.0)\n // ═══════════════════════════════════════════════════════════════════════════\n\n // 1. CHROMOSPHERE RED RIM - thin pink/red ring at sun's edge (hydrogen emission)\n float rimStart = shadowEdge;\n float rimEnd = shadowEdge + 0.025;\n float chromosphereRim = smoothstep(rimStart - 0.005, rimStart, dist) *\n (1.0 - smoothstep(rimEnd - 0.01, rimEnd, dist));\n chromosphereRim *= 0.6 * isTotalEclipse; // Scale by eclipse progress\n vec3 chromosphereColor = vec3(1.0, 0.3, 0.4); // Pink-red (H-alpha emission)\n\n // 2. STRONGER BRIGHTNESS FALLOFF - inner corona much brighter\n // Mix between 1.0 (normal) and enhanced falloff based on isTotalEclipse\n float enhancedFalloff = mix(3.0, 0.3, pow(coronaDist, 0.7));\n float brightnessMultiplier = mix(1.0, enhancedFalloff, isTotalEclipse);\n\n // 3. F-CORONA OUTER GLOW - faint diffuse glow from interplanetary dust\n float fCoronaDist = clamp((dist - shadowEdge) / 1.2, 0.0, 1.0);\n float fCorona = (1.0 - fCoronaDist) * 0.08;\n fCorona *= smoothstep(0.3, 0.5, coronaDist);\n fCorona *= isTotalEclipse; // Scale by eclipse progress\n\n // 4. WISPY TENDRILS - add fine detail noise to ray intensity\n float noiseAngle = angle * 8.0 + time * 0.1;\n float noiseRadius = dist * 15.0;\n float wispyDetail = hash(noiseAngle + noiseRadius + randomSeed * 3.0) * 0.15;\n wispyDetail *= rayIntensity * isTotalEclipse; // Scale by eclipse progress\n\n // Combine: base glow + streamers + wispy detail\n float finalIntensity = (baseGlow * 0.6 + rayIntensity + wispyDetail) * intensity;\n finalIntensity *= brightnessMultiplier;\n\n // Multi-stage color gradient for realistic corona\n vec3 innerGlow = vec3(1.0, 1.0, 1.0); // Pure white at base\n vec3 middleGlow = vec3(0.9, 0.95, 1.0); // Cool white\n vec3 outerGlow = vec3(0.6, 0.75, 0.95); // Pale blue\n vec3 farGlow = vec3(0.3, 0.5, 0.8); // Deep blue\n\n // Three-stage color mix\n vec3 coronaColor;\n if (coronaDist < 0.3) {\n // Inner: white → cool white\n coronaColor = mix(innerGlow, middleGlow, coronaDist / 0.3);\n } else if (coronaDist < 0.7) {\n // Middle: cool white → pale blue\n coronaColor = mix(middleGlow, outerGlow, (coronaDist - 0.3) / 0.4);\n } else {\n // Outer: pale blue → deep blue\n coronaColor = mix(outerGlow, farGlow, (coronaDist - 0.7) / 0.3);\n }\n\n vec3 finalColor = coronaColor * finalIntensity;\n\n // Add chromosphere red rim (total eclipse only)\n finalColor += chromosphereColor * chromosphereRim * intensity;\n\n // Add F-corona outer glow (total eclipse only)\n finalColor += vec3(0.9, 0.85, 0.8) * fCorona * intensity; // Slightly warm white\n\n // ═══════════════════════════════════════════════════════════════════════════\n // BLEND LAYERS (Applied globally to entire corona)\n // These allow adjusting the appearance of the corona to prevent black edges\n // ═══════════════════════════════════════════════════════════════════════════\n\n // Layer 1\n if (layer1Enabled > 0.5) {\n vec3 blendColor1 = vec3(min(layer1Strength, 1.0));\n int mode1 = int(layer1Mode + 0.5);\n vec3 blended1 = clamp(applyBlendMode(finalColor, blendColor1, mode1), 0.0, 1.0);\n finalColor = clamp(blended1, 0.0, 1.0);\n }\n\n // Layer 2\n if (layer2Enabled > 0.5) {\n vec3 blendColor2 = vec3(min(layer2Strength, 1.0));\n int mode2 = int(layer2Mode + 0.5);\n vec3 blended2 = clamp(applyBlendMode(finalColor, blendColor2, mode2), 0.0, 1.0);\n finalColor = clamp(blended2, 0.0, 1.0);\n }\n\n // Layer 3\n if (layer3Enabled > 0.5) {\n vec3 blendColor3 = vec3(min(layer3Strength, 1.0));\n int mode3 = int(layer3Mode + 0.5);\n vec3 blended3 = clamp(applyBlendMode(finalColor, blendColor3, mode3), 0.0, 1.0);\n finalColor = clamp(blended3, 0.0, 1.0);\n }\n\n // Layer 4\n if (layer4Enabled > 0.5) {\n vec3 blendColor4 = vec3(min(layer4Strength, 1.0));\n int mode4 = int(layer4Mode + 0.5);\n vec3 blended4 = clamp(applyBlendMode(finalColor, blendColor4, mode4), 0.0, 1.0);\n finalColor = clamp(blended4, 0.0, 1.0);\n }\n\n // Sharp alpha falloff to prevent black bleeding in bloom\n // Higher power = sharper cutoff at edges (less semi-transparent area)\n float alphaFalloff = pow(1.0 - coronaDist, 3.0);\n float alpha = finalIntensity * alphaFalloff * 0.95;\n\n gl_FragColor = vec4(finalColor, alpha);\n }\n `,transparent:!0,blending:e.AdditiveBlending,depthWrite:!1,side:e.DoubleSide});this.coronaDisk=new e.Mesh(n,a),this.coronaDisk.position.set(0,0,0),this.coronaDisk.renderOrder=9998,this.scene.add(this.coronaDisk)}createCounterCoronaDisk(){const t=this.coronaDisk.geometry,i=this.randomSeed+5e3,n=new e.ShaderMaterial({uniforms:{time:{value:0},glowColor:{value:new e.Color(.9,.95,1)},intensity:{value:2.4},randomSeed:{value:i},uvRotation:{value:0},rayElongation:{value:1},uberHeroElongation:{value:1},isTotalEclipse:{value:0},layer1Mode:{value:11},layer1Strength:{value:2.155},layer1Enabled:{value:1},layer2Mode:{value:5},layer2Strength:{value:.695},layer2Enabled:{value:1},layer3Mode:{value:0},layer3Strength:{value:1},layer3Enabled:{value:0},layer4Mode:{value:0},layer4Strength:{value:1},layer4Enabled:{value:0}},vertexShader:this.coronaDisk.material.vertexShader,fragmentShader:this.coronaDisk.material.fragmentShader,transparent:!0,blending:e.AdditiveBlending,depthWrite:!1,side:e.DoubleSide});this.counterCoronaDisk=new e.Mesh(t,n),this.counterCoronaDisk.position.set(0,0,0),this.counterCoronaDisk.renderOrder=9997,this.scene.add(this.counterCoronaDisk)}setShadowCoverage(e){this.customShadowCoverage=e}setCoronaBlendLayer(e,t){if(e<1||e>4)return void console.error(`❌ Invalid corona layer number: ${e} (must be 1-4)`);const{mode:i=0,strength:n=1,enabled:a=!1}=t;this.coronaDisk?.material?.uniforms&&(this.coronaDisk.material.uniforms[`layer${e}Mode`].value=i,this.coronaDisk.material.uniforms[`layer${e}Strength`].value=n,this.coronaDisk.material.uniforms[`layer${e}Enabled`].value=a?1:0),this.counterCoronaDisk?.material?.uniforms&&(this.counterCoronaDisk.material.uniforms[`layer${e}Mode`].value=i,this.counterCoronaDisk.material.uniforms[`layer${e}Strength`].value=n,this.counterCoronaDisk.material.uniforms[`layer${e}Enabled`].value=a?1:0)}setEclipseType(e){if(e===this.eclipseType)return;const t=this.enabled;this.previousEclipseType=this.eclipseType,this.eclipseType=e,this.enabled=e!==wi,this.manualControl=!1;const i=Ci(this.previousEclipseType),n=Ci(e);this.startShadowCoverage=i.shadowCoverage,this.targetShadowCoverage=n.shadowCoverage,!t&&this.enabled?(this.transitionDirection="in",this.isTransitioning=!0,this.transitionProgress=0):t&&!this.enabled?(this.transitionDirection="out",this.isTransitioning=!0,this.transitionProgress=0):t&&this.enabled&&(this.isTransitioning=!0,this.transitionProgress=0,this.transitionDirection="switch")}easeInOutCubic(e){return e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2}setManualProgress(e){this.manualControl=!0,this.transitionProgress=Math.max(0,Math.min(1,e)),this.isTransitioning=!0,this.transitionDirection="in"}setManualShadowPosition(e){this.manualControl=!0,this.manualShadowPosition=Math.max(-2,Math.min(2,e)),this.isTransitioning=!0,this.transitionDirection="manual"}update(e,t,i,n=null){const a=e.position,s=t.position,o=t.scale.x;let r=1;if(null!==n&&n>.5){const e=2*(n-.5);r=e*(2-e)}else if(null!==n&&n<=.5){const e=2*n;r=1-e*e}const l=this.eclipseType===wi?3:1;if(this.time+=i*l,this.isTransitioning&&!this.manualControl){const e=i/this.transitionDuration;this.transitionProgress+=e,this.transitionProgress>=1&&(this.transitionProgress=1,this.isTransitioning=!1)}if(this.enabled||"out"===this.transitionDirection&&this.isTransitioning){const e="out"===this.transitionDirection&&this.isTransitioning?this.previousEclipseType:this.eclipseType,t=Ci(e),n=this.sunRadius*o,l=this.easeInOutCubic(this.transitionProgress);let h;h=void 0!==this.customShadowCoverage?this.customShadowCoverage:"switch"===this.transitionDirection&&this.isTransitioning&&void 0!==this.startShadowCoverage&&void 0!==this.targetShadowCoverage?this.startShadowCoverage+(this.targetShadowCoverage-this.startShadowCoverage)*l:t.shadowCoverage;const c=n*h/this.sunRadius;this.shadowDisk.scale.setScalar(c),this.currentShadowPosX=-2,"manual"===this.transitionDirection&&void 0!==this.manualShadowPosition?this.currentShadowPosX=this.manualShadowPosition:this.isTransitioning?"in"===this.transitionDirection?this.currentShadowPosX=2*l-2:"out"===this.transitionDirection?this.currentShadowPosX=0+1*l:"switch"===this.transitionDirection&&(this.currentShadowPosX=0):this.currentShadowPosX=0;const u=this.currentShadowPosX,d=2.5*n,m=u*d*.5,p=-u*u*d*.25;this._directionToCamera.subVectors(a,s).normalize(),this._right.crossVectors(this._directionToCamera,this._up).normalize(),this._upVector.crossVectors(this._right,this._directionToCamera).normalize();const g=0;this._tempOffset.copy(this._directionToCamera).multiplyScalar(g),this.shadowDisk.position.copy(s).add(this._tempOffset),this._tempOffset.copy(this._right).multiplyScalar(m),this.shadowDisk.position.add(this._tempOffset),this._tempOffset.copy(this._upVector).multiplyScalar(p),this.shadowDisk.position.add(this._tempOffset),this.shadowDisk.lookAt(a),this.coronaDisk.parent&&this.coronaDisk.parent!==this.scene||(this.coronaDisk.position.copy(s),this.counterCoronaDisk.position.copy(s),this.coronaDisk.scale.setScalar(o),this.counterCoronaDisk.scale.setScalar(o));const f=Math.abs(this.currentShadowPosX||0),y=2,v=Math.max(0,1-f/y);let b=0;if("switch"===this.transitionDirection&&this.isTransitioning){const e=this.previousEclipseType===Si,t=this.eclipseType===Si;t&&!e?b=l:!t&&e&&(b=1-l)}else e===Si&&(b=1);const w=1+(1+24*Math.pow(v,4)-1)*b,M=1+(1+199*Math.pow(v,5)-1)*b;this.coronaDisk.material.uniforms.rayElongation.value=w,this.counterCoronaDisk.material.uniforms.rayElongation.value=w,this.coronaDisk.material.uniforms.uberHeroElongation.value=M,this.counterCoronaDisk.material.uniforms.uberHeroElongation.value=M;const S=.5,x=.99,C=Math.max(0,Math.min(1,(v-S)/(x-S))),D=C*C*(3-2*C),P=D*b;this.coronaDisk.material.uniforms.isTotalEclipse.value=P,this.counterCoronaDisk.material.uniforms.isTotalEclipse.value=P;const B=b>0&&v>=S,k=1-.947*D*b;this.setCoronaBlendLayer(3,{mode:1,strength:k,enabled:B}),this.coronaDisk.lookAt(a),this.counterCoronaDisk.lookAt(a);let T=0;if(e===wi)T=i/1e3*.075;else if(e===Mi){const e=.075;T=i/1e3*(e-(e-.25*e)*v)}else if(e===Si){const e=.075;T=i/1e3*(e-(e-.05*e)*v)}this.coronaDisk.material.uniforms.uvRotation.value+=T,this.counterCoronaDisk.material.uniforms.uvRotation.value-=T;let E=1.2;if(e===wi)E=3.6;else if(e===Mi){const e=3.6,t=.08*e;this.transitionDirection,E=e-(e-t)*v}else if(e===Si){const e=3.6,t=.65*e;this.transitionDirection,E=e-(e-t)*v}this.coronaDisk.material.uniforms.intensity.value=E*r,this.counterCoronaDisk.material.uniforms.intensity.value=E*r,this.coronaDisk.material.uniforms.time.value=this.time,this.counterCoronaDisk.material.uniforms.time.value=this.time}else{this.shadowDisk.position.set(200,0,0),this.coronaDisk.parent&&this.coronaDisk.parent!==this.scene||(this.coronaDisk.position.copy(s),this.counterCoronaDisk.position.copy(s),this.coronaDisk.scale.setScalar(o),this.counterCoronaDisk.scale.setScalar(o)),this.coronaDisk.material.uniforms.rayElongation.value=1,this.counterCoronaDisk.material.uniforms.rayElongation.value=1,this.coronaDisk.material.uniforms.uberHeroElongation.value=1,this.counterCoronaDisk.material.uniforms.uberHeroElongation.value=1,this.coronaDisk.material.uniforms.isTotalEclipse.value=0,this.counterCoronaDisk.material.uniforms.isTotalEclipse.value=0,this.coronaDisk.material.uniforms.intensity.value=3.06*r,this.counterCoronaDisk.material.uniforms.intensity.value=3.06*r,this.setCoronaBlendLayer(3,{mode:1,strength:0,enabled:!1}),this.coronaDisk.lookAt(a),this.counterCoronaDisk.lookAt(a);const e=i/1e3*.075;this.coronaDisk.material.uniforms.uvRotation.value+=e,this.counterCoronaDisk.material.uniforms.uvRotation.value-=e,this.coronaDisk.material.uniforms.intensity.value=3.6*r,this.counterCoronaDisk.material.uniforms.intensity.value=3.6*r,this.coronaDisk.material.uniforms.time.value=this.time,this.counterCoronaDisk.material.uniforms.time.value=this.time}if(this.eclipseType===Si){let t=0,n=!1;if("manual"===this.transitionDirection){const e=Math.abs(this.currentShadowPosX),i=2;t=Math.max(0,Math.min(1,1-e/i)),t>=.9&&t<=1&&(n=!0)}else if("in"===this.transitionDirection&&this.isTransitioning){const e=.8;this.transitionProgress>=e&&(n=!0,t=.9+(this.transitionProgress-e)/(1-e)*.1)}else if("out"===this.transitionDirection&&this.isTransitioning){const e=.2;this.transitionProgress<=e&&(n=!0,t=1-this.transitionProgress/e*.1)}else this.isTransitioning||(t=1,n=!0);this.baileysBeads.setVisible(n),this.baileysBeads.update(e,s,t,i,o)}else this.baileysBeads.setVisible(!1),this.baileysBeads.update(e,s,0,i,o)}dispose(){this.shadowDisk&&(this.scene.remove(this.shadowDisk),this.shadowDisk.geometry.dispose(),this.shadowDisk.material.dispose(),this.shadowDisk=null),this.coronaDisk&&(this.coronaDisk.parent&&this.coronaDisk.parent.remove(this.coronaDisk),this.coronaDisk.geometry.dispose(),this.coronaDisk.material.dispose(),this.coronaDisk=null),this.counterCoronaDisk&&(this.counterCoronaDisk.parent&&this.counterCoronaDisk.parent.remove(this.counterCoronaDisk),this.counterCoronaDisk.material.dispose(),this.counterCoronaDisk=null),this.baileysBeads&&(this.baileysBeads.dispose(),this.baileysBeads=null),this._directionToCamera=null,this._up=null,this._right=null,this._upVector=null,this._tempOffset=null,this._tempColor=null,this.scene=null,this.sunMesh=null}}class Bi{constructor(e){this.material=e,this.eclipseType="off",this.progress=0,this.targetProgress=0,this.animating=!1,this.bloodMoonColor={r:.85,g:.18,b:.08},this.animationDuration=3e3,this.startTime=0,this.shadowX=-2,this.shadowY=0,this.shadowRadius=.7,this.targetShadowX=-2,this.shadowSpeed=1,this.material.uniforms.eclipseProgress||(this.material.uniforms.eclipseProgress={value:0},this.material.uniforms.eclipseIntensity={value:0},this.material.uniforms.bloodMoonColor={value:[this.bloodMoonColor.r,this.bloodMoonColor.g,this.bloodMoonColor.b]},this.material.uniforms.eclipseShadowPos={value:[this.shadowX,this.shadowY]},this.material.uniforms.eclipseShadowRadius={value:this.shadowRadius})}setEclipseType(e){if(this.eclipseType===e)return;const t="off"===this.eclipseType;switch(this.eclipseType=e,t&&"off"!==e&&(this.shadowX=-2,this.material.uniforms.eclipseShadowPos.value=[this.shadowX,this.shadowY]),e){case"off":this.targetProgress=0,this.targetShadowX=2;break;case"penumbral":this.targetProgress=.3,this.targetShadowX=-1;break;case"partial":this.targetProgress=.65,this.targetShadowX=-.6;break;case"total":this.targetProgress=1,this.targetShadowX=0;break;default:return void console.warn(`Unknown lunar eclipse type: ${e}`)}this.animating=!0,this.startTime=performance.now()}update(e){if(!this.animating)return;const t=performance.now()-this.startTime,i=Math.min(t/this.animationDuration,1),n=this.easeInOutCubic(i);this.progress=this.progress+(this.targetProgress-this.progress)*n,this.shadowX=this.shadowX+(this.targetShadowX-this.shadowX)*n*this.shadowSpeed,this.material.uniforms.eclipseProgress.value=this.progress,this.material.uniforms.eclipseShadowPos.value=[this.shadowX,this.shadowY];let a=0;"total"===this.eclipseType?a=this.progress:"partial"===this.eclipseType?a=.6*this.progress:"penumbral"===this.eclipseType&&(a=.25*this.progress),this.material.uniforms.eclipseIntensity.value=a,i>=1&&(this.animating=!1)}easeInOutCubic(e){return e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2}reset(){this.progress=0,this.targetProgress=0,this.shadowX=-2,this.targetShadowX=-2,this.animating=!1,this.eclipseType="off",this.material.uniforms.eclipseProgress&&(this.material.uniforms.eclipseProgress.value=0,this.material.uniforms.eclipseIntensity.value=0,this.material.uniforms.eclipseShadowPos.value=[this.shadowX,this.shadowY])}dispose(){}}const ki={quartz:{sssStrength:.8,sssAbsorption:[2.8,2.9,3],sssScatterDistance:[.2,.2,.25],sssThicknessBias:.6,sssThicknessScale:1.8,sssCurvatureScale:3,sssAmbient:.12,frostiness:.15,innerGlowStrength:.2,fresnelIntensity:1.5,causticIntensity:1.2},emerald:{sssStrength:2,sssAbsorption:[.05,4,.1],sssScatterDistance:[.1,.5,.1],sssThicknessBias:.65,sssThicknessScale:1.8,sssCurvatureScale:3,sssAmbient:.1,frostiness:.2,innerGlowStrength:.15,fresnelIntensity:1.2,emotionColorBleed:.35},ruby:{sssStrength:1.8,sssAbsorption:[4,.03,.08],sssScatterDistance:[.4,.04,.08],sssThicknessBias:.65,sssThicknessScale:1.9,sssCurvatureScale:2.5,sssAmbient:.08,frostiness:.12,innerGlowStrength:.12,fresnelIntensity:1.2,causticIntensity:1.15,emotionColorBleed:.35},sapphire:{sssStrength:2.2,sssAbsorption:[.15,.4,4],sssScatterDistance:[.1,.15,.5],sssThicknessBias:.65,sssThicknessScale:1.8,sssCurvatureScale:3,sssAmbient:.1,frostiness:.18,innerGlowStrength:.15,fresnelIntensity:1.3,emotionColorBleed:.35},amethyst:{sssStrength:2.5,sssAbsorption:[3,.05,4.5],sssScatterDistance:[.4,.05,.5],sssThicknessBias:.7,sssThicknessScale:2,sssCurvatureScale:3,sssAmbient:.08,frostiness:.18,innerGlowStrength:.12,fresnelIntensity:1.4,emotionColorBleed:.35}},Ti=`\nuniform float time;\nuniform vec3 emotionColor;\nuniform float glowIntensity;\nuniform float opacity;\n\n// Crystal appearance controls\nuniform float frostiness; // 0 = clear glass, 1 = fully frosted (default: 0.7)\nuniform float fresnelPower; // Edge brightness falloff (default: 3.0)\nuniform float fresnelIntensity; // Edge brightness strength (default: 1.2)\nuniform float innerGlowStrength; // How much inner soul shows through (default: 0.8)\nuniform float surfaceRoughness; // Surface texture variation (default: 0.3)\n\n// Enhanced lighting controls\nuniform float shadowDarkness; // How dark shadows can get (0-1, default: 0.4)\nuniform float specularIntensity; // Edge highlight brightness (default: 0.8)\nuniform float specularPower; // Specular falloff sharpness (default: 32.0)\nuniform float transmissionContrast; // Thin/thick brightness ratio (default: 1.5)\nuniform float minBrightness; // Minimum brightness floor (default: 0.05)\n\n// Noise scale controls\nuniform float surfaceNoiseScale; // Scale of surface frost pattern (default: 1.5)\nuniform float noiseFrequency; // Frequency of hash noise pattern (default: 1.0)\n\n// Internal caustics - light pooling inside the gem\nuniform float causticIntensity; // Brightness of internal caustics (default: 0.4)\nuniform float causticScale; // Scale of caustic pattern (default: 3.0)\nuniform float causticSpeed; // Animation speed of caustics (default: 0.15)\n\n// Texture\nuniform sampler2D crystalTexture;\nuniform float textureStrength; // How much texture affects appearance (default: 0.5)\n\n// Soul refraction - samples soul rendered to texture with optical distortion\nuniform sampler2D soulTexture; // Soul mesh rendered to texture\nuniform vec2 resolution; // Screen resolution for UV calculation\nuniform vec2 soulTextureSize; // Soul render target size (may differ from screen)\nuniform vec2 soulScreenCenter; // Soul center projected to screen UV (0-1 range)\nuniform float refractionIndex; // Index of refraction (1.5 glass, 2.4 diamond)\nuniform float refractionStrength; // Distortion magnitude (0.1-0.5)\n\n// Physically-based subsurface scattering\nuniform float sssStrength; // Overall SSS intensity (0-1)\nuniform vec3 sssAbsorption; // Absorption coefficients per RGB channel\nuniform vec3 sssScatterDistance; // Mean free path / scatter radius per RGB\nuniform float sssThicknessBias; // Thickness offset (0-1)\nuniform float sssThicknessScale; // Thickness multiplier\nuniform float sssCurvatureScale; // How much curvature affects SSS\nuniform float sssAmbient; // Ambient SSS contribution\nuniform vec3 sssLightDir; // Primary light direction for SSS\nuniform vec3 sssLightColor; // Light color for SSS\n\n// Emotion color bleed - how much soul color tints the gem material\nuniform float emotionColorBleed; // 0 = gem color only, 1 = full emotion tint (default: 0.0)\n\n// Component-specific blend layers\n// Shell layers - affect the frosted crystal shell\nuniform float shellLayer1Mode;\nuniform float shellLayer1Strength;\nuniform float shellLayer1Enabled;\nuniform float shellLayer2Mode;\nuniform float shellLayer2Strength;\nuniform float shellLayer2Enabled;\n\n// Soul layers - affect the inner glowing soul color\nuniform float soulLayer1Mode;\nuniform float soulLayer1Strength;\nuniform float soulLayer1Enabled;\nuniform float soulLayer2Mode;\nuniform float soulLayer2Strength;\nuniform float soulLayer2Enabled;\n\n// Rim layers - affect the fresnel rim glow\nuniform float rimLayer1Mode;\nuniform float rimLayer1Strength;\nuniform float rimLayer1Enabled;\nuniform float rimLayer2Mode;\nuniform float rimLayer2Strength;\nuniform float rimLayer2Enabled;\n\n// SSS layers - affect subsurface scattering contribution\nuniform float sssLayer1Mode;\nuniform float sssLayer1Strength;\nuniform float sssLayer1Enabled;\nuniform float sssLayer2Mode;\nuniform float sssLayer2Strength;\nuniform float sssLayer2Enabled;\n\nvarying vec3 vPosition;\nvarying vec3 vNormal;\nvarying vec3 vViewPosition;\nvarying vec2 vUv;\n\n// ═══════════════════════════════════════════════════════════════════════════\n// NOISE FUNCTIONS for surface variation and frosted effect\n// ═══════════════════════════════════════════════════════════════════════════\n\n// Simple 3D noise for frosted surface\nfloat hash(vec3 p) {\n p = p * noiseFrequency; // Apply frequency control\n p = fract(p * vec3(443.8975, 397.2973, 491.1871));\n p += dot(p.zxy, p.yxz + 19.19);\n return fract(p.x * p.y * p.z);\n}\n\nfloat noise3D(vec3 p) {\n vec3 i = floor(p);\n vec3 f = fract(p);\n f = f * f * (3.0 - 2.0 * f); // Smoothstep\n\n float n = mix(\n mix(\n mix(hash(i), hash(i + vec3(1, 0, 0)), f.x),\n mix(hash(i + vec3(0, 1, 0)), hash(i + vec3(1, 1, 0)), f.x),\n f.y\n ),\n mix(\n mix(hash(i + vec3(0, 0, 1)), hash(i + vec3(1, 0, 1)), f.x),\n mix(hash(i + vec3(0, 1, 1)), hash(i + vec3(1, 1, 1)), f.x),\n f.y\n ),\n f.z\n );\n return n;\n}\n\n// Fractal Brownian Motion for natural-looking frosted texture\nfloat fbm(vec3 p) {\n float value = 0.0;\n float amplitude = 0.5;\n float frequency = 1.0;\n\n for (int i = 0; i < 3; i++) {\n value += amplitude * noise3D(p * frequency);\n frequency *= 2.0;\n amplitude *= 0.5;\n }\n return value;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// BLEND MODES (from universal library)\n// ═══════════════════════════════════════════════════════════════════════════\n${S}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// ENHANCED LIGHTING FUNCTIONS\n// ═══════════════════════════════════════════════════════════════════════════\n\n// Calculate ambient occlusion from geometry\nfloat calculateAO(vec3 normal, vec3 viewDir, vec3 position) {\n // Faces pointing away from view are in shadow\n float viewAO = max(0.0, dot(normal, viewDir));\n\n // Use light direction for directional shadow instead of gravity\n // This creates shadows on the side away from light\n vec3 lightDir = normalize(vec3(0.5, 1.0, 0.8)); // Match sssLightDir default\n float lightAO = dot(normal, lightDir) * 0.5 + 0.5;\n\n // Combine AO factors - no gravity term\n return viewAO * 0.5 + lightAO * 0.5;\n}\n\n// Calculate specular highlights on facet edges\nfloat calculateFacetSpecular(vec3 normal, vec3 viewDir, vec3 lightDir, float power) {\n // Detect facet edges from normal discontinuities\n float edgeDetect = length(fwidth(normal)) * 15.0;\n edgeDetect = smoothstep(0.1, 0.5, edgeDetect);\n\n // Standard Blinn-Phong specular\n vec3 halfVec = normalize(lightDir + viewDir);\n float specular = pow(max(0.0, dot(normal, halfVec)), power);\n\n // Boost specular on edges\n specular += edgeDetect * 0.5;\n\n return specular;\n}\n\n// Calculate "fire" - intense sparkle points that real gems exhibit\n// These are concentrated, view-dependent highlights from light dispersion\nfloat calculateFire(vec3 normal, vec3 viewDir, vec3 lightDir) {\n // Primary fire highlight - VERY sharp falloff for pinpoint sparkles\n vec3 reflectDir = reflect(-lightDir, normal);\n float fire1 = pow(max(0.0, dot(reflectDir, viewDir)), 512.0);\n\n // Secondary fire from different light angle (simulates environment)\n vec3 lightDir2 = normalize(vec3(-0.3, 0.8, 0.5));\n vec3 reflectDir2 = reflect(-lightDir2, normal);\n float fire2 = pow(max(0.0, dot(reflectDir2, viewDir)), 384.0);\n\n // Third fire point for more sparkle\n vec3 lightDir3 = normalize(vec3(0.7, 0.4, -0.6));\n vec3 reflectDir3 = reflect(-lightDir3, normal);\n float fire3 = pow(max(0.0, dot(reflectDir3, viewDir)), 256.0);\n\n // Combine fire points - only keep the brightest peaks\n float fire = fire1 + fire2 * 0.7 + fire3 * 0.5;\n\n // Facet edges catch more fire\n float edgeFactor = length(fwidth(normal)) * 20.0;\n fire *= (1.0 + edgeFactor * 2.0);\n\n return fire;\n}\n\n// Calculate bright lines along facet edges where bevels catch light\nfloat calculateFacetEdgeLines(vec3 normal, vec3 viewDir, vec3 lightDir) {\n // Detect edges from normal discontinuities\n float edgeMag = length(fwidth(normal));\n\n // Sharp threshold to create distinct lines\n float edgeLine = smoothstep(0.02, 0.08, edgeMag);\n\n // Modulate by light angle - edges facing light are brighter\n float lightFacing = max(0.0, dot(normal, lightDir));\n edgeLine *= (0.3 + lightFacing * 0.7);\n\n // View-dependent - edges perpendicular to view are more visible\n float viewPerp = 1.0 - abs(dot(normal, viewDir));\n edgeLine *= (0.5 + viewPerp * 0.5);\n\n return edgeLine;\n}\n\n// Calculate light transmission based on thickness\nfloat calculateTransmission(vec3 position, vec3 normal, vec3 viewDir, float contrast) {\n // Thickness estimation - edges are thin, center is thick\n float distFromCenter = length(position);\n float thickness = smoothstep(0.0, 0.6, distFromCenter);\n\n // View angle affects perceived thickness\n float viewThickness = 1.0 - abs(dot(normal, viewDir));\n thickness = mix(thickness, viewThickness, 0.5);\n\n // Thin areas transmit more light (brighter), thick areas are darker\n float transmission = 1.0 - thickness * contrast * 0.5;\n\n return clamp(transmission, 0.3, 1.5);\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// PHYSICALLY-BASED SUBSURFACE SCATTERING\n// ═══════════════════════════════════════════════════════════════════════════\n\n// ═══════════════════════════════════════════════════════════════════════════\n// PHYSICALLY-BASED SUBSURFACE SCATTERING\n// Based on Disney's Burley Normalized Diffusion (2015)\n// ═══════════════════════════════════════════════════════════════════════════\n\n// SSS Uniforms - declare these in your shader\n// uniform float sssStrength; // Overall SSS intensity (0-1)\n// uniform vec3 sssAbsorption; // Absorption coefficients per RGB channel\n// uniform vec3 sssScatterDistance; // Mean free path / scatter radius per RGB\n// uniform float sssThicknessBias; // Thickness offset (0-1)\n// uniform float sssThicknessScale; // Thickness multiplier\n// uniform float sssCurvatureScale; // How much curvature affects SSS\n// uniform float sssAmbient; // Ambient SSS contribution\n// uniform vec3 sssLightDir; // Primary light direction for SSS\n// uniform vec3 sssLightColor; // Light color for SSS\n\n/**\n * Estimate local thickness from geometry\n * Uses the relationship between view angle and surface normal\n * Combined with a simple depth approximation\n *\n * @param normal - Surface normal in view space\n * @param viewDir - View direction\n * @param position - Vertex position (for depth-based estimation)\n * @param thicknessBias - Base thickness value\n * @param thicknessScale - Thickness multiplier\n * @return Estimated thickness (0-1)\n */\nfloat estimateThickness(vec3 normal, vec3 viewDir, vec3 position, float thicknessBias, float thicknessScale) {\n // Method 1: View-dependent thickness\n // Surfaces facing away from viewer are "thicker" (light travels further)\n float viewThickness = 1.0 - abs(dot(normal, viewDir));\n\n // Method 2: Position-based depth (simple spherical assumption)\n // Objects are thinner at edges, thicker in center\n float posDepth = 1.0 - length(position) * 0.5;\n posDepth = clamp(posDepth, 0.0, 1.0);\n\n // Method 3: Curvature hint from normal variation\n // High-frequency normal changes indicate thin areas (edges, details)\n // This is approximated by the gradient of the normal\n float curvatureHint = length(fwidth(normal)) * 10.0;\n curvatureHint = 1.0 - clamp(curvatureHint, 0.0, 1.0);\n\n // Combine methods with weighting\n float thickness = viewThickness * 0.4 + posDepth * 0.4 + curvatureHint * 0.2;\n\n // Apply bias and scale\n thickness = thicknessBias + thickness * thicknessScale;\n\n return clamp(thickness, 0.01, 1.0);\n}\n\n/**\n * Beer's Law absorption - light attenuates exponentially through material\n * Different wavelengths absorb at different rates, creating color shifts\n *\n * @param thickness - Distance light travels through material\n * @param absorption - Absorption coefficients per RGB (higher = more absorbed)\n * @return Transmittance per RGB channel (0-1)\n */\nvec3 beersLawAbsorption(float thickness, vec3 absorption) {\n // Beer-Lambert Law: T = e^(-σ * d)\n // Where σ is absorption coefficient, d is distance\n return exp(-absorption * thickness * 4.0);\n}\n\n/**\n * Burley Normalized Diffusion Profile\n * Disney's approximation of the full BSSRDF, energy-conserving\n *\n * R(r) = A * s * (e^(-s*r) + e^(-s*r/3)) / (8πr)\n *\n * @param radius - Distance from entry point (normalized)\n * @param scatterDist - Mean free path / diffusion length\n * @return Diffusion weight at this radius\n */\nfloat burleyDiffusionProfile(float radius, float scatterDist) {\n // Prevent division by zero\n float r = max(radius, 0.001);\n float s = 1.0 / max(scatterDist, 0.001);\n\n // Burley's two-term approximation\n float term1 = exp(-s * r);\n float term2 = exp(-s * r / 3.0);\n\n // Normalized profile (simplified, without 8πr for real-time)\n float profile = (term1 + term2) * s * 0.25;\n\n return profile;\n}\n\n/**\n * Christensen-Burley Normalized Diffusion\n * Improved version with better energy conservation\n *\n * @param radius - Distance from entry point\n * @param A - Surface albedo\n * @param d - Diffusion length (mean free path)\n * @return RGB diffusion weights\n */\nvec3 christensenBurleyDiffusion(float radius, vec3 A, vec3 d) {\n vec3 result = vec3(0.0);\n\n // Per-channel diffusion (different scatter distances for RGB)\n for (int i = 0; i < 3; i++) {\n float s = 1.9 - A[i] + 3.5 * (A[i] - 0.8) * (A[i] - 0.8);\n s = 1.0 / (s * max(d[i], 0.001));\n\n float r = max(radius, 0.001);\n\n // Two-exponential fit\n float profile = s * (exp(-s * r) + exp(-s * r / 3.0)) / (8.0 * 3.14159 * r);\n\n result[i] = profile;\n }\n\n return result;\n}\n\n/**\n * Calculate curvature factor for SSS intensity\n * SSS is more visible on curved surfaces (fingers, ears, edges)\n *\n * @param normal - Surface normal\n * @return Curvature factor (higher = more curved)\n */\nfloat calculateCurvature(vec3 normal) {\n // Use screen-space derivatives to estimate curvature\n vec3 dx = dFdx(normal);\n vec3 dy = dFdy(normal);\n\n // Curvature magnitude\n float curvature = length(dx) + length(dy);\n\n // Normalize to useful range\n return clamp(curvature * 5.0, 0.0, 1.0);\n}\n\n/**\n * Full physically-based SSS calculation\n * Combines all components for realistic translucent materials\n *\n * @param normal - Surface normal (view space)\n * @param viewDir - View direction\n * @param position - Vertex position\n * @param lightDir - Light direction\n * @param lightColor - Light color\n * @param baseColor - Material base/albedo color\n * @param sssStrength - Overall SSS strength\n * @param absorption - Absorption coefficients RGB (inverted: higher = MORE of that color)\n * @param scatterDist - Scatter distance RGB (higher = more scatter)\n * @param thicknessBias - Base thickness\n * @param thicknessScale - Thickness multiplier\n * @param curvatureScale - Curvature influence\n * @param ambient - Ambient SSS contribution\n * @return Final SSS color contribution\n */\nvec3 calculatePhysicalSSS(\n vec3 normal,\n vec3 viewDir,\n vec3 position,\n vec3 lightDir,\n vec3 lightColor,\n vec3 baseColor,\n float sssStrength,\n vec3 absorption,\n vec3 scatterDist,\n float thicknessBias,\n float thicknessScale,\n float curvatureScale,\n float ambient\n) {\n if (sssStrength < 0.001) {\n return vec3(0.0);\n }\n\n // ─────────────────────────────────────────────────────────────────────\n // THICKNESS ESTIMATION\n // ─────────────────────────────────────────────────────────────────────\n float thickness = estimateThickness(normal, viewDir, position, thicknessBias, thicknessScale);\n\n // ─────────────────────────────────────────────────────────────────────\n // ABSORPTION COLOR (Beer's Law with artist-friendly values)\n // Creates the characteristic color of translucent materials\n // absorption values: high value = MORE of that color passes through (transmitted)\n // This is inverted from physics but intuitive: jade has high green absorption\n // ─────────────────────────────────────────────────────────────────────\n // Use absorption directly as transmittance - higher = more of that color shows\n // Normalize to prevent any channel from dominating\n float maxAbsorption = max(absorption.r, max(absorption.g, absorption.b));\n vec3 normalizedTransmit = absorption / max(maxAbsorption, 0.001);\n\n // Apply thickness-based falloff - thin areas show more color\n float thicknessFactor = 1.0 - thickness * 0.3;\n vec3 colorShift = normalizedTransmit * thicknessFactor;\n\n // Ensure minimum color presence\n colorShift = max(colorShift, vec3(0.15));\n\n // ─────────────────────────────────────────────────────────────────────\n // SCATTER INTENSITY\n // How much light scatters based on material properties\n // ─────────────────────────────────────────────────────────────────────\n // Higher scatter distance = more light gets through, but keep it subtle\n vec3 scatterIntensity = scatterDist * 0.8;\n scatterIntensity = clamp(scatterIntensity, vec3(0.1), vec3(1.0));\n\n // ─────────────────────────────────────────────────────────────────────\n // LIGHTING TERMS - Boosted for visibility\n // ─────────────────────────────────────────────────────────────────────\n\n // Back-lighting: light passing through from behind (strongest SSS cue)\n float NdotL = dot(normal, lightDir);\n float backLight = max(0.0, -NdotL);\n backLight = pow(backLight, 1.2) * 1.5; // Boosted\n\n // Wrap lighting: soft diffuse that wraps around\n float wrapLight = (NdotL + 1.0) * 0.5; // Full wrap, 0-1 range\n wrapLight = wrapLight * wrapLight;\n\n // View-dependent translucency (looking through thin parts)\n float VdotL = dot(viewDir, -lightDir);\n float translucency = pow(max(0.0, VdotL), 1.5) * 1.2; // Boosted\n\n // Edge glow (fresnel-like SSS at silhouettes)\n float edgeGlow = pow(1.0 - abs(dot(normal, viewDir)), 2.0);\n\n // ─────────────────────────────────────────────────────────────────────\n // THICKNESS-BASED TRANSMISSION\n // Thin areas let more light through\n // ─────────────────────────────────────────────────────────────────────\n float thinTransmission = 1.0 - thickness * 0.5;\n thinTransmission = max(thinTransmission, 0.3);\n\n // ─────────────────────────────────────────────────────────────────────\n // CURVATURE ENHANCEMENT\n // ─────────────────────────────────────────────────────────────────────\n float curvature = calculateCurvature(normal);\n float curvatureFactor = 1.0 + curvature * curvatureScale;\n\n // ─────────────────────────────────────────────────────────────────────\n // COMBINE ALL TERMS\n // ─────────────────────────────────────────────────────────────────────\n\n // Total light contribution (more additive for visibility)\n float totalLight = backLight + translucency * 0.8 + wrapLight * 0.4 + edgeGlow * 0.5;\n totalLight *= curvatureFactor * thinTransmission;\n\n // Base SSS color - colorShift IS the tint (e.g., green for jade)\n // Don't multiply by baseColor to avoid washing out with emotionColor\n vec3 sssColor = colorShift * scatterIntensity;\n\n // Ambient SSS (always visible, gives material its translucent look)\n vec3 ambientSSS = sssColor * ambient;\n\n // Direct SSS from lighting - subtle contribution\n vec3 directSSS = sssColor * lightColor * totalLight * 0.5;\n\n // Final combination\n vec3 finalSSS = directSSS + ambientSSS;\n\n // Apply overall strength (linear, no boost to prevent blowout)\n return finalSSS * sssStrength;\n}\n\n/**\n * Simplified SSS for performance-critical scenarios\n * Uses pre-computed approximations\n *\n * @param normal - Surface normal\n * @param viewDir - View direction\n * @param lightDir - Light direction\n * @param thickness - Pre-computed or approximated thickness\n * @param baseColor - Material color\n * @param scatterColor - Scatter tint color\n * @param strength - SSS strength\n * @return SSS color contribution\n */\nvec3 calculateSimpleSSS(\n vec3 normal,\n vec3 viewDir,\n vec3 lightDir,\n float thickness,\n vec3 baseColor,\n vec3 scatterColor,\n float strength\n) {\n if (strength < 0.001) {\n return vec3(0.0);\n }\n\n // Back-lighting\n float backLight = pow(max(0.0, dot(viewDir, -lightDir)), 2.0);\n\n // Transmittance (simplified Beer's law)\n float transmit = exp(-thickness * 2.0);\n\n // Edge enhancement\n float edge = pow(1.0 - abs(dot(normal, viewDir)), 2.0);\n\n // Combine\n float sssIntensity = (backLight * transmit + edge * 0.3) * strength;\n\n return mix(baseColor, scatterColor, 0.5) * sssIntensity;\n}\n\n\nvoid main() {\n vec3 normal = normalize(vNormal);\n vec3 viewDir = normalize(vViewPosition);\n\n // ═══════════════════════════════════════════════════════════════════════\n // FRESNEL EFFECT - Colored rim at edges (cyan-tinted)\n // ═══════════════════════════════════════════════════════════════════════\n float fresnel = pow(1.0 - abs(dot(normal, viewDir)), fresnelPower);\n fresnel *= fresnelIntensity;\n\n // ═══════════════════════════════════════════════════════════════════════\n // AMBIENT OCCLUSION - Dark shadows for depth\n // ═══════════════════════════════════════════════════════════════════════\n float ao = calculateAO(normal, viewDir, vPosition);\n float shadowFactor = mix(1.0, ao, shadowDarkness);\n\n // ═══════════════════════════════════════════════════════════════════════\n // SPECULAR HIGHLIGHTS - Bright catches on facet edges\n // ═══════════════════════════════════════════════════════════════════════\n vec3 lightDir = normalize(sssLightDir);\n float specular = calculateFacetSpecular(normal, viewDir, lightDir, specularPower);\n specular *= specularIntensity;\n\n // ═══════════════════════════════════════════════════════════════════════\n // LIGHT TRANSMISSION - Thin areas glow, thick areas darken\n // ═══════════════════════════════════════════════════════════════════════\n float transmission = calculateTransmission(vPosition, normal, viewDir, transmissionContrast);\n\n // ═══════════════════════════════════════════════════════════════════════\n // TEXTURE SAMPLING - Crystal surface detail from UV-mapped texture\n // ═══════════════════════════════════════════════════════════════════════\n vec4 texColor = texture2D(crystalTexture, vUv);\n float texValue = (texColor.r + texColor.g + texColor.b) / 3.0; // Grayscale\n\n // ═══════════════════════════════════════════════════════════════════════\n // FROSTED SURFACE - Subtle cloudy variation (not opaque white!)\n // ═══════════════════════════════════════════════════════════════════════\n float surfaceNoise = fbm(vPosition * surfaceNoiseScale + time * 0.02);\n surfaceNoise = surfaceNoise * surfaceRoughness;\n\n // ═══════════════════════════════════════════════════════════════════════\n // INNER SOUL GLOW - The glowing core visible through the crystal\n // ═══════════════════════════════════════════════════════════════════════\n\n // Animated internal glow - subtle pulsing\n float glowPulse = sin(time * 0.5) * 0.15 + 0.85;\n\n // Core glow - strongest in center, fades toward edges with sharper falloff\n float distFromCenter = length(vPosition);\n float coreGlow = exp(-distFromCenter * 2.5) * glowPulse;\n\n // ═══════════════════════════════════════════════════════════════════════\n // INTERNAL CAUSTICS - Light refraction pools inside the gem\n // Creates bright concentrated spots that shift with viewing angle\n // Real caustics form where refracted light rays converge inside the gem\n // Now with CHROMATIC ABERRATION - different wavelengths refract differently\n // ═══════════════════════════════════════════════════════════════════════\n\n // Refract view direction through gem surface with different IOR per wavelength\n // Red refracts less (higher IOR ratio), blue refracts more (lower IOR ratio)\n // Chromatic separation is REDUCED for colored gems to avoid color contamination\n // Quartz (low sssStrength) gets full rainbow, colored gems get subtle dispersion\n float chromaticStrength = 1.0 - clamp((sssStrength - 0.5) * 0.8, 0.0, 0.8);\n float iorR = mix(0.57, 0.70, chromaticStrength); // Red - approaches green for colored gems\n float iorB = mix(0.57, 0.44, chromaticStrength); // Blue - approaches green for colored gems\n vec3 refractDirR = refract(-viewDir, normal, iorR);\n vec3 refractDirG = refract(-viewDir, normal, 0.57); // Green - always medium\n vec3 refractDirB = refract(-viewDir, normal, iorB);\n\n // Animated drift\n float causticTime = time * causticSpeed;\n vec3 drift = vec3(causticTime * 0.3, causticTime * 0.2, causticTime * 0.1);\n\n // Sample positions for each color channel\n // Offset is also reduced for colored gems to minimize chromatic contamination\n float spatialOffset = mix(1.0, 3.0, chromaticStrength);\n vec3 causticPosR = vPosition * causticScale + refractDirR * spatialOffset + drift;\n vec3 causticPosG = vPosition * causticScale + refractDirG * spatialOffset + drift;\n vec3 causticPosB = vPosition * causticScale + refractDirB * spatialOffset + drift;\n\n // Create caustic pattern for each channel\n // Red channel\n float waveR1 = sin(causticPosR.x * 2.0 + causticPosR.y * 1.5 + causticPosR.z);\n float waveR2 = sin(causticPosR.y * 2.3 - causticPosR.x * 1.2 + causticPosR.z * 1.8);\n float waveR3 = sin(causticPosR.z * 1.9 + causticPosR.x * 0.8 - causticPosR.y * 1.4);\n float interferenceR = (waveR1 + waveR2 + waveR3) / 3.0;\n float causticR = smoothstep(0.3, 0.8, interferenceR);\n\n // Green channel\n float waveG1 = sin(causticPosG.x * 2.0 + causticPosG.y * 1.5 + causticPosG.z);\n float waveG2 = sin(causticPosG.y * 2.3 - causticPosG.x * 1.2 + causticPosG.z * 1.8);\n float waveG3 = sin(causticPosG.z * 1.9 + causticPosG.x * 0.8 - causticPosG.y * 1.4);\n float interferenceG = (waveG1 + waveG2 + waveG3) / 3.0;\n float causticG = smoothstep(0.3, 0.8, interferenceG);\n\n // Blue channel\n float waveB1 = sin(causticPosB.x * 2.0 + causticPosB.y * 1.5 + causticPosB.z);\n float waveB2 = sin(causticPosB.y * 2.3 - causticPosB.x * 1.2 + causticPosB.z * 1.8);\n float waveB3 = sin(causticPosB.z * 1.9 + causticPosB.x * 0.8 - causticPosB.y * 1.4);\n float interferenceB = (waveB1 + waveB2 + waveB3) / 3.0;\n float causticB = smoothstep(0.3, 0.8, interferenceB);\n\n // Combine into RGB caustic with chromatic separation\n vec3 causticRGB = vec3(causticR, causticG, causticB);\n\n // Add noise variation to break up uniformity\n float noiseVar = noise3D(causticPosG * 0.5);\n causticRGB *= (0.7 + noiseVar * 0.6);\n\n // Clamp caustic peaks to prevent hot spot blobs\n // This keeps caustics subtle and distributed rather than concentrated\n causticRGB = min(causticRGB, vec3(0.6));\n\n // Caustics are MORE visible in thick areas (center) where light has more\n // material to refract through and pool\n float thickness = abs(dot(normal, viewDir)); // 1 at center, 0 at edges\n causticRGB *= (0.3 + thickness * 0.7);\n\n // Apply intensity control\n causticRGB *= causticIntensity;\n\n // Boost caustic visibility for colored gems to compensate for reduced chromatic spread\n // Colored gems (high sssStrength) have suppressed chromatic aberration, so boost their\n // monochromatic caustics to maintain internal "life" and sparkle\n float causticBoost = 1.0 + clamp((sssStrength - 0.5) * 0.8, 0.0, 0.6);\n causticRGB *= causticBoost;\n\n // Also keep a scalar caustic for compatibility\n float caustic = (causticRGB.r + causticRGB.g + causticRGB.b) / 3.0;\n\n // Animation pattern (0-1 range) - core glow + caustic hot spots\n float animationPattern = coreGlow * 0.7 + caustic * 0.3;\n\n // Soul intensity controls overall brightness with more dramatic falloff\n // Brighter near core, darker at edges\n float baseLevel = 0.1; // Lower base for more contrast\n float patternContrast = 0.9; // Higher contrast for more variation\n float soulIntensity = (baseLevel + animationPattern * patternContrast) * innerGlowStrength;\n\n // Apply transmission to soul - thin areas glow brighter\n soulIntensity *= transmission;\n\n // Soul color from emotion\n // NOTE: emotionColor is pre-normalized by normalizeColorLuminance() in Core3DManager\n // This ensures consistent perceived brightness across all emotions (yellow won't wash out, blue stays visible)\n // Reduced intensity to prevent blowout - soul should be visible but not white\n float glowCurve = sqrt(innerGlowStrength * glowIntensity) * 0.5;\n vec3 soulColor = emotionColor * soulIntensity * glowCurve;\n // Clamp soul color to prevent blowout\n soulColor = min(soulColor, vec3(0.8));\n\n // ═══════════════════════════════════════════════════════════════════════\n // REFRACTED SOUL SAMPLING - True optical lensing through crystal\n // The soul is rendered to a texture, then sampled with refraction distortion\n // This creates the effect of looking at the soul through a crystal lens\n // ═══════════════════════════════════════════════════════════════════════\n\n // ═══════════════════════════════════════════════════════════════════\n // REFRACTED SOUL SAMPLING\n // Sample the soul texture with physical refraction distortion\n // Creates the "looking through glass" lensing effect\n // ═══════════════════════════════════════════════════════════════════\n vec3 refractedSoulColor = vec3(0.0);\n float refractedSoulAlpha = 0.0;\n\n if (soulTextureSize.x > 0.0 && soulScreenCenter.x >= 0.0) {\n // Fragment's screen UV position\n vec2 fragUV = gl_FragCoord.xy / soulTextureSize;\n\n // Calculate refraction offset using Snell's law\n float ior = refractionIndex;\n vec3 refractedDir = refract(-viewDir, normal, 1.0 / ior);\n\n // Apply refraction distortion toward the soul center\n // This creates the magnifying glass effect - bending light toward center\n vec2 refractionOffset = refractedDir.xy * refractionStrength * 0.1;\n\n // Sample at fragment position with refraction offset\n // The soul texture contains the soul rendered at its actual screen position\n vec2 soulUV = fragUV + refractionOffset;\n\n // Clamp to valid UV range\n soulUV = clamp(soulUV, 0.0, 1.0);\n\n // Sample the soul texture\n vec4 soulSample = texture2D(soulTexture, soulUV);\n\n // Store for later use in final composition\n refractedSoulColor = soulSample.rgb;\n refractedSoulAlpha = soulSample.a;\n\n // Also blend into soulColor for existing pipeline\n soulColor = mix(soulColor, soulSample.rgb, soulSample.a * 0.5);\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // SOUL BLEND LAYERS - Apply before combining with shell\n // ═══════════════════════════════════════════════════════════════════════\n if (soulLayer1Enabled > 0.5) {\n int mode = int(soulLayer1Mode + 0.5);\n vec3 blendResult = applyBlendMode(soulColor, emotionColor * soulLayer1Strength, mode);\n soulColor = mix(soulColor, blendResult, soulLayer1Strength);\n }\n if (soulLayer2Enabled > 0.5) {\n int mode = int(soulLayer2Mode + 0.5);\n vec3 blendResult = applyBlendMode(soulColor, emotionColor * soulLayer2Strength, mode);\n soulColor = mix(soulColor, blendResult, soulLayer2Strength);\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // FROSTED SHELL - Milky white layer with INTERNAL lighting model\n // Lit from inside: thin edges bright, thick center dark\n // ═══════════════════════════════════════════════════════════════════════\n\n // Frosted glass base - will be modulated by thickness\n // Lower base values allow for darker thick areas while maintaining bright edges\n vec3 frostBase = vec3(0.45, 0.48, 0.55) * frostiness;\n\n // THICKNESS-BASED DARKNESS (internal lighting model)\n // Face-on facets are THICK (light travels far through) = DARK\n // Edge-on facets are THIN (light escapes easily) = BRIGHT\n float edgeThinness = 1.0 - abs(dot(normal, viewDir)); // 1 at edges, 0 facing camera\n\n // Apply curve to make face-on areas darker more aggressively\n float thinness = pow(edgeThinness, 0.7); // Push more area toward dark\n\n // Thickness multiplier: thin edges=bright (1.0), thick face-on=dark (0.01 for near-black)\n float thicknessMultiplier = 0.01 + thinness * 0.99;\n frostBase *= thicknessMultiplier;\n\n // Surface variation adds subtle texture\n frostBase += vec3(surfaceNoise * 0.03);\n\n // Specular highlights on facet edges (external light catch)\n float facetHighlight = pow(max(0.0, dot(normal, normalize(vec3(0.5, 1.0, 0.8)))), 16.0);\n frostBase += vec3(facetHighlight * 0.2);\n\n // SOUL BLEED - Inner glow illuminates the shell from inside\n // Use gentler falloff so color reaches the shell surface\n float soulBleed = exp(-distFromCenter * 1.2) * innerGlowStrength;\n // Stronger color contribution - tint the frost with emotion color\n frostBase = mix(frostBase, frostBase + emotionColor * 0.4, soulBleed);\n\n // ═══════════════════════════════════════════════════════════════════════\n // SHELL BLEND LAYERS - Apply to frosted shell\n // ═══════════════════════════════════════════════════════════════════════\n if (shellLayer1Enabled > 0.5) {\n int mode = int(shellLayer1Mode + 0.5);\n vec3 blendResult = applyBlendMode(frostBase, emotionColor * shellLayer1Strength, mode);\n frostBase = mix(frostBase, blendResult, shellLayer1Strength);\n }\n if (shellLayer2Enabled > 0.5) {\n int mode = int(shellLayer2Mode + 0.5);\n vec3 blendResult = applyBlendMode(frostBase, emotionColor * shellLayer2Strength, mode);\n frostBase = mix(frostBase, blendResult, shellLayer2Strength);\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // FRESNEL RIM - Bright emotion-colored edge glow\n // ═══════════════════════════════════════════════════════════════════════\n vec3 rimColor = mix(vec3(0.5, 0.9, 1.0), emotionColor, 0.6);\n vec3 rimGlow = rimColor * fresnel * 1.2;\n\n // ═══════════════════════════════════════════════════════════════════════\n // RIM BLEND LAYERS - Apply to fresnel rim glow\n // ═══════════════════════════════════════════════════════════════════════\n if (rimLayer1Enabled > 0.5) {\n int mode = int(rimLayer1Mode + 0.5);\n vec3 blendResult = applyBlendMode(rimGlow, emotionColor * rimLayer1Strength, mode);\n rimGlow = mix(rimGlow, blendResult, rimLayer1Strength);\n }\n if (rimLayer2Enabled > 0.5) {\n int mode = int(rimLayer2Mode + 0.5);\n vec3 blendResult = applyBlendMode(rimGlow, emotionColor * rimLayer2Strength, mode);\n rimGlow = mix(rimGlow, blendResult, rimLayer2Strength);\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // PHYSICALLY-BASED SUBSURFACE SCATTERING\n // Uses BSSRDF with Beer's Law absorption and Burley diffusion profile\n // ═══════════════════════════════════════════════════════════════════════\n vec3 sss = calculatePhysicalSSS(\n normal,\n viewDir,\n vPosition,\n normalize(sssLightDir),\n sssLightColor,\n emotionColor,\n sssStrength,\n sssAbsorption,\n sssScatterDistance,\n sssThicknessBias,\n sssThicknessScale,\n sssCurvatureScale,\n sssAmbient\n );\n\n // ═══════════════════════════════════════════════════════════════════════\n // SSS BLEND LAYERS - Apply to subsurface scattering contribution\n // ═══════════════════════════════════════════════════════════════════════\n if (sssLayer1Enabled > 0.5) {\n int mode = int(sssLayer1Mode + 0.5);\n vec3 blendResult = applyBlendMode(sss, emotionColor * sssLayer1Strength, mode);\n sss = mix(sss, blendResult, sssLayer1Strength);\n }\n if (sssLayer2Enabled > 0.5) {\n int mode = int(sssLayer2Mode + 0.5);\n vec3 blendResult = applyBlendMode(sss, emotionColor * sssLayer2Strength, mode);\n sss = mix(sss, blendResult, sssLayer2Strength);\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // COMBINE - Frosted shell base + soul glow (soul adds to shell, doesn't replace)\n // ═══════════════════════════════════════════════════════════════════════\n\n // Start with shell as base - preserves dark shadows\n vec3 finalColor = frostBase;\n\n // Add soul glow on top (additive, not replacement) - concentrated in center\n // Soul should illuminate dark areas but not wash out entirely\n float soulBlendFactor = soulIntensity * 0.6;\n finalColor += soulColor * soulBlendFactor;\n\n // Apply texture - blend based on texture brightness and strength\n vec3 texContribution = texColor.rgb * textureStrength;\n finalColor = mix(finalColor, finalColor + texContribution, textureStrength);\n\n // Apply SSS material color - PRESERVE BRIGHTNESS, only change HUE\n // The sssAbsorption values define the material color hue\n // But thickness-based darkness must be preserved for gemstone look\n if (sssStrength > 0.01) {\n // Get current brightness (this includes thickness darkening)\n float currentLum = dot(finalColor, vec3(0.299, 0.587, 0.114));\n\n // Normalize absorption to get hue direction (0-1 range)\n vec3 absorption = sssAbsorption;\n float maxAbs = max(max(absorption.r, absorption.g), absorption.b);\n vec3 hue = absorption / max(maxAbs, 0.001);\n\n // Create material color that PRESERVES current brightness\n // This keeps dark areas dark while tinting them with the gem color\n float hueLum = dot(hue, vec3(0.299, 0.587, 0.114));\n vec3 materialColor = hue * currentLum / max(hueLum, 0.001);\n\n // Clamp to prevent blowout on bright areas\n materialColor = min(materialColor, vec3(1.0));\n\n // Add subtle variation from SSS lighting calculation\n float sssLum = dot(sss, vec3(0.299, 0.587, 0.114));\n materialColor *= (0.9 + sssLum * 0.2);\n\n // Replace crystal color with material color\n float replaceAmount = sssStrength * 0.7;\n finalColor = mix(finalColor, materialColor, replaceAmount);\n }\n\n // Add rim glow, tinted toward material color\n if (sssStrength > 0.01) {\n vec3 absorption = sssAbsorption;\n float maxAbs = max(max(absorption.r, absorption.g), absorption.b);\n vec3 hue = absorption / max(maxAbs, 0.001);\n // Stronger tint for colored gems - use gem hue directly\n float rimTintStrength = clamp(sssStrength * 0.6, 0.0, 0.95);\n vec3 tintedRim = rimGlow * mix(vec3(1.0), hue * 1.2, rimTintStrength);\n // Cap rim to prevent bloom\n tintedRim = min(tintedRim, vec3(0.5));\n finalColor += tintedRim;\n } else {\n finalColor += rimGlow;\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // SPECULAR HIGHLIGHTS - Add bright hot spots\n // Tinted by gem color for colored gems to prevent white bloom\n // ═══════════════════════════════════════════════════════════════════════\n vec3 specularColor = vec3(1.0, 0.98, 0.95); // Warm white highlights for clear gems\n float specularIntensityMod = 1.0;\n\n if (sssStrength > 0.5) {\n // Tint specular by gem color to prevent white bloom\n vec3 absorption = sssAbsorption;\n float maxAbs = max(max(absorption.r, absorption.g), absorption.b);\n vec3 gemHue = absorption / max(maxAbs, 0.001);\n float colorStrength = clamp((sssStrength - 0.5) * 0.5, 0.0, 1.0);\n // Use gem hue for specular color\n specularColor = mix(specularColor, gemHue * 1.3, colorStrength);\n // Also reduce specular intensity for colored gems\n specularIntensityMod = mix(1.0, 0.4, colorStrength);\n }\n\n vec3 specularContrib = specularColor * specular * transmission * specularIntensityMod;\n specularContrib = min(specularContrib, vec3(0.5)); // Cap specular to prevent bloom\n finalColor += specularContrib;\n\n // ═══════════════════════════════════════════════════════════════════════\n // FACET EDGE LINES - Bright catches along beveled edges\n // ═══════════════════════════════════════════════════════════════════════\n float edgeLines = calculateFacetEdgeLines(normal, viewDir, lightDir);\n finalColor += vec3(edgeLines * 0.15) * transmission;\n\n // ═══════════════════════════════════════════════════════════════════════\n // SATURATION BOOST AT THIN EDGES\n // Real gems have MORE saturated color at thin edges where light escapes\n // ═══════════════════════════════════════════════════════════════════════\n if (sssStrength > 0.01) {\n // thinness: 1 at edges, 0 facing camera\n float satBoost = thinness * 0.4; // Up to 40% saturation boost at edges\n\n // Get current color's saturation\n float maxC = max(max(finalColor.r, finalColor.g), finalColor.b);\n float minC = min(min(finalColor.r, finalColor.g), finalColor.b);\n float currentSat = maxC > 0.001 ? (maxC - minC) / maxC : 0.0;\n\n // Boost saturation at thin areas\n if (maxC > 0.001 && currentSat > 0.01) {\n // Calculate luminance\n float lum = dot(finalColor, vec3(0.299, 0.587, 0.114));\n // Increase saturation by moving away from gray toward the color\n vec3 gray = vec3(lum);\n float newSat = min(currentSat + satBoost, 1.0);\n float satRatio = currentSat > 0.001 ? newSat / currentSat : 1.0;\n finalColor = gray + (finalColor - gray) * satRatio;\n }\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // FINAL THICKNESS APPLICATION - Apply AFTER all additive terms\n // This ensures thick areas stay dark even with glow added\n // ═══════════════════════════════════════════════════════════════════════\n // thicknessMultiplier: 0.15 in thick center, 1.0 at thin edges\n finalColor *= thicknessMultiplier;\n\n // ═══════════════════════════════════════════════════════════════════════\n // INTERNAL CAUSTICS - Bright spots from light concentration inside gem\n // Now with chromatic aberration for rainbow dispersion effect\n // Applied AFTER thickness darkening so they punch through dark areas\n // ═══════════════════════════════════════════════════════════════════════\n if (causticIntensity > 0.01) {\n // Get material hue for tinting caustics\n vec3 causticTint = vec3(1.0); // Default white\n float causticTintStrength = 0.4; // Default for clear gems\n if (sssStrength > 0.5) {\n vec3 absorption = sssAbsorption;\n float maxAbs = max(max(absorption.r, absorption.g), absorption.b);\n vec3 hue = absorption / max(maxAbs, 0.001);\n // Stronger tint for colored gems to prevent white bloom\n causticTintStrength = clamp((sssStrength - 0.5) * 0.8 + 0.4, 0.4, 0.9);\n causticTint = mix(vec3(1.0), hue * 1.2, causticTintStrength);\n }\n // Add RGB caustic with chromatic aberration\n // Reduce raw RGB blend for colored gems\n float rawBlend = mix(0.3, 0.1, clamp((sssStrength - 0.5) * 0.5, 0.0, 1.0));\n vec3 causticFinal = causticRGB * causticTint + causticRGB * rawBlend;\n causticFinal = min(causticFinal, vec3(0.4)); // Cap to prevent bloom\n finalColor += causticFinal;\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // FIRE - Intense sparkle points from light dispersion in facets\n // The "fire" effect that makes gems sparkle brilliantly\n // ═══════════════════════════════════════════════════════════════════════\n float fire = calculateFire(normal, viewDir, lightDir);\n\n // Tint fire by gem color - colored gems should have tinted highlights\n // Pure white fire only for quartz/clear gems (low sssStrength)\n vec3 fireColor = vec3(1.0, 0.99, 0.97); // Base warm white\n float fireIntensity = 0.3; // Base intensity for clear gems\n float fireClamp = 1.5; // Max fire value for clear gems\n\n if (sssStrength > 0.5) {\n // Get gem hue from absorption - this IS the gem's color\n vec3 absorption = sssAbsorption;\n float maxAbs = max(max(absorption.r, absorption.g), absorption.b);\n vec3 gemHue = absorption / max(maxAbs, 0.001);\n\n // For colored gems, fire should BE the gem color, not white\n // The more colored the gem (higher sssStrength), the more the fire matches the gem\n float colorStrength = clamp((sssStrength - 0.5) * 0.5, 0.0, 1.0);\n\n // Use gem hue directly as fire color - NOT mixed with white\n // This ensures fire can never bloom to white\n fireColor = gemHue * 1.2; // Slight brightness boost but stay saturated\n\n // Reduce fire intensity AND clamp for colored gems to prevent bloom washout\n // Colored gems should have subtle, saturated fire, not bright white spots\n fireIntensity = mix(0.3, 0.08, colorStrength); // Much lower for colored gems\n fireClamp = mix(1.5, 0.5, colorStrength); // Much lower clamp for colored gems\n }\n\n // Apply fire clamp BEFORE multiplying by color\n fire = min(fire, fireClamp);\n\n // Calculate fire contribution and clamp to prevent any channel from blooming\n vec3 fireContribution = fireColor * fire * fireIntensity;\n fireContribution = min(fireContribution, vec3(0.4)); // Hard cap on fire brightness\n finalColor += fireContribution;\n\n // Ensure minimum brightness - allow near-black for gemstones\n // minBrightness of 0.01 allows true darks while preventing total black\n finalColor = max(finalColor, vec3(minBrightness));\n\n // ═══════════════════════════════════════════════════════════════════════\n // ALPHA - More opaque for visibility\n // ═══════════════════════════════════════════════════════════════════════\n\n // Higher base opacity\n float baseAlpha = 0.6 + frostiness * 0.25;\n\n // Fresnel makes edges solid\n float rimAlpha = fresnel * 0.3;\n\n // Soul glow adds opacity\n float glowAlpha = soulIntensity * 0.15;\n\n float finalAlpha = min(baseAlpha + rimAlpha + glowAlpha, 0.95) * opacity;\n\n // ═══════════════════════════════════════════════════════════════════════\n // REFRACTED SOUL - Add the soul visible through the crystal\n // This is the actual soul mesh rendered to texture and sampled with refraction\n // ═══════════════════════════════════════════════════════════════════════\n if (refractedSoulAlpha > 0.01) {\n // The soul should glow through the crystal, tinted by the crystal's color\n // Use additive blending so the soul illuminates the crystal from within\n vec3 soulGlow = refractedSoulColor * refractedSoulAlpha;\n\n // Tint the soul by the crystal's SSS color for colored gems\n // emotionColorBleed controls how much pure emotion color comes through\n // 0 = fully tinted by gem color, 1 = pure emotion color\n if (sssStrength > 0.01) {\n vec3 absorption = sssAbsorption;\n float maxAbs = max(max(absorption.r, absorption.g), absorption.b);\n vec3 gemHue = absorption / max(maxAbs, 0.001);\n float tintAmount = sssStrength * 0.5 * (1.0 - emotionColorBleed);\n soulGlow *= mix(vec3(1.0), gemHue, tintAmount);\n }\n\n // Add soul glow to final color\n finalColor += soulGlow * 0.8;\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // EMOTION COLOR BLEED - Additional inner glow from soul emotion\n // Adds pure emotion color as light shining through the gem from the soul\n // ═══════════════════════════════════════════════════════════════════════\n if (emotionColorBleed > 0.001 && sssStrength > 0.01) {\n // Inner glow based on thickness - thinner areas show more soul light\n float innerGlow = 1.0 - abs(dot(normal, viewDir)); // Edges are thin\n innerGlow = pow(innerGlow, 1.5) * emotionColorBleed;\n\n // Also add glow near the core\n float coreProximity = exp(-distFromCenter * 2.0);\n innerGlow += coreProximity * emotionColorBleed * 0.5;\n\n // Add pure emotion color as inner light\n finalColor += emotionColor * innerGlow * 0.4;\n }\n\n gl_FragColor = vec4(finalColor, finalAlpha);\n}\n`,Ei={time:0,glowIntensity:1,opacity:1,frostiness:.55,fresnelPower:2.8,fresnelIntensity:.35,innerGlowStrength:.55,surfaceRoughness:.12,shadowDarkness:.6,specularIntensity:.9,specularPower:28,transmissionContrast:1,minBrightness:.005,surfaceNoiseScale:1.5,noiseFrequency:1.33,causticIntensity:.8,causticScale:2,causticSpeed:.12,textureStrength:.55,refractionIndex:1.5,refractionStrength:.5,resolution:[1920,1080],soulTextureSize:[1920,1080],soulScreenCenter:[.5,.5],sssStrength:.65,sssAbsorption:[2.4,2.5,2.8],sssScatterDistance:[.35,.4,.45],sssThicknessBias:.18,sssThicknessScale:.6,sssCurvatureScale:1.8,sssAmbient:.3,sssLightDir:[.5,1,.8],sssLightColor:[1,.98,.95],shellLayer1Mode:0,shellLayer1Strength:0,shellLayer1Enabled:0,shellLayer2Mode:0,shellLayer2Strength:0,shellLayer2Enabled:0,soulLayer1Mode:0,soulLayer1Strength:0,soulLayer1Enabled:0,soulLayer2Mode:0,soulLayer2Strength:0,soulLayer2Enabled:0,rimLayer1Mode:0,rimLayer1Strength:0,rimLayer1Enabled:0,rimLayer2Mode:0,rimLayer2Strength:0,rimLayer2Enabled:0,sssLayer1Mode:0,sssLayer1Strength:0,sssLayer1Enabled:0,sssLayer2Mode:0,sssLayer2Strength:0,sssLayer2Enabled:0};function Ii(t,i,n={}){const{glowColor:a=[1,1,.95],glowIntensity:s=1,materialVariant:o=null,emotionData:r=null,assetBasePath:l="/assets"}=n;return"custom"===i.material?function(t,i,n,a,s,o){const r=new e.TextureLoader;switch(t){case"moon":return function(t,i,n,a=null,s="/assets"){if("multiplexer"===a)return{material:U(t,{resolution:"2k",glowColor:new e.Color(i[0],i[1],i[2]),glowIntensity:n,assetBasePath:s}),type:"moon-multiplexer"};return{material:L(t,{resolution:"2k",glowColor:new e.Color(i[0],i[1],i[2]),glowIntensity:n,moonPhase:"full",assetBasePath:s}),type:"moon"}}(r,i,n,a,o);case"crystal":return Ai(i,n,"crystal",{sssPreset:"quartz"},o);case"rough":return Ai(i,n,"rough",{frostiness:.05,innerGlowStrength:0,fresnelIntensity:1.6},o);case"heart":return Ai(i,n,"heart",{frostiness:.475,innerGlowStrength:.117,fresnelIntensity:1.206},o);case"star":return Ai(i,n,"star",{sssPreset:"citrine"},o);default:return console.warn("Unknown custom material type:",t),null}}(t,a,s,o,0,l):"emissive"===i.material?function(t,i,n,a,s,o){const r=new e.TextureLoader;return"sun"===t?function(e,t,i,n=null,a=null,s="/assets"){return{material:X(e,{glowColor:t,glowIntensity:i,resolution:"4k",materialVariant:n,assetBasePath:s}),type:"sun"}}(r,i,n,a,s,o):(console.warn("Unknown emissive material type:",t),null)}(t,a,s,o,r,l):null}function Ai(t,i,n="crystal",a={},s="/assets"){const{vertexShader:o,fragmentShader:r}={vertexShader:"\nvarying vec3 vPosition;\nvarying vec3 vNormal;\nvarying vec3 vViewPosition;\nvarying vec2 vUv;\n\nvoid main() {\n vUv = uv;\n vPosition = position;\n vNormal = normalize(normalMatrix * normal);\n\n vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);\n vViewPosition = -mvPosition.xyz;\n\n gl_Position = projectionMatrix * mvPosition;\n}\n",fragmentShader:Ti};let l=null;if(n){const t=new e.TextureLoader,i={crystal:`${s}/textures/Crystal/crystal.jpg`,rough:`${s}/textures/Crystal/rough.jpg`,heart:`${s}/textures/Crystal/heart.jpg`,star:`${s}/textures/Crystal/star.jpg`},a=i[n]||i.crystal;l=t.load(a,void 0,e=>console.warn(`💎 ${n} texture failed to load:`,e))}const h=a.sssPreset?ki[a.sssPreset]:null;return{material:new e.ShaderMaterial({uniforms:{time:{value:0},emotionColor:{value:new e.Color(t[0],t[1],t[2])},glowIntensity:{value:i},opacity:{value:1},frostiness:{value:a.frostiness??Ei.frostiness},fresnelPower:{value:a.fresnelPower??Ei.fresnelPower},fresnelIntensity:{value:a.fresnelIntensity??Ei.fresnelIntensity},innerGlowStrength:{value:a.innerGlowStrength??Ei.innerGlowStrength},surfaceRoughness:{value:Ei.surfaceRoughness},shadowDarkness:{value:a.shadowDarkness??Ei.shadowDarkness},specularIntensity:{value:a.specularIntensity??Ei.specularIntensity},specularPower:{value:a.specularPower??Ei.specularPower},transmissionContrast:{value:a.transmissionContrast??Ei.transmissionContrast},minBrightness:{value:a.minBrightness??Ei.minBrightness},surfaceNoiseScale:{value:Ei.surfaceNoiseScale},noiseFrequency:{value:Ei.noiseFrequency},causticIntensity:{value:a.causticIntensity??Ei.causticIntensity},causticScale:{value:a.causticScale??Ei.causticScale},causticSpeed:{value:a.causticSpeed??Ei.causticSpeed},crystalTexture:{value:l},textureStrength:{value:"heart"===n?.35:n?Ei.textureStrength:0},soulTexture:{value:null},resolution:{value:new e.Vector2(Ei.resolution[0],Ei.resolution[1])},soulTextureSize:{value:new e.Vector2(Ei.soulTextureSize[0],Ei.soulTextureSize[1])},soulScreenCenter:{value:new e.Vector2(Ei.soulScreenCenter[0],Ei.soulScreenCenter[1])},refractionIndex:{value:a.refractionIndex??Ei.refractionIndex},refractionStrength:{value:a.refractionStrength??Ei.refractionStrength},sssStrength:{value:a.sssStrength??h?.sssStrength??Ei.sssStrength},sssAbsorption:{value:new e.Vector3(...a.sssAbsorption??h?.sssAbsorption??Ei.sssAbsorption)},sssScatterDistance:{value:new e.Vector3(...a.sssScatterDistance??h?.sssScatterDistance??Ei.sssScatterDistance)},sssThicknessBias:{value:a.sssThicknessBias??h?.sssThicknessBias??Ei.sssThicknessBias},sssThicknessScale:{value:a.sssThicknessScale??h?.sssThicknessScale??Ei.sssThicknessScale},sssCurvatureScale:{value:a.sssCurvatureScale??h?.sssCurvatureScale??Ei.sssCurvatureScale},sssAmbient:{value:a.sssAmbient??h?.sssAmbient??Ei.sssAmbient},sssLightDir:{value:new e.Vector3(...a.sssLightDir??Ei.sssLightDir)},sssLightColor:{value:new e.Vector3(...a.sssLightColor??Ei.sssLightColor)},emotionColorBleed:{value:a.emotionColorBleed??h?.emotionColorBleed??0},shellLayer1Mode:{value:Ei.shellLayer1Mode},shellLayer1Strength:{value:Ei.shellLayer1Strength},shellLayer1Enabled:{value:Ei.shellLayer1Enabled},shellLayer2Mode:{value:Ei.shellLayer2Mode},shellLayer2Strength:{value:Ei.shellLayer2Strength},shellLayer2Enabled:{value:Ei.shellLayer2Enabled},soulLayer1Mode:{value:Ei.soulLayer1Mode},soulLayer1Strength:{value:Ei.soulLayer1Strength},soulLayer1Enabled:{value:Ei.soulLayer1Enabled},soulLayer2Mode:{value:Ei.soulLayer2Mode},soulLayer2Strength:{value:Ei.soulLayer2Strength},soulLayer2Enabled:{value:Ei.soulLayer2Enabled},rimLayer1Mode:{value:Ei.rimLayer1Mode},rimLayer1Strength:{value:Ei.rimLayer1Strength},rimLayer1Enabled:{value:Ei.rimLayer1Enabled},rimLayer2Mode:{value:Ei.rimLayer2Mode},rimLayer2Strength:{value:Ei.rimLayer2Strength},rimLayer2Enabled:{value:Ei.rimLayer2Enabled},sssLayer1Mode:{value:Ei.sssLayer1Mode},sssLayer1Strength:{value:Ei.sssLayer1Strength},sssLayer1Enabled:{value:Ei.sssLayer1Enabled},sssLayer2Mode:{value:Ei.sssLayer2Mode},sssLayer2Strength:{value:Ei.sssLayer2Strength},sssLayer2Enabled:{value:Ei.sssLayer2Enabled}},vertexShader:o,fragmentShader:r,transparent:!0,side:e.DoubleSide,depthWrite:!1,blending:e.NormalBlending}),type:"crystal"}}function Ri(e){e&&(e.map&&e.map.dispose(),e.normalMap&&e.normalMap.dispose(),e.emissiveMap&&e.emissiveMap.dispose(),e.roughnessMap&&e.roughnessMap.dispose(),e.metalnessMap&&e.metalnessMap.dispose())}const zi=new Map;async function _i(e,t={}){if(zi.has(e)){const t=zi.get(e);if(t.loaded)return t}const i=ie[e];if(!i)return console.warn(`[GeometryCache] Unknown geometry type: ${e}`),null;const n={geometry:null,material:null,materialType:null,config:i,loaded:!1};if(i.geometryLoader?n.geometry=await i.geometryLoader(t.assetBasePath):n.geometry=i.geometry,"custom"===i.material||"emissive"===i.material){const a=Ii(e,i,{glowColor:t.glowColor||[1,1,.95],glowIntensity:t.glowIntensity||1,materialVariant:t.materialVariant,emotionData:t.emotionData,assetBasePath:t.assetBasePath});a&&(n.material=a.material,n.materialType=a.type)}return n.loaded=!0,zi.set(e,n),n}async function Oi(e={}){await Promise.all(["crystal","rough","heart","moon","sun"].map(t=>_i(t,e)))}function Fi(){for(const[e,t]of zi.entries())t.material&&(Ri(t.material),t.material.dispose());zi.clear()}var Li={preload:_i,preloadAll:Oi,get:function(e){const t=zi.get(e);return t&&t.loaded?t:null},has:function(e){const t=zi.get(e);return t&&t.loaded},updateMaterialOptions:function(e,t){const i=zi.get(e);if(!i||!i.material)return;const{uniforms:n}=i.material;n&&(t.glowColor&&n.glowColor&&n.glowColor.value.set(...t.glowColor),void 0!==t.glowIntensity&&n.glowIntensity&&(n.glowIntensity.value=t.glowIntensity))},dispose:Fi,getStatus:function(){const e={};for(const[t,i]of zi.entries())e[t]={loaded:i.loaded,hasGeometry:!!i.geometry,hasMaterial:!!i.material,materialType:i.materialType};return e}};class Gi{constructor(t,i={}){this._instanceId=Math.random().toString(36).substr(2,6),this.canvas=t,this.options=i,this._destroyed=!1,this._ready=!1,this._readyPromise=null,this.assetBasePath=i.assetBasePath||"/assets",this.geometryType=i.geometry||"sphere";const n="moon"===this.geometryType;this.renderer=new M(t,{enablePostProcessing:!1!==i.enablePostProcessing,enableShadows:i.enableShadows||!1,enableControls:!1!==i.enableControls,autoRotate:!n&&!1!==i.autoRotate,autoRotateSpeed:i.autoRotateSpeed,cameraDistance:i.cameraDistance,fov:i.fov,minZoom:i.minZoom,maxZoom:i.maxZoom,assetBasePath:this.assetBasePath});const a=ie[this.geometryType];a?this.geometryConfig=a:(console.warn(`Unknown geometry: ${this.geometryType}, falling back to sphere`),this.geometryConfig=ie.sphere),this.geometry=this.geometryConfig.geometry,this.geometry&&!this.geometry.isGroup&&(this.geometry.userData.geometryType=this.geometryType),this.materialVariant=i.materialVariant||null,this.onMaterialSwap=null;let s=null;const o=me(this.emotion),r=Ii(this.geometryType,this.geometryConfig,{glowColor:this.glowColor||[1,1,.95],glowIntensity:this.glowIntensity||1,materialVariant:this.materialVariant,emotionData:o,assetBasePath:this.assetBasePath});if(r&&(s=r.material,this.customMaterial=s,this.customMaterialType=r.type),this.geometryConfig.geometryLoader?this._readyPromise=this._loadAsyncGeometry():(this._ready=!0,this._readyPromise=Promise.resolve()),null===this.geometry&&this.geometryConfig.geometryLoader?this._deferredMeshCreation=!0:(this.coreMesh=this.renderer.createCoreMesh(this.geometry,s),"crystal"===this.customMaterialType&&this.createCrystalInnerCore()),this.calibrationRotation=[0,0,0],this.cameraRoll=0,"moon"===this.geometryType){const e=Math.PI/180;this.calibrationRotation=[B*e,k*e,T*e],this.cameraRoll=0}if("crystal"===this.geometryType||"rough"===this.geometryType||"heart"===this.geometryType||"star"===this.geometryType){const e=Math.PI/180;this.calibrationRotation=[0*e,30*e,0*e]}if(this.animator=new ne,this.breathingAnimator=new ae,this.breathingEnabled=!1!==i.enableBreathing,this._breathPhase=null,this._breathPhaseStartTime=0,this._breathPhaseDuration=0,this._breathPhaseStartScale=1,this._breathPhaseTargetScale=1,this._breathPhaseScale=1,this.gestureBlender=new se,this.geometryMorpher=new Me,this.blinkAnimator=new ye(this.geometryConfig),this.blinkAnimator.setEmotion(this.emotion),this.blinkingManuallyDisabled=!1,!1===i.enableBlinking&&(this.blinkAnimator.pause(),this.blinkingManuallyDisabled=!0),this.rotationBehavior=null,this.rotationDisabled=!1===i.autoRotate,this.wobbleEnabled=!0,this.rightingBehavior=new xe({strength:5,damping:.85,centerOfMass:[0,-.3,0],axes:{pitch:!0,roll:!0,yaw:!1}}),this.facingBehavior=null,n&&E.enabled){const e=Math.PI/180;this.facingBehavior=new Ce({strength:E.strength,lockedFace:E.lockedFace,lerpSpeed:E.lerpSpeed,calibrationRotation:[B*e,k*e,T*e]},this.renderer.camera)}this.emotion=i.emotion||"neutral",this.undertone=i.undertone||null,this.glowColor=[1,1,1],this.glowColorHex="#FFFFFF",this.glowIntensity=1,this.coreGlowEnabled=!0,this.glowIntensityOverride=null,this.intensityCalibrationOffset=0,this.baseEuler=[0,0,0],this.baseQuaternion=new e.Quaternion,this.gestureQuaternion=new e.Quaternion,this.tempEuler=new e.Euler,this.rotation=[0,0,0],this.baseScale=.16,this.scale=.16,this.position=[0,0,0],this.rhythmEngine=i.rhythmEngine||null,this.rhythm3DAdapter=we,this.rhythmEnabled=!1!==i.enableRhythm,this.rhythmEnabled&&this.rhythm3DAdapter.initialize(),this.particlesEnabled=!1!==i.enableParticles,this.particleVisibility=this.particlesEnabled;const l=new hi(50);l.canvasWidth=t.width,l.canvasHeight=t.height;const h=new ci({worldScale:2,baseRadius:1.5,depthScale:.75,verticalScale:1,coreRadius3D:2}),c=new gi(150,{renderer:this.renderer.renderer}),u=c.getPoints();if(u.layers.set(1),this.renderer.scene.add(u),this.particleOrchestrator=new bi(l,h,c),this.particleOrchestrator.setGeometryType(this.geometryType),this.particlesEnabled||c.geometry.setDrawRange(0,0),"sun"===this.geometryType){const e=this.geometry.parameters?.radius||.5;this.solarEclipse=new Pi(this.renderer.scene,e,this.coreMesh)}"moon"===this.geometryType&&this.customMaterial&&(this.lunarEclipse=new Bi(this.customMaterial)),this.virtualParticlePool=this.createVirtualParticlePool(5),this.nextPoolIndex=0,this.geometryConfig.defaultGlassMode&&!this.customMaterial&&this.setGlassMaterialEnabled(!0),this.setEmotion(this.emotion)}createVirtualParticlePool(e){const t=[];for(let i=0;i<e;i++)t.push({x:0,y:0,vx:0,vy:0,size:1,baseSize:1,opacity:1,scaleFactor:1,gestureData:null});return t}getVirtualParticleFromPool(){const e=this.virtualParticlePool[this.nextPoolIndex];return this.nextPoolIndex=(this.nextPoolIndex+1)%this.virtualParticlePool.length,e.x=0,e.y=0,e.vx=0,e.vy=0,e.size=1,e.baseSize=1,e.opacity=1,e.scaleFactor=1,e.gestureData=null,e}setEmotion(t,i=null){this.emotion=t,this.undertone=i;const n=me(t);if(n&&n.visual){if(n.visual.glowColor){let e=(a=(a=n.visual.glowColor).replace("#",""),[parseInt(a.substring(0,2),16)/255,parseInt(a.substring(2,4),16)/255,parseInt(a.substring(4,6),16)/255]);e=function(e,t){if(!t||"clear"===t||"none"===t)return e;const i={intense:{saturation:2.5,lightness:1.3},confident:{saturation:1.8,lightness:1.15},nervous:{saturation:1.6,lightness:1.1},tired:{saturation:.4,lightness:.65},subdued:{saturation:.25,lightness:.55}}[t];if(!i)return e;const n=function(e,t,i){const n=Math.max(e,t,i),a=Math.min(e,t,i),s=n-a,o=n+a;let r=0,l=0;const h=o/2;if(0!==s)switch(l=h>.5?s/(2-o):s/o,n){case e:r=((t-i)/s+(t<i?6:0))/6;break;case t:r=((i-e)/s+2)/6;break;case i:r=((e-t)/s+4)/6}return[360*r,100*l,100*h]}(e[0],e[1],e[2]);return n[1]=Math.min(100,n[1]*i.saturation),n[2]=Math.min(100,Math.max(0,n[2]*i.lightness)),function(e,t,i){let n,a,s;if(e/=360,i/=100,0==(t/=100))n=a=s=i;else{const o=(e,t,i)=>(i<0&&(i+=1),i>1&&(i-=1),i<1/6?e+6*(t-e)*i:i<.5?t:i<2/3?e+(t-e)*(2/3-i)*6:e),r=i<.5?i*(1+t):i+t-i*t,l=2*i-r;n=o(l,r,e+1/3),a=o(l,r,e),s=o(l,r,e-1/3)}return[n,a,s]}(n[0],n[1],n[2])}(e,i),this.glowColor=e,this.glowColorHex=n.visual.glowColor;const t=this.renderer.materialMode||"glass";this.glowIntensity=b(n.visual.glowColor,this.intensityCalibrationOffset,t)}if(this.renderer.updateLighting(t,n),this.customMaterial&&"moon"===this.customMaterialType){const t=new e.Color(this.glowColor[0],this.glowColor[1],this.glowColor[2]);N(this.customMaterial,t,this.glowIntensity)}else this.customMaterial&&"sun"===this.customMaterialType&&$(this.coreMesh,this.glowColor,this.glowIntensity,0)}var a;const s="sun"===this.geometryType?W:null;this.rotationDisabled||"moon"===this.geometryType?this.rotationBehavior=null:n&&n["3d"]&&n["3d"].rotation?this.rotationBehavior?this.rotationBehavior.updateConfig(n["3d"].rotation):(this.rotationBehavior=new Se(n["3d"].rotation,this.rhythmEngine,s),this.rotationBehavior.setWobbleEnabled(this.wobbleEnabled)):this.rotationBehavior||this.rotationDisabled||(this.rotationBehavior=new Se({type:"gentle",speed:1,axes:[0,.01,0]},this.rhythmEngine,s),this.rotationBehavior.setWobbleEnabled(this.wobbleEnabled)),this.rightingBehavior&&this.rightingBehavior.reset(),this.baseEuler[0]=0,this.baseEuler[2]=0;const o=vt(i);if(o&&o["3d"]){const e=o["3d"];e.rotation&&this.rotationBehavior&&this.rotationBehavior.applyUndertoneMultipliers(e.rotation),e.righting&&this.rightingBehavior&&this.rightingBehavior.applyUndertoneMultipliers(e.righting)}this.animator.stopAll();const r=n?.visual?.glowColor||"#00BCD4",l=this.renderer.materialMode||"glass";if(this.baseGlowIntensity=b(r,this.intensityCalibrationOffset,l),o&&o["3d"]&&o["3d"].glow&&(this.baseGlowIntensity,this.baseGlowIntensity*=o["3d"].glow.intensityMultiplier),this.breathingAnimator.setEmotion(t,o),this.blinkAnimator.setEmotion(t),this.renderer.updateBloom(this.baseGlowIntensity,1,this.geometryType),this.animator.playEmotion(t),this.particlesEnabled&&this.particleOrchestrator&&this.particleOrchestrator.setEmotion(t,i),n&&n.soulAnimation){const e=n.soulAnimation;this.setCrystalSoulEffects({driftEnabled:!0,driftSpeed:e.driftSpeed||.5,shimmerEnabled:!0,shimmerSpeed:e.shimmerSpeed||.5})}}setCoreGlowEnabled(e){this.coreGlowEnabled=e,this.crystalSoul&&this.crystalSoul.setVisible(e)}setGlassMaterialEnabled(e){const t=e?"glass":"glow";this.renderer.setMaterialMode(t)}setGlowIntensity(e){this.glowIntensityOverride=e,null!==e&&(this.glowIntensity=e,this.baseGlowIntensity=e)}sliderToIntensity(e){const t=e/100;return.3*Math.pow(10/.3,t)}setIntensityCalibration(e){this.intensityCalibrationOffset=e,this.setEmotion(this.emotion,this.undertone)}getGlowIntensity(){return this.glowIntensity}playGesture(e){const t=ft(e);if(!t)return void console.warn(`Unknown gesture: ${e}`);const i=this.getVirtualParticleFromPool(),n=t.config||{},a=n.musicalDuration?.musical?500*(n.musicalDuration.beats||2):n.duration||800,s=this.animator.time;if(this.position,this.rotation,this.scale,this.animator.animations.length>=10){const e=this.animator.animations.shift();console.warn(`⚠️ Animation limit reached (10), removed oldest: ${e.gestureName||"unknown"}`)}const o={initialized:!1};this.animator.animations.push({gestureName:e,duration:a,startTime:s,config:n,evaluate:e=>{i.x=0,i.y=0,i.vx=0,i.vy=0,i.size=1,i.opacity=1,t.apply&&t.apply(i,o,n,e,1,0,0);const a={...n,particle:i,config:n,strength:n.strength||1};return t["3d"]&&t["3d"].evaluate?t["3d"].evaluate.call(t,e,a):{position:[0,0,0],rotation:[0,0,0],scale:1}},callbacks:{onUpdate:(e,t)=>{e.position&&(this.position=e.position),e.rotation&&(this.tempEuler.set(e.rotation[0],e.rotation[1],e.rotation[2],"XYZ"),this.gestureQuaternion.setFromEuler(this.tempEuler)),void 0!==e.scale&&(this.scale=this.baseScale*e.scale),void 0!==e.glowIntensity&&(this.glowIntensity=this.baseGlowIntensity*e.glowIntensity)},onComplete:()=>{t.cleanup&&t.cleanup(i),this.position=[0,0,0],this.scale=this.baseScale}}})}setSunShadow(e="off"){"sun"===this.geometryType&&this.solarEclipse?this.solarEclipse.setEclipseType(e):console.warn("⚠️ Eclipse only available for sun geometry")}startSolarEclipse(e={}){const t=e.type||"total";"sun"===this.geometryType&&this.solarEclipse?this.solarEclipse.setEclipseType(t):(this.morphToShape("sun"),setTimeout(()=>{this.solarEclipse&&this.solarEclipse.setEclipseType(t)},600))}startLunarEclipse(e={}){const t=e.type||"total";"moon"===this.geometryType&&this.lunarEclipse?this.lunarEclipse.setEclipseType(t):(this.morphToShape("moon"),setTimeout(()=>{this.lunarEclipse&&this.lunarEclipse.setEclipseType(t)},600))}stopEclipse(){this.solarEclipse&&this.solarEclipse.setEclipseType("off"),this.lunarEclipse&&this.lunarEclipse.setEclipseType("off")}setMoonEclipse(e="off"){"moon"===this.geometryType&&this.lunarEclipse?this.lunarEclipse.setEclipseType(e):console.warn("⚠️ Lunar eclipse only available for moon geometry")}setBloodMoonBlend(e={}){"moon"===this.geometryType&&this.customMaterial?(void 0!==e.blendMode&&(this.customMaterial.uniforms.blendMode.value=e.blendMode),void 0!==e.blendStrength&&(this.customMaterial.uniforms.blendStrength.value=e.blendStrength),void 0!==e.emissiveStrength&&(this.customMaterial.uniforms.emissiveStrength.value=e.emissiveStrength),void 0!==e.eclipseIntensity&&(this.customMaterial.uniforms.eclipseIntensity.value=e.eclipseIntensity)):console.warn("⚠️ Blood moon blend only available for moon geometry")}setBlendLayer(e,t={}){if("moon"!==this.geometryType&&"sun"!==this.geometryType||!this.customMaterial)return void console.warn("⚠️ Blend layers only available for moon and sun geometry");const i=`layer${e}`;void 0!==t.mode&&this.customMaterial.uniforms[`${i}Mode`]&&(this.customMaterial.uniforms[`${i}Mode`].value=t.mode),void 0!==t.strength&&this.customMaterial.uniforms[`${i}Strength`]&&(this.customMaterial.uniforms[`${i}Strength`].value=t.strength),void 0!==t.enabled&&this.customMaterial.uniforms[`${i}Enabled`]&&(this.customMaterial.uniforms[`${i}Enabled`].value=t.enabled?1:0)}setAllBlendLayers(e){"moon"!==this.geometryType&&"sun"!==this.geometryType||!this.customMaterial?console.warn("⚠️ Blend layers only available for moon and sun geometry"):e.forEach((e,t)=>{this.setBlendLayer(t+1,e)})}setCrystalBlendLayer(e,t,i={}){if("crystal"!==this.geometryType&&"rough"!==this.geometryType||!this.customMaterial||"crystal"!==this.customMaterialType)return;const n=`${e}Blend${t}`;void 0!==i.mode&&this.customMaterial.uniforms[`${n}Mode`]&&(this.customMaterial.uniforms[`${n}Mode`].value=i.mode),void 0!==i.strength&&this.customMaterial.uniforms[`${n}Strength`]&&(this.customMaterial.uniforms[`${n}Strength`].value=i.strength),void 0!==i.enabled&&this.customMaterial.uniforms[`${n}Enabled`]&&(this.customMaterial.uniforms[`${n}Enabled`].value=i.enabled?1:0)}setCrystalUniforms(e={}){if("crystal"!==this.geometryType&&"rough"!==this.geometryType||!this.customMaterial||"crystal"!==this.customMaterialType)return void console.warn("⚠️ Crystal uniforms only available with crystal blend-layers material");const{uniforms:t}=this.customMaterial,i=(e,t,i=0,n=10)=>{e&&"number"==typeof t&&!isNaN(t)&&isFinite(t)&&(e.value=Math.max(i,Math.min(n,t)))};i(t.coreGlowStrength,e.coreGlowStrength,0,2),void 0===e.coreGlowFalloff||isNaN(e.coreGlowFalloff)||(i(t.coreGlowFalloff,e.coreGlowFalloff,.1,3),this.setCrystalCoreSize(e.coreGlowFalloff)),i(t.fresnelStrength,e.fresnelStrength,0,2),i(t.fresnelPower,e.fresnelPower,.5,10),i(t.transmissionStrength,e.transmissionStrength,0,1),i(t.facetStrength,e.facetStrength,0,2),i(t.iridescenceStrength,e.iridescenceStrength,0,1),i(t.chromaticAberration,e.chromaticAberration,0,1),i(t.causticStrength,e.causticStrength,0,1),i(t.emissiveIntensity,e.emissiveIntensity,0,5),i(t.sparkleEnabled,e.sparkleEnabled,0,1),i(t.sparkleSpeed,e.sparkleSpeed,.1,5),i(t.causticEnabled,e.causticEnabled,0,1),i(t.causticSpeed,e.causticSpeed,.1,10),i(t.causticScale,e.causticScale,.5,10),i(t.causticCoverage,e.causticCoverage,0,1),i(t.energyPulseEnabled,e.energyPulseEnabled,0,1),i(t.energyPulseSpeed,e.energyPulseSpeed,.1,5)}createCrystalInnerCore(){if(this.crystalSoul&&(this.crystalSoul.dispose(),this.crystalSoul=null),!this.coreMesh)return;const e=this._targetGeometryType||this.geometryType;this.crystalSoul=new pi({radius:.35,detail:1,geometryType:e,renderer:this.renderer,assetBasePath:this.assetBasePath}),this.crystalSoul.attachTo(this.coreMesh,this.renderer?.scene);let t=1;"heart"===e?(this.crystalShellBaseScale=2.4,t=1):"rough"===e?(this.crystalShellBaseScale=1.6,t=1):"star"===e?(this.crystalShellBaseScale=2,t=1.4):"crystal"===e&&(this.crystalShellBaseScale=2,t=1),this.crystalSoul.baseScale=t,this.crystalSoul.mesh.scale.setScalar(t),this.crystalSoul.setVisible(this.coreGlowEnabled),this.crystalInnerCore=this.crystalSoul.mesh,this.crystalInnerCoreMaterial=this.crystalSoul.material,this.crystalInnerCoreBaseScale=this.crystalSoul.baseScale}updateCrystalInnerCore(e,t=0){if(!this.crystalSoul)return;const i=this.breathingAnimator&&this.breathingEnabled?this.breathingAnimator.getBreathingScale():1;this.crystalSoul.update(t,e,i),this.crystalInnerCoreBaseScale=this.crystalSoul.baseScale}setCrystalSoulEffects(e={}){this.crystalSoul&&this.crystalSoul.setEffects(e)}setCrystalCoreSize(e){this.crystalSoul&&(this.crystalSoul.setSize(e),this.crystalInnerCoreBaseScale=this.crystalSoul.baseScale)}setCrystalShellSize(e){!this.coreMesh||"crystal"!==this.geometryType&&"rough"!==this.geometryType&&"heart"!==this.geometryType||(this.crystalShellBaseScale=e)}setWobbleEnabled(e){this.wobbleEnabled=e,this.rotationBehavior&&this.rotationBehavior.setWobbleEnabled(e),e||(this.rightingBehavior&&this.rightingBehavior.reset(),this.baseEuler[0]=0,this.baseEuler[2]=0)}setMaterialVariant(e){this.materialVariant=e}setRhythmEnabled(e){this.rhythmEnabled=e,e&&this.rhythm3DAdapter&&!this.rhythm3DAdapter.enabled&&this.rhythm3DAdapter.initialize()}setGrooveEnabled(e){this.rhythm3DAdapter&&this.rhythm3DAdapter.setGrooveEnabled(e)}setBeatSyncStrength(e){this.rhythm3DAdapter&&this.rhythm3DAdapter.setBeatSyncStrength(e)}setGrooveConfig(e){this.rhythm3DAdapter&&this.rhythm3DAdapter.setGrooveConfig(e)}isRhythmPlaying(){return this.rhythm3DAdapter?.isPlaying()||!1}getRhythmBPM(){return this.rhythm3DAdapter?.getBPM()||120}startRhythm(e=120,t="straight"){this.rhythm3DAdapter&&this.rhythm3DAdapter.start(e,t)}stopRhythm(){this.rhythm3DAdapter&&this.rhythm3DAdapter.stop()}setRhythmBPM(e){this.rhythm3DAdapter&&this.rhythm3DAdapter.setBPM(e)}setRhythmPattern(e){this.rhythm3DAdapter&&this.rhythm3DAdapter.setPattern(e)}breathePhase(e,t){const i=Math.max(.5,Math.min(30,t));switch(this._breathPhaseStartScale=this._breathPhaseScale,this._breathPhaseStartTime=performance.now(),this._breathPhaseDuration=1e3*i,this._breathPhase=e,e){case"inhale":this._breathPhaseTargetScale=1.3;break;case"exhale":this._breathPhaseTargetScale=.85;break;default:this._breathPhaseTargetScale=this._breathPhaseStartScale}console.log(`[Core3D] breathePhase: ${e} for ${i}s (${this._breathPhaseStartScale.toFixed(2)} → ${this._breathPhaseTargetScale.toFixed(2)})`)}stopBreathingPhase(){this._breathPhase=null,this._breathPhaseScale=1,this._breathPhaseStartScale=1,this._breathPhaseTargetScale=1,console.log("[Core3D] breathePhase stopped, scale reset to 1.0")}_updateBreathingPhase(e){if(!this._breathPhase)return this._breathPhaseScale;const t=performance.now()-this._breathPhaseStartTime,i=this._breathPhaseDuration,n=Math.min(1,t/i),a=Math.sin(n*Math.PI/2);return this._breathPhaseScale=this._breathPhaseStartScale+(this._breathPhaseTargetScale-this._breathPhaseStartScale)*a,n>=1&&(this._breathPhaseScale=this._breathPhaseTargetScale,this._breathPhase=null),this._breathPhaseScale}morphToShape(e,t=800){const i=ie[e];i?this.geometryMorpher.startMorph(this.geometryType,e,t)&&(this.geometryMorpher.getInterruptedTarget(),this.blinkAnimator.pause(),this._targetGeometryConfig=i,this._targetGeometryType=e,i.geometryLoader&&!i.geometry?(this._targetGeometry=null,this._pendingGeometryLoad=i.geometryLoader(this.assetBasePath).then(e=>{this._targetGeometry=e,i.geometry=e,this._pendingGeometryLoad=null})):(this._targetGeometry=i.geometry,this._pendingGeometryLoad=null)):console.warn(`Unknown shape: ${e}`)}isMorphing(){return this.geometryMorpher.isTransitioning}getMorphState(){return this.geometryMorpher.getState()}growIn(e=500){this.geometryMorpher.growIn(this.geometryType,e)}easeInOutCubic(e){return e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2}render(e){if(this._destroyed)return;if(!this._ready)return;this.animator.update(e);const t=this.geometryMorpher.update(e);if(t.shouldSwapGeometry&&this._pendingGeometryLoad&&this.geometryMorpher.pauseAtSwap(),t.waitingForGeometry&&this._targetGeometry&&!this._pendingGeometryLoad&&(this.geometryMorpher.resumeFromSwap(),this.geometryMorpher.hasSwappedGeometry=!1),t.shouldSwapGeometry&&this._targetGeometry){const e=this.geometryType;this.customMaterial&&function(e,t){switch(e){case"moon":!function(e){if(!e||!e.uniforms)return;const t=e.uniforms;t.shadowOffset&&t.shadowOffset.value.set(I.full.x,I.full.y),t.shadowCoverage&&(t.shadowCoverage.value=.5),t.shadowSoftness&&(t.shadowSoftness.value=.05),t.eclipseProgress&&(t.eclipseProgress.value=0),t.eclipseIntensity&&(t.eclipseIntensity.value=0),t.bloodMoonColor&&(t.bloodMoonColor.value=[.85,.18,.08]),t.emissiveStrength&&(t.emissiveStrength.value=.39),t.eclipseShadowPos&&(t.eclipseShadowPos.value=[-2,0]),t.eclipseShadowRadius&&(t.eclipseShadowRadius.value=1.2),t.shadowDarkness&&(t.shadowDarkness.value=.53),t.eclipseShadowColor&&(t.eclipseShadowColor.value=[1,.58,0]),t.eclipseMidtoneColor&&(t.eclipseMidtoneColor.value=[.71,.43,.03]),t.eclipseHighlightColor&&(t.eclipseHighlightColor.value=[1,.28,.1]),t.eclipseGlowColor&&(t.eclipseGlowColor.value=[.09,.09,.09]),t.eclipseBrightnessModel&&(t.eclipseBrightnessModel.value=0),t.layer1Mode&&(t.layer1Mode.value=9),t.layer1Strength&&(t.layer1Strength.value=.322),t.layer1Enabled&&(t.layer1Enabled.value=1),t.layer2Mode&&(t.layer2Mode.value=0),t.layer2Strength&&(t.layer2Strength.value=2.785),t.layer2Enabled&&(t.layer2Enabled.value=1),t.layer3Mode&&(t.layer3Mode.value=7),t.layer3Strength&&(t.layer3Strength.value=.199),t.layer3Enabled&&(t.layer3Enabled.value=1),t.layer4Mode&&(t.layer4Mode.value=0),t.layer4Strength&&(t.layer4Strength.value=0),t.layer4Enabled&&(t.layer4Enabled.value=0),t.opacity&&(t.opacity.value=1)}(t);break;case"sun":!function(e){if(!e||!e.uniforms)return;const t=e.uniforms;t.eclipseProgress&&(t.eclipseProgress.value=0),t.eclipseShadowPos&&(t.eclipseShadowPos.value=[-2,0]),t.eclipseShadowRadius&&(t.eclipseShadowRadius.value=.882),t.shadowDarkness&&(t.shadowDarkness.value=1),t.shadowOffset&&t.shadowOffset.value.set(200,0),t.shadowCoverage&&(t.shadowCoverage.value=.5),t.shadowSoftness&&(t.shadowSoftness.value=.1),t.layer1Mode&&(t.layer1Mode.value=0),t.layer1Strength&&(t.layer1Strength.value=.23),t.layer1Enabled&&(t.layer1Enabled.value=1),t.layer2Mode&&(t.layer2Mode.value=0),t.layer2Strength&&(t.layer2Strength.value=0),t.layer2Enabled&&(t.layer2Enabled.value=0),t.layer3Mode&&(t.layer3Mode.value=0),t.layer3Strength&&(t.layer3Strength.value=0),t.layer3Enabled&&(t.layer3Enabled.value=0),t.layer4Mode&&(t.layer4Mode.value=0),t.layer4Strength&&(t.layer4Strength.value=0),t.layer4Enabled&&(t.layer4Enabled.value=0),t.emissiveIntensity&&(t.emissiveIntensity.value=4),t.opacity&&(t.opacity.value=1),t.time&&(t.time.value=0)}(t);break;case"crystal":case"diamond":!function(e){if(!e||!e.uniforms)return;const t=e.uniforms,i=Ei;t.frostiness&&(t.frostiness.value=i.frostiness),t.fresnelPower&&(t.fresnelPower.value=i.fresnelPower),t.fresnelIntensity&&(t.fresnelIntensity.value=i.fresnelIntensity),t.innerGlowStrength&&(t.innerGlowStrength.value=i.innerGlowStrength),t.surfaceRoughness&&(t.surfaceRoughness.value=i.surfaceRoughness),t.surfaceNoiseScale&&(t.surfaceNoiseScale.value=i.surfaceNoiseScale),t.noiseFrequency&&(t.noiseFrequency.value=i.noiseFrequency),t.causticIntensity&&(t.causticIntensity.value=i.causticIntensity),t.causticScale&&(t.causticScale.value=i.causticScale),t.causticSpeed&&(t.causticSpeed.value=i.causticSpeed),t.textureStrength&&(t.textureStrength.value=i.textureStrength),t.layer1Mode&&(t.layer1Mode.value=i.layer1Mode),t.layer1Strength&&(t.layer1Strength.value=i.layer1Strength),t.layer1Enabled&&(t.layer1Enabled.value=i.layer1Enabled),t.layer2Mode&&(t.layer2Mode.value=i.layer2Mode),t.layer2Strength&&(t.layer2Strength.value=i.layer2Strength),t.layer2Enabled&&(t.layer2Enabled.value=i.layer2Enabled),t.layer3Mode&&(t.layer3Mode.value=i.layer3Mode),t.layer3Strength&&(t.layer3Strength.value=i.layer3Strength),t.layer3Enabled&&(t.layer3Enabled.value=i.layer3Enabled),t.layer4Mode&&(t.layer4Mode.value=i.layer4Mode),t.layer4Strength&&(t.layer4Strength.value=i.layer4Strength),t.layer4Enabled&&(t.layer4Enabled.value=i.layer4Enabled),t.glowIntensity&&(t.glowIntensity.value=i.glowIntensity),t.opacity&&(t.opacity.value=i.opacity),t.time&&(t.time.value=i.time)}(t)}}(e,this.customMaterial),this.geometry=this._targetGeometry,this.geometryType=this._targetGeometryType,this.geometryConfig=this._targetGeometryConfig,this.customMaterial&&(Ri(this.customMaterial),this.renderer.disposeMaterial(this.customMaterial),this.customMaterial=null,this.customMaterialType=null);let t=null;const i=me(this.emotion),n=Ii(this._targetGeometryType,this._targetGeometryConfig,{glowColor:this.glowColor||[1,1,.95],glowIntensity:this.glowIntensity||1,materialVariant:this.materialVariant,emotionData:i,assetBasePath:this.assetBasePath});if(n&&(t=n.material,this.customMaterial=t,this.customMaterialType=n.type),t)this.renderer.swapGeometry(this.geometry,t);else{this.renderer.swapGeometry(this.geometry);const e=!0===this._targetGeometryConfig.defaultGlassMode;this.setGlassMaterialEnabled(e)}if(this.onMaterialSwap&&this.onMaterialSwap({geometryType:this._targetGeometryType,material:this.customMaterial,materialType:this.customMaterialType}),this.blinkAnimator.setGeometry(this._targetGeometryConfig),this.rightingBehavior&&this.rightingBehavior.reset(),this.rotation=[0,0,0],"sun"===this._targetGeometryType){if(!this.solarEclipse){const e=this.geometry.parameters?.radius||.5;this.solarEclipse=new Pi(this.renderer.scene,e,this.renderer.coreMesh)}}else this.solarEclipse&&(this.solarEclipse.dispose(),this.solarEclipse=null);if("moon"===this._targetGeometryType?!this.lunarEclipse&&this.customMaterial&&(this.lunarEclipse=new Bi(this.customMaterial)):this.lunarEclipse&&(this.lunarEclipse.dispose(),this.lunarEclipse=null),"crystal"===this._targetGeometryType||"rough"===this._targetGeometryType||"heart"===this._targetGeometryType||"star"===this._targetGeometryType?"crystal"===this.customMaterialType&&this.createCrystalInnerCore():this.crystalSoul&&(this.crystalSoul.dispose(),this.crystalSoul=null,this.crystalInnerCore=null,this.crystalInnerCoreMaterial=null),"moon"===this._targetGeometryType){this.rotationBehavior=null,this.renderer?.controls&&(this.renderer.controls.autoRotate=!1),this.renderer?.setCameraPreset&&this.renderer.setCameraPreset("front",0,!0);const e=Math.PI/180;this.calibrationRotation[0]=B*e,this.calibrationRotation[1]=k*e,this.calibrationRotation[2]=T*e,!this.facingBehavior&&E.enabled&&(this.facingBehavior=new Ce({strength:E.strength,lockedFace:E.lockedFace,lerpSpeed:E.lerpSpeed,calibrationRotation:[B*e,k*e,T*e]},this.renderer.camera))}else{if(this.facingBehavior&&(this.facingBehavior.dispose(),this.facingBehavior=null),this.renderer?.controls&&!1!==this.options.autoRotate&&(this.renderer.controls.autoRotate=!0),"crystal"===this._targetGeometryType||"rough"===this._targetGeometryType||"heart"===this._targetGeometryType){const e=Math.PI/180;this.calibrationRotation[0]=0*e,this.calibrationRotation[1]=30*e,this.calibrationRotation[2]=0*e}else this.calibrationRotation[0]=0,this.calibrationRotation[1]=0,this.calibrationRotation[2]=0;if(this.rotationDisabled)this.rotationBehavior=null;else{const e=me(this.emotion);e&&e["3d"]&&e["3d"].rotation&&(this.rotationBehavior?this.rotationBehavior.updateConfig(e["3d"].rotation):(this.rotationBehavior=new Se(e["3d"].rotation,this.rhythmEngine),this.rotationBehavior.setWobbleEnabled(this.wobbleEnabled)))}}}t.completed&&(this._targetGeometry=null,this._targetGeometryType=null,this._targetGeometryConfig=null,this.blinkingManuallyDisabled||this.blinkAnimator.resume()),this.breathingAnimator.update(e,this.emotion,vt(this.undertone));const i=this._updateBreathingPhase(e),n=1!==i?i:this.breathingEnabled?this.breathingAnimator.getBreathingScale():1,a=t.scaleMultiplier,s=this.blinkAnimator.update(e);this.rotationBehavior?this.rotationBehavior.update(e,this.baseEuler):"moon"===this.geometryType||this.rotationDisabled||(this.baseEuler[1]+=3e-4*e),this.rightingBehavior&&this.rightingBehavior.update(e,this.baseEuler),this.facingBehavior&&(this.baseEuler[0]=0,this.baseEuler[1]=0,this.baseEuler[2]=0);this.baseEuler[0]=Math.max(-.35,Math.min(.35,this.baseEuler[0])),this.baseEuler[2]=Math.max(-.35,Math.min(.35,this.baseEuler[2])),this.tempEuler.set(this.baseEuler[0],this.baseEuler[1],this.baseEuler[2],"XYZ"),this.baseQuaternion.setFromEuler(this.tempEuler),this.rhythm3DAdapter&&this.rhythm3DAdapter.update(e);const o=this.gestureBlender.blend(this.animator.animations,this.animator.time,this.baseQuaternion,this.baseScale,this.baseGlowIntensity),r=this.rhythm3DAdapter?.isPlaying()?this.rhythm3DAdapter.getModulation():null,l=this.animator.animations.length>0;this.position=r&&!l?[o.position[0]+r.grooveOffset[0],o.position[1]+r.grooveOffset[1],o.position[2]+r.grooveOffset[2]]:r&&l?[o.position[0]*r.positionMultiplier,o.position[1]*r.positionMultiplier,o.position[2]*r.positionMultiplier]:o.position,this.rotation=r&&!l?[o.rotation[0]+r.grooveRotation[0],o.rotation[1]+r.grooveRotation[1],o.rotation[2]+r.grooveRotation[2]]:o.rotation,this.scale=r&&!l?o.scale*r.grooveScale:r&&l?o.scale*r.scaleMultiplier:o.scale,null===this.glowIntensityOverride&&(this.glowIntensity=r&&l?o.glowIntensity*r.glowMultiplier:o.glowIntensity),this.gestureQuaternion=o.gestureQuaternion,this.glowBoost=o.glowBoost||0,s.isBlinking&&s.rotation&&(this.rotation[0]+=s.rotation[0],this.rotation[1]+=s.rotation[1],this.rotation[2]+=s.rotation[2]);const h="crystal"!==this.geometryType&&"rough"!==this.geometryType,c=s.isBlinking&&h?s.scale[1]:1,u=this.crystalShellBaseScale||2,d=this.scale*a*n*c*u;if(this.particleVisibility&&this.particleOrchestrator){const t=this.geometryConfig?.particleRadiusMultiplier||1,i=(this.crystalShellBaseScale||2)*this.scale*n*t;this.particleOrchestrator.update(e,this.emotion,this.undertone,this.animator.animations,this.animator.time,{x:this.position[0],y:this.position[1],z:this.position[2]},{width:this.canvas.width,height:this.canvas.height},{euler:this.baseEuler,quaternion:this.baseQuaternion,angularVelocity:this.rotationBehavior?this.rotationBehavior.axes:[0,0,0]},this.baseScale,i)}const m=s.isBlinking&&s.glowBoost?1+s.glowBoost:1,p=this.coreGlowEnabled?this.glowIntensity*m:0,g=this.emotiveEngine?.getVirtualParticle(),f=p*(g?.opacity??1),y=t.isTransitioning?.3:.1;if(this.renderer.updateBloom(f,y,this.geometryType),this.glowBoost>0||this.renderer.glowLayer&&this.renderer.glowLayer.isActive()){const t=this.coreMesh?.position;this.renderer.updateGlowLayer(this.glowBoost,this.glowColor,t,e)}if("sun"===this.customMaterialType&&$(this.coreMesh,this.glowColor,f,e),"moon"!==this.customMaterialType&&"moon-multiplexer"!==this.customMaterialType||!this.customMaterial||this.customMaterial.uniforms&&this.customMaterial.uniforms.glowIntensity&&(this.customMaterial.uniforms.glowIntensity.value=f),"crystal"===this.customMaterialType&&this.customMaterial){if(this.customMaterial.uniforms){this.customMaterial.uniforms.time.value+=e/1e3,this.customMaterial.uniforms.glowIntensity&&(this.customMaterial.uniforms.glowIntensity.value=f);const t=v(this.glowColor,.3),i=[t.r,t.g,t.b];if(this.customMaterial.uniforms.emotionColor.value.setRGB(i[0],i[1],i[2]),this.customMaterial.uniforms.blinkIntensity){const e=s.isBlinking?Math.sin(s.progress*Math.PI):0;this.customMaterial.uniforms.blinkIntensity.value=e}}if(this.coreGlowEnabled){const t=v(this.glowColor,.3),i=[t.r,t.g,t.b];this.updateCrystalInnerCore(i,e)}}this.renderer.render({position:this.position,rotation:this.rotation,scale:d,glowColor:this.glowColor,glowColorHex:this.glowColorHex,glowIntensity:f,hasActiveGesture:this.animator.animations.length>0,calibrationRotation:this.calibrationRotation,solarEclipse:this.solarEclipse,deltaTime:e,morphProgress:t.isTransitioning?t.visualProgress:null}),this.lunarEclipse&&this.lunarEclipse.update(e)}async _loadAsyncGeometry(){try{const e=await _i(this.geometryType,{glowColor:this.glowColor||[1,1,.95],glowIntensity:this.glowIntensity||1,materialVariant:this.materialVariant,emotionData:me(this.emotion),assetBasePath:this.assetBasePath});if(this._destroyed)return;if(!e||!e.geometry)return console.warn(`[Core3D:${this._instanceId}] Async geometry load returned null!`),void(this._ready=!0);const t=e.geometry.clone();if(t.userData.geometryType=this.geometryType,this.geometry=t,this._deferredMeshCreation){if(this.coreMesh=this.renderer.createCoreMesh(t,this.customMaterial),this._destroyed)return;if("crystal"===this.customMaterialType&&(await this._createCrystalInnerCoreAsync(),this._destroyed))return;this._deferredMeshCreation=!1}else if(this.coreMesh){const e=this.coreMesh.geometry;if(this.coreMesh.geometry=t,e&&e!==t&&e.dispose(),this._destroyed)return;if("crystal"===this.customMaterialType&&(await this._createCrystalInnerCoreAsync(),this._destroyed))return}if(this._destroyed)return;this._logSceneHierarchy(),this._ready=!0}catch(e){console.warn(`[Core3D:${this._instanceId}] Async geometry load FAILED:`,e),this._destroyed||(this._ready=!0)}}_logSceneHierarchy(){const e=this.renderer?.scene;e&&e.children.forEach((e,t)=>{const i=null===e?"NULL!":void 0===e?"UNDEFINED!":null===e.visible?"visible=NULL!":void 0===e.visible?"visible=UNDEF!":"OK";console.log(` [${t}] ${e?.name||e?.type||"UNKNOWN"} status=${i} uuid=${e?.uuid?.slice(0,8)||"N/A"}`)})}async _createCrystalInnerCoreAsync(){if(this.crystalSoul&&(this.crystalSoul.dispose(),this.crystalSoul=null),!this.coreMesh)return;if(await pi._loadInclusionGeometry(this.assetBasePath),this._destroyed||!this.coreMesh)return;this.crystalSoul=new pi({radius:.35,detail:1,geometryType:this.geometryType,renderer:this.renderer,assetBasePath:this.assetBasePath}),this.crystalSoul.attachTo(this.coreMesh,this.renderer?.scene);let e=1;"heart"===this.geometryType?(this.crystalShellBaseScale=2.4,e=1):"rough"===this.geometryType?(this.crystalShellBaseScale=1.6,e=1):"crystal"===this.geometryType&&(e=1),this.crystalSoul.baseScale=e,this.crystalSoul.mesh.scale.setScalar(e),this.crystalSoul.setVisible(this.coreGlowEnabled),this.crystalInnerCore=this.crystalSoul.mesh,this.crystalInnerCoreMaterial=this.crystalSoul.material,this.crystalInnerCoreBaseScale=this.crystalSoul.baseScale}isReady(){return this._ready}async waitUntilReady(){this._ready||this._readyPromise&&await this._readyPromise}destroy(){if(this._instanceId,this._ready,this._destroyed,this.crystalSoul,this.renderer,this._destroyed=!0,this.crystalSoul&&(this.crystalSoul.dispose(),this.crystalSoul=null,this.crystalInnerCore=null,this.crystalInnerCoreMaterial=null),this.particleOrchestrator){const e=this.particleOrchestrator.renderer;if(e){const t=e.getPoints();t&&this.renderer?.scene&&this.renderer.scene.remove(t)}this.particleOrchestrator.destroy(),this.particleOrchestrator=null}this.solarEclipse&&(this.solarEclipse.dispose(),this.solarEclipse=null),this.lunarEclipse&&(this.lunarEclipse.dispose(),this.lunarEclipse=null),this.customMaterial&&(this.renderer.disposeMaterial(this.customMaterial),this.customMaterial=null,this.customMaterialType=null),this.facingBehavior&&(this.facingBehavior.dispose(),this.facingBehavior=null),this.animator.stopAll(),this.renderer.destroy(),this.virtualParticlePool&&(this.virtualParticlePool.length=0,this.virtualParticlePool=null),this.animator.destroy?.(),this.breathingAnimator.destroy?.(),this.gestureBlender.destroy?.(),this.geometryMorpher.destroy?.(),this.blinkAnimator.destroy?.(),this.rotationBehavior&&(this.rotationBehavior.destroy?.(),this.rotationBehavior=null),this.rightingBehavior&&(this.rightingBehavior.destroy?.(),this.rightingBehavior=null),this.tempEuler=null,this.baseQuaternion=null,this.gestureQuaternion=null,this.geometry=null,this.geometryConfig=null,this._targetGeometry=null,this._targetGeometryConfig=null,this._targetGeometryType=null,this.canvas=null,this.options=null,this.coreMesh=null,this.rhythmEngine=null,this.rhythm3DAdapter=null,this.emotiveEngine=null,Fi()}async preloadGeometries(){const e={glowColor:this.glowColor||[1,1,.95],glowIntensity:this.glowIntensity||1,materialVariant:this.materialVariant,emotionData:me(this.emotion)};await Oi(e)}}class Vi{constructor(){this.listeners=new Map,this.groups=new Map,this.stats={registered:0,removed:0,active:0}}addEventListener(e,t,i,n={},a="default"){const s=this.generateId(),o={id:s,target:e,eventType:t,handler:i,options:n,group:a,active:!0};return this.listeners.set(s,o),this.groups.has(a)||this.groups.set(a,new Set),this.groups.get(a).add(s),e.addEventListener(t,i,n),this.stats.registered++,this.stats.active++,s}removeEventListener(e){const t=this.listeners.get(e);if(!t||!t.active)return!1;t.target.removeEventListener(t.eventType,t.handler,t.options),t.active=!1;const i=this.groups.get(t.group);return i&&(i.delete(e),0===i.size&&this.groups.delete(t.group)),this.listeners.delete(e),this.stats.removed++,this.stats.active--,!0}removeGroup(e){const t=this.groups.get(e);if(!t)return 0;let i=0;for(const e of t)this.removeEventListener(e)&&i++;return i}removeAllForTarget(e){let t=0;for(const[i,n]of this.listeners.entries())n.target===e&&n.active&&this.removeEventListener(i)&&t++;return t}removeAllOfType(e){let t=0;for(const[i,n]of this.listeners.entries())n.eventType===e&&n.active&&this.removeEventListener(i)&&t++;return t}removeAll(){let e=0;for(const[t,i]of this.listeners.entries())i.active&&this.removeEventListener(t)&&e++;return e}createAutoRemove(e,t,i,n={}){const a=this.addEventListener(e,t,i,n);return{id:a,remove:()=>this.removeEventListener(a)}}once(e,t,i,n={}){const a=this.addEventListener(e,t,e=>{i(e),this.removeEventListener(a)},n);return a}debounced(e,t,i,n=250,a={}){let s;return this.addEventListener(e,t,e=>{clearTimeout(s),s=setTimeout(()=>i(e),n)},a)}throttled(e,t,i,n=100,a={}){let s=!1;return this.addEventListener(e,t,e=>{s||(i(e),s=!0,setTimeout(()=>{s=!1},n))},a)}generateId(){return`listener_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}getStats(){return{...this.stats,groups:this.groups.size,listeners:this.listeners.size}}getActiveListeners(){const e=[];for(const[t,i]of this.listeners.entries())i.active&&e.push({id:t,eventType:i.eventType,group:i.group,target:i.target.constructor.name});return e}analyzeLeaks(){const e={totalListeners:this.listeners.size,activeListeners:this.stats.active,inactiveButNotRemoved:0,byTarget:new Map,byType:new Map,potentialLeaks:[]};for(const[t,i]of this.listeners.entries()){const n=i.target.constructor.name;e.byTarget.set(n,(e.byTarget.get(n)||0)+1),e.byType.set(i.eventType,(e.byType.get(i.eventType)||0)+1),i.active||(e.inactiveButNotRemoved++,e.potentialLeaks.push({id:t,eventType:i.eventType,target:n}))}return e.byTarget=Object.fromEntries(e.byTarget),e.byType=Object.fromEntries(e.byType),e}cleanup(){let e=0;for(const[t,i]of this.listeners.entries())i.active||(this.listeners.delete(t),e++);return e}destroy(){const e=this.removeAll();return this.listeners.clear(),this.groups.clear(),this.stats={registered:0,removed:0,active:0},e}}class qi{constructor(){this.errors=[],this.maxErrors=10,this.errorCounts=new Map,this.defaults={emotion:"neutral",gesture:null,audioLevel:0,particleCount:0,glowIntensity:.7,coreSize:1,breathRate:1,color:"#B0B0B0"}}wrap(e,t,i=null){return(...n)=>{try{return e(...n)}catch(e){return this.logError(e,t),null!==i?i:this.getDefault(t)}}}logError(e,t){const i={timestamp:(new Date).toISOString(),context:t,message:e.message,stack:e.stack};this.errors.push(i);const n=this.errorCounts.get(t)||0;this.errorCounts.set(t,n+1),this.errors.length>this.maxErrors&&this.errors.shift()}getDefault(e){const t={"emotion-transition":this.defaults.emotion,"gesture-execution":this.defaults.gesture,"audio-processing":this.defaults.audioLevel,"particle-system":this.defaults.particleCount,rendering:{glowIntensity:this.defaults.glowIntensity,coreSize:this.defaults.coreSize,color:this.defaults.color},"canvas-operations":null,"state-management":this.defaults.emotion};return Object.prototype.hasOwnProperty.call(t,e)?t[e]:null}validateInput(e,t,i){try{switch(t){case"emotion":return["neutral","joy","sadness","anger","fear","surprise","disgust","love","euphoria"].includes(e)?e:i;case"undertone":return null===e||["nervous","confident","tired","intense","subdued"].includes(e)?e:null;case"gesture":return["bounce","pulse","shake","spin","nod","tilt","expand","contract","flash","drift"].includes(e)?e:i;case"number":return"number"!=typeof e||isNaN(e)?i:e;case"string":return"string"==typeof e?e:i;case"boolean":return"boolean"==typeof e?e:i;default:return null!=e?e:i}}catch(e){return this.logError(e,"input-validation"),i}}hasExceededThreshold(e,t=5){return(this.errorCounts.get(e)||0)>=t}getErrorStats(){return{totalErrors:this.errors.length,errorsByContext:Object.fromEntries(this.errorCounts),recentErrors:this.errors.slice(-5)}}clearErrors(){this.errors=[],this.errorCounts.clear()}async attemptRecovery(e,t,i=3){let n=0;for(;n<i;)try{return await t()}catch(t){if(n++,this.logError(t,`recovery-${e}-attempt-${n}`),n>=i)throw new Error(`Recovery failed for ${e} after ${i} attempts`);await new Promise(e=>setTimeout(e,100*Math.pow(2,n)))}}}const Ni={quartz:{sssStrength:.8,sssAbsorption:[2.8,2.9,3],sssScatterDistance:[.2,.2,.25],sssThicknessBias:.6,sssThicknessScale:1.8,sssCurvatureScale:3,sssAmbient:.12,frostiness:.15,innerGlowStrength:.2,fresnelIntensity:1.5,causticIntensity:1.2,emotionColorBleed:0},emerald:{sssStrength:2,sssAbsorption:[.05,4,.1],sssScatterDistance:[.1,.5,.1],sssThicknessBias:.65,sssThicknessScale:1.8,sssCurvatureScale:3,sssAmbient:.1,frostiness:.2,innerGlowStrength:.15,fresnelIntensity:1.2,causticIntensity:1,emotionColorBleed:.35},ruby:{sssStrength:1.8,sssAbsorption:[4,.03,.08],sssScatterDistance:[.4,.04,.08],sssThicknessBias:.65,sssThicknessScale:1.9,sssCurvatureScale:2.5,sssAmbient:.08,frostiness:.12,innerGlowStrength:.12,fresnelIntensity:1.2,causticIntensity:1.15,emotionColorBleed:.35},sapphire:{sssStrength:2.2,sssAbsorption:[.15,.4,4],sssScatterDistance:[.1,.15,.5],sssThicknessBias:.65,sssThicknessScale:1.8,sssCurvatureScale:3,sssAmbient:.1,frostiness:.18,innerGlowStrength:.15,fresnelIntensity:1.3,causticIntensity:1,emotionColorBleed:.35},amethyst:{sssStrength:2.5,sssAbsorption:[3,.05,4.5],sssScatterDistance:[.4,.05,.5],sssThicknessBias:.7,sssThicknessScale:2,sssCurvatureScale:3,sssAmbient:.08,frostiness:.18,innerGlowStrength:.12,fresnelIntensity:1.4,causticIntensity:1,emotionColorBleed:.35},topaz:{sssStrength:1.5,sssAbsorption:[3.5,2,.1],sssScatterDistance:[.3,.2,.05],sssThicknessBias:.6,sssThicknessScale:1.7,sssCurvatureScale:2.8,sssAmbient:.12,frostiness:.14,innerGlowStrength:.18,fresnelIntensity:1.4,causticIntensity:1.1,emotionColorBleed:.25},citrine:{sssStrength:1.6,sssAbsorption:[3.8,2.5,.05],sssScatterDistance:[.35,.25,.05],sssThicknessBias:.58,sssThicknessScale:1.6,sssCurvatureScale:2.6,sssAmbient:.14,frostiness:.12,innerGlowStrength:.22,fresnelIntensity:1.3,causticIntensity:1.2,emotionColorBleed:.2},diamond:{sssStrength:.5,sssAbsorption:[2.5,2.5,2.5],sssScatterDistance:[.15,.15,.15],sssThicknessBias:.55,sssThicknessScale:1.5,sssCurvatureScale:4,sssAmbient:.15,frostiness:.08,innerGlowStrength:.25,fresnelIntensity:2,causticIntensity:1.5,emotionColorBleed:0}};function ji(e,t){if(!t||!e?.core3D?.customMaterial?.uniforms)return!1;const i=Ni[t];if(!i)return!1;const n=e.core3D.customMaterial.uniforms;return n.sssStrength&&(n.sssStrength.value=i.sssStrength),n.sssAbsorption&&n.sssAbsorption.value.set(...i.sssAbsorption),n.sssScatterDistance&&n.sssScatterDistance.value.set(...i.sssScatterDistance),n.sssThicknessBias&&(n.sssThicknessBias.value=i.sssThicknessBias),n.sssThicknessScale&&(n.sssThicknessScale.value=i.sssThicknessScale),n.sssCurvatureScale&&(n.sssCurvatureScale.value=i.sssCurvatureScale),n.sssAmbient&&(n.sssAmbient.value=i.sssAmbient),n.frostiness&&(n.frostiness.value=i.frostiness),n.innerGlowStrength&&(n.innerGlowStrength.value=i.innerGlowStrength),n.fresnelIntensity&&(n.fresnelIntensity.value=i.fresnelIntensity),void 0!==i.causticIntensity&&n.causticIntensity&&(n.causticIntensity.value=i.causticIntensity),n.emotionColorBleed&&(n.emotionColorBleed.value=i.emotionColorBleed??0),!0}function Ui(){return Object.keys(Ni)}function Hi(e){return Ni[e]||null}const Wi=["bouncing up and down","hopping around","rocking back and forth","side to side","light on feet","spring in step","leaning forward","leaning in","leaning closer","leaning toward","reaching out","reaching toward","pointing at","pointing to","waving hello","waving goodbye","nodding head","shaking head","head shake","head nod","head bob","head tilt","deep breath","taking a breath","breathing deeply","settling down","calming down","winding down","getting bigger","getting smaller","puffing up","spinning around","twirling around","at peace","in love","on cloud nine","over the moon","on top of the world","in awe","grossed out","freaked out","low key","low-key","high key","on edge","keyed up","wound up","low energy","no energy","running low","just a bit","just a little","a little bit","kind of","sort of","a bit","a little","a lot","over the top","off the charts","through the roof","split second","one time","few times","many times","again and again","over and over","on repeat","blood moon","full moon","new moon","half moon","solar eclipse","lunar eclipse","total eclipse","ring of fire","diamond ring","killing it","crushing it","nailed it","sussy baka","side eye"],Xi=/[,;|\/]+/,Yi=new Set(["a","an","the","is","are","am","be","being","been","i","me","my","it","its","to","of","for","with","as","this","that","these","those","just","only","also","too","please","pls","plz"]),$i=new Set(["but","and","or","yet","while","although","not","no","never","very","really","so","quite","rather","slightly","barely","extremely","completely","feeling","feel","feels","become","becoming","morph","morphing"]);function Qi(e){return e.toLowerCase().trim().replace(/['']/g,"'").replace(/[""]/g,'"').replace(/\s+/g," ")}function Zi(e){return["but","and","or","yet","while","although","with"].includes(e)}function Ji(e){return["not","no","never","don't","dont","doesn't","doesnt","isn't","isnt"].includes(e)}const Ki={nervous:{candidates:[{category:"emotion",target:"fear",priority:1},{category:"undertone",target:"nervous",priority:2}],rule:"standalone_is_emotion",examples:[{input:"nervous",resolved:{emotion:"fear"}},{input:"happy but nervous",resolved:{emotion:"joy",undertone:"nervous"}}]},anxious:{candidates:[{category:"emotion",target:"fear",priority:1},{category:"undertone",target:"nervous",priority:2}],rule:"standalone_is_emotion"},confident:{candidates:[{category:"emotion",target:"trust",priority:2},{category:"undertone",target:"confident",priority:1}],rule:"prefer_undertone",examples:[{input:"confident",resolved:{undertone:"confident"}},{input:"feeling confident",resolved:{emotion:"trust"}}]},tired:{candidates:[{category:"emotion",target:"sadness",priority:2},{category:"undertone",target:"tired",priority:1}],rule:"prefer_undertone",examples:[{input:"tired",resolved:{undertone:"tired"}},{input:"feeling tired",resolved:{emotion:"sadness",undertone:"tired"}}]},intense:{candidates:[{category:"undertone",target:"intense",priority:1},{category:"modifier",target:"intensity.very",priority:2}],rule:"prefer_undertone"},curious:{candidates:[{category:"emotion",target:"focused",priority:1},{category:"gesture",target:"lean",priority:2}],rule:"standalone_is_emotion",examples:[{input:"curious",resolved:{emotion:"focused"}},{input:"curious, leaning in",resolved:{emotion:"focused",gesture:"lean"}}]},interested:{candidates:[{category:"emotion",target:"focused",priority:1},{category:"gesture",target:"lean",priority:2}],rule:"standalone_is_emotion"},excited:{candidates:[{category:"emotion",target:"joy",priority:1},{category:"gesture",target:"bounce",priority:3}],rule:"standalone_is_emotion"},shaking:{candidates:[{category:"gesture",target:"shake",priority:1},{category:"emotion",target:"fear",priority:2}],rule:"standalone_is_gesture"},nodding:{candidates:[{category:"gesture",target:"nod",priority:1}],rule:"always_gesture"},glowing:{candidates:[{category:"gesture",target:"glow",priority:1},{category:"shape",target:"sun",priority:3}],rule:"standalone_is_gesture"},spinning:{candidates:[{category:"gesture",target:"spin",priority:1}],rule:"always_gesture"},love:{candidates:[{category:"emotion",target:"love",priority:1},{category:"shape",target:"heart",priority:2}],rule:"standalone_is_emotion",examples:[{input:"love",resolved:{emotion:"love"}},{input:"love heart",resolved:{emotion:"love",shape:"heart"}},{input:"become love",resolved:{shape:"heart"}}]},suspicious:{candidates:[{category:"emotion",target:"suspicion",priority:1},{category:"shape",target:"suspicion",priority:2}],rule:"standalone_is_emotion"},bright:{candidates:[{category:"emotion",target:"joy",priority:2},{category:"shape",target:"sun",priority:3},{category:"modifier",target:"intensity.very",priority:4}],rule:"context_dependent"},yes:{candidates:[{category:"gesture",target:"nod",priority:1}],rule:"always_gesture"},no:{candidates:[{category:"gesture",target:"shake",priority:1}],rule:"always_gesture"},agree:{candidates:[{category:"gesture",target:"nod",priority:1},{category:"emotion",target:"trust",priority:2}],rule:"standalone_is_gesture"},disagree:{candidates:[{category:"gesture",target:"shake",priority:1}],rule:"always_gesture"}},en={emotionContext:["feeling","feel","feels","felt","emotion","emotional","emotionally","mood","moody","state","am","is","are","being","becoming","become","grew","growing"],gestureContext:["do","doing","does","did","perform","performing","action","move","moving","movement","start","starting","begin","beginning","physically","motion"],shapeContext:["morph","morphing","morphed","transform","transforming","transformed","become","becoming","turn into","shape","form","look like","change to","change into"],undertoneContext:["but","yet","while","although","with","and also","mixed with","underneath","underlying","beneath","a bit","slightly","somewhat"],modifierContext:["very","really","so","extremely","slightly","barely","completely","quickly","slowly","briefly"]};function tn(e,t,i){const n=en[`${i}Context`];if(!n)return!1;const a=Math.max(0,t-3),s=Math.min(e.length,t+4);for(let i=a;i<s;i++)if(i!==t&&n.includes(e[i]))return!0;return!1}function nn(e,t){switch(t){case"emotion":return null!==e.emotion;case"gesture":return e.gestures&&e.gestures.length>0;case"shape":return null!==e.shape;case"undertone":return null!==e.undertone;default:return!1}}function an(e,t,i,n){const a=Ki[e];if(!a)return null;const{candidates:s,rule:o}=a;if(1===s.length)return s[0];switch(o){case"standalone_is_emotion":if(nn(n,"emotion")){const e=s.find(e=>"emotion"!==e.category);if(e)return e}return tn(t,i,"emotion"),s.find(e=>"emotion"===e.category)||s[0];case"standalone_is_gesture":if(nn(n,"gesture")){const e=s.find(e=>"gesture"!==e.category);if(e)return e}return tn(t,i,"gesture"),s.find(e=>"gesture"===e.category)||s[0];case"prefer_undertone":return tn(t,i,"emotion")?s.find(e=>"emotion"===e.category)||s[0]:s.find(e=>"undertone"===e.category)||s[0];case"always_gesture":return s.find(e=>"gesture"===e.category)||s[0];case"always_emotion":return s.find(e=>"emotion"===e.category)||s[0];case"context_dependent":for(const e of["emotion","gesture","shape","undertone"])if(tn(t,i,e)){const t=s.find(t=>t.category===e);if(t)return t}return s.sort((e,t)=>e.priority-t.priority)[0];default:return s.sort((e,t)=>e.priority-t.priority)[0]}}function sn(e){return e in Ki}const on={neutral:["neutral","default","normal","baseline","standard","nothing special","nothing particular","no strong feeling","not much","meh","whatever","indifferent","balanced","even","steady","stable","centered","level","middle ground","in between","ready","waiting","standing by","at attention","present","here","available","attentive","reset","clear","blank","empty","clean slate"],joy:["happy","joy","joyful","joyous","pleased","glad","content","satisfied","gratified","comfortable","good","cheerful","cheery","merry","jovial","jolly","upbeat","sunny","bright","lighthearted","buoyant","delighted","thrilled","overjoyed","elated","jubilant","exultant","gleeful","glowing","beaming","radiant","pumped","stoked","psyched","amped","hyped","vibing","living","slaying","winning","lit","fire","sick","dope","chuffed","pleased as punch","over the moon","made up","tickled","tickled pink","felicitous","beatific","blissful","smiling","grinning","laughing","giggling"],calm:["calm","peaceful","serene","tranquil","relaxed","at ease","comfortable","loose","unwound","decompressed","chilled","still","quiet","hushed","silent","soft","gentle","mild","placid","smooth","composed","collected","centered","grounded","untroubled","unworried","unbothered","unfazed","meditative","zen","mindful","contemplative","reflective","introspective","soothed","eased","mellowed","softened","chill","coasting","floating","drifting","laid back","easy going","low key","sorted","easy peasy"],excited:["excited","exciting","excitable","enthusiastic","eager","keen","avid","passionate","fervent","ardent","zealous","energetic","energized","animated","lively","spirited","vivacious","vibrant","dynamic","bouncy","peppy","perky","sprightly","anticipating","expectant","looking forward","itching","raring","chomping at the bit","fired up","charged","electric","electrified","buzzing","tingling","crackling","sparking","jazzed","juiced","geeked","hype","turnt","going off","well excited","buzzing","restless","fidgety","antsy","jumpy","twitchy","keyed up","wound up"],sadness:["sad","sadness","saddened","unhappy","down","low","blue","glum","bummed","disappointed","let down","discouraged","disheartened","dispirited","deflated","melancholy","melancholic","somber","gloomy","mournful","sorrowful","doleful","woeful","heavy-hearted","downcast","crestfallen","heartbroken","devastated","crushed","shattered","despairing","despondent","desolate","inconsolable","grief","grieving","mourning","bereft","empty","hollow","numb","void","wistful","longing","yearning","pining","nostalgic","bummed out","down in the dumps","in a funk","in the dumps","feeling low","gutted","choked","crying","tearful","weeping","sobbing","sighing","drooping","wilting","slumping"],anger:["angry","anger","angered","mad","annoyed","irritated","bothered","irked","peeved","miffed","vexed","displeased","put out","ticked off","ticked","frustrated","aggravated","exasperated","fed up","sick of","had enough","cross","upset","worked up","furious","enraged","livid","irate","incensed","infuriated","outraged","seething","fuming","boiling","burning","smoldering","raging","ballistic","apoplectic","berserk","seeing red","losing it","pissed","pissed off","salty","pressed","triggered","tilted","heated","steaming","narked","cheesed off","brassed off","shirty","stroppy","mardy","ropeable","filthy","spewing","clenching","tensing","grinding"],fear:["afraid","scared","fear","fearful","uneasy","unsettled","apprehensive","wary","concerned","worried","jittery","shaky","trembling","quivering","tense","tight","clenched","knotted","frightened","alarmed","startled","spooked","freaked","freaked out","creeped out","on edge","rattled","unnerved","terrified","petrified","horrified","panicked","panic","panicking","terror","dread","paranoid","distrustful","looking over shoulder","sketched","sketched out","wigged out","shook","bricking it","having kittens","in a flap","frozen","paralyzed","deer in headlights","heart racing","heart pounding","sweating"],surprise:["surprised","surprise","surprising","oh","huh","hmm","interesting","unexpected","caught off guard","astonished","amazed","astounded","startled","taken aback","struck","shocked","stunned","staggered","floored","dumbfounded","flabbergasted","gobsmacked","blown away","mind blown","speechless","wow","whoa","omg","no way","incredible","unbelievable","amazing","alarmed","dismayed","appalled","bewildered","baffled","perplexed","puzzled","confused","disoriented","thrown","shooketh","gagged","dead","wait what","blimey","crikey","bloody hell","jaw dropped","eyes wide","double take","gasp","gasping"],disgust:["disgusted","disgust","disgusting","distaste","dislike","aversion","put off","turned off","off-putting","repulsed","revolted","repelled","grossed out","creeped out","icked out","sickened","nauseated","nauseous","appalled","horrified","scandalized","offended","outraged","indignant","contempt","contemptuous","disdain","scorn","gagging","retching","cringing","wincing","recoiling","shrinking back","gross","ew","eww","yuck","yucky","ick","nasty","foul","vile","rank","minging","manky","grotty"],love:["love","loving","loved","affection","affectionate","fond","fondness","tender","tenderness","gentle","caring","care","nurturing","supportive","protective","devoted","dedicated","warm","warmth","warm-hearted","kind","kind-hearted","compassionate","sympathetic","adoring","adore","cherish","cherishing","treasure","treasuring","doting","romantic","amorous","passionate","smitten","infatuated","enamored","besotted","head over heels","falling for","connected","bonded","attached","close","intimate","deep","profound","heart eyes","crushing","swooning","melting","hugging","embracing","holding","cuddling","snuggling","nuzzling"],euphoria:["euphoric","euphoria","bliss","blissful","transcendent","otherworldly","sublime","heavenly","divine","ethereal","celestial","ecstatic","ecstasy","rapture","rapturous","exultant","exalted","elevated","peak","pinnacle","height","climax","breakthrough","revelation","epiphany","overwhelming joy","pure joy","absolute joy","complete happiness","total bliss","floating","soaring","flying","weightless","radiating","shining","on cloud nine","in heaven","on top of the world","walking on air","living my best life","ascended"],focused:["focused","focus","focusing","concentrating","concentration","concentrated","attentive","attention","attending","thinking","thought","thoughtful","pondering","considering","contemplating","reflecting","musing","mulling","engaged","absorbed","immersed","engrossed","rapt","riveted","captivated","enthralled","intent","determined","resolute","single-minded","laser focused","zeroed in","working","processing","analyzing","examining","studying","learning","figuring out","locked in","dialed in","in the zone","flow state","deep work","grinding","staring","gazing","peering","squinting","furrowed brow"],suspicion:["suspicious","suspicion","suspect","doubtful","doubt","doubting","skeptical","skepticism","questioning","uncertain","unsure","unconvinced","wary","cautious","guarded","careful","leery","circumspect","vigilant","distrustful","mistrust","mistrustful","disbelieving","incredulous","unbelieving","scrutinizing","examining","assessing","evaluating","judging","sizing up","sus","sussy","suss","side eye","giving side eye","side-eyeing","eyeing","not buying it","narrowed eyes","squinting","raised eyebrow","cocked head","tilted head","looking askance"],resting:["resting","rest","restful","tired","weary","fatigued","exhausted","drained","spent","depleted","worn out","sleepy","drowsy","dozy","groggy","yawning","nodding off","drifting off","sluggish","lethargic","listless","languid","lazy","idle","inactive","recovering","recuperating","recharging","winding down","powering down","shutting down","sleeping","asleep","slumbering","dozing","napping","snoozing","zonked","wiped","beat","dead tired","running on empty","out of gas","crashed","knackered","shattered","cream crackered"],glitch:["glitch","glitchy","glitching","malfunction","malfunctioning","broken","bugged","buggy","error","erroring","corrupted","corruption","scrambled","garbled","distorted","warped","static","noise","interference","pixelated","artifacting","tearing","haywire","fritzing","shorting out","going crazy","spazzing","unstable","erratic","unpredictable","flickering","stuttering","lagging","does not compute","syntax error","crash"]},rn={nervous:["nervous","nervously","anxious","anxiously","worried","worriedly","uneasy","uneasily","apprehensive","jittery","shaky","trembling","quivering","fidgety","restless","twitchy","tense","tensely","on edge","edgy","keyed up","wound up","uptight","self-conscious","awkward","awkwardly","hesitant","hesitantly","uncertain","uncertainly","sketchy","stressed","stressing","low-key panicking","kinda freaking out"],confident:["confident","confidently","confidence","assured","assuredly","certain","certainly","sure","surely","positive","positively","bold","boldly","brave","bravely","daring","daringly","fearless","fearlessly","strong","strongly","powerful","powerfully","firm","firmly","solid","solidly","authoritative","commanding","assertive","decisive","decisively","resolute","resolutely","poised","self-assured","unflappable","unfazed","owning it","killing it","crushing it","boss","like a boss"],tired:["tired","tiredly","tiredness","exhausted","weary","wearily","fatigued","drained","spent","depleted","sluggish","sluggishly","slow","slowly","lethargic","listless","languid","low energy","no energy","out of energy","running low","running on fumes","droopy","drooping","sagging","slumping","heavy","weighted","dragging","wiped","beat","dead","zonked","burned out","fried","cooked","toast"],intense:["intense","intensely","intensity","heightened","elevated","amplified","magnified","increased","enhanced","forceful","forcefully","powerful","powerfully","fierce","fiercely","strong","strongly","passionate","passionately","fervent","fervently","ardent","ardently","vehement","vehemently","sharp","sharply","acute","acutely","keen","keenly","piercing","piercingly","extreme","extremely","deeply","profoundly","tremendously","immensely","incredibly","super","mega","ultra","hella","mad","crazy"],subdued:["subdued","subduedly","soft","softly","gentle","gently","mild","mildly","light","lightly","restrained","held back","contained","tempered","moderated","toned down","quiet","quietly","hushed","muted","understated","subtle","subtly","modest","modestly","humble","humbly","reserved","demure","unassuming","faint","faintly","dim","dimly","pale","faded","washed out","low key","lowkey","easy","easy going"],clear:["clear","clearly","pure","purely","clean","cleanly","simple","simply","plain","plainly","direct","directly","straightforward","honest","honestly","frank","frankly","transparent","transparently","open","openly","obvious","obviously","evident","evidently","unmodified","unaltered","unchanged","normal","normally","regular","regularly","standard","basic","baseline"]},ln={bounce:["bounce","bouncing","bouncy","hop","hopping","hoppy","spring","springing","springy","boing","boinging","bouncing up and down","hopping around","spring in step","light on feet"],pulse:["pulse","pulsing","pulsate","pulsating","throb","throbbing","beat","beating","pulsing gently","steady pulse","heartbeat","heart beat"],shake:["shake","shaking","shaky","shudder","shuddering","tremble","trembling","quake","quaking","shiver","shivering","no","nope","nah","disagree","disagreeing","refuse","refusing","deny","denying","shaking head","shake head","head shake","saying no","shaking no"],nod:["nod","nodding","yes","yeah","yep","yup","agree","agreeing","acknowledge","acknowledging","confirm","confirming","accept","accepting","approve","approving","understand","understanding","got it","gotcha","i see","makes sense","understood","nodding head","nod head","head nod","nodding along","nodding yes"],vibrate:["vibrate","vibrating","vibration","buzz","buzzing","hum","humming","quiver","quivering","vibrating slightly","gentle buzz","low hum","subtle vibration"],orbit:["orbit","orbiting","circle","circling","revolve","revolving","rotate","rotating","circling around","going around","rotating slowly","orbital motion"],sway:["sway","swaying","rock","rocking","swing","swinging","oscillate","oscillating","swaying gently","rocking back and forth","gentle sway","side to side"],float:["float","floating","drift","drifting","hover","hovering","glide","gliding","levitate","levitating","weightless","weightlessness","buoyant","airy","floating gently","drifting along","hovering in place","light as air"],lean:["lean","leaning","incline","inclining","tilt","tilting","leaning in","lean in","leaning forward","lean forward","leaning toward","lean toward","leaning closer","lean closer","moving closer","coming closer","drawing near","approaching","interested","intrigued","curious","engaged","attentive","listening closely","paying attention"],reach:["reach","reaching","extend","extending","stretch","stretching","reaching out","reach out","reaching toward","reach toward","extending toward","stretching toward","offer","offering","present","presenting","give","giving","help","helping"],point:["point","pointing","indicate","indicating","gesture","gesturing","direct","directing","pointing at","pointing to","pointing toward","gesturing toward","showing","directing attention"],wave:["wave","waving","greet","greeting","hello","hi","hey","goodbye","bye","farewell","welcome","welcoming","waving hello","waving goodbye","friendly wave","waving hand"],headBob:["headbob","head bob","headbobbing","head bobbing","bobbing","bob","nodding to beat","nodding to music","bobbing along","bobbing to rhythm","vibing","grooving","jamming","bobbing head","bob head","feeling the beat","moving to music"],wiggle:["wiggle","wiggling","wiggly","jiggle","jiggling","jiggly","squirm","squirming","wriggle","wriggling","wiggling around","little wiggle","happy wiggle","excited wiggle"],groove:["groove","grooving","groovy","dance","dancing","boogie","boogying","funk","funky","rhythmic","moving to music","feeling the music","in the groove","getting down","busting a move","doing a little dance"],twitch:["twitch","twitching","twitchy","spasm","spasming","jerk","jerking","jerky","flinch","flinching","quick twitch","nervous twitch","sudden movement"],jitter:["jitter","jittering","jittery","stutter","stuttering","jittering around","slight jitter","nervous jitter"],spin:["spin","spinning","twirl","twirling","whirl","whirling","rotate","rotating","turn","turning","spinning around","quick spin","full rotation","twirling around"],jump:["jump","jumping","jumpy","leap","leaping","spring","springing","bound","bounding","jumping up","leap up","spring up","jumping for joy"],stretch:["stretch","stretching","stretchy","elongate","elongating","extend","extending","lengthen","lengthening","stretching out","big stretch","reaching up","stretching tall"],expand:["expand","expanding","grow","growing","enlarge","enlarging","swell","swelling","inflate","inflating","bloat","bloating","getting bigger","growing larger","puffing up","expanding outward"],contract:["contract","contracting","shrink","shrinking","compress","compressing","deflate","deflating","reduce","reducing","getting smaller","shrinking down","pulling in","contracting inward"],twist:["twist","twisting","twisty","contort","contorting","warp","warping","distort","distorting","twisting around","getting twisted","warping shape"],tilt:["tilt","tilting","tilted","angle","angling","angled","cock","cocking","cocked","tilting head","tilt head","cocking head","curious tilt","angling sideways","head tilt"],hula:["hula","hula-ing","hip sway","swaying hips","circular sway","round motion","hula motion","hula dance"],sparkle:["sparkle","sparkling","sparkly","twinkle","twinkling","twinkly","glitter","glittering","glittery","shine","shining","shiny","celebrate","celebrating","celebration","celebratory","festive","party","partying","victory","triumphant","triumph","winning","success","successful","achievement","accomplished","nailed it","slay","slaying","killing it","yasss","yay","woo","woohoo"],shimmer:["shimmer","shimmering","shimmery","glisten","glistening","gleam","gleaming","lustrous","luminous","soft shimmer","gentle gleam","shimmering light","pearlescent"],glow:["glow","glowing","glowy","radiate","radiating","emanate","emanating","luminous","luminescent","bright","brighten","brightening","soft glow","warm glow","inner glow","glowing warmly","lighting up","lit up"],flash:["flash","flashing","flashy","blink","blinking","strobe","strobing","flare","flaring","quick flash","bright flash","flashing light","strobing light"],flicker:["flicker","flickering","flickery","flutter","fluttering","waver","wavering","guttering","flickering light","unsteady light","wavering glow","candle-like"],burst:["burst","bursting","explode","exploding","explosion","erupt","erupting","eruption","pop","popping","boom","booming","bursting out","burst of energy","explosive","big burst"],settle:["settle","settling","settled","calm","calming","ground","grounding","grounded","center","centering","centered","anchor","anchoring","anchored","root","rooting","rooted","relax","relaxing","unwind","unwinding","decompress","decompressing","settling down","calming down","winding down","cooling down","coming to rest","finding peace","sinking into","melting into"],breathe:["breathe","breathing","breath","inhale","inhaling","exhale","exhaling","sigh","sighing","respire","respiring","deep breath","deep breathing","slow breath","slow breathing","long breath","full breath","breathing deeply","breathing slowly","taking a breath","take a breath","catching breath","breath work","breathwork","inhale exhale","in and out","meditative breathing","calming breath","cleansing breath","relaxing breath","centering breath","mindful breathing"],peek:["peek","peeking","peer","peering","peep","peeping","glance","glancing","peeking out","peek out","looking shyly","shy glance","quick peek","sneaking a look"],fade:["fade","fading","dim","dimming","disappear","disappearing","vanish","vanishing","fading out","fading away","growing dim","becoming transparent","dissolving","melting away"],hold:["hold","holding","pause","pausing","paused","freeze","freezing","frozen","still","stillness","stop","stopping","stopped","holding still","staying still","frozen in place","completely still","motionless","stationary"],rain:["rain","raining","shower","showering","drip","dripping","pour","pouring","fall","falling","raining down","particles falling","gentle rain","shower of particles"]},hn={circle:["circle","circular","round","rounded","orb","ball","sphere","spherical","ring","disc","disk","whole","complete","unity","unified","endless","infinite","continuous","full circle","perfect round","come full circle"],sphere:["sphere","spherical","globe","globular","ball","3d circle","three dimensional","round ball","floating sphere"],square:["square","squared","boxy","box","rectangle","rectangular","quadrilateral","cube","cubic","block","blocky","stable","solid","grounded","sturdy","rigid","firm","structured","four sided","four corners","box shape"],triangle:["triangle","triangular","tri","pyramid","pyramidal","delta","wedge","arrow","arrowhead","pointed","sharp","dynamic","directional","ascending","three sided","three pointed","pointing up"],heart:["heart","hearted","hearts","love","loving","lovely","valentine","romantic","affection","affectionate","caring","care","tender","warmth","warm-hearted","heartfelt","compassion","compassionate","devotion","devoted","luv","wuv","<3","❤️","💕","💗","full of love","with love","heart shape","heart shaped","from the heart"],suspicion:["suspicion","suspicious","suspect","sly","slyly","sneaky","sneakily","mischievous","mischief","smirk","smirking","smirky","grin","grinning","sly grin","side eye","sideeye","side-eye","skeptical","skepticism","doubtful","doubt","doubting","wary","distrustful","distrust","sus","sussy","sussy baka","hmm","hmmm","hmmmm","shady","fishy","sketchy","not buying it","something fishy","seems off","up to something"],star:["star","starred","starry","stars","stellar","astral","twinkle","twinkling","achievement","achieved","excellence","excellent","gold star","five star","superstar","rockstar","rock star","wonder","wonderful","wondrous","magical","magic","miraculous","amazing","spectacular","reach for stars","seeing stars","star shape","shining star"],sun:["sun","sunny","sunshine","sunlight","solar","sol","daylight","daytime","day","radiant","radiance","radiating","bright","brightness","brilliant","glowing","glow","blazing","blaze","warm","warmth","cheerful","cheery","optimistic","optimism","hopeful","hope","positive","positivity","full of light","ray of sunshine","like the sun","sunny disposition"],moon:["moon","moony","moonlight","moonlit","lunar","crescent","nighttime","night","nocturnal","waxing","waning","gibbous","new moon","full moon","half moon","quarter moon","crescent moon","dreamy","dreamlike","dream","mysterious","mystery","mystical","ethereal","otherworldly","serene","serenity","tranquil","contemplative","reflective","moonlit night","by moonlight","moon shape","under the moon"],lunar:["lunar eclipse","blood moon","blood-moon","red moon","copper moon","rust moon","eclipsing","eclipsed","shadow crossing","earth shadow","ominous","foreboding","portentous","dramatic","intense","transforming","transformation","moon in shadow","moon turning red","eclipse phase","lunar event"],solar:["solar eclipse","total eclipse","corona","diamond ring","totality","umbra","penumbra","ring of fire","dark sun","blocked sun","occluded","awe","awesome","awe-inspiring","rare","momentous","historic","breathtaking","magnificent","sun blocked","sun covered","total darkness","corona visible"],eclipse:["eclipse","eclipsing","eclipsed","celestial event","astronomical event","overshadow","overshadowed","blocked","blocking","obscured","hidden","hiding","concealed","passing","crossing","alignment","in eclipse","going dark","being eclipsed","eclipsed by"]},cn={intensity:{barely:["barely","hardly","scarcely","faintly","slightly","marginally","just a bit","just a little","just barely","hint of","touch of","trace of"],slightly:["slightly","somewhat","a little","a bit","mildly","lightly","kind of","kinda","sort of","sorta","a tad","a touch","a smidge"],moderately:["moderately","reasonably","fairly","pretty","rather","quite"],normal:["normal","normally","regular","regularly","standard","typical","typically","average","ordinary"],notably:["notably","noticeably","clearly","definitely","certainly","decidedly","genuinely","truly","really"],very:["very","really","so","such","quite","highly","deeply","seriously","majorly","hella","super","extra","mad"],extremely:["extremely","incredibly","immensely","tremendously","enormously","hugely","intensely","fiercely","wildly","insanely","crazy","ridiculously","mega","ultra","hyper"],absolutely:["absolutely","completely","totally","utterly","entirely","wholly","fully","maximum","max","over the top","off the charts","through the roof","to the max"]},duration:{flash:["flash","instant","instantaneous","split second","split-second","momentary","fleeting","brief flash"],quick:["quick","quickly","fast","rapid","swift","swiftly","brief","briefly","short","shortly","snap"],normal:["normal","regular","standard","typical","usual"],slow:["slow","slowly","gradual","gradually","gentle","gently","easy","easily","leisurely","unhurried"],long:["long","prolonged","extended","sustained","lasting","lingering","drawn out","drawn-out"],persistent:["persistent","constant","continuous","ongoing","steady","maintained","held","holding","stay","staying","keep","keeping","remain","remaining"]},transition:{instant:["instant","instantly","immediate","immediately","sudden","suddenly","abrupt","abruptly","snap","cut","jump"],snappy:["snappy","crisp","sharp","sharply","brisk","briskly","punchy"],smooth:["smooth","smoothly","natural","naturally","fluid","fluidly","flowing"],gentle:["gentle","gently","soft","softly","gradual","gradually","easing","gliding","drifting"],dreamy:["dreamy","dreamlike","floaty","ethereal","languid","lazy","flowing","melting"]},repetition:{once:["once","one time","single","just once","only once","one shot"],few:["few","few times","couple","couple times","twice","two times","thrice","three times"],several:["several","several times","multiple","multiple times","repeatedly","again and again"],many:["many","many times","lots","lots of times","over and over","nonstop"],loop:["loop","looping","looped","continuous","continuously","forever","infinitely","endlessly","always","keep going","on repeat"]}},un={barely:{min:.1,max:.2,default:.15},slightly:{min:.2,max:.4,default:.3},moderately:{min:.4,max:.5,default:.45},normal:{min:.5,max:.6,default:.55},notably:{min:.6,max:.7,default:.65},very:{min:.7,max:.85,default:.8},extremely:{min:.85,max:.95,default:.9},absolutely:{min:.95,max:1,default:1}},dn={flash:{min:100,max:500,default:250},quick:{min:500,max:1e3,default:750},normal:{min:1e3,max:2e3,default:1500},slow:{min:2e3,max:4e3,default:3e3},long:{min:4e3,max:8e3,default:6e3},persistent:{min:8e3,max:1/0,default:1e4}};function mn(e){const t=new Map;for(const[i,n]of Object.entries(e)){for(const e of n){const n=e.toLowerCase().trim();t.set(n,i)}t.set(i.toLowerCase(),i)}return t}class pn{constructor(){this.emotionLookup=mn(on),this.undertoneLookup=mn(rn),this.gestureLookup=mn(ln),this.shapeLookup=mn(hn),this.modifierLookup=function(e){const t=new Map;for(const[i,n]of Object.entries(e))for(const[e,a]of Object.entries(n))for(const n of a){const a=n.toLowerCase().trim();t.set(a,{type:i,level:e})}return t}(cn)}parse(e){const t={emotion:null,undertone:"clear",gestures:[],shape:null,intensity:un.normal.default,duration:dn.normal.default,transition:"smooth",repetition:"once",unrecognized:[],raw:e};if(!e||"string"!=typeof e)return t;const{tokens:i}=function(e){if(!e||"string"!=typeof e)return{tokens:[],segments:[],phrases:new Map};const t=Qi(e),{processed:i,phrases:n}=function(e){const t=new Map;let i=e,n=0;for(const e of Wi){const a=Qi(e);if(i.includes(a)){const e=`__PHRASE_${n}__`;i=i.replace(new RegExp(a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"g"),e),t.set(e,a),n++}}return{processed:i,phrases:t}}(t),a=i.split(Xi).map(e=>e.trim()).filter(e=>e.length>0),s=[],o=[];for(const e of a){let t=e;for(const[e,i]of n)t=t.replace(e,i);o.push(t.trim());const i=e.split(/\s+/);for(const e of i){if(n.has(e)){s.push(n.get(e));continue}if(!e)continue;if(Yi.has(e)&&!$i.has(e))continue;const t=e.replace(/^[^\w]+|[^\w]+$/g,"");t&&s.push(t)}}return{tokens:s,segments:o,phrases:n}}(e);if(0===i.length)return t;let n=!1;for(let e=0;e<i.length;e++){const a=i[e];if(!Zi(a))if(Ji(a))n=!0;else if(n)n=!1;else{if(sn(a)){const n=an(a,i,e,t);if(n){this._applyResolution(t,n);continue}}this._tryEmotion(a,t)||this._tryGesture(a,t)||this._tryShape(a,t)||this._tryUndertone(a,t)||this._tryModifier(a,t)||t.unrecognized.push(a)}}return t}_applyResolution(e,t){const{category:i,target:n}=t;switch(i){case"emotion":e.emotion||(e.emotion=n);break;case"undertone":"clear"===e.undertone&&(e.undertone=n);break;case"gesture":e.gestures.includes(n)||e.gestures.push(n);break;case"shape":e.shape||(e.shape=n)}}_tryEmotion(e,t){const i=this.emotionLookup.get(e);return!(!i||t.emotion||(t.emotion=i,0))}_tryGesture(e,t){const i=this.gestureLookup.get(e);return!(!i||t.gestures.includes(i)||(t.gestures.push(i),0))}_tryShape(e,t){const i=this.shapeLookup.get(e);return!(!i||t.shape||(t.shape=i,0))}_tryUndertone(e,t){const i=this.undertoneLookup.get(e);return!(!i||"clear"!==t.undertone||(t.undertone=i,0))}_tryModifier(e,t){const i=this.modifierLookup.get(e);if(i){const{type:e,level:n}=i;switch(e){case"intensity":t.intensity=un[n]?.default||t.intensity;break;case"duration":t.duration=dn[n]?.default||t.duration;break;case"transition":t.transition=n;break;case"repetition":t.repetition=n}return!0}return!1}validate(e){const t=[];return e.emotion||0!==e.gestures.length||e.shape||t.push("No actionable intent found (need emotion, gesture, or shape)"),(e.intensity<0||e.intensity>1)&&t.push(`Intensity ${e.intensity} out of range [0, 1]`),e.duration<=0&&t.push(`Duration ${e.duration} must be positive`),{valid:0===t.length,errors:t}}static getAvailableEmotions(){return Object.keys(on)}static getAvailableUndertones(){return Object.keys(rn)}static getAvailableGestures(){return Object.keys(ln)}static getAvailableShapes(){return Object.keys(hn)}}function gn(e=32,t=32){const i=[],n=[],a=[];for(let a=0;a<=t;a++){const s=a/t*Math.PI;for(let t=0;t<=e;t++){const a=t/e*Math.PI*2,o=Math.cos(a)*Math.sin(s),r=Math.cos(s),l=Math.sin(a)*Math.sin(s);i.push(o,r,l),n.push(o,r,l)}}for(let i=0;i<t;i++)for(let t=0;t<e;t++){const n=i*(e+1)+t,s=n+e+1,o=n+1,r=s+1;a.push(n,s,o),a.push(o,s,r)}return{vertices:new Float32Array(i),normals:new Float32Array(n),indices:new Uint16Array(a)}}function fn(e=6){const t=[],i=[],n=[],a=new Map;let s=0;function o(e,n,o,r,l,h){const c=`${e},${n},${o}`;return a.has(c)||(t.push(e,n,o),i.push(r,l,h),a.set(c,s++)),a.get(c)}const r=o(0,1.5,0,0,1,0),l=[];for(let t=0;t<e;t++){const i=t/e*Math.PI*2,n=o(.7*Math.cos(i),0,.7*Math.sin(i),Math.cos(i),0,Math.sin(i));l.push(n)}const h=o(0,-1.5,0,0,-1,0);for(let t=0;t<e;t++){const i=(t+1)%e;n.push(r,l[t],l[i])}for(let t=0;t<e;t++){const i=(t+1)%e;n.push(l[t],h,l[i])}return{vertices:new Float32Array(t),normals:new Float32Array(i),indices:new Uint16Array(n)}}function yn(){const e=[],t=[],i=[],n=[0,1.2,0],a=[0,-.8,0],s=[];for(let e=0;e<8;e++){const t=e/8*Math.PI*2;s.push([.8*Math.cos(t),0,.8*Math.sin(t)])}function o(n,a,s){const o=[a[0]-n[0],a[1]-n[1],a[2]-n[2]],r=[s[0]-n[0],s[1]-n[1],s[2]-n[2]],l=o[1]*r[2]-o[2]*r[1],h=o[2]*r[0]-o[0]*r[2],c=o[0]*r[1]-o[1]*r[0],u=Math.sqrt(l*l+h*h+c*c),d=[l/u,h/u,c/u],m=e.length/3;e.push(...n),t.push(...d),e.push(...a),t.push(...d),e.push(...s),t.push(...d),i.push(m,m+1,m+2)}for(let e=0;e<8;e++){const t=(e+1)%8;o(n,s[e],s[t])}for(let e=0;e<8;e++){const t=(e+1)%8;o(s[e],a,s[t])}return{vertices:new Float32Array(e),normals:new Float32Array(t),indices:new Uint16Array(i)}}const vn={sphere:gn(32,32),crystal:fn(6),diamond:yn()};function bn(){Object.values(vn).forEach(e=>{e&&e.vertices&&(e.vertices=null,e.normals=null,e.indices=null)})}class wn{constructor(e={}){this.config={canvasId:e.canvasId||"emotive-canvas",coreGeometry:e.coreGeometry||"sphere",targetFPS:e.targetFPS||60,enableParticles:!1!==e.enableParticles,defaultEmotion:e.defaultEmotion||"neutral",...e},this.container=null,this.webglCanvas=null,this.canvas2D=null,this.core3D=null,this.particleSystem=null,this.isRunning=!1,this._destroyed=!1,this.animationFrameId=null,this.lastFrameTime=0,this.gestureTimeouts=[],this.eventManager=new Vi,this.eventManager.emit||(this.eventManager._listeners={},this.eventManager.emit=(e,t)=>{const i=this.eventManager._listeners[e];i&&i.forEach(e=>e(t))},this.eventManager.on=(e,t)=>{this.eventManager._listeners[e]||(this.eventManager._listeners[e]=[]),this.eventManager._listeners[e].push(t)},this.eventManager.off=(e,t)=>{const i=this.eventManager._listeners[e];if(i){const e=i.indexOf(t);e>-1&&i.splice(e,1)}}),this.errorBoundary=new qi,this.emotion="neutral",this.undertone=null,this._intentParser=new pn,this._feelRateLimiter={calls:[],windowMs:1e3,maxCallsPerSecond:10}}init(e){try{if(this.setupCanvasLayers(e),this.core3D=new Gi(this.webglCanvas,{geometry:this.config.coreGeometry,emotion:this.config.defaultEmotion,enableParticles:this.config.enableParticles,enablePostProcessing:this.config.enablePostProcessing,enableShadows:this.config.enableShadows,enableControls:this.config.enableControls,autoRotate:this.config.autoRotate,enableBlinking:this.config.enableBlinking,enableBreathing:this.config.enableBreathing,cameraDistance:this.config.cameraDistance,fov:this.config.fov,minZoom:this.config.minZoom,maxZoom:this.config.maxZoom,materialVariant:this.config.materialVariant,assetBasePath:this.config.assetBasePath}),this.ctx2D=this.canvas2D.getContext("2d"),this.config.enableParticles&&!this.core3D?.particleOrchestrator){const e=this.config.maxParticles||300;this.particleSystem=new hi(e,this.errorBoundary),this.particleSystem.canvasWidth=this.canvas2D.width,this.particleSystem.canvasHeight=this.canvas2D.height}return this}catch(e){throw console.error("Failed to initialize 3D engine:",e),e}}setupCanvasLayers(e){if("CANVAS"===e.tagName){const t=e.parentElement;this.container=document.createElement("div"),this.container.style.position="relative",this.container.style.width="100%",this.container.style.height="100%",t.replaceChild(this.container,e)}else this.container=e,this.container.style.position&&"static"!==this.container.style.position||(this.container.style.position="relative");this.canvas2D=document.createElement("canvas"),this.canvas2D.id=`${this.config.canvasId}-particles`,this.canvas2D.width=this.container.offsetWidth||400,this.canvas2D.height=this.container.offsetHeight||400,this.canvas2D.style.position="absolute",this.canvas2D.style.top="0",this.canvas2D.style.left="0",this.canvas2D.style.width="100%",this.canvas2D.style.height="100%",this.canvas2D.style.background="transparent",this.canvas2D.style.zIndex="1",this.canvas2D.style.pointerEvents="none",this.container.appendChild(this.canvas2D),this.webglCanvas=document.createElement("canvas"),this.webglCanvas.id=`${this.config.canvasId}-3d`,this.webglCanvas.width=this.canvas2D.width,this.webglCanvas.height=this.canvas2D.height,this.webglCanvas.style.position="absolute",this.webglCanvas.style.top="0",this.webglCanvas.style.left="0",this.webglCanvas.style.width="100%",this.webglCanvas.style.height="100%",this.webglCanvas.style.background="transparent",this.webglCanvas.style.zIndex="2",this.config.enableControls?(this.webglCanvas.style.pointerEvents="auto",this.webglCanvas.style.touchAction="none"):(this.webglCanvas.style.pointerEvents="none",this.webglCanvas.style.touchAction="auto"),this.container.appendChild(this.webglCanvas)}async start(){this.isRunning||(this.core3D&&await this.core3D.waitUntilReady(),this.isRunning=!0,this.lastFrameTime=null,this.animationFrameId=requestAnimationFrame(this.animate.bind(this)))}stop(){this.isRunning=!1,this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null)}animate(e){if(!this.isRunning||this._destroyed)return;if(null===this.lastFrameTime)return this.lastFrameTime=e,void(this.animationFrameId=requestAnimationFrame(this.animate.bind(this)));const t=e-this.lastFrameTime,i=Math.min(t,100);if(this.lastFrameTime=e,this.core3D&&!this._destroyed&&this.core3D.render(i),this.canvas2D&&this.ctx2D&&(this.ctx2D.clearRect(0,0,this.canvas2D.width,this.canvas2D.height),this.ctx2D.fillStyle="rgba(0,0,0,0)",this.ctx2D.fillRect(0,0,this.canvas2D.width,this.canvas2D.height),this.particleSystem)){const t=this.canvas2D.width/2,n=this.canvas2D.height/2,a=this.core3D?this.core3D.emotion:"neutral",s=me(a),o=this.core3D?this.rgbToHex(this.core3D.glowColor):"#FFFFFF",r=s?.visual?.particleBehavior||"ambient",l=s?.visual?.particleRate||15,h=s?.visual?.minParticles||5,c=s?.visual?.maxParticles||30,u=s?.visual?.particleColors||null;this.particleSystem.spawn(r,a,l,t,n,i,null,h,c,1,1,u,this.undertone);let d=null,m=0;if(this.currentGesture){const t=e-this.currentGesture.startTime;m=Math.min(t/this.currentGesture.duration,1),d={...this.currentGesture.config,type:this.currentGesture.name}}this.particleSystem.update(i,t,n,d,m,this.undertone),this.particleSystem.render(this.ctx2D,o,null)}this.animationFrameId=requestAnimationFrame(e=>this.animate(e))}setEmotion(e,t){this.eventManager&&this.eventManager._listeners&&(this.emotion=e,void 0!==t&&("string"==typeof t?this.undertone=t:t&&"object"==typeof t?this.undertone=t.undertone||null:null===t&&(this.undertone=null)),this.core3D&&this.core3D.setEmotion(e,this.undertone),this.particleSystem&&(this.particleSystem.particles=[]),this.eventManager.emit("emotion:change",{emotion:e,undertone:this.undertone}))}updateUndertone(e){this.undertone=e,this.core3D&&this.emotion&&this.core3D.setEmotion(this.emotion,e),this.eventManager.emit("undertone:change",{undertone:e})}setUndertone(e){this.updateUndertone(e)}express(e){if(!this.eventManager||!this.eventManager._listeners)return;this.core3D&&this.core3D.playGesture(e);const t=ft(e);if(t){const i=t.config||{},n=i.musicalDuration?.musical?500*(i.musicalDuration.beats||2):i.duration||800;this.currentGesture={name:e,gesture:t,config:i,startTime:performance.now(),duration:n};const a=setTimeout(()=>{this.currentGesture&&this.currentGesture.name===e&&(this.currentGesture=null)},n);this.gestureTimeouts.push(a)}this.eventManager.emit("gesture:trigger",{gesture:e})}chain(e){const t=("string"==typeof e?{rise:"breathe > sway+lean+tilt",flow:"sway > lean+tilt > spin > bounce",burst:"jump > nod > shake > flash",drift:"sway+breathe+float+drift",chaos:"shake+shake > spin+flash > bounce+pulse > twist+sparkle",morph:"expand > contract > morph+glow > expand+flash",rhythm:"pulse > pulse+sparkle > pulse+flicker",spiral:"spin > orbital > twist > orbital+sparkle",routine:"nod > bounce > spin+sparkle > sway+pulse > nod+flash",radiance:"sparkle > pulse+flicker > shimmer",twinkle:"sparkle > flash > pulse+sparkle > shimmer+flicker",stream:"wave > nod+pulse > sparkle > flash"}[e]||e:e.join(">")).split(">").map(e=>e.trim().split("+").map(e=>e.trim()).filter(e=>e.length>0));this.executeChainSequence(t)}executeChainSequence(e){if(!e||0===e.length)return;let t=0;const i=()=>{if(!(t>=e.length)&&(e[t].forEach(e=>{this.express(e)}),t++,t<e.length)){const e=setTimeout(i,800);this.gestureTimeouts.push(e)}};i()}morphTo(e,t={}){if(this.core3D){if(void 0!==t.materialVariant&&this.core3D.setMaterialVariant(t.materialVariant),t.onMaterialSwap){const e=this.core3D.onMaterialSwap;this.core3D.onMaterialSwap=i=>{e&&e(i),t.onMaterialSwap(i),this.core3D.onMaterialSwap=e}}const i=t.duration||800;this.core3D.morphToShape(e,i)}this.eventManager.emit("shape:morph",{shape:e})}feel(e){if(!this.eventManager||!this.eventManager._listeners)return{success:!1,error:"Engine destroyed",parsed:null};const t=Date.now(),i=this._feelRateLimiter;if(i.calls=i.calls.filter(e=>t-e<i.windowMs),i.calls.length>=i.maxCallsPerSecond)return console.warn("[feel] Rate limit exceeded. Max 10 calls per second."),{success:!1,error:"Rate limit exceeded",parsed:null};i.calls.push(t);const n=this._intentParser.parse(e),a=this._intentParser.validate(n);if(!a.valid)return console.warn("[feel] Invalid intent:",a.errors),{success:!1,error:a.errors.join("; "),parsed:n};try{if(n.emotion){const e={};n.undertone&&"clear"!==n.undertone&&(e.undertone=n.undertone),this.setEmotion(n.emotion,e)}for(const e of n.gestures)this.express(e);return n.shape&&this.morphTo(n.shape),{success:!0,error:null,parsed:n}}catch(e){return console.error("[feel] Execution error:",e),{success:!1,error:e.message,parsed:n}}}isMorphing(){return!!this.core3D&&this.core3D.isMorphing()}getMorphState(){return this.core3D?this.core3D.getMorphState():null}growIn(e=500){this.core3D&&this.core3D.growIn(e),this.eventManager.emit("animation:growIn",{duration:e})}setCoreGlowEnabled(e){this.core3D&&this.core3D.setCoreGlowEnabled(e),this.eventManager.emit("coreGlow:toggle",{enabled:e})}isCoreGlowEnabled(){return!this.core3D||this.core3D.coreGlowEnabled}enableAutoRotate(){this.core3D&&"moon"!==this.core3D.geometryType&&(this.core3D.renderer?.controls&&(this.core3D.renderer.controls.autoRotate=!0,this.core3D.renderer.controls.autoRotateSpeed=this.core3D.options?.autoRotateSpeed??.5),this.core3D.rotationDisabled=!1,this.setEmotion(this.core3D.emotion,this.undertone))}disableAutoRotate(){this.core3D?.renderer?.controls&&(this.core3D.renderer.controls.autoRotate=!1,this.core3D.renderer.controls.autoRotateSpeed=0),this.core3D&&(this.core3D.rotationDisabled=!0,this.core3D.rotationBehavior=null,this.core3D.baseEuler&&(this.core3D.baseEuler[0]=0,this.core3D.baseEuler[1]=0,this.core3D.baseEuler[2]=0))}setCameraPreset(e,t=1e3){this.core3D?.renderer?.setCameraPreset&&this.core3D.renderer.setCameraPreset(e,t)}get autoRotateEnabled(){return!1===this.core3D?.rotationDisabled}enableParticles(){if(this.core3D?.particleOrchestrator?.renderer&&(this.core3D.particleVisibility=!0,this.core3D.particleOrchestrator.renderer.setVisible(!0),this.core3D.particleOrchestrator.setEmotion(this.core3D.emotion,this.core3D.undertone)),!this.core3D?.particleOrchestrator&&!this.particleSystem&&this.canvas2D){const e=this.config.maxParticles||300;this.particleSystem=new hi(e,this.errorBoundary),this.particleSystem.canvasWidth=this.canvas2D.width,this.particleSystem.canvasHeight=this.canvas2D.height}}disableParticles(){this.core3D?.particleOrchestrator?.renderer&&(this.core3D.particleVisibility=!1,this.core3D.particleOrchestrator.renderer.setVisible(!1),this.core3D.particleOrchestrator.clear()),this.core3D?.particleOrchestrator||this.particleSystem&&(this.particleSystem.destroy(),this.particleSystem=null)}get particlesEnabled(){return this.core3D?.particleOrchestrator?!0===this.core3D.particleVisibility:null!==this.particleSystem}enableBlinking(){this.core3D&&(this.core3D.blinkingManuallyDisabled=!1,this.core3D.blinkAnimator&&this.core3D.blinkAnimator.resume())}disableBlinking(){this.core3D&&(this.core3D.blinkingManuallyDisabled=!0,this.core3D.blinkAnimator&&this.core3D.blinkAnimator.pause())}get blinkingEnabled(){return!(!this.core3D||!this.core3D.blinkAnimator)&&this.core3D.blinkAnimator.enabled}enableBreathing(){this.core3D&&(this.core3D.breathingEnabled=!0)}disableBreathing(){this.core3D&&(this.core3D.breathingEnabled=!1)}get breathingEnabled(){return!this.core3D||!1!==this.core3D.breathingEnabled}breathePhase(e,t){this.core3D&&this.core3D.breathePhase(e,t)}stopBreathingPhase(){this.core3D&&this.core3D.stopBreathingPhase()}enableWobble(){this.core3D&&this.core3D.setWobbleEnabled(!0)}disableWobble(){this.core3D&&this.core3D.setWobbleEnabled(!1)}get wobbleEnabled(){return!this.core3D||!1!==this.core3D.wobbleEnabled}enableRhythmSync(){this.core3D&&this.core3D.setRhythmEnabled(!0)}disableRhythmSync(){this.core3D&&this.core3D.setRhythmEnabled(!1)}get rhythmSyncEnabled(){return!!this.core3D&&this.core3D.rhythmEnabled}enableGroove(){this.core3D&&this.core3D.setGrooveEnabled(!0)}disableGroove(){this.core3D&&this.core3D.setGrooveEnabled(!1)}setBeatSyncStrength(e){this.core3D&&this.core3D.setBeatSyncStrength(e)}setGrooveConfig(e){this.core3D&&this.core3D.setGrooveConfig(e)}isRhythmPlaying(){return this.core3D?.isRhythmPlaying()||!1}getRhythmBPM(){return this.core3D?.getRhythmBPM()||120}startRhythm(e=120,t="straight"){this.core3D&&this.core3D.startRhythm(e,t)}stopRhythm(){this.core3D&&this.core3D.stopRhythm()}setRhythmBPM(e){this.core3D&&this.core3D.setRhythmBPM(e)}setRhythmPattern(e){this.core3D&&this.core3D.setRhythmPattern(e)}async connectAudio(e){if(!e)return;this._audioElement=e,this._audioContext||(this._audioContext=new(window.AudioContext||window.webkitAudioContext)),"suspended"===this._audioContext.state&&await this._audioContext.resume(),this._analyzerNode||(this._analyzerNode=this._audioContext.createAnalyser(),this._analyzerNode.fftSize=256,this._analyzerNode.smoothingTimeConstant=.8),this._audioSourceNode||(this._audioSourceNode=this._audioContext.createMediaElementSource(e),this._audioSourceNode.connect(this._analyzerNode),this._analyzerNode.connect(this._audioContext.destination));const t=()=>{const e=this._detectedBPM||120;this.startRhythm(e,"straight")},i=()=>{this.stopRhythm()},n=()=>{this.stopRhythm()};this._audioHandlers={onPlay:t,onPause:i,onEnded:n},e.addEventListener("play",t),e.addEventListener("pause",i),e.addEventListener("ended",n),e.paused||t(),this._startBPMDetection()}disconnectAudio(){this.stopRhythm(),this._audioElement&&this._audioHandlers&&(this._audioElement.removeEventListener("play",this._audioHandlers.onPlay),this._audioElement.removeEventListener("pause",this._audioHandlers.onPause),this._audioElement.removeEventListener("ended",this._audioHandlers.onEnded)),this._stopBPMDetection(),this._audioElement=null,this._audioHandlers=null}_startBPMDetection(){if(this._bpmDetectionInterval)return;const e=this._analyzerNode?.frequencyBinCount||128,t=new Uint8Array(e);let i=0;const n=[];this._bpmDetectionInterval=setInterval(()=>{if(!this._analyzerNode||!this._audioElement||this._audioElement.paused)return;this._analyzerNode.getByteFrequencyData(t);let e=0;for(let i=0;i<8;i++)e+=t[i];e/=8;const a=performance.now();if(e>180&&a-i>200){if(i>0){const e=a-i;if(n.push(e),n.length>8&&n.shift(),n.length>=4){const e=n.reduce((e,t)=>e+t,0)/n.length,t=Math.round(6e4/e);t>=60&&t<=180&&(this._detectedBPM=t,this.isRhythmPlaying()&&this.setRhythmBPM(t))}}i=a}},50)}_stopBPMDetection(){this._bpmDetectionInterval&&(clearInterval(this._bpmDetectionInterval),this._bpmDetectionInterval=null)}rgbToHex(e){return`#${[Math.round(255*e[0]),Math.round(255*e[1]),Math.round(255*e[2])].map(e=>{const t=e.toString(16);return 1===t.length?`0${t}`:t}).join("")}`}setPosition(e,t,i=0){if(!this.container)return;this.position={x:e,y:t,z:i};const n=window.innerWidth<768;this.container.style.transform=n?`translate(calc(-50% + ${e}px), calc(-50% + ${t}px))`:`translate(${e}px, calc(-50% + ${t}px))`}getPosition(){return this.position||{x:0,y:0,z:0}}animateToPosition(e,t,i=0,n=1e3,a="easeOutCubic"){if(!this.container)return;const s=this.getPosition(),o=performance.now(),r=a=>{const l=a-o,h=Math.min(l/n,1),c=(u=h,1-Math.pow(1-u,3));var u;const d=s.x+(e-s.x)*c,m=s.y+(t-s.y)*c,p=s.z+(i-s.z)*c;this.setPosition(d,m,p),h<1&&requestAnimationFrame(r)};requestAnimationFrame(r)}setContainment(e,t=1){if(this._containmentBounds=e,this._containmentScale=t,this.particleSystem&&1!==t){const e=this.config.particleSpawnRadius||150;this.particleSystem.setSpawnRadius(e*t)}return this}attachToElement(e,t={}){const i="string"==typeof e?document.querySelector(e):e;if(!i)return console.error(`[EmotiveMascot3D] Element not found: ${e}`),this;this._attachedElement=i,this._attachOptions={offsetX:t.offsetX||0,offsetY:t.offsetY||0,animate:!1!==t.animate,duration:t.duration||1e3,scale:t.scale||1,containParticles:!1!==t.containParticles},this._hasAttachedBefore=this._hasAttachedBefore||!1;const n=i.getBoundingClientRect();return this._attachOptions.containParticles?this.setContainment({width:n.width,height:n.height},this._attachOptions.scale):1!==this._attachOptions.scale&&this.setContainment(null,this._attachOptions.scale),this._updateAttachedPosition(),this._setupElementTracking(),this}_updateAttachedPosition(){if(!this._attachedElement||!this.container)return;const e=this._attachedElement.getBoundingClientRect(),t=window.innerWidth<768,i=e.left+e.width/2,n=e.top+e.height/2;let a,s;if(t)a=window.innerWidth/2,s=.18*window.innerHeight;else{const e=750;a=Math.max(20,(window.innerWidth/2-500)/2-375)+e/2,s=window.innerHeight/2}const o=i-a+this._attachOptions.offsetX,r=n-s+this._attachOptions.offsetY,l=!this._hasAttachedBefore;this._hasAttachedBefore=!0,l&&this._attachOptions.animate?this.animateToPosition(o,r,0,this._attachOptions.duration):this.setPosition(o,r,0)}_setupElementTracking(){this._elementTrackingHandlers||(this._elementTrackingHandlers={scroll:()=>this._updateAttachedPosition(),resize:()=>this._updateAttachedPosition()},window.addEventListener("scroll",this._elementTrackingHandlers.scroll,{passive:!0}),window.addEventListener("resize",this._elementTrackingHandlers.resize))}isAttachedToElement(){return!!this._attachedElement}detachFromElement(){return this._attachedElement=null,this._hasAttachedBefore=!1,this._elementTrackingHandlers&&(window.removeEventListener("scroll",this._elementTrackingHandlers.scroll),window.removeEventListener("resize",this._elementTrackingHandlers.resize),this._elementTrackingHandlers=null),this.setContainment(null,1),this.setEmotion("neutral"),this}setSSSPreset(e){this._currentSSSPreset=e,this.core3D&&!this._materialSwapCallbackSet&&(this._materialSwapCallbackSet=!0,this.core3D.onMaterialSwap=e=>{this._currentSSSPreset&&setTimeout(()=>{ji(this,this._currentSSSPreset)},50)});const t=ji(this,e);return t&&this.eventManager.emit("sss:presetChanged",{preset:e}),t}setGeometry(e,t={}){this.morphTo(e,t)}startSolarEclipse(e={}){this.core3D&&"function"==typeof this.core3D.startSolarEclipse?this.core3D.startSolarEclipse(e):(this.morphTo("sun"),this.eventManager.emit("eclipse:solar:start",{type:e.type||"total"}))}startLunarEclipse(e={}){this.core3D&&"function"==typeof this.core3D.startLunarEclipse?this.core3D.startLunarEclipse(e):(this.morphTo("moon"),this.eventManager.emit("eclipse:lunar:start",{type:e.type||"total"}))}stopEclipse(){this.core3D&&"function"==typeof this.core3D.stopEclipse&&this.core3D.stopEclipse(),this.eventManager&&this.eventManager.emit("eclipse:stop")}destroy(){this._destroyed=!0,this.stop(),this.disconnectAudio(),this._audioContext&&(this._audioContext.close(),this._audioContext=null),this._analyzerNode=null,this._audioSourceNode=null,this._elementTrackingHandlers&&(window.removeEventListener("scroll",this._elementTrackingHandlers.scroll),window.removeEventListener("resize",this._elementTrackingHandlers.resize),this._elementTrackingHandlers=null),this._attachedElement=null,this.gestureTimeouts.forEach(e=>clearTimeout(e)),this.gestureTimeouts=[],this.eventManager&&this.eventManager._listeners&&(Object.keys(this.eventManager._listeners).forEach(e=>{this.eventManager._listeners[e]=[]}),this.eventManager._listeners=null),this.core3D&&this.core3D.destroy(),this.particleSystem&&this.particleSystem.destroy(),this.webglCanvas&&this.webglCanvas.parentNode&&this.webglCanvas.parentNode.removeChild(this.webglCanvas),this.canvas2D&&this.canvas2D.parentNode&&this.canvas2D.parentNode.removeChild(this.canvas2D),this.container=null,this.webglCanvas=null,this.canvas2D=null,this.ctx2D=null,this.config=null,this.errorBoundary=null,this.currentGesture=null}}export{vn as CORE_GEOMETRIES,Gi as Core3DManager,wn as EmotiveMascot3D,Li as GeometryCache,I as MOON_PHASES,be as Rhythm3DAdapter,Ni as SSSPresets,q as animateMoonPhase,ji as applySSSPreset,x as blendModeNames,fn as createCrystal,yn as createDiamond,z as createMoon,G as createMoonCrescentMaterial,F as createMoonFallbackMaterial,O as createMoonMaterial,gn as createSphere,Y as createSunGeometry,X as createSunMaterial,wn as default,bn as disposeCoreGeometries,_ as disposeMoon,Q as disposeSun,D as getBlendModeIndex,C as getBlendModeName,A as getMoonPhaseNames,R as getPhaseFromProgress,Hi as getSSSPreset,Ui as getSSSPresetNames,we as rhythm3DAdapter,V as setMoonPhase,j as updateCrescentShadow,N as updateMoonGlow,$ as updateSunMaterial};
1
+ const e="181",t=0,i=1,n=2,a=100,r=101,s=102,o=200,l=201,h=202,c=203,u=204,d=205,p=206,m=207,f=208,g=209,v=210,y=211,b=212,M=213,_=214,x=0,S=1,w=2,E=3,T=4,C=5,A=6,P=7,D=301,R=302,I=303,L=306,B=1e3,O=1001,F=1002,U=1003,z=1004,k=1005,N=1006,G=1007,V=1008,H=1009,W=1012,j=1013,X=1014,q=1015,Y=1016,$=1017,Z=1018,K=1020,Q=1023,J=1026,ee=1027,te=1029,ie=1030,ne=1031,ae=1033,re=33776,se=33777,oe=33778,le=33779,he=35840,ce=35841,ue=35842,de=35843,pe=36196,me=37492,fe=37496,ge=37808,ve=37809,ye=37810,be=37811,Me=37812,_e=37813,xe=37814,Se=37815,we=37816,Ee=37817,Te=37818,Ce=37819,Ae=37820,Pe=37821,De=36492,Re=36494,Ie=36495,Le=36283,Be=36284,Oe=36285,Fe=36286,Ue="",ze="srgb",ke="srgb-linear",Ne="linear",Ge="srgb",Ve=7680,He=512,We=513,je=514,Xe=515,qe=516,Ye=517,$e=518,Ze=519,Ke=35044,Qe=35048,Je="300 es",et=2e3,tt=2001;function it(e){for(let t=e.length-1;t>=0;--t)if(e[t]>=65535)return!0;return!1}function nt(e){return document.createElementNS("http://www.w3.org/1999/xhtml",e)}function at(){const e=nt("canvas");return e.style.display="block",e}const rt={};function st(...e){const t="THREE."+e.shift();console.log(t,...e)}function ot(...e){const t="THREE."+e.shift();console.warn(t,...e)}function lt(...e){const t="THREE."+e.shift();console.error(t,...e)}function ht(...e){const t=e.join(" ");t in rt||(rt[t]=!0,ot(...e))}class ct{addEventListener(e,t){void 0===this._listeners&&(this._listeners={});const i=this._listeners;void 0===i[e]&&(i[e]=[]),-1===i[e].indexOf(t)&&i[e].push(t)}hasEventListener(e,t){const i=this._listeners;return void 0!==i&&void 0!==i[e]&&-1!==i[e].indexOf(t)}removeEventListener(e,t){const i=this._listeners;if(void 0===i)return;const n=i[e];if(void 0!==n){const e=n.indexOf(t);-1!==e&&n.splice(e,1)}}dispatchEvent(e){const t=this._listeners;if(void 0===t)return;const i=t[e.type];if(void 0!==i){e.target=this;const t=i.slice(0);for(let i=0,n=t.length;i<n;i++)t[i].call(this,e);e.target=null}}}const ut=["00","01","02","03","04","05","06","07","08","09","0a","0b","0c","0d","0e","0f","10","11","12","13","14","15","16","17","18","19","1a","1b","1c","1d","1e","1f","20","21","22","23","24","25","26","27","28","29","2a","2b","2c","2d","2e","2f","30","31","32","33","34","35","36","37","38","39","3a","3b","3c","3d","3e","3f","40","41","42","43","44","45","46","47","48","49","4a","4b","4c","4d","4e","4f","50","51","52","53","54","55","56","57","58","59","5a","5b","5c","5d","5e","5f","60","61","62","63","64","65","66","67","68","69","6a","6b","6c","6d","6e","6f","70","71","72","73","74","75","76","77","78","79","7a","7b","7c","7d","7e","7f","80","81","82","83","84","85","86","87","88","89","8a","8b","8c","8d","8e","8f","90","91","92","93","94","95","96","97","98","99","9a","9b","9c","9d","9e","9f","a0","a1","a2","a3","a4","a5","a6","a7","a8","a9","aa","ab","ac","ad","ae","af","b0","b1","b2","b3","b4","b5","b6","b7","b8","b9","ba","bb","bc","bd","be","bf","c0","c1","c2","c3","c4","c5","c6","c7","c8","c9","ca","cb","cc","cd","ce","cf","d0","d1","d2","d3","d4","d5","d6","d7","d8","d9","da","db","dc","dd","de","df","e0","e1","e2","e3","e4","e5","e6","e7","e8","e9","ea","eb","ec","ed","ee","ef","f0","f1","f2","f3","f4","f5","f6","f7","f8","f9","fa","fb","fc","fd","fe","ff"],dt=Math.PI/180,pt=180/Math.PI;function mt(){const e=4294967295*Math.random()|0,t=4294967295*Math.random()|0,i=4294967295*Math.random()|0,n=4294967295*Math.random()|0;return(ut[255&e]+ut[e>>8&255]+ut[e>>16&255]+ut[e>>24&255]+"-"+ut[255&t]+ut[t>>8&255]+"-"+ut[t>>16&15|64]+ut[t>>24&255]+"-"+ut[63&i|128]+ut[i>>8&255]+"-"+ut[i>>16&255]+ut[i>>24&255]+ut[255&n]+ut[n>>8&255]+ut[n>>16&255]+ut[n>>24&255]).toLowerCase()}function ft(e,t,i){return Math.max(t,Math.min(i,e))}function gt(e,t,i){return(1-i)*e+i*t}function vt(e,t){switch(t.constructor){case Float32Array:return e;case Uint32Array:return e/4294967295;case Uint16Array:return e/65535;case Uint8Array:return e/255;case Int32Array:return Math.max(e/2147483647,-1);case Int16Array:return Math.max(e/32767,-1);case Int8Array:return Math.max(e/127,-1);default:throw new Error("Invalid component type.")}}function yt(e,t){switch(t.constructor){case Float32Array:return e;case Uint32Array:return Math.round(4294967295*e);case Uint16Array:return Math.round(65535*e);case Uint8Array:return Math.round(255*e);case Int32Array:return Math.round(2147483647*e);case Int16Array:return Math.round(32767*e);case Int8Array:return Math.round(127*e);default:throw new Error("Invalid component type.")}}const bt=dt;class Mt{constructor(e=0,t=0){Mt.prototype.isVector2=!0,this.x=e,this.y=t}get width(){return this.x}set width(e){this.x=e}get height(){return this.y}set height(e){this.y=e}set(e,t){return this.x=e,this.y=t,this}setScalar(e){return this.x=e,this.y=e,this}setX(e){return this.x=e,this}setY(e){return this.y=e,this}setComponent(e,t){switch(e){case 0:this.x=t;break;case 1:this.y=t;break;default:throw new Error("index is out of range: "+e)}return this}getComponent(e){switch(e){case 0:return this.x;case 1:return this.y;default:throw new Error("index is out of range: "+e)}}clone(){return new this.constructor(this.x,this.y)}copy(e){return this.x=e.x,this.y=e.y,this}add(e){return this.x+=e.x,this.y+=e.y,this}addScalar(e){return this.x+=e,this.y+=e,this}addVectors(e,t){return this.x=e.x+t.x,this.y=e.y+t.y,this}addScaledVector(e,t){return this.x+=e.x*t,this.y+=e.y*t,this}sub(e){return this.x-=e.x,this.y-=e.y,this}subScalar(e){return this.x-=e,this.y-=e,this}subVectors(e,t){return this.x=e.x-t.x,this.y=e.y-t.y,this}multiply(e){return this.x*=e.x,this.y*=e.y,this}multiplyScalar(e){return this.x*=e,this.y*=e,this}divide(e){return this.x/=e.x,this.y/=e.y,this}divideScalar(e){return this.multiplyScalar(1/e)}applyMatrix3(e){const t=this.x,i=this.y,n=e.elements;return this.x=n[0]*t+n[3]*i+n[6],this.y=n[1]*t+n[4]*i+n[7],this}min(e){return this.x=Math.min(this.x,e.x),this.y=Math.min(this.y,e.y),this}max(e){return this.x=Math.max(this.x,e.x),this.y=Math.max(this.y,e.y),this}clamp(e,t){return this.x=ft(this.x,e.x,t.x),this.y=ft(this.y,e.y,t.y),this}clampScalar(e,t){return this.x=ft(this.x,e,t),this.y=ft(this.y,e,t),this}clampLength(e,t){const i=this.length();return this.divideScalar(i||1).multiplyScalar(ft(i,e,t))}floor(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this}ceil(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this}round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this}roundToZero(){return this.x=Math.trunc(this.x),this.y=Math.trunc(this.y),this}negate(){return this.x=-this.x,this.y=-this.y,this}dot(e){return this.x*e.x+this.y*e.y}cross(e){return this.x*e.y-this.y*e.x}lengthSq(){return this.x*this.x+this.y*this.y}length(){return Math.sqrt(this.x*this.x+this.y*this.y)}manhattanLength(){return Math.abs(this.x)+Math.abs(this.y)}normalize(){return this.divideScalar(this.length()||1)}angle(){return Math.atan2(-this.y,-this.x)+Math.PI}angleTo(e){const t=Math.sqrt(this.lengthSq()*e.lengthSq());if(0===t)return Math.PI/2;const i=this.dot(e)/t;return Math.acos(ft(i,-1,1))}distanceTo(e){return Math.sqrt(this.distanceToSquared(e))}distanceToSquared(e){const t=this.x-e.x,i=this.y-e.y;return t*t+i*i}manhattanDistanceTo(e){return Math.abs(this.x-e.x)+Math.abs(this.y-e.y)}setLength(e){return this.normalize().multiplyScalar(e)}lerp(e,t){return this.x+=(e.x-this.x)*t,this.y+=(e.y-this.y)*t,this}lerpVectors(e,t,i){return this.x=e.x+(t.x-e.x)*i,this.y=e.y+(t.y-e.y)*i,this}equals(e){return e.x===this.x&&e.y===this.y}fromArray(e,t=0){return this.x=e[t],this.y=e[t+1],this}toArray(e=[],t=0){return e[t]=this.x,e[t+1]=this.y,e}fromBufferAttribute(e,t){return this.x=e.getX(t),this.y=e.getY(t),this}rotateAround(e,t){const i=Math.cos(t),n=Math.sin(t),a=this.x-e.x,r=this.y-e.y;return this.x=a*i-r*n+e.x,this.y=a*n+r*i+e.y,this}random(){return this.x=Math.random(),this.y=Math.random(),this}*[Symbol.iterator](){yield this.x,yield this.y}}class _t{constructor(e=0,t=0,i=0,n=1){this.isQuaternion=!0,this._x=e,this._y=t,this._z=i,this._w=n}static slerpFlat(e,t,i,n,a,r,s){let o=i[n+0],l=i[n+1],h=i[n+2],c=i[n+3],u=a[r+0],d=a[r+1],p=a[r+2],m=a[r+3];if(s<=0)return e[t+0]=o,e[t+1]=l,e[t+2]=h,void(e[t+3]=c);if(s>=1)return e[t+0]=u,e[t+1]=d,e[t+2]=p,void(e[t+3]=m);if(c!==m||o!==u||l!==d||h!==p){let e=o*u+l*d+h*p+c*m;e<0&&(u=-u,d=-d,p=-p,m=-m,e=-e);let t=1-s;if(e<.9995){const i=Math.acos(e),n=Math.sin(i);t=Math.sin(t*i)/n,o=o*t+u*(s=Math.sin(s*i)/n),l=l*t+d*s,h=h*t+p*s,c=c*t+m*s}else{o=o*t+u*s,l=l*t+d*s,h=h*t+p*s,c=c*t+m*s;const e=1/Math.sqrt(o*o+l*l+h*h+c*c);o*=e,l*=e,h*=e,c*=e}}e[t]=o,e[t+1]=l,e[t+2]=h,e[t+3]=c}static multiplyQuaternionsFlat(e,t,i,n,a,r){const s=i[n],o=i[n+1],l=i[n+2],h=i[n+3],c=a[r],u=a[r+1],d=a[r+2],p=a[r+3];return e[t]=s*p+h*c+o*d-l*u,e[t+1]=o*p+h*u+l*c-s*d,e[t+2]=l*p+h*d+s*u-o*c,e[t+3]=h*p-s*c-o*u-l*d,e}get x(){return this._x}set x(e){this._x=e,this._onChangeCallback()}get y(){return this._y}set y(e){this._y=e,this._onChangeCallback()}get z(){return this._z}set z(e){this._z=e,this._onChangeCallback()}get w(){return this._w}set w(e){this._w=e,this._onChangeCallback()}set(e,t,i,n){return this._x=e,this._y=t,this._z=i,this._w=n,this._onChangeCallback(),this}clone(){return new this.constructor(this._x,this._y,this._z,this._w)}copy(e){return this._x=e.x,this._y=e.y,this._z=e.z,this._w=e.w,this._onChangeCallback(),this}setFromEuler(e,t=!0){const i=e._x,n=e._y,a=e._z,r=e._order,s=Math.cos,o=Math.sin,l=s(i/2),h=s(n/2),c=s(a/2),u=o(i/2),d=o(n/2),p=o(a/2);switch(r){case"XYZ":this._x=u*h*c+l*d*p,this._y=l*d*c-u*h*p,this._z=l*h*p+u*d*c,this._w=l*h*c-u*d*p;break;case"YXZ":this._x=u*h*c+l*d*p,this._y=l*d*c-u*h*p,this._z=l*h*p-u*d*c,this._w=l*h*c+u*d*p;break;case"ZXY":this._x=u*h*c-l*d*p,this._y=l*d*c+u*h*p,this._z=l*h*p+u*d*c,this._w=l*h*c-u*d*p;break;case"ZYX":this._x=u*h*c-l*d*p,this._y=l*d*c+u*h*p,this._z=l*h*p-u*d*c,this._w=l*h*c+u*d*p;break;case"YZX":this._x=u*h*c+l*d*p,this._y=l*d*c+u*h*p,this._z=l*h*p-u*d*c,this._w=l*h*c-u*d*p;break;case"XZY":this._x=u*h*c-l*d*p,this._y=l*d*c-u*h*p,this._z=l*h*p+u*d*c,this._w=l*h*c+u*d*p;break;default:ot("Quaternion: .setFromEuler() encountered an unknown order: "+r)}return!0===t&&this._onChangeCallback(),this}setFromAxisAngle(e,t){const i=t/2,n=Math.sin(i);return this._x=e.x*n,this._y=e.y*n,this._z=e.z*n,this._w=Math.cos(i),this._onChangeCallback(),this}setFromRotationMatrix(e){const t=e.elements,i=t[0],n=t[4],a=t[8],r=t[1],s=t[5],o=t[9],l=t[2],h=t[6],c=t[10],u=i+s+c;if(u>0){const e=.5/Math.sqrt(u+1);this._w=.25/e,this._x=(h-o)*e,this._y=(a-l)*e,this._z=(r-n)*e}else if(i>s&&i>c){const e=2*Math.sqrt(1+i-s-c);this._w=(h-o)/e,this._x=.25*e,this._y=(n+r)/e,this._z=(a+l)/e}else if(s>c){const e=2*Math.sqrt(1+s-i-c);this._w=(a-l)/e,this._x=(n+r)/e,this._y=.25*e,this._z=(o+h)/e}else{const e=2*Math.sqrt(1+c-i-s);this._w=(r-n)/e,this._x=(a+l)/e,this._y=(o+h)/e,this._z=.25*e}return this._onChangeCallback(),this}setFromUnitVectors(e,t){let i=e.dot(t)+1;return i<1e-8?(i=0,Math.abs(e.x)>Math.abs(e.z)?(this._x=-e.y,this._y=e.x,this._z=0,this._w=i):(this._x=0,this._y=-e.z,this._z=e.y,this._w=i)):(this._x=e.y*t.z-e.z*t.y,this._y=e.z*t.x-e.x*t.z,this._z=e.x*t.y-e.y*t.x,this._w=i),this.normalize()}angleTo(e){return 2*Math.acos(Math.abs(ft(this.dot(e),-1,1)))}rotateTowards(e,t){const i=this.angleTo(e);if(0===i)return this;const n=Math.min(1,t/i);return this.slerp(e,n),this}identity(){return this.set(0,0,0,1)}invert(){return this.conjugate()}conjugate(){return this._x*=-1,this._y*=-1,this._z*=-1,this._onChangeCallback(),this}dot(e){return this._x*e._x+this._y*e._y+this._z*e._z+this._w*e._w}lengthSq(){return this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w}length(){return Math.sqrt(this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w)}normalize(){let e=this.length();return 0===e?(this._x=0,this._y=0,this._z=0,this._w=1):(e=1/e,this._x=this._x*e,this._y=this._y*e,this._z=this._z*e,this._w=this._w*e),this._onChangeCallback(),this}multiply(e){return this.multiplyQuaternions(this,e)}premultiply(e){return this.multiplyQuaternions(e,this)}multiplyQuaternions(e,t){const i=e._x,n=e._y,a=e._z,r=e._w,s=t._x,o=t._y,l=t._z,h=t._w;return this._x=i*h+r*s+n*l-a*o,this._y=n*h+r*o+a*s-i*l,this._z=a*h+r*l+i*o-n*s,this._w=r*h-i*s-n*o-a*l,this._onChangeCallback(),this}slerp(e,t){if(t<=0)return this;if(t>=1)return this.copy(e);let i=e._x,n=e._y,a=e._z,r=e._w,s=this.dot(e);s<0&&(i=-i,n=-n,a=-a,r=-r,s=-s);let o=1-t;if(s<.9995){const e=Math.acos(s),l=Math.sin(e);o=Math.sin(o*e)/l,t=Math.sin(t*e)/l,this._x=this._x*o+i*t,this._y=this._y*o+n*t,this._z=this._z*o+a*t,this._w=this._w*o+r*t,this._onChangeCallback()}else this._x=this._x*o+i*t,this._y=this._y*o+n*t,this._z=this._z*o+a*t,this._w=this._w*o+r*t,this.normalize();return this}slerpQuaternions(e,t,i){return this.copy(e).slerp(t,i)}random(){const e=2*Math.PI*Math.random(),t=2*Math.PI*Math.random(),i=Math.random(),n=Math.sqrt(1-i),a=Math.sqrt(i);return this.set(n*Math.sin(e),n*Math.cos(e),a*Math.sin(t),a*Math.cos(t))}equals(e){return e._x===this._x&&e._y===this._y&&e._z===this._z&&e._w===this._w}fromArray(e,t=0){return this._x=e[t],this._y=e[t+1],this._z=e[t+2],this._w=e[t+3],this._onChangeCallback(),this}toArray(e=[],t=0){return e[t]=this._x,e[t+1]=this._y,e[t+2]=this._z,e[t+3]=this._w,e}fromBufferAttribute(e,t){return this._x=e.getX(t),this._y=e.getY(t),this._z=e.getZ(t),this._w=e.getW(t),this._onChangeCallback(),this}toJSON(){return this.toArray()}_onChange(e){return this._onChangeCallback=e,this}_onChangeCallback(){}*[Symbol.iterator](){yield this._x,yield this._y,yield this._z,yield this._w}}class xt{constructor(e=0,t=0,i=0){xt.prototype.isVector3=!0,this.x=e,this.y=t,this.z=i}set(e,t,i){return void 0===i&&(i=this.z),this.x=e,this.y=t,this.z=i,this}setScalar(e){return this.x=e,this.y=e,this.z=e,this}setX(e){return this.x=e,this}setY(e){return this.y=e,this}setZ(e){return this.z=e,this}setComponent(e,t){switch(e){case 0:this.x=t;break;case 1:this.y=t;break;case 2:this.z=t;break;default:throw new Error("index is out of range: "+e)}return this}getComponent(e){switch(e){case 0:return this.x;case 1:return this.y;case 2:return this.z;default:throw new Error("index is out of range: "+e)}}clone(){return new this.constructor(this.x,this.y,this.z)}copy(e){return this.x=e.x,this.y=e.y,this.z=e.z,this}add(e){return this.x+=e.x,this.y+=e.y,this.z+=e.z,this}addScalar(e){return this.x+=e,this.y+=e,this.z+=e,this}addVectors(e,t){return this.x=e.x+t.x,this.y=e.y+t.y,this.z=e.z+t.z,this}addScaledVector(e,t){return this.x+=e.x*t,this.y+=e.y*t,this.z+=e.z*t,this}sub(e){return this.x-=e.x,this.y-=e.y,this.z-=e.z,this}subScalar(e){return this.x-=e,this.y-=e,this.z-=e,this}subVectors(e,t){return this.x=e.x-t.x,this.y=e.y-t.y,this.z=e.z-t.z,this}multiply(e){return this.x*=e.x,this.y*=e.y,this.z*=e.z,this}multiplyScalar(e){return this.x*=e,this.y*=e,this.z*=e,this}multiplyVectors(e,t){return this.x=e.x*t.x,this.y=e.y*t.y,this.z=e.z*t.z,this}applyEuler(e){return this.applyQuaternion(wt.setFromEuler(e))}applyAxisAngle(e,t){return this.applyQuaternion(wt.setFromAxisAngle(e,t))}applyMatrix3(e){const t=this.x,i=this.y,n=this.z,a=e.elements;return this.x=a[0]*t+a[3]*i+a[6]*n,this.y=a[1]*t+a[4]*i+a[7]*n,this.z=a[2]*t+a[5]*i+a[8]*n,this}applyNormalMatrix(e){return this.applyMatrix3(e).normalize()}applyMatrix4(e){const t=this.x,i=this.y,n=this.z,a=e.elements,r=1/(a[3]*t+a[7]*i+a[11]*n+a[15]);return this.x=(a[0]*t+a[4]*i+a[8]*n+a[12])*r,this.y=(a[1]*t+a[5]*i+a[9]*n+a[13])*r,this.z=(a[2]*t+a[6]*i+a[10]*n+a[14])*r,this}applyQuaternion(e){const t=this.x,i=this.y,n=this.z,a=e.x,r=e.y,s=e.z,o=e.w,l=2*(r*n-s*i),h=2*(s*t-a*n),c=2*(a*i-r*t);return this.x=t+o*l+r*c-s*h,this.y=i+o*h+s*l-a*c,this.z=n+o*c+a*h-r*l,this}project(e){return this.applyMatrix4(e.matrixWorldInverse).applyMatrix4(e.projectionMatrix)}unproject(e){return this.applyMatrix4(e.projectionMatrixInverse).applyMatrix4(e.matrixWorld)}transformDirection(e){const t=this.x,i=this.y,n=this.z,a=e.elements;return this.x=a[0]*t+a[4]*i+a[8]*n,this.y=a[1]*t+a[5]*i+a[9]*n,this.z=a[2]*t+a[6]*i+a[10]*n,this.normalize()}divide(e){return this.x/=e.x,this.y/=e.y,this.z/=e.z,this}divideScalar(e){return this.multiplyScalar(1/e)}min(e){return this.x=Math.min(this.x,e.x),this.y=Math.min(this.y,e.y),this.z=Math.min(this.z,e.z),this}max(e){return this.x=Math.max(this.x,e.x),this.y=Math.max(this.y,e.y),this.z=Math.max(this.z,e.z),this}clamp(e,t){return this.x=ft(this.x,e.x,t.x),this.y=ft(this.y,e.y,t.y),this.z=ft(this.z,e.z,t.z),this}clampScalar(e,t){return this.x=ft(this.x,e,t),this.y=ft(this.y,e,t),this.z=ft(this.z,e,t),this}clampLength(e,t){const i=this.length();return this.divideScalar(i||1).multiplyScalar(ft(i,e,t))}floor(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this.z=Math.floor(this.z),this}ceil(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this.z=Math.ceil(this.z),this}round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this.z=Math.round(this.z),this}roundToZero(){return this.x=Math.trunc(this.x),this.y=Math.trunc(this.y),this.z=Math.trunc(this.z),this}negate(){return this.x=-this.x,this.y=-this.y,this.z=-this.z,this}dot(e){return this.x*e.x+this.y*e.y+this.z*e.z}lengthSq(){return this.x*this.x+this.y*this.y+this.z*this.z}length(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)}manhattanLength(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)}normalize(){return this.divideScalar(this.length()||1)}setLength(e){return this.normalize().multiplyScalar(e)}lerp(e,t){return this.x+=(e.x-this.x)*t,this.y+=(e.y-this.y)*t,this.z+=(e.z-this.z)*t,this}lerpVectors(e,t,i){return this.x=e.x+(t.x-e.x)*i,this.y=e.y+(t.y-e.y)*i,this.z=e.z+(t.z-e.z)*i,this}cross(e){return this.crossVectors(this,e)}crossVectors(e,t){const i=e.x,n=e.y,a=e.z,r=t.x,s=t.y,o=t.z;return this.x=n*o-a*s,this.y=a*r-i*o,this.z=i*s-n*r,this}projectOnVector(e){const t=e.lengthSq();if(0===t)return this.set(0,0,0);const i=e.dot(this)/t;return this.copy(e).multiplyScalar(i)}projectOnPlane(e){return St.copy(this).projectOnVector(e),this.sub(St)}reflect(e){return this.sub(St.copy(e).multiplyScalar(2*this.dot(e)))}angleTo(e){const t=Math.sqrt(this.lengthSq()*e.lengthSq());if(0===t)return Math.PI/2;const i=this.dot(e)/t;return Math.acos(ft(i,-1,1))}distanceTo(e){return Math.sqrt(this.distanceToSquared(e))}distanceToSquared(e){const t=this.x-e.x,i=this.y-e.y,n=this.z-e.z;return t*t+i*i+n*n}manhattanDistanceTo(e){return Math.abs(this.x-e.x)+Math.abs(this.y-e.y)+Math.abs(this.z-e.z)}setFromSpherical(e){return this.setFromSphericalCoords(e.radius,e.phi,e.theta)}setFromSphericalCoords(e,t,i){const n=Math.sin(t)*e;return this.x=n*Math.sin(i),this.y=Math.cos(t)*e,this.z=n*Math.cos(i),this}setFromCylindrical(e){return this.setFromCylindricalCoords(e.radius,e.theta,e.y)}setFromCylindricalCoords(e,t,i){return this.x=e*Math.sin(t),this.y=i,this.z=e*Math.cos(t),this}setFromMatrixPosition(e){const t=e.elements;return this.x=t[12],this.y=t[13],this.z=t[14],this}setFromMatrixScale(e){const t=this.setFromMatrixColumn(e,0).length(),i=this.setFromMatrixColumn(e,1).length(),n=this.setFromMatrixColumn(e,2).length();return this.x=t,this.y=i,this.z=n,this}setFromMatrixColumn(e,t){return this.fromArray(e.elements,4*t)}setFromMatrix3Column(e,t){return this.fromArray(e.elements,3*t)}setFromEuler(e){return this.x=e._x,this.y=e._y,this.z=e._z,this}setFromColor(e){return this.x=e.r,this.y=e.g,this.z=e.b,this}equals(e){return e.x===this.x&&e.y===this.y&&e.z===this.z}fromArray(e,t=0){return this.x=e[t],this.y=e[t+1],this.z=e[t+2],this}toArray(e=[],t=0){return e[t]=this.x,e[t+1]=this.y,e[t+2]=this.z,e}fromBufferAttribute(e,t){return this.x=e.getX(t),this.y=e.getY(t),this.z=e.getZ(t),this}random(){return this.x=Math.random(),this.y=Math.random(),this.z=Math.random(),this}randomDirection(){const e=Math.random()*Math.PI*2,t=2*Math.random()-1,i=Math.sqrt(1-t*t);return this.x=i*Math.cos(e),this.y=t,this.z=i*Math.sin(e),this}*[Symbol.iterator](){yield this.x,yield this.y,yield this.z}}const St=new xt,wt=new _t;class Et{constructor(e,t,i,n,a,r,s,o,l){Et.prototype.isMatrix3=!0,this.elements=[1,0,0,0,1,0,0,0,1],void 0!==e&&this.set(e,t,i,n,a,r,s,o,l)}set(e,t,i,n,a,r,s,o,l){const h=this.elements;return h[0]=e,h[1]=n,h[2]=s,h[3]=t,h[4]=a,h[5]=o,h[6]=i,h[7]=r,h[8]=l,this}identity(){return this.set(1,0,0,0,1,0,0,0,1),this}copy(e){const t=this.elements,i=e.elements;return t[0]=i[0],t[1]=i[1],t[2]=i[2],t[3]=i[3],t[4]=i[4],t[5]=i[5],t[6]=i[6],t[7]=i[7],t[8]=i[8],this}extractBasis(e,t,i){return e.setFromMatrix3Column(this,0),t.setFromMatrix3Column(this,1),i.setFromMatrix3Column(this,2),this}setFromMatrix4(e){const t=e.elements;return this.set(t[0],t[4],t[8],t[1],t[5],t[9],t[2],t[6],t[10]),this}multiply(e){return this.multiplyMatrices(this,e)}premultiply(e){return this.multiplyMatrices(e,this)}multiplyMatrices(e,t){const i=e.elements,n=t.elements,a=this.elements,r=i[0],s=i[3],o=i[6],l=i[1],h=i[4],c=i[7],u=i[2],d=i[5],p=i[8],m=n[0],f=n[3],g=n[6],v=n[1],y=n[4],b=n[7],M=n[2],_=n[5],x=n[8];return a[0]=r*m+s*v+o*M,a[3]=r*f+s*y+o*_,a[6]=r*g+s*b+o*x,a[1]=l*m+h*v+c*M,a[4]=l*f+h*y+c*_,a[7]=l*g+h*b+c*x,a[2]=u*m+d*v+p*M,a[5]=u*f+d*y+p*_,a[8]=u*g+d*b+p*x,this}multiplyScalar(e){const t=this.elements;return t[0]*=e,t[3]*=e,t[6]*=e,t[1]*=e,t[4]*=e,t[7]*=e,t[2]*=e,t[5]*=e,t[8]*=e,this}determinant(){const e=this.elements,t=e[0],i=e[1],n=e[2],a=e[3],r=e[4],s=e[5],o=e[6],l=e[7],h=e[8];return t*r*h-t*s*l-i*a*h+i*s*o+n*a*l-n*r*o}invert(){const e=this.elements,t=e[0],i=e[1],n=e[2],a=e[3],r=e[4],s=e[5],o=e[6],l=e[7],h=e[8],c=h*r-s*l,u=s*o-h*a,d=l*a-r*o,p=t*c+i*u+n*d;if(0===p)return this.set(0,0,0,0,0,0,0,0,0);const m=1/p;return e[0]=c*m,e[1]=(n*l-h*i)*m,e[2]=(s*i-n*r)*m,e[3]=u*m,e[4]=(h*t-n*o)*m,e[5]=(n*a-s*t)*m,e[6]=d*m,e[7]=(i*o-l*t)*m,e[8]=(r*t-i*a)*m,this}transpose(){let e;const t=this.elements;return e=t[1],t[1]=t[3],t[3]=e,e=t[2],t[2]=t[6],t[6]=e,e=t[5],t[5]=t[7],t[7]=e,this}getNormalMatrix(e){return this.setFromMatrix4(e).invert().transpose()}transposeIntoArray(e){const t=this.elements;return e[0]=t[0],e[1]=t[3],e[2]=t[6],e[3]=t[1],e[4]=t[4],e[5]=t[7],e[6]=t[2],e[7]=t[5],e[8]=t[8],this}setUvTransform(e,t,i,n,a,r,s){const o=Math.cos(a),l=Math.sin(a);return this.set(i*o,i*l,-i*(o*r+l*s)+r+e,-n*l,n*o,-n*(-l*r+o*s)+s+t,0,0,1),this}scale(e,t){return this.premultiply(Tt.makeScale(e,t)),this}rotate(e){return this.premultiply(Tt.makeRotation(-e)),this}translate(e,t){return this.premultiply(Tt.makeTranslation(e,t)),this}makeTranslation(e,t){return e.isVector2?this.set(1,0,e.x,0,1,e.y,0,0,1):this.set(1,0,e,0,1,t,0,0,1),this}makeRotation(e){const t=Math.cos(e),i=Math.sin(e);return this.set(t,-i,0,i,t,0,0,0,1),this}makeScale(e,t){return this.set(e,0,0,0,t,0,0,0,1),this}equals(e){const t=this.elements,i=e.elements;for(let e=0;e<9;e++)if(t[e]!==i[e])return!1;return!0}fromArray(e,t=0){for(let i=0;i<9;i++)this.elements[i]=e[i+t];return this}toArray(e=[],t=0){const i=this.elements;return e[t]=i[0],e[t+1]=i[1],e[t+2]=i[2],e[t+3]=i[3],e[t+4]=i[4],e[t+5]=i[5],e[t+6]=i[6],e[t+7]=i[7],e[t+8]=i[8],e}clone(){return(new this.constructor).fromArray(this.elements)}}const Tt=new Et,Ct=(new Et).set(.4123908,.3575843,.1804808,.212639,.7151687,.0721923,.0193308,.1191948,.9505322),At=(new Et).set(3.2409699,-1.5373832,-.4986108,-.9692436,1.8759675,.0415551,.0556301,-.203977,1.0569715);function Pt(){const e={enabled:!0,workingColorSpace:ke,spaces:{},convert:function(e,t,i){return!1!==this.enabled&&t!==i&&t&&i?(this.spaces[t].transfer===Ge&&(e.r=Rt(e.r),e.g=Rt(e.g),e.b=Rt(e.b)),this.spaces[t].primaries!==this.spaces[i].primaries&&(e.applyMatrix3(this.spaces[t].toXYZ),e.applyMatrix3(this.spaces[i].fromXYZ)),this.spaces[i].transfer===Ge&&(e.r=It(e.r),e.g=It(e.g),e.b=It(e.b)),e):e},workingToColorSpace:function(e,t){return this.convert(e,this.workingColorSpace,t)},colorSpaceToWorking:function(e,t){return this.convert(e,t,this.workingColorSpace)},getPrimaries:function(e){return this.spaces[e].primaries},getTransfer:function(e){return e===Ue?Ne:this.spaces[e].transfer},getToneMappingMode:function(e){return this.spaces[e].outputColorSpaceConfig.toneMappingMode||"standard"},getLuminanceCoefficients:function(e,t=this.workingColorSpace){return e.fromArray(this.spaces[t].luminanceCoefficients)},define:function(e){Object.assign(this.spaces,e)},_getMatrix:function(e,t,i){return e.copy(this.spaces[t].toXYZ).multiply(this.spaces[i].fromXYZ)},_getDrawingBufferColorSpace:function(e){return this.spaces[e].outputColorSpaceConfig.drawingBufferColorSpace},_getUnpackColorSpace:function(e=this.workingColorSpace){return this.spaces[e].workingColorSpaceConfig.unpackColorSpace},fromWorkingColorSpace:function(t,i){return ht("ColorManagement: .fromWorkingColorSpace() has been renamed to .workingToColorSpace()."),e.workingToColorSpace(t,i)},toWorkingColorSpace:function(t,i){return ht("ColorManagement: .toWorkingColorSpace() has been renamed to .colorSpaceToWorking()."),e.colorSpaceToWorking(t,i)}},t=[.64,.33,.3,.6,.15,.06],i=[.2126,.7152,.0722],n=[.3127,.329];return e.define({[ke]:{primaries:t,whitePoint:n,transfer:Ne,toXYZ:Ct,fromXYZ:At,luminanceCoefficients:i,workingColorSpaceConfig:{unpackColorSpace:ze},outputColorSpaceConfig:{drawingBufferColorSpace:ze}},[ze]:{primaries:t,whitePoint:n,transfer:Ge,toXYZ:Ct,fromXYZ:At,luminanceCoefficients:i,outputColorSpaceConfig:{drawingBufferColorSpace:ze}}}),e}const Dt=Pt();function Rt(e){return e<.04045?.0773993808*e:Math.pow(.9478672986*e+.0521327014,2.4)}function It(e){return e<.0031308?12.92*e:1.055*Math.pow(e,.41666)-.055}let Lt;class Bt{static getDataURL(e,t="image/png"){if(/^data:/i.test(e.src))return e.src;if("undefined"==typeof HTMLCanvasElement)return e.src;let i;if(e instanceof HTMLCanvasElement)i=e;else{void 0===Lt&&(Lt=nt("canvas")),Lt.width=e.width,Lt.height=e.height;const t=Lt.getContext("2d");e instanceof ImageData?t.putImageData(e,0,0):t.drawImage(e,0,0,e.width,e.height),i=Lt}return i.toDataURL(t)}static sRGBToLinear(e){if("undefined"!=typeof HTMLImageElement&&e instanceof HTMLImageElement||"undefined"!=typeof HTMLCanvasElement&&e instanceof HTMLCanvasElement||"undefined"!=typeof ImageBitmap&&e instanceof ImageBitmap){const t=nt("canvas");t.width=e.width,t.height=e.height;const i=t.getContext("2d");i.drawImage(e,0,0,e.width,e.height);const n=i.getImageData(0,0,e.width,e.height),a=n.data;for(let e=0;e<a.length;e++)a[e]=255*Rt(a[e]/255);return i.putImageData(n,0,0),t}if(e.data){const t=e.data.slice(0);for(let e=0;e<t.length;e++)t instanceof Uint8Array||t instanceof Uint8ClampedArray?t[e]=Math.floor(255*Rt(t[e]/255)):t[e]=Rt(t[e]);return{data:t,width:e.width,height:e.height}}return ot("ImageUtils.sRGBToLinear(): Unsupported image type. No color space conversion applied."),e}}let Ot=0;class Ft{constructor(e=null){this.isSource=!0,Object.defineProperty(this,"id",{value:Ot++}),this.uuid=mt(),this.data=e,this.dataReady=!0,this.version=0}getSize(e){const t=this.data;return"undefined"!=typeof HTMLVideoElement&&t instanceof HTMLVideoElement?e.set(t.videoWidth,t.videoHeight,0):t instanceof VideoFrame?e.set(t.displayHeight,t.displayWidth,0):null!==t?e.set(t.width,t.height,t.depth||0):e.set(0,0,0),e}set needsUpdate(e){!0===e&&this.version++}toJSON(e){const t=void 0===e||"string"==typeof e;if(!t&&void 0!==e.images[this.uuid])return e.images[this.uuid];const i={uuid:this.uuid,url:""},n=this.data;if(null!==n){let e;if(Array.isArray(n)){e=[];for(let t=0,i=n.length;t<i;t++)n[t].isDataTexture?e.push(Ut(n[t].image)):e.push(Ut(n[t]))}else e=Ut(n);i.url=e}return t||(e.images[this.uuid]=i),i}}function Ut(e){return"undefined"!=typeof HTMLImageElement&&e instanceof HTMLImageElement||"undefined"!=typeof HTMLCanvasElement&&e instanceof HTMLCanvasElement||"undefined"!=typeof ImageBitmap&&e instanceof ImageBitmap?Bt.getDataURL(e):e.data?{data:Array.from(e.data),width:e.width,height:e.height,type:e.data.constructor.name}:(ot("Texture: Unable to serialize Texture."),{})}let zt=0;const kt=new xt;class Nt extends ct{constructor(e=Nt.DEFAULT_IMAGE,t=Nt.DEFAULT_MAPPING,i=1001,n=1001,a=1006,r=1008,s=1023,o=1009,l=Nt.DEFAULT_ANISOTROPY,h=""){super(),this.isTexture=!0,Object.defineProperty(this,"id",{value:zt++}),this.uuid=mt(),this.name="",this.source=new Ft(e),this.mipmaps=[],this.mapping=t,this.channel=0,this.wrapS=i,this.wrapT=n,this.magFilter=a,this.minFilter=r,this.anisotropy=l,this.format=s,this.internalFormat=null,this.type=o,this.offset=new Mt(0,0),this.repeat=new Mt(1,1),this.center=new Mt(0,0),this.rotation=0,this.matrixAutoUpdate=!0,this.matrix=new Et,this.generateMipmaps=!0,this.premultiplyAlpha=!1,this.flipY=!0,this.unpackAlignment=4,this.colorSpace=h,this.userData={},this.updateRanges=[],this.version=0,this.onUpdate=null,this.renderTarget=null,this.isRenderTargetTexture=!1,this.isArrayTexture=!!(e&&e.depth&&e.depth>1),this.pmremVersion=0}get width(){return this.source.getSize(kt).x}get height(){return this.source.getSize(kt).y}get depth(){return this.source.getSize(kt).z}get image(){return this.source.data}set image(e=null){this.source.data=e}updateMatrix(){this.matrix.setUvTransform(this.offset.x,this.offset.y,this.repeat.x,this.repeat.y,this.rotation,this.center.x,this.center.y)}addUpdateRange(e,t){this.updateRanges.push({start:e,count:t})}clearUpdateRanges(){this.updateRanges.length=0}clone(){return(new this.constructor).copy(this)}copy(e){return this.name=e.name,this.source=e.source,this.mipmaps=e.mipmaps.slice(0),this.mapping=e.mapping,this.channel=e.channel,this.wrapS=e.wrapS,this.wrapT=e.wrapT,this.magFilter=e.magFilter,this.minFilter=e.minFilter,this.anisotropy=e.anisotropy,this.format=e.format,this.internalFormat=e.internalFormat,this.type=e.type,this.offset.copy(e.offset),this.repeat.copy(e.repeat),this.center.copy(e.center),this.rotation=e.rotation,this.matrixAutoUpdate=e.matrixAutoUpdate,this.matrix.copy(e.matrix),this.generateMipmaps=e.generateMipmaps,this.premultiplyAlpha=e.premultiplyAlpha,this.flipY=e.flipY,this.unpackAlignment=e.unpackAlignment,this.colorSpace=e.colorSpace,this.renderTarget=e.renderTarget,this.isRenderTargetTexture=e.isRenderTargetTexture,this.isArrayTexture=e.isArrayTexture,this.userData=JSON.parse(JSON.stringify(e.userData)),this.needsUpdate=!0,this}setValues(e){for(const t in e){const i=e[t];if(void 0===i){ot(`Texture.setValues(): parameter '${t}' has value of undefined.`);continue}const n=this[t];void 0!==n?n&&i&&n.isVector2&&i.isVector2||n&&i&&n.isVector3&&i.isVector3||n&&i&&n.isMatrix3&&i.isMatrix3?n.copy(i):this[t]=i:ot(`Texture.setValues(): property '${t}' does not exist.`)}}toJSON(e){const t=void 0===e||"string"==typeof e;if(!t&&void 0!==e.textures[this.uuid])return e.textures[this.uuid];const i={metadata:{version:4.7,type:"Texture",generator:"Texture.toJSON"},uuid:this.uuid,name:this.name,image:this.source.toJSON(e).uuid,mapping:this.mapping,channel:this.channel,repeat:[this.repeat.x,this.repeat.y],offset:[this.offset.x,this.offset.y],center:[this.center.x,this.center.y],rotation:this.rotation,wrap:[this.wrapS,this.wrapT],format:this.format,internalFormat:this.internalFormat,type:this.type,colorSpace:this.colorSpace,minFilter:this.minFilter,magFilter:this.magFilter,anisotropy:this.anisotropy,flipY:this.flipY,generateMipmaps:this.generateMipmaps,premultiplyAlpha:this.premultiplyAlpha,unpackAlignment:this.unpackAlignment};return Object.keys(this.userData).length>0&&(i.userData=this.userData),t||(e.textures[this.uuid]=i),i}dispose(){this.dispatchEvent({type:"dispose"})}transformUv(e){if(300!==this.mapping)return e;if(e.applyMatrix3(this.matrix),e.x<0||e.x>1)switch(this.wrapS){case B:e.x=e.x-Math.floor(e.x);break;case O:e.x=e.x<0?0:1;break;case F:1===Math.abs(Math.floor(e.x)%2)?e.x=Math.ceil(e.x)-e.x:e.x=e.x-Math.floor(e.x)}if(e.y<0||e.y>1)switch(this.wrapT){case B:e.y=e.y-Math.floor(e.y);break;case O:e.y=e.y<0?0:1;break;case F:1===Math.abs(Math.floor(e.y)%2)?e.y=Math.ceil(e.y)-e.y:e.y=e.y-Math.floor(e.y)}return this.flipY&&(e.y=1-e.y),e}set needsUpdate(e){!0===e&&(this.version++,this.source.needsUpdate=!0)}set needsPMREMUpdate(e){!0===e&&this.pmremVersion++}}Nt.DEFAULT_IMAGE=null,Nt.DEFAULT_MAPPING=300,Nt.DEFAULT_ANISOTROPY=1;class Gt{constructor(e=0,t=0,i=0,n=1){Gt.prototype.isVector4=!0,this.x=e,this.y=t,this.z=i,this.w=n}get width(){return this.z}set width(e){this.z=e}get height(){return this.w}set height(e){this.w=e}set(e,t,i,n){return this.x=e,this.y=t,this.z=i,this.w=n,this}setScalar(e){return this.x=e,this.y=e,this.z=e,this.w=e,this}setX(e){return this.x=e,this}setY(e){return this.y=e,this}setZ(e){return this.z=e,this}setW(e){return this.w=e,this}setComponent(e,t){switch(e){case 0:this.x=t;break;case 1:this.y=t;break;case 2:this.z=t;break;case 3:this.w=t;break;default:throw new Error("index is out of range: "+e)}return this}getComponent(e){switch(e){case 0:return this.x;case 1:return this.y;case 2:return this.z;case 3:return this.w;default:throw new Error("index is out of range: "+e)}}clone(){return new this.constructor(this.x,this.y,this.z,this.w)}copy(e){return this.x=e.x,this.y=e.y,this.z=e.z,this.w=void 0!==e.w?e.w:1,this}add(e){return this.x+=e.x,this.y+=e.y,this.z+=e.z,this.w+=e.w,this}addScalar(e){return this.x+=e,this.y+=e,this.z+=e,this.w+=e,this}addVectors(e,t){return this.x=e.x+t.x,this.y=e.y+t.y,this.z=e.z+t.z,this.w=e.w+t.w,this}addScaledVector(e,t){return this.x+=e.x*t,this.y+=e.y*t,this.z+=e.z*t,this.w+=e.w*t,this}sub(e){return this.x-=e.x,this.y-=e.y,this.z-=e.z,this.w-=e.w,this}subScalar(e){return this.x-=e,this.y-=e,this.z-=e,this.w-=e,this}subVectors(e,t){return this.x=e.x-t.x,this.y=e.y-t.y,this.z=e.z-t.z,this.w=e.w-t.w,this}multiply(e){return this.x*=e.x,this.y*=e.y,this.z*=e.z,this.w*=e.w,this}multiplyScalar(e){return this.x*=e,this.y*=e,this.z*=e,this.w*=e,this}applyMatrix4(e){const t=this.x,i=this.y,n=this.z,a=this.w,r=e.elements;return this.x=r[0]*t+r[4]*i+r[8]*n+r[12]*a,this.y=r[1]*t+r[5]*i+r[9]*n+r[13]*a,this.z=r[2]*t+r[6]*i+r[10]*n+r[14]*a,this.w=r[3]*t+r[7]*i+r[11]*n+r[15]*a,this}divide(e){return this.x/=e.x,this.y/=e.y,this.z/=e.z,this.w/=e.w,this}divideScalar(e){return this.multiplyScalar(1/e)}setAxisAngleFromQuaternion(e){this.w=2*Math.acos(e.w);const t=Math.sqrt(1-e.w*e.w);return t<1e-4?(this.x=1,this.y=0,this.z=0):(this.x=e.x/t,this.y=e.y/t,this.z=e.z/t),this}setAxisAngleFromRotationMatrix(e){let t,i,n,a;const r=.01,s=.1,o=e.elements,l=o[0],h=o[4],c=o[8],u=o[1],d=o[5],p=o[9],m=o[2],f=o[6],g=o[10];if(Math.abs(h-u)<r&&Math.abs(c-m)<r&&Math.abs(p-f)<r){if(Math.abs(h+u)<s&&Math.abs(c+m)<s&&Math.abs(p+f)<s&&Math.abs(l+d+g-3)<s)return this.set(1,0,0,0),this;t=Math.PI;const e=(l+1)/2,o=(d+1)/2,v=(g+1)/2,y=(h+u)/4,b=(c+m)/4,M=(p+f)/4;return e>o&&e>v?e<r?(i=0,n=.707106781,a=.707106781):(i=Math.sqrt(e),n=y/i,a=b/i):o>v?o<r?(i=.707106781,n=0,a=.707106781):(n=Math.sqrt(o),i=y/n,a=M/n):v<r?(i=.707106781,n=.707106781,a=0):(a=Math.sqrt(v),i=b/a,n=M/a),this.set(i,n,a,t),this}let v=Math.sqrt((f-p)*(f-p)+(c-m)*(c-m)+(u-h)*(u-h));return Math.abs(v)<.001&&(v=1),this.x=(f-p)/v,this.y=(c-m)/v,this.z=(u-h)/v,this.w=Math.acos((l+d+g-1)/2),this}setFromMatrixPosition(e){const t=e.elements;return this.x=t[12],this.y=t[13],this.z=t[14],this.w=t[15],this}min(e){return this.x=Math.min(this.x,e.x),this.y=Math.min(this.y,e.y),this.z=Math.min(this.z,e.z),this.w=Math.min(this.w,e.w),this}max(e){return this.x=Math.max(this.x,e.x),this.y=Math.max(this.y,e.y),this.z=Math.max(this.z,e.z),this.w=Math.max(this.w,e.w),this}clamp(e,t){return this.x=ft(this.x,e.x,t.x),this.y=ft(this.y,e.y,t.y),this.z=ft(this.z,e.z,t.z),this.w=ft(this.w,e.w,t.w),this}clampScalar(e,t){return this.x=ft(this.x,e,t),this.y=ft(this.y,e,t),this.z=ft(this.z,e,t),this.w=ft(this.w,e,t),this}clampLength(e,t){const i=this.length();return this.divideScalar(i||1).multiplyScalar(ft(i,e,t))}floor(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this.z=Math.floor(this.z),this.w=Math.floor(this.w),this}ceil(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this.z=Math.ceil(this.z),this.w=Math.ceil(this.w),this}round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this.z=Math.round(this.z),this.w=Math.round(this.w),this}roundToZero(){return this.x=Math.trunc(this.x),this.y=Math.trunc(this.y),this.z=Math.trunc(this.z),this.w=Math.trunc(this.w),this}negate(){return this.x=-this.x,this.y=-this.y,this.z=-this.z,this.w=-this.w,this}dot(e){return this.x*e.x+this.y*e.y+this.z*e.z+this.w*e.w}lengthSq(){return this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w}length(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)}manhattanLength(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)+Math.abs(this.w)}normalize(){return this.divideScalar(this.length()||1)}setLength(e){return this.normalize().multiplyScalar(e)}lerp(e,t){return this.x+=(e.x-this.x)*t,this.y+=(e.y-this.y)*t,this.z+=(e.z-this.z)*t,this.w+=(e.w-this.w)*t,this}lerpVectors(e,t,i){return this.x=e.x+(t.x-e.x)*i,this.y=e.y+(t.y-e.y)*i,this.z=e.z+(t.z-e.z)*i,this.w=e.w+(t.w-e.w)*i,this}equals(e){return e.x===this.x&&e.y===this.y&&e.z===this.z&&e.w===this.w}fromArray(e,t=0){return this.x=e[t],this.y=e[t+1],this.z=e[t+2],this.w=e[t+3],this}toArray(e=[],t=0){return e[t]=this.x,e[t+1]=this.y,e[t+2]=this.z,e[t+3]=this.w,e}fromBufferAttribute(e,t){return this.x=e.getX(t),this.y=e.getY(t),this.z=e.getZ(t),this.w=e.getW(t),this}random(){return this.x=Math.random(),this.y=Math.random(),this.z=Math.random(),this.w=Math.random(),this}*[Symbol.iterator](){yield this.x,yield this.y,yield this.z,yield this.w}}class Vt extends ct{constructor(e=1,t=1,i={}){super(),i=Object.assign({generateMipmaps:!1,internalFormat:null,minFilter:N,depthBuffer:!0,stencilBuffer:!1,resolveDepthBuffer:!0,resolveStencilBuffer:!0,depthTexture:null,samples:0,count:1,depth:1,multiview:!1},i),this.isRenderTarget=!0,this.width=e,this.height=t,this.depth=i.depth,this.scissor=new Gt(0,0,e,t),this.scissorTest=!1,this.viewport=new Gt(0,0,e,t);const n={width:e,height:t,depth:i.depth},a=new Nt(n);this.textures=[];const r=i.count;for(let e=0;e<r;e++)this.textures[e]=a.clone(),this.textures[e].isRenderTargetTexture=!0,this.textures[e].renderTarget=this;this._setTextureOptions(i),this.depthBuffer=i.depthBuffer,this.stencilBuffer=i.stencilBuffer,this.resolveDepthBuffer=i.resolveDepthBuffer,this.resolveStencilBuffer=i.resolveStencilBuffer,this._depthTexture=null,this.depthTexture=i.depthTexture,this.samples=i.samples,this.multiview=i.multiview}_setTextureOptions(e={}){const t={minFilter:N,generateMipmaps:!1,flipY:!1,internalFormat:null};void 0!==e.mapping&&(t.mapping=e.mapping),void 0!==e.wrapS&&(t.wrapS=e.wrapS),void 0!==e.wrapT&&(t.wrapT=e.wrapT),void 0!==e.wrapR&&(t.wrapR=e.wrapR),void 0!==e.magFilter&&(t.magFilter=e.magFilter),void 0!==e.minFilter&&(t.minFilter=e.minFilter),void 0!==e.format&&(t.format=e.format),void 0!==e.type&&(t.type=e.type),void 0!==e.anisotropy&&(t.anisotropy=e.anisotropy),void 0!==e.colorSpace&&(t.colorSpace=e.colorSpace),void 0!==e.flipY&&(t.flipY=e.flipY),void 0!==e.generateMipmaps&&(t.generateMipmaps=e.generateMipmaps),void 0!==e.internalFormat&&(t.internalFormat=e.internalFormat);for(let e=0;e<this.textures.length;e++)this.textures[e].setValues(t)}get texture(){return this.textures[0]}set texture(e){this.textures[0]=e}set depthTexture(e){null!==this._depthTexture&&(this._depthTexture.renderTarget=null),null!==e&&(e.renderTarget=this),this._depthTexture=e}get depthTexture(){return this._depthTexture}setSize(e,t,i=1){if(this.width!==e||this.height!==t||this.depth!==i){this.width=e,this.height=t,this.depth=i;for(let n=0,a=this.textures.length;n<a;n++)this.textures[n].image.width=e,this.textures[n].image.height=t,this.textures[n].image.depth=i,!0!==this.textures[n].isData3DTexture&&(this.textures[n].isArrayTexture=this.textures[n].image.depth>1);this.dispose()}this.viewport.set(0,0,e,t),this.scissor.set(0,0,e,t)}clone(){return(new this.constructor).copy(this)}copy(e){this.width=e.width,this.height=e.height,this.depth=e.depth,this.scissor.copy(e.scissor),this.scissorTest=e.scissorTest,this.viewport.copy(e.viewport),this.textures.length=0;for(let t=0,i=e.textures.length;t<i;t++){this.textures[t]=e.textures[t].clone(),this.textures[t].isRenderTargetTexture=!0,this.textures[t].renderTarget=this;const i=Object.assign({},e.textures[t].image);this.textures[t].source=new Ft(i)}return this.depthBuffer=e.depthBuffer,this.stencilBuffer=e.stencilBuffer,this.resolveDepthBuffer=e.resolveDepthBuffer,this.resolveStencilBuffer=e.resolveStencilBuffer,null!==e.depthTexture&&(this.depthTexture=e.depthTexture.clone()),this.samples=e.samples,this}dispose(){this.dispatchEvent({type:"dispose"})}}class Ht extends Vt{constructor(e=1,t=1,i={}){super(e,t,i),this.isWebGLRenderTarget=!0}}class Wt extends Nt{constructor(e=null,t=1,i=1,n=1){super(null),this.isDataArrayTexture=!0,this.image={data:e,width:t,height:i,depth:n},this.magFilter=U,this.minFilter=U,this.wrapR=O,this.generateMipmaps=!1,this.flipY=!1,this.unpackAlignment=1,this.layerUpdates=new Set}addLayerUpdate(e){this.layerUpdates.add(e)}clearLayerUpdates(){this.layerUpdates.clear()}}class jt extends Nt{constructor(e=null,t=1,i=1,n=1){super(null),this.isData3DTexture=!0,this.image={data:e,width:t,height:i,depth:n},this.magFilter=U,this.minFilter=U,this.wrapR=O,this.generateMipmaps=!1,this.flipY=!1,this.unpackAlignment=1}}class Xt{constructor(e=new xt(1/0,1/0,1/0),t=new xt(-1/0,-1/0,-1/0)){this.isBox3=!0,this.min=e,this.max=t}set(e,t){return this.min.copy(e),this.max.copy(t),this}setFromArray(e){this.makeEmpty();for(let t=0,i=e.length;t<i;t+=3)this.expandByPoint(Yt.fromArray(e,t));return this}setFromBufferAttribute(e){this.makeEmpty();for(let t=0,i=e.count;t<i;t++)this.expandByPoint(Yt.fromBufferAttribute(e,t));return this}setFromPoints(e){this.makeEmpty();for(let t=0,i=e.length;t<i;t++)this.expandByPoint(e[t]);return this}setFromCenterAndSize(e,t){const i=Yt.copy(t).multiplyScalar(.5);return this.min.copy(e).sub(i),this.max.copy(e).add(i),this}setFromObject(e,t=!1){return this.makeEmpty(),this.expandByObject(e,t)}clone(){return(new this.constructor).copy(this)}copy(e){return this.min.copy(e.min),this.max.copy(e.max),this}makeEmpty(){return this.min.x=this.min.y=this.min.z=1/0,this.max.x=this.max.y=this.max.z=-1/0,this}isEmpty(){return this.max.x<this.min.x||this.max.y<this.min.y||this.max.z<this.min.z}getCenter(e){return this.isEmpty()?e.set(0,0,0):e.addVectors(this.min,this.max).multiplyScalar(.5)}getSize(e){return this.isEmpty()?e.set(0,0,0):e.subVectors(this.max,this.min)}expandByPoint(e){return this.min.min(e),this.max.max(e),this}expandByVector(e){return this.min.sub(e),this.max.add(e),this}expandByScalar(e){return this.min.addScalar(-e),this.max.addScalar(e),this}expandByObject(e,t=!1){e.updateWorldMatrix(!1,!1);const i=e.geometry;if(void 0!==i){const n=i.getAttribute("position");if(!0===t&&void 0!==n&&!0!==e.isInstancedMesh)for(let t=0,i=n.count;t<i;t++)!0===e.isMesh?e.getVertexPosition(t,Yt):Yt.fromBufferAttribute(n,t),Yt.applyMatrix4(e.matrixWorld),this.expandByPoint(Yt);else void 0!==e.boundingBox?(null===e.boundingBox&&e.computeBoundingBox(),$t.copy(e.boundingBox)):(null===i.boundingBox&&i.computeBoundingBox(),$t.copy(i.boundingBox)),$t.applyMatrix4(e.matrixWorld),this.union($t)}const n=e.children;for(let e=0,i=n.length;e<i;e++)this.expandByObject(n[e],t);return this}containsPoint(e){return e.x>=this.min.x&&e.x<=this.max.x&&e.y>=this.min.y&&e.y<=this.max.y&&e.z>=this.min.z&&e.z<=this.max.z}containsBox(e){return this.min.x<=e.min.x&&e.max.x<=this.max.x&&this.min.y<=e.min.y&&e.max.y<=this.max.y&&this.min.z<=e.min.z&&e.max.z<=this.max.z}getParameter(e,t){return t.set((e.x-this.min.x)/(this.max.x-this.min.x),(e.y-this.min.y)/(this.max.y-this.min.y),(e.z-this.min.z)/(this.max.z-this.min.z))}intersectsBox(e){return e.max.x>=this.min.x&&e.min.x<=this.max.x&&e.max.y>=this.min.y&&e.min.y<=this.max.y&&e.max.z>=this.min.z&&e.min.z<=this.max.z}intersectsSphere(e){return this.clampPoint(e.center,Yt),Yt.distanceToSquared(e.center)<=e.radius*e.radius}intersectsPlane(e){let t,i;return e.normal.x>0?(t=e.normal.x*this.min.x,i=e.normal.x*this.max.x):(t=e.normal.x*this.max.x,i=e.normal.x*this.min.x),e.normal.y>0?(t+=e.normal.y*this.min.y,i+=e.normal.y*this.max.y):(t+=e.normal.y*this.max.y,i+=e.normal.y*this.min.y),e.normal.z>0?(t+=e.normal.z*this.min.z,i+=e.normal.z*this.max.z):(t+=e.normal.z*this.max.z,i+=e.normal.z*this.min.z),t<=-e.constant&&i>=-e.constant}intersectsTriangle(e){if(this.isEmpty())return!1;this.getCenter(ii),ni.subVectors(this.max,ii),Zt.subVectors(e.a,ii),Kt.subVectors(e.b,ii),Qt.subVectors(e.c,ii),Jt.subVectors(Kt,Zt),ei.subVectors(Qt,Kt),ti.subVectors(Zt,Qt);let t=[0,-Jt.z,Jt.y,0,-ei.z,ei.y,0,-ti.z,ti.y,Jt.z,0,-Jt.x,ei.z,0,-ei.x,ti.z,0,-ti.x,-Jt.y,Jt.x,0,-ei.y,ei.x,0,-ti.y,ti.x,0];return!!si(t,Zt,Kt,Qt,ni)&&(t=[1,0,0,0,1,0,0,0,1],!!si(t,Zt,Kt,Qt,ni)&&(ai.crossVectors(Jt,ei),t=[ai.x,ai.y,ai.z],si(t,Zt,Kt,Qt,ni)))}clampPoint(e,t){return t.copy(e).clamp(this.min,this.max)}distanceToPoint(e){return this.clampPoint(e,Yt).distanceTo(e)}getBoundingSphere(e){return this.isEmpty()?e.makeEmpty():(this.getCenter(e.center),e.radius=.5*this.getSize(Yt).length()),e}intersect(e){return this.min.max(e.min),this.max.min(e.max),this.isEmpty()&&this.makeEmpty(),this}union(e){return this.min.min(e.min),this.max.max(e.max),this}applyMatrix4(e){return this.isEmpty()||(qt[0].set(this.min.x,this.min.y,this.min.z).applyMatrix4(e),qt[1].set(this.min.x,this.min.y,this.max.z).applyMatrix4(e),qt[2].set(this.min.x,this.max.y,this.min.z).applyMatrix4(e),qt[3].set(this.min.x,this.max.y,this.max.z).applyMatrix4(e),qt[4].set(this.max.x,this.min.y,this.min.z).applyMatrix4(e),qt[5].set(this.max.x,this.min.y,this.max.z).applyMatrix4(e),qt[6].set(this.max.x,this.max.y,this.min.z).applyMatrix4(e),qt[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(e),this.setFromPoints(qt)),this}translate(e){return this.min.add(e),this.max.add(e),this}equals(e){return e.min.equals(this.min)&&e.max.equals(this.max)}toJSON(){return{min:this.min.toArray(),max:this.max.toArray()}}fromJSON(e){return this.min.fromArray(e.min),this.max.fromArray(e.max),this}}const qt=[new xt,new xt,new xt,new xt,new xt,new xt,new xt,new xt],Yt=new xt,$t=new Xt,Zt=new xt,Kt=new xt,Qt=new xt,Jt=new xt,ei=new xt,ti=new xt,ii=new xt,ni=new xt,ai=new xt,ri=new xt;function si(e,t,i,n,a){for(let r=0,s=e.length-3;r<=s;r+=3){ri.fromArray(e,r);const s=a.x*Math.abs(ri.x)+a.y*Math.abs(ri.y)+a.z*Math.abs(ri.z),o=t.dot(ri),l=i.dot(ri),h=n.dot(ri);if(Math.max(-Math.max(o,l,h),Math.min(o,l,h))>s)return!1}return!0}const oi=new Xt,li=new xt,hi=new xt;class ci{constructor(e=new xt,t=-1){this.isSphere=!0,this.center=e,this.radius=t}set(e,t){return this.center.copy(e),this.radius=t,this}setFromPoints(e,t){const i=this.center;void 0!==t?i.copy(t):oi.setFromPoints(e).getCenter(i);let n=0;for(let t=0,a=e.length;t<a;t++)n=Math.max(n,i.distanceToSquared(e[t]));return this.radius=Math.sqrt(n),this}copy(e){return this.center.copy(e.center),this.radius=e.radius,this}isEmpty(){return this.radius<0}makeEmpty(){return this.center.set(0,0,0),this.radius=-1,this}containsPoint(e){return e.distanceToSquared(this.center)<=this.radius*this.radius}distanceToPoint(e){return e.distanceTo(this.center)-this.radius}intersectsSphere(e){const t=this.radius+e.radius;return e.center.distanceToSquared(this.center)<=t*t}intersectsBox(e){return e.intersectsSphere(this)}intersectsPlane(e){return Math.abs(e.distanceToPoint(this.center))<=this.radius}clampPoint(e,t){const i=this.center.distanceToSquared(e);return t.copy(e),i>this.radius*this.radius&&(t.sub(this.center).normalize(),t.multiplyScalar(this.radius).add(this.center)),t}getBoundingBox(e){return this.isEmpty()?(e.makeEmpty(),e):(e.set(this.center,this.center),e.expandByScalar(this.radius),e)}applyMatrix4(e){return this.center.applyMatrix4(e),this.radius=this.radius*e.getMaxScaleOnAxis(),this}translate(e){return this.center.add(e),this}expandByPoint(e){if(this.isEmpty())return this.center.copy(e),this.radius=0,this;li.subVectors(e,this.center);const t=li.lengthSq();if(t>this.radius*this.radius){const e=Math.sqrt(t),i=.5*(e-this.radius);this.center.addScaledVector(li,i/e),this.radius+=i}return this}union(e){return e.isEmpty()?this:this.isEmpty()?(this.copy(e),this):(!0===this.center.equals(e.center)?this.radius=Math.max(this.radius,e.radius):(hi.subVectors(e.center,this.center).setLength(e.radius),this.expandByPoint(li.copy(e.center).add(hi)),this.expandByPoint(li.copy(e.center).sub(hi))),this)}equals(e){return e.center.equals(this.center)&&e.radius===this.radius}clone(){return(new this.constructor).copy(this)}toJSON(){return{radius:this.radius,center:this.center.toArray()}}fromJSON(e){return this.radius=e.radius,this.center.fromArray(e.center),this}}const ui=new xt,di=new xt,pi=new xt,mi=new xt,fi=new xt,gi=new xt,vi=new xt;class yi{constructor(e=new xt,t=new xt(0,0,-1)){this.origin=e,this.direction=t}set(e,t){return this.origin.copy(e),this.direction.copy(t),this}copy(e){return this.origin.copy(e.origin),this.direction.copy(e.direction),this}at(e,t){return t.copy(this.origin).addScaledVector(this.direction,e)}lookAt(e){return this.direction.copy(e).sub(this.origin).normalize(),this}recast(e){return this.origin.copy(this.at(e,ui)),this}closestPointToPoint(e,t){t.subVectors(e,this.origin);const i=t.dot(this.direction);return i<0?t.copy(this.origin):t.copy(this.origin).addScaledVector(this.direction,i)}distanceToPoint(e){return Math.sqrt(this.distanceSqToPoint(e))}distanceSqToPoint(e){const t=ui.subVectors(e,this.origin).dot(this.direction);return t<0?this.origin.distanceToSquared(e):(ui.copy(this.origin).addScaledVector(this.direction,t),ui.distanceToSquared(e))}distanceSqToSegment(e,t,i,n){di.copy(e).add(t).multiplyScalar(.5),pi.copy(t).sub(e).normalize(),mi.copy(this.origin).sub(di);const a=.5*e.distanceTo(t),r=-this.direction.dot(pi),s=mi.dot(this.direction),o=-mi.dot(pi),l=mi.lengthSq(),h=Math.abs(1-r*r);let c,u,d,p;if(h>0)if(c=r*o-s,u=r*s-o,p=a*h,c>=0)if(u>=-p)if(u<=p){const e=1/h;c*=e,u*=e,d=c*(c+r*u+2*s)+u*(r*c+u+2*o)+l}else u=a,c=Math.max(0,-(r*u+s)),d=-c*c+u*(u+2*o)+l;else u=-a,c=Math.max(0,-(r*u+s)),d=-c*c+u*(u+2*o)+l;else u<=-p?(c=Math.max(0,-(-r*a+s)),u=c>0?-a:Math.min(Math.max(-a,-o),a),d=-c*c+u*(u+2*o)+l):u<=p?(c=0,u=Math.min(Math.max(-a,-o),a),d=u*(u+2*o)+l):(c=Math.max(0,-(r*a+s)),u=c>0?a:Math.min(Math.max(-a,-o),a),d=-c*c+u*(u+2*o)+l);else u=r>0?-a:a,c=Math.max(0,-(r*u+s)),d=-c*c+u*(u+2*o)+l;return i&&i.copy(this.origin).addScaledVector(this.direction,c),n&&n.copy(di).addScaledVector(pi,u),d}intersectSphere(e,t){ui.subVectors(e.center,this.origin);const i=ui.dot(this.direction),n=ui.dot(ui)-i*i,a=e.radius*e.radius;if(n>a)return null;const r=Math.sqrt(a-n),s=i-r,o=i+r;return o<0?null:s<0?this.at(o,t):this.at(s,t)}intersectsSphere(e){return!(e.radius<0)&&this.distanceSqToPoint(e.center)<=e.radius*e.radius}distanceToPlane(e){const t=e.normal.dot(this.direction);if(0===t)return 0===e.distanceToPoint(this.origin)?0:null;const i=-(this.origin.dot(e.normal)+e.constant)/t;return i>=0?i:null}intersectPlane(e,t){const i=this.distanceToPlane(e);return null===i?null:this.at(i,t)}intersectsPlane(e){const t=e.distanceToPoint(this.origin);return 0===t||e.normal.dot(this.direction)*t<0}intersectBox(e,t){let i,n,a,r,s,o;const l=1/this.direction.x,h=1/this.direction.y,c=1/this.direction.z,u=this.origin;return l>=0?(i=(e.min.x-u.x)*l,n=(e.max.x-u.x)*l):(i=(e.max.x-u.x)*l,n=(e.min.x-u.x)*l),h>=0?(a=(e.min.y-u.y)*h,r=(e.max.y-u.y)*h):(a=(e.max.y-u.y)*h,r=(e.min.y-u.y)*h),i>r||a>n?null:((a>i||isNaN(i))&&(i=a),(r<n||isNaN(n))&&(n=r),c>=0?(s=(e.min.z-u.z)*c,o=(e.max.z-u.z)*c):(s=(e.max.z-u.z)*c,o=(e.min.z-u.z)*c),i>o||s>n?null:((s>i||i!=i)&&(i=s),(o<n||n!=n)&&(n=o),n<0?null:this.at(i>=0?i:n,t)))}intersectsBox(e){return null!==this.intersectBox(e,ui)}intersectTriangle(e,t,i,n,a){fi.subVectors(t,e),gi.subVectors(i,e),vi.crossVectors(fi,gi);let r,s=this.direction.dot(vi);if(s>0){if(n)return null;r=1}else{if(!(s<0))return null;r=-1,s=-s}mi.subVectors(this.origin,e);const o=r*this.direction.dot(gi.crossVectors(mi,gi));if(o<0)return null;const l=r*this.direction.dot(fi.cross(mi));if(l<0)return null;if(o+l>s)return null;const h=-r*mi.dot(vi);return h<0?null:this.at(h/s,a)}applyMatrix4(e){return this.origin.applyMatrix4(e),this.direction.transformDirection(e),this}equals(e){return e.origin.equals(this.origin)&&e.direction.equals(this.direction)}clone(){return(new this.constructor).copy(this)}}class bi{constructor(e,t,i,n,a,r,s,o,l,h,c,u,d,p,m,f){bi.prototype.isMatrix4=!0,this.elements=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],void 0!==e&&this.set(e,t,i,n,a,r,s,o,l,h,c,u,d,p,m,f)}set(e,t,i,n,a,r,s,o,l,h,c,u,d,p,m,f){const g=this.elements;return g[0]=e,g[4]=t,g[8]=i,g[12]=n,g[1]=a,g[5]=r,g[9]=s,g[13]=o,g[2]=l,g[6]=h,g[10]=c,g[14]=u,g[3]=d,g[7]=p,g[11]=m,g[15]=f,this}identity(){return this.set(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1),this}clone(){return(new bi).fromArray(this.elements)}copy(e){const t=this.elements,i=e.elements;return t[0]=i[0],t[1]=i[1],t[2]=i[2],t[3]=i[3],t[4]=i[4],t[5]=i[5],t[6]=i[6],t[7]=i[7],t[8]=i[8],t[9]=i[9],t[10]=i[10],t[11]=i[11],t[12]=i[12],t[13]=i[13],t[14]=i[14],t[15]=i[15],this}copyPosition(e){const t=this.elements,i=e.elements;return t[12]=i[12],t[13]=i[13],t[14]=i[14],this}setFromMatrix3(e){const t=e.elements;return this.set(t[0],t[3],t[6],0,t[1],t[4],t[7],0,t[2],t[5],t[8],0,0,0,0,1),this}extractBasis(e,t,i){return e.setFromMatrixColumn(this,0),t.setFromMatrixColumn(this,1),i.setFromMatrixColumn(this,2),this}makeBasis(e,t,i){return this.set(e.x,t.x,i.x,0,e.y,t.y,i.y,0,e.z,t.z,i.z,0,0,0,0,1),this}extractRotation(e){const t=this.elements,i=e.elements,n=1/Mi.setFromMatrixColumn(e,0).length(),a=1/Mi.setFromMatrixColumn(e,1).length(),r=1/Mi.setFromMatrixColumn(e,2).length();return t[0]=i[0]*n,t[1]=i[1]*n,t[2]=i[2]*n,t[3]=0,t[4]=i[4]*a,t[5]=i[5]*a,t[6]=i[6]*a,t[7]=0,t[8]=i[8]*r,t[9]=i[9]*r,t[10]=i[10]*r,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,this}makeRotationFromEuler(e){const t=this.elements,i=e.x,n=e.y,a=e.z,r=Math.cos(i),s=Math.sin(i),o=Math.cos(n),l=Math.sin(n),h=Math.cos(a),c=Math.sin(a);if("XYZ"===e.order){const e=r*h,i=r*c,n=s*h,a=s*c;t[0]=o*h,t[4]=-o*c,t[8]=l,t[1]=i+n*l,t[5]=e-a*l,t[9]=-s*o,t[2]=a-e*l,t[6]=n+i*l,t[10]=r*o}else if("YXZ"===e.order){const e=o*h,i=o*c,n=l*h,a=l*c;t[0]=e+a*s,t[4]=n*s-i,t[8]=r*l,t[1]=r*c,t[5]=r*h,t[9]=-s,t[2]=i*s-n,t[6]=a+e*s,t[10]=r*o}else if("ZXY"===e.order){const e=o*h,i=o*c,n=l*h,a=l*c;t[0]=e-a*s,t[4]=-r*c,t[8]=n+i*s,t[1]=i+n*s,t[5]=r*h,t[9]=a-e*s,t[2]=-r*l,t[6]=s,t[10]=r*o}else if("ZYX"===e.order){const e=r*h,i=r*c,n=s*h,a=s*c;t[0]=o*h,t[4]=n*l-i,t[8]=e*l+a,t[1]=o*c,t[5]=a*l+e,t[9]=i*l-n,t[2]=-l,t[6]=s*o,t[10]=r*o}else if("YZX"===e.order){const e=r*o,i=r*l,n=s*o,a=s*l;t[0]=o*h,t[4]=a-e*c,t[8]=n*c+i,t[1]=c,t[5]=r*h,t[9]=-s*h,t[2]=-l*h,t[6]=i*c+n,t[10]=e-a*c}else if("XZY"===e.order){const e=r*o,i=r*l,n=s*o,a=s*l;t[0]=o*h,t[4]=-c,t[8]=l*h,t[1]=e*c+a,t[5]=r*h,t[9]=i*c-n,t[2]=n*c-i,t[6]=s*h,t[10]=a*c+e}return t[3]=0,t[7]=0,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,this}makeRotationFromQuaternion(e){return this.compose(xi,e,Si)}lookAt(e,t,i){const n=this.elements;return Ti.subVectors(e,t),0===Ti.lengthSq()&&(Ti.z=1),Ti.normalize(),wi.crossVectors(i,Ti),0===wi.lengthSq()&&(1===Math.abs(i.z)?Ti.x+=1e-4:Ti.z+=1e-4,Ti.normalize(),wi.crossVectors(i,Ti)),wi.normalize(),Ei.crossVectors(Ti,wi),n[0]=wi.x,n[4]=Ei.x,n[8]=Ti.x,n[1]=wi.y,n[5]=Ei.y,n[9]=Ti.y,n[2]=wi.z,n[6]=Ei.z,n[10]=Ti.z,this}multiply(e){return this.multiplyMatrices(this,e)}premultiply(e){return this.multiplyMatrices(e,this)}multiplyMatrices(e,t){const i=e.elements,n=t.elements,a=this.elements,r=i[0],s=i[4],o=i[8],l=i[12],h=i[1],c=i[5],u=i[9],d=i[13],p=i[2],m=i[6],f=i[10],g=i[14],v=i[3],y=i[7],b=i[11],M=i[15],_=n[0],x=n[4],S=n[8],w=n[12],E=n[1],T=n[5],C=n[9],A=n[13],P=n[2],D=n[6],R=n[10],I=n[14],L=n[3],B=n[7],O=n[11],F=n[15];return a[0]=r*_+s*E+o*P+l*L,a[4]=r*x+s*T+o*D+l*B,a[8]=r*S+s*C+o*R+l*O,a[12]=r*w+s*A+o*I+l*F,a[1]=h*_+c*E+u*P+d*L,a[5]=h*x+c*T+u*D+d*B,a[9]=h*S+c*C+u*R+d*O,a[13]=h*w+c*A+u*I+d*F,a[2]=p*_+m*E+f*P+g*L,a[6]=p*x+m*T+f*D+g*B,a[10]=p*S+m*C+f*R+g*O,a[14]=p*w+m*A+f*I+g*F,a[3]=v*_+y*E+b*P+M*L,a[7]=v*x+y*T+b*D+M*B,a[11]=v*S+y*C+b*R+M*O,a[15]=v*w+y*A+b*I+M*F,this}multiplyScalar(e){const t=this.elements;return t[0]*=e,t[4]*=e,t[8]*=e,t[12]*=e,t[1]*=e,t[5]*=e,t[9]*=e,t[13]*=e,t[2]*=e,t[6]*=e,t[10]*=e,t[14]*=e,t[3]*=e,t[7]*=e,t[11]*=e,t[15]*=e,this}determinant(){const e=this.elements,t=e[0],i=e[4],n=e[8],a=e[12],r=e[1],s=e[5],o=e[9],l=e[13],h=e[2],c=e[6],u=e[10],d=e[14];return e[3]*(+a*o*c-n*l*c-a*s*u+i*l*u+n*s*d-i*o*d)+e[7]*(+t*o*d-t*l*u+a*r*u-n*r*d+n*l*h-a*o*h)+e[11]*(+t*l*c-t*s*d-a*r*c+i*r*d+a*s*h-i*l*h)+e[15]*(-n*s*h-t*o*c+t*s*u+n*r*c-i*r*u+i*o*h)}transpose(){const e=this.elements;let t;return t=e[1],e[1]=e[4],e[4]=t,t=e[2],e[2]=e[8],e[8]=t,t=e[6],e[6]=e[9],e[9]=t,t=e[3],e[3]=e[12],e[12]=t,t=e[7],e[7]=e[13],e[13]=t,t=e[11],e[11]=e[14],e[14]=t,this}setPosition(e,t,i){const n=this.elements;return e.isVector3?(n[12]=e.x,n[13]=e.y,n[14]=e.z):(n[12]=e,n[13]=t,n[14]=i),this}invert(){const e=this.elements,t=e[0],i=e[1],n=e[2],a=e[3],r=e[4],s=e[5],o=e[6],l=e[7],h=e[8],c=e[9],u=e[10],d=e[11],p=e[12],m=e[13],f=e[14],g=e[15],v=c*f*l-m*u*l+m*o*d-s*f*d-c*o*g+s*u*g,y=p*u*l-h*f*l-p*o*d+r*f*d+h*o*g-r*u*g,b=h*m*l-p*c*l+p*s*d-r*m*d-h*s*g+r*c*g,M=p*c*o-h*m*o-p*s*u+r*m*u+h*s*f-r*c*f,_=t*v+i*y+n*b+a*M;if(0===_)return this.set(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);const x=1/_;return e[0]=v*x,e[1]=(m*u*a-c*f*a-m*n*d+i*f*d+c*n*g-i*u*g)*x,e[2]=(s*f*a-m*o*a+m*n*l-i*f*l-s*n*g+i*o*g)*x,e[3]=(c*o*a-s*u*a-c*n*l+i*u*l+s*n*d-i*o*d)*x,e[4]=y*x,e[5]=(h*f*a-p*u*a+p*n*d-t*f*d-h*n*g+t*u*g)*x,e[6]=(p*o*a-r*f*a-p*n*l+t*f*l+r*n*g-t*o*g)*x,e[7]=(r*u*a-h*o*a+h*n*l-t*u*l-r*n*d+t*o*d)*x,e[8]=b*x,e[9]=(p*c*a-h*m*a-p*i*d+t*m*d+h*i*g-t*c*g)*x,e[10]=(r*m*a-p*s*a+p*i*l-t*m*l-r*i*g+t*s*g)*x,e[11]=(h*s*a-r*c*a-h*i*l+t*c*l+r*i*d-t*s*d)*x,e[12]=M*x,e[13]=(h*m*n-p*c*n+p*i*u-t*m*u-h*i*f+t*c*f)*x,e[14]=(p*s*n-r*m*n-p*i*o+t*m*o+r*i*f-t*s*f)*x,e[15]=(r*c*n-h*s*n+h*i*o-t*c*o-r*i*u+t*s*u)*x,this}scale(e){const t=this.elements,i=e.x,n=e.y,a=e.z;return t[0]*=i,t[4]*=n,t[8]*=a,t[1]*=i,t[5]*=n,t[9]*=a,t[2]*=i,t[6]*=n,t[10]*=a,t[3]*=i,t[7]*=n,t[11]*=a,this}getMaxScaleOnAxis(){const e=this.elements,t=e[0]*e[0]+e[1]*e[1]+e[2]*e[2],i=e[4]*e[4]+e[5]*e[5]+e[6]*e[6],n=e[8]*e[8]+e[9]*e[9]+e[10]*e[10];return Math.sqrt(Math.max(t,i,n))}makeTranslation(e,t,i){return e.isVector3?this.set(1,0,0,e.x,0,1,0,e.y,0,0,1,e.z,0,0,0,1):this.set(1,0,0,e,0,1,0,t,0,0,1,i,0,0,0,1),this}makeRotationX(e){const t=Math.cos(e),i=Math.sin(e);return this.set(1,0,0,0,0,t,-i,0,0,i,t,0,0,0,0,1),this}makeRotationY(e){const t=Math.cos(e),i=Math.sin(e);return this.set(t,0,i,0,0,1,0,0,-i,0,t,0,0,0,0,1),this}makeRotationZ(e){const t=Math.cos(e),i=Math.sin(e);return this.set(t,-i,0,0,i,t,0,0,0,0,1,0,0,0,0,1),this}makeRotationAxis(e,t){const i=Math.cos(t),n=Math.sin(t),a=1-i,r=e.x,s=e.y,o=e.z,l=a*r,h=a*s;return this.set(l*r+i,l*s-n*o,l*o+n*s,0,l*s+n*o,h*s+i,h*o-n*r,0,l*o-n*s,h*o+n*r,a*o*o+i,0,0,0,0,1),this}makeScale(e,t,i){return this.set(e,0,0,0,0,t,0,0,0,0,i,0,0,0,0,1),this}makeShear(e,t,i,n,a,r){return this.set(1,i,a,0,e,1,r,0,t,n,1,0,0,0,0,1),this}compose(e,t,i){const n=this.elements,a=t._x,r=t._y,s=t._z,o=t._w,l=a+a,h=r+r,c=s+s,u=a*l,d=a*h,p=a*c,m=r*h,f=r*c,g=s*c,v=o*l,y=o*h,b=o*c,M=i.x,_=i.y,x=i.z;return n[0]=(1-(m+g))*M,n[1]=(d+b)*M,n[2]=(p-y)*M,n[3]=0,n[4]=(d-b)*_,n[5]=(1-(u+g))*_,n[6]=(f+v)*_,n[7]=0,n[8]=(p+y)*x,n[9]=(f-v)*x,n[10]=(1-(u+m))*x,n[11]=0,n[12]=e.x,n[13]=e.y,n[14]=e.z,n[15]=1,this}decompose(e,t,i){const n=this.elements;let a=Mi.set(n[0],n[1],n[2]).length();const r=Mi.set(n[4],n[5],n[6]).length(),s=Mi.set(n[8],n[9],n[10]).length();this.determinant()<0&&(a=-a),e.x=n[12],e.y=n[13],e.z=n[14],_i.copy(this);const o=1/a,l=1/r,h=1/s;return _i.elements[0]*=o,_i.elements[1]*=o,_i.elements[2]*=o,_i.elements[4]*=l,_i.elements[5]*=l,_i.elements[6]*=l,_i.elements[8]*=h,_i.elements[9]*=h,_i.elements[10]*=h,t.setFromRotationMatrix(_i),i.x=a,i.y=r,i.z=s,this}makePerspective(e,t,i,n,a,r,s=2e3,o=!1){const l=this.elements,h=2*a/(t-e),c=2*a/(i-n),u=(t+e)/(t-e),d=(i+n)/(i-n);let p,m;if(o)p=a/(r-a),m=r*a/(r-a);else if(s===et)p=-(r+a)/(r-a),m=-2*r*a/(r-a);else{if(s!==tt)throw new Error("THREE.Matrix4.makePerspective(): Invalid coordinate system: "+s);p=-r/(r-a),m=-r*a/(r-a)}return l[0]=h,l[4]=0,l[8]=u,l[12]=0,l[1]=0,l[5]=c,l[9]=d,l[13]=0,l[2]=0,l[6]=0,l[10]=p,l[14]=m,l[3]=0,l[7]=0,l[11]=-1,l[15]=0,this}makeOrthographic(e,t,i,n,a,r,s=2e3,o=!1){const l=this.elements,h=2/(t-e),c=2/(i-n),u=-(t+e)/(t-e),d=-(i+n)/(i-n);let p,m;if(o)p=1/(r-a),m=r/(r-a);else if(s===et)p=-2/(r-a),m=-(r+a)/(r-a);else{if(s!==tt)throw new Error("THREE.Matrix4.makeOrthographic(): Invalid coordinate system: "+s);p=-1/(r-a),m=-a/(r-a)}return l[0]=h,l[4]=0,l[8]=0,l[12]=u,l[1]=0,l[5]=c,l[9]=0,l[13]=d,l[2]=0,l[6]=0,l[10]=p,l[14]=m,l[3]=0,l[7]=0,l[11]=0,l[15]=1,this}equals(e){const t=this.elements,i=e.elements;for(let e=0;e<16;e++)if(t[e]!==i[e])return!1;return!0}fromArray(e,t=0){for(let i=0;i<16;i++)this.elements[i]=e[i+t];return this}toArray(e=[],t=0){const i=this.elements;return e[t]=i[0],e[t+1]=i[1],e[t+2]=i[2],e[t+3]=i[3],e[t+4]=i[4],e[t+5]=i[5],e[t+6]=i[6],e[t+7]=i[7],e[t+8]=i[8],e[t+9]=i[9],e[t+10]=i[10],e[t+11]=i[11],e[t+12]=i[12],e[t+13]=i[13],e[t+14]=i[14],e[t+15]=i[15],e}}const Mi=new xt,_i=new bi,xi=new xt(0,0,0),Si=new xt(1,1,1),wi=new xt,Ei=new xt,Ti=new xt,Ci=new bi,Ai=new _t;class Pi{constructor(e=0,t=0,i=0,n=Pi.DEFAULT_ORDER){this.isEuler=!0,this._x=e,this._y=t,this._z=i,this._order=n}get x(){return this._x}set x(e){this._x=e,this._onChangeCallback()}get y(){return this._y}set y(e){this._y=e,this._onChangeCallback()}get z(){return this._z}set z(e){this._z=e,this._onChangeCallback()}get order(){return this._order}set order(e){this._order=e,this._onChangeCallback()}set(e,t,i,n=this._order){return this._x=e,this._y=t,this._z=i,this._order=n,this._onChangeCallback(),this}clone(){return new this.constructor(this._x,this._y,this._z,this._order)}copy(e){return this._x=e._x,this._y=e._y,this._z=e._z,this._order=e._order,this._onChangeCallback(),this}setFromRotationMatrix(e,t=this._order,i=!0){const n=e.elements,a=n[0],r=n[4],s=n[8],o=n[1],l=n[5],h=n[9],c=n[2],u=n[6],d=n[10];switch(t){case"XYZ":this._y=Math.asin(ft(s,-1,1)),Math.abs(s)<.9999999?(this._x=Math.atan2(-h,d),this._z=Math.atan2(-r,a)):(this._x=Math.atan2(u,l),this._z=0);break;case"YXZ":this._x=Math.asin(-ft(h,-1,1)),Math.abs(h)<.9999999?(this._y=Math.atan2(s,d),this._z=Math.atan2(o,l)):(this._y=Math.atan2(-c,a),this._z=0);break;case"ZXY":this._x=Math.asin(ft(u,-1,1)),Math.abs(u)<.9999999?(this._y=Math.atan2(-c,d),this._z=Math.atan2(-r,l)):(this._y=0,this._z=Math.atan2(o,a));break;case"ZYX":this._y=Math.asin(-ft(c,-1,1)),Math.abs(c)<.9999999?(this._x=Math.atan2(u,d),this._z=Math.atan2(o,a)):(this._x=0,this._z=Math.atan2(-r,l));break;case"YZX":this._z=Math.asin(ft(o,-1,1)),Math.abs(o)<.9999999?(this._x=Math.atan2(-h,l),this._y=Math.atan2(-c,a)):(this._x=0,this._y=Math.atan2(s,d));break;case"XZY":this._z=Math.asin(-ft(r,-1,1)),Math.abs(r)<.9999999?(this._x=Math.atan2(u,l),this._y=Math.atan2(s,a)):(this._x=Math.atan2(-h,d),this._y=0);break;default:ot("Euler: .setFromRotationMatrix() encountered an unknown order: "+t)}return this._order=t,!0===i&&this._onChangeCallback(),this}setFromQuaternion(e,t,i){return Ci.makeRotationFromQuaternion(e),this.setFromRotationMatrix(Ci,t,i)}setFromVector3(e,t=this._order){return this.set(e.x,e.y,e.z,t)}reorder(e){return Ai.setFromEuler(this),this.setFromQuaternion(Ai,e)}equals(e){return e._x===this._x&&e._y===this._y&&e._z===this._z&&e._order===this._order}fromArray(e){return this._x=e[0],this._y=e[1],this._z=e[2],void 0!==e[3]&&(this._order=e[3]),this._onChangeCallback(),this}toArray(e=[],t=0){return e[t]=this._x,e[t+1]=this._y,e[t+2]=this._z,e[t+3]=this._order,e}_onChange(e){return this._onChangeCallback=e,this}_onChangeCallback(){}*[Symbol.iterator](){yield this._x,yield this._y,yield this._z,yield this._order}}Pi.DEFAULT_ORDER="XYZ";class Di{constructor(){this.mask=1}set(e){this.mask=1<<e>>>0}enable(e){this.mask|=1<<e}enableAll(){this.mask=-1}toggle(e){this.mask^=1<<e}disable(e){this.mask&=~(1<<e)}disableAll(){this.mask=0}test(e){return 0!==(this.mask&e.mask)}isEnabled(e){return!!(this.mask&1<<e)}}let Ri=0;const Ii=new xt,Li=new _t,Bi=new bi,Oi=new xt,Fi=new xt,Ui=new xt,zi=new _t,ki=new xt(1,0,0),Ni=new xt(0,1,0),Gi=new xt(0,0,1),Vi={type:"added"},Hi={type:"removed"},Wi={type:"childadded",child:null},ji={type:"childremoved",child:null};class Xi extends ct{constructor(){super(),this.isObject3D=!0,Object.defineProperty(this,"id",{value:Ri++}),this.uuid=mt(),this.name="",this.type="Object3D",this.parent=null,this.children=[],this.up=Xi.DEFAULT_UP.clone();const e=new xt,t=new Pi,i=new _t,n=new xt(1,1,1);t._onChange(function(){i.setFromEuler(t,!1)}),i._onChange(function(){t.setFromQuaternion(i,void 0,!1)}),Object.defineProperties(this,{position:{configurable:!0,enumerable:!0,value:e},rotation:{configurable:!0,enumerable:!0,value:t},quaternion:{configurable:!0,enumerable:!0,value:i},scale:{configurable:!0,enumerable:!0,value:n},modelViewMatrix:{value:new bi},normalMatrix:{value:new Et}}),this.matrix=new bi,this.matrixWorld=new bi,this.matrixAutoUpdate=Xi.DEFAULT_MATRIX_AUTO_UPDATE,this.matrixWorldAutoUpdate=Xi.DEFAULT_MATRIX_WORLD_AUTO_UPDATE,this.matrixWorldNeedsUpdate=!1,this.layers=new Di,this.visible=!0,this.castShadow=!1,this.receiveShadow=!1,this.frustumCulled=!0,this.renderOrder=0,this.animations=[],this.customDepthMaterial=void 0,this.customDistanceMaterial=void 0,this.userData={}}onBeforeShadow(){}onAfterShadow(){}onBeforeRender(){}onAfterRender(){}applyMatrix4(e){this.matrixAutoUpdate&&this.updateMatrix(),this.matrix.premultiply(e),this.matrix.decompose(this.position,this.quaternion,this.scale)}applyQuaternion(e){return this.quaternion.premultiply(e),this}setRotationFromAxisAngle(e,t){this.quaternion.setFromAxisAngle(e,t)}setRotationFromEuler(e){this.quaternion.setFromEuler(e,!0)}setRotationFromMatrix(e){this.quaternion.setFromRotationMatrix(e)}setRotationFromQuaternion(e){this.quaternion.copy(e)}rotateOnAxis(e,t){return Li.setFromAxisAngle(e,t),this.quaternion.multiply(Li),this}rotateOnWorldAxis(e,t){return Li.setFromAxisAngle(e,t),this.quaternion.premultiply(Li),this}rotateX(e){return this.rotateOnAxis(ki,e)}rotateY(e){return this.rotateOnAxis(Ni,e)}rotateZ(e){return this.rotateOnAxis(Gi,e)}translateOnAxis(e,t){return Ii.copy(e).applyQuaternion(this.quaternion),this.position.add(Ii.multiplyScalar(t)),this}translateX(e){return this.translateOnAxis(ki,e)}translateY(e){return this.translateOnAxis(Ni,e)}translateZ(e){return this.translateOnAxis(Gi,e)}localToWorld(e){return this.updateWorldMatrix(!0,!1),e.applyMatrix4(this.matrixWorld)}worldToLocal(e){return this.updateWorldMatrix(!0,!1),e.applyMatrix4(Bi.copy(this.matrixWorld).invert())}lookAt(e,t,i){e.isVector3?Oi.copy(e):Oi.set(e,t,i);const n=this.parent;this.updateWorldMatrix(!0,!1),Fi.setFromMatrixPosition(this.matrixWorld),this.isCamera||this.isLight?Bi.lookAt(Fi,Oi,this.up):Bi.lookAt(Oi,Fi,this.up),this.quaternion.setFromRotationMatrix(Bi),n&&(Bi.extractRotation(n.matrixWorld),Li.setFromRotationMatrix(Bi),this.quaternion.premultiply(Li.invert()))}add(e){if(arguments.length>1){for(let e=0;e<arguments.length;e++)this.add(arguments[e]);return this}return e===this?(lt("Object3D.add: object can't be added as a child of itself.",e),this):(e&&e.isObject3D?(e.removeFromParent(),e.parent=this,this.children.push(e),e.dispatchEvent(Vi),Wi.child=e,this.dispatchEvent(Wi),Wi.child=null):lt("Object3D.add: object not an instance of THREE.Object3D.",e),this)}remove(e){if(arguments.length>1){for(let e=0;e<arguments.length;e++)this.remove(arguments[e]);return this}const t=this.children.indexOf(e);return-1!==t&&(e.parent=null,this.children.splice(t,1),e.dispatchEvent(Hi),ji.child=e,this.dispatchEvent(ji),ji.child=null),this}removeFromParent(){const e=this.parent;return null!==e&&e.remove(this),this}clear(){return this.remove(...this.children)}attach(e){return this.updateWorldMatrix(!0,!1),Bi.copy(this.matrixWorld).invert(),null!==e.parent&&(e.parent.updateWorldMatrix(!0,!1),Bi.multiply(e.parent.matrixWorld)),e.applyMatrix4(Bi),e.removeFromParent(),e.parent=this,this.children.push(e),e.updateWorldMatrix(!1,!0),e.dispatchEvent(Vi),Wi.child=e,this.dispatchEvent(Wi),Wi.child=null,this}getObjectById(e){return this.getObjectByProperty("id",e)}getObjectByName(e){return this.getObjectByProperty("name",e)}getObjectByProperty(e,t){if(this[e]===t)return this;for(let i=0,n=this.children.length;i<n;i++){const n=this.children[i].getObjectByProperty(e,t);if(void 0!==n)return n}}getObjectsByProperty(e,t,i=[]){this[e]===t&&i.push(this);const n=this.children;for(let a=0,r=n.length;a<r;a++)n[a].getObjectsByProperty(e,t,i);return i}getWorldPosition(e){return this.updateWorldMatrix(!0,!1),e.setFromMatrixPosition(this.matrixWorld)}getWorldQuaternion(e){return this.updateWorldMatrix(!0,!1),this.matrixWorld.decompose(Fi,e,Ui),e}getWorldScale(e){return this.updateWorldMatrix(!0,!1),this.matrixWorld.decompose(Fi,zi,e),e}getWorldDirection(e){this.updateWorldMatrix(!0,!1);const t=this.matrixWorld.elements;return e.set(t[8],t[9],t[10]).normalize()}raycast(){}traverse(e){e(this);const t=this.children;for(let i=0,n=t.length;i<n;i++)t[i].traverse(e)}traverseVisible(e){if(!1===this.visible)return;e(this);const t=this.children;for(let i=0,n=t.length;i<n;i++)t[i].traverseVisible(e)}traverseAncestors(e){const t=this.parent;null!==t&&(e(t),t.traverseAncestors(e))}updateMatrix(){this.matrix.compose(this.position,this.quaternion,this.scale),this.matrixWorldNeedsUpdate=!0}updateMatrixWorld(e){this.matrixAutoUpdate&&this.updateMatrix(),(this.matrixWorldNeedsUpdate||e)&&(!0===this.matrixWorldAutoUpdate&&(null===this.parent?this.matrixWorld.copy(this.matrix):this.matrixWorld.multiplyMatrices(this.parent.matrixWorld,this.matrix)),this.matrixWorldNeedsUpdate=!1,e=!0);const t=this.children;for(let i=0,n=t.length;i<n;i++)t[i].updateMatrixWorld(e)}updateWorldMatrix(e,t){const i=this.parent;if(!0===e&&null!==i&&i.updateWorldMatrix(!0,!1),this.matrixAutoUpdate&&this.updateMatrix(),!0===this.matrixWorldAutoUpdate&&(null===this.parent?this.matrixWorld.copy(this.matrix):this.matrixWorld.multiplyMatrices(this.parent.matrixWorld,this.matrix)),!0===t){const e=this.children;for(let t=0,i=e.length;t<i;t++)e[t].updateWorldMatrix(!1,!0)}}toJSON(e){const t=void 0===e||"string"==typeof e,i={};t&&(e={geometries:{},materials:{},textures:{},images:{},shapes:{},skeletons:{},animations:{},nodes:{}},i.metadata={version:4.7,type:"Object",generator:"Object3D.toJSON"});const n={};function a(t,i){return void 0===t[i.uuid]&&(t[i.uuid]=i.toJSON(e)),i.uuid}if(n.uuid=this.uuid,n.type=this.type,""!==this.name&&(n.name=this.name),!0===this.castShadow&&(n.castShadow=!0),!0===this.receiveShadow&&(n.receiveShadow=!0),!1===this.visible&&(n.visible=!1),!1===this.frustumCulled&&(n.frustumCulled=!1),0!==this.renderOrder&&(n.renderOrder=this.renderOrder),Object.keys(this.userData).length>0&&(n.userData=this.userData),n.layers=this.layers.mask,n.matrix=this.matrix.toArray(),n.up=this.up.toArray(),!1===this.matrixAutoUpdate&&(n.matrixAutoUpdate=!1),this.isInstancedMesh&&(n.type="InstancedMesh",n.count=this.count,n.instanceMatrix=this.instanceMatrix.toJSON(),null!==this.instanceColor&&(n.instanceColor=this.instanceColor.toJSON())),this.isBatchedMesh&&(n.type="BatchedMesh",n.perObjectFrustumCulled=this.perObjectFrustumCulled,n.sortObjects=this.sortObjects,n.drawRanges=this._drawRanges,n.reservedRanges=this._reservedRanges,n.geometryInfo=this._geometryInfo.map(e=>({...e,boundingBox:e.boundingBox?e.boundingBox.toJSON():void 0,boundingSphere:e.boundingSphere?e.boundingSphere.toJSON():void 0})),n.instanceInfo=this._instanceInfo.map(e=>({...e})),n.availableInstanceIds=this._availableInstanceIds.slice(),n.availableGeometryIds=this._availableGeometryIds.slice(),n.nextIndexStart=this._nextIndexStart,n.nextVertexStart=this._nextVertexStart,n.geometryCount=this._geometryCount,n.maxInstanceCount=this._maxInstanceCount,n.maxVertexCount=this._maxVertexCount,n.maxIndexCount=this._maxIndexCount,n.geometryInitialized=this._geometryInitialized,n.matricesTexture=this._matricesTexture.toJSON(e),n.indirectTexture=this._indirectTexture.toJSON(e),null!==this._colorsTexture&&(n.colorsTexture=this._colorsTexture.toJSON(e)),null!==this.boundingSphere&&(n.boundingSphere=this.boundingSphere.toJSON()),null!==this.boundingBox&&(n.boundingBox=this.boundingBox.toJSON())),this.isScene)this.background&&(this.background.isColor?n.background=this.background.toJSON():this.background.isTexture&&(n.background=this.background.toJSON(e).uuid)),this.environment&&this.environment.isTexture&&!0!==this.environment.isRenderTargetTexture&&(n.environment=this.environment.toJSON(e).uuid);else if(this.isMesh||this.isLine||this.isPoints){n.geometry=a(e.geometries,this.geometry);const t=this.geometry.parameters;if(void 0!==t&&void 0!==t.shapes){const i=t.shapes;if(Array.isArray(i))for(let t=0,n=i.length;t<n;t++){const n=i[t];a(e.shapes,n)}else a(e.shapes,i)}}if(this.isSkinnedMesh&&(n.bindMode=this.bindMode,n.bindMatrix=this.bindMatrix.toArray(),void 0!==this.skeleton&&(a(e.skeletons,this.skeleton),n.skeleton=this.skeleton.uuid)),void 0!==this.material)if(Array.isArray(this.material)){const t=[];for(let i=0,n=this.material.length;i<n;i++)t.push(a(e.materials,this.material[i]));n.material=t}else n.material=a(e.materials,this.material);if(this.children.length>0){n.children=[];for(let t=0;t<this.children.length;t++)n.children.push(this.children[t].toJSON(e).object)}if(this.animations.length>0){n.animations=[];for(let t=0;t<this.animations.length;t++){const i=this.animations[t];n.animations.push(a(e.animations,i))}}if(t){const t=r(e.geometries),n=r(e.materials),a=r(e.textures),s=r(e.images),o=r(e.shapes),l=r(e.skeletons),h=r(e.animations),c=r(e.nodes);t.length>0&&(i.geometries=t),n.length>0&&(i.materials=n),a.length>0&&(i.textures=a),s.length>0&&(i.images=s),o.length>0&&(i.shapes=o),l.length>0&&(i.skeletons=l),h.length>0&&(i.animations=h),c.length>0&&(i.nodes=c)}return i.object=n,i;function r(e){const t=[];for(const i in e){const n=e[i];delete n.metadata,t.push(n)}return t}}clone(e){return(new this.constructor).copy(this,e)}copy(e,t=!0){if(this.name=e.name,this.up.copy(e.up),this.position.copy(e.position),this.rotation.order=e.rotation.order,this.quaternion.copy(e.quaternion),this.scale.copy(e.scale),this.matrix.copy(e.matrix),this.matrixWorld.copy(e.matrixWorld),this.matrixAutoUpdate=e.matrixAutoUpdate,this.matrixWorldAutoUpdate=e.matrixWorldAutoUpdate,this.matrixWorldNeedsUpdate=e.matrixWorldNeedsUpdate,this.layers.mask=e.layers.mask,this.visible=e.visible,this.castShadow=e.castShadow,this.receiveShadow=e.receiveShadow,this.frustumCulled=e.frustumCulled,this.renderOrder=e.renderOrder,this.animations=e.animations.slice(),this.userData=JSON.parse(JSON.stringify(e.userData)),!0===t)for(let t=0;t<e.children.length;t++){const i=e.children[t];this.add(i.clone())}return this}}Xi.DEFAULT_UP=new xt(0,1,0),Xi.DEFAULT_MATRIX_AUTO_UPDATE=!0,Xi.DEFAULT_MATRIX_WORLD_AUTO_UPDATE=!0;const qi=new xt,Yi=new xt,$i=new xt,Zi=new xt,Ki=new xt,Qi=new xt,Ji=new xt,en=new xt,tn=new xt,nn=new xt,an=new Gt,rn=new Gt,sn=new Gt;class on{constructor(e=new xt,t=new xt,i=new xt){this.a=e,this.b=t,this.c=i}static getNormal(e,t,i,n){n.subVectors(i,t),qi.subVectors(e,t),n.cross(qi);const a=n.lengthSq();return a>0?n.multiplyScalar(1/Math.sqrt(a)):n.set(0,0,0)}static getBarycoord(e,t,i,n,a){qi.subVectors(n,t),Yi.subVectors(i,t),$i.subVectors(e,t);const r=qi.dot(qi),s=qi.dot(Yi),o=qi.dot($i),l=Yi.dot(Yi),h=Yi.dot($i),c=r*l-s*s;if(0===c)return a.set(0,0,0),null;const u=1/c,d=(l*o-s*h)*u,p=(r*h-s*o)*u;return a.set(1-d-p,p,d)}static containsPoint(e,t,i,n){return null!==this.getBarycoord(e,t,i,n,Zi)&&Zi.x>=0&&Zi.y>=0&&Zi.x+Zi.y<=1}static getInterpolation(e,t,i,n,a,r,s,o){return null===this.getBarycoord(e,t,i,n,Zi)?(o.x=0,o.y=0,"z"in o&&(o.z=0),"w"in o&&(o.w=0),null):(o.setScalar(0),o.addScaledVector(a,Zi.x),o.addScaledVector(r,Zi.y),o.addScaledVector(s,Zi.z),o)}static getInterpolatedAttribute(e,t,i,n,a,r){return an.setScalar(0),rn.setScalar(0),sn.setScalar(0),an.fromBufferAttribute(e,t),rn.fromBufferAttribute(e,i),sn.fromBufferAttribute(e,n),r.setScalar(0),r.addScaledVector(an,a.x),r.addScaledVector(rn,a.y),r.addScaledVector(sn,a.z),r}static isFrontFacing(e,t,i,n){return qi.subVectors(i,t),Yi.subVectors(e,t),qi.cross(Yi).dot(n)<0}set(e,t,i){return this.a.copy(e),this.b.copy(t),this.c.copy(i),this}setFromPointsAndIndices(e,t,i,n){return this.a.copy(e[t]),this.b.copy(e[i]),this.c.copy(e[n]),this}setFromAttributeAndIndices(e,t,i,n){return this.a.fromBufferAttribute(e,t),this.b.fromBufferAttribute(e,i),this.c.fromBufferAttribute(e,n),this}clone(){return(new this.constructor).copy(this)}copy(e){return this.a.copy(e.a),this.b.copy(e.b),this.c.copy(e.c),this}getArea(){return qi.subVectors(this.c,this.b),Yi.subVectors(this.a,this.b),.5*qi.cross(Yi).length()}getMidpoint(e){return e.addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)}getNormal(e){return on.getNormal(this.a,this.b,this.c,e)}getPlane(e){return e.setFromCoplanarPoints(this.a,this.b,this.c)}getBarycoord(e,t){return on.getBarycoord(e,this.a,this.b,this.c,t)}getInterpolation(e,t,i,n,a){return on.getInterpolation(e,this.a,this.b,this.c,t,i,n,a)}containsPoint(e){return on.containsPoint(e,this.a,this.b,this.c)}isFrontFacing(e){return on.isFrontFacing(this.a,this.b,this.c,e)}intersectsBox(e){return e.intersectsTriangle(this)}closestPointToPoint(e,t){const i=this.a,n=this.b,a=this.c;let r,s;Ki.subVectors(n,i),Qi.subVectors(a,i),en.subVectors(e,i);const o=Ki.dot(en),l=Qi.dot(en);if(o<=0&&l<=0)return t.copy(i);tn.subVectors(e,n);const h=Ki.dot(tn),c=Qi.dot(tn);if(h>=0&&c<=h)return t.copy(n);const u=o*c-h*l;if(u<=0&&o>=0&&h<=0)return r=o/(o-h),t.copy(i).addScaledVector(Ki,r);nn.subVectors(e,a);const d=Ki.dot(nn),p=Qi.dot(nn);if(p>=0&&d<=p)return t.copy(a);const m=d*l-o*p;if(m<=0&&l>=0&&p<=0)return s=l/(l-p),t.copy(i).addScaledVector(Qi,s);const f=h*p-d*c;if(f<=0&&c-h>=0&&d-p>=0)return Ji.subVectors(a,n),s=(c-h)/(c-h+(d-p)),t.copy(n).addScaledVector(Ji,s);const g=1/(f+m+u);return r=m*g,s=u*g,t.copy(i).addScaledVector(Ki,r).addScaledVector(Qi,s)}equals(e){return e.a.equals(this.a)&&e.b.equals(this.b)&&e.c.equals(this.c)}}const ln={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074},hn={h:0,s:0,l:0},cn={h:0,s:0,l:0};function un(e,t,i){return i<0&&(i+=1),i>1&&(i-=1),i<1/6?e+6*(t-e)*i:i<.5?t:i<2/3?e+6*(t-e)*(2/3-i):e}class dn{constructor(e,t,i){return this.isColor=!0,this.r=1,this.g=1,this.b=1,this.set(e,t,i)}set(e,t,i){if(void 0===t&&void 0===i){const t=e;t&&t.isColor?this.copy(t):"number"==typeof t?this.setHex(t):"string"==typeof t&&this.setStyle(t)}else this.setRGB(e,t,i);return this}setScalar(e){return this.r=e,this.g=e,this.b=e,this}setHex(e,t=ze){return e=Math.floor(e),this.r=(e>>16&255)/255,this.g=(e>>8&255)/255,this.b=(255&e)/255,Dt.colorSpaceToWorking(this,t),this}setRGB(e,t,i,n=Dt.workingColorSpace){return this.r=e,this.g=t,this.b=i,Dt.colorSpaceToWorking(this,n),this}setHSL(e,t,i,n=Dt.workingColorSpace){if(e=(e%1+1)%1,t=ft(t,0,1),i=ft(i,0,1),0===t)this.r=this.g=this.b=i;else{const n=i<=.5?i*(1+t):i+t-i*t,a=2*i-n;this.r=un(a,n,e+1/3),this.g=un(a,n,e),this.b=un(a,n,e-1/3)}return Dt.colorSpaceToWorking(this,n),this}setStyle(e,t=ze){function i(t){void 0!==t&&parseFloat(t)<1&&ot("Color: Alpha component of "+e+" will be ignored.")}let n;if(n=/^(\w+)\(([^\)]*)\)/.exec(e)){let a;const r=n[1],s=n[2];switch(r){case"rgb":case"rgba":if(a=/^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(s))return i(a[4]),this.setRGB(Math.min(255,parseInt(a[1],10))/255,Math.min(255,parseInt(a[2],10))/255,Math.min(255,parseInt(a[3],10))/255,t);if(a=/^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(s))return i(a[4]),this.setRGB(Math.min(100,parseInt(a[1],10))/100,Math.min(100,parseInt(a[2],10))/100,Math.min(100,parseInt(a[3],10))/100,t);break;case"hsl":case"hsla":if(a=/^\s*(\d*\.?\d+)\s*,\s*(\d*\.?\d+)\%\s*,\s*(\d*\.?\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(s))return i(a[4]),this.setHSL(parseFloat(a[1])/360,parseFloat(a[2])/100,parseFloat(a[3])/100,t);break;default:ot("Color: Unknown color model "+e)}}else if(n=/^\#([A-Fa-f\d]+)$/.exec(e)){const i=n[1],a=i.length;if(3===a)return this.setRGB(parseInt(i.charAt(0),16)/15,parseInt(i.charAt(1),16)/15,parseInt(i.charAt(2),16)/15,t);if(6===a)return this.setHex(parseInt(i,16),t);ot("Color: Invalid hex color "+e)}else if(e&&e.length>0)return this.setColorName(e,t);return this}setColorName(e,t=ze){const i=ln[e.toLowerCase()];return void 0!==i?this.setHex(i,t):ot("Color: Unknown color "+e),this}clone(){return new this.constructor(this.r,this.g,this.b)}copy(e){return this.r=e.r,this.g=e.g,this.b=e.b,this}copySRGBToLinear(e){return this.r=Rt(e.r),this.g=Rt(e.g),this.b=Rt(e.b),this}copyLinearToSRGB(e){return this.r=It(e.r),this.g=It(e.g),this.b=It(e.b),this}convertSRGBToLinear(){return this.copySRGBToLinear(this),this}convertLinearToSRGB(){return this.copyLinearToSRGB(this),this}getHex(e=ze){return Dt.workingToColorSpace(pn.copy(this),e),65536*Math.round(ft(255*pn.r,0,255))+256*Math.round(ft(255*pn.g,0,255))+Math.round(ft(255*pn.b,0,255))}getHexString(e=ze){return("000000"+this.getHex(e).toString(16)).slice(-6)}getHSL(e,t=Dt.workingColorSpace){Dt.workingToColorSpace(pn.copy(this),t);const i=pn.r,n=pn.g,a=pn.b,r=Math.max(i,n,a),s=Math.min(i,n,a);let o,l;const h=(s+r)/2;if(s===r)o=0,l=0;else{const e=r-s;switch(l=h<=.5?e/(r+s):e/(2-r-s),r){case i:o=(n-a)/e+(n<a?6:0);break;case n:o=(a-i)/e+2;break;case a:o=(i-n)/e+4}o/=6}return e.h=o,e.s=l,e.l=h,e}getRGB(e,t=Dt.workingColorSpace){return Dt.workingToColorSpace(pn.copy(this),t),e.r=pn.r,e.g=pn.g,e.b=pn.b,e}getStyle(e=ze){Dt.workingToColorSpace(pn.copy(this),e);const t=pn.r,i=pn.g,n=pn.b;return e!==ze?`color(${e} ${t.toFixed(3)} ${i.toFixed(3)} ${n.toFixed(3)})`:`rgb(${Math.round(255*t)},${Math.round(255*i)},${Math.round(255*n)})`}offsetHSL(e,t,i){return this.getHSL(hn),this.setHSL(hn.h+e,hn.s+t,hn.l+i)}add(e){return this.r+=e.r,this.g+=e.g,this.b+=e.b,this}addColors(e,t){return this.r=e.r+t.r,this.g=e.g+t.g,this.b=e.b+t.b,this}addScalar(e){return this.r+=e,this.g+=e,this.b+=e,this}sub(e){return this.r=Math.max(0,this.r-e.r),this.g=Math.max(0,this.g-e.g),this.b=Math.max(0,this.b-e.b),this}multiply(e){return this.r*=e.r,this.g*=e.g,this.b*=e.b,this}multiplyScalar(e){return this.r*=e,this.g*=e,this.b*=e,this}lerp(e,t){return this.r+=(e.r-this.r)*t,this.g+=(e.g-this.g)*t,this.b+=(e.b-this.b)*t,this}lerpColors(e,t,i){return this.r=e.r+(t.r-e.r)*i,this.g=e.g+(t.g-e.g)*i,this.b=e.b+(t.b-e.b)*i,this}lerpHSL(e,t){this.getHSL(hn),e.getHSL(cn);const i=gt(hn.h,cn.h,t),n=gt(hn.s,cn.s,t),a=gt(hn.l,cn.l,t);return this.setHSL(i,n,a),this}setFromVector3(e){return this.r=e.x,this.g=e.y,this.b=e.z,this}applyMatrix3(e){const t=this.r,i=this.g,n=this.b,a=e.elements;return this.r=a[0]*t+a[3]*i+a[6]*n,this.g=a[1]*t+a[4]*i+a[7]*n,this.b=a[2]*t+a[5]*i+a[8]*n,this}equals(e){return e.r===this.r&&e.g===this.g&&e.b===this.b}fromArray(e,t=0){return this.r=e[t],this.g=e[t+1],this.b=e[t+2],this}toArray(e=[],t=0){return e[t]=this.r,e[t+1]=this.g,e[t+2]=this.b,e}fromBufferAttribute(e,t){return this.r=e.getX(t),this.g=e.getY(t),this.b=e.getZ(t),this}toJSON(){return this.getHex()}*[Symbol.iterator](){yield this.r,yield this.g,yield this.b}}const pn=new dn;dn.NAMES=ln;let mn=0;class fn extends ct{constructor(){super(),this.isMaterial=!0,Object.defineProperty(this,"id",{value:mn++}),this.uuid=mt(),this.name="",this.type="Material",this.blending=1,this.side=0,this.vertexColors=!1,this.opacity=1,this.transparent=!1,this.alphaHash=!1,this.blendSrc=204,this.blendDst=d,this.blendEquation=a,this.blendSrcAlpha=null,this.blendDstAlpha=null,this.blendEquationAlpha=null,this.blendColor=new dn(0,0,0),this.blendAlpha=0,this.depthFunc=3,this.depthTest=!0,this.depthWrite=!0,this.stencilWriteMask=255,this.stencilFunc=519,this.stencilRef=0,this.stencilFuncMask=255,this.stencilFail=Ve,this.stencilZFail=Ve,this.stencilZPass=Ve,this.stencilWrite=!1,this.clippingPlanes=null,this.clipIntersection=!1,this.clipShadows=!1,this.shadowSide=null,this.colorWrite=!0,this.precision=null,this.polygonOffset=!1,this.polygonOffsetFactor=0,this.polygonOffsetUnits=0,this.dithering=!1,this.alphaToCoverage=!1,this.premultipliedAlpha=!1,this.forceSinglePass=!1,this.allowOverride=!0,this.visible=!0,this.toneMapped=!0,this.userData={},this.version=0,this._alphaTest=0}get alphaTest(){return this._alphaTest}set alphaTest(e){this._alphaTest>0!=e>0&&this.version++,this._alphaTest=e}onBeforeRender(){}onBeforeCompile(){}customProgramCacheKey(){return this.onBeforeCompile.toString()}setValues(e){if(void 0!==e)for(const t in e){const i=e[t];if(void 0===i){ot(`Material: parameter '${t}' has value of undefined.`);continue}const n=this[t];void 0!==n?n&&n.isColor?n.set(i):n&&n.isVector3&&i&&i.isVector3?n.copy(i):this[t]=i:ot(`Material: '${t}' is not a property of THREE.${this.type}.`)}}toJSON(e){const t=void 0===e||"string"==typeof e;t&&(e={textures:{},images:{}});const i={metadata:{version:4.7,type:"Material",generator:"Material.toJSON"}};function n(e){const t=[];for(const i in e){const n=e[i];delete n.metadata,t.push(n)}return t}if(i.uuid=this.uuid,i.type=this.type,""!==this.name&&(i.name=this.name),this.color&&this.color.isColor&&(i.color=this.color.getHex()),void 0!==this.roughness&&(i.roughness=this.roughness),void 0!==this.metalness&&(i.metalness=this.metalness),void 0!==this.sheen&&(i.sheen=this.sheen),this.sheenColor&&this.sheenColor.isColor&&(i.sheenColor=this.sheenColor.getHex()),void 0!==this.sheenRoughness&&(i.sheenRoughness=this.sheenRoughness),this.emissive&&this.emissive.isColor&&(i.emissive=this.emissive.getHex()),void 0!==this.emissiveIntensity&&1!==this.emissiveIntensity&&(i.emissiveIntensity=this.emissiveIntensity),this.specular&&this.specular.isColor&&(i.specular=this.specular.getHex()),void 0!==this.specularIntensity&&(i.specularIntensity=this.specularIntensity),this.specularColor&&this.specularColor.isColor&&(i.specularColor=this.specularColor.getHex()),void 0!==this.shininess&&(i.shininess=this.shininess),void 0!==this.clearcoat&&(i.clearcoat=this.clearcoat),void 0!==this.clearcoatRoughness&&(i.clearcoatRoughness=this.clearcoatRoughness),this.clearcoatMap&&this.clearcoatMap.isTexture&&(i.clearcoatMap=this.clearcoatMap.toJSON(e).uuid),this.clearcoatRoughnessMap&&this.clearcoatRoughnessMap.isTexture&&(i.clearcoatRoughnessMap=this.clearcoatRoughnessMap.toJSON(e).uuid),this.clearcoatNormalMap&&this.clearcoatNormalMap.isTexture&&(i.clearcoatNormalMap=this.clearcoatNormalMap.toJSON(e).uuid,i.clearcoatNormalScale=this.clearcoatNormalScale.toArray()),this.sheenColorMap&&this.sheenColorMap.isTexture&&(i.sheenColorMap=this.sheenColorMap.toJSON(e).uuid),this.sheenRoughnessMap&&this.sheenRoughnessMap.isTexture&&(i.sheenRoughnessMap=this.sheenRoughnessMap.toJSON(e).uuid),void 0!==this.dispersion&&(i.dispersion=this.dispersion),void 0!==this.iridescence&&(i.iridescence=this.iridescence),void 0!==this.iridescenceIOR&&(i.iridescenceIOR=this.iridescenceIOR),void 0!==this.iridescenceThicknessRange&&(i.iridescenceThicknessRange=this.iridescenceThicknessRange),this.iridescenceMap&&this.iridescenceMap.isTexture&&(i.iridescenceMap=this.iridescenceMap.toJSON(e).uuid),this.iridescenceThicknessMap&&this.iridescenceThicknessMap.isTexture&&(i.iridescenceThicknessMap=this.iridescenceThicknessMap.toJSON(e).uuid),void 0!==this.anisotropy&&(i.anisotropy=this.anisotropy),void 0!==this.anisotropyRotation&&(i.anisotropyRotation=this.anisotropyRotation),this.anisotropyMap&&this.anisotropyMap.isTexture&&(i.anisotropyMap=this.anisotropyMap.toJSON(e).uuid),this.map&&this.map.isTexture&&(i.map=this.map.toJSON(e).uuid),this.matcap&&this.matcap.isTexture&&(i.matcap=this.matcap.toJSON(e).uuid),this.alphaMap&&this.alphaMap.isTexture&&(i.alphaMap=this.alphaMap.toJSON(e).uuid),this.lightMap&&this.lightMap.isTexture&&(i.lightMap=this.lightMap.toJSON(e).uuid,i.lightMapIntensity=this.lightMapIntensity),this.aoMap&&this.aoMap.isTexture&&(i.aoMap=this.aoMap.toJSON(e).uuid,i.aoMapIntensity=this.aoMapIntensity),this.bumpMap&&this.bumpMap.isTexture&&(i.bumpMap=this.bumpMap.toJSON(e).uuid,i.bumpScale=this.bumpScale),this.normalMap&&this.normalMap.isTexture&&(i.normalMap=this.normalMap.toJSON(e).uuid,i.normalMapType=this.normalMapType,i.normalScale=this.normalScale.toArray()),this.displacementMap&&this.displacementMap.isTexture&&(i.displacementMap=this.displacementMap.toJSON(e).uuid,i.displacementScale=this.displacementScale,i.displacementBias=this.displacementBias),this.roughnessMap&&this.roughnessMap.isTexture&&(i.roughnessMap=this.roughnessMap.toJSON(e).uuid),this.metalnessMap&&this.metalnessMap.isTexture&&(i.metalnessMap=this.metalnessMap.toJSON(e).uuid),this.emissiveMap&&this.emissiveMap.isTexture&&(i.emissiveMap=this.emissiveMap.toJSON(e).uuid),this.specularMap&&this.specularMap.isTexture&&(i.specularMap=this.specularMap.toJSON(e).uuid),this.specularIntensityMap&&this.specularIntensityMap.isTexture&&(i.specularIntensityMap=this.specularIntensityMap.toJSON(e).uuid),this.specularColorMap&&this.specularColorMap.isTexture&&(i.specularColorMap=this.specularColorMap.toJSON(e).uuid),this.envMap&&this.envMap.isTexture&&(i.envMap=this.envMap.toJSON(e).uuid,void 0!==this.combine&&(i.combine=this.combine)),void 0!==this.envMapRotation&&(i.envMapRotation=this.envMapRotation.toArray()),void 0!==this.envMapIntensity&&(i.envMapIntensity=this.envMapIntensity),void 0!==this.reflectivity&&(i.reflectivity=this.reflectivity),void 0!==this.refractionRatio&&(i.refractionRatio=this.refractionRatio),this.gradientMap&&this.gradientMap.isTexture&&(i.gradientMap=this.gradientMap.toJSON(e).uuid),void 0!==this.transmission&&(i.transmission=this.transmission),this.transmissionMap&&this.transmissionMap.isTexture&&(i.transmissionMap=this.transmissionMap.toJSON(e).uuid),void 0!==this.thickness&&(i.thickness=this.thickness),this.thicknessMap&&this.thicknessMap.isTexture&&(i.thicknessMap=this.thicknessMap.toJSON(e).uuid),void 0!==this.attenuationDistance&&this.attenuationDistance!==1/0&&(i.attenuationDistance=this.attenuationDistance),void 0!==this.attenuationColor&&(i.attenuationColor=this.attenuationColor.getHex()),void 0!==this.size&&(i.size=this.size),null!==this.shadowSide&&(i.shadowSide=this.shadowSide),void 0!==this.sizeAttenuation&&(i.sizeAttenuation=this.sizeAttenuation),1!==this.blending&&(i.blending=this.blending),0!==this.side&&(i.side=this.side),!0===this.vertexColors&&(i.vertexColors=!0),this.opacity<1&&(i.opacity=this.opacity),!0===this.transparent&&(i.transparent=!0),204!==this.blendSrc&&(i.blendSrc=this.blendSrc),this.blendDst!==d&&(i.blendDst=this.blendDst),this.blendEquation!==a&&(i.blendEquation=this.blendEquation),null!==this.blendSrcAlpha&&(i.blendSrcAlpha=this.blendSrcAlpha),null!==this.blendDstAlpha&&(i.blendDstAlpha=this.blendDstAlpha),null!==this.blendEquationAlpha&&(i.blendEquationAlpha=this.blendEquationAlpha),this.blendColor&&this.blendColor.isColor&&(i.blendColor=this.blendColor.getHex()),0!==this.blendAlpha&&(i.blendAlpha=this.blendAlpha),3!==this.depthFunc&&(i.depthFunc=this.depthFunc),!1===this.depthTest&&(i.depthTest=this.depthTest),!1===this.depthWrite&&(i.depthWrite=this.depthWrite),!1===this.colorWrite&&(i.colorWrite=this.colorWrite),255!==this.stencilWriteMask&&(i.stencilWriteMask=this.stencilWriteMask),519!==this.stencilFunc&&(i.stencilFunc=this.stencilFunc),0!==this.stencilRef&&(i.stencilRef=this.stencilRef),255!==this.stencilFuncMask&&(i.stencilFuncMask=this.stencilFuncMask),this.stencilFail!==Ve&&(i.stencilFail=this.stencilFail),this.stencilZFail!==Ve&&(i.stencilZFail=this.stencilZFail),this.stencilZPass!==Ve&&(i.stencilZPass=this.stencilZPass),!0===this.stencilWrite&&(i.stencilWrite=this.stencilWrite),void 0!==this.rotation&&0!==this.rotation&&(i.rotation=this.rotation),!0===this.polygonOffset&&(i.polygonOffset=!0),0!==this.polygonOffsetFactor&&(i.polygonOffsetFactor=this.polygonOffsetFactor),0!==this.polygonOffsetUnits&&(i.polygonOffsetUnits=this.polygonOffsetUnits),void 0!==this.linewidth&&1!==this.linewidth&&(i.linewidth=this.linewidth),void 0!==this.dashSize&&(i.dashSize=this.dashSize),void 0!==this.gapSize&&(i.gapSize=this.gapSize),void 0!==this.scale&&(i.scale=this.scale),!0===this.dithering&&(i.dithering=!0),this.alphaTest>0&&(i.alphaTest=this.alphaTest),!0===this.alphaHash&&(i.alphaHash=!0),!0===this.alphaToCoverage&&(i.alphaToCoverage=!0),!0===this.premultipliedAlpha&&(i.premultipliedAlpha=!0),!0===this.forceSinglePass&&(i.forceSinglePass=!0),!0===this.wireframe&&(i.wireframe=!0),this.wireframeLinewidth>1&&(i.wireframeLinewidth=this.wireframeLinewidth),"round"!==this.wireframeLinecap&&(i.wireframeLinecap=this.wireframeLinecap),"round"!==this.wireframeLinejoin&&(i.wireframeLinejoin=this.wireframeLinejoin),!0===this.flatShading&&(i.flatShading=!0),!1===this.visible&&(i.visible=!1),!1===this.toneMapped&&(i.toneMapped=!1),!1===this.fog&&(i.fog=!1),Object.keys(this.userData).length>0&&(i.userData=this.userData),t){const t=n(e.textures),a=n(e.images);t.length>0&&(i.textures=t),a.length>0&&(i.images=a)}return i}clone(){return(new this.constructor).copy(this)}copy(e){this.name=e.name,this.blending=e.blending,this.side=e.side,this.vertexColors=e.vertexColors,this.opacity=e.opacity,this.transparent=e.transparent,this.blendSrc=e.blendSrc,this.blendDst=e.blendDst,this.blendEquation=e.blendEquation,this.blendSrcAlpha=e.blendSrcAlpha,this.blendDstAlpha=e.blendDstAlpha,this.blendEquationAlpha=e.blendEquationAlpha,this.blendColor.copy(e.blendColor),this.blendAlpha=e.blendAlpha,this.depthFunc=e.depthFunc,this.depthTest=e.depthTest,this.depthWrite=e.depthWrite,this.stencilWriteMask=e.stencilWriteMask,this.stencilFunc=e.stencilFunc,this.stencilRef=e.stencilRef,this.stencilFuncMask=e.stencilFuncMask,this.stencilFail=e.stencilFail,this.stencilZFail=e.stencilZFail,this.stencilZPass=e.stencilZPass,this.stencilWrite=e.stencilWrite;const t=e.clippingPlanes;let i=null;if(null!==t){const e=t.length;i=new Array(e);for(let n=0;n!==e;++n)i[n]=t[n].clone()}return this.clippingPlanes=i,this.clipIntersection=e.clipIntersection,this.clipShadows=e.clipShadows,this.shadowSide=e.shadowSide,this.colorWrite=e.colorWrite,this.precision=e.precision,this.polygonOffset=e.polygonOffset,this.polygonOffsetFactor=e.polygonOffsetFactor,this.polygonOffsetUnits=e.polygonOffsetUnits,this.dithering=e.dithering,this.alphaTest=e.alphaTest,this.alphaHash=e.alphaHash,this.alphaToCoverage=e.alphaToCoverage,this.premultipliedAlpha=e.premultipliedAlpha,this.forceSinglePass=e.forceSinglePass,this.visible=e.visible,this.toneMapped=e.toneMapped,this.userData=JSON.parse(JSON.stringify(e.userData)),this}dispose(){this.dispatchEvent({type:"dispose"})}set needsUpdate(e){!0===e&&this.version++}}class gn extends fn{constructor(e){super(),this.isMeshBasicMaterial=!0,this.type="MeshBasicMaterial",this.color=new dn(16777215),this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.specularMap=null,this.alphaMap=null,this.envMap=null,this.envMapRotation=new Pi,this.combine=0,this.reflectivity=1,this.refractionRatio=.98,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.fog=!0,this.setValues(e)}copy(e){return super.copy(e),this.color.copy(e.color),this.map=e.map,this.lightMap=e.lightMap,this.lightMapIntensity=e.lightMapIntensity,this.aoMap=e.aoMap,this.aoMapIntensity=e.aoMapIntensity,this.specularMap=e.specularMap,this.alphaMap=e.alphaMap,this.envMap=e.envMap,this.envMapRotation.copy(e.envMapRotation),this.combine=e.combine,this.reflectivity=e.reflectivity,this.refractionRatio=e.refractionRatio,this.wireframe=e.wireframe,this.wireframeLinewidth=e.wireframeLinewidth,this.wireframeLinecap=e.wireframeLinecap,this.wireframeLinejoin=e.wireframeLinejoin,this.fog=e.fog,this}}const vn=yn();function yn(){const e=new ArrayBuffer(4),t=new Float32Array(e),i=new Uint32Array(e),n=new Uint32Array(512),a=new Uint32Array(512);for(let e=0;e<256;++e){const t=e-127;t<-27?(n[e]=0,n[256|e]=32768,a[e]=24,a[256|e]=24):t<-14?(n[e]=1024>>-t-14,n[256|e]=1024>>-t-14|32768,a[e]=-t-1,a[256|e]=-t-1):t<=15?(n[e]=t+15<<10,n[256|e]=t+15<<10|32768,a[e]=13,a[256|e]=13):t<128?(n[e]=31744,n[256|e]=64512,a[e]=24,a[256|e]=24):(n[e]=31744,n[256|e]=64512,a[e]=13,a[256|e]=13)}const r=new Uint32Array(2048),s=new Uint32Array(64),o=new Uint32Array(64);for(let e=1;e<1024;++e){let t=e<<13,i=0;for(;!(8388608&t);)t<<=1,i-=8388608;t&=-8388609,i+=947912704,r[e]=t|i}for(let e=1024;e<2048;++e)r[e]=939524096+(e-1024<<13);for(let e=1;e<31;++e)s[e]=e<<23;s[31]=1199570944,s[32]=2147483648;for(let e=33;e<63;++e)s[e]=2147483648+(e-32<<23);s[63]=3347054592;for(let e=1;e<64;++e)32!==e&&(o[e]=1024);return{floatView:t,uint32View:i,baseTable:n,shiftTable:a,mantissaTable:r,exponentTable:s,offsetTable:o}}class bn{static toHalfFloat(e){return function(e){Math.abs(e)>65504&&ot("DataUtils.toHalfFloat(): Value out of range."),e=ft(e,-65504,65504),vn.floatView[0]=e;const t=vn.uint32View[0],i=t>>23&511;return vn.baseTable[i]+((8388607&t)>>vn.shiftTable[i])}(e)}static fromHalfFloat(e){return function(e){const t=e>>10;return vn.uint32View[0]=vn.mantissaTable[vn.offsetTable[t]+(1023&e)]+vn.exponentTable[t],vn.floatView[0]}(e)}}const Mn=new xt,_n=new Mt;let xn=0;class Sn{constructor(e,t,i=!1){if(Array.isArray(e))throw new TypeError("THREE.BufferAttribute: array should be a Typed Array.");this.isBufferAttribute=!0,Object.defineProperty(this,"id",{value:xn++}),this.name="",this.array=e,this.itemSize=t,this.count=void 0!==e?e.length/t:0,this.normalized=i,this.usage=Ke,this.updateRanges=[],this.gpuType=q,this.version=0}onUploadCallback(){}set needsUpdate(e){!0===e&&this.version++}setUsage(e){return this.usage=e,this}addUpdateRange(e,t){this.updateRanges.push({start:e,count:t})}clearUpdateRanges(){this.updateRanges.length=0}copy(e){return this.name=e.name,this.array=new e.array.constructor(e.array),this.itemSize=e.itemSize,this.count=e.count,this.normalized=e.normalized,this.usage=e.usage,this.gpuType=e.gpuType,this}copyAt(e,t,i){e*=this.itemSize,i*=t.itemSize;for(let n=0,a=this.itemSize;n<a;n++)this.array[e+n]=t.array[i+n];return this}copyArray(e){return this.array.set(e),this}applyMatrix3(e){if(2===this.itemSize)for(let t=0,i=this.count;t<i;t++)_n.fromBufferAttribute(this,t),_n.applyMatrix3(e),this.setXY(t,_n.x,_n.y);else if(3===this.itemSize)for(let t=0,i=this.count;t<i;t++)Mn.fromBufferAttribute(this,t),Mn.applyMatrix3(e),this.setXYZ(t,Mn.x,Mn.y,Mn.z);return this}applyMatrix4(e){for(let t=0,i=this.count;t<i;t++)Mn.fromBufferAttribute(this,t),Mn.applyMatrix4(e),this.setXYZ(t,Mn.x,Mn.y,Mn.z);return this}applyNormalMatrix(e){for(let t=0,i=this.count;t<i;t++)Mn.fromBufferAttribute(this,t),Mn.applyNormalMatrix(e),this.setXYZ(t,Mn.x,Mn.y,Mn.z);return this}transformDirection(e){for(let t=0,i=this.count;t<i;t++)Mn.fromBufferAttribute(this,t),Mn.transformDirection(e),this.setXYZ(t,Mn.x,Mn.y,Mn.z);return this}set(e,t=0){return this.array.set(e,t),this}getComponent(e,t){let i=this.array[e*this.itemSize+t];return this.normalized&&(i=vt(i,this.array)),i}setComponent(e,t,i){return this.normalized&&(i=yt(i,this.array)),this.array[e*this.itemSize+t]=i,this}getX(e){let t=this.array[e*this.itemSize];return this.normalized&&(t=vt(t,this.array)),t}setX(e,t){return this.normalized&&(t=yt(t,this.array)),this.array[e*this.itemSize]=t,this}getY(e){let t=this.array[e*this.itemSize+1];return this.normalized&&(t=vt(t,this.array)),t}setY(e,t){return this.normalized&&(t=yt(t,this.array)),this.array[e*this.itemSize+1]=t,this}getZ(e){let t=this.array[e*this.itemSize+2];return this.normalized&&(t=vt(t,this.array)),t}setZ(e,t){return this.normalized&&(t=yt(t,this.array)),this.array[e*this.itemSize+2]=t,this}getW(e){let t=this.array[e*this.itemSize+3];return this.normalized&&(t=vt(t,this.array)),t}setW(e,t){return this.normalized&&(t=yt(t,this.array)),this.array[e*this.itemSize+3]=t,this}setXY(e,t,i){return e*=this.itemSize,this.normalized&&(t=yt(t,this.array),i=yt(i,this.array)),this.array[e+0]=t,this.array[e+1]=i,this}setXYZ(e,t,i,n){return e*=this.itemSize,this.normalized&&(t=yt(t,this.array),i=yt(i,this.array),n=yt(n,this.array)),this.array[e+0]=t,this.array[e+1]=i,this.array[e+2]=n,this}setXYZW(e,t,i,n,a){return e*=this.itemSize,this.normalized&&(t=yt(t,this.array),i=yt(i,this.array),n=yt(n,this.array),a=yt(a,this.array)),this.array[e+0]=t,this.array[e+1]=i,this.array[e+2]=n,this.array[e+3]=a,this}onUpload(e){return this.onUploadCallback=e,this}clone(){return new this.constructor(this.array,this.itemSize).copy(this)}toJSON(){const e={itemSize:this.itemSize,type:this.array.constructor.name,array:Array.from(this.array),normalized:this.normalized};return""!==this.name&&(e.name=this.name),this.usage!==Ke&&(e.usage=this.usage),e}}class wn extends Sn{constructor(e,t,i){super(new Uint16Array(e),t,i)}}class En extends Sn{constructor(e,t,i){super(new Uint32Array(e),t,i)}}class Tn extends Sn{constructor(e,t,i){super(new Float32Array(e),t,i)}}let Cn=0;const An=new bi,Pn=new Xi,Dn=new xt,Rn=new Xt,In=new Xt,Ln=new xt;class Bn extends ct{constructor(){super(),this.isBufferGeometry=!0,Object.defineProperty(this,"id",{value:Cn++}),this.uuid=mt(),this.name="",this.type="BufferGeometry",this.index=null,this.indirect=null,this.attributes={},this.morphAttributes={},this.morphTargetsRelative=!1,this.groups=[],this.boundingBox=null,this.boundingSphere=null,this.drawRange={start:0,count:1/0},this.userData={}}getIndex(){return this.index}setIndex(e){return Array.isArray(e)?this.index=new(it(e)?En:wn)(e,1):this.index=e,this}setIndirect(e){return this.indirect=e,this}getIndirect(){return this.indirect}getAttribute(e){return this.attributes[e]}setAttribute(e,t){return this.attributes[e]=t,this}deleteAttribute(e){return delete this.attributes[e],this}hasAttribute(e){return void 0!==this.attributes[e]}addGroup(e,t,i=0){this.groups.push({start:e,count:t,materialIndex:i})}clearGroups(){this.groups=[]}setDrawRange(e,t){this.drawRange.start=e,this.drawRange.count=t}applyMatrix4(e){const t=this.attributes.position;void 0!==t&&(t.applyMatrix4(e),t.needsUpdate=!0);const i=this.attributes.normal;if(void 0!==i){const t=(new Et).getNormalMatrix(e);i.applyNormalMatrix(t),i.needsUpdate=!0}const n=this.attributes.tangent;return void 0!==n&&(n.transformDirection(e),n.needsUpdate=!0),null!==this.boundingBox&&this.computeBoundingBox(),null!==this.boundingSphere&&this.computeBoundingSphere(),this}applyQuaternion(e){return An.makeRotationFromQuaternion(e),this.applyMatrix4(An),this}rotateX(e){return An.makeRotationX(e),this.applyMatrix4(An),this}rotateY(e){return An.makeRotationY(e),this.applyMatrix4(An),this}rotateZ(e){return An.makeRotationZ(e),this.applyMatrix4(An),this}translate(e,t,i){return An.makeTranslation(e,t,i),this.applyMatrix4(An),this}scale(e,t,i){return An.makeScale(e,t,i),this.applyMatrix4(An),this}lookAt(e){return Pn.lookAt(e),Pn.updateMatrix(),this.applyMatrix4(Pn.matrix),this}center(){return this.computeBoundingBox(),this.boundingBox.getCenter(Dn).negate(),this.translate(Dn.x,Dn.y,Dn.z),this}setFromPoints(e){const t=this.getAttribute("position");if(void 0===t){const t=[];for(let i=0,n=e.length;i<n;i++){const n=e[i];t.push(n.x,n.y,n.z||0)}this.setAttribute("position",new Tn(t,3))}else{const i=Math.min(e.length,t.count);for(let n=0;n<i;n++){const i=e[n];t.setXYZ(n,i.x,i.y,i.z||0)}e.length>t.count&&ot("BufferGeometry: Buffer size too small for points data. Use .dispose() and create a new geometry."),t.needsUpdate=!0}return this}computeBoundingBox(){null===this.boundingBox&&(this.boundingBox=new Xt);const e=this.attributes.position,t=this.morphAttributes.position;if(e&&e.isGLBufferAttribute)return lt("BufferGeometry.computeBoundingBox(): GLBufferAttribute requires a manual bounding box.",this),void this.boundingBox.set(new xt(-1/0,-1/0,-1/0),new xt(1/0,1/0,1/0));if(void 0!==e){if(this.boundingBox.setFromBufferAttribute(e),t)for(let e=0,i=t.length;e<i;e++){const i=t[e];Rn.setFromBufferAttribute(i),this.morphTargetsRelative?(Ln.addVectors(this.boundingBox.min,Rn.min),this.boundingBox.expandByPoint(Ln),Ln.addVectors(this.boundingBox.max,Rn.max),this.boundingBox.expandByPoint(Ln)):(this.boundingBox.expandByPoint(Rn.min),this.boundingBox.expandByPoint(Rn.max))}}else this.boundingBox.makeEmpty();(isNaN(this.boundingBox.min.x)||isNaN(this.boundingBox.min.y)||isNaN(this.boundingBox.min.z))&&lt('BufferGeometry.computeBoundingBox(): Computed min/max have NaN values. The "position" attribute is likely to have NaN values.',this)}computeBoundingSphere(){null===this.boundingSphere&&(this.boundingSphere=new ci);const e=this.attributes.position,t=this.morphAttributes.position;if(e&&e.isGLBufferAttribute)return lt("BufferGeometry.computeBoundingSphere(): GLBufferAttribute requires a manual bounding sphere.",this),void this.boundingSphere.set(new xt,1/0);if(e){const i=this.boundingSphere.center;if(Rn.setFromBufferAttribute(e),t)for(let e=0,i=t.length;e<i;e++){const i=t[e];In.setFromBufferAttribute(i),this.morphTargetsRelative?(Ln.addVectors(Rn.min,In.min),Rn.expandByPoint(Ln),Ln.addVectors(Rn.max,In.max),Rn.expandByPoint(Ln)):(Rn.expandByPoint(In.min),Rn.expandByPoint(In.max))}Rn.getCenter(i);let n=0;for(let t=0,a=e.count;t<a;t++)Ln.fromBufferAttribute(e,t),n=Math.max(n,i.distanceToSquared(Ln));if(t)for(let a=0,r=t.length;a<r;a++){const r=t[a],s=this.morphTargetsRelative;for(let t=0,a=r.count;t<a;t++)Ln.fromBufferAttribute(r,t),s&&(Dn.fromBufferAttribute(e,t),Ln.add(Dn)),n=Math.max(n,i.distanceToSquared(Ln))}this.boundingSphere.radius=Math.sqrt(n),isNaN(this.boundingSphere.radius)&&lt('BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.',this)}}computeTangents(){const e=this.index,t=this.attributes;if(null===e||void 0===t.position||void 0===t.normal||void 0===t.uv)return void lt("BufferGeometry: .computeTangents() failed. Missing required attributes (index, position, normal or uv)");const i=t.position,n=t.normal,a=t.uv;!1===this.hasAttribute("tangent")&&this.setAttribute("tangent",new Sn(new Float32Array(4*i.count),4));const r=this.getAttribute("tangent"),s=[],o=[];for(let e=0;e<i.count;e++)s[e]=new xt,o[e]=new xt;const l=new xt,h=new xt,c=new xt,u=new Mt,d=new Mt,p=new Mt,m=new xt,f=new xt;function g(e,t,n){l.fromBufferAttribute(i,e),h.fromBufferAttribute(i,t),c.fromBufferAttribute(i,n),u.fromBufferAttribute(a,e),d.fromBufferAttribute(a,t),p.fromBufferAttribute(a,n),h.sub(l),c.sub(l),d.sub(u),p.sub(u);const r=1/(d.x*p.y-p.x*d.y);isFinite(r)&&(m.copy(h).multiplyScalar(p.y).addScaledVector(c,-d.y).multiplyScalar(r),f.copy(c).multiplyScalar(d.x).addScaledVector(h,-p.x).multiplyScalar(r),s[e].add(m),s[t].add(m),s[n].add(m),o[e].add(f),o[t].add(f),o[n].add(f))}let v=this.groups;0===v.length&&(v=[{start:0,count:e.count}]);for(let t=0,i=v.length;t<i;++t){const i=v[t],n=i.start;for(let t=n,a=n+i.count;t<a;t+=3)g(e.getX(t+0),e.getX(t+1),e.getX(t+2))}const y=new xt,b=new xt,M=new xt,_=new xt;function x(e){M.fromBufferAttribute(n,e),_.copy(M);const t=s[e];y.copy(t),y.sub(M.multiplyScalar(M.dot(t))).normalize(),b.crossVectors(_,t);const i=b.dot(o[e])<0?-1:1;r.setXYZW(e,y.x,y.y,y.z,i)}for(let t=0,i=v.length;t<i;++t){const i=v[t],n=i.start;for(let t=n,a=n+i.count;t<a;t+=3)x(e.getX(t+0)),x(e.getX(t+1)),x(e.getX(t+2))}}computeVertexNormals(){const e=this.index,t=this.getAttribute("position");if(void 0!==t){let i=this.getAttribute("normal");if(void 0===i)i=new Sn(new Float32Array(3*t.count),3),this.setAttribute("normal",i);else for(let e=0,t=i.count;e<t;e++)i.setXYZ(e,0,0,0);const n=new xt,a=new xt,r=new xt,s=new xt,o=new xt,l=new xt,h=new xt,c=new xt;if(e)for(let u=0,d=e.count;u<d;u+=3){const d=e.getX(u+0),p=e.getX(u+1),m=e.getX(u+2);n.fromBufferAttribute(t,d),a.fromBufferAttribute(t,p),r.fromBufferAttribute(t,m),h.subVectors(r,a),c.subVectors(n,a),h.cross(c),s.fromBufferAttribute(i,d),o.fromBufferAttribute(i,p),l.fromBufferAttribute(i,m),s.add(h),o.add(h),l.add(h),i.setXYZ(d,s.x,s.y,s.z),i.setXYZ(p,o.x,o.y,o.z),i.setXYZ(m,l.x,l.y,l.z)}else for(let e=0,s=t.count;e<s;e+=3)n.fromBufferAttribute(t,e+0),a.fromBufferAttribute(t,e+1),r.fromBufferAttribute(t,e+2),h.subVectors(r,a),c.subVectors(n,a),h.cross(c),i.setXYZ(e+0,h.x,h.y,h.z),i.setXYZ(e+1,h.x,h.y,h.z),i.setXYZ(e+2,h.x,h.y,h.z);this.normalizeNormals(),i.needsUpdate=!0}}normalizeNormals(){const e=this.attributes.normal;for(let t=0,i=e.count;t<i;t++)Ln.fromBufferAttribute(e,t),Ln.normalize(),e.setXYZ(t,Ln.x,Ln.y,Ln.z)}toNonIndexed(){function e(e,t){const i=e.array,n=e.itemSize,a=e.normalized,r=new i.constructor(t.length*n);let s=0,o=0;for(let a=0,l=t.length;a<l;a++){s=e.isInterleavedBufferAttribute?t[a]*e.data.stride+e.offset:t[a]*n;for(let e=0;e<n;e++)r[o++]=i[s++]}return new Sn(r,n,a)}if(null===this.index)return ot("BufferGeometry.toNonIndexed(): BufferGeometry is already non-indexed."),this;const t=new Bn,i=this.index.array,n=this.attributes;for(const a in n){const r=e(n[a],i);t.setAttribute(a,r)}const a=this.morphAttributes;for(const n in a){const r=[],s=a[n];for(let t=0,n=s.length;t<n;t++){const n=e(s[t],i);r.push(n)}t.morphAttributes[n]=r}t.morphTargetsRelative=this.morphTargetsRelative;const r=this.groups;for(let e=0,i=r.length;e<i;e++){const i=r[e];t.addGroup(i.start,i.count,i.materialIndex)}return t}toJSON(){const e={metadata:{version:4.7,type:"BufferGeometry",generator:"BufferGeometry.toJSON"}};if(e.uuid=this.uuid,e.type=this.type,""!==this.name&&(e.name=this.name),Object.keys(this.userData).length>0&&(e.userData=this.userData),void 0!==this.parameters){const t=this.parameters;for(const i in t)void 0!==t[i]&&(e[i]=t[i]);return e}e.data={attributes:{}};const t=this.index;null!==t&&(e.data.index={type:t.array.constructor.name,array:Array.prototype.slice.call(t.array)});const i=this.attributes;for(const t in i){const n=i[t];e.data.attributes[t]=n.toJSON(e.data)}const n={};let a=!1;for(const t in this.morphAttributes){const i=this.morphAttributes[t],r=[];for(let t=0,n=i.length;t<n;t++){const n=i[t];r.push(n.toJSON(e.data))}r.length>0&&(n[t]=r,a=!0)}a&&(e.data.morphAttributes=n,e.data.morphTargetsRelative=this.morphTargetsRelative);const r=this.groups;r.length>0&&(e.data.groups=JSON.parse(JSON.stringify(r)));const s=this.boundingSphere;return null!==s&&(e.data.boundingSphere=s.toJSON()),e}clone(){return(new this.constructor).copy(this)}copy(e){this.index=null,this.attributes={},this.morphAttributes={},this.groups=[],this.boundingBox=null,this.boundingSphere=null;const t={};this.name=e.name;const i=e.index;null!==i&&this.setIndex(i.clone());const n=e.attributes;for(const e in n){const i=n[e];this.setAttribute(e,i.clone(t))}const a=e.morphAttributes;for(const e in a){const i=[],n=a[e];for(let e=0,a=n.length;e<a;e++)i.push(n[e].clone(t));this.morphAttributes[e]=i}this.morphTargetsRelative=e.morphTargetsRelative;const r=e.groups;for(let e=0,t=r.length;e<t;e++){const t=r[e];this.addGroup(t.start,t.count,t.materialIndex)}const s=e.boundingBox;null!==s&&(this.boundingBox=s.clone());const o=e.boundingSphere;return null!==o&&(this.boundingSphere=o.clone()),this.drawRange.start=e.drawRange.start,this.drawRange.count=e.drawRange.count,this.userData=e.userData,this}dispose(){this.dispatchEvent({type:"dispose"})}}const On=new bi,Fn=new yi,Un=new ci,zn=new xt,kn=new xt,Nn=new xt,Gn=new xt,Vn=new xt,Hn=new xt,Wn=new xt,jn=new xt;class Xn extends Xi{constructor(e=new Bn,t=new gn){super(),this.isMesh=!0,this.type="Mesh",this.geometry=e,this.material=t,this.morphTargetDictionary=void 0,this.morphTargetInfluences=void 0,this.count=1,this.updateMorphTargets()}copy(e,t){return super.copy(e,t),void 0!==e.morphTargetInfluences&&(this.morphTargetInfluences=e.morphTargetInfluences.slice()),void 0!==e.morphTargetDictionary&&(this.morphTargetDictionary=Object.assign({},e.morphTargetDictionary)),this.material=Array.isArray(e.material)?e.material.slice():e.material,this.geometry=e.geometry,this}updateMorphTargets(){const e=this.geometry.morphAttributes,t=Object.keys(e);if(t.length>0){const i=e[t[0]];if(void 0!==i){this.morphTargetInfluences=[],this.morphTargetDictionary={};for(let e=0,t=i.length;e<t;e++){const t=i[e].name||String(e);this.morphTargetInfluences.push(0),this.morphTargetDictionary[t]=e}}}}getVertexPosition(e,t){const i=this.geometry,n=i.attributes.position,a=i.morphAttributes.position,r=i.morphTargetsRelative;t.fromBufferAttribute(n,e);const s=this.morphTargetInfluences;if(a&&s){Hn.set(0,0,0);for(let i=0,n=a.length;i<n;i++){const n=s[i],o=a[i];0!==n&&(Vn.fromBufferAttribute(o,e),r?Hn.addScaledVector(Vn,n):Hn.addScaledVector(Vn.sub(t),n))}t.add(Hn)}return t}raycast(e,t){const i=this.geometry,n=this.material,a=this.matrixWorld;if(void 0!==n){if(null===i.boundingSphere&&i.computeBoundingSphere(),Un.copy(i.boundingSphere),Un.applyMatrix4(a),Fn.copy(e.ray).recast(e.near),!1===Un.containsPoint(Fn.origin)){if(null===Fn.intersectSphere(Un,zn))return;if(Fn.origin.distanceToSquared(zn)>(e.far-e.near)**2)return}On.copy(a).invert(),Fn.copy(e.ray).applyMatrix4(On),null!==i.boundingBox&&!1===Fn.intersectsBox(i.boundingBox)||this._computeIntersections(e,t,Fn)}}_computeIntersections(e,t,i){let n;const a=this.geometry,r=this.material,s=a.index,o=a.attributes.position,l=a.attributes.uv,h=a.attributes.uv1,c=a.attributes.normal,u=a.groups,d=a.drawRange;if(null!==s)if(Array.isArray(r))for(let a=0,o=u.length;a<o;a++){const o=u[a],p=r[o.materialIndex];for(let a=Math.max(o.start,d.start),r=Math.min(s.count,Math.min(o.start+o.count,d.start+d.count));a<r;a+=3)n=qn(this,p,e,i,l,h,c,s.getX(a),s.getX(a+1),s.getX(a+2)),n&&(n.faceIndex=Math.floor(a/3),n.face.materialIndex=o.materialIndex,t.push(n))}else for(let a=Math.max(0,d.start),o=Math.min(s.count,d.start+d.count);a<o;a+=3)n=qn(this,r,e,i,l,h,c,s.getX(a),s.getX(a+1),s.getX(a+2)),n&&(n.faceIndex=Math.floor(a/3),t.push(n));else if(void 0!==o)if(Array.isArray(r))for(let a=0,s=u.length;a<s;a++){const s=u[a],p=r[s.materialIndex];for(let a=Math.max(s.start,d.start),r=Math.min(o.count,Math.min(s.start+s.count,d.start+d.count));a<r;a+=3)n=qn(this,p,e,i,l,h,c,a,a+1,a+2),n&&(n.faceIndex=Math.floor(a/3),n.face.materialIndex=s.materialIndex,t.push(n))}else for(let a=Math.max(0,d.start),s=Math.min(o.count,d.start+d.count);a<s;a+=3)n=qn(this,r,e,i,l,h,c,a,a+1,a+2),n&&(n.faceIndex=Math.floor(a/3),t.push(n))}}function qn(e,t,i,n,a,r,s,o,l,h){e.getVertexPosition(o,kn),e.getVertexPosition(l,Nn),e.getVertexPosition(h,Gn);const c=function(e,t,i,n,a,r,s,o){let l;if(l=1===t.side?n.intersectTriangle(s,r,a,!0,o):n.intersectTriangle(a,r,s,0===t.side,o),null===l)return null;jn.copy(o),jn.applyMatrix4(e.matrixWorld);const h=i.ray.origin.distanceTo(jn);return h<i.near||h>i.far?null:{distance:h,point:jn.clone(),object:e}}(e,t,i,n,kn,Nn,Gn,Wn);if(c){const e=new xt;on.getBarycoord(Wn,kn,Nn,Gn,e),a&&(c.uv=on.getInterpolatedAttribute(a,o,l,h,e,new Mt)),r&&(c.uv1=on.getInterpolatedAttribute(r,o,l,h,e,new Mt)),s&&(c.normal=on.getInterpolatedAttribute(s,o,l,h,e,new xt),c.normal.dot(n.direction)>0&&c.normal.multiplyScalar(-1));const t={a:o,b:l,c:h,normal:new xt,materialIndex:0};on.getNormal(kn,Nn,Gn,t.normal),c.face=t,c.barycoord=e}return c}class Yn extends Bn{constructor(e=1,t=1,i=1,n=1,a=1,r=1){super(),this.type="BoxGeometry",this.parameters={width:e,height:t,depth:i,widthSegments:n,heightSegments:a,depthSegments:r};const s=this;n=Math.floor(n),a=Math.floor(a),r=Math.floor(r);const o=[],l=[],h=[],c=[];let u=0,d=0;function p(e,t,i,n,a,r,p,m,f,g,v){const y=r/f,b=p/g,M=r/2,_=p/2,x=m/2,S=f+1,w=g+1;let E=0,T=0;const C=new xt;for(let r=0;r<w;r++){const s=r*b-_;for(let o=0;o<S;o++){const u=o*y-M;C[e]=u*n,C[t]=s*a,C[i]=x,l.push(C.x,C.y,C.z),C[e]=0,C[t]=0,C[i]=m>0?1:-1,h.push(C.x,C.y,C.z),c.push(o/f),c.push(1-r/g),E+=1}}for(let e=0;e<g;e++)for(let t=0;t<f;t++){const i=u+t+S*e,n=u+t+S*(e+1),a=u+(t+1)+S*(e+1),r=u+(t+1)+S*e;o.push(i,n,r),o.push(n,a,r),T+=6}s.addGroup(d,T,v),d+=T,u+=E}p("z","y","x",-1,-1,i,t,e,r,a,0),p("z","y","x",1,-1,i,t,-e,r,a,1),p("x","z","y",1,1,e,i,t,n,r,2),p("x","z","y",1,-1,e,i,-t,n,r,3),p("x","y","z",1,-1,e,t,i,n,a,4),p("x","y","z",-1,-1,e,t,-i,n,a,5),this.setIndex(o),this.setAttribute("position",new Tn(l,3)),this.setAttribute("normal",new Tn(h,3)),this.setAttribute("uv",new Tn(c,2))}copy(e){return super.copy(e),this.parameters=Object.assign({},e.parameters),this}static fromJSON(e){return new Yn(e.width,e.height,e.depth,e.widthSegments,e.heightSegments,e.depthSegments)}}function $n(e){const t={};for(const i in e){t[i]={};for(const n in e[i]){const a=e[i][n];a&&(a.isColor||a.isMatrix3||a.isMatrix4||a.isVector2||a.isVector3||a.isVector4||a.isTexture||a.isQuaternion)?a.isRenderTargetTexture?(ot("UniformsUtils: Textures of render targets cannot be cloned via cloneUniforms() or mergeUniforms()."),t[i][n]=null):t[i][n]=a.clone():Array.isArray(a)?t[i][n]=a.slice():t[i][n]=a}}return t}function Zn(e){const t={};for(let i=0;i<e.length;i++){const n=$n(e[i]);for(const e in n)t[e]=n[e]}return t}function Kn(e){const t=e.getRenderTarget();return null===t?e.outputColorSpace:!0===t.isXRRenderTarget?t.texture.colorSpace:Dt.workingColorSpace}const Qn={clone:$n,merge:Zn};class Jn extends fn{constructor(e){super(),this.isShaderMaterial=!0,this.type="ShaderMaterial",this.defines={},this.uniforms={},this.uniformsGroups=[],this.vertexShader="void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",this.fragmentShader="void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}",this.linewidth=1,this.wireframe=!1,this.wireframeLinewidth=1,this.fog=!1,this.lights=!1,this.clipping=!1,this.forceSinglePass=!0,this.extensions={clipCullDistance:!1,multiDraw:!1},this.defaultAttributeValues={color:[1,1,1],uv:[0,0],uv1:[0,0]},this.index0AttributeName=void 0,this.uniformsNeedUpdate=!1,this.glslVersion=null,void 0!==e&&this.setValues(e)}copy(e){return super.copy(e),this.fragmentShader=e.fragmentShader,this.vertexShader=e.vertexShader,this.uniforms=$n(e.uniforms),this.uniformsGroups=function(e){const t=[];for(let i=0;i<e.length;i++)t.push(e[i].clone());return t}(e.uniformsGroups),this.defines=Object.assign({},e.defines),this.wireframe=e.wireframe,this.wireframeLinewidth=e.wireframeLinewidth,this.fog=e.fog,this.lights=e.lights,this.clipping=e.clipping,this.extensions=Object.assign({},e.extensions),this.glslVersion=e.glslVersion,this}toJSON(e){const t=super.toJSON(e);t.glslVersion=this.glslVersion,t.uniforms={};for(const i in this.uniforms){const n=this.uniforms[i].value;n&&n.isTexture?t.uniforms[i]={type:"t",value:n.toJSON(e).uuid}:n&&n.isColor?t.uniforms[i]={type:"c",value:n.getHex()}:n&&n.isVector2?t.uniforms[i]={type:"v2",value:n.toArray()}:n&&n.isVector3?t.uniforms[i]={type:"v3",value:n.toArray()}:n&&n.isVector4?t.uniforms[i]={type:"v4",value:n.toArray()}:n&&n.isMatrix3?t.uniforms[i]={type:"m3",value:n.toArray()}:n&&n.isMatrix4?t.uniforms[i]={type:"m4",value:n.toArray()}:t.uniforms[i]={value:n}}Object.keys(this.defines).length>0&&(t.defines=this.defines),t.vertexShader=this.vertexShader,t.fragmentShader=this.fragmentShader,t.lights=this.lights,t.clipping=this.clipping;const i={};for(const e in this.extensions)!0===this.extensions[e]&&(i[e]=!0);return Object.keys(i).length>0&&(t.extensions=i),t}}class ea extends Xi{constructor(){super(),this.isCamera=!0,this.type="Camera",this.matrixWorldInverse=new bi,this.projectionMatrix=new bi,this.projectionMatrixInverse=new bi,this.coordinateSystem=et,this._reversedDepth=!1}get reversedDepth(){return this._reversedDepth}copy(e,t){return super.copy(e,t),this.matrixWorldInverse.copy(e.matrixWorldInverse),this.projectionMatrix.copy(e.projectionMatrix),this.projectionMatrixInverse.copy(e.projectionMatrixInverse),this.coordinateSystem=e.coordinateSystem,this}getWorldDirection(e){return super.getWorldDirection(e).negate()}updateMatrixWorld(e){super.updateMatrixWorld(e),this.matrixWorldInverse.copy(this.matrixWorld).invert()}updateWorldMatrix(e,t){super.updateWorldMatrix(e,t),this.matrixWorldInverse.copy(this.matrixWorld).invert()}clone(){return(new this.constructor).copy(this)}}const ta=new xt,ia=new Mt,na=new Mt;class aa extends ea{constructor(e=50,t=1,i=.1,n=2e3){super(),this.isPerspectiveCamera=!0,this.type="PerspectiveCamera",this.fov=e,this.zoom=1,this.near=i,this.far=n,this.focus=10,this.aspect=t,this.view=null,this.filmGauge=35,this.filmOffset=0,this.updateProjectionMatrix()}copy(e,t){return super.copy(e,t),this.fov=e.fov,this.zoom=e.zoom,this.near=e.near,this.far=e.far,this.focus=e.focus,this.aspect=e.aspect,this.view=null===e.view?null:Object.assign({},e.view),this.filmGauge=e.filmGauge,this.filmOffset=e.filmOffset,this}setFocalLength(e){const t=.5*this.getFilmHeight()/e;this.fov=2*pt*Math.atan(t),this.updateProjectionMatrix()}getFocalLength(){const e=Math.tan(.5*dt*this.fov);return.5*this.getFilmHeight()/e}getEffectiveFOV(){return 2*pt*Math.atan(Math.tan(.5*dt*this.fov)/this.zoom)}getFilmWidth(){return this.filmGauge*Math.min(this.aspect,1)}getFilmHeight(){return this.filmGauge/Math.max(this.aspect,1)}getViewBounds(e,t,i){ta.set(-1,-1,.5).applyMatrix4(this.projectionMatrixInverse),t.set(ta.x,ta.y).multiplyScalar(-e/ta.z),ta.set(1,1,.5).applyMatrix4(this.projectionMatrixInverse),i.set(ta.x,ta.y).multiplyScalar(-e/ta.z)}getViewSize(e,t){return this.getViewBounds(e,ia,na),t.subVectors(na,ia)}setViewOffset(e,t,i,n,a,r){this.aspect=e/t,null===this.view&&(this.view={enabled:!0,fullWidth:1,fullHeight:1,offsetX:0,offsetY:0,width:1,height:1}),this.view.enabled=!0,this.view.fullWidth=e,this.view.fullHeight=t,this.view.offsetX=i,this.view.offsetY=n,this.view.width=a,this.view.height=r,this.updateProjectionMatrix()}clearViewOffset(){null!==this.view&&(this.view.enabled=!1),this.updateProjectionMatrix()}updateProjectionMatrix(){const e=this.near;let t=e*Math.tan(.5*dt*this.fov)/this.zoom,i=2*t,n=this.aspect*i,a=-.5*n;const r=this.view;if(null!==this.view&&this.view.enabled){const e=r.fullWidth,s=r.fullHeight;a+=r.offsetX*n/e,t-=r.offsetY*i/s,n*=r.width/e,i*=r.height/s}const s=this.filmOffset;0!==s&&(a+=e*s/this.getFilmWidth()),this.projectionMatrix.makePerspective(a,a+n,t,t-i,e,this.far,this.coordinateSystem,this.reversedDepth),this.projectionMatrixInverse.copy(this.projectionMatrix).invert()}toJSON(e){const t=super.toJSON(e);return t.object.fov=this.fov,t.object.zoom=this.zoom,t.object.near=this.near,t.object.far=this.far,t.object.focus=this.focus,t.object.aspect=this.aspect,null!==this.view&&(t.object.view=Object.assign({},this.view)),t.object.filmGauge=this.filmGauge,t.object.filmOffset=this.filmOffset,t}}const ra=-90;class sa extends Xi{constructor(e,t,i){super(),this.type="CubeCamera",this.renderTarget=i,this.coordinateSystem=null,this.activeMipmapLevel=0;const n=new aa(ra,1,e,t);n.layers=this.layers,this.add(n);const a=new aa(ra,1,e,t);a.layers=this.layers,this.add(a);const r=new aa(ra,1,e,t);r.layers=this.layers,this.add(r);const s=new aa(ra,1,e,t);s.layers=this.layers,this.add(s);const o=new aa(ra,1,e,t);o.layers=this.layers,this.add(o);const l=new aa(ra,1,e,t);l.layers=this.layers,this.add(l)}updateCoordinateSystem(){const e=this.coordinateSystem,t=this.children.concat(),[i,n,a,r,s,o]=t;for(const e of t)this.remove(e);if(e===et)i.up.set(0,1,0),i.lookAt(1,0,0),n.up.set(0,1,0),n.lookAt(-1,0,0),a.up.set(0,0,-1),a.lookAt(0,1,0),r.up.set(0,0,1),r.lookAt(0,-1,0),s.up.set(0,1,0),s.lookAt(0,0,1),o.up.set(0,1,0),o.lookAt(0,0,-1);else{if(e!==tt)throw new Error("THREE.CubeCamera.updateCoordinateSystem(): Invalid coordinate system: "+e);i.up.set(0,-1,0),i.lookAt(-1,0,0),n.up.set(0,-1,0),n.lookAt(1,0,0),a.up.set(0,0,1),a.lookAt(0,1,0),r.up.set(0,0,-1),r.lookAt(0,-1,0),s.up.set(0,-1,0),s.lookAt(0,0,1),o.up.set(0,-1,0),o.lookAt(0,0,-1)}for(const e of t)this.add(e),e.updateMatrixWorld()}update(e,t){null===this.parent&&this.updateMatrixWorld();const{renderTarget:i,activeMipmapLevel:n}=this;this.coordinateSystem!==e.coordinateSystem&&(this.coordinateSystem=e.coordinateSystem,this.updateCoordinateSystem());const[a,r,s,o,l,h]=this.children,c=e.getRenderTarget(),u=e.getActiveCubeFace(),d=e.getActiveMipmapLevel(),p=e.xr.enabled;e.xr.enabled=!1;const m=i.texture.generateMipmaps;i.texture.generateMipmaps=!1,e.setRenderTarget(i,0,n),e.render(t,a),e.setRenderTarget(i,1,n),e.render(t,r),e.setRenderTarget(i,2,n),e.render(t,s),e.setRenderTarget(i,3,n),e.render(t,o),e.setRenderTarget(i,4,n),e.render(t,l),i.texture.generateMipmaps=m,e.setRenderTarget(i,5,n),e.render(t,h),e.setRenderTarget(c,u,d),e.xr.enabled=p,i.texture.needsPMREMUpdate=!0}}class oa extends Nt{constructor(e=[],t=301,i,n,a,r,s,o,l,h){super(e,t,i,n,a,r,s,o,l,h),this.isCubeTexture=!0,this.flipY=!1}get images(){return this.image}set images(e){this.image=e}}class la extends Ht{constructor(e=1,t={}){super(e,e,t),this.isWebGLCubeRenderTarget=!0;const i={width:e,height:e,depth:1},n=[i,i,i,i,i,i];this.texture=new oa(n),this._setTextureOptions(t),this.texture.isRenderTargetTexture=!0}fromEquirectangularTexture(e,t){this.texture.type=t.type,this.texture.colorSpace=t.colorSpace,this.texture.generateMipmaps=t.generateMipmaps,this.texture.minFilter=t.minFilter,this.texture.magFilter=t.magFilter;const i={tEquirect:{value:null}},n="\n\n\t\t\t\tvarying vec3 vWorldDirection;\n\n\t\t\t\tvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\n\t\t\t\t\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n\n\t\t\t\t}\n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tvWorldDirection = transformDirection( position, modelMatrix );\n\n\t\t\t\t\t#include <begin_vertex>\n\t\t\t\t\t#include <project_vertex>\n\n\t\t\t\t}\n\t\t\t",a="\n\n\t\t\t\tuniform sampler2D tEquirect;\n\n\t\t\t\tvarying vec3 vWorldDirection;\n\n\t\t\t\t#include <common>\n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tvec3 direction = normalize( vWorldDirection );\n\n\t\t\t\t\tvec2 sampleUV = equirectUv( direction );\n\n\t\t\t\t\tgl_FragColor = texture2D( tEquirect, sampleUV );\n\n\t\t\t\t}\n\t\t\t",r=new Yn(5,5,5),s=new Jn({name:"CubemapFromEquirect",uniforms:$n(i),vertexShader:n,fragmentShader:a,side:1,blending:0});s.uniforms.tEquirect.value=t;const o=new Xn(r,s),l=t.minFilter;return t.minFilter===V&&(t.minFilter=N),new sa(1,10,this).update(e,o),t.minFilter=l,o.geometry.dispose(),o.material.dispose(),this}clear(e,t=!0,i=!0,n=!0){const a=e.getRenderTarget();for(let a=0;a<6;a++)e.setRenderTarget(this,a),e.clear(t,i,n);e.setRenderTarget(a)}}class ha extends Xi{constructor(){super(),this.isGroup=!0,this.type="Group"}}const ca={type:"move"};class ua{constructor(){this._targetRay=null,this._grip=null,this._hand=null}getHandSpace(){return null===this._hand&&(this._hand=new ha,this._hand.matrixAutoUpdate=!1,this._hand.visible=!1,this._hand.joints={},this._hand.inputState={pinching:!1}),this._hand}getTargetRaySpace(){return null===this._targetRay&&(this._targetRay=new ha,this._targetRay.matrixAutoUpdate=!1,this._targetRay.visible=!1,this._targetRay.hasLinearVelocity=!1,this._targetRay.linearVelocity=new xt,this._targetRay.hasAngularVelocity=!1,this._targetRay.angularVelocity=new xt),this._targetRay}getGripSpace(){return null===this._grip&&(this._grip=new ha,this._grip.matrixAutoUpdate=!1,this._grip.visible=!1,this._grip.hasLinearVelocity=!1,this._grip.linearVelocity=new xt,this._grip.hasAngularVelocity=!1,this._grip.angularVelocity=new xt),this._grip}dispatchEvent(e){return null!==this._targetRay&&this._targetRay.dispatchEvent(e),null!==this._grip&&this._grip.dispatchEvent(e),null!==this._hand&&this._hand.dispatchEvent(e),this}connect(e){if(e&&e.hand){const t=this._hand;if(t)for(const i of e.hand.values())this._getHandJoint(t,i)}return this.dispatchEvent({type:"connected",data:e}),this}disconnect(e){return this.dispatchEvent({type:"disconnected",data:e}),null!==this._targetRay&&(this._targetRay.visible=!1),null!==this._grip&&(this._grip.visible=!1),null!==this._hand&&(this._hand.visible=!1),this}update(e,t,i){let n=null,a=null,r=null;const s=this._targetRay,o=this._grip,l=this._hand;if(e&&"visible-blurred"!==t.session.visibilityState){if(l&&e.hand){r=!0;for(const n of e.hand.values()){const e=t.getJointPose(n,i),a=this._getHandJoint(l,n);null!==e&&(a.matrix.fromArray(e.transform.matrix),a.matrix.decompose(a.position,a.rotation,a.scale),a.matrixWorldNeedsUpdate=!0,a.jointRadius=e.radius),a.visible=null!==e}const n=l.joints["index-finger-tip"],a=l.joints["thumb-tip"],s=n.position.distanceTo(a.position),o=.02,h=.005;l.inputState.pinching&&s>o+h?(l.inputState.pinching=!1,this.dispatchEvent({type:"pinchend",handedness:e.handedness,target:this})):!l.inputState.pinching&&s<=o-h&&(l.inputState.pinching=!0,this.dispatchEvent({type:"pinchstart",handedness:e.handedness,target:this}))}else null!==o&&e.gripSpace&&(a=t.getPose(e.gripSpace,i),null!==a&&(o.matrix.fromArray(a.transform.matrix),o.matrix.decompose(o.position,o.rotation,o.scale),o.matrixWorldNeedsUpdate=!0,a.linearVelocity?(o.hasLinearVelocity=!0,o.linearVelocity.copy(a.linearVelocity)):o.hasLinearVelocity=!1,a.angularVelocity?(o.hasAngularVelocity=!0,o.angularVelocity.copy(a.angularVelocity)):o.hasAngularVelocity=!1));null!==s&&(n=t.getPose(e.targetRaySpace,i),null===n&&null!==a&&(n=a),null!==n&&(s.matrix.fromArray(n.transform.matrix),s.matrix.decompose(s.position,s.rotation,s.scale),s.matrixWorldNeedsUpdate=!0,n.linearVelocity?(s.hasLinearVelocity=!0,s.linearVelocity.copy(n.linearVelocity)):s.hasLinearVelocity=!1,n.angularVelocity?(s.hasAngularVelocity=!0,s.angularVelocity.copy(n.angularVelocity)):s.hasAngularVelocity=!1,this.dispatchEvent(ca)))}return null!==s&&(s.visible=null!==n),null!==o&&(o.visible=null!==a),null!==l&&(l.visible=null!==r),this}_getHandJoint(e,t){if(void 0===e.joints[t.jointName]){const i=new ha;i.matrixAutoUpdate=!1,i.visible=!1,e.joints[t.jointName]=i,e.add(i)}return e.joints[t.jointName]}}class da extends Xi{constructor(){super(),this.isScene=!0,this.type="Scene",this.background=null,this.environment=null,this.fog=null,this.backgroundBlurriness=0,this.backgroundIntensity=1,this.backgroundRotation=new Pi,this.environmentIntensity=1,this.environmentRotation=new Pi,this.overrideMaterial=null,"undefined"!=typeof __THREE_DEVTOOLS__&&__THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("observe",{detail:this}))}copy(e,t){return super.copy(e,t),null!==e.background&&(this.background=e.background.clone()),null!==e.environment&&(this.environment=e.environment.clone()),null!==e.fog&&(this.fog=e.fog.clone()),this.backgroundBlurriness=e.backgroundBlurriness,this.backgroundIntensity=e.backgroundIntensity,this.backgroundRotation.copy(e.backgroundRotation),this.environmentIntensity=e.environmentIntensity,this.environmentRotation.copy(e.environmentRotation),null!==e.overrideMaterial&&(this.overrideMaterial=e.overrideMaterial.clone()),this.matrixAutoUpdate=e.matrixAutoUpdate,this}toJSON(e){const t=super.toJSON(e);return null!==this.fog&&(t.object.fog=this.fog.toJSON()),this.backgroundBlurriness>0&&(t.object.backgroundBlurriness=this.backgroundBlurriness),1!==this.backgroundIntensity&&(t.object.backgroundIntensity=this.backgroundIntensity),t.object.backgroundRotation=this.backgroundRotation.toArray(),1!==this.environmentIntensity&&(t.object.environmentIntensity=this.environmentIntensity),t.object.environmentRotation=this.environmentRotation.toArray(),t}}class pa{constructor(e,t){this.isInterleavedBuffer=!0,this.array=e,this.stride=t,this.count=void 0!==e?e.length/t:0,this.usage=Ke,this.updateRanges=[],this.version=0,this.uuid=mt()}onUploadCallback(){}set needsUpdate(e){!0===e&&this.version++}setUsage(e){return this.usage=e,this}addUpdateRange(e,t){this.updateRanges.push({start:e,count:t})}clearUpdateRanges(){this.updateRanges.length=0}copy(e){return this.array=new e.array.constructor(e.array),this.count=e.count,this.stride=e.stride,this.usage=e.usage,this}copyAt(e,t,i){e*=this.stride,i*=t.stride;for(let n=0,a=this.stride;n<a;n++)this.array[e+n]=t.array[i+n];return this}set(e,t=0){return this.array.set(e,t),this}clone(e){void 0===e.arrayBuffers&&(e.arrayBuffers={}),void 0===this.array.buffer._uuid&&(this.array.buffer._uuid=mt()),void 0===e.arrayBuffers[this.array.buffer._uuid]&&(e.arrayBuffers[this.array.buffer._uuid]=this.array.slice(0).buffer);const t=new this.array.constructor(e.arrayBuffers[this.array.buffer._uuid]),i=new this.constructor(t,this.stride);return i.setUsage(this.usage),i}onUpload(e){return this.onUploadCallback=e,this}toJSON(e){return void 0===e.arrayBuffers&&(e.arrayBuffers={}),void 0===this.array.buffer._uuid&&(this.array.buffer._uuid=mt()),void 0===e.arrayBuffers[this.array.buffer._uuid]&&(e.arrayBuffers[this.array.buffer._uuid]=Array.from(new Uint32Array(this.array.buffer))),{uuid:this.uuid,buffer:this.array.buffer._uuid,type:this.array.constructor.name,stride:this.stride}}}const ma=new xt;class fa{constructor(e,t,i,n=!1){this.isInterleavedBufferAttribute=!0,this.name="",this.data=e,this.itemSize=t,this.offset=i,this.normalized=n}get count(){return this.data.count}get array(){return this.data.array}set needsUpdate(e){this.data.needsUpdate=e}applyMatrix4(e){for(let t=0,i=this.data.count;t<i;t++)ma.fromBufferAttribute(this,t),ma.applyMatrix4(e),this.setXYZ(t,ma.x,ma.y,ma.z);return this}applyNormalMatrix(e){for(let t=0,i=this.count;t<i;t++)ma.fromBufferAttribute(this,t),ma.applyNormalMatrix(e),this.setXYZ(t,ma.x,ma.y,ma.z);return this}transformDirection(e){for(let t=0,i=this.count;t<i;t++)ma.fromBufferAttribute(this,t),ma.transformDirection(e),this.setXYZ(t,ma.x,ma.y,ma.z);return this}getComponent(e,t){let i=this.array[e*this.data.stride+this.offset+t];return this.normalized&&(i=vt(i,this.array)),i}setComponent(e,t,i){return this.normalized&&(i=yt(i,this.array)),this.data.array[e*this.data.stride+this.offset+t]=i,this}setX(e,t){return this.normalized&&(t=yt(t,this.array)),this.data.array[e*this.data.stride+this.offset]=t,this}setY(e,t){return this.normalized&&(t=yt(t,this.array)),this.data.array[e*this.data.stride+this.offset+1]=t,this}setZ(e,t){return this.normalized&&(t=yt(t,this.array)),this.data.array[e*this.data.stride+this.offset+2]=t,this}setW(e,t){return this.normalized&&(t=yt(t,this.array)),this.data.array[e*this.data.stride+this.offset+3]=t,this}getX(e){let t=this.data.array[e*this.data.stride+this.offset];return this.normalized&&(t=vt(t,this.array)),t}getY(e){let t=this.data.array[e*this.data.stride+this.offset+1];return this.normalized&&(t=vt(t,this.array)),t}getZ(e){let t=this.data.array[e*this.data.stride+this.offset+2];return this.normalized&&(t=vt(t,this.array)),t}getW(e){let t=this.data.array[e*this.data.stride+this.offset+3];return this.normalized&&(t=vt(t,this.array)),t}setXY(e,t,i){return e=e*this.data.stride+this.offset,this.normalized&&(t=yt(t,this.array),i=yt(i,this.array)),this.data.array[e+0]=t,this.data.array[e+1]=i,this}setXYZ(e,t,i,n){return e=e*this.data.stride+this.offset,this.normalized&&(t=yt(t,this.array),i=yt(i,this.array),n=yt(n,this.array)),this.data.array[e+0]=t,this.data.array[e+1]=i,this.data.array[e+2]=n,this}setXYZW(e,t,i,n,a){return e=e*this.data.stride+this.offset,this.normalized&&(t=yt(t,this.array),i=yt(i,this.array),n=yt(n,this.array),a=yt(a,this.array)),this.data.array[e+0]=t,this.data.array[e+1]=i,this.data.array[e+2]=n,this.data.array[e+3]=a,this}clone(e){if(void 0===e){st("InterleavedBufferAttribute.clone(): Cloning an interleaved buffer attribute will de-interleave buffer data.");const e=[];for(let t=0;t<this.count;t++){const i=t*this.data.stride+this.offset;for(let t=0;t<this.itemSize;t++)e.push(this.data.array[i+t])}return new Sn(new this.array.constructor(e),this.itemSize,this.normalized)}return void 0===e.interleavedBuffers&&(e.interleavedBuffers={}),void 0===e.interleavedBuffers[this.data.uuid]&&(e.interleavedBuffers[this.data.uuid]=this.data.clone(e)),new fa(e.interleavedBuffers[this.data.uuid],this.itemSize,this.offset,this.normalized)}toJSON(e){if(void 0===e){st("InterleavedBufferAttribute.toJSON(): Serializing an interleaved buffer attribute will de-interleave buffer data.");const e=[];for(let t=0;t<this.count;t++){const i=t*this.data.stride+this.offset;for(let t=0;t<this.itemSize;t++)e.push(this.data.array[i+t])}return{itemSize:this.itemSize,type:this.array.constructor.name,array:e,normalized:this.normalized}}return void 0===e.interleavedBuffers&&(e.interleavedBuffers={}),void 0===e.interleavedBuffers[this.data.uuid]&&(e.interleavedBuffers[this.data.uuid]=this.data.toJSON(e)),{isInterleavedBufferAttribute:!0,itemSize:this.itemSize,data:this.data.uuid,offset:this.offset,normalized:this.normalized}}}class ga extends fn{constructor(e){super(),this.isSpriteMaterial=!0,this.type="SpriteMaterial",this.color=new dn(16777215),this.map=null,this.alphaMap=null,this.rotation=0,this.sizeAttenuation=!0,this.transparent=!0,this.fog=!0,this.setValues(e)}copy(e){return super.copy(e),this.color.copy(e.color),this.map=e.map,this.alphaMap=e.alphaMap,this.rotation=e.rotation,this.sizeAttenuation=e.sizeAttenuation,this.fog=e.fog,this}}let va;const ya=new xt,ba=new xt,Ma=new xt,_a=new Mt,xa=new Mt,Sa=new bi,wa=new xt,Ea=new xt,Ta=new xt,Ca=new Mt,Aa=new Mt,Pa=new Mt;class Da extends Xi{constructor(e=new ga){if(super(),this.isSprite=!0,this.type="Sprite",void 0===va){va=new Bn;const e=new Float32Array([-.5,-.5,0,0,0,.5,-.5,0,1,0,.5,.5,0,1,1,-.5,.5,0,0,1]),t=new pa(e,5);va.setIndex([0,1,2,0,2,3]),va.setAttribute("position",new fa(t,3,0,!1)),va.setAttribute("uv",new fa(t,2,3,!1))}this.geometry=va,this.material=e,this.center=new Mt(.5,.5),this.count=1}raycast(e,t){null===e.camera&&lt('Sprite: "Raycaster.camera" needs to be set in order to raycast against sprites.'),ba.setFromMatrixScale(this.matrixWorld),Sa.copy(e.camera.matrixWorld),this.modelViewMatrix.multiplyMatrices(e.camera.matrixWorldInverse,this.matrixWorld),Ma.setFromMatrixPosition(this.modelViewMatrix),e.camera.isPerspectiveCamera&&!1===this.material.sizeAttenuation&&ba.multiplyScalar(-Ma.z);const i=this.material.rotation;let n,a;0!==i&&(a=Math.cos(i),n=Math.sin(i));const r=this.center;Ra(wa.set(-.5,-.5,0),Ma,r,ba,n,a),Ra(Ea.set(.5,-.5,0),Ma,r,ba,n,a),Ra(Ta.set(.5,.5,0),Ma,r,ba,n,a),Ca.set(0,0),Aa.set(1,0),Pa.set(1,1);let s=e.ray.intersectTriangle(wa,Ea,Ta,!1,ya);if(null===s&&(Ra(Ea.set(-.5,.5,0),Ma,r,ba,n,a),Aa.set(0,1),s=e.ray.intersectTriangle(wa,Ta,Ea,!1,ya),null===s))return;const o=e.ray.origin.distanceTo(ya);o<e.near||o>e.far||t.push({distance:o,point:ya.clone(),uv:on.getInterpolation(ya,wa,Ea,Ta,Ca,Aa,Pa,new Mt),face:null,object:this})}copy(e,t){return super.copy(e,t),void 0!==e.center&&this.center.copy(e.center),this.material=e.material,this}}function Ra(e,t,i,n,a,r){_a.subVectors(e,i).addScalar(.5).multiply(n),void 0!==a?(xa.x=r*_a.x-a*_a.y,xa.y=a*_a.x+r*_a.y):xa.copy(_a),e.copy(t),e.x+=xa.x,e.y+=xa.y,e.applyMatrix4(Sa)}class Ia extends Nt{constructor(e=null,t=1,i=1,n,a,r,s,o,l=1003,h=1003,c,u){super(null,r,s,o,l,h,n,a,c,u),this.isDataTexture=!0,this.image={data:e,width:t,height:i},this.generateMipmaps=!1,this.flipY=!1,this.unpackAlignment=1}}const La=new xt,Ba=new xt,Oa=new Et;class Fa{constructor(e=new xt(1,0,0),t=0){this.isPlane=!0,this.normal=e,this.constant=t}set(e,t){return this.normal.copy(e),this.constant=t,this}setComponents(e,t,i,n){return this.normal.set(e,t,i),this.constant=n,this}setFromNormalAndCoplanarPoint(e,t){return this.normal.copy(e),this.constant=-t.dot(this.normal),this}setFromCoplanarPoints(e,t,i){const n=La.subVectors(i,t).cross(Ba.subVectors(e,t)).normalize();return this.setFromNormalAndCoplanarPoint(n,e),this}copy(e){return this.normal.copy(e.normal),this.constant=e.constant,this}normalize(){const e=1/this.normal.length();return this.normal.multiplyScalar(e),this.constant*=e,this}negate(){return this.constant*=-1,this.normal.negate(),this}distanceToPoint(e){return this.normal.dot(e)+this.constant}distanceToSphere(e){return this.distanceToPoint(e.center)-e.radius}projectPoint(e,t){return t.copy(e).addScaledVector(this.normal,-this.distanceToPoint(e))}intersectLine(e,t){const i=e.delta(La),n=this.normal.dot(i);if(0===n)return 0===this.distanceToPoint(e.start)?t.copy(e.start):null;const a=-(e.start.dot(this.normal)+this.constant)/n;return a<0||a>1?null:t.copy(e.start).addScaledVector(i,a)}intersectsLine(e){const t=this.distanceToPoint(e.start),i=this.distanceToPoint(e.end);return t<0&&i>0||i<0&&t>0}intersectsBox(e){return e.intersectsPlane(this)}intersectsSphere(e){return e.intersectsPlane(this)}coplanarPoint(e){return e.copy(this.normal).multiplyScalar(-this.constant)}applyMatrix4(e,t){const i=t||Oa.getNormalMatrix(e),n=this.coplanarPoint(La).applyMatrix4(e),a=this.normal.applyMatrix3(i).normalize();return this.constant=-n.dot(a),this}translate(e){return this.constant-=e.dot(this.normal),this}equals(e){return e.normal.equals(this.normal)&&e.constant===this.constant}clone(){return(new this.constructor).copy(this)}}const Ua=new ci,za=new Mt(.5,.5),ka=new xt;class Na{constructor(e=new Fa,t=new Fa,i=new Fa,n=new Fa,a=new Fa,r=new Fa){this.planes=[e,t,i,n,a,r]}set(e,t,i,n,a,r){const s=this.planes;return s[0].copy(e),s[1].copy(t),s[2].copy(i),s[3].copy(n),s[4].copy(a),s[5].copy(r),this}copy(e){const t=this.planes;for(let i=0;i<6;i++)t[i].copy(e.planes[i]);return this}setFromProjectionMatrix(e,t=2e3,i=!1){const n=this.planes,a=e.elements,r=a[0],s=a[1],o=a[2],l=a[3],h=a[4],c=a[5],u=a[6],d=a[7],p=a[8],m=a[9],f=a[10],g=a[11],v=a[12],y=a[13],b=a[14],M=a[15];if(n[0].setComponents(l-r,d-h,g-p,M-v).normalize(),n[1].setComponents(l+r,d+h,g+p,M+v).normalize(),n[2].setComponents(l+s,d+c,g+m,M+y).normalize(),n[3].setComponents(l-s,d-c,g-m,M-y).normalize(),i)n[4].setComponents(o,u,f,b).normalize(),n[5].setComponents(l-o,d-u,g-f,M-b).normalize();else if(n[4].setComponents(l-o,d-u,g-f,M-b).normalize(),t===et)n[5].setComponents(l+o,d+u,g+f,M+b).normalize();else{if(t!==tt)throw new Error("THREE.Frustum.setFromProjectionMatrix(): Invalid coordinate system: "+t);n[5].setComponents(o,u,f,b).normalize()}return this}intersectsObject(e){if(void 0!==e.boundingSphere)null===e.boundingSphere&&e.computeBoundingSphere(),Ua.copy(e.boundingSphere).applyMatrix4(e.matrixWorld);else{const t=e.geometry;null===t.boundingSphere&&t.computeBoundingSphere(),Ua.copy(t.boundingSphere).applyMatrix4(e.matrixWorld)}return this.intersectsSphere(Ua)}intersectsSprite(e){Ua.center.set(0,0,0);const t=za.distanceTo(e.center);return Ua.radius=.7071067811865476+t,Ua.applyMatrix4(e.matrixWorld),this.intersectsSphere(Ua)}intersectsSphere(e){const t=this.planes,i=e.center,n=-e.radius;for(let e=0;e<6;e++)if(t[e].distanceToPoint(i)<n)return!1;return!0}intersectsBox(e){const t=this.planes;for(let i=0;i<6;i++){const n=t[i];if(ka.x=n.normal.x>0?e.max.x:e.min.x,ka.y=n.normal.y>0?e.max.y:e.min.y,ka.z=n.normal.z>0?e.max.z:e.min.z,n.distanceToPoint(ka)<0)return!1}return!0}containsPoint(e){const t=this.planes;for(let i=0;i<6;i++)if(t[i].distanceToPoint(e)<0)return!1;return!0}clone(){return(new this.constructor).copy(this)}}class Ga extends fn{constructor(e){super(),this.isLineBasicMaterial=!0,this.type="LineBasicMaterial",this.color=new dn(16777215),this.map=null,this.linewidth=1,this.linecap="round",this.linejoin="round",this.fog=!0,this.setValues(e)}copy(e){return super.copy(e),this.color.copy(e.color),this.map=e.map,this.linewidth=e.linewidth,this.linecap=e.linecap,this.linejoin=e.linejoin,this.fog=e.fog,this}}const Va=new xt,Ha=new xt,Wa=new bi,ja=new yi,Xa=new ci,qa=new xt,Ya=new xt;class $a extends Xi{constructor(e=new Bn,t=new Ga){super(),this.isLine=!0,this.type="Line",this.geometry=e,this.material=t,this.morphTargetDictionary=void 0,this.morphTargetInfluences=void 0,this.updateMorphTargets()}copy(e,t){return super.copy(e,t),this.material=Array.isArray(e.material)?e.material.slice():e.material,this.geometry=e.geometry,this}computeLineDistances(){const e=this.geometry;if(null===e.index){const t=e.attributes.position,i=[0];for(let e=1,n=t.count;e<n;e++)Va.fromBufferAttribute(t,e-1),Ha.fromBufferAttribute(t,e),i[e]=i[e-1],i[e]+=Va.distanceTo(Ha);e.setAttribute("lineDistance",new Tn(i,1))}else ot("Line.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.");return this}raycast(e,t){const i=this.geometry,n=this.matrixWorld,a=e.params.Line.threshold,r=i.drawRange;if(null===i.boundingSphere&&i.computeBoundingSphere(),Xa.copy(i.boundingSphere),Xa.applyMatrix4(n),Xa.radius+=a,!1===e.ray.intersectsSphere(Xa))return;Wa.copy(n).invert(),ja.copy(e.ray).applyMatrix4(Wa);const s=a/((this.scale.x+this.scale.y+this.scale.z)/3),o=s*s,l=this.isLineSegments?2:1,h=i.index,c=i.attributes.position;if(null!==h){const i=Math.max(0,r.start),n=Math.min(h.count,r.start+r.count);for(let a=i,r=n-1;a<r;a+=l){const i=h.getX(a),n=h.getX(a+1),r=Za(this,e,ja,o,i,n,a);r&&t.push(r)}if(this.isLineLoop){const a=h.getX(n-1),r=h.getX(i),s=Za(this,e,ja,o,a,r,n-1);s&&t.push(s)}}else{const i=Math.max(0,r.start),n=Math.min(c.count,r.start+r.count);for(let a=i,r=n-1;a<r;a+=l){const i=Za(this,e,ja,o,a,a+1,a);i&&t.push(i)}if(this.isLineLoop){const a=Za(this,e,ja,o,n-1,i,n-1);a&&t.push(a)}}}updateMorphTargets(){const e=this.geometry.morphAttributes,t=Object.keys(e);if(t.length>0){const i=e[t[0]];if(void 0!==i){this.morphTargetInfluences=[],this.morphTargetDictionary={};for(let e=0,t=i.length;e<t;e++){const t=i[e].name||String(e);this.morphTargetInfluences.push(0),this.morphTargetDictionary[t]=e}}}}}function Za(e,t,i,n,a,r,s){const o=e.geometry.attributes.position;if(Va.fromBufferAttribute(o,a),Ha.fromBufferAttribute(o,r),i.distanceSqToSegment(Va,Ha,qa,Ya)>n)return;qa.applyMatrix4(e.matrixWorld);const l=t.ray.origin.distanceTo(qa);return l<t.near||l>t.far?void 0:{distance:l,point:Ya.clone().applyMatrix4(e.matrixWorld),index:s,face:null,faceIndex:null,barycoord:null,object:e}}const Ka=new xt,Qa=new xt;class Ja extends $a{constructor(e,t){super(e,t),this.isLineSegments=!0,this.type="LineSegments"}computeLineDistances(){const e=this.geometry;if(null===e.index){const t=e.attributes.position,i=[];for(let e=0,n=t.count;e<n;e+=2)Ka.fromBufferAttribute(t,e),Qa.fromBufferAttribute(t,e+1),i[e]=0===e?0:i[e-1],i[e+1]=i[e]+Ka.distanceTo(Qa);e.setAttribute("lineDistance",new Tn(i,1))}else ot("LineSegments.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.");return this}}class er extends fn{constructor(e){super(),this.isPointsMaterial=!0,this.type="PointsMaterial",this.color=new dn(16777215),this.map=null,this.alphaMap=null,this.size=1,this.sizeAttenuation=!0,this.fog=!0,this.setValues(e)}copy(e){return super.copy(e),this.color.copy(e.color),this.map=e.map,this.alphaMap=e.alphaMap,this.size=e.size,this.sizeAttenuation=e.sizeAttenuation,this.fog=e.fog,this}}const tr=new bi,ir=new yi,nr=new ci,ar=new xt;class rr extends Xi{constructor(e=new Bn,t=new er){super(),this.isPoints=!0,this.type="Points",this.geometry=e,this.material=t,this.morphTargetDictionary=void 0,this.morphTargetInfluences=void 0,this.updateMorphTargets()}copy(e,t){return super.copy(e,t),this.material=Array.isArray(e.material)?e.material.slice():e.material,this.geometry=e.geometry,this}raycast(e,t){const i=this.geometry,n=this.matrixWorld,a=e.params.Points.threshold,r=i.drawRange;if(null===i.boundingSphere&&i.computeBoundingSphere(),nr.copy(i.boundingSphere),nr.applyMatrix4(n),nr.radius+=a,!1===e.ray.intersectsSphere(nr))return;tr.copy(n).invert(),ir.copy(e.ray).applyMatrix4(tr);const s=a/((this.scale.x+this.scale.y+this.scale.z)/3),o=s*s,l=i.index,h=i.attributes.position;if(null!==l)for(let i=Math.max(0,r.start),a=Math.min(l.count,r.start+r.count);i<a;i++){const a=l.getX(i);ar.fromBufferAttribute(h,a),sr(ar,a,o,n,e,t,this)}else for(let i=Math.max(0,r.start),a=Math.min(h.count,r.start+r.count);i<a;i++)ar.fromBufferAttribute(h,i),sr(ar,i,o,n,e,t,this)}updateMorphTargets(){const e=this.geometry.morphAttributes,t=Object.keys(e);if(t.length>0){const i=e[t[0]];if(void 0!==i){this.morphTargetInfluences=[],this.morphTargetDictionary={};for(let e=0,t=i.length;e<t;e++){const t=i[e].name||String(e);this.morphTargetInfluences.push(0),this.morphTargetDictionary[t]=e}}}}}function sr(e,t,i,n,a,r,s){const o=ir.distanceSqToPoint(e);if(o<i){const i=new xt;ir.closestPointToPoint(e,i),i.applyMatrix4(n);const l=a.ray.origin.distanceTo(i);if(l<a.near||l>a.far)return;r.push({distance:l,distanceToRay:Math.sqrt(o),point:i,index:t,face:null,faceIndex:null,barycoord:null,object:s})}}class or extends Nt{constructor(e,t,i,n,a,r,s,o,l){super(e,t,i,n,a,r,s,o,l),this.isCanvasTexture=!0,this.needsUpdate=!0}}class lr extends Nt{constructor(e,t,i=1014,n,a,r,s=1003,o=1003,l,h=1026,c=1){if(h!==J&&h!==ee)throw new Error("DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat");super({width:e,height:t,depth:c},n,a,r,s,o,h,i,l),this.isDepthTexture=!0,this.flipY=!1,this.generateMipmaps=!1,this.compareFunction=null}copy(e){return super.copy(e),this.source=new Ft(Object.assign({},e.image)),this.compareFunction=e.compareFunction,this}toJSON(e){const t=super.toJSON(e);return null!==this.compareFunction&&(t.compareFunction=this.compareFunction),t}}class hr extends Nt{constructor(e=null){super(),this.sourceTexture=e,this.isExternalTexture=!0}copy(e){return super.copy(e),this.sourceTexture=e.sourceTexture,this}}class cr extends Bn{constructor(e=1,t=32,i=0,n=2*Math.PI){super(),this.type="CircleGeometry",this.parameters={radius:e,segments:t,thetaStart:i,thetaLength:n},t=Math.max(3,t);const a=[],r=[],s=[],o=[],l=new xt,h=new Mt;r.push(0,0,0),s.push(0,0,1),o.push(.5,.5);for(let a=0,c=3;a<=t;a++,c+=3){const u=i+a/t*n;l.x=e*Math.cos(u),l.y=e*Math.sin(u),r.push(l.x,l.y,l.z),s.push(0,0,1),h.x=(r[c]/e+1)/2,h.y=(r[c+1]/e+1)/2,o.push(h.x,h.y)}for(let e=1;e<=t;e++)a.push(e,e+1,0);this.setIndex(a),this.setAttribute("position",new Tn(r,3)),this.setAttribute("normal",new Tn(s,3)),this.setAttribute("uv",new Tn(o,2))}copy(e){return super.copy(e),this.parameters=Object.assign({},e.parameters),this}static fromJSON(e){return new cr(e.radius,e.segments,e.thetaStart,e.thetaLength)}}class ur extends Bn{constructor(e=[],t=[],i=1,n=0){super(),this.type="PolyhedronGeometry",this.parameters={vertices:e,indices:t,radius:i,detail:n};const a=[],r=[];function s(e,t,i,n){const a=n+1,r=[];for(let n=0;n<=a;n++){r[n]=[];const s=e.clone().lerp(i,n/a),o=t.clone().lerp(i,n/a),l=a-n;for(let e=0;e<=l;e++)r[n][e]=0===e&&n===a?s:s.clone().lerp(o,e/l)}for(let e=0;e<a;e++)for(let t=0;t<2*(a-e)-1;t++){const i=Math.floor(t/2);t%2==0?(o(r[e][i+1]),o(r[e+1][i]),o(r[e][i])):(o(r[e][i+1]),o(r[e+1][i+1]),o(r[e+1][i]))}}function o(e){a.push(e.x,e.y,e.z)}function l(t,i){const n=3*t;i.x=e[n+0],i.y=e[n+1],i.z=e[n+2]}function h(e,t,i,n){n<0&&1===e.x&&(r[t]=e.x-1),0===i.x&&0===i.z&&(r[t]=n/2/Math.PI+.5)}function c(e){return Math.atan2(e.z,-e.x)}function u(e){return Math.atan2(-e.y,Math.sqrt(e.x*e.x+e.z*e.z))}!function(e){const i=new xt,n=new xt,a=new xt;for(let r=0;r<t.length;r+=3)l(t[r+0],i),l(t[r+1],n),l(t[r+2],a),s(i,n,a,e)}(n),function(e){const t=new xt;for(let i=0;i<a.length;i+=3)t.x=a[i+0],t.y=a[i+1],t.z=a[i+2],t.normalize().multiplyScalar(e),a[i+0]=t.x,a[i+1]=t.y,a[i+2]=t.z}(i),function(){const e=new xt;for(let t=0;t<a.length;t+=3){e.x=a[t+0],e.y=a[t+1],e.z=a[t+2];const i=c(e)/2/Math.PI+.5,n=u(e)/Math.PI+.5;r.push(i,1-n)}(function(){const e=new xt,t=new xt,i=new xt,n=new xt,s=new Mt,o=new Mt,l=new Mt;for(let u=0,d=0;u<a.length;u+=9,d+=6){e.set(a[u+0],a[u+1],a[u+2]),t.set(a[u+3],a[u+4],a[u+5]),i.set(a[u+6],a[u+7],a[u+8]),s.set(r[d+0],r[d+1]),o.set(r[d+2],r[d+3]),l.set(r[d+4],r[d+5]),n.copy(e).add(t).add(i).divideScalar(3);const p=c(n);h(s,d+0,e,p),h(o,d+2,t,p),h(l,d+4,i,p)}})(),function(){for(let e=0;e<r.length;e+=6){const t=r[e+0],i=r[e+2],n=r[e+4],a=Math.max(t,i,n),s=Math.min(t,i,n);a>.9&&s<.1&&(t<.2&&(r[e+0]+=1),i<.2&&(r[e+2]+=1),n<.2&&(r[e+4]+=1))}}()}(),this.setAttribute("position",new Tn(a,3)),this.setAttribute("normal",new Tn(a.slice(),3)),this.setAttribute("uv",new Tn(r,2)),0===n?this.computeVertexNormals():this.normalizeNormals()}copy(e){return super.copy(e),this.parameters=Object.assign({},e.parameters),this}static fromJSON(e){return new ur(e.vertices,e.indices,e.radius,e.details)}}class dr extends ur{constructor(e=1,t=0){const i=(1+Math.sqrt(5))/2,n=1/i;super([-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,0,-n,-i,0,-n,i,0,n,-i,0,n,i,-n,-i,0,-n,i,0,n,-i,0,n,i,0,-i,0,-n,i,0,-n,-i,0,n,i,0,n],[3,11,7,3,7,15,3,15,13,7,19,17,7,17,6,7,6,15,17,4,8,17,8,10,17,10,6,8,0,16,8,16,2,8,2,10,0,12,1,0,1,18,0,18,16,6,10,2,6,2,13,6,13,15,2,16,18,2,18,3,2,3,13,18,1,9,18,9,11,18,11,3,4,14,12,4,12,0,4,0,8,11,9,5,11,5,19,11,19,7,19,5,14,19,14,4,19,4,17,1,12,14,1,14,5,1,5,9],e,t),this.type="DodecahedronGeometry",this.parameters={radius:e,detail:t}}static fromJSON(e){return new dr(e.radius,e.detail)}}class pr extends ur{constructor(e=1,t=0){const i=(1+Math.sqrt(5))/2;super([-1,i,0,1,i,0,-1,-i,0,1,-i,0,0,-1,i,0,1,i,0,-1,-i,0,1,-i,i,0,-1,i,0,1,-i,0,-1,-i,0,1],[0,11,5,0,5,1,0,1,7,0,7,10,0,10,11,1,5,9,5,11,4,11,10,2,10,7,6,7,1,8,3,9,4,3,4,2,3,2,6,3,6,8,3,8,9,4,9,5,2,4,11,6,2,10,8,6,7,9,8,1],e,t),this.type="IcosahedronGeometry",this.parameters={radius:e,detail:t}}static fromJSON(e){return new pr(e.radius,e.detail)}}class mr extends ur{constructor(e=1,t=0){super([1,0,0,-1,0,0,0,1,0,0,-1,0,0,0,1,0,0,-1],[0,2,4,0,4,3,0,3,5,0,5,2,1,2,5,1,5,3,1,3,4,1,4,2],e,t),this.type="OctahedronGeometry",this.parameters={radius:e,detail:t}}static fromJSON(e){return new mr(e.radius,e.detail)}}class fr extends Bn{constructor(e=1,t=1,i=1,n=1){super(),this.type="PlaneGeometry",this.parameters={width:e,height:t,widthSegments:i,heightSegments:n};const a=e/2,r=t/2,s=Math.floor(i),o=Math.floor(n),l=s+1,h=o+1,c=e/s,u=t/o,d=[],p=[],m=[],f=[];for(let e=0;e<h;e++){const t=e*u-r;for(let i=0;i<l;i++){const n=i*c-a;p.push(n,-t,0),m.push(0,0,1),f.push(i/s),f.push(1-e/o)}}for(let e=0;e<o;e++)for(let t=0;t<s;t++){const i=t+l*e,n=t+l*(e+1),a=t+1+l*(e+1),r=t+1+l*e;d.push(i,n,r),d.push(n,a,r)}this.setIndex(d),this.setAttribute("position",new Tn(p,3)),this.setAttribute("normal",new Tn(m,3)),this.setAttribute("uv",new Tn(f,2))}copy(e){return super.copy(e),this.parameters=Object.assign({},e.parameters),this}static fromJSON(e){return new fr(e.width,e.height,e.widthSegments,e.heightSegments)}}class gr extends Bn{constructor(e=.5,t=1,i=32,n=1,a=0,r=2*Math.PI){super(),this.type="RingGeometry",this.parameters={innerRadius:e,outerRadius:t,thetaSegments:i,phiSegments:n,thetaStart:a,thetaLength:r},i=Math.max(3,i);const s=[],o=[],l=[],h=[];let c=e;const u=(t-e)/(n=Math.max(1,n)),d=new xt,p=new Mt;for(let e=0;e<=n;e++){for(let e=0;e<=i;e++){const n=a+e/i*r;d.x=c*Math.cos(n),d.y=c*Math.sin(n),o.push(d.x,d.y,d.z),l.push(0,0,1),p.x=(d.x/t+1)/2,p.y=(d.y/t+1)/2,h.push(p.x,p.y)}c+=u}for(let e=0;e<n;e++){const t=e*(i+1);for(let e=0;e<i;e++){const n=e+t,a=n,r=n+i+1,o=n+i+2,l=n+1;s.push(a,r,l),s.push(r,o,l)}}this.setIndex(s),this.setAttribute("position",new Tn(o,3)),this.setAttribute("normal",new Tn(l,3)),this.setAttribute("uv",new Tn(h,2))}copy(e){return super.copy(e),this.parameters=Object.assign({},e.parameters),this}static fromJSON(e){return new gr(e.innerRadius,e.outerRadius,e.thetaSegments,e.phiSegments,e.thetaStart,e.thetaLength)}}class vr extends Bn{constructor(e=1,t=32,i=16,n=0,a=2*Math.PI,r=0,s=Math.PI){super(),this.type="SphereGeometry",this.parameters={radius:e,widthSegments:t,heightSegments:i,phiStart:n,phiLength:a,thetaStart:r,thetaLength:s},t=Math.max(3,Math.floor(t)),i=Math.max(2,Math.floor(i));const o=Math.min(r+s,Math.PI);let l=0;const h=[],c=new xt,u=new xt,d=[],p=[],m=[],f=[];for(let d=0;d<=i;d++){const g=[],v=d/i;let y=0;0===d&&0===r?y=.5/t:d===i&&o===Math.PI&&(y=-.5/t);for(let i=0;i<=t;i++){const o=i/t;c.x=-e*Math.cos(n+o*a)*Math.sin(r+v*s),c.y=e*Math.cos(r+v*s),c.z=e*Math.sin(n+o*a)*Math.sin(r+v*s),p.push(c.x,c.y,c.z),u.copy(c).normalize(),m.push(u.x,u.y,u.z),f.push(o+y,1-v),g.push(l++)}h.push(g)}for(let e=0;e<i;e++)for(let n=0;n<t;n++){const t=h[e][n+1],a=h[e][n],s=h[e+1][n],l=h[e+1][n+1];(0!==e||r>0)&&d.push(t,a,l),(e!==i-1||o<Math.PI)&&d.push(a,s,l)}this.setIndex(d),this.setAttribute("position",new Tn(p,3)),this.setAttribute("normal",new Tn(m,3)),this.setAttribute("uv",new Tn(f,2))}copy(e){return super.copy(e),this.parameters=Object.assign({},e.parameters),this}static fromJSON(e){return new vr(e.radius,e.widthSegments,e.heightSegments,e.phiStart,e.phiLength,e.thetaStart,e.thetaLength)}}class yr extends ur{constructor(e=1,t=0){super([1,1,1,-1,-1,1,-1,1,-1,1,-1,-1],[2,1,0,0,3,2,1,3,0,2,3,1],e,t),this.type="TetrahedronGeometry",this.parameters={radius:e,detail:t}}static fromJSON(e){return new yr(e.radius,e.detail)}}class br extends Bn{constructor(e=1,t=.4,i=12,n=48,a=2*Math.PI){super(),this.type="TorusGeometry",this.parameters={radius:e,tube:t,radialSegments:i,tubularSegments:n,arc:a},i=Math.floor(i),n=Math.floor(n);const r=[],s=[],o=[],l=[],h=new xt,c=new xt,u=new xt;for(let r=0;r<=i;r++)for(let d=0;d<=n;d++){const p=d/n*a,m=r/i*Math.PI*2;c.x=(e+t*Math.cos(m))*Math.cos(p),c.y=(e+t*Math.cos(m))*Math.sin(p),c.z=t*Math.sin(m),s.push(c.x,c.y,c.z),h.x=e*Math.cos(p),h.y=e*Math.sin(p),u.subVectors(c,h).normalize(),o.push(u.x,u.y,u.z),l.push(d/n),l.push(r/i)}for(let e=1;e<=i;e++)for(let t=1;t<=n;t++){const i=(n+1)*e+t-1,a=(n+1)*(e-1)+t-1,s=(n+1)*(e-1)+t,o=(n+1)*e+t;r.push(i,a,o),r.push(a,s,o)}this.setIndex(r),this.setAttribute("position",new Tn(s,3)),this.setAttribute("normal",new Tn(o,3)),this.setAttribute("uv",new Tn(l,2))}copy(e){return super.copy(e),this.parameters=Object.assign({},e.parameters),this}static fromJSON(e){return new br(e.radius,e.tube,e.radialSegments,e.tubularSegments,e.arc)}}class Mr extends fn{constructor(e){super(),this.isMeshStandardMaterial=!0,this.type="MeshStandardMaterial",this.defines={STANDARD:""},this.color=new dn(16777215),this.roughness=1,this.metalness=0,this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.emissive=new dn(0),this.emissiveIntensity=1,this.emissiveMap=null,this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new Mt(1,1),this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.roughnessMap=null,this.metalnessMap=null,this.alphaMap=null,this.envMap=null,this.envMapRotation=new Pi,this.envMapIntensity=1,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.flatShading=!1,this.fog=!0,this.setValues(e)}copy(e){return super.copy(e),this.defines={STANDARD:""},this.color.copy(e.color),this.roughness=e.roughness,this.metalness=e.metalness,this.map=e.map,this.lightMap=e.lightMap,this.lightMapIntensity=e.lightMapIntensity,this.aoMap=e.aoMap,this.aoMapIntensity=e.aoMapIntensity,this.emissive.copy(e.emissive),this.emissiveMap=e.emissiveMap,this.emissiveIntensity=e.emissiveIntensity,this.bumpMap=e.bumpMap,this.bumpScale=e.bumpScale,this.normalMap=e.normalMap,this.normalMapType=e.normalMapType,this.normalScale.copy(e.normalScale),this.displacementMap=e.displacementMap,this.displacementScale=e.displacementScale,this.displacementBias=e.displacementBias,this.roughnessMap=e.roughnessMap,this.metalnessMap=e.metalnessMap,this.alphaMap=e.alphaMap,this.envMap=e.envMap,this.envMapRotation.copy(e.envMapRotation),this.envMapIntensity=e.envMapIntensity,this.wireframe=e.wireframe,this.wireframeLinewidth=e.wireframeLinewidth,this.wireframeLinecap=e.wireframeLinecap,this.wireframeLinejoin=e.wireframeLinejoin,this.flatShading=e.flatShading,this.fog=e.fog,this}}class _r extends Mr{constructor(e){super(),this.isMeshPhysicalMaterial=!0,this.defines={STANDARD:"",PHYSICAL:""},this.type="MeshPhysicalMaterial",this.anisotropyRotation=0,this.anisotropyMap=null,this.clearcoatMap=null,this.clearcoatRoughness=0,this.clearcoatRoughnessMap=null,this.clearcoatNormalScale=new Mt(1,1),this.clearcoatNormalMap=null,this.ior=1.5,Object.defineProperty(this,"reflectivity",{get:function(){return ft(2.5*(this.ior-1)/(this.ior+1),0,1)},set:function(e){this.ior=(1+.4*e)/(1-.4*e)}}),this.iridescenceMap=null,this.iridescenceIOR=1.3,this.iridescenceThicknessRange=[100,400],this.iridescenceThicknessMap=null,this.sheenColor=new dn(0),this.sheenColorMap=null,this.sheenRoughness=1,this.sheenRoughnessMap=null,this.transmissionMap=null,this.thickness=0,this.thicknessMap=null,this.attenuationDistance=1/0,this.attenuationColor=new dn(1,1,1),this.specularIntensity=1,this.specularIntensityMap=null,this.specularColor=new dn(1,1,1),this.specularColorMap=null,this._anisotropy=0,this._clearcoat=0,this._dispersion=0,this._iridescence=0,this._sheen=0,this._transmission=0,this.setValues(e)}get anisotropy(){return this._anisotropy}set anisotropy(e){this._anisotropy>0!=e>0&&this.version++,this._anisotropy=e}get clearcoat(){return this._clearcoat}set clearcoat(e){this._clearcoat>0!=e>0&&this.version++,this._clearcoat=e}get iridescence(){return this._iridescence}set iridescence(e){this._iridescence>0!=e>0&&this.version++,this._iridescence=e}get dispersion(){return this._dispersion}set dispersion(e){this._dispersion>0!=e>0&&this.version++,this._dispersion=e}get sheen(){return this._sheen}set sheen(e){this._sheen>0!=e>0&&this.version++,this._sheen=e}get transmission(){return this._transmission}set transmission(e){this._transmission>0!=e>0&&this.version++,this._transmission=e}copy(e){return super.copy(e),this.defines={STANDARD:"",PHYSICAL:""},this.anisotropy=e.anisotropy,this.anisotropyRotation=e.anisotropyRotation,this.anisotropyMap=e.anisotropyMap,this.clearcoat=e.clearcoat,this.clearcoatMap=e.clearcoatMap,this.clearcoatRoughness=e.clearcoatRoughness,this.clearcoatRoughnessMap=e.clearcoatRoughnessMap,this.clearcoatNormalMap=e.clearcoatNormalMap,this.clearcoatNormalScale.copy(e.clearcoatNormalScale),this.dispersion=e.dispersion,this.ior=e.ior,this.iridescence=e.iridescence,this.iridescenceMap=e.iridescenceMap,this.iridescenceIOR=e.iridescenceIOR,this.iridescenceThicknessRange=[...e.iridescenceThicknessRange],this.iridescenceThicknessMap=e.iridescenceThicknessMap,this.sheen=e.sheen,this.sheenColor.copy(e.sheenColor),this.sheenColorMap=e.sheenColorMap,this.sheenRoughness=e.sheenRoughness,this.sheenRoughnessMap=e.sheenRoughnessMap,this.transmission=e.transmission,this.transmissionMap=e.transmissionMap,this.thickness=e.thickness,this.thicknessMap=e.thicknessMap,this.attenuationDistance=e.attenuationDistance,this.attenuationColor.copy(e.attenuationColor),this.specularIntensity=e.specularIntensity,this.specularIntensityMap=e.specularIntensityMap,this.specularColor.copy(e.specularColor),this.specularColorMap=e.specularColorMap,this}}class xr extends fn{constructor(e){super(),this.isMeshPhongMaterial=!0,this.type="MeshPhongMaterial",this.color=new dn(16777215),this.specular=new dn(1118481),this.shininess=30,this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.emissive=new dn(0),this.emissiveIntensity=1,this.emissiveMap=null,this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new Mt(1,1),this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.specularMap=null,this.alphaMap=null,this.envMap=null,this.envMapRotation=new Pi,this.combine=0,this.reflectivity=1,this.refractionRatio=.98,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.flatShading=!1,this.fog=!0,this.setValues(e)}copy(e){return super.copy(e),this.color.copy(e.color),this.specular.copy(e.specular),this.shininess=e.shininess,this.map=e.map,this.lightMap=e.lightMap,this.lightMapIntensity=e.lightMapIntensity,this.aoMap=e.aoMap,this.aoMapIntensity=e.aoMapIntensity,this.emissive.copy(e.emissive),this.emissiveMap=e.emissiveMap,this.emissiveIntensity=e.emissiveIntensity,this.bumpMap=e.bumpMap,this.bumpScale=e.bumpScale,this.normalMap=e.normalMap,this.normalMapType=e.normalMapType,this.normalScale.copy(e.normalScale),this.displacementMap=e.displacementMap,this.displacementScale=e.displacementScale,this.displacementBias=e.displacementBias,this.specularMap=e.specularMap,this.alphaMap=e.alphaMap,this.envMap=e.envMap,this.envMapRotation.copy(e.envMapRotation),this.combine=e.combine,this.reflectivity=e.reflectivity,this.refractionRatio=e.refractionRatio,this.wireframe=e.wireframe,this.wireframeLinewidth=e.wireframeLinewidth,this.wireframeLinecap=e.wireframeLinecap,this.wireframeLinejoin=e.wireframeLinejoin,this.flatShading=e.flatShading,this.fog=e.fog,this}}class Sr extends fn{constructor(e){super(),this.isMeshDepthMaterial=!0,this.type="MeshDepthMaterial",this.depthPacking=3200,this.map=null,this.alphaMap=null,this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.wireframe=!1,this.wireframeLinewidth=1,this.setValues(e)}copy(e){return super.copy(e),this.depthPacking=e.depthPacking,this.map=e.map,this.alphaMap=e.alphaMap,this.displacementMap=e.displacementMap,this.displacementScale=e.displacementScale,this.displacementBias=e.displacementBias,this.wireframe=e.wireframe,this.wireframeLinewidth=e.wireframeLinewidth,this}}class wr extends fn{constructor(e){super(),this.isMeshDistanceMaterial=!0,this.type="MeshDistanceMaterial",this.map=null,this.alphaMap=null,this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.setValues(e)}copy(e){return super.copy(e),this.map=e.map,this.alphaMap=e.alphaMap,this.displacementMap=e.displacementMap,this.displacementScale=e.displacementScale,this.displacementBias=e.displacementBias,this}}const Er={enabled:!1,files:{},add:function(e,t){!1!==this.enabled&&(this.files[e]=t)},get:function(e){if(!1!==this.enabled)return this.files[e]},remove:function(e){delete this.files[e]},clear:function(){this.files={}}};class Tr{constructor(e,t,i){const n=this;let a,r=!1,s=0,o=0;const l=[];this.onStart=void 0,this.onLoad=e,this.onProgress=t,this.onError=i,this._abortController=null,this.itemStart=function(e){o++,!1===r&&void 0!==n.onStart&&n.onStart(e,s,o),r=!0},this.itemEnd=function(e){s++,void 0!==n.onProgress&&n.onProgress(e,s,o),s===o&&(r=!1,void 0!==n.onLoad&&n.onLoad())},this.itemError=function(e){void 0!==n.onError&&n.onError(e)},this.resolveURL=function(e){return a?a(e):e},this.setURLModifier=function(e){return a=e,this},this.addHandler=function(e,t){return l.push(e,t),this},this.removeHandler=function(e){const t=l.indexOf(e);return-1!==t&&l.splice(t,2),this},this.getHandler=function(e){for(let t=0,i=l.length;t<i;t+=2){const i=l[t],n=l[t+1];if(i.global&&(i.lastIndex=0),i.test(e))return n}return null},this.abort=function(){return this.abortController.abort(),this._abortController=null,this}}get abortController(){return this._abortController||(this._abortController=new AbortController),this._abortController}}const Cr=new Tr;class Ar{constructor(e){this.manager=void 0!==e?e:Cr,this.crossOrigin="anonymous",this.withCredentials=!1,this.path="",this.resourcePath="",this.requestHeader={}}load(){}loadAsync(e,t){const i=this;return new Promise(function(n,a){i.load(e,n,t,a)})}parse(){}setCrossOrigin(e){return this.crossOrigin=e,this}setWithCredentials(e){return this.withCredentials=e,this}setPath(e){return this.path=e,this}setResourcePath(e){return this.resourcePath=e,this}setRequestHeader(e){return this.requestHeader=e,this}abort(){return this}}Ar.DEFAULT_MATERIAL_NAME="__DEFAULT";const Pr={};class Dr extends Error{constructor(e,t){super(e),this.response=t}}class Rr extends Ar{constructor(e){super(e),this.mimeType="",this.responseType="",this._abortController=new AbortController}load(e,t,i,n){void 0===e&&(e=""),void 0!==this.path&&(e=this.path+e),e=this.manager.resolveURL(e);const a=Er.get(`file:${e}`);if(void 0!==a)return this.manager.itemStart(e),setTimeout(()=>{t&&t(a),this.manager.itemEnd(e)},0),a;if(void 0!==Pr[e])return void Pr[e].push({onLoad:t,onProgress:i,onError:n});Pr[e]=[],Pr[e].push({onLoad:t,onProgress:i,onError:n});const r=new Request(e,{headers:new Headers(this.requestHeader),credentials:this.withCredentials?"include":"same-origin",signal:"function"==typeof AbortSignal.any?AbortSignal.any([this._abortController.signal,this.manager.abortController.signal]):this._abortController.signal}),s=this.mimeType,o=this.responseType;fetch(r).then(t=>{if(200===t.status||0===t.status){if(0===t.status&&ot("FileLoader: HTTP Status 0 received."),"undefined"==typeof ReadableStream||void 0===t.body||void 0===t.body.getReader)return t;const i=Pr[e],n=t.body.getReader(),a=t.headers.get("X-File-Size")||t.headers.get("Content-Length"),r=a?parseInt(a):0,s=0!==r;let o=0;const l=new ReadableStream({start(e){!function t(){n.read().then(({done:n,value:a})=>{if(n)e.close();else{o+=a.byteLength;const n=new ProgressEvent("progress",{lengthComputable:s,loaded:o,total:r});for(let e=0,t=i.length;e<t;e++){const t=i[e];t.onProgress&&t.onProgress(n)}e.enqueue(a),t()}},t=>{e.error(t)})}()}});return new Response(l)}throw new Dr(`fetch for "${t.url}" responded with ${t.status}: ${t.statusText}`,t)}).then(e=>{switch(o){case"arraybuffer":return e.arrayBuffer();case"blob":return e.blob();case"document":return e.text().then(e=>(new DOMParser).parseFromString(e,s));case"json":return e.json();default:if(""===s)return e.text();{const t=/charset="?([^;"\s]*)"?/i.exec(s),i=t&&t[1]?t[1].toLowerCase():void 0,n=new TextDecoder(i);return e.arrayBuffer().then(e=>n.decode(e))}}}).then(t=>{Er.add(`file:${e}`,t);const i=Pr[e];delete Pr[e];for(let e=0,n=i.length;e<n;e++){const n=i[e];n.onLoad&&n.onLoad(t)}}).catch(t=>{const i=Pr[e];if(void 0===i)throw this.manager.itemError(e),t;delete Pr[e];for(let e=0,n=i.length;e<n;e++){const n=i[e];n.onError&&n.onError(t)}this.manager.itemError(e)}).finally(()=>{this.manager.itemEnd(e)}),this.manager.itemStart(e)}setResponseType(e){return this.responseType=e,this}setMimeType(e){return this.mimeType=e,this}abort(){return this._abortController.abort(),this._abortController=new AbortController,this}}const Ir=new WeakMap;class Lr extends Ar{constructor(e){super(e)}load(e,t,i,n){void 0!==this.path&&(e=this.path+e),e=this.manager.resolveURL(e);const a=this,r=Er.get(`image:${e}`);if(void 0!==r){if(!0===r.complete)a.manager.itemStart(e),setTimeout(function(){t&&t(r),a.manager.itemEnd(e)},0);else{let e=Ir.get(r);void 0===e&&(e=[],Ir.set(r,e)),e.push({onLoad:t,onError:n})}return r}const s=nt("img");function o(){h(),t&&t(this);const i=Ir.get(this)||[];for(let e=0;e<i.length;e++){const t=i[e];t.onLoad&&t.onLoad(this)}Ir.delete(this),a.manager.itemEnd(e)}function l(t){h(),n&&n(t),Er.remove(`image:${e}`);const i=Ir.get(this)||[];for(let e=0;e<i.length;e++){const n=i[e];n.onError&&n.onError(t)}Ir.delete(this),a.manager.itemError(e),a.manager.itemEnd(e)}function h(){s.removeEventListener("load",o,!1),s.removeEventListener("error",l,!1)}return s.addEventListener("load",o,!1),s.addEventListener("error",l,!1),"data:"!==e.slice(0,5)&&void 0!==this.crossOrigin&&(s.crossOrigin=this.crossOrigin),Er.add(`image:${e}`,s),a.manager.itemStart(e),s.src=e,s}}class Br extends Ar{constructor(e){super(e)}load(e,t,i,n){const a=this,r=new Ia,s=new Rr(this.manager);return s.setResponseType("arraybuffer"),s.setRequestHeader(this.requestHeader),s.setPath(this.path),s.setWithCredentials(a.withCredentials),s.load(e,function(e){let i;try{i=a.parse(e)}catch(e){if(void 0===n)return void e(e);n(e)}void 0!==i.image?r.image=i.image:void 0!==i.data&&(r.image.width=i.width,r.image.height=i.height,r.image.data=i.data),r.wrapS=void 0!==i.wrapS?i.wrapS:O,r.wrapT=void 0!==i.wrapT?i.wrapT:O,r.magFilter=void 0!==i.magFilter?i.magFilter:N,r.minFilter=void 0!==i.minFilter?i.minFilter:N,r.anisotropy=void 0!==i.anisotropy?i.anisotropy:1,void 0!==i.colorSpace&&(r.colorSpace=i.colorSpace),void 0!==i.flipY&&(r.flipY=i.flipY),void 0!==i.format&&(r.format=i.format),void 0!==i.type&&(r.type=i.type),void 0!==i.mipmaps&&(r.mipmaps=i.mipmaps,r.minFilter=V),1===i.mipmapCount&&(r.minFilter=N),void 0!==i.generateMipmaps&&(r.generateMipmaps=i.generateMipmaps),r.needsUpdate=!0,t&&t(r,i)},i,n),r}}class Or extends Ar{constructor(e){super(e)}load(e,t,i,n){const a=new Nt,r=new Lr(this.manager);return r.setCrossOrigin(this.crossOrigin),r.setPath(this.path),r.load(e,function(e){a.image=e,a.needsUpdate=!0,void 0!==t&&t(a)},i,n),a}}class Fr extends Xi{constructor(e,t=1){super(),this.isLight=!0,this.type="Light",this.color=new dn(e),this.intensity=t}dispose(){}copy(e,t){return super.copy(e,t),this.color.copy(e.color),this.intensity=e.intensity,this}toJSON(e){const t=super.toJSON(e);return t.object.color=this.color.getHex(),t.object.intensity=this.intensity,void 0!==this.groundColor&&(t.object.groundColor=this.groundColor.getHex()),void 0!==this.distance&&(t.object.distance=this.distance),void 0!==this.angle&&(t.object.angle=this.angle),void 0!==this.decay&&(t.object.decay=this.decay),void 0!==this.penumbra&&(t.object.penumbra=this.penumbra),void 0!==this.shadow&&(t.object.shadow=this.shadow.toJSON()),void 0!==this.target&&(t.object.target=this.target.uuid),t}}class Ur extends Fr{constructor(e,t,i){super(e,i),this.isHemisphereLight=!0,this.type="HemisphereLight",this.position.copy(Xi.DEFAULT_UP),this.updateMatrix(),this.groundColor=new dn(t)}copy(e,t){return super.copy(e,t),this.groundColor.copy(e.groundColor),this}}const zr=new bi,kr=new xt,Nr=new xt;class Gr{constructor(e){this.camera=e,this.intensity=1,this.bias=0,this.normalBias=0,this.radius=1,this.blurSamples=8,this.mapSize=new Mt(512,512),this.mapType=H,this.map=null,this.mapPass=null,this.matrix=new bi,this.autoUpdate=!0,this.needsUpdate=!1,this._frustum=new Na,this._frameExtents=new Mt(1,1),this._viewportCount=1,this._viewports=[new Gt(0,0,1,1)]}getViewportCount(){return this._viewportCount}getFrustum(){return this._frustum}updateMatrices(e){const t=this.camera,i=this.matrix;kr.setFromMatrixPosition(e.matrixWorld),t.position.copy(kr),Nr.setFromMatrixPosition(e.target.matrixWorld),t.lookAt(Nr),t.updateMatrixWorld(),zr.multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse),this._frustum.setFromProjectionMatrix(zr,t.coordinateSystem,t.reversedDepth),t.reversedDepth?i.set(.5,0,0,.5,0,.5,0,.5,0,0,1,0,0,0,0,1):i.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1),i.multiply(zr)}getViewport(e){return this._viewports[e]}getFrameExtents(){return this._frameExtents}dispose(){this.map&&this.map.dispose(),this.mapPass&&this.mapPass.dispose()}copy(e){return this.camera=e.camera.clone(),this.intensity=e.intensity,this.bias=e.bias,this.radius=e.radius,this.autoUpdate=e.autoUpdate,this.needsUpdate=e.needsUpdate,this.normalBias=e.normalBias,this.blurSamples=e.blurSamples,this.mapSize.copy(e.mapSize),this}clone(){return(new this.constructor).copy(this)}toJSON(){const e={};return 1!==this.intensity&&(e.intensity=this.intensity),0!==this.bias&&(e.bias=this.bias),0!==this.normalBias&&(e.normalBias=this.normalBias),1!==this.radius&&(e.radius=this.radius),512===this.mapSize.x&&512===this.mapSize.y||(e.mapSize=this.mapSize.toArray()),e.camera=this.camera.toJSON(!1).object,delete e.camera.matrix,e}}const Vr=new bi,Hr=new xt,Wr=new xt;class jr extends Gr{constructor(){super(new aa(90,1,.5,500)),this.isPointLightShadow=!0,this._frameExtents=new Mt(4,2),this._viewportCount=6,this._viewports=[new Gt(2,1,1,1),new Gt(0,1,1,1),new Gt(3,1,1,1),new Gt(1,1,1,1),new Gt(3,0,1,1),new Gt(1,0,1,1)],this._cubeDirections=[new xt(1,0,0),new xt(-1,0,0),new xt(0,0,1),new xt(0,0,-1),new xt(0,1,0),new xt(0,-1,0)],this._cubeUps=[new xt(0,1,0),new xt(0,1,0),new xt(0,1,0),new xt(0,1,0),new xt(0,0,1),new xt(0,0,-1)]}updateMatrices(e,t=0){const i=this.camera,n=this.matrix,a=e.distance||i.far;a!==i.far&&(i.far=a,i.updateProjectionMatrix()),Hr.setFromMatrixPosition(e.matrixWorld),i.position.copy(Hr),Wr.copy(i.position),Wr.add(this._cubeDirections[t]),i.up.copy(this._cubeUps[t]),i.lookAt(Wr),i.updateMatrixWorld(),n.makeTranslation(-Hr.x,-Hr.y,-Hr.z),Vr.multiplyMatrices(i.projectionMatrix,i.matrixWorldInverse),this._frustum.setFromProjectionMatrix(Vr,i.coordinateSystem,i.reversedDepth)}}class Xr extends Fr{constructor(e,t,i=0,n=2){super(e,t),this.isPointLight=!0,this.type="PointLight",this.distance=i,this.decay=n,this.shadow=new jr}get power(){return 4*this.intensity*Math.PI}set power(e){this.intensity=e/(4*Math.PI)}dispose(){this.shadow.dispose()}copy(e,t){return super.copy(e,t),this.distance=e.distance,this.decay=e.decay,this.shadow=e.shadow.clone(),this}}class qr extends ea{constructor(e=-1,t=1,i=1,n=-1,a=.1,r=2e3){super(),this.isOrthographicCamera=!0,this.type="OrthographicCamera",this.zoom=1,this.view=null,this.left=e,this.right=t,this.top=i,this.bottom=n,this.near=a,this.far=r,this.updateProjectionMatrix()}copy(e,t){return super.copy(e,t),this.left=e.left,this.right=e.right,this.top=e.top,this.bottom=e.bottom,this.near=e.near,this.far=e.far,this.zoom=e.zoom,this.view=null===e.view?null:Object.assign({},e.view),this}setViewOffset(e,t,i,n,a,r){null===this.view&&(this.view={enabled:!0,fullWidth:1,fullHeight:1,offsetX:0,offsetY:0,width:1,height:1}),this.view.enabled=!0,this.view.fullWidth=e,this.view.fullHeight=t,this.view.offsetX=i,this.view.offsetY=n,this.view.width=a,this.view.height=r,this.updateProjectionMatrix()}clearViewOffset(){null!==this.view&&(this.view.enabled=!1),this.updateProjectionMatrix()}updateProjectionMatrix(){const e=(this.right-this.left)/(2*this.zoom),t=(this.top-this.bottom)/(2*this.zoom),i=(this.right+this.left)/2,n=(this.top+this.bottom)/2;let a=i-e,r=i+e,s=n+t,o=n-t;if(null!==this.view&&this.view.enabled){const e=(this.right-this.left)/this.view.fullWidth/this.zoom,t=(this.top-this.bottom)/this.view.fullHeight/this.zoom;a+=e*this.view.offsetX,r=a+e*this.view.width,s-=t*this.view.offsetY,o=s-t*this.view.height}this.projectionMatrix.makeOrthographic(a,r,s,o,this.near,this.far,this.coordinateSystem,this.reversedDepth),this.projectionMatrixInverse.copy(this.projectionMatrix).invert()}toJSON(e){const t=super.toJSON(e);return t.object.zoom=this.zoom,t.object.left=this.left,t.object.right=this.right,t.object.top=this.top,t.object.bottom=this.bottom,t.object.near=this.near,t.object.far=this.far,null!==this.view&&(t.object.view=Object.assign({},this.view)),t}}class Yr extends Gr{constructor(){super(new qr(-5,5,5,-5,.5,500)),this.isDirectionalLightShadow=!0}}class $r extends Fr{constructor(e,t){super(e,t),this.isDirectionalLight=!0,this.type="DirectionalLight",this.position.copy(Xi.DEFAULT_UP),this.updateMatrix(),this.target=new Xi,this.shadow=new Yr}dispose(){this.shadow.dispose()}copy(e){return super.copy(e),this.target=e.target.clone(),this.shadow=e.shadow.clone(),this}}class Zr extends Fr{constructor(e,t){super(e,t),this.isAmbientLight=!0,this.type="AmbientLight"}}class Kr extends aa{constructor(e=[]){super(),this.isArrayCamera=!0,this.isMultiViewCamera=!1,this.cameras=e}}class Qr{constructor(e=!0){this.autoStart=e,this.startTime=0,this.oldTime=0,this.elapsedTime=0,this.running=!1}start(){this.startTime=performance.now(),this.oldTime=this.startTime,this.elapsedTime=0,this.running=!0}stop(){this.getElapsedTime(),this.running=!1,this.autoStart=!1}getElapsedTime(){return this.getDelta(),this.elapsedTime}getDelta(){let e=0;if(this.autoStart&&!this.running)return this.start(),0;if(this.running){const t=performance.now();e=(t-this.oldTime)/1e3,this.oldTime=t,this.elapsedTime+=e}return e}}class Jr{constructor(e=1,t=0,i=0){this.radius=e,this.phi=t,this.theta=i}set(e,t,i){return this.radius=e,this.phi=t,this.theta=i,this}copy(e){return this.radius=e.radius,this.phi=e.phi,this.theta=e.theta,this}makeSafe(){const e=1e-6;return this.phi=ft(this.phi,e,Math.PI-e),this}setFromVector3(e){return this.setFromCartesianCoords(e.x,e.y,e.z)}setFromCartesianCoords(e,t,i){return this.radius=Math.sqrt(e*e+t*t+i*i),0===this.radius?(this.theta=0,this.phi=0):(this.theta=Math.atan2(e,i),this.phi=Math.acos(ft(t/this.radius,-1,1))),this}clone(){return(new this.constructor).copy(this)}}class es extends ct{constructor(e,t=null){super(),this.object=e,this.domElement=t,this.enabled=!0,this.state=-1,this.keys={},this.mouseButtons={LEFT:null,MIDDLE:null,RIGHT:null},this.touches={ONE:null,TWO:null}}connect(e){void 0!==e?(null!==this.domElement&&this.disconnect(),this.domElement=e):ot("Controls: connect() now requires an element.")}disconnect(){}dispose(){}update(){}}function ts(e,t,i,n){const a=function(e){switch(e){case H:case 1010:return{byteLength:1,components:1};case W:case 1011:case Y:return{byteLength:2,components:1};case $:case Z:return{byteLength:2,components:4};case X:case j:case q:return{byteLength:4,components:1};case 35902:case 35899:return{byteLength:4,components:3}}throw new Error(`Unknown texture type ${e}.`)}(n);switch(i){case 1021:return e*t;case 1028:case te:return e*t/a.components*a.byteLength;case ie:case ne:return e*t*2/a.components*a.byteLength;case 1022:return e*t*3/a.components*a.byteLength;case Q:case ae:return e*t*4/a.components*a.byteLength;case re:case se:return Math.floor((e+3)/4)*Math.floor((t+3)/4)*8;case oe:case le:return Math.floor((e+3)/4)*Math.floor((t+3)/4)*16;case ce:case de:return Math.max(e,16)*Math.max(t,8)/4;case he:case ue:return Math.max(e,8)*Math.max(t,8)/2;case pe:case me:return Math.floor((e+3)/4)*Math.floor((t+3)/4)*8;case fe:case ge:return Math.floor((e+3)/4)*Math.floor((t+3)/4)*16;case ve:return Math.floor((e+4)/5)*Math.floor((t+3)/4)*16;case ye:return Math.floor((e+4)/5)*Math.floor((t+4)/5)*16;case be:return Math.floor((e+5)/6)*Math.floor((t+4)/5)*16;case Me:return Math.floor((e+5)/6)*Math.floor((t+5)/6)*16;case _e:return Math.floor((e+7)/8)*Math.floor((t+4)/5)*16;case xe:return Math.floor((e+7)/8)*Math.floor((t+5)/6)*16;case Se:return Math.floor((e+7)/8)*Math.floor((t+7)/8)*16;case we:return Math.floor((e+9)/10)*Math.floor((t+4)/5)*16;case Ee:return Math.floor((e+9)/10)*Math.floor((t+5)/6)*16;case Te:return Math.floor((e+9)/10)*Math.floor((t+7)/8)*16;case Ce:return Math.floor((e+9)/10)*Math.floor((t+9)/10)*16;case Ae:return Math.floor((e+11)/12)*Math.floor((t+9)/10)*16;case Pe:return Math.floor((e+11)/12)*Math.floor((t+11)/12)*16;case De:case Re:case Ie:return Math.ceil(e/4)*Math.ceil(t/4)*16;case Le:case Be:return Math.ceil(e/4)*Math.ceil(t/4)*8;case Oe:case Fe:return Math.ceil(e/4)*Math.ceil(t/4)*16}throw new Error(`Unable to determine texture byte length for ${i} format.`)}function is(){let e=null,t=!1,i=null,n=null;function a(t,r){i(t,r),n=e.requestAnimationFrame(a)}return{start:function(){!0!==t&&null!==i&&(n=e.requestAnimationFrame(a),t=!0)},stop:function(){e.cancelAnimationFrame(n),t=!1},setAnimationLoop:function(e){i=e},setContext:function(t){e=t}}}function ns(e){const t=new WeakMap;return{get:function(e){return e.isInterleavedBufferAttribute&&(e=e.data),t.get(e)},remove:function(i){i.isInterleavedBufferAttribute&&(i=i.data);const n=t.get(i);n&&(e.deleteBuffer(n.buffer),t.delete(i))},update:function(i,n){if(i.isInterleavedBufferAttribute&&(i=i.data),i.isGLBufferAttribute){const e=t.get(i);return void((!e||e.version<i.version)&&t.set(i,{buffer:i.buffer,type:i.type,bytesPerElement:i.elementSize,version:i.version}))}const a=t.get(i);if(void 0===a)t.set(i,function(t,i){const n=t.array,a=t.usage,r=n.byteLength,s=e.createBuffer();let o;if(e.bindBuffer(i,s),e.bufferData(i,n,a),t.onUploadCallback(),n instanceof Float32Array)o=e.FLOAT;else if("undefined"!=typeof Float16Array&&n instanceof Float16Array)o=e.HALF_FLOAT;else if(n instanceof Uint16Array)o=t.isFloat16BufferAttribute?e.HALF_FLOAT:e.UNSIGNED_SHORT;else if(n instanceof Int16Array)o=e.SHORT;else if(n instanceof Uint32Array)o=e.UNSIGNED_INT;else if(n instanceof Int32Array)o=e.INT;else if(n instanceof Int8Array)o=e.BYTE;else if(n instanceof Uint8Array)o=e.UNSIGNED_BYTE;else{if(!(n instanceof Uint8ClampedArray))throw new Error("THREE.WebGLAttributes: Unsupported buffer data format: "+n);o=e.UNSIGNED_BYTE}return{buffer:s,type:o,bytesPerElement:n.BYTES_PER_ELEMENT,version:t.version,size:r}}(i,n));else if(a.version<i.version){if(a.size!==i.array.byteLength)throw new Error("THREE.WebGLAttributes: The size of the buffer attribute's array buffer does not match the original size. Resizing buffer attributes is not supported.");!function(t,i,n){const a=i.array,r=i.updateRanges;if(e.bindBuffer(n,t),0===r.length)e.bufferSubData(n,0,a);else{r.sort((e,t)=>e.start-t.start);let t=0;for(let e=1;e<r.length;e++){const i=r[t],n=r[e];n.start<=i.start+i.count+1?i.count=Math.max(i.count,n.start+n.count-i.start):(++t,r[t]=n)}r.length=t+1;for(let t=0,i=r.length;t<i;t++){const i=r[t];e.bufferSubData(n,i.start*a.BYTES_PER_ELEMENT,a,i.start,i.count)}i.clearUpdateRanges()}i.onUploadCallback()}(a.buffer,i,n),a.version=i.version}}}}"undefined"!=typeof __THREE_DEVTOOLS__&&__THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("register",{detail:{revision:e}})),"undefined"!=typeof window&&(window.__THREE__?ot("WARNING: Multiple instances of Three.js being imported."):window.__THREE__=e);const as={alphahash_fragment:"#ifdef USE_ALPHAHASH\n\tif ( diffuseColor.a < getAlphaHashThreshold( vPosition ) ) discard;\n#endif",alphahash_pars_fragment:"#ifdef USE_ALPHAHASH\n\tconst float ALPHA_HASH_SCALE = 0.05;\n\tfloat hash2D( vec2 value ) {\n\t\treturn fract( 1.0e4 * sin( 17.0 * value.x + 0.1 * value.y ) * ( 0.1 + abs( sin( 13.0 * value.y + value.x ) ) ) );\n\t}\n\tfloat hash3D( vec3 value ) {\n\t\treturn hash2D( vec2( hash2D( value.xy ), value.z ) );\n\t}\n\tfloat getAlphaHashThreshold( vec3 position ) {\n\t\tfloat maxDeriv = max(\n\t\t\tlength( dFdx( position.xyz ) ),\n\t\t\tlength( dFdy( position.xyz ) )\n\t\t);\n\t\tfloat pixScale = 1.0 / ( ALPHA_HASH_SCALE * maxDeriv );\n\t\tvec2 pixScales = vec2(\n\t\t\texp2( floor( log2( pixScale ) ) ),\n\t\t\texp2( ceil( log2( pixScale ) ) )\n\t\t);\n\t\tvec2 alpha = vec2(\n\t\t\thash3D( floor( pixScales.x * position.xyz ) ),\n\t\t\thash3D( floor( pixScales.y * position.xyz ) )\n\t\t);\n\t\tfloat lerpFactor = fract( log2( pixScale ) );\n\t\tfloat x = ( 1.0 - lerpFactor ) * alpha.x + lerpFactor * alpha.y;\n\t\tfloat a = min( lerpFactor, 1.0 - lerpFactor );\n\t\tvec3 cases = vec3(\n\t\t\tx * x / ( 2.0 * a * ( 1.0 - a ) ),\n\t\t\t( x - 0.5 * a ) / ( 1.0 - a ),\n\t\t\t1.0 - ( ( 1.0 - x ) * ( 1.0 - x ) / ( 2.0 * a * ( 1.0 - a ) ) )\n\t\t);\n\t\tfloat threshold = ( x < ( 1.0 - a ) )\n\t\t\t? ( ( x < a ) ? cases.x : cases.y )\n\t\t\t: cases.z;\n\t\treturn clamp( threshold , 1.0e-6, 1.0 );\n\t}\n#endif",alphamap_fragment:"#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vAlphaMapUv ).g;\n#endif",alphamap_pars_fragment:"#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif",alphatest_fragment:"#ifdef USE_ALPHATEST\n\t#ifdef ALPHA_TO_COVERAGE\n\tdiffuseColor.a = smoothstep( alphaTest, alphaTest + fwidth( diffuseColor.a ), diffuseColor.a );\n\tif ( diffuseColor.a == 0.0 ) discard;\n\t#else\n\tif ( diffuseColor.a < alphaTest ) discard;\n\t#endif\n#endif",alphatest_pars_fragment:"#ifdef USE_ALPHATEST\n\tuniform float alphaTest;\n#endif",aomap_fragment:"#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vAoMapUv ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_CLEARCOAT ) \n\t\tclearcoatSpecularIndirect *= ambientOcclusion;\n\t#endif\n\t#if defined( USE_SHEEN ) \n\t\tsheenSpecularIndirect *= ambientOcclusion;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( STANDARD )\n\t\tfloat dotNV = saturate( dot( geometryNormal, geometryViewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.roughness );\n\t#endif\n#endif",aomap_pars_fragment:"#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif",batching_pars_vertex:"#ifdef USE_BATCHING\n\t#if ! defined( GL_ANGLE_multi_draw )\n\t#define gl_DrawID _gl_DrawID\n\tuniform int _gl_DrawID;\n\t#endif\n\tuniform highp sampler2D batchingTexture;\n\tuniform highp usampler2D batchingIdTexture;\n\tmat4 getBatchingMatrix( const in float i ) {\n\t\tint size = textureSize( batchingTexture, 0 ).x;\n\t\tint j = int( i ) * 4;\n\t\tint x = j % size;\n\t\tint y = j / size;\n\t\tvec4 v1 = texelFetch( batchingTexture, ivec2( x, y ), 0 );\n\t\tvec4 v2 = texelFetch( batchingTexture, ivec2( x + 1, y ), 0 );\n\t\tvec4 v3 = texelFetch( batchingTexture, ivec2( x + 2, y ), 0 );\n\t\tvec4 v4 = texelFetch( batchingTexture, ivec2( x + 3, y ), 0 );\n\t\treturn mat4( v1, v2, v3, v4 );\n\t}\n\tfloat getIndirectIndex( const in int i ) {\n\t\tint size = textureSize( batchingIdTexture, 0 ).x;\n\t\tint x = i % size;\n\t\tint y = i / size;\n\t\treturn float( texelFetch( batchingIdTexture, ivec2( x, y ), 0 ).r );\n\t}\n#endif\n#ifdef USE_BATCHING_COLOR\n\tuniform sampler2D batchingColorTexture;\n\tvec3 getBatchingColor( const in float i ) {\n\t\tint size = textureSize( batchingColorTexture, 0 ).x;\n\t\tint j = int( i );\n\t\tint x = j % size;\n\t\tint y = j / size;\n\t\treturn texelFetch( batchingColorTexture, ivec2( x, y ), 0 ).rgb;\n\t}\n#endif",batching_vertex:"#ifdef USE_BATCHING\n\tmat4 batchingMatrix = getBatchingMatrix( getIndirectIndex( gl_DrawID ) );\n#endif",begin_vertex:"vec3 transformed = vec3( position );\n#ifdef USE_ALPHAHASH\n\tvPosition = vec3( position );\n#endif",beginnormal_vertex:"vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif",bsdfs:"float G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_BlinnPhong( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, 1.0, dotVH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n} // validated",iridescence_fragment:"#ifdef USE_IRIDESCENCE\n\tconst mat3 XYZ_TO_REC709 = mat3(\n\t\t 3.2404542, -0.9692660, 0.0556434,\n\t\t-1.5371385, 1.8760108, -0.2040259,\n\t\t-0.4985314, 0.0415560, 1.0572252\n\t);\n\tvec3 Fresnel0ToIor( vec3 fresnel0 ) {\n\t\tvec3 sqrtF0 = sqrt( fresnel0 );\n\t\treturn ( vec3( 1.0 ) + sqrtF0 ) / ( vec3( 1.0 ) - sqrtF0 );\n\t}\n\tvec3 IorToFresnel0( vec3 transmittedIor, float incidentIor ) {\n\t\treturn pow2( ( transmittedIor - vec3( incidentIor ) ) / ( transmittedIor + vec3( incidentIor ) ) );\n\t}\n\tfloat IorToFresnel0( float transmittedIor, float incidentIor ) {\n\t\treturn pow2( ( transmittedIor - incidentIor ) / ( transmittedIor + incidentIor ));\n\t}\n\tvec3 evalSensitivity( float OPD, vec3 shift ) {\n\t\tfloat phase = 2.0 * PI * OPD * 1.0e-9;\n\t\tvec3 val = vec3( 5.4856e-13, 4.4201e-13, 5.2481e-13 );\n\t\tvec3 pos = vec3( 1.6810e+06, 1.7953e+06, 2.2084e+06 );\n\t\tvec3 var = vec3( 4.3278e+09, 9.3046e+09, 6.6121e+09 );\n\t\tvec3 xyz = val * sqrt( 2.0 * PI * var ) * cos( pos * phase + shift ) * exp( - pow2( phase ) * var );\n\t\txyz.x += 9.7470e-14 * sqrt( 2.0 * PI * 4.5282e+09 ) * cos( 2.2399e+06 * phase + shift[ 0 ] ) * exp( - 4.5282e+09 * pow2( phase ) );\n\t\txyz /= 1.0685e-7;\n\t\tvec3 rgb = XYZ_TO_REC709 * xyz;\n\t\treturn rgb;\n\t}\n\tvec3 evalIridescence( float outsideIOR, float eta2, float cosTheta1, float thinFilmThickness, vec3 baseF0 ) {\n\t\tvec3 I;\n\t\tfloat iridescenceIOR = mix( outsideIOR, eta2, smoothstep( 0.0, 0.03, thinFilmThickness ) );\n\t\tfloat sinTheta2Sq = pow2( outsideIOR / iridescenceIOR ) * ( 1.0 - pow2( cosTheta1 ) );\n\t\tfloat cosTheta2Sq = 1.0 - sinTheta2Sq;\n\t\tif ( cosTheta2Sq < 0.0 ) {\n\t\t\treturn vec3( 1.0 );\n\t\t}\n\t\tfloat cosTheta2 = sqrt( cosTheta2Sq );\n\t\tfloat R0 = IorToFresnel0( iridescenceIOR, outsideIOR );\n\t\tfloat R12 = F_Schlick( R0, 1.0, cosTheta1 );\n\t\tfloat T121 = 1.0 - R12;\n\t\tfloat phi12 = 0.0;\n\t\tif ( iridescenceIOR < outsideIOR ) phi12 = PI;\n\t\tfloat phi21 = PI - phi12;\n\t\tvec3 baseIOR = Fresnel0ToIor( clamp( baseF0, 0.0, 0.9999 ) );\t\tvec3 R1 = IorToFresnel0( baseIOR, iridescenceIOR );\n\t\tvec3 R23 = F_Schlick( R1, 1.0, cosTheta2 );\n\t\tvec3 phi23 = vec3( 0.0 );\n\t\tif ( baseIOR[ 0 ] < iridescenceIOR ) phi23[ 0 ] = PI;\n\t\tif ( baseIOR[ 1 ] < iridescenceIOR ) phi23[ 1 ] = PI;\n\t\tif ( baseIOR[ 2 ] < iridescenceIOR ) phi23[ 2 ] = PI;\n\t\tfloat OPD = 2.0 * iridescenceIOR * thinFilmThickness * cosTheta2;\n\t\tvec3 phi = vec3( phi21 ) + phi23;\n\t\tvec3 R123 = clamp( R12 * R23, 1e-5, 0.9999 );\n\t\tvec3 r123 = sqrt( R123 );\n\t\tvec3 Rs = pow2( T121 ) * R23 / ( vec3( 1.0 ) - R123 );\n\t\tvec3 C0 = R12 + Rs;\n\t\tI = C0;\n\t\tvec3 Cm = Rs - T121;\n\t\tfor ( int m = 1; m <= 2; ++ m ) {\n\t\t\tCm *= r123;\n\t\t\tvec3 Sm = 2.0 * evalSensitivity( float( m ) * OPD, float( m ) * phi );\n\t\t\tI += Cm * Sm;\n\t\t}\n\t\treturn max( I, vec3( 0.0 ) );\n\t}\n#endif",bumpmap_pars_fragment:"#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vBumpMapUv );\n\t\tvec2 dSTdy = dFdy( vBumpMapUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vBumpMapUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vBumpMapUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vBumpMapUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy, float faceDirection ) {\n\t\tvec3 vSigmaX = normalize( dFdx( surf_pos.xyz ) );\n\t\tvec3 vSigmaY = normalize( dFdy( surf_pos.xyz ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 ) * faceDirection;\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif",clipping_planes_fragment:"#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#ifdef ALPHA_TO_COVERAGE\n\t\tfloat distanceToPlane, distanceGradient;\n\t\tfloat clipOpacity = 1.0;\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tdistanceToPlane = - dot( vClipPosition, plane.xyz ) + plane.w;\n\t\t\tdistanceGradient = fwidth( distanceToPlane ) / 2.0;\n\t\t\tclipOpacity *= smoothstep( - distanceGradient, distanceGradient, distanceToPlane );\n\t\t\tif ( clipOpacity == 0.0 ) discard;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\t\tfloat unionClipOpacity = 1.0;\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\t\tplane = clippingPlanes[ i ];\n\t\t\t\tdistanceToPlane = - dot( vClipPosition, plane.xyz ) + plane.w;\n\t\t\t\tdistanceGradient = fwidth( distanceToPlane ) / 2.0;\n\t\t\t\tunionClipOpacity *= 1.0 - smoothstep( - distanceGradient, distanceGradient, distanceToPlane );\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t\tclipOpacity *= 1.0 - unionClipOpacity;\n\t\t#endif\n\t\tdiffuseColor.a *= clipOpacity;\n\t\tif ( diffuseColor.a == 0.0 ) discard;\n\t#else\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tif ( dot( vClipPosition, plane.xyz ) > plane.w ) discard;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\t\tbool clipped = true;\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\t\tplane = clippingPlanes[ i ];\n\t\t\t\tclipped = ( dot( vClipPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t\tif ( clipped ) discard;\n\t\t#endif\n\t#endif\n#endif",clipping_planes_pars_fragment:"#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif",clipping_planes_pars_vertex:"#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n#endif",clipping_planes_vertex:"#if NUM_CLIPPING_PLANES > 0\n\tvClipPosition = - mvPosition.xyz;\n#endif",color_fragment:"#if defined( USE_COLOR_ALPHA )\n\tdiffuseColor *= vColor;\n#elif defined( USE_COLOR )\n\tdiffuseColor.rgb *= vColor;\n#endif",color_pars_fragment:"#if defined( USE_COLOR_ALPHA )\n\tvarying vec4 vColor;\n#elif defined( USE_COLOR )\n\tvarying vec3 vColor;\n#endif",color_pars_vertex:"#if defined( USE_COLOR_ALPHA )\n\tvarying vec4 vColor;\n#elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR ) || defined( USE_BATCHING_COLOR )\n\tvarying vec3 vColor;\n#endif",color_vertex:"#if defined( USE_COLOR_ALPHA )\n\tvColor = vec4( 1.0 );\n#elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR ) || defined( USE_BATCHING_COLOR )\n\tvColor = vec3( 1.0 );\n#endif\n#ifdef USE_COLOR\n\tvColor *= color;\n#endif\n#ifdef USE_INSTANCING_COLOR\n\tvColor.xyz *= instanceColor.xyz;\n#endif\n#ifdef USE_BATCHING_COLOR\n\tvec3 batchingColor = getBatchingColor( getIndirectIndex( gl_DrawID ) );\n\tvColor.xyz *= batchingColor.xyz;\n#endif",common:"#define PI 3.141592653589793\n#define PI2 6.283185307179586\n#define PI_HALF 1.5707963267948966\n#define RECIPROCAL_PI 0.3183098861837907\n#define RECIPROCAL_PI2 0.15915494309189535\n#define EPSILON 1e-6\n#ifndef saturate\n#define saturate( a ) clamp( a, 0.0, 1.0 )\n#endif\n#define whiteComplement( a ) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nvec3 pow2( const in vec3 x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat max3( const in vec3 v ) { return max( max( v.x, v.y ), v.z ); }\nfloat average( const in vec3 v ) { return dot( v, vec3( 0.3333333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract( sin( sn ) * c );\n}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat precisionSafeLength( vec3 v ) {\n\t\tfloat maxComponent = max3( abs( v ) );\n\t\treturn length( v / maxComponent ) * maxComponent;\n\t}\n#endif\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\n#ifdef USE_ALPHAHASH\n\tvarying vec3 vPosition;\n#endif\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nbool isPerspectiveMatrix( mat4 m ) {\n\treturn m[ 2 ][ 3 ] == - 1.0;\n}\nvec2 equirectUv( in vec3 dir ) {\n\tfloat u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;\n\tfloat v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\treturn vec2( u, v );\n}\nvec3 BRDF_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n}\nfloat F_Schlick( const in float f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n} // validated",cube_uv_reflection_fragment:"#ifdef ENVMAP_TYPE_CUBE_UV\n\t#define cubeUV_minMipLevel 4.0\n\t#define cubeUV_minTileSize 16.0\n\tfloat getFace( vec3 direction ) {\n\t\tvec3 absDirection = abs( direction );\n\t\tfloat face = - 1.0;\n\t\tif ( absDirection.x > absDirection.z ) {\n\t\t\tif ( absDirection.x > absDirection.y )\n\t\t\t\tface = direction.x > 0.0 ? 0.0 : 3.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t} else {\n\t\t\tif ( absDirection.z > absDirection.y )\n\t\t\t\tface = direction.z > 0.0 ? 2.0 : 5.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t}\n\t\treturn face;\n\t}\n\tvec2 getUV( vec3 direction, float face ) {\n\t\tvec2 uv;\n\t\tif ( face == 0.0 ) {\n\t\t\tuv = vec2( direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 1.0 ) {\n\t\t\tuv = vec2( - direction.x, - direction.z ) / abs( direction.y );\n\t\t} else if ( face == 2.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.y ) / abs( direction.z );\n\t\t} else if ( face == 3.0 ) {\n\t\t\tuv = vec2( - direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 4.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.z ) / abs( direction.y );\n\t\t} else {\n\t\t\tuv = vec2( direction.x, direction.y ) / abs( direction.z );\n\t\t}\n\t\treturn 0.5 * ( uv + 1.0 );\n\t}\n\tvec3 bilinearCubeUV( sampler2D envMap, vec3 direction, float mipInt ) {\n\t\tfloat face = getFace( direction );\n\t\tfloat filterInt = max( cubeUV_minMipLevel - mipInt, 0.0 );\n\t\tmipInt = max( mipInt, cubeUV_minMipLevel );\n\t\tfloat faceSize = exp2( mipInt );\n\t\thighp vec2 uv = getUV( direction, face ) * ( faceSize - 2.0 ) + 1.0;\n\t\tif ( face > 2.0 ) {\n\t\t\tuv.y += faceSize;\n\t\t\tface -= 3.0;\n\t\t}\n\t\tuv.x += face * faceSize;\n\t\tuv.x += filterInt * 3.0 * cubeUV_minTileSize;\n\t\tuv.y += 4.0 * ( exp2( CUBEUV_MAX_MIP ) - faceSize );\n\t\tuv.x *= CUBEUV_TEXEL_WIDTH;\n\t\tuv.y *= CUBEUV_TEXEL_HEIGHT;\n\t\t#ifdef texture2DGradEXT\n\t\t\treturn texture2DGradEXT( envMap, uv, vec2( 0.0 ), vec2( 0.0 ) ).rgb;\n\t\t#else\n\t\t\treturn texture2D( envMap, uv ).rgb;\n\t\t#endif\n\t}\n\t#define cubeUV_r0 1.0\n\t#define cubeUV_m0 - 2.0\n\t#define cubeUV_r1 0.8\n\t#define cubeUV_m1 - 1.0\n\t#define cubeUV_r4 0.4\n\t#define cubeUV_m4 2.0\n\t#define cubeUV_r5 0.305\n\t#define cubeUV_m5 3.0\n\t#define cubeUV_r6 0.21\n\t#define cubeUV_m6 4.0\n\tfloat roughnessToMip( float roughness ) {\n\t\tfloat mip = 0.0;\n\t\tif ( roughness >= cubeUV_r1 ) {\n\t\t\tmip = ( cubeUV_r0 - roughness ) * ( cubeUV_m1 - cubeUV_m0 ) / ( cubeUV_r0 - cubeUV_r1 ) + cubeUV_m0;\n\t\t} else if ( roughness >= cubeUV_r4 ) {\n\t\t\tmip = ( cubeUV_r1 - roughness ) * ( cubeUV_m4 - cubeUV_m1 ) / ( cubeUV_r1 - cubeUV_r4 ) + cubeUV_m1;\n\t\t} else if ( roughness >= cubeUV_r5 ) {\n\t\t\tmip = ( cubeUV_r4 - roughness ) * ( cubeUV_m5 - cubeUV_m4 ) / ( cubeUV_r4 - cubeUV_r5 ) + cubeUV_m4;\n\t\t} else if ( roughness >= cubeUV_r6 ) {\n\t\t\tmip = ( cubeUV_r5 - roughness ) * ( cubeUV_m6 - cubeUV_m5 ) / ( cubeUV_r5 - cubeUV_r6 ) + cubeUV_m5;\n\t\t} else {\n\t\t\tmip = - 2.0 * log2( 1.16 * roughness );\t\t}\n\t\treturn mip;\n\t}\n\tvec4 textureCubeUV( sampler2D envMap, vec3 sampleDir, float roughness ) {\n\t\tfloat mip = clamp( roughnessToMip( roughness ), cubeUV_m0, CUBEUV_MAX_MIP );\n\t\tfloat mipF = fract( mip );\n\t\tfloat mipInt = floor( mip );\n\t\tvec3 color0 = bilinearCubeUV( envMap, sampleDir, mipInt );\n\t\tif ( mipF == 0.0 ) {\n\t\t\treturn vec4( color0, 1.0 );\n\t\t} else {\n\t\t\tvec3 color1 = bilinearCubeUV( envMap, sampleDir, mipInt + 1.0 );\n\t\t\treturn vec4( mix( color0, color1, mipF ), 1.0 );\n\t\t}\n\t}\n#endif",defaultnormal_vertex:"vec3 transformedNormal = objectNormal;\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = objectTangent;\n#endif\n#ifdef USE_BATCHING\n\tmat3 bm = mat3( batchingMatrix );\n\ttransformedNormal /= vec3( dot( bm[ 0 ], bm[ 0 ] ), dot( bm[ 1 ], bm[ 1 ] ), dot( bm[ 2 ], bm[ 2 ] ) );\n\ttransformedNormal = bm * transformedNormal;\n\t#ifdef USE_TANGENT\n\t\ttransformedTangent = bm * transformedTangent;\n\t#endif\n#endif\n#ifdef USE_INSTANCING\n\tmat3 im = mat3( instanceMatrix );\n\ttransformedNormal /= vec3( dot( im[ 0 ], im[ 0 ] ), dot( im[ 1 ], im[ 1 ] ), dot( im[ 2 ], im[ 2 ] ) );\n\ttransformedNormal = im * transformedNormal;\n\t#ifdef USE_TANGENT\n\t\ttransformedTangent = im * transformedTangent;\n\t#endif\n#endif\ntransformedNormal = normalMatrix * transformedNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\ttransformedTangent = ( modelViewMatrix * vec4( transformedTangent, 0.0 ) ).xyz;\n\t#ifdef FLIP_SIDED\n\t\ttransformedTangent = - transformedTangent;\n\t#endif\n#endif",displacementmap_pars_vertex:"#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif",displacementmap_vertex:"#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, vDisplacementMapUv ).x * displacementScale + displacementBias );\n#endif",emissivemap_fragment:"#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vEmissiveMapUv );\n\t#ifdef DECODE_VIDEO_TEXTURE_EMISSIVE\n\t\temissiveColor = sRGBTransferEOTF( emissiveColor );\n\t#endif\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif",emissivemap_pars_fragment:"#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif",colorspace_fragment:"gl_FragColor = linearToOutputTexel( gl_FragColor );",colorspace_pars_fragment:"vec4 LinearTransferOETF( in vec4 value ) {\n\treturn value;\n}\nvec4 sRGBTransferEOTF( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );\n}\nvec4 sRGBTransferOETF( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );\n}",envmap_fragment:"#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvec3 cameraToFrag;\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToFrag = normalize( vWorldPosition - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToFrag, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToFrag, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, envMapRotation * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif",envmap_common_pars_fragment:"#ifdef USE_ENVMAP\n\tuniform float envMapIntensity;\n\tuniform float flipEnvMap;\n\tuniform mat3 envMapRotation;\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n#endif",envmap_pars_fragment:"#ifdef USE_ENVMAP\n\tuniform float reflectivity;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\tvarying vec3 vWorldPosition;\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif",envmap_pars_vertex:"#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\t\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif",envmap_physical_pars_fragment:"#ifdef USE_ENVMAP\n\tvec3 getIBLIrradiance( const in vec3 normal ) {\n\t\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, envMapRotation * worldNormal, 1.0 );\n\t\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t\t#else\n\t\t\treturn vec3( 0.0 );\n\t\t#endif\n\t}\n\tvec3 getIBLRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness ) {\n\t\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t\tvec3 reflectVec = reflect( - viewDir, normal );\n\t\t\treflectVec = normalize( mix( reflectVec, normal, pow4( roughness ) ) );\n\t\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, envMapRotation * reflectVec, roughness );\n\t\t\treturn envMapColor.rgb * envMapIntensity;\n\t\t#else\n\t\t\treturn vec3( 0.0 );\n\t\t#endif\n\t}\n\t#ifdef USE_ANISOTROPY\n\t\tvec3 getIBLAnisotropyRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in vec3 bitangent, const in float anisotropy ) {\n\t\t\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t\t\tvec3 bentNormal = cross( bitangent, viewDir );\n\t\t\t\tbentNormal = normalize( cross( bentNormal, bitangent ) );\n\t\t\t\tbentNormal = normalize( mix( bentNormal, normal, pow2( pow2( 1.0 - anisotropy * ( 1.0 - roughness ) ) ) ) );\n\t\t\t\treturn getIBLRadiance( viewDir, bentNormal, roughness );\n\t\t\t#else\n\t\t\t\treturn vec3( 0.0 );\n\t\t\t#endif\n\t\t}\n\t#endif\n#endif",envmap_vertex:"#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex;\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToVertex = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif",fog_vertex:"#ifdef USE_FOG\n\tvFogDepth = - mvPosition.z;\n#endif",fog_pars_vertex:"#ifdef USE_FOG\n\tvarying float vFogDepth;\n#endif",fog_fragment:"#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, vFogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif",fog_pars_fragment:"#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float vFogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif",gradientmap_pars_fragment:"#ifdef USE_GRADIENTMAP\n\tuniform sampler2D gradientMap;\n#endif\nvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\tfloat dotNL = dot( normal, lightDirection );\n\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t#ifdef USE_GRADIENTMAP\n\t\treturn vec3( texture2D( gradientMap, coord ).r );\n\t#else\n\t\tvec2 fw = fwidth( coord ) * 0.5;\n\t\treturn mix( vec3( 0.7 ), vec3( 1.0 ), smoothstep( 0.7 - fw.x, 0.7 + fw.x, coord.x ) );\n\t#endif\n}",lightmap_pars_fragment:"#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif",lights_lambert_fragment:"LambertMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularStrength = specularStrength;",lights_lambert_pars_fragment:"varying vec3 vViewPosition;\nstruct LambertMaterial {\n\tvec3 diffuseColor;\n\tfloat specularStrength;\n};\nvoid RE_Direct_Lambert( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Lambert( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Lambert\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Lambert",lights_pars_begin:"uniform bool receiveShadow;\nuniform vec3 ambientLightColor;\n#if defined( USE_LIGHT_PROBES )\n\tuniform vec3 lightProbe[ 9 ];\n#endif\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n\tfloat x = normal.x, y = normal.y, z = normal.z;\n\tvec3 result = shCoefficients[ 0 ] * 0.886227;\n\tresult += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n\tresult += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n\tresult += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n\tresult += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n\tresult += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n\tresult += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n\tresult += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n\tresult += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n\treturn result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in vec3 normal ) {\n\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\treturn irradiance;\n}\nfloat getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif ( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n}\nfloat getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {\n\treturn smoothstep( coneCosine, penumbraCosine, angleCosine );\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalLightInfo( const in DirectionalLight directionalLight, out IncidentLight light ) {\n\t\tlight.color = directionalLight.color;\n\t\tlight.direction = directionalLight.direction;\n\t\tlight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointLightInfo( const in PointLight pointLight, const in vec3 geometryPosition, out IncidentLight light ) {\n\t\tvec3 lVector = pointLight.position - geometryPosition;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tlight.color = pointLight.color;\n\t\tlight.color *= getDistanceAttenuation( lightDistance, pointLight.distance, pointLight.decay );\n\t\tlight.visible = ( light.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotLightInfo( const in SpotLight spotLight, const in vec3 geometryPosition, out IncidentLight light ) {\n\t\tvec3 lVector = spotLight.position - geometryPosition;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat angleCos = dot( light.direction, spotLight.direction );\n\t\tfloat spotAttenuation = getSpotAttenuation( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\tif ( spotAttenuation > 0.0 ) {\n\t\t\tfloat lightDistance = length( lVector );\n\t\t\tlight.color = spotLight.color * spotAttenuation;\n\t\t\tlight.color *= getDistanceAttenuation( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tlight.visible = ( light.color != vec3( 0.0 ) );\n\t\t} else {\n\t\t\tlight.color = vec3( 0.0 );\n\t\t\tlight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in vec3 normal ) {\n\t\tfloat dotNL = dot( normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\treturn irradiance;\n\t}\n#endif",lights_toon_fragment:"ToonMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;",lights_toon_pars_fragment:"varying vec3 vViewPosition;\nstruct ToonMaterial {\n\tvec3 diffuseColor;\n};\nvoid RE_Direct_Toon( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\tvec3 irradiance = getGradientIrradiance( geometryNormal, directLight.direction ) * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Toon\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Toon",lights_phong_fragment:"BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;",lights_phong_pars_fragment:"varying vec3 vViewPosition;\nstruct BlinnPhongMaterial {\n\tvec3 diffuseColor;\n\tvec3 specularColor;\n\tfloat specularShininess;\n\tfloat specularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometryViewDir, geometryNormal, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong",lights_physical_fragment:"PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nvec3 dxy = max( abs( dFdx( nonPerturbedNormal ) ), abs( dFdy( nonPerturbedNormal ) ) );\nfloat geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );\nmaterial.roughness = max( roughnessFactor, 0.0525 );material.roughness += geometryRoughness;\nmaterial.roughness = min( material.roughness, 1.0 );\n#ifdef IOR\n\tmaterial.ior = ior;\n\t#ifdef USE_SPECULAR\n\t\tfloat specularIntensityFactor = specularIntensity;\n\t\tvec3 specularColorFactor = specularColor;\n\t\t#ifdef USE_SPECULAR_COLORMAP\n\t\t\tspecularColorFactor *= texture2D( specularColorMap, vSpecularColorMapUv ).rgb;\n\t\t#endif\n\t\t#ifdef USE_SPECULAR_INTENSITYMAP\n\t\t\tspecularIntensityFactor *= texture2D( specularIntensityMap, vSpecularIntensityMapUv ).a;\n\t\t#endif\n\t\tmaterial.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );\n\t#else\n\t\tfloat specularIntensityFactor = 1.0;\n\t\tvec3 specularColorFactor = vec3( 1.0 );\n\t\tmaterial.specularF90 = 1.0;\n\t#endif\n\tmaterial.specularColor = mix( min( pow2( ( material.ior - 1.0 ) / ( material.ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor, diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.specularF90 = 1.0;\n#endif\n#ifdef USE_CLEARCOAT\n\tmaterial.clearcoat = clearcoat;\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\tmaterial.clearcoatF0 = vec3( 0.04 );\n\tmaterial.clearcoatF90 = 1.0;\n\t#ifdef USE_CLEARCOATMAP\n\t\tmaterial.clearcoat *= texture2D( clearcoatMap, vClearcoatMapUv ).x;\n\t#endif\n\t#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\t\tmaterial.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vClearcoatRoughnessMapUv ).y;\n\t#endif\n\tmaterial.clearcoat = saturate( material.clearcoat );\tmaterial.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );\n\tmaterial.clearcoatRoughness += geometryRoughness;\n\tmaterial.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );\n#endif\n#ifdef USE_DISPERSION\n\tmaterial.dispersion = dispersion;\n#endif\n#ifdef USE_IRIDESCENCE\n\tmaterial.iridescence = iridescence;\n\tmaterial.iridescenceIOR = iridescenceIOR;\n\t#ifdef USE_IRIDESCENCEMAP\n\t\tmaterial.iridescence *= texture2D( iridescenceMap, vIridescenceMapUv ).r;\n\t#endif\n\t#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\t\tmaterial.iridescenceThickness = (iridescenceThicknessMaximum - iridescenceThicknessMinimum) * texture2D( iridescenceThicknessMap, vIridescenceThicknessMapUv ).g + iridescenceThicknessMinimum;\n\t#else\n\t\tmaterial.iridescenceThickness = iridescenceThicknessMaximum;\n\t#endif\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheenColor;\n\t#ifdef USE_SHEEN_COLORMAP\n\t\tmaterial.sheenColor *= texture2D( sheenColorMap, vSheenColorMapUv ).rgb;\n\t#endif\n\tmaterial.sheenRoughness = clamp( sheenRoughness, 0.07, 1.0 );\n\t#ifdef USE_SHEEN_ROUGHNESSMAP\n\t\tmaterial.sheenRoughness *= texture2D( sheenRoughnessMap, vSheenRoughnessMapUv ).a;\n\t#endif\n#endif\n#ifdef USE_ANISOTROPY\n\t#ifdef USE_ANISOTROPYMAP\n\t\tmat2 anisotropyMat = mat2( anisotropyVector.x, anisotropyVector.y, - anisotropyVector.y, anisotropyVector.x );\n\t\tvec3 anisotropyPolar = texture2D( anisotropyMap, vAnisotropyMapUv ).rgb;\n\t\tvec2 anisotropyV = anisotropyMat * normalize( 2.0 * anisotropyPolar.rg - vec2( 1.0 ) ) * anisotropyPolar.b;\n\t#else\n\t\tvec2 anisotropyV = anisotropyVector;\n\t#endif\n\tmaterial.anisotropy = length( anisotropyV );\n\tif( material.anisotropy == 0.0 ) {\n\t\tanisotropyV = vec2( 1.0, 0.0 );\n\t} else {\n\t\tanisotropyV /= material.anisotropy;\n\t\tmaterial.anisotropy = saturate( material.anisotropy );\n\t}\n\tmaterial.alphaT = mix( pow2( material.roughness ), 1.0, pow2( material.anisotropy ) );\n\tmaterial.anisotropyT = tbn[ 0 ] * anisotropyV.x + tbn[ 1 ] * anisotropyV.y;\n\tmaterial.anisotropyB = tbn[ 1 ] * anisotropyV.x - tbn[ 0 ] * anisotropyV.y;\n#endif",lights_physical_pars_fragment:"uniform sampler2D dfgLUT;\nstruct PhysicalMaterial {\n\tvec3 diffuseColor;\n\tfloat roughness;\n\tvec3 specularColor;\n\tfloat specularF90;\n\tfloat dispersion;\n\t#ifdef USE_CLEARCOAT\n\t\tfloat clearcoat;\n\t\tfloat clearcoatRoughness;\n\t\tvec3 clearcoatF0;\n\t\tfloat clearcoatF90;\n\t#endif\n\t#ifdef USE_IRIDESCENCE\n\t\tfloat iridescence;\n\t\tfloat iridescenceIOR;\n\t\tfloat iridescenceThickness;\n\t\tvec3 iridescenceFresnel;\n\t\tvec3 iridescenceF0;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tvec3 sheenColor;\n\t\tfloat sheenRoughness;\n\t#endif\n\t#ifdef IOR\n\t\tfloat ior;\n\t#endif\n\t#ifdef USE_TRANSMISSION\n\t\tfloat transmission;\n\t\tfloat transmissionAlpha;\n\t\tfloat thickness;\n\t\tfloat attenuationDistance;\n\t\tvec3 attenuationColor;\n\t#endif\n\t#ifdef USE_ANISOTROPY\n\t\tfloat anisotropy;\n\t\tfloat alphaT;\n\t\tvec3 anisotropyT;\n\t\tvec3 anisotropyB;\n\t#endif\n};\nvec3 clearcoatSpecularDirect = vec3( 0.0 );\nvec3 clearcoatSpecularIndirect = vec3( 0.0 );\nvec3 sheenSpecularDirect = vec3( 0.0 );\nvec3 sheenSpecularIndirect = vec3(0.0 );\nvec3 Schlick_to_F0( const in vec3 f, const in float f90, const in float dotVH ) {\n float x = clamp( 1.0 - dotVH, 0.0, 1.0 );\n float x2 = x * x;\n float x5 = clamp( x * x2 * x2, 0.0, 0.9999 );\n return ( f - vec3( f90 ) * x5 ) / ( 1.0 - x5 );\n}\nfloat V_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\n#ifdef USE_ANISOTROPY\n\tfloat V_GGX_SmithCorrelated_Anisotropic( const in float alphaT, const in float alphaB, const in float dotTV, const in float dotBV, const in float dotTL, const in float dotBL, const in float dotNV, const in float dotNL ) {\n\t\tfloat gv = dotNL * length( vec3( alphaT * dotTV, alphaB * dotBV, dotNV ) );\n\t\tfloat gl = dotNV * length( vec3( alphaT * dotTL, alphaB * dotBL, dotNL ) );\n\t\tfloat v = 0.5 / ( gv + gl );\n\t\treturn saturate(v);\n\t}\n\tfloat D_GGX_Anisotropic( const in float alphaT, const in float alphaB, const in float dotNH, const in float dotTH, const in float dotBH ) {\n\t\tfloat a2 = alphaT * alphaB;\n\t\thighp vec3 v = vec3( alphaB * dotTH, alphaT * dotBH, a2 * dotNH );\n\t\thighp float v2 = dot( v, v );\n\t\tfloat w2 = a2 / v2;\n\t\treturn RECIPROCAL_PI * a2 * pow2 ( w2 );\n\t}\n#endif\n#ifdef USE_CLEARCOAT\n\tvec3 BRDF_GGX_Clearcoat( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material) {\n\t\tvec3 f0 = material.clearcoatF0;\n\t\tfloat f90 = material.clearcoatF90;\n\t\tfloat roughness = material.clearcoatRoughness;\n\t\tfloat alpha = pow2( roughness );\n\t\tvec3 halfDir = normalize( lightDir + viewDir );\n\t\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\t\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\t\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\t\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\t\tvec3 F = F_Schlick( f0, f90, dotVH );\n\t\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\t\tfloat D = D_GGX( alpha, dotNH );\n\t\treturn F * ( V * D );\n\t}\n#endif\nvec3 BRDF_GGX( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material ) {\n\tvec3 f0 = material.specularColor;\n\tfloat f90 = material.specularF90;\n\tfloat roughness = material.roughness;\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\tvec3 F = F_Schlick( f0, f90, dotVH );\n\t#ifdef USE_IRIDESCENCE\n\t\tF = mix( F, material.iridescenceFresnel, material.iridescence );\n\t#endif\n\t#ifdef USE_ANISOTROPY\n\t\tfloat dotTL = dot( material.anisotropyT, lightDir );\n\t\tfloat dotTV = dot( material.anisotropyT, viewDir );\n\t\tfloat dotTH = dot( material.anisotropyT, halfDir );\n\t\tfloat dotBL = dot( material.anisotropyB, lightDir );\n\t\tfloat dotBV = dot( material.anisotropyB, viewDir );\n\t\tfloat dotBH = dot( material.anisotropyB, halfDir );\n\t\tfloat V = V_GGX_SmithCorrelated_Anisotropic( material.alphaT, alpha, dotTV, dotBV, dotTL, dotBL, dotNV, dotNL );\n\t\tfloat D = D_GGX_Anisotropic( material.alphaT, alpha, dotNH, dotTH, dotBH );\n\t#else\n\t\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\t\tfloat D = D_GGX( alpha, dotNH );\n\t#endif\n\treturn F * ( V * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transpose( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\n#if defined( USE_SHEEN )\nfloat D_Charlie( float roughness, float dotNH ) {\n\tfloat alpha = pow2( roughness );\n\tfloat invAlpha = 1.0 / alpha;\n\tfloat cos2h = dotNH * dotNH;\n\tfloat sin2h = max( 1.0 - cos2h, 0.0078125 );\n\treturn ( 2.0 + invAlpha ) * pow( sin2h, invAlpha * 0.5 ) / ( 2.0 * PI );\n}\nfloat V_Neubelt( float dotNV, float dotNL ) {\n\treturn saturate( 1.0 / ( 4.0 * ( dotNL + dotNV - dotNL * dotNV ) ) );\n}\nvec3 BRDF_Sheen( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, vec3 sheenColor, const in float sheenRoughness ) {\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat D = D_Charlie( sheenRoughness, dotNH );\n\tfloat V = V_Neubelt( dotNV, dotNL );\n\treturn sheenColor * ( D * V );\n}\n#endif\nfloat IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat r2 = roughness * roughness;\n\tfloat a = roughness < 0.25 ? -339.2 * r2 + 161.4 * roughness - 25.9 : -8.48 * r2 + 14.3 * roughness - 9.95;\n\tfloat b = roughness < 0.25 ? 44.0 * r2 - 23.7 * roughness + 3.26 : 1.97 * r2 - 3.27 * roughness + 0.72;\n\tfloat DG = exp( a * dotNV + b ) + ( roughness < 0.25 ? 0.0 : 0.1 * ( roughness - 0.25 ) );\n\treturn saturate( DG * RECIPROCAL_PI );\n}\nvec2 DFGApprox( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tvec2 uv = vec2( roughness, dotNV );\n\treturn texture2D( dfgLUT, uv ).rg;\n}\nvec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) {\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\treturn specularColor * fab.x + specularF90 * fab.y;\n}\n#ifdef USE_IRIDESCENCE\nvoid computeMultiscatteringIridescence( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float iridescence, const in vec3 iridescenceF0, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#else\nvoid computeMultiscattering( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#endif\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\t#ifdef USE_IRIDESCENCE\n\t\tvec3 Fr = mix( specularColor, iridescenceF0, iridescence );\n\t#else\n\t\tvec3 Fr = specularColor;\n\t#endif\n\tvec3 FssEss = Fr * fab.x + specularF90 * fab.y;\n\tfloat Ess = fab.x + fab.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = Fr + ( 1.0 - Fr ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\nvec3 BRDF_GGX_Multiscatter( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material ) {\n\tvec3 singleScatter = BRDF_GGX( lightDir, viewDir, normal, material );\n\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tvec2 dfgV = DFGApprox( vec3(0.0, 0.0, 1.0), vec3(sqrt(1.0 - dotNV * dotNV), 0.0, dotNV), material.roughness );\n\tvec2 dfgL = DFGApprox( vec3(0.0, 0.0, 1.0), vec3(sqrt(1.0 - dotNL * dotNL), 0.0, dotNL), material.roughness );\n\tvec3 FssEss_V = material.specularColor * dfgV.x + material.specularF90 * dfgV.y;\n\tvec3 FssEss_L = material.specularColor * dfgL.x + material.specularF90 * dfgL.y;\n\tfloat Ess_V = dfgV.x + dfgV.y;\n\tfloat Ess_L = dfgL.x + dfgL.y;\n\tfloat Ems_V = 1.0 - Ess_V;\n\tfloat Ems_L = 1.0 - Ess_L;\n\tvec3 Favg = material.specularColor + ( 1.0 - material.specularColor ) * 0.047619;\n\tvec3 Fms = FssEss_V * FssEss_L * Favg / ( 1.0 - Ems_V * Ems_L * Favg * Favg + EPSILON );\n\tfloat compensationFactor = Ems_V * Ems_L;\n\tvec3 multiScatter = Fms * compensationFactor;\n\treturn singleScatter + multiScatter;\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometryNormal;\n\t\tvec3 viewDir = geometryViewDir;\n\t\tvec3 position = geometryPosition;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.roughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifdef USE_CLEARCOAT\n\t\tfloat dotNLcc = saturate( dot( geometryClearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = dotNLcc * directLight.color;\n\t\tclearcoatSpecularDirect += ccIrradiance * BRDF_GGX_Clearcoat( directLight.direction, geometryViewDir, geometryClearcoatNormal, material );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecularDirect += irradiance * BRDF_Sheen( directLight.direction, geometryViewDir, geometryNormal, material.sheenColor, material.sheenRoughness );\n\t#endif\n\treflectedLight.directSpecular += irradiance * BRDF_GGX_Multiscatter( directLight.direction, geometryViewDir, geometryNormal, material );\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\t#ifdef USE_CLEARCOAT\n\t\tclearcoatSpecularIndirect += clearcoatRadiance * EnvironmentBRDF( geometryClearcoatNormal, geometryViewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecularIndirect += irradiance * material.sheenColor * IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );\n\t#endif\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\t#ifdef USE_IRIDESCENCE\n\t\tcomputeMultiscatteringIridescence( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness, singleScattering, multiScattering );\n\t#else\n\t\tcomputeMultiscattering( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.roughness, singleScattering, multiScattering );\n\t#endif\n\tvec3 totalScattering = singleScattering + multiScattering;\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - max( max( totalScattering.r, totalScattering.g ), totalScattering.b ) );\n\treflectedLight.indirectSpecular += radiance * singleScattering;\n\treflectedLight.indirectSpecular += multiScattering * cosineWeightedIrradiance;\n\treflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}",lights_fragment_begin:"\nvec3 geometryPosition = - vViewPosition;\nvec3 geometryNormal = normal;\nvec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\nvec3 geometryClearcoatNormal = vec3( 0.0 );\n#ifdef USE_CLEARCOAT\n\tgeometryClearcoatNormal = clearcoatNormal;\n#endif\n#ifdef USE_IRIDESCENCE\n\tfloat dotNVi = saturate( dot( normal, geometryViewDir ) );\n\tif ( material.iridescenceThickness == 0.0 ) {\n\t\tmaterial.iridescence = 0.0;\n\t} else {\n\t\tmaterial.iridescence = saturate( material.iridescence );\n\t}\n\tif ( material.iridescence > 0.0 ) {\n\t\tmaterial.iridescenceFresnel = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n\t\tmaterial.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );\n\t}\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointLightInfo( pointLight, geometryPosition, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\tpointLightShadow = pointLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowIntensity, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\tvec4 spotColor;\n\tvec3 spotLightCoord;\n\tbool inSpotLightMap;\n\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotLightInfo( spotLight, geometryPosition, directLight );\n\t\t#if ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#define SPOT_LIGHT_MAP_INDEX UNROLLED_LOOP_INDEX\n\t\t#elif ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t#define SPOT_LIGHT_MAP_INDEX NUM_SPOT_LIGHT_MAPS\n\t\t#else\n\t\t#define SPOT_LIGHT_MAP_INDEX ( UNROLLED_LOOP_INDEX - NUM_SPOT_LIGHT_SHADOWS + NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#endif\n\t\t#if ( SPOT_LIGHT_MAP_INDEX < NUM_SPOT_LIGHT_MAPS )\n\t\t\tspotLightCoord = vSpotLightCoord[ i ].xyz / vSpotLightCoord[ i ].w;\n\t\t\tinSpotLightMap = all( lessThan( abs( spotLightCoord * 2. - 1. ), vec3( 1.0 ) ) );\n\t\t\tspotColor = texture2D( spotLightMap[ SPOT_LIGHT_MAP_INDEX ], spotLightCoord.xy );\n\t\t\tdirectLight.color = inSpotLightMap ? directLight.color * spotColor.rgb : directLight.color;\n\t\t#endif\n\t\t#undef SPOT_LIGHT_MAP_INDEX\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tspotLightShadow = spotLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowIntensity, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotLightCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalLightInfo( directionalLight, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowIntensity, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 iblIrradiance = vec3( 0.0 );\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\t#if defined( USE_LIGHT_PROBES )\n\t\tirradiance += getLightProbeIrradiance( lightProbe, geometryNormal );\n\t#endif\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometryNormal );\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n#endif",lights_fragment_maps:"#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel = texture2D( lightMap, vLightMapUv );\n\t\tvec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tiblIrradiance += getIBLIrradiance( geometryNormal );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\t#ifdef USE_ANISOTROPY\n\t\tradiance += getIBLAnisotropyRadiance( geometryViewDir, geometryNormal, material.roughness, material.anisotropyB, material.anisotropy );\n\t#else\n\t\tradiance += getIBLRadiance( geometryViewDir, geometryNormal, material.roughness );\n\t#endif\n\t#ifdef USE_CLEARCOAT\n\t\tclearcoatRadiance += getIBLRadiance( geometryViewDir, geometryClearcoatNormal, material.clearcoatRoughness );\n\t#endif\n#endif",lights_fragment_end:"#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n#endif",logdepthbuf_fragment:"#if defined( USE_LOGARITHMIC_DEPTH_BUFFER )\n\tgl_FragDepth = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif",logdepthbuf_pars_fragment:"#if defined( USE_LOGARITHMIC_DEPTH_BUFFER )\n\tuniform float logDepthBufFC;\n\tvarying float vFragDepth;\n\tvarying float vIsPerspective;\n#endif",logdepthbuf_pars_vertex:"#ifdef USE_LOGARITHMIC_DEPTH_BUFFER\n\tvarying float vFragDepth;\n\tvarying float vIsPerspective;\n#endif",logdepthbuf_vertex:"#ifdef USE_LOGARITHMIC_DEPTH_BUFFER\n\tvFragDepth = 1.0 + gl_Position.w;\n\tvIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) );\n#endif",map_fragment:"#ifdef USE_MAP\n\tvec4 sampledDiffuseColor = texture2D( map, vMapUv );\n\t#ifdef DECODE_VIDEO_TEXTURE\n\t\tsampledDiffuseColor = sRGBTransferEOTF( sampledDiffuseColor );\n\t#endif\n\tdiffuseColor *= sampledDiffuseColor;\n#endif",map_pars_fragment:"#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif",map_particle_fragment:"#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\t#if defined( USE_POINTS_UV )\n\t\tvec2 uv = vUv;\n\t#else\n\t\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n\t#endif\n#endif\n#ifdef USE_MAP\n\tdiffuseColor *= texture2D( map, uv );\n#endif\n#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, uv ).g;\n#endif",map_particle_pars_fragment:"#if defined( USE_POINTS_UV )\n\tvarying vec2 vUv;\n#else\n\t#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\t\tuniform mat3 uvTransform;\n\t#endif\n#endif\n#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif\n#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif",metalnessmap_fragment:"float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vMetalnessMapUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif",metalnessmap_pars_fragment:"#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif",morphinstance_vertex:"#ifdef USE_INSTANCING_MORPH\n\tfloat morphTargetInfluences[ MORPHTARGETS_COUNT ];\n\tfloat morphTargetBaseInfluence = texelFetch( morphTexture, ivec2( 0, gl_InstanceID ), 0 ).r;\n\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\tmorphTargetInfluences[i] = texelFetch( morphTexture, ivec2( i + 1, gl_InstanceID ), 0 ).r;\n\t}\n#endif",morphcolor_vertex:"#if defined( USE_MORPHCOLORS )\n\tvColor *= morphTargetBaseInfluence;\n\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\t#if defined( USE_COLOR_ALPHA )\n\t\t\tif ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ) * morphTargetInfluences[ i ];\n\t\t#elif defined( USE_COLOR )\n\t\t\tif ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ).rgb * morphTargetInfluences[ i ];\n\t\t#endif\n\t}\n#endif",morphnormal_vertex:"#ifdef USE_MORPHNORMALS\n\tobjectNormal *= morphTargetBaseInfluence;\n\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\tif ( morphTargetInfluences[ i ] != 0.0 ) objectNormal += getMorph( gl_VertexID, i, 1 ).xyz * morphTargetInfluences[ i ];\n\t}\n#endif",morphtarget_pars_vertex:"#ifdef USE_MORPHTARGETS\n\t#ifndef USE_INSTANCING_MORPH\n\t\tuniform float morphTargetBaseInfluence;\n\t\tuniform float morphTargetInfluences[ MORPHTARGETS_COUNT ];\n\t#endif\n\tuniform sampler2DArray morphTargetsTexture;\n\tuniform ivec2 morphTargetsTextureSize;\n\tvec4 getMorph( const in int vertexIndex, const in int morphTargetIndex, const in int offset ) {\n\t\tint texelIndex = vertexIndex * MORPHTARGETS_TEXTURE_STRIDE + offset;\n\t\tint y = texelIndex / morphTargetsTextureSize.x;\n\t\tint x = texelIndex - y * morphTargetsTextureSize.x;\n\t\tivec3 morphUV = ivec3( x, y, morphTargetIndex );\n\t\treturn texelFetch( morphTargetsTexture, morphUV, 0 );\n\t}\n#endif",morphtarget_vertex:"#ifdef USE_MORPHTARGETS\n\ttransformed *= morphTargetBaseInfluence;\n\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\tif ( morphTargetInfluences[ i ] != 0.0 ) transformed += getMorph( gl_VertexID, i, 0 ).xyz * morphTargetInfluences[ i ];\n\t}\n#endif",normal_fragment_begin:"float faceDirection = gl_FrontFacing ? 1.0 : - 1.0;\n#ifdef FLAT_SHADED\n\tvec3 fdx = dFdx( vViewPosition );\n\tvec3 fdy = dFdy( vViewPosition );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal *= faceDirection;\n\t#endif\n#endif\n#if defined( USE_NORMALMAP_TANGENTSPACE ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( USE_ANISOTROPY )\n\t#ifdef USE_TANGENT\n\t\tmat3 tbn = mat3( normalize( vTangent ), normalize( vBitangent ), normal );\n\t#else\n\t\tmat3 tbn = getTangentFrame( - vViewPosition, normal,\n\t\t#if defined( USE_NORMALMAP )\n\t\t\tvNormalMapUv\n\t\t#elif defined( USE_CLEARCOAT_NORMALMAP )\n\t\t\tvClearcoatNormalMapUv\n\t\t#else\n\t\t\tvUv\n\t\t#endif\n\t\t);\n\t#endif\n\t#if defined( DOUBLE_SIDED ) && ! defined( FLAT_SHADED )\n\t\ttbn[0] *= faceDirection;\n\t\ttbn[1] *= faceDirection;\n\t#endif\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\t#ifdef USE_TANGENT\n\t\tmat3 tbn2 = mat3( normalize( vTangent ), normalize( vBitangent ), normal );\n\t#else\n\t\tmat3 tbn2 = getTangentFrame( - vViewPosition, normal, vClearcoatNormalMapUv );\n\t#endif\n\t#if defined( DOUBLE_SIDED ) && ! defined( FLAT_SHADED )\n\t\ttbn2[0] *= faceDirection;\n\t\ttbn2[1] *= faceDirection;\n\t#endif\n#endif\nvec3 nonPerturbedNormal = normal;",normal_fragment_maps:"#ifdef USE_NORMALMAP_OBJECTSPACE\n\tnormal = texture2D( normalMap, vNormalMapUv ).xyz * 2.0 - 1.0;\n\t#ifdef FLIP_SIDED\n\t\tnormal = - normal;\n\t#endif\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * faceDirection;\n\t#endif\n\tnormal = normalize( normalMatrix * normal );\n#elif defined( USE_NORMALMAP_TANGENTSPACE )\n\tvec3 mapN = texture2D( normalMap, vNormalMapUv ).xyz * 2.0 - 1.0;\n\tmapN.xy *= normalScale;\n\tnormal = normalize( tbn * mapN );\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( - vViewPosition, normal, dHdxy_fwd(), faceDirection );\n#endif",normal_pars_fragment:"#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif",normal_pars_vertex:"#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif",normal_vertex:"#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif",normalmap_pars_fragment:"#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n#endif\n#ifdef USE_NORMALMAP_OBJECTSPACE\n\tuniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( USE_NORMALMAP_TANGENTSPACE ) || defined ( USE_CLEARCOAT_NORMALMAP ) || defined( USE_ANISOTROPY ) )\n\tmat3 getTangentFrame( vec3 eye_pos, vec3 surf_norm, vec2 uv ) {\n\t\tvec3 q0 = dFdx( eye_pos.xyz );\n\t\tvec3 q1 = dFdy( eye_pos.xyz );\n\t\tvec2 st0 = dFdx( uv.st );\n\t\tvec2 st1 = dFdy( uv.st );\n\t\tvec3 N = surf_norm;\n\t\tvec3 q1perp = cross( q1, N );\n\t\tvec3 q0perp = cross( N, q0 );\n\t\tvec3 T = q1perp * st0.x + q0perp * st1.x;\n\t\tvec3 B = q1perp * st0.y + q0perp * st1.y;\n\t\tfloat det = max( dot( T, T ), dot( B, B ) );\n\t\tfloat scale = ( det == 0.0 ) ? 0.0 : inversesqrt( det );\n\t\treturn mat3( T * scale, B * scale, N );\n\t}\n#endif",clearcoat_normal_fragment_begin:"#ifdef USE_CLEARCOAT\n\tvec3 clearcoatNormal = nonPerturbedNormal;\n#endif",clearcoat_normal_fragment_maps:"#ifdef USE_CLEARCOAT_NORMALMAP\n\tvec3 clearcoatMapN = texture2D( clearcoatNormalMap, vClearcoatNormalMapUv ).xyz * 2.0 - 1.0;\n\tclearcoatMapN.xy *= clearcoatNormalScale;\n\tclearcoatNormal = normalize( tbn2 * clearcoatMapN );\n#endif",clearcoat_pars_fragment:"#ifdef USE_CLEARCOATMAP\n\tuniform sampler2D clearcoatMap;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform sampler2D clearcoatNormalMap;\n\tuniform vec2 clearcoatNormalScale;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tuniform sampler2D clearcoatRoughnessMap;\n#endif",iridescence_pars_fragment:"#ifdef USE_IRIDESCENCEMAP\n\tuniform sampler2D iridescenceMap;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tuniform sampler2D iridescenceThicknessMap;\n#endif",opaque_fragment:"#ifdef OPAQUE\ndiffuseColor.a = 1.0;\n#endif\n#ifdef USE_TRANSMISSION\ndiffuseColor.a *= material.transmissionAlpha;\n#endif\ngl_FragColor = vec4( outgoingLight, diffuseColor.a );",packing:"vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;const float ShiftRight8 = 1. / 256.;\nconst float Inv255 = 1. / 255.;\nconst vec4 PackFactors = vec4( 1.0, 256.0, 256.0 * 256.0, 256.0 * 256.0 * 256.0 );\nconst vec2 UnpackFactors2 = vec2( UnpackDownscale, 1.0 / PackFactors.g );\nconst vec3 UnpackFactors3 = vec3( UnpackDownscale / PackFactors.rg, 1.0 / PackFactors.b );\nconst vec4 UnpackFactors4 = vec4( UnpackDownscale / PackFactors.rgb, 1.0 / PackFactors.a );\nvec4 packDepthToRGBA( const in float v ) {\n\tif( v <= 0.0 )\n\t\treturn vec4( 0., 0., 0., 0. );\n\tif( v >= 1.0 )\n\t\treturn vec4( 1., 1., 1., 1. );\n\tfloat vuf;\n\tfloat af = modf( v * PackFactors.a, vuf );\n\tfloat bf = modf( vuf * ShiftRight8, vuf );\n\tfloat gf = modf( vuf * ShiftRight8, vuf );\n\treturn vec4( vuf * Inv255, gf * PackUpscale, bf * PackUpscale, af );\n}\nvec3 packDepthToRGB( const in float v ) {\n\tif( v <= 0.0 )\n\t\treturn vec3( 0., 0., 0. );\n\tif( v >= 1.0 )\n\t\treturn vec3( 1., 1., 1. );\n\tfloat vuf;\n\tfloat bf = modf( v * PackFactors.b, vuf );\n\tfloat gf = modf( vuf * ShiftRight8, vuf );\n\treturn vec3( vuf * Inv255, gf * PackUpscale, bf );\n}\nvec2 packDepthToRG( const in float v ) {\n\tif( v <= 0.0 )\n\t\treturn vec2( 0., 0. );\n\tif( v >= 1.0 )\n\t\treturn vec2( 1., 1. );\n\tfloat vuf;\n\tfloat gf = modf( v * 256., vuf );\n\treturn vec2( vuf * Inv255, gf );\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors4 );\n}\nfloat unpackRGBToDepth( const in vec3 v ) {\n\treturn dot( v, UnpackFactors3 );\n}\nfloat unpackRGToDepth( const in vec2 v ) {\n\treturn v.r * UnpackFactors2.r + v.g * UnpackFactors2.g;\n}\nvec4 pack2HalfToRGBA( const in vec2 v ) {\n\tvec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ) );\n\treturn vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w );\n}\nvec2 unpackRGBATo2Half( const in vec4 v ) {\n\treturn vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float depth, const in float near, const in float far ) {\n\treturn depth * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( ( near + viewZ ) * far ) / ( ( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float depth, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * depth - far );\n}",premultiplied_alpha_fragment:"#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif",project_vertex:"vec4 mvPosition = vec4( transformed, 1.0 );\n#ifdef USE_BATCHING\n\tmvPosition = batchingMatrix * mvPosition;\n#endif\n#ifdef USE_INSTANCING\n\tmvPosition = instanceMatrix * mvPosition;\n#endif\nmvPosition = modelViewMatrix * mvPosition;\ngl_Position = projectionMatrix * mvPosition;",dithering_fragment:"#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif",dithering_pars_fragment:"#ifdef DITHERING\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif",roughnessmap_fragment:"float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vRoughnessMapUv );\n\troughnessFactor *= texelRoughness.g;\n#endif",roughnessmap_pars_fragment:"#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif",shadowmap_pars_fragment:"#if NUM_SPOT_LIGHT_COORDS > 0\n\tvarying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];\n#endif\n#if NUM_SPOT_LIGHT_MAPS > 0\n\tuniform sampler2D spotLightMap[ NUM_SPOT_LIGHT_MAPS ];\n#endif\n#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\tfloat depth = unpackRGBAToDepth( texture2D( depths, uv ) );\n\t\t#ifdef USE_REVERSED_DEPTH_BUFFER\n\t\t\treturn step( depth, compare );\n\t\t#else\n\t\t\treturn step( compare, depth );\n\t\t#endif\n\t}\n\tvec2 texture2DDistribution( sampler2D shadow, vec2 uv ) {\n\t\treturn unpackRGBATo2Half( texture2D( shadow, uv ) );\n\t}\n\tfloat VSMShadow( sampler2D shadow, vec2 uv, float compare ) {\n\t\tfloat occlusion = 1.0;\n\t\tvec2 distribution = texture2DDistribution( shadow, uv );\n\t\t#ifdef USE_REVERSED_DEPTH_BUFFER\n\t\t\tfloat hard_shadow = step( distribution.x, compare );\n\t\t#else\n\t\t\tfloat hard_shadow = step( compare, distribution.x );\n\t\t#endif\n\t\tif ( hard_shadow != 1.0 ) {\n\t\t\tfloat distance = compare - distribution.x;\n\t\t\tfloat variance = max( 0.00000, distribution.y * distribution.y );\n\t\t\tfloat softness_probability = variance / (variance + distance * distance );\t\t\tsoftness_probability = clamp( ( softness_probability - 0.3 ) / ( 0.95 - 0.3 ), 0.0, 1.0 );\t\t\tocclusion = clamp( max( hard_shadow, softness_probability ), 0.0, 1.0 );\n\t\t}\n\t\treturn occlusion;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0;\n\t\tbool frustumTest = inFrustum && shadowCoord.z <= 1.0;\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tfloat dx2 = dx0 / 2.0;\n\t\t\tfloat dy2 = dy0 / 2.0;\n\t\t\tfloat dx3 = dx1 / 2.0;\n\t\t\tfloat dy3 = dy1 / 2.0;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 17.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx = texelSize.x;\n\t\t\tfloat dy = texelSize.y;\n\t\t\tvec2 uv = shadowCoord.xy;\n\t\t\tvec2 f = fract( uv * shadowMapSize + 0.5 );\n\t\t\tuv -= f * texelSize;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, uv, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( dx, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( 0.0, dy ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + texelSize, shadowCoord.z ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, 0.0 ), shadowCoord.z ),\n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 0.0 ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, dy ), shadowCoord.z ),\n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, dy ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( 0.0, -dy ), shadowCoord.z ),\n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 0.0, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( dx, -dy ), shadowCoord.z ),\n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( mix( texture2DCompare( shadowMap, uv + vec2( -dx, -dy ), shadowCoord.z ),\n\t\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, -dy ), shadowCoord.z ),\n\t\t\t\t\t\t f.x ),\n\t\t\t\t\t mix( texture2DCompare( shadowMap, uv + vec2( -dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t\t f.x ),\n\t\t\t\t\t f.y )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_VSM )\n\t\t\tshadow = VSMShadow( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn mix( 1.0, shadow, shadowIntensity );\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tfloat shadow = 1.0;\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\t\n\t\tfloat lightToPositionLength = length( lightToPosition );\n\t\tif ( lightToPositionLength - shadowCameraFar <= 0.0 && lightToPositionLength - shadowCameraNear >= 0.0 ) {\n\t\t\tfloat dp = ( lightToPositionLength - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\t\tdp += shadowBias;\n\t\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) || defined( SHADOWMAP_TYPE_VSM )\n\t\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\t\tshadow = (\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t\t) * ( 1.0 / 9.0 );\n\t\t\t#else\n\t\t\t\tshadow = texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t\t#endif\n\t\t}\n\t\treturn mix( 1.0, shadow, shadowIntensity );\n\t}\n#endif",shadowmap_pars_vertex:"#if NUM_SPOT_LIGHT_COORDS > 0\n\tuniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ];\n\tvarying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];\n#endif\n#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n#endif",shadowmap_vertex:"#if ( defined( USE_SHADOWMAP ) && ( NUM_DIR_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0 ) ) || ( NUM_SPOT_LIGHT_COORDS > 0 )\n\tvec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\tvec4 shadowWorldPosition;\n#endif\n#if defined( USE_SHADOWMAP )\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 );\n\t\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * shadowWorldPosition;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * pointLightShadows[ i ].shadowNormalBias, 0 );\n\t\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * shadowWorldPosition;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#if NUM_SPOT_LIGHT_COORDS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_COORDS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition;\n\t\t#if ( defined( USE_SHADOWMAP ) && UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t\tshadowWorldPosition.xyz += shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias;\n\t\t#endif\n\t\tvSpotLightCoord[ i ] = spotLightMatrix[ i ] * shadowWorldPosition;\n\t}\n\t#pragma unroll_loop_end\n#endif",shadowmask_pars_fragment:"float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tdirectionalLight = directionalLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowIntensity, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tspotLight = spotLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowIntensity, spotLight.shadowBias, spotLight.shadowRadius, vSpotLightCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tpointLight = pointLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowIntensity, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#endif\n\treturn shadow;\n}",skinbase_vertex:"#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif",skinning_pars_vertex:"#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\tuniform highp sampler2D boneTexture;\n\tmat4 getBoneMatrix( const in float i ) {\n\t\tint size = textureSize( boneTexture, 0 ).x;\n\t\tint j = int( i ) * 4;\n\t\tint x = j % size;\n\t\tint y = j / size;\n\t\tvec4 v1 = texelFetch( boneTexture, ivec2( x, y ), 0 );\n\t\tvec4 v2 = texelFetch( boneTexture, ivec2( x + 1, y ), 0 );\n\t\tvec4 v3 = texelFetch( boneTexture, ivec2( x + 2, y ), 0 );\n\t\tvec4 v4 = texelFetch( boneTexture, ivec2( x + 3, y ), 0 );\n\t\treturn mat4( v1, v2, v3, v4 );\n\t}\n#endif",skinning_vertex:"#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif",skinnormal_vertex:"#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif",specularmap_fragment:"float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vSpecularMapUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif",specularmap_pars_fragment:"#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif",tonemapping_fragment:"#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif",tonemapping_pars_fragment:"#ifndef saturate\n#define saturate( a ) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn saturate( toneMappingExposure * color );\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\nvec3 CineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 RRTAndODTFit( vec3 v ) {\n\tvec3 a = v * ( v + 0.0245786 ) - 0.000090537;\n\tvec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;\n\treturn a / b;\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tconst mat3 ACESInputMat = mat3(\n\t\tvec3( 0.59719, 0.07600, 0.02840 ),\t\tvec3( 0.35458, 0.90834, 0.13383 ),\n\t\tvec3( 0.04823, 0.01566, 0.83777 )\n\t);\n\tconst mat3 ACESOutputMat = mat3(\n\t\tvec3( 1.60475, -0.10208, -0.00327 ),\t\tvec3( -0.53108, 1.10813, -0.07276 ),\n\t\tvec3( -0.07367, -0.00605, 1.07602 )\n\t);\n\tcolor *= toneMappingExposure / 0.6;\n\tcolor = ACESInputMat * color;\n\tcolor = RRTAndODTFit( color );\n\tcolor = ACESOutputMat * color;\n\treturn saturate( color );\n}\nconst mat3 LINEAR_REC2020_TO_LINEAR_SRGB = mat3(\n\tvec3( 1.6605, - 0.1246, - 0.0182 ),\n\tvec3( - 0.5876, 1.1329, - 0.1006 ),\n\tvec3( - 0.0728, - 0.0083, 1.1187 )\n);\nconst mat3 LINEAR_SRGB_TO_LINEAR_REC2020 = mat3(\n\tvec3( 0.6274, 0.0691, 0.0164 ),\n\tvec3( 0.3293, 0.9195, 0.0880 ),\n\tvec3( 0.0433, 0.0113, 0.8956 )\n);\nvec3 agxDefaultContrastApprox( vec3 x ) {\n\tvec3 x2 = x * x;\n\tvec3 x4 = x2 * x2;\n\treturn + 15.5 * x4 * x2\n\t\t- 40.14 * x4 * x\n\t\t+ 31.96 * x4\n\t\t- 6.868 * x2 * x\n\t\t+ 0.4298 * x2\n\t\t+ 0.1191 * x\n\t\t- 0.00232;\n}\nvec3 AgXToneMapping( vec3 color ) {\n\tconst mat3 AgXInsetMatrix = mat3(\n\t\tvec3( 0.856627153315983, 0.137318972929847, 0.11189821299995 ),\n\t\tvec3( 0.0951212405381588, 0.761241990602591, 0.0767994186031903 ),\n\t\tvec3( 0.0482516061458583, 0.101439036467562, 0.811302368396859 )\n\t);\n\tconst mat3 AgXOutsetMatrix = mat3(\n\t\tvec3( 1.1271005818144368, - 0.1413297634984383, - 0.14132976349843826 ),\n\t\tvec3( - 0.11060664309660323, 1.157823702216272, - 0.11060664309660294 ),\n\t\tvec3( - 0.016493938717834573, - 0.016493938717834257, 1.2519364065950405 )\n\t);\n\tconst float AgxMinEv = - 12.47393;\tconst float AgxMaxEv = 4.026069;\n\tcolor *= toneMappingExposure;\n\tcolor = LINEAR_SRGB_TO_LINEAR_REC2020 * color;\n\tcolor = AgXInsetMatrix * color;\n\tcolor = max( color, 1e-10 );\tcolor = log2( color );\n\tcolor = ( color - AgxMinEv ) / ( AgxMaxEv - AgxMinEv );\n\tcolor = clamp( color, 0.0, 1.0 );\n\tcolor = agxDefaultContrastApprox( color );\n\tcolor = AgXOutsetMatrix * color;\n\tcolor = pow( max( vec3( 0.0 ), color ), vec3( 2.2 ) );\n\tcolor = LINEAR_REC2020_TO_LINEAR_SRGB * color;\n\tcolor = clamp( color, 0.0, 1.0 );\n\treturn color;\n}\nvec3 NeutralToneMapping( vec3 color ) {\n\tconst float StartCompression = 0.8 - 0.04;\n\tconst float Desaturation = 0.15;\n\tcolor *= toneMappingExposure;\n\tfloat x = min( color.r, min( color.g, color.b ) );\n\tfloat offset = x < 0.08 ? x - 6.25 * x * x : 0.04;\n\tcolor -= offset;\n\tfloat peak = max( color.r, max( color.g, color.b ) );\n\tif ( peak < StartCompression ) return color;\n\tfloat d = 1. - StartCompression;\n\tfloat newPeak = 1. - d * d / ( peak + d - StartCompression );\n\tcolor *= newPeak / peak;\n\tfloat g = 1. - 1. / ( Desaturation * ( peak - newPeak ) + 1. );\n\treturn mix( color, vec3( newPeak ), g );\n}\nvec3 CustomToneMapping( vec3 color ) { return color; }",transmission_fragment:"#ifdef USE_TRANSMISSION\n\tmaterial.transmission = transmission;\n\tmaterial.transmissionAlpha = 1.0;\n\tmaterial.thickness = thickness;\n\tmaterial.attenuationDistance = attenuationDistance;\n\tmaterial.attenuationColor = attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tmaterial.transmission *= texture2D( transmissionMap, vTransmissionMapUv ).r;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tmaterial.thickness *= texture2D( thicknessMap, vThicknessMapUv ).g;\n\t#endif\n\tvec3 pos = vWorldPosition;\n\tvec3 v = normalize( cameraPosition - pos );\n\tvec3 n = inverseTransformDirection( normal, viewMatrix );\n\tvec4 transmitted = getIBLVolumeRefraction(\n\t\tn, v, material.roughness, material.diffuseColor, material.specularColor, material.specularF90,\n\t\tpos, modelMatrix, viewMatrix, projectionMatrix, material.dispersion, material.ior, material.thickness,\n\t\tmaterial.attenuationColor, material.attenuationDistance );\n\tmaterial.transmissionAlpha = mix( material.transmissionAlpha, transmitted.a, material.transmission );\n\ttotalDiffuse = mix( totalDiffuse, transmitted.rgb, material.transmission );\n#endif",transmission_pars_fragment:"#ifdef USE_TRANSMISSION\n\tuniform float transmission;\n\tuniform float thickness;\n\tuniform float attenuationDistance;\n\tuniform vec3 attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tuniform sampler2D transmissionMap;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tuniform sampler2D thicknessMap;\n\t#endif\n\tuniform vec2 transmissionSamplerSize;\n\tuniform sampler2D transmissionSamplerMap;\n\tuniform mat4 modelMatrix;\n\tuniform mat4 projectionMatrix;\n\tvarying vec3 vWorldPosition;\n\tfloat w0( float a ) {\n\t\treturn ( 1.0 / 6.0 ) * ( a * ( a * ( - a + 3.0 ) - 3.0 ) + 1.0 );\n\t}\n\tfloat w1( float a ) {\n\t\treturn ( 1.0 / 6.0 ) * ( a * a * ( 3.0 * a - 6.0 ) + 4.0 );\n\t}\n\tfloat w2( float a ){\n\t\treturn ( 1.0 / 6.0 ) * ( a * ( a * ( - 3.0 * a + 3.0 ) + 3.0 ) + 1.0 );\n\t}\n\tfloat w3( float a ) {\n\t\treturn ( 1.0 / 6.0 ) * ( a * a * a );\n\t}\n\tfloat g0( float a ) {\n\t\treturn w0( a ) + w1( a );\n\t}\n\tfloat g1( float a ) {\n\t\treturn w2( a ) + w3( a );\n\t}\n\tfloat h0( float a ) {\n\t\treturn - 1.0 + w1( a ) / ( w0( a ) + w1( a ) );\n\t}\n\tfloat h1( float a ) {\n\t\treturn 1.0 + w3( a ) / ( w2( a ) + w3( a ) );\n\t}\n\tvec4 bicubic( sampler2D tex, vec2 uv, vec4 texelSize, float lod ) {\n\t\tuv = uv * texelSize.zw + 0.5;\n\t\tvec2 iuv = floor( uv );\n\t\tvec2 fuv = fract( uv );\n\t\tfloat g0x = g0( fuv.x );\n\t\tfloat g1x = g1( fuv.x );\n\t\tfloat h0x = h0( fuv.x );\n\t\tfloat h1x = h1( fuv.x );\n\t\tfloat h0y = h0( fuv.y );\n\t\tfloat h1y = h1( fuv.y );\n\t\tvec2 p0 = ( vec2( iuv.x + h0x, iuv.y + h0y ) - 0.5 ) * texelSize.xy;\n\t\tvec2 p1 = ( vec2( iuv.x + h1x, iuv.y + h0y ) - 0.5 ) * texelSize.xy;\n\t\tvec2 p2 = ( vec2( iuv.x + h0x, iuv.y + h1y ) - 0.5 ) * texelSize.xy;\n\t\tvec2 p3 = ( vec2( iuv.x + h1x, iuv.y + h1y ) - 0.5 ) * texelSize.xy;\n\t\treturn g0( fuv.y ) * ( g0x * textureLod( tex, p0, lod ) + g1x * textureLod( tex, p1, lod ) ) +\n\t\t\tg1( fuv.y ) * ( g0x * textureLod( tex, p2, lod ) + g1x * textureLod( tex, p3, lod ) );\n\t}\n\tvec4 textureBicubic( sampler2D sampler, vec2 uv, float lod ) {\n\t\tvec2 fLodSize = vec2( textureSize( sampler, int( lod ) ) );\n\t\tvec2 cLodSize = vec2( textureSize( sampler, int( lod + 1.0 ) ) );\n\t\tvec2 fLodSizeInv = 1.0 / fLodSize;\n\t\tvec2 cLodSizeInv = 1.0 / cLodSize;\n\t\tvec4 fSample = bicubic( sampler, uv, vec4( fLodSizeInv, fLodSize ), floor( lod ) );\n\t\tvec4 cSample = bicubic( sampler, uv, vec4( cLodSizeInv, cLodSize ), ceil( lod ) );\n\t\treturn mix( fSample, cSample, fract( lod ) );\n\t}\n\tvec3 getVolumeTransmissionRay( const in vec3 n, const in vec3 v, const in float thickness, const in float ior, const in mat4 modelMatrix ) {\n\t\tvec3 refractionVector = refract( - v, normalize( n ), 1.0 / ior );\n\t\tvec3 modelScale;\n\t\tmodelScale.x = length( vec3( modelMatrix[ 0 ].xyz ) );\n\t\tmodelScale.y = length( vec3( modelMatrix[ 1 ].xyz ) );\n\t\tmodelScale.z = length( vec3( modelMatrix[ 2 ].xyz ) );\n\t\treturn normalize( refractionVector ) * thickness * modelScale;\n\t}\n\tfloat applyIorToRoughness( const in float roughness, const in float ior ) {\n\t\treturn roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 );\n\t}\n\tvec4 getTransmissionSample( const in vec2 fragCoord, const in float roughness, const in float ior ) {\n\t\tfloat lod = log2( transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior );\n\t\treturn textureBicubic( transmissionSamplerMap, fragCoord.xy, lod );\n\t}\n\tvec3 volumeAttenuation( const in float transmissionDistance, const in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tif ( isinf( attenuationDistance ) ) {\n\t\t\treturn vec3( 1.0 );\n\t\t} else {\n\t\t\tvec3 attenuationCoefficient = -log( attenuationColor ) / attenuationDistance;\n\t\t\tvec3 transmittance = exp( - attenuationCoefficient * transmissionDistance );\t\t\treturn transmittance;\n\t\t}\n\t}\n\tvec4 getIBLVolumeRefraction( const in vec3 n, const in vec3 v, const in float roughness, const in vec3 diffuseColor,\n\t\tconst in vec3 specularColor, const in float specularF90, const in vec3 position, const in mat4 modelMatrix,\n\t\tconst in mat4 viewMatrix, const in mat4 projMatrix, const in float dispersion, const in float ior, const in float thickness,\n\t\tconst in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tvec4 transmittedLight;\n\t\tvec3 transmittance;\n\t\t#ifdef USE_DISPERSION\n\t\t\tfloat halfSpread = ( ior - 1.0 ) * 0.025 * dispersion;\n\t\t\tvec3 iors = vec3( ior - halfSpread, ior, ior + halfSpread );\n\t\t\tfor ( int i = 0; i < 3; i ++ ) {\n\t\t\t\tvec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, iors[ i ], modelMatrix );\n\t\t\t\tvec3 refractedRayExit = position + transmissionRay;\n\t\t\t\tvec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\n\t\t\t\tvec2 refractionCoords = ndcPos.xy / ndcPos.w;\n\t\t\t\trefractionCoords += 1.0;\n\t\t\t\trefractionCoords /= 2.0;\n\t\t\t\tvec4 transmissionSample = getTransmissionSample( refractionCoords, roughness, iors[ i ] );\n\t\t\t\ttransmittedLight[ i ] = transmissionSample[ i ];\n\t\t\t\ttransmittedLight.a += transmissionSample.a;\n\t\t\t\ttransmittance[ i ] = diffuseColor[ i ] * volumeAttenuation( length( transmissionRay ), attenuationColor, attenuationDistance )[ i ];\n\t\t\t}\n\t\t\ttransmittedLight.a /= 3.0;\n\t\t#else\n\t\t\tvec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix );\n\t\t\tvec3 refractedRayExit = position + transmissionRay;\n\t\t\tvec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\n\t\t\tvec2 refractionCoords = ndcPos.xy / ndcPos.w;\n\t\t\trefractionCoords += 1.0;\n\t\t\trefractionCoords /= 2.0;\n\t\t\ttransmittedLight = getTransmissionSample( refractionCoords, roughness, ior );\n\t\t\ttransmittance = diffuseColor * volumeAttenuation( length( transmissionRay ), attenuationColor, attenuationDistance );\n\t\t#endif\n\t\tvec3 attenuatedColor = transmittance * transmittedLight.rgb;\n\t\tvec3 F = EnvironmentBRDF( n, v, specularColor, specularF90, roughness );\n\t\tfloat transmittanceFactor = ( transmittance.r + transmittance.g + transmittance.b ) / 3.0;\n\t\treturn vec4( ( 1.0 - F ) * attenuatedColor, 1.0 - ( 1.0 - transmittedLight.a ) * transmittanceFactor );\n\t}\n#endif",uv_pars_fragment:"#if defined( USE_UV ) || defined( USE_ANISOTROPY )\n\tvarying vec2 vUv;\n#endif\n#ifdef USE_MAP\n\tvarying vec2 vMapUv;\n#endif\n#ifdef USE_ALPHAMAP\n\tvarying vec2 vAlphaMapUv;\n#endif\n#ifdef USE_LIGHTMAP\n\tvarying vec2 vLightMapUv;\n#endif\n#ifdef USE_AOMAP\n\tvarying vec2 vAoMapUv;\n#endif\n#ifdef USE_BUMPMAP\n\tvarying vec2 vBumpMapUv;\n#endif\n#ifdef USE_NORMALMAP\n\tvarying vec2 vNormalMapUv;\n#endif\n#ifdef USE_EMISSIVEMAP\n\tvarying vec2 vEmissiveMapUv;\n#endif\n#ifdef USE_METALNESSMAP\n\tvarying vec2 vMetalnessMapUv;\n#endif\n#ifdef USE_ROUGHNESSMAP\n\tvarying vec2 vRoughnessMapUv;\n#endif\n#ifdef USE_ANISOTROPYMAP\n\tvarying vec2 vAnisotropyMapUv;\n#endif\n#ifdef USE_CLEARCOATMAP\n\tvarying vec2 vClearcoatMapUv;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tvarying vec2 vClearcoatNormalMapUv;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tvarying vec2 vClearcoatRoughnessMapUv;\n#endif\n#ifdef USE_IRIDESCENCEMAP\n\tvarying vec2 vIridescenceMapUv;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tvarying vec2 vIridescenceThicknessMapUv;\n#endif\n#ifdef USE_SHEEN_COLORMAP\n\tvarying vec2 vSheenColorMapUv;\n#endif\n#ifdef USE_SHEEN_ROUGHNESSMAP\n\tvarying vec2 vSheenRoughnessMapUv;\n#endif\n#ifdef USE_SPECULARMAP\n\tvarying vec2 vSpecularMapUv;\n#endif\n#ifdef USE_SPECULAR_COLORMAP\n\tvarying vec2 vSpecularColorMapUv;\n#endif\n#ifdef USE_SPECULAR_INTENSITYMAP\n\tvarying vec2 vSpecularIntensityMapUv;\n#endif\n#ifdef USE_TRANSMISSIONMAP\n\tuniform mat3 transmissionMapTransform;\n\tvarying vec2 vTransmissionMapUv;\n#endif\n#ifdef USE_THICKNESSMAP\n\tuniform mat3 thicknessMapTransform;\n\tvarying vec2 vThicknessMapUv;\n#endif",uv_pars_vertex:"#if defined( USE_UV ) || defined( USE_ANISOTROPY )\n\tvarying vec2 vUv;\n#endif\n#ifdef USE_MAP\n\tuniform mat3 mapTransform;\n\tvarying vec2 vMapUv;\n#endif\n#ifdef USE_ALPHAMAP\n\tuniform mat3 alphaMapTransform;\n\tvarying vec2 vAlphaMapUv;\n#endif\n#ifdef USE_LIGHTMAP\n\tuniform mat3 lightMapTransform;\n\tvarying vec2 vLightMapUv;\n#endif\n#ifdef USE_AOMAP\n\tuniform mat3 aoMapTransform;\n\tvarying vec2 vAoMapUv;\n#endif\n#ifdef USE_BUMPMAP\n\tuniform mat3 bumpMapTransform;\n\tvarying vec2 vBumpMapUv;\n#endif\n#ifdef USE_NORMALMAP\n\tuniform mat3 normalMapTransform;\n\tvarying vec2 vNormalMapUv;\n#endif\n#ifdef USE_DISPLACEMENTMAP\n\tuniform mat3 displacementMapTransform;\n\tvarying vec2 vDisplacementMapUv;\n#endif\n#ifdef USE_EMISSIVEMAP\n\tuniform mat3 emissiveMapTransform;\n\tvarying vec2 vEmissiveMapUv;\n#endif\n#ifdef USE_METALNESSMAP\n\tuniform mat3 metalnessMapTransform;\n\tvarying vec2 vMetalnessMapUv;\n#endif\n#ifdef USE_ROUGHNESSMAP\n\tuniform mat3 roughnessMapTransform;\n\tvarying vec2 vRoughnessMapUv;\n#endif\n#ifdef USE_ANISOTROPYMAP\n\tuniform mat3 anisotropyMapTransform;\n\tvarying vec2 vAnisotropyMapUv;\n#endif\n#ifdef USE_CLEARCOATMAP\n\tuniform mat3 clearcoatMapTransform;\n\tvarying vec2 vClearcoatMapUv;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform mat3 clearcoatNormalMapTransform;\n\tvarying vec2 vClearcoatNormalMapUv;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tuniform mat3 clearcoatRoughnessMapTransform;\n\tvarying vec2 vClearcoatRoughnessMapUv;\n#endif\n#ifdef USE_SHEEN_COLORMAP\n\tuniform mat3 sheenColorMapTransform;\n\tvarying vec2 vSheenColorMapUv;\n#endif\n#ifdef USE_SHEEN_ROUGHNESSMAP\n\tuniform mat3 sheenRoughnessMapTransform;\n\tvarying vec2 vSheenRoughnessMapUv;\n#endif\n#ifdef USE_IRIDESCENCEMAP\n\tuniform mat3 iridescenceMapTransform;\n\tvarying vec2 vIridescenceMapUv;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tuniform mat3 iridescenceThicknessMapTransform;\n\tvarying vec2 vIridescenceThicknessMapUv;\n#endif\n#ifdef USE_SPECULARMAP\n\tuniform mat3 specularMapTransform;\n\tvarying vec2 vSpecularMapUv;\n#endif\n#ifdef USE_SPECULAR_COLORMAP\n\tuniform mat3 specularColorMapTransform;\n\tvarying vec2 vSpecularColorMapUv;\n#endif\n#ifdef USE_SPECULAR_INTENSITYMAP\n\tuniform mat3 specularIntensityMapTransform;\n\tvarying vec2 vSpecularIntensityMapUv;\n#endif\n#ifdef USE_TRANSMISSIONMAP\n\tuniform mat3 transmissionMapTransform;\n\tvarying vec2 vTransmissionMapUv;\n#endif\n#ifdef USE_THICKNESSMAP\n\tuniform mat3 thicknessMapTransform;\n\tvarying vec2 vThicknessMapUv;\n#endif",uv_vertex:"#if defined( USE_UV ) || defined( USE_ANISOTROPY )\n\tvUv = vec3( uv, 1 ).xy;\n#endif\n#ifdef USE_MAP\n\tvMapUv = ( mapTransform * vec3( MAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_ALPHAMAP\n\tvAlphaMapUv = ( alphaMapTransform * vec3( ALPHAMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_LIGHTMAP\n\tvLightMapUv = ( lightMapTransform * vec3( LIGHTMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_AOMAP\n\tvAoMapUv = ( aoMapTransform * vec3( AOMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_BUMPMAP\n\tvBumpMapUv = ( bumpMapTransform * vec3( BUMPMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_NORMALMAP\n\tvNormalMapUv = ( normalMapTransform * vec3( NORMALMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_DISPLACEMENTMAP\n\tvDisplacementMapUv = ( displacementMapTransform * vec3( DISPLACEMENTMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_EMISSIVEMAP\n\tvEmissiveMapUv = ( emissiveMapTransform * vec3( EMISSIVEMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_METALNESSMAP\n\tvMetalnessMapUv = ( metalnessMapTransform * vec3( METALNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_ROUGHNESSMAP\n\tvRoughnessMapUv = ( roughnessMapTransform * vec3( ROUGHNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_ANISOTROPYMAP\n\tvAnisotropyMapUv = ( anisotropyMapTransform * vec3( ANISOTROPYMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_CLEARCOATMAP\n\tvClearcoatMapUv = ( clearcoatMapTransform * vec3( CLEARCOATMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tvClearcoatNormalMapUv = ( clearcoatNormalMapTransform * vec3( CLEARCOAT_NORMALMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tvClearcoatRoughnessMapUv = ( clearcoatRoughnessMapTransform * vec3( CLEARCOAT_ROUGHNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_IRIDESCENCEMAP\n\tvIridescenceMapUv = ( iridescenceMapTransform * vec3( IRIDESCENCEMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tvIridescenceThicknessMapUv = ( iridescenceThicknessMapTransform * vec3( IRIDESCENCE_THICKNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SHEEN_COLORMAP\n\tvSheenColorMapUv = ( sheenColorMapTransform * vec3( SHEEN_COLORMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SHEEN_ROUGHNESSMAP\n\tvSheenRoughnessMapUv = ( sheenRoughnessMapTransform * vec3( SHEEN_ROUGHNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SPECULARMAP\n\tvSpecularMapUv = ( specularMapTransform * vec3( SPECULARMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SPECULAR_COLORMAP\n\tvSpecularColorMapUv = ( specularColorMapTransform * vec3( SPECULAR_COLORMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SPECULAR_INTENSITYMAP\n\tvSpecularIntensityMapUv = ( specularIntensityMapTransform * vec3( SPECULAR_INTENSITYMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_TRANSMISSIONMAP\n\tvTransmissionMapUv = ( transmissionMapTransform * vec3( TRANSMISSIONMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_THICKNESSMAP\n\tvThicknessMapUv = ( thicknessMapTransform * vec3( THICKNESSMAP_UV, 1 ) ).xy;\n#endif",worldpos_vertex:"#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION ) || NUM_SPOT_LIGHT_COORDS > 0\n\tvec4 worldPosition = vec4( transformed, 1.0 );\n\t#ifdef USE_BATCHING\n\t\tworldPosition = batchingMatrix * worldPosition;\n\t#endif\n\t#ifdef USE_INSTANCING\n\t\tworldPosition = instanceMatrix * worldPosition;\n\t#endif\n\tworldPosition = modelMatrix * worldPosition;\n#endif",background_vert:"varying vec2 vUv;\nuniform mat3 uvTransform;\nvoid main() {\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\tgl_Position = vec4( position.xy, 1.0, 1.0 );\n}",background_frag:"uniform sampler2D t2D;\nuniform float backgroundIntensity;\nvarying vec2 vUv;\nvoid main() {\n\tvec4 texColor = texture2D( t2D, vUv );\n\t#ifdef DECODE_VIDEO_TEXTURE\n\t\ttexColor = vec4( mix( pow( texColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), texColor.rgb * 0.0773993808, vec3( lessThanEqual( texColor.rgb, vec3( 0.04045 ) ) ) ), texColor.w );\n\t#endif\n\ttexColor.rgb *= backgroundIntensity;\n\tgl_FragColor = texColor;\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n}",backgroundCube_vert:"varying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n\tgl_Position.z = gl_Position.w;\n}",backgroundCube_frag:"#ifdef ENVMAP_TYPE_CUBE\n\tuniform samplerCube envMap;\n#elif defined( ENVMAP_TYPE_CUBE_UV )\n\tuniform sampler2D envMap;\n#endif\nuniform float flipEnvMap;\nuniform float backgroundBlurriness;\nuniform float backgroundIntensity;\nuniform mat3 backgroundRotation;\nvarying vec3 vWorldDirection;\n#include <cube_uv_reflection_fragment>\nvoid main() {\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 texColor = textureCube( envMap, backgroundRotation * vec3( flipEnvMap * vWorldDirection.x, vWorldDirection.yz ) );\n\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\tvec4 texColor = textureCubeUV( envMap, backgroundRotation * vWorldDirection, backgroundBlurriness );\n\t#else\n\t\tvec4 texColor = vec4( 0.0, 0.0, 0.0, 1.0 );\n\t#endif\n\ttexColor.rgb *= backgroundIntensity;\n\tgl_FragColor = texColor;\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n}",cube_vert:"varying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n\tgl_Position.z = gl_Position.w;\n}",cube_frag:"uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldDirection;\nvoid main() {\n\tvec4 texColor = textureCube( tCube, vec3( tFlip * vWorldDirection.x, vWorldDirection.yz ) );\n\tgl_FragColor = texColor;\n\tgl_FragColor.a *= opacity;\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n}",depth_vert:"#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include <uv_vertex>\n\t#include <batching_vertex>\n\t#include <skinbase_vertex>\n\t#include <morphinstance_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvHighPrecisionZW = gl_Position.zw;\n}",depth_frag:"#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include <common>\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include <clipping_planes_fragment>\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\t#include <logdepthbuf_fragment>\n\t#ifdef USE_REVERSED_DEPTH_BUFFER\n\t\tfloat fragCoordZ = vHighPrecisionZW[ 0 ] / vHighPrecisionZW[ 1 ];\n\t#else\n\t\tfloat fragCoordZ = 0.5 * vHighPrecisionZW[ 0 ] / vHighPrecisionZW[ 1 ] + 0.5;\n\t#endif\n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( fragCoordZ );\n\t#elif DEPTH_PACKING == 3202\n\t\tgl_FragColor = vec4( packDepthToRGB( fragCoordZ ), 1.0 );\n\t#elif DEPTH_PACKING == 3203\n\t\tgl_FragColor = vec4( packDepthToRG( fragCoordZ ), 0.0, 1.0 );\n\t#endif\n}",distanceRGBA_vert:"#define DISTANCE\nvarying vec3 vWorldPosition;\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <batching_vertex>\n\t#include <skinbase_vertex>\n\t#include <morphinstance_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\tvWorldPosition = worldPosition.xyz;\n}",distanceRGBA_frag:"#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include <common>\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main () {\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include <clipping_planes_fragment>\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = packDepthToRGBA( dist );\n}",equirect_vert:"varying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n}",equirect_frag:"uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV = equirectUv( direction );\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n}",linedashed_vert:"uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include <common>\n#include <uv_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\tvLineDistance = scale * lineDistance;\n\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <morphinstance_vertex>\n\t#include <morphcolor_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n}",linedashed_frag:"uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <clipping_planes_fragment>\n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n}",meshbasic_vert:"#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <morphinstance_vertex>\n\t#include <morphcolor_vertex>\n\t#include <batching_vertex>\n\t#if defined ( USE_ENVMAP ) || defined ( USE_SKINNING )\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinbase_vertex>\n\t\t#include <skinnormal_vertex>\n\t\t#include <defaultnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <fog_vertex>\n}",meshbasic_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <clipping_planes_fragment>\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\t#include <specularmap_fragment>\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel = texture2D( lightMap, vLightMapUv );\n\t\treflectedLight.indirectDiffuse += lightMapTexel.rgb * lightMapIntensity * RECIPROCAL_PI;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include <aomap_fragment>\n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include <envmap_fragment>\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}",meshlambert_vert:"#define LAMBERT\nvarying vec3 vViewPosition;\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <morphinstance_vertex>\n\t#include <morphcolor_vertex>\n\t#include <batching_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}",meshlambert_frag:"#define LAMBERT\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <normal_pars_fragment>\n#include <lights_lambert_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <clipping_planes_fragment>\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\t#include <specularmap_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_lambert_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include <envmap_fragment>\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}",meshmatcap_vert:"#define MATCAP\nvarying vec3 vViewPosition;\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <color_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <morphinstance_vertex>\n\t#include <morphcolor_vertex>\n\t#include <batching_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n\tvViewPosition = - mvPosition.xyz;\n}",meshmatcap_frag:"#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\nvarying vec3 vViewPosition;\n#include <common>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <fog_pars_fragment>\n#include <normal_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <clipping_planes_fragment>\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\tvec3 viewDir = normalize( vViewPosition );\n\tvec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n\tvec3 y = cross( viewDir, x );\n\tvec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5;\n\t#ifdef USE_MATCAP\n\t\tvec4 matcapColor = texture2D( matcap, uv );\n\t#else\n\t\tvec4 matcapColor = vec4( vec3( mix( 0.2, 0.8, uv.y ) ), 1.0 );\n\t#endif\n\tvec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}",meshnormal_vert:"#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )\n\tvarying vec3 vViewPosition;\n#endif\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <batching_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphinstance_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}",meshnormal_frag:"#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )\n\tvarying vec3 vViewPosition;\n#endif\n#include <packing>\n#include <uv_pars_fragment>\n#include <normal_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\tvec4 diffuseColor = vec4( 0.0, 0.0, 0.0, opacity );\n\t#include <clipping_planes_fragment>\n\t#include <logdepthbuf_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\tgl_FragColor = vec4( packNormalToRGB( normal ), diffuseColor.a );\n\t#ifdef OPAQUE\n\t\tgl_FragColor.a = 1.0;\n\t#endif\n}",meshphong_vert:"#define PHONG\nvarying vec3 vViewPosition;\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <morphcolor_vertex>\n\t#include <batching_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphinstance_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}",meshphong_frag:"#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <normal_pars_fragment>\n#include <lights_phong_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <clipping_planes_fragment>\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\t#include <specularmap_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_phong_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include <envmap_fragment>\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}",meshphysical_vert:"#define STANDARD\nvarying vec3 vViewPosition;\n#ifdef USE_TRANSMISSION\n\tvarying vec3 vWorldPosition;\n#endif\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <morphinstance_vertex>\n\t#include <morphcolor_vertex>\n\t#include <batching_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n#ifdef USE_TRANSMISSION\n\tvWorldPosition = worldPosition.xyz;\n#endif\n}",meshphysical_frag:"#define STANDARD\n#ifdef PHYSICAL\n\t#define IOR\n\t#define USE_SPECULAR\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef IOR\n\tuniform float ior;\n#endif\n#ifdef USE_SPECULAR\n\tuniform float specularIntensity;\n\tuniform vec3 specularColor;\n\t#ifdef USE_SPECULAR_COLORMAP\n\t\tuniform sampler2D specularColorMap;\n\t#endif\n\t#ifdef USE_SPECULAR_INTENSITYMAP\n\t\tuniform sampler2D specularIntensityMap;\n\t#endif\n#endif\n#ifdef USE_CLEARCOAT\n\tuniform float clearcoat;\n\tuniform float clearcoatRoughness;\n#endif\n#ifdef USE_DISPERSION\n\tuniform float dispersion;\n#endif\n#ifdef USE_IRIDESCENCE\n\tuniform float iridescence;\n\tuniform float iridescenceIOR;\n\tuniform float iridescenceThicknessMinimum;\n\tuniform float iridescenceThicknessMaximum;\n#endif\n#ifdef USE_SHEEN\n\tuniform vec3 sheenColor;\n\tuniform float sheenRoughness;\n\t#ifdef USE_SHEEN_COLORMAP\n\t\tuniform sampler2D sheenColorMap;\n\t#endif\n\t#ifdef USE_SHEEN_ROUGHNESSMAP\n\t\tuniform sampler2D sheenRoughnessMap;\n\t#endif\n#endif\n#ifdef USE_ANISOTROPY\n\tuniform vec2 anisotropyVector;\n\t#ifdef USE_ANISOTROPYMAP\n\t\tuniform sampler2D anisotropyMap;\n\t#endif\n#endif\nvarying vec3 vViewPosition;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <iridescence_fragment>\n#include <cube_uv_reflection_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_physical_pars_fragment>\n#include <fog_pars_fragment>\n#include <lights_pars_begin>\n#include <normal_pars_fragment>\n#include <lights_physical_pars_fragment>\n#include <transmission_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <clearcoat_pars_fragment>\n#include <iridescence_pars_fragment>\n#include <roughnessmap_pars_fragment>\n#include <metalnessmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <clipping_planes_fragment>\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\t#include <roughnessmap_fragment>\n\t#include <metalnessmap_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <clearcoat_normal_fragment_begin>\n\t#include <clearcoat_normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_physical_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 totalDiffuse = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse;\n\tvec3 totalSpecular = reflectedLight.directSpecular + reflectedLight.indirectSpecular;\n\t#include <transmission_fragment>\n\tvec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance;\n\t#ifdef USE_SHEEN\n\t\tfloat sheenEnergyComp = 1.0 - 0.157 * max3( material.sheenColor );\n\t\toutgoingLight = outgoingLight * sheenEnergyComp + sheenSpecularDirect + sheenSpecularIndirect;\n\t#endif\n\t#ifdef USE_CLEARCOAT\n\t\tfloat dotNVcc = saturate( dot( geometryClearcoatNormal, geometryViewDir ) );\n\t\tvec3 Fcc = F_Schlick( material.clearcoatF0, material.clearcoatF90, dotNVcc );\n\t\toutgoingLight = outgoingLight * ( 1.0 - material.clearcoat * Fcc ) + ( clearcoatSpecularDirect + clearcoatSpecularIndirect ) * material.clearcoat;\n\t#endif\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}",meshtoon_vert:"#define TOON\nvarying vec3 vViewPosition;\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <morphinstance_vertex>\n\t#include <morphcolor_vertex>\n\t#include <batching_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}",meshtoon_frag:"#define TOON\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <gradientmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <normal_pars_fragment>\n#include <lights_toon_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <clipping_planes_fragment>\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_toon_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}",points_vert:"uniform float size;\nuniform float scale;\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\n#ifdef USE_POINTS_UV\n\tvarying vec2 vUv;\n\tuniform mat3 uvTransform;\n#endif\nvoid main() {\n\t#ifdef USE_POINTS_UV\n\t\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\t#endif\n\t#include <color_vertex>\n\t#include <morphinstance_vertex>\n\t#include <morphcolor_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <project_vertex>\n\tgl_PointSize = size;\n\t#ifdef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\t#endif\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <fog_vertex>\n}",points_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#include <common>\n#include <color_pars_fragment>\n#include <map_particle_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <clipping_planes_fragment>\n\tvec3 outgoingLight = vec3( 0.0 );\n\t#include <logdepthbuf_fragment>\n\t#include <map_particle_fragment>\n\t#include <color_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n}",shadow_vert:"#include <common>\n#include <batching_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <shadowmap_pars_vertex>\nvoid main() {\n\t#include <batching_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphinstance_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}",shadow_frag:"uniform vec3 color;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <logdepthbuf_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <shadowmask_pars_fragment>\nvoid main() {\n\t#include <logdepthbuf_fragment>\n\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n}",sprite_vert:"uniform float rotation;\nuniform vec2 center;\n#include <common>\n#include <uv_pars_vertex>\n#include <fog_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\tvec4 mvPosition = modelViewMatrix[ 3 ];\n\tvec2 scale = vec2( length( modelMatrix[ 0 ].xyz ), length( modelMatrix[ 1 ].xyz ) );\n\t#ifndef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) scale *= - mvPosition.z;\n\t#endif\n\tvec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;\n\tvec2 rotatedPosition;\n\trotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n\trotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n\tmvPosition.xy += rotatedPosition;\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n}",sprite_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#include <common>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <clipping_planes_fragment>\n\tvec3 outgoingLight = vec3( 0.0 );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n}"},rs={common:{diffuse:{value:new dn(16777215)},opacity:{value:1},map:{value:null},mapTransform:{value:new Et},alphaMap:{value:null},alphaMapTransform:{value:new Et},alphaTest:{value:0}},specularmap:{specularMap:{value:null},specularMapTransform:{value:new Et}},envmap:{envMap:{value:null},envMapRotation:{value:new Et},flipEnvMap:{value:-1},reflectivity:{value:1},ior:{value:1.5},refractionRatio:{value:.98},dfgLUT:{value:null}},aomap:{aoMap:{value:null},aoMapIntensity:{value:1},aoMapTransform:{value:new Et}},lightmap:{lightMap:{value:null},lightMapIntensity:{value:1},lightMapTransform:{value:new Et}},bumpmap:{bumpMap:{value:null},bumpMapTransform:{value:new Et},bumpScale:{value:1}},normalmap:{normalMap:{value:null},normalMapTransform:{value:new Et},normalScale:{value:new Mt(1,1)}},displacementmap:{displacementMap:{value:null},displacementMapTransform:{value:new Et},displacementScale:{value:1},displacementBias:{value:0}},emissivemap:{emissiveMap:{value:null},emissiveMapTransform:{value:new Et}},metalnessmap:{metalnessMap:{value:null},metalnessMapTransform:{value:new Et}},roughnessmap:{roughnessMap:{value:null},roughnessMapTransform:{value:new Et}},gradientmap:{gradientMap:{value:null}},fog:{fogDensity:{value:25e-5},fogNear:{value:1},fogFar:{value:2e3},fogColor:{value:new dn(16777215)}},lights:{ambientLightColor:{value:[]},lightProbe:{value:[]},directionalLights:{value:[],properties:{direction:{},color:{}}},directionalLightShadows:{value:[],properties:{shadowIntensity:1,shadowBias:{},shadowNormalBias:{},shadowRadius:{},shadowMapSize:{}}},directionalShadowMap:{value:[]},directionalShadowMatrix:{value:[]},spotLights:{value:[],properties:{color:{},position:{},direction:{},distance:{},coneCos:{},penumbraCos:{},decay:{}}},spotLightShadows:{value:[],properties:{shadowIntensity:1,shadowBias:{},shadowNormalBias:{},shadowRadius:{},shadowMapSize:{}}},spotLightMap:{value:[]},spotShadowMap:{value:[]},spotLightMatrix:{value:[]},pointLights:{value:[],properties:{color:{},position:{},decay:{},distance:{}}},pointLightShadows:{value:[],properties:{shadowIntensity:1,shadowBias:{},shadowNormalBias:{},shadowRadius:{},shadowMapSize:{},shadowCameraNear:{},shadowCameraFar:{}}},pointShadowMap:{value:[]},pointShadowMatrix:{value:[]},hemisphereLights:{value:[],properties:{direction:{},skyColor:{},groundColor:{}}},rectAreaLights:{value:[],properties:{color:{},position:{},width:{},height:{}}},ltc_1:{value:null},ltc_2:{value:null}},points:{diffuse:{value:new dn(16777215)},opacity:{value:1},size:{value:1},scale:{value:1},map:{value:null},alphaMap:{value:null},alphaMapTransform:{value:new Et},alphaTest:{value:0},uvTransform:{value:new Et}},sprite:{diffuse:{value:new dn(16777215)},opacity:{value:1},center:{value:new Mt(.5,.5)},rotation:{value:0},map:{value:null},mapTransform:{value:new Et},alphaMap:{value:null},alphaMapTransform:{value:new Et},alphaTest:{value:0}}},ss={basic:{uniforms:Zn([rs.common,rs.specularmap,rs.envmap,rs.aomap,rs.lightmap,rs.fog]),vertexShader:as.meshbasic_vert,fragmentShader:as.meshbasic_frag},lambert:{uniforms:Zn([rs.common,rs.specularmap,rs.envmap,rs.aomap,rs.lightmap,rs.emissivemap,rs.bumpmap,rs.normalmap,rs.displacementmap,rs.fog,rs.lights,{emissive:{value:new dn(0)}}]),vertexShader:as.meshlambert_vert,fragmentShader:as.meshlambert_frag},phong:{uniforms:Zn([rs.common,rs.specularmap,rs.envmap,rs.aomap,rs.lightmap,rs.emissivemap,rs.bumpmap,rs.normalmap,rs.displacementmap,rs.fog,rs.lights,{emissive:{value:new dn(0)},specular:{value:new dn(1118481)},shininess:{value:30}}]),vertexShader:as.meshphong_vert,fragmentShader:as.meshphong_frag},standard:{uniforms:Zn([rs.common,rs.envmap,rs.aomap,rs.lightmap,rs.emissivemap,rs.bumpmap,rs.normalmap,rs.displacementmap,rs.roughnessmap,rs.metalnessmap,rs.fog,rs.lights,{emissive:{value:new dn(0)},roughness:{value:1},metalness:{value:0},envMapIntensity:{value:1}}]),vertexShader:as.meshphysical_vert,fragmentShader:as.meshphysical_frag},toon:{uniforms:Zn([rs.common,rs.aomap,rs.lightmap,rs.emissivemap,rs.bumpmap,rs.normalmap,rs.displacementmap,rs.gradientmap,rs.fog,rs.lights,{emissive:{value:new dn(0)}}]),vertexShader:as.meshtoon_vert,fragmentShader:as.meshtoon_frag},matcap:{uniforms:Zn([rs.common,rs.bumpmap,rs.normalmap,rs.displacementmap,rs.fog,{matcap:{value:null}}]),vertexShader:as.meshmatcap_vert,fragmentShader:as.meshmatcap_frag},points:{uniforms:Zn([rs.points,rs.fog]),vertexShader:as.points_vert,fragmentShader:as.points_frag},dashed:{uniforms:Zn([rs.common,rs.fog,{scale:{value:1},dashSize:{value:1},totalSize:{value:2}}]),vertexShader:as.linedashed_vert,fragmentShader:as.linedashed_frag},depth:{uniforms:Zn([rs.common,rs.displacementmap]),vertexShader:as.depth_vert,fragmentShader:as.depth_frag},normal:{uniforms:Zn([rs.common,rs.bumpmap,rs.normalmap,rs.displacementmap,{opacity:{value:1}}]),vertexShader:as.meshnormal_vert,fragmentShader:as.meshnormal_frag},sprite:{uniforms:Zn([rs.sprite,rs.fog]),vertexShader:as.sprite_vert,fragmentShader:as.sprite_frag},background:{uniforms:{uvTransform:{value:new Et},t2D:{value:null},backgroundIntensity:{value:1}},vertexShader:as.background_vert,fragmentShader:as.background_frag},backgroundCube:{uniforms:{envMap:{value:null},flipEnvMap:{value:-1},backgroundBlurriness:{value:0},backgroundIntensity:{value:1},backgroundRotation:{value:new Et}},vertexShader:as.backgroundCube_vert,fragmentShader:as.backgroundCube_frag},cube:{uniforms:{tCube:{value:null},tFlip:{value:-1},opacity:{value:1}},vertexShader:as.cube_vert,fragmentShader:as.cube_frag},equirect:{uniforms:{tEquirect:{value:null}},vertexShader:as.equirect_vert,fragmentShader:as.equirect_frag},distanceRGBA:{uniforms:Zn([rs.common,rs.displacementmap,{referencePosition:{value:new xt},nearDistance:{value:1},farDistance:{value:1e3}}]),vertexShader:as.distanceRGBA_vert,fragmentShader:as.distanceRGBA_frag},shadow:{uniforms:Zn([rs.lights,rs.fog,{color:{value:new dn(0)},opacity:{value:1}}]),vertexShader:as.shadow_vert,fragmentShader:as.shadow_frag}};ss.physical={uniforms:Zn([ss.standard.uniforms,{clearcoat:{value:0},clearcoatMap:{value:null},clearcoatMapTransform:{value:new Et},clearcoatNormalMap:{value:null},clearcoatNormalMapTransform:{value:new Et},clearcoatNormalScale:{value:new Mt(1,1)},clearcoatRoughness:{value:0},clearcoatRoughnessMap:{value:null},clearcoatRoughnessMapTransform:{value:new Et},dispersion:{value:0},iridescence:{value:0},iridescenceMap:{value:null},iridescenceMapTransform:{value:new Et},iridescenceIOR:{value:1.3},iridescenceThicknessMinimum:{value:100},iridescenceThicknessMaximum:{value:400},iridescenceThicknessMap:{value:null},iridescenceThicknessMapTransform:{value:new Et},sheen:{value:0},sheenColor:{value:new dn(0)},sheenColorMap:{value:null},sheenColorMapTransform:{value:new Et},sheenRoughness:{value:1},sheenRoughnessMap:{value:null},sheenRoughnessMapTransform:{value:new Et},transmission:{value:0},transmissionMap:{value:null},transmissionMapTransform:{value:new Et},transmissionSamplerSize:{value:new Mt},transmissionSamplerMap:{value:null},thickness:{value:0},thicknessMap:{value:null},thicknessMapTransform:{value:new Et},attenuationDistance:{value:0},attenuationColor:{value:new dn(0)},specularColor:{value:new dn(1,1,1)},specularColorMap:{value:null},specularColorMapTransform:{value:new Et},specularIntensity:{value:1},specularIntensityMap:{value:null},specularIntensityMapTransform:{value:new Et},anisotropyVector:{value:new Mt},anisotropyMap:{value:null},anisotropyMapTransform:{value:new Et}}]),vertexShader:as.meshphysical_vert,fragmentShader:as.meshphysical_frag};const os={r:0,b:0,g:0},ls=new Pi,hs=new bi;function cs(e,t,i,n,a,r,s){const o=new dn(0);let l,h,c=!0===r?0:1,u=null,d=0,p=null;function m(e){let n=!0===e.isScene?e.background:null;return n&&n.isTexture&&(n=(e.backgroundBlurriness>0?i:t).get(n)),n}function f(t,i){t.getRGB(os,Kn(e)),n.buffers.color.setClear(os.r,os.g,os.b,i,s)}return{getClearColor:function(){return o},setClearColor:function(e,t=1){o.set(e),c=t,f(o,c)},getClearAlpha:function(){return c},setClearAlpha:function(e){c=e,f(o,c)},render:function(t){let i=!1;const a=m(t);null===a?f(o,c):a&&a.isColor&&(f(a,1),i=!0);const r=e.xr.getEnvironmentBlendMode();"additive"===r?n.buffers.color.setClear(0,0,0,1,s):"alpha-blend"===r&&n.buffers.color.setClear(0,0,0,0,s),(e.autoClear||i)&&(n.buffers.depth.setTest(!0),n.buffers.depth.setMask(!0),n.buffers.color.setMask(!0),e.clear(e.autoClearColor,e.autoClearDepth,e.autoClearStencil))},addToRenderList:function(t,i){const n=m(i);n&&(n.isCubeTexture||n.mapping===L)?(void 0===h&&(h=new Xn(new Yn(1,1,1),new Jn({name:"BackgroundCubeMaterial",uniforms:$n(ss.backgroundCube.uniforms),vertexShader:ss.backgroundCube.vertexShader,fragmentShader:ss.backgroundCube.fragmentShader,side:1,depthTest:!1,depthWrite:!1,fog:!1,allowOverride:!1})),h.geometry.deleteAttribute("normal"),h.geometry.deleteAttribute("uv"),h.onBeforeRender=function(e,t,i){this.matrixWorld.copyPosition(i.matrixWorld)},Object.defineProperty(h.material,"envMap",{get:function(){return this.uniforms.envMap.value}}),a.update(h)),ls.copy(i.backgroundRotation),ls.x*=-1,ls.y*=-1,ls.z*=-1,n.isCubeTexture&&!1===n.isRenderTargetTexture&&(ls.y*=-1,ls.z*=-1),h.material.uniforms.envMap.value=n,h.material.uniforms.flipEnvMap.value=n.isCubeTexture&&!1===n.isRenderTargetTexture?-1:1,h.material.uniforms.backgroundBlurriness.value=i.backgroundBlurriness,h.material.uniforms.backgroundIntensity.value=i.backgroundIntensity,h.material.uniforms.backgroundRotation.value.setFromMatrix4(hs.makeRotationFromEuler(ls)),h.material.toneMapped=Dt.getTransfer(n.colorSpace)!==Ge,u===n&&d===n.version&&p===e.toneMapping||(h.material.needsUpdate=!0,u=n,d=n.version,p=e.toneMapping),h.layers.enableAll(),t.unshift(h,h.geometry,h.material,0,0,null)):n&&n.isTexture&&(void 0===l&&(l=new Xn(new fr(2,2),new Jn({name:"BackgroundMaterial",uniforms:$n(ss.background.uniforms),vertexShader:ss.background.vertexShader,fragmentShader:ss.background.fragmentShader,side:0,depthTest:!1,depthWrite:!1,fog:!1,allowOverride:!1})),l.geometry.deleteAttribute("normal"),Object.defineProperty(l.material,"map",{get:function(){return this.uniforms.t2D.value}}),a.update(l)),l.material.uniforms.t2D.value=n,l.material.uniforms.backgroundIntensity.value=i.backgroundIntensity,l.material.toneMapped=Dt.getTransfer(n.colorSpace)!==Ge,!0===n.matrixAutoUpdate&&n.updateMatrix(),l.material.uniforms.uvTransform.value.copy(n.matrix),u===n&&d===n.version&&p===e.toneMapping||(l.material.needsUpdate=!0,u=n,d=n.version,p=e.toneMapping),l.layers.enableAll(),t.unshift(l,l.geometry,l.material,0,0,null))},dispose:function(){void 0!==h&&(h.geometry.dispose(),h.material.dispose(),h=void 0),void 0!==l&&(l.geometry.dispose(),l.material.dispose(),l=void 0)}}}function us(e,t){const i=e.getParameter(e.MAX_VERTEX_ATTRIBS),n={},a=h(null);let r=a,s=!1;function o(t){return e.bindVertexArray(t)}function l(t){return e.deleteVertexArray(t)}function h(e){const t=[],n=[],a=[];for(let e=0;e<i;e++)t[e]=0,n[e]=0,a[e]=0;return{geometry:null,program:null,wireframe:!1,newAttributes:t,enabledAttributes:n,attributeDivisors:a,object:e,attributes:{},index:null}}function c(){const e=r.newAttributes;for(let t=0,i=e.length;t<i;t++)e[t]=0}function u(e){d(e,0)}function d(t,i){const n=r.newAttributes,a=r.enabledAttributes,s=r.attributeDivisors;n[t]=1,0===a[t]&&(e.enableVertexAttribArray(t),a[t]=1),s[t]!==i&&(e.vertexAttribDivisor(t,i),s[t]=i)}function p(){const t=r.newAttributes,i=r.enabledAttributes;for(let n=0,a=i.length;n<a;n++)i[n]!==t[n]&&(e.disableVertexAttribArray(n),i[n]=0)}function m(t,i,n,a,r,s,o){!0===o?e.vertexAttribIPointer(t,i,n,r,s):e.vertexAttribPointer(t,i,n,a,r,s)}function f(){g(),s=!0,r!==a&&(r=a,o(r.object))}function g(){a.geometry=null,a.program=null,a.wireframe=!1}return{setup:function(i,a,l,f,g){let v=!1;const y=function(t,i,a){const r=!0===a.wireframe;let s=n[t.id];void 0===s&&(s={},n[t.id]=s);let o=s[i.id];void 0===o&&(o={},s[i.id]=o);let l=o[r];return void 0===l&&(l=h(e.createVertexArray()),o[r]=l),l}(f,l,a);r!==y&&(r=y,o(r.object)),v=function(e,t,i,n){const a=r.attributes,s=t.attributes;let o=0;const l=i.getAttributes();for(const t in l)if(l[t].location>=0){const i=a[t];let n=s[t];if(void 0===n&&("instanceMatrix"===t&&e.instanceMatrix&&(n=e.instanceMatrix),"instanceColor"===t&&e.instanceColor&&(n=e.instanceColor)),void 0===i)return!0;if(i.attribute!==n)return!0;if(n&&i.data!==n.data)return!0;o++}return r.attributesNum!==o||r.index!==n}(i,f,l,g),v&&function(e,t,i,n){const a={},s=t.attributes;let o=0;const l=i.getAttributes();for(const t in l)if(l[t].location>=0){let i=s[t];void 0===i&&("instanceMatrix"===t&&e.instanceMatrix&&(i=e.instanceMatrix),"instanceColor"===t&&e.instanceColor&&(i=e.instanceColor));const n={};n.attribute=i,i&&i.data&&(n.data=i.data),a[t]=n,o++}r.attributes=a,r.attributesNum=o,r.index=n}(i,f,l,g),null!==g&&t.update(g,e.ELEMENT_ARRAY_BUFFER),(v||s)&&(s=!1,function(i,n,a,r){c();const s=r.attributes,o=a.getAttributes(),l=n.defaultAttributeValues;for(const n in o){const a=o[n];if(a.location>=0){let o=s[n];if(void 0===o&&("instanceMatrix"===n&&i.instanceMatrix&&(o=i.instanceMatrix),"instanceColor"===n&&i.instanceColor&&(o=i.instanceColor)),void 0!==o){const n=o.normalized,s=o.itemSize,l=t.get(o);if(void 0===l)continue;const h=l.buffer,c=l.type,p=l.bytesPerElement,f=c===e.INT||c===e.UNSIGNED_INT||o.gpuType===j;if(o.isInterleavedBufferAttribute){const t=o.data,l=t.stride,g=o.offset;if(t.isInstancedInterleavedBuffer){for(let e=0;e<a.locationSize;e++)d(a.location+e,t.meshPerAttribute);!0!==i.isInstancedMesh&&void 0===r._maxInstanceCount&&(r._maxInstanceCount=t.meshPerAttribute*t.count)}else for(let e=0;e<a.locationSize;e++)u(a.location+e);e.bindBuffer(e.ARRAY_BUFFER,h);for(let e=0;e<a.locationSize;e++)m(a.location+e,s/a.locationSize,c,n,l*p,(g+s/a.locationSize*e)*p,f)}else{if(o.isInstancedBufferAttribute){for(let e=0;e<a.locationSize;e++)d(a.location+e,o.meshPerAttribute);!0!==i.isInstancedMesh&&void 0===r._maxInstanceCount&&(r._maxInstanceCount=o.meshPerAttribute*o.count)}else for(let e=0;e<a.locationSize;e++)u(a.location+e);e.bindBuffer(e.ARRAY_BUFFER,h);for(let e=0;e<a.locationSize;e++)m(a.location+e,s/a.locationSize,c,n,s*p,s/a.locationSize*e*p,f)}}else if(void 0!==l){const t=l[n];if(void 0!==t)switch(t.length){case 2:e.vertexAttrib2fv(a.location,t);break;case 3:e.vertexAttrib3fv(a.location,t);break;case 4:e.vertexAttrib4fv(a.location,t);break;default:e.vertexAttrib1fv(a.location,t)}}}}p()}(i,a,l,f),null!==g&&e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,t.get(g).buffer))},reset:f,resetDefaultState:g,dispose:function(){f();for(const e in n){const t=n[e];for(const e in t){const i=t[e];for(const e in i)l(i[e].object),delete i[e];delete t[e]}delete n[e]}},releaseStatesOfGeometry:function(e){if(void 0===n[e.id])return;const t=n[e.id];for(const e in t){const i=t[e];for(const e in i)l(i[e].object),delete i[e];delete t[e]}delete n[e.id]},releaseStatesOfProgram:function(e){for(const t in n){const i=n[t];if(void 0===i[e.id])continue;const a=i[e.id];for(const e in a)l(a[e].object),delete a[e];delete i[e.id]}},initAttributes:c,enableAttribute:u,disableUnusedAttributes:p}}function ds(e,t,i){let n;function a(t,a,r){0!==r&&(e.drawArraysInstanced(n,t,a,r),i.update(a,n,r))}this.setMode=function(e){n=e},this.render=function(t,a){e.drawArrays(n,t,a),i.update(a,n,1)},this.renderInstances=a,this.renderMultiDraw=function(e,a,r){if(0===r)return;t.get("WEBGL_multi_draw").multiDrawArraysWEBGL(n,e,0,a,0,r);let s=0;for(let e=0;e<r;e++)s+=a[e];i.update(s,n,1)},this.renderMultiDrawInstances=function(e,r,s,o){if(0===s)return;const l=t.get("WEBGL_multi_draw");if(null===l)for(let t=0;t<e.length;t++)a(e[t],r[t],o[t]);else{l.multiDrawArraysInstancedWEBGL(n,e,0,r,0,o,0,s);let t=0;for(let e=0;e<s;e++)t+=r[e]*o[e];i.update(t,n,1)}}}function ps(e,t,i,n){let a;function r(t){if("highp"===t){if(e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.HIGH_FLOAT).precision>0&&e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_FLOAT).precision>0)return"highp";t="mediump"}return"mediump"===t&&e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.MEDIUM_FLOAT).precision>0&&e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_FLOAT).precision>0?"mediump":"lowp"}let s=void 0!==i.precision?i.precision:"highp";const o=r(s);o!==s&&(ot("WebGLRenderer:",s,"not supported, using",o,"instead."),s=o);const l=!0===i.logarithmicDepthBuffer,h=!0===i.reversedDepthBuffer&&t.has("EXT_clip_control"),c=e.getParameter(e.MAX_TEXTURE_IMAGE_UNITS),u=e.getParameter(e.MAX_VERTEX_TEXTURE_IMAGE_UNITS);return{isWebGL2:!0,getMaxAnisotropy:function(){if(void 0!==a)return a;if(!0===t.has("EXT_texture_filter_anisotropic")){const i=t.get("EXT_texture_filter_anisotropic");a=e.getParameter(i.MAX_TEXTURE_MAX_ANISOTROPY_EXT)}else a=0;return a},getMaxPrecision:r,textureFormatReadable:function(t){return t===Q||n.convert(t)===e.getParameter(e.IMPLEMENTATION_COLOR_READ_FORMAT)},textureTypeReadable:function(i){const a=i===Y&&(t.has("EXT_color_buffer_half_float")||t.has("EXT_color_buffer_float"));return!(i!==H&&n.convert(i)!==e.getParameter(e.IMPLEMENTATION_COLOR_READ_TYPE)&&i!==q&&!a)},precision:s,logarithmicDepthBuffer:l,reversedDepthBuffer:h,maxTextures:c,maxVertexTextures:u,maxTextureSize:e.getParameter(e.MAX_TEXTURE_SIZE),maxCubemapSize:e.getParameter(e.MAX_CUBE_MAP_TEXTURE_SIZE),maxAttributes:e.getParameter(e.MAX_VERTEX_ATTRIBS),maxVertexUniforms:e.getParameter(e.MAX_VERTEX_UNIFORM_VECTORS),maxVaryings:e.getParameter(e.MAX_VARYING_VECTORS),maxFragmentUniforms:e.getParameter(e.MAX_FRAGMENT_UNIFORM_VECTORS),vertexTextures:u>0,maxSamples:e.getParameter(e.MAX_SAMPLES)}}function ms(e){const t=this;let i=null,n=0,a=!1,r=!1;const s=new Fa,o=new Et,l={value:null,needsUpdate:!1};function h(e,i,n,a){const r=null!==e?e.length:0;let h=null;if(0!==r){if(h=l.value,!0!==a||null===h){const t=n+4*r,a=i.matrixWorldInverse;o.getNormalMatrix(a),(null===h||h.length<t)&&(h=new Float32Array(t));for(let t=0,i=n;t!==r;++t,i+=4)s.copy(e[t]).applyMatrix4(a,o),s.normal.toArray(h,i),h[i+3]=s.constant}l.value=h,l.needsUpdate=!0}return t.numPlanes=r,t.numIntersection=0,h}this.uniform=l,this.numPlanes=0,this.numIntersection=0,this.init=function(e,t){const i=0!==e.length||t||0!==n||a;return a=t,n=e.length,i},this.beginShadows=function(){r=!0,h(null)},this.endShadows=function(){r=!1},this.setGlobalState=function(e,t){i=h(e,t,0)},this.setState=function(s,o,c){const u=s.clippingPlanes,d=s.clipIntersection,p=s.clipShadows,m=e.get(s);if(!a||null===u||0===u.length||r&&!p)r?h(null):(l.value!==i&&(l.value=i,l.needsUpdate=n>0),t.numPlanes=n,t.numIntersection=0);else{const e=r?0:n,t=4*e;let a=m.clippingState||null;l.value=a,a=h(u,o,t,c);for(let e=0;e!==t;++e)a[e]=i[e];m.clippingState=a,this.numIntersection=d?this.numPlanes:0,this.numPlanes+=e}}}function fs(e){let t=new WeakMap;function i(e,t){return t===I?e.mapping=D:304===t&&(e.mapping=R),e}function n(e){const i=e.target;i.removeEventListener("dispose",n);const a=t.get(i);void 0!==a&&(t.delete(i),a.dispose())}return{get:function(a){if(a&&a.isTexture){const r=a.mapping;if(r===I||304===r){if(t.has(a))return i(t.get(a).texture,a.mapping);{const r=a.image;if(r&&r.height>0){const s=new la(r.height);return s.fromEquirectangularTexture(e,a),t.set(a,s),a.addEventListener("dispose",n),i(s.texture,a.mapping)}return null}}}return a},dispose:function(){t=new WeakMap}}}const gs=[.125,.215,.35,.446,.526,.582],vs=new qr,ys=new dn;let bs=null,Ms=0,_s=0,xs=!1;const Ss=new xt;class ws{constructor(e){this._renderer=e,this._pingPongRenderTarget=null,this._lodMax=0,this._cubeSize=0,this._sizeLods=[],this._sigmas=[],this._lodMeshes=[],this._backgroundBox=null,this._cubemapMaterial=null,this._equirectMaterial=null,this._blurMaterial=null,this._ggxMaterial=null}fromScene(e,t=0,i=.1,n=100,a={}){const{size:r=256,position:s=Ss}=a;bs=this._renderer.getRenderTarget(),Ms=this._renderer.getActiveCubeFace(),_s=this._renderer.getActiveMipmapLevel(),xs=this._renderer.xr.enabled,this._renderer.xr.enabled=!1,this._setSize(r);const o=this._allocateTargets();return o.depthBuffer=!0,this._sceneToCubeUV(e,i,n,o,s),t>0&&this._blur(o,0,0,t),this._applyPMREM(o),this._cleanup(o),o}fromEquirectangular(e,t=null){return this._fromTexture(e,t)}fromCubemap(e,t=null){return this._fromTexture(e,t)}compileCubemapShader(){null===this._cubemapMaterial&&(this._cubemapMaterial=As(),this._compileMaterial(this._cubemapMaterial))}compileEquirectangularShader(){null===this._equirectMaterial&&(this._equirectMaterial=Cs(),this._compileMaterial(this._equirectMaterial))}dispose(){this._dispose(),null!==this._cubemapMaterial&&this._cubemapMaterial.dispose(),null!==this._equirectMaterial&&this._equirectMaterial.dispose(),null!==this._backgroundBox&&(this._backgroundBox.geometry.dispose(),this._backgroundBox.material.dispose())}_setSize(e){this._lodMax=Math.floor(Math.log2(e)),this._cubeSize=Math.pow(2,this._lodMax)}_dispose(){null!==this._blurMaterial&&this._blurMaterial.dispose(),null!==this._ggxMaterial&&this._ggxMaterial.dispose(),null!==this._pingPongRenderTarget&&this._pingPongRenderTarget.dispose();for(let e=0;e<this._lodMeshes.length;e++)this._lodMeshes[e].geometry.dispose()}_cleanup(e){this._renderer.setRenderTarget(bs,Ms,_s),this._renderer.xr.enabled=xs,e.scissorTest=!1,Ts(e,0,0,e.width,e.height)}_fromTexture(e,t){e.mapping===D||e.mapping===R?this._setSize(0===e.image.length?16:e.image[0].width||e.image[0].image.width):this._setSize(e.image.width/4),bs=this._renderer.getRenderTarget(),Ms=this._renderer.getActiveCubeFace(),_s=this._renderer.getActiveMipmapLevel(),xs=this._renderer.xr.enabled,this._renderer.xr.enabled=!1;const i=t||this._allocateTargets();return this._textureToCubeUV(e,i),this._applyPMREM(i),this._cleanup(i),i}_allocateTargets(){const e=3*Math.max(this._cubeSize,112),t=4*this._cubeSize,i={magFilter:N,minFilter:N,generateMipmaps:!1,type:Y,format:Q,colorSpace:ke,depthBuffer:!1},n=Es(e,t,i);if(null===this._pingPongRenderTarget||this._pingPongRenderTarget.width!==e||this._pingPongRenderTarget.height!==t){null!==this._pingPongRenderTarget&&this._dispose(),this._pingPongRenderTarget=Es(e,t,i);const{_lodMax:n}=this;({lodMeshes:this._lodMeshes,sizeLods:this._sizeLods,sigmas:this._sigmas}=function(e){const t=[],i=[],n=[];let a=e;const r=e-4+1+gs.length;for(let s=0;s<r;s++){const r=Math.pow(2,a);t.push(r);let o=1/r;s>e-4?o=gs[s-e+4-1]:0===s&&(o=0),i.push(o);const l=1/(r-2),h=-l,c=1+l,u=[h,h,c,h,c,c,h,h,c,c,h,c],d=6,p=6,m=3,f=2,g=1,v=new Float32Array(m*p*d),y=new Float32Array(f*p*d),b=new Float32Array(g*p*d);for(let e=0;e<d;e++){const t=e%3*2/3-1,i=e>2?0:-1,n=[t,i,0,t+2/3,i,0,t+2/3,i+1,0,t,i,0,t+2/3,i+1,0,t,i+1,0];v.set(n,m*p*e),y.set(u,f*p*e);const a=[e,e,e,e,e,e];b.set(a,g*p*e)}const M=new Bn;M.setAttribute("position",new Sn(v,m)),M.setAttribute("uv",new Sn(y,f)),M.setAttribute("faceIndex",new Sn(b,g)),n.push(new Xn(M,null)),a>4&&a--}return{lodMeshes:n,sizeLods:t,sigmas:i}}(n)),this._blurMaterial=function(e,t,i){const n=new Float32Array(20),a=new xt(0,1,0);return new Jn({name:"SphericalGaussianBlur",defines:{n:20,CUBEUV_TEXEL_WIDTH:1/t,CUBEUV_TEXEL_HEIGHT:1/i,CUBEUV_MAX_MIP:`${e}.0`},uniforms:{envMap:{value:null},samples:{value:1},weights:{value:n},latitudinal:{value:!1},dTheta:{value:0},mipInt:{value:0},poleAxis:{value:a}},vertexShader:"\n\n\t\tprecision mediump float;\n\t\tprecision mediump int;\n\n\t\tattribute float faceIndex;\n\n\t\tvarying vec3 vOutputDirection;\n\n\t\t// RH coordinate system; PMREM face-indexing convention\n\t\tvec3 getDirection( vec2 uv, float face ) {\n\n\t\t\tuv = 2.0 * uv - 1.0;\n\n\t\t\tvec3 direction = vec3( uv, 1.0 );\n\n\t\t\tif ( face == 0.0 ) {\n\n\t\t\t\tdirection = direction.zyx; // ( 1, v, u ) pos x\n\n\t\t\t} else if ( face == 1.0 ) {\n\n\t\t\t\tdirection = direction.xzy;\n\t\t\t\tdirection.xz *= -1.0; // ( -u, 1, -v ) pos y\n\n\t\t\t} else if ( face == 2.0 ) {\n\n\t\t\t\tdirection.x *= -1.0; // ( -u, v, 1 ) pos z\n\n\t\t\t} else if ( face == 3.0 ) {\n\n\t\t\t\tdirection = direction.zyx;\n\t\t\t\tdirection.xz *= -1.0; // ( -1, v, -u ) neg x\n\n\t\t\t} else if ( face == 4.0 ) {\n\n\t\t\t\tdirection = direction.xzy;\n\t\t\t\tdirection.xy *= -1.0; // ( -u, -1, v ) neg y\n\n\t\t\t} else if ( face == 5.0 ) {\n\n\t\t\t\tdirection.z *= -1.0; // ( u, v, -1 ) neg z\n\n\t\t\t}\n\n\t\t\treturn direction;\n\n\t\t}\n\n\t\tvoid main() {\n\n\t\t\tvOutputDirection = getDirection( uv, faceIndex );\n\t\t\tgl_Position = vec4( position, 1.0 );\n\n\t\t}\n\t",fragmentShader:"\n\n\t\t\tprecision mediump float;\n\t\t\tprecision mediump int;\n\n\t\t\tvarying vec3 vOutputDirection;\n\n\t\t\tuniform sampler2D envMap;\n\t\t\tuniform int samples;\n\t\t\tuniform float weights[ n ];\n\t\t\tuniform bool latitudinal;\n\t\t\tuniform float dTheta;\n\t\t\tuniform float mipInt;\n\t\t\tuniform vec3 poleAxis;\n\n\t\t\t#define ENVMAP_TYPE_CUBE_UV\n\t\t\t#include <cube_uv_reflection_fragment>\n\n\t\t\tvec3 getSample( float theta, vec3 axis ) {\n\n\t\t\t\tfloat cosTheta = cos( theta );\n\t\t\t\t// Rodrigues' axis-angle rotation\n\t\t\t\tvec3 sampleDirection = vOutputDirection * cosTheta\n\t\t\t\t\t+ cross( axis, vOutputDirection ) * sin( theta )\n\t\t\t\t\t+ axis * dot( axis, vOutputDirection ) * ( 1.0 - cosTheta );\n\n\t\t\t\treturn bilinearCubeUV( envMap, sampleDirection, mipInt );\n\n\t\t\t}\n\n\t\t\tvoid main() {\n\n\t\t\t\tvec3 axis = latitudinal ? poleAxis : cross( poleAxis, vOutputDirection );\n\n\t\t\t\tif ( all( equal( axis, vec3( 0.0 ) ) ) ) {\n\n\t\t\t\t\taxis = vec3( vOutputDirection.z, 0.0, - vOutputDirection.x );\n\n\t\t\t\t}\n\n\t\t\t\taxis = normalize( axis );\n\n\t\t\t\tgl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );\n\t\t\t\tgl_FragColor.rgb += weights[ 0 ] * getSample( 0.0, axis );\n\n\t\t\t\tfor ( int i = 1; i < n; i++ ) {\n\n\t\t\t\t\tif ( i >= samples ) {\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfloat theta = dTheta * float( i );\n\t\t\t\t\tgl_FragColor.rgb += weights[ i ] * getSample( -1.0 * theta, axis );\n\t\t\t\t\tgl_FragColor.rgb += weights[ i ] * getSample( theta, axis );\n\n\t\t\t\t}\n\n\t\t\t}\n\t\t",blending:0,depthTest:!1,depthWrite:!1})}(n,e,t)}return n}_compileMaterial(e){const t=new Xn(new Bn,e);this._renderer.compile(t,vs)}_sceneToCubeUV(e,t,i,n,a){const r=new aa(90,1,t,i),s=[1,-1,1,1,1,1],o=[1,1,1,-1,-1,-1],l=this._renderer,h=l.autoClear,c=l.toneMapping;l.getClearColor(ys),l.toneMapping=0,l.autoClear=!1,l.state.buffers.depth.getReversed()&&(l.setRenderTarget(n),l.clearDepth(),l.setRenderTarget(null)),null===this._backgroundBox&&(this._backgroundBox=new Xn(new Yn,new gn({name:"PMREM.Background",side:1,depthWrite:!1,depthTest:!1})));const u=this._backgroundBox,d=u.material;let p=!1;const m=e.background;m?m.isColor&&(d.color.copy(m),e.background=null,p=!0):(d.color.copy(ys),p=!0);for(let t=0;t<6;t++){const i=t%3;0===i?(r.up.set(0,s[t],0),r.position.set(a.x,a.y,a.z),r.lookAt(a.x+o[t],a.y,a.z)):1===i?(r.up.set(0,0,s[t]),r.position.set(a.x,a.y,a.z),r.lookAt(a.x,a.y+o[t],a.z)):(r.up.set(0,s[t],0),r.position.set(a.x,a.y,a.z),r.lookAt(a.x,a.y,a.z+o[t]));const h=this._cubeSize;Ts(n,i*h,t>2?h:0,h,h),l.setRenderTarget(n),p&&l.render(u,r),l.render(e,r)}l.toneMapping=c,l.autoClear=h,e.background=m}_textureToCubeUV(e,t){const i=this._renderer,n=e.mapping===D||e.mapping===R;n?(null===this._cubemapMaterial&&(this._cubemapMaterial=As()),this._cubemapMaterial.uniforms.flipEnvMap.value=!1===e.isRenderTargetTexture?-1:1):null===this._equirectMaterial&&(this._equirectMaterial=Cs());const a=n?this._cubemapMaterial:this._equirectMaterial,r=this._lodMeshes[0];r.material=a,a.uniforms.envMap.value=e;const s=this._cubeSize;Ts(t,0,0,3*s,2*s),i.setRenderTarget(t),i.render(r,vs)}_applyPMREM(e){const t=this._renderer,i=t.autoClear;t.autoClear=!1;const n=this._lodMeshes.length;for(let t=1;t<n;t++)this._applyGGXFilter(e,t-1,t);t.autoClear=i}_applyGGXFilter(e,t,i){const n=this._renderer,a=this._pingPongRenderTarget;if(null===this._ggxMaterial){const e=3*Math.max(this._cubeSize,16),t=4*this._cubeSize;this._ggxMaterial=function(e,t,i){return new Jn({name:"PMREMGGXConvolution",defines:{GGX_SAMPLES:512,CUBEUV_TEXEL_WIDTH:1/t,CUBEUV_TEXEL_HEIGHT:1/i,CUBEUV_MAX_MIP:`${e}.0`},uniforms:{envMap:{value:null},roughness:{value:0},mipInt:{value:0}},vertexShader:"\n\n\t\tprecision mediump float;\n\t\tprecision mediump int;\n\n\t\tattribute float faceIndex;\n\n\t\tvarying vec3 vOutputDirection;\n\n\t\t// RH coordinate system; PMREM face-indexing convention\n\t\tvec3 getDirection( vec2 uv, float face ) {\n\n\t\t\tuv = 2.0 * uv - 1.0;\n\n\t\t\tvec3 direction = vec3( uv, 1.0 );\n\n\t\t\tif ( face == 0.0 ) {\n\n\t\t\t\tdirection = direction.zyx; // ( 1, v, u ) pos x\n\n\t\t\t} else if ( face == 1.0 ) {\n\n\t\t\t\tdirection = direction.xzy;\n\t\t\t\tdirection.xz *= -1.0; // ( -u, 1, -v ) pos y\n\n\t\t\t} else if ( face == 2.0 ) {\n\n\t\t\t\tdirection.x *= -1.0; // ( -u, v, 1 ) pos z\n\n\t\t\t} else if ( face == 3.0 ) {\n\n\t\t\t\tdirection = direction.zyx;\n\t\t\t\tdirection.xz *= -1.0; // ( -1, v, -u ) neg x\n\n\t\t\t} else if ( face == 4.0 ) {\n\n\t\t\t\tdirection = direction.xzy;\n\t\t\t\tdirection.xy *= -1.0; // ( -u, -1, v ) neg y\n\n\t\t\t} else if ( face == 5.0 ) {\n\n\t\t\t\tdirection.z *= -1.0; // ( u, v, -1 ) neg z\n\n\t\t\t}\n\n\t\t\treturn direction;\n\n\t\t}\n\n\t\tvoid main() {\n\n\t\t\tvOutputDirection = getDirection( uv, faceIndex );\n\t\t\tgl_Position = vec4( position, 1.0 );\n\n\t\t}\n\t",fragmentShader:'\n\n\t\t\tprecision mediump float;\n\t\t\tprecision mediump int;\n\n\t\t\tvarying vec3 vOutputDirection;\n\n\t\t\tuniform sampler2D envMap;\n\t\t\tuniform float roughness;\n\t\t\tuniform float mipInt;\n\n\t\t\t#define ENVMAP_TYPE_CUBE_UV\n\t\t\t#include <cube_uv_reflection_fragment>\n\n\t\t\t#define PI 3.14159265359\n\n\t\t\t// Van der Corput radical inverse\n\t\t\tfloat radicalInverse_VdC(uint bits) {\n\t\t\t\tbits = (bits << 16u) | (bits >> 16u);\n\t\t\t\tbits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);\n\t\t\t\tbits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);\n\t\t\t\tbits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);\n\t\t\t\tbits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);\n\t\t\t\treturn float(bits) * 2.3283064365386963e-10; // / 0x100000000\n\t\t\t}\n\n\t\t\t// Hammersley sequence\n\t\t\tvec2 hammersley(uint i, uint N) {\n\t\t\t\treturn vec2(float(i) / float(N), radicalInverse_VdC(i));\n\t\t\t}\n\n\t\t\t// GGX VNDF importance sampling (Eric Heitz 2018)\n\t\t\t// "Sampling the GGX Distribution of Visible Normals"\n\t\t\t// https://jcgt.org/published/0007/04/01/\n\t\t\tvec3 importanceSampleGGX_VNDF(vec2 Xi, vec3 V, float roughness) {\n\t\t\t\tfloat alpha = roughness * roughness;\n\n\t\t\t\t// Section 3.2: Transform view direction to hemisphere configuration\n\t\t\t\tvec3 Vh = normalize(vec3(alpha * V.x, alpha * V.y, V.z));\n\n\t\t\t\t// Section 4.1: Orthonormal basis\n\t\t\t\tfloat lensq = Vh.x * Vh.x + Vh.y * Vh.y;\n\t\t\t\tvec3 T1 = lensq > 0.0 ? vec3(-Vh.y, Vh.x, 0.0) / sqrt(lensq) : vec3(1.0, 0.0, 0.0);\n\t\t\t\tvec3 T2 = cross(Vh, T1);\n\n\t\t\t\t// Section 4.2: Parameterization of projected area\n\t\t\t\tfloat r = sqrt(Xi.x);\n\t\t\t\tfloat phi = 2.0 * PI * Xi.y;\n\t\t\t\tfloat t1 = r * cos(phi);\n\t\t\t\tfloat t2 = r * sin(phi);\n\t\t\t\tfloat s = 0.5 * (1.0 + Vh.z);\n\t\t\t\tt2 = (1.0 - s) * sqrt(1.0 - t1 * t1) + s * t2;\n\n\t\t\t\t// Section 4.3: Reprojection onto hemisphere\n\t\t\t\tvec3 Nh = t1 * T1 + t2 * T2 + sqrt(max(0.0, 1.0 - t1 * t1 - t2 * t2)) * Vh;\n\n\t\t\t\t// Section 3.4: Transform back to ellipsoid configuration\n\t\t\t\treturn normalize(vec3(alpha * Nh.x, alpha * Nh.y, max(0.0, Nh.z)));\n\t\t\t}\n\n\t\t\tvoid main() {\n\t\t\t\tvec3 N = normalize(vOutputDirection);\n\t\t\t\tvec3 V = N; // Assume view direction equals normal for pre-filtering\n\n\t\t\t\tvec3 prefilteredColor = vec3(0.0);\n\t\t\t\tfloat totalWeight = 0.0;\n\n\t\t\t\t// For very low roughness, just sample the environment directly\n\t\t\t\tif (roughness < 0.001) {\n\t\t\t\t\tgl_FragColor = vec4(bilinearCubeUV(envMap, N, mipInt), 1.0);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Tangent space basis for VNDF sampling\n\t\t\t\tvec3 up = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);\n\t\t\t\tvec3 tangent = normalize(cross(up, N));\n\t\t\t\tvec3 bitangent = cross(N, tangent);\n\n\t\t\t\tfor(uint i = 0u; i < uint(GGX_SAMPLES); i++) {\n\t\t\t\t\tvec2 Xi = hammersley(i, uint(GGX_SAMPLES));\n\n\t\t\t\t\t// For PMREM, V = N, so in tangent space V is always (0, 0, 1)\n\t\t\t\t\tvec3 H_tangent = importanceSampleGGX_VNDF(Xi, vec3(0.0, 0.0, 1.0), roughness);\n\n\t\t\t\t\t// Transform H back to world space\n\t\t\t\t\tvec3 H = normalize(tangent * H_tangent.x + bitangent * H_tangent.y + N * H_tangent.z);\n\t\t\t\t\tvec3 L = normalize(2.0 * dot(V, H) * H - V);\n\n\t\t\t\t\tfloat NdotL = max(dot(N, L), 0.0);\n\n\t\t\t\t\tif(NdotL > 0.0) {\n\t\t\t\t\t\t// Sample environment at fixed mip level\n\t\t\t\t\t\t// VNDF importance sampling handles the distribution filtering\n\t\t\t\t\t\tvec3 sampleColor = bilinearCubeUV(envMap, L, mipInt);\n\n\t\t\t\t\t\t// Weight by NdotL for the split-sum approximation\n\t\t\t\t\t\t// VNDF PDF naturally accounts for the visible microfacet distribution\n\t\t\t\t\t\tprefilteredColor += sampleColor * NdotL;\n\t\t\t\t\t\ttotalWeight += NdotL;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (totalWeight > 0.0) {\n\t\t\t\t\tprefilteredColor = prefilteredColor / totalWeight;\n\t\t\t\t}\n\n\t\t\t\tgl_FragColor = vec4(prefilteredColor, 1.0);\n\t\t\t}\n\t\t',blending:0,depthTest:!1,depthWrite:!1})}(this._lodMax,e,t)}const r=this._ggxMaterial,s=this._lodMeshes[i];s.material=r;const o=r.uniforms,l=i/(this._lodMeshes.length-1),h=t/(this._lodMeshes.length-1),c=Math.sqrt(l*l-h*h)*(.05+.95*l),{_lodMax:u}=this,d=this._sizeLods[i],p=3*d*(i>u-4?i-u+4:0),m=4*(this._cubeSize-d);o.envMap.value=e.texture,o.roughness.value=c,o.mipInt.value=u-t,Ts(a,p,m,3*d,2*d),n.setRenderTarget(a),n.render(s,vs),o.envMap.value=a.texture,o.roughness.value=0,o.mipInt.value=u-i,Ts(e,p,m,3*d,2*d),n.setRenderTarget(e),n.render(s,vs)}_blur(e,t,i,n,a){const r=this._pingPongRenderTarget;this._halfBlur(e,r,t,i,n,"latitudinal",a),this._halfBlur(r,e,i,i,n,"longitudinal",a)}_halfBlur(e,t,i,n,a,r,s){const o=this._renderer,l=this._blurMaterial;"latitudinal"!==r&&"longitudinal"!==r&&lt("blur direction must be either latitudinal or longitudinal!");const h=this._lodMeshes[n];h.material=l;const c=l.uniforms,u=this._sizeLods[i]-1,d=isFinite(a)?Math.PI/(2*u):2*Math.PI/39,p=a/d,m=isFinite(a)?1+Math.floor(3*p):20;m>20&&ot(`sigmaRadians, ${a}, is too large and will clip, as it requested ${m} samples when the maximum is set to 20`);const f=[];let g=0;for(let e=0;e<20;++e){const t=e/p,i=Math.exp(-t*t/2);f.push(i),0===e?g+=i:e<m&&(g+=2*i)}for(let e=0;e<f.length;e++)f[e]=f[e]/g;c.envMap.value=e.texture,c.samples.value=m,c.weights.value=f,c.latitudinal.value="latitudinal"===r,s&&(c.poleAxis.value=s);const{_lodMax:v}=this;c.dTheta.value=d,c.mipInt.value=v-i;const y=this._sizeLods[n];Ts(t,3*y*(n>v-4?n-v+4:0),4*(this._cubeSize-y),3*y,2*y),o.setRenderTarget(t),o.render(h,vs)}}function Es(e,t,i){const n=new Ht(e,t,i);return n.texture.mapping=L,n.texture.name="PMREM.cubeUv",n.scissorTest=!0,n}function Ts(e,t,i,n,a){e.viewport.set(t,i,n,a),e.scissor.set(t,i,n,a)}function Cs(){return new Jn({name:"EquirectangularToCubeUV",uniforms:{envMap:{value:null}},vertexShader:"\n\n\t\tprecision mediump float;\n\t\tprecision mediump int;\n\n\t\tattribute float faceIndex;\n\n\t\tvarying vec3 vOutputDirection;\n\n\t\t// RH coordinate system; PMREM face-indexing convention\n\t\tvec3 getDirection( vec2 uv, float face ) {\n\n\t\t\tuv = 2.0 * uv - 1.0;\n\n\t\t\tvec3 direction = vec3( uv, 1.0 );\n\n\t\t\tif ( face == 0.0 ) {\n\n\t\t\t\tdirection = direction.zyx; // ( 1, v, u ) pos x\n\n\t\t\t} else if ( face == 1.0 ) {\n\n\t\t\t\tdirection = direction.xzy;\n\t\t\t\tdirection.xz *= -1.0; // ( -u, 1, -v ) pos y\n\n\t\t\t} else if ( face == 2.0 ) {\n\n\t\t\t\tdirection.x *= -1.0; // ( -u, v, 1 ) pos z\n\n\t\t\t} else if ( face == 3.0 ) {\n\n\t\t\t\tdirection = direction.zyx;\n\t\t\t\tdirection.xz *= -1.0; // ( -1, v, -u ) neg x\n\n\t\t\t} else if ( face == 4.0 ) {\n\n\t\t\t\tdirection = direction.xzy;\n\t\t\t\tdirection.xy *= -1.0; // ( -u, -1, v ) neg y\n\n\t\t\t} else if ( face == 5.0 ) {\n\n\t\t\t\tdirection.z *= -1.0; // ( u, v, -1 ) neg z\n\n\t\t\t}\n\n\t\t\treturn direction;\n\n\t\t}\n\n\t\tvoid main() {\n\n\t\t\tvOutputDirection = getDirection( uv, faceIndex );\n\t\t\tgl_Position = vec4( position, 1.0 );\n\n\t\t}\n\t",fragmentShader:"\n\n\t\t\tprecision mediump float;\n\t\t\tprecision mediump int;\n\n\t\t\tvarying vec3 vOutputDirection;\n\n\t\t\tuniform sampler2D envMap;\n\n\t\t\t#include <common>\n\n\t\t\tvoid main() {\n\n\t\t\t\tvec3 outputDirection = normalize( vOutputDirection );\n\t\t\t\tvec2 uv = equirectUv( outputDirection );\n\n\t\t\t\tgl_FragColor = vec4( texture2D ( envMap, uv ).rgb, 1.0 );\n\n\t\t\t}\n\t\t",blending:0,depthTest:!1,depthWrite:!1})}function As(){return new Jn({name:"CubemapToCubeUV",uniforms:{envMap:{value:null},flipEnvMap:{value:-1}},vertexShader:"\n\n\t\tprecision mediump float;\n\t\tprecision mediump int;\n\n\t\tattribute float faceIndex;\n\n\t\tvarying vec3 vOutputDirection;\n\n\t\t// RH coordinate system; PMREM face-indexing convention\n\t\tvec3 getDirection( vec2 uv, float face ) {\n\n\t\t\tuv = 2.0 * uv - 1.0;\n\n\t\t\tvec3 direction = vec3( uv, 1.0 );\n\n\t\t\tif ( face == 0.0 ) {\n\n\t\t\t\tdirection = direction.zyx; // ( 1, v, u ) pos x\n\n\t\t\t} else if ( face == 1.0 ) {\n\n\t\t\t\tdirection = direction.xzy;\n\t\t\t\tdirection.xz *= -1.0; // ( -u, 1, -v ) pos y\n\n\t\t\t} else if ( face == 2.0 ) {\n\n\t\t\t\tdirection.x *= -1.0; // ( -u, v, 1 ) pos z\n\n\t\t\t} else if ( face == 3.0 ) {\n\n\t\t\t\tdirection = direction.zyx;\n\t\t\t\tdirection.xz *= -1.0; // ( -1, v, -u ) neg x\n\n\t\t\t} else if ( face == 4.0 ) {\n\n\t\t\t\tdirection = direction.xzy;\n\t\t\t\tdirection.xy *= -1.0; // ( -u, -1, v ) neg y\n\n\t\t\t} else if ( face == 5.0 ) {\n\n\t\t\t\tdirection.z *= -1.0; // ( u, v, -1 ) neg z\n\n\t\t\t}\n\n\t\t\treturn direction;\n\n\t\t}\n\n\t\tvoid main() {\n\n\t\t\tvOutputDirection = getDirection( uv, faceIndex );\n\t\t\tgl_Position = vec4( position, 1.0 );\n\n\t\t}\n\t",fragmentShader:"\n\n\t\t\tprecision mediump float;\n\t\t\tprecision mediump int;\n\n\t\t\tuniform float flipEnvMap;\n\n\t\t\tvarying vec3 vOutputDirection;\n\n\t\t\tuniform samplerCube envMap;\n\n\t\t\tvoid main() {\n\n\t\t\t\tgl_FragColor = textureCube( envMap, vec3( flipEnvMap * vOutputDirection.x, vOutputDirection.yz ) );\n\n\t\t\t}\n\t\t",blending:0,depthTest:!1,depthWrite:!1})}function Ps(e){let t=new WeakMap,i=null;function n(e){const i=e.target;i.removeEventListener("dispose",n);const a=t.get(i);void 0!==a&&(t.delete(i),a.dispose())}return{get:function(a){if(a&&a.isTexture){const r=a.mapping,s=r===I||304===r,o=r===D||r===R;if(s||o){let r=t.get(a);const l=void 0!==r?r.texture.pmremVersion:0;if(a.isRenderTargetTexture&&a.pmremVersion!==l)return null===i&&(i=new ws(e)),r=s?i.fromEquirectangular(a,r):i.fromCubemap(a,r),r.texture.pmremVersion=a.pmremVersion,t.set(a,r),r.texture;if(void 0!==r)return r.texture;{const l=a.image;return s&&l&&l.height>0||o&&l&&function(e){let t=0;for(let i=0;i<6;i++)void 0!==e[i]&&t++;return 6===t}(l)?(null===i&&(i=new ws(e)),r=s?i.fromEquirectangular(a):i.fromCubemap(a),r.texture.pmremVersion=a.pmremVersion,t.set(a,r),a.addEventListener("dispose",n),r.texture):null}}}return a},dispose:function(){t=new WeakMap,null!==i&&(i.dispose(),i=null)}}}function Ds(e){const t={};function i(i){if(void 0!==t[i])return t[i];const n=e.getExtension(i);return t[i]=n,n}return{has:function(e){return null!==i(e)},init:function(){i("EXT_color_buffer_float"),i("WEBGL_clip_cull_distance"),i("OES_texture_float_linear"),i("EXT_color_buffer_half_float"),i("WEBGL_multisampled_render_to_texture"),i("WEBGL_render_shared_exponent")},get:function(e){const t=i(e);return null===t&&ht("WebGLRenderer: "+e+" extension not supported."),t}}}function Rs(e,t,i,n){const a={},r=new WeakMap;function s(e){const o=e.target;null!==o.index&&t.remove(o.index);for(const e in o.attributes)t.remove(o.attributes[e]);o.removeEventListener("dispose",s),delete a[o.id];const l=r.get(o);l&&(t.remove(l),r.delete(o)),n.releaseStatesOfGeometry(o),!0===o.isInstancedBufferGeometry&&delete o._maxInstanceCount,i.memory.geometries--}function o(e){const i=[],n=e.index,a=e.attributes.position;let s=0;if(null!==n){const e=n.array;s=n.version;for(let t=0,n=e.length;t<n;t+=3){const n=e[t+0],a=e[t+1],r=e[t+2];i.push(n,a,a,r,r,n)}}else{if(void 0===a)return;{const e=a.array;s=a.version;for(let t=0,n=e.length/3-1;t<n;t+=3){const e=t+0,n=t+1,a=t+2;i.push(e,n,n,a,a,e)}}}const o=new(it(i)?En:wn)(i,1);o.version=s;const l=r.get(e);l&&t.remove(l),r.set(e,o)}return{get:function(e,t){return!0===a[t.id]||(t.addEventListener("dispose",s),a[t.id]=!0,i.memory.geometries++),t},update:function(i){const n=i.attributes;for(const i in n)t.update(n[i],e.ARRAY_BUFFER)},getWireframeAttribute:function(e){const t=r.get(e);if(t){const i=e.index;null!==i&&t.version<i.version&&o(e)}else o(e);return r.get(e)}}}function Is(e,t,i){let n,a,r;function s(t,s,o){0!==o&&(e.drawElementsInstanced(n,s,a,t*r,o),i.update(s,n,o))}this.setMode=function(e){n=e},this.setIndex=function(e){a=e.type,r=e.bytesPerElement},this.render=function(t,s){e.drawElements(n,s,a,t*r),i.update(s,n,1)},this.renderInstances=s,this.renderMultiDraw=function(e,r,s){if(0===s)return;t.get("WEBGL_multi_draw").multiDrawElementsWEBGL(n,r,0,a,e,0,s);let o=0;for(let e=0;e<s;e++)o+=r[e];i.update(o,n,1)},this.renderMultiDrawInstances=function(e,o,l,h){if(0===l)return;const c=t.get("WEBGL_multi_draw");if(null===c)for(let t=0;t<e.length;t++)s(e[t]/r,o[t],h[t]);else{c.multiDrawElementsInstancedWEBGL(n,o,0,a,e,0,h,0,l);let t=0;for(let e=0;e<l;e++)t+=o[e]*h[e];i.update(t,n,1)}}}function Ls(e){const t={frame:0,calls:0,triangles:0,points:0,lines:0};return{memory:{geometries:0,textures:0},render:t,programs:null,autoReset:!0,reset:function(){t.calls=0,t.triangles=0,t.points=0,t.lines=0},update:function(i,n,a){switch(t.calls++,n){case e.TRIANGLES:t.triangles+=a*(i/3);break;case e.LINES:t.lines+=a*(i/2);break;case e.LINE_STRIP:t.lines+=a*(i-1);break;case e.LINE_LOOP:t.lines+=a*i;break;case e.POINTS:t.points+=a*i;break;default:lt("WebGLInfo: Unknown draw mode:",n)}}}}function Bs(e,t,i){const n=new WeakMap,a=new Gt;return{update:function(r,s,o){const l=r.morphTargetInfluences,h=s.morphAttributes.position||s.morphAttributes.normal||s.morphAttributes.color,c=void 0!==h?h.length:0;let u=n.get(s);if(void 0===u||u.count!==c){void 0!==u&&u.texture.dispose();const d=void 0!==s.morphAttributes.position,p=void 0!==s.morphAttributes.normal,m=void 0!==s.morphAttributes.color,f=s.morphAttributes.position||[],g=s.morphAttributes.normal||[],v=s.morphAttributes.color||[];let y=0;!0===d&&(y=1),!0===p&&(y=2),!0===m&&(y=3);let b=s.attributes.position.count*y,M=1;b>t.maxTextureSize&&(M=Math.ceil(b/t.maxTextureSize),b=t.maxTextureSize);const _=new Float32Array(b*M*4*c),x=new Wt(_,b,M,c);x.type=q,x.needsUpdate=!0;const S=4*y;for(let E=0;E<c;E++){const T=f[E],C=g[E],A=v[E],P=b*M*4*E;for(let D=0;D<T.count;D++){const R=D*S;!0===d&&(a.fromBufferAttribute(T,D),_[P+R+0]=a.x,_[P+R+1]=a.y,_[P+R+2]=a.z,_[P+R+3]=0),!0===p&&(a.fromBufferAttribute(C,D),_[P+R+4]=a.x,_[P+R+5]=a.y,_[P+R+6]=a.z,_[P+R+7]=0),!0===m&&(a.fromBufferAttribute(A,D),_[P+R+8]=a.x,_[P+R+9]=a.y,_[P+R+10]=a.z,_[P+R+11]=4===A.itemSize?a.w:1)}}function w(){x.dispose(),n.delete(s),s.removeEventListener("dispose",w)}u={count:c,texture:x,size:new Mt(b,M)},n.set(s,u),s.addEventListener("dispose",w)}if(!0===r.isInstancedMesh&&null!==r.morphTexture)o.getUniforms().setValue(e,"morphTexture",r.morphTexture,i);else{let I=0;for(let B=0;B<l.length;B++)I+=l[B];const L=s.morphTargetsRelative?1:1-I;o.getUniforms().setValue(e,"morphTargetBaseInfluence",L),o.getUniforms().setValue(e,"morphTargetInfluences",l)}o.getUniforms().setValue(e,"morphTargetsTexture",u.texture,i),o.getUniforms().setValue(e,"morphTargetsTextureSize",u.size)}}}function Os(e,t,i,n){let a=new WeakMap;function r(e){const t=e.target;t.removeEventListener("dispose",r),i.remove(t.instanceMatrix),null!==t.instanceColor&&i.remove(t.instanceColor)}return{update:function(s){const o=n.render.frame,l=s.geometry,h=t.get(s,l);if(a.get(h)!==o&&(t.update(h),a.set(h,o)),s.isInstancedMesh&&(!1===s.hasEventListener("dispose",r)&&s.addEventListener("dispose",r),a.get(s)!==o&&(i.update(s.instanceMatrix,e.ARRAY_BUFFER),null!==s.instanceColor&&i.update(s.instanceColor,e.ARRAY_BUFFER),a.set(s,o))),s.isSkinnedMesh){const e=s.skeleton;a.get(e)!==o&&(e.update(),a.set(e,o))}return h},dispose:function(){a=new WeakMap}}}const Fs=new Nt,Us=new lr(1,1),zs=new Wt,ks=new jt,Ns=new oa,Gs=[],Vs=[],Hs=new Float32Array(16),Ws=new Float32Array(9),js=new Float32Array(4);function Xs(e,t,i){const n=e[0];if(n<=0||n>0)return e;const a=t*i;let r=Gs[a];if(void 0===r&&(r=new Float32Array(a),Gs[a]=r),0!==t){n.toArray(r,0);for(let n=1,a=0;n!==t;++n)a+=i,e[n].toArray(r,a)}return r}function qs(e,t){if(e.length!==t.length)return!1;for(let i=0,n=e.length;i<n;i++)if(e[i]!==t[i])return!1;return!0}function Ys(e,t){for(let i=0,n=t.length;i<n;i++)e[i]=t[i]}function $s(e,t){let i=Vs[t];void 0===i&&(i=new Int32Array(t),Vs[t]=i);for(let n=0;n!==t;++n)i[n]=e.allocateTextureUnit();return i}function Zs(e,t){const i=this.cache;i[0]!==t&&(e.uniform1f(this.addr,t),i[0]=t)}function Ks(e,t){const i=this.cache;if(void 0!==t.x)i[0]===t.x&&i[1]===t.y||(e.uniform2f(this.addr,t.x,t.y),i[0]=t.x,i[1]=t.y);else{if(qs(i,t))return;e.uniform2fv(this.addr,t),Ys(i,t)}}function Qs(e,t){const i=this.cache;if(void 0!==t.x)i[0]===t.x&&i[1]===t.y&&i[2]===t.z||(e.uniform3f(this.addr,t.x,t.y,t.z),i[0]=t.x,i[1]=t.y,i[2]=t.z);else if(void 0!==t.r)i[0]===t.r&&i[1]===t.g&&i[2]===t.b||(e.uniform3f(this.addr,t.r,t.g,t.b),i[0]=t.r,i[1]=t.g,i[2]=t.b);else{if(qs(i,t))return;e.uniform3fv(this.addr,t),Ys(i,t)}}function Js(e,t){const i=this.cache;if(void 0!==t.x)i[0]===t.x&&i[1]===t.y&&i[2]===t.z&&i[3]===t.w||(e.uniform4f(this.addr,t.x,t.y,t.z,t.w),i[0]=t.x,i[1]=t.y,i[2]=t.z,i[3]=t.w);else{if(qs(i,t))return;e.uniform4fv(this.addr,t),Ys(i,t)}}function eo(e,t){const i=this.cache,n=t.elements;if(void 0===n){if(qs(i,t))return;e.uniformMatrix2fv(this.addr,!1,t),Ys(i,t)}else{if(qs(i,n))return;js.set(n),e.uniformMatrix2fv(this.addr,!1,js),Ys(i,n)}}function to(e,t){const i=this.cache,n=t.elements;if(void 0===n){if(qs(i,t))return;e.uniformMatrix3fv(this.addr,!1,t),Ys(i,t)}else{if(qs(i,n))return;Ws.set(n),e.uniformMatrix3fv(this.addr,!1,Ws),Ys(i,n)}}function io(e,t){const i=this.cache,n=t.elements;if(void 0===n){if(qs(i,t))return;e.uniformMatrix4fv(this.addr,!1,t),Ys(i,t)}else{if(qs(i,n))return;Hs.set(n),e.uniformMatrix4fv(this.addr,!1,Hs),Ys(i,n)}}function no(e,t){const i=this.cache;i[0]!==t&&(e.uniform1i(this.addr,t),i[0]=t)}function ao(e,t){const i=this.cache;if(void 0!==t.x)i[0]===t.x&&i[1]===t.y||(e.uniform2i(this.addr,t.x,t.y),i[0]=t.x,i[1]=t.y);else{if(qs(i,t))return;e.uniform2iv(this.addr,t),Ys(i,t)}}function ro(e,t){const i=this.cache;if(void 0!==t.x)i[0]===t.x&&i[1]===t.y&&i[2]===t.z||(e.uniform3i(this.addr,t.x,t.y,t.z),i[0]=t.x,i[1]=t.y,i[2]=t.z);else{if(qs(i,t))return;e.uniform3iv(this.addr,t),Ys(i,t)}}function so(e,t){const i=this.cache;if(void 0!==t.x)i[0]===t.x&&i[1]===t.y&&i[2]===t.z&&i[3]===t.w||(e.uniform4i(this.addr,t.x,t.y,t.z,t.w),i[0]=t.x,i[1]=t.y,i[2]=t.z,i[3]=t.w);else{if(qs(i,t))return;e.uniform4iv(this.addr,t),Ys(i,t)}}function oo(e,t){const i=this.cache;i[0]!==t&&(e.uniform1ui(this.addr,t),i[0]=t)}function lo(e,t){const i=this.cache;if(void 0!==t.x)i[0]===t.x&&i[1]===t.y||(e.uniform2ui(this.addr,t.x,t.y),i[0]=t.x,i[1]=t.y);else{if(qs(i,t))return;e.uniform2uiv(this.addr,t),Ys(i,t)}}function ho(e,t){const i=this.cache;if(void 0!==t.x)i[0]===t.x&&i[1]===t.y&&i[2]===t.z||(e.uniform3ui(this.addr,t.x,t.y,t.z),i[0]=t.x,i[1]=t.y,i[2]=t.z);else{if(qs(i,t))return;e.uniform3uiv(this.addr,t),Ys(i,t)}}function co(e,t){const i=this.cache;if(void 0!==t.x)i[0]===t.x&&i[1]===t.y&&i[2]===t.z&&i[3]===t.w||(e.uniform4ui(this.addr,t.x,t.y,t.z,t.w),i[0]=t.x,i[1]=t.y,i[2]=t.z,i[3]=t.w);else{if(qs(i,t))return;e.uniform4uiv(this.addr,t),Ys(i,t)}}function uo(e,t,i){const n=this.cache,a=i.allocateTextureUnit();let r;n[0]!==a&&(e.uniform1i(this.addr,a),n[0]=a),this.type===e.SAMPLER_2D_SHADOW?(Us.compareFunction=515,r=Us):r=Fs,i.setTexture2D(t||r,a)}function po(e,t,i){const n=this.cache,a=i.allocateTextureUnit();n[0]!==a&&(e.uniform1i(this.addr,a),n[0]=a),i.setTexture3D(t||ks,a)}function mo(e,t,i){const n=this.cache,a=i.allocateTextureUnit();n[0]!==a&&(e.uniform1i(this.addr,a),n[0]=a),i.setTextureCube(t||Ns,a)}function fo(e,t,i){const n=this.cache,a=i.allocateTextureUnit();n[0]!==a&&(e.uniform1i(this.addr,a),n[0]=a),i.setTexture2DArray(t||zs,a)}function go(e,t){e.uniform1fv(this.addr,t)}function vo(e,t){const i=Xs(t,this.size,2);e.uniform2fv(this.addr,i)}function yo(e,t){const i=Xs(t,this.size,3);e.uniform3fv(this.addr,i)}function bo(e,t){const i=Xs(t,this.size,4);e.uniform4fv(this.addr,i)}function Mo(e,t){const i=Xs(t,this.size,4);e.uniformMatrix2fv(this.addr,!1,i)}function _o(e,t){const i=Xs(t,this.size,9);e.uniformMatrix3fv(this.addr,!1,i)}function xo(e,t){const i=Xs(t,this.size,16);e.uniformMatrix4fv(this.addr,!1,i)}function So(e,t){e.uniform1iv(this.addr,t)}function wo(e,t){e.uniform2iv(this.addr,t)}function Eo(e,t){e.uniform3iv(this.addr,t)}function To(e,t){e.uniform4iv(this.addr,t)}function Co(e,t){e.uniform1uiv(this.addr,t)}function Ao(e,t){e.uniform2uiv(this.addr,t)}function Po(e,t){e.uniform3uiv(this.addr,t)}function Do(e,t){e.uniform4uiv(this.addr,t)}function Ro(e,t,i){const n=this.cache,a=t.length,r=$s(i,a);qs(n,r)||(e.uniform1iv(this.addr,r),Ys(n,r));for(let e=0;e!==a;++e)i.setTexture2D(t[e]||Fs,r[e])}function Io(e,t,i){const n=this.cache,a=t.length,r=$s(i,a);qs(n,r)||(e.uniform1iv(this.addr,r),Ys(n,r));for(let e=0;e!==a;++e)i.setTexture3D(t[e]||ks,r[e])}function Lo(e,t,i){const n=this.cache,a=t.length,r=$s(i,a);qs(n,r)||(e.uniform1iv(this.addr,r),Ys(n,r));for(let e=0;e!==a;++e)i.setTextureCube(t[e]||Ns,r[e])}function Bo(e,t,i){const n=this.cache,a=t.length,r=$s(i,a);qs(n,r)||(e.uniform1iv(this.addr,r),Ys(n,r));for(let e=0;e!==a;++e)i.setTexture2DArray(t[e]||zs,r[e])}class Oo{constructor(e,t,i){this.id=e,this.addr=i,this.cache=[],this.type=t.type,this.setValue=function(e){switch(e){case 5126:return Zs;case 35664:return Ks;case 35665:return Qs;case 35666:return Js;case 35674:return eo;case 35675:return to;case 35676:return io;case 5124:case 35670:return no;case 35667:case 35671:return ao;case 35668:case 35672:return ro;case 35669:case 35673:return so;case 5125:return oo;case 36294:return lo;case 36295:return ho;case 36296:return co;case 35678:case 36198:case 36298:case 36306:case 35682:return uo;case 35679:case 36299:case 36307:return po;case 35680:case 36300:case 36308:case 36293:return mo;case 36289:case 36303:case 36311:case 36292:return fo}}(t.type)}}class Fo{constructor(e,t,i){this.id=e,this.addr=i,this.cache=[],this.type=t.type,this.size=t.size,this.setValue=function(e){switch(e){case 5126:return go;case 35664:return vo;case 35665:return yo;case 35666:return bo;case 35674:return Mo;case 35675:return _o;case 35676:return xo;case 5124:case 35670:return So;case 35667:case 35671:return wo;case 35668:case 35672:return Eo;case 35669:case 35673:return To;case 5125:return Co;case 36294:return Ao;case 36295:return Po;case 36296:return Do;case 35678:case 36198:case 36298:case 36306:case 35682:return Ro;case 35679:case 36299:case 36307:return Io;case 35680:case 36300:case 36308:case 36293:return Lo;case 36289:case 36303:case 36311:case 36292:return Bo}}(t.type)}}class Uo{constructor(e){this.id=e,this.seq=[],this.map={}}setValue(e,t,i){const n=this.seq;for(let a=0,r=n.length;a!==r;++a){const r=n[a];r.setValue(e,t[r.id],i)}}}const zo=/(\w+)(\])?(\[|\.)?/g;function ko(e,t){e.seq.push(t),e.map[t.id]=t}function No(e,t,i){const n=e.name,a=n.length;for(zo.lastIndex=0;;){const r=zo.exec(n),s=zo.lastIndex;let o=r[1];const l="]"===r[2],h=r[3];if(l&&(o|=0),void 0===h||"["===h&&s+2===a){ko(i,void 0===h?new Oo(o,e,t):new Fo(o,e,t));break}{let e=i.map[o];void 0===e&&(e=new Uo(o),ko(i,e)),i=e}}}class Go{constructor(e,t){this.seq=[],this.map={};const i=e.getProgramParameter(t,e.ACTIVE_UNIFORMS);for(let n=0;n<i;++n){const i=e.getActiveUniform(t,n);No(i,e.getUniformLocation(t,i.name),this)}}setValue(e,t,i,n){const a=this.map[t];void 0!==a&&a.setValue(e,i,n)}setOptional(e,t,i){const n=t[i];void 0!==n&&this.setValue(e,i,n)}static upload(e,t,i,n){for(let a=0,r=t.length;a!==r;++a){const r=t[a],s=i[r.id];!1!==s.needsUpdate&&r.setValue(e,s.value,n)}}static seqWithValue(e,t){const i=[];for(let n=0,a=e.length;n!==a;++n){const a=e[n];a.id in t&&i.push(a)}return i}}function Vo(e,t,i){const n=e.createShader(t);return e.shaderSource(n,i),e.compileShader(n),n}let Ho=0;const Wo=new Et;function jo(e,t,i){const n=e.getShaderParameter(t,e.COMPILE_STATUS),a=(e.getShaderInfoLog(t)||"").trim();if(n&&""===a)return"";const r=/ERROR: 0:(\d+)/.exec(a);if(r){const n=parseInt(r[1]);return i.toUpperCase()+"\n\n"+a+"\n\n"+function(e,t){const i=e.split("\n"),n=[],a=Math.max(t-6,0),r=Math.min(t+6,i.length);for(let e=a;e<r;e++){const a=e+1;n.push(`${a===t?">":" "} ${a}: ${i[e]}`)}return n.join("\n")}(e.getShaderSource(t),n)}return a}function Xo(e,t){const i=function(e){Dt._getMatrix(Wo,Dt.workingColorSpace,e);const t=`mat3( ${Wo.elements.map(e=>e.toFixed(4))} )`;switch(Dt.getTransfer(e)){case Ne:return[t,"LinearTransferOETF"];case Ge:return[t,"sRGBTransferOETF"];default:return ot("WebGLProgram: Unsupported color space: ",e),[t,"LinearTransferOETF"]}}(t);return[`vec4 ${e}( vec4 value ) {`,`\treturn ${i[1]}( vec4( value.rgb * ${i[0]}, value.a ) );`,"}"].join("\n")}function qo(e,t){let i;switch(t){case 1:i="Linear";break;case 2:i="Reinhard";break;case 3:i="Cineon";break;case 4:i="ACESFilmic";break;case 6:i="AgX";break;case 7:i="Neutral";break;case 5:i="Custom";break;default:ot("WebGLProgram: Unsupported toneMapping:",t),i="Linear"}return"vec3 "+e+"( vec3 color ) { return "+i+"ToneMapping( color ); }"}const Yo=new xt;function $o(e){return""!==e}function Zo(e,t){const i=t.numSpotLightShadows+t.numSpotLightMaps-t.numSpotLightShadowsWithMaps;return e.replace(/NUM_DIR_LIGHTS/g,t.numDirLights).replace(/NUM_SPOT_LIGHTS/g,t.numSpotLights).replace(/NUM_SPOT_LIGHT_MAPS/g,t.numSpotLightMaps).replace(/NUM_SPOT_LIGHT_COORDS/g,i).replace(/NUM_RECT_AREA_LIGHTS/g,t.numRectAreaLights).replace(/NUM_POINT_LIGHTS/g,t.numPointLights).replace(/NUM_HEMI_LIGHTS/g,t.numHemiLights).replace(/NUM_DIR_LIGHT_SHADOWS/g,t.numDirLightShadows).replace(/NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS/g,t.numSpotLightShadowsWithMaps).replace(/NUM_SPOT_LIGHT_SHADOWS/g,t.numSpotLightShadows).replace(/NUM_POINT_LIGHT_SHADOWS/g,t.numPointLightShadows)}function Ko(e,t){return e.replace(/NUM_CLIPPING_PLANES/g,t.numClippingPlanes).replace(/UNION_CLIPPING_PLANES/g,t.numClippingPlanes-t.numClipIntersection)}const Qo=/^[ \t]*#include +<([\w\d./]+)>/gm;function Jo(e){return e.replace(Qo,tl)}const el=new Map;function tl(e,t){let i=as[t];if(void 0===i){const e=el.get(t);if(void 0===e)throw new Error("Can not resolve #include <"+t+">");i=as[e],ot('WebGLRenderer: Shader chunk "%s" has been deprecated. Use "%s" instead.',t,e)}return Jo(i)}const il=/#pragma unroll_loop_start\s+for\s*\(\s*int\s+i\s*=\s*(\d+)\s*;\s*i\s*<\s*(\d+)\s*;\s*i\s*\+\+\s*\)\s*{([\s\S]+?)}\s+#pragma unroll_loop_end/g;function nl(e){return e.replace(il,al)}function al(e,t,i,n){let a="";for(let e=parseInt(t);e<parseInt(i);e++)a+=n.replace(/\[\s*i\s*\]/g,"[ "+e+" ]").replace(/UNROLLED_LOOP_INDEX/g,e);return a}function rl(e){let t=`precision ${e.precision} float;\n\tprecision ${e.precision} int;\n\tprecision ${e.precision} sampler2D;\n\tprecision ${e.precision} samplerCube;\n\tprecision ${e.precision} sampler3D;\n\tprecision ${e.precision} sampler2DArray;\n\tprecision ${e.precision} sampler2DShadow;\n\tprecision ${e.precision} samplerCubeShadow;\n\tprecision ${e.precision} sampler2DArrayShadow;\n\tprecision ${e.precision} isampler2D;\n\tprecision ${e.precision} isampler3D;\n\tprecision ${e.precision} isamplerCube;\n\tprecision ${e.precision} isampler2DArray;\n\tprecision ${e.precision} usampler2D;\n\tprecision ${e.precision} usampler3D;\n\tprecision ${e.precision} usamplerCube;\n\tprecision ${e.precision} usampler2DArray;\n\t`;return"highp"===e.precision?t+="\n#define HIGH_PRECISION":"mediump"===e.precision?t+="\n#define MEDIUM_PRECISION":"lowp"===e.precision&&(t+="\n#define LOW_PRECISION"),t}function sl(e,t,i,n){const a=e.getContext(),r=i.defines;let s=i.vertexShader,o=i.fragmentShader;const l=function(e){let t="SHADOWMAP_TYPE_BASIC";return 1===e.shadowMapType?t="SHADOWMAP_TYPE_PCF":2===e.shadowMapType?t="SHADOWMAP_TYPE_PCF_SOFT":3===e.shadowMapType&&(t="SHADOWMAP_TYPE_VSM"),t}(i),h=function(e){let t="ENVMAP_TYPE_CUBE";if(e.envMap)switch(e.envMapMode){case D:case R:t="ENVMAP_TYPE_CUBE";break;case L:t="ENVMAP_TYPE_CUBE_UV"}return t}(i),c=function(e){let t="ENVMAP_MODE_REFLECTION";return e.envMap&&e.envMapMode===R&&(t="ENVMAP_MODE_REFRACTION"),t}(i),u=function(e){let t="ENVMAP_BLENDING_NONE";if(e.envMap)switch(e.combine){case 0:t="ENVMAP_BLENDING_MULTIPLY";break;case 1:t="ENVMAP_BLENDING_MIX";break;case 2:t="ENVMAP_BLENDING_ADD"}return t}(i),d=function(e){const t=e.envMapCubeUVHeight;if(null===t)return null;const i=Math.log2(t)-2,n=1/t;return{texelWidth:1/(3*Math.max(Math.pow(2,i),112)),texelHeight:n,maxMip:i}}(i),p=function(e){return[e.extensionClipCullDistance?"#extension GL_ANGLE_clip_cull_distance : require":"",e.extensionMultiDraw?"#extension GL_ANGLE_multi_draw : require":""].filter($o).join("\n")}(i),m=function(e){const t=[];for(const i in e){const n=e[i];!1!==n&&t.push("#define "+i+" "+n)}return t.join("\n")}(r),f=a.createProgram();let g,v,y=i.glslVersion?"#version "+i.glslVersion+"\n":"";i.isRawShaderMaterial?(g=["#define SHADER_TYPE "+i.shaderType,"#define SHADER_NAME "+i.shaderName,m].filter($o).join("\n"),g.length>0&&(g+="\n"),v=["#define SHADER_TYPE "+i.shaderType,"#define SHADER_NAME "+i.shaderName,m].filter($o).join("\n"),v.length>0&&(v+="\n")):(g=[rl(i),"#define SHADER_TYPE "+i.shaderType,"#define SHADER_NAME "+i.shaderName,m,i.extensionClipCullDistance?"#define USE_CLIP_DISTANCE":"",i.batching?"#define USE_BATCHING":"",i.batchingColor?"#define USE_BATCHING_COLOR":"",i.instancing?"#define USE_INSTANCING":"",i.instancingColor?"#define USE_INSTANCING_COLOR":"",i.instancingMorph?"#define USE_INSTANCING_MORPH":"",i.useFog&&i.fog?"#define USE_FOG":"",i.useFog&&i.fogExp2?"#define FOG_EXP2":"",i.map?"#define USE_MAP":"",i.envMap?"#define USE_ENVMAP":"",i.envMap?"#define "+c:"",i.lightMap?"#define USE_LIGHTMAP":"",i.aoMap?"#define USE_AOMAP":"",i.bumpMap?"#define USE_BUMPMAP":"",i.normalMap?"#define USE_NORMALMAP":"",i.normalMapObjectSpace?"#define USE_NORMALMAP_OBJECTSPACE":"",i.normalMapTangentSpace?"#define USE_NORMALMAP_TANGENTSPACE":"",i.displacementMap?"#define USE_DISPLACEMENTMAP":"",i.emissiveMap?"#define USE_EMISSIVEMAP":"",i.anisotropy?"#define USE_ANISOTROPY":"",i.anisotropyMap?"#define USE_ANISOTROPYMAP":"",i.clearcoatMap?"#define USE_CLEARCOATMAP":"",i.clearcoatRoughnessMap?"#define USE_CLEARCOAT_ROUGHNESSMAP":"",i.clearcoatNormalMap?"#define USE_CLEARCOAT_NORMALMAP":"",i.iridescenceMap?"#define USE_IRIDESCENCEMAP":"",i.iridescenceThicknessMap?"#define USE_IRIDESCENCE_THICKNESSMAP":"",i.specularMap?"#define USE_SPECULARMAP":"",i.specularColorMap?"#define USE_SPECULAR_COLORMAP":"",i.specularIntensityMap?"#define USE_SPECULAR_INTENSITYMAP":"",i.roughnessMap?"#define USE_ROUGHNESSMAP":"",i.metalnessMap?"#define USE_METALNESSMAP":"",i.alphaMap?"#define USE_ALPHAMAP":"",i.alphaHash?"#define USE_ALPHAHASH":"",i.transmission?"#define USE_TRANSMISSION":"",i.transmissionMap?"#define USE_TRANSMISSIONMAP":"",i.thicknessMap?"#define USE_THICKNESSMAP":"",i.sheenColorMap?"#define USE_SHEEN_COLORMAP":"",i.sheenRoughnessMap?"#define USE_SHEEN_ROUGHNESSMAP":"",i.mapUv?"#define MAP_UV "+i.mapUv:"",i.alphaMapUv?"#define ALPHAMAP_UV "+i.alphaMapUv:"",i.lightMapUv?"#define LIGHTMAP_UV "+i.lightMapUv:"",i.aoMapUv?"#define AOMAP_UV "+i.aoMapUv:"",i.emissiveMapUv?"#define EMISSIVEMAP_UV "+i.emissiveMapUv:"",i.bumpMapUv?"#define BUMPMAP_UV "+i.bumpMapUv:"",i.normalMapUv?"#define NORMALMAP_UV "+i.normalMapUv:"",i.displacementMapUv?"#define DISPLACEMENTMAP_UV "+i.displacementMapUv:"",i.metalnessMapUv?"#define METALNESSMAP_UV "+i.metalnessMapUv:"",i.roughnessMapUv?"#define ROUGHNESSMAP_UV "+i.roughnessMapUv:"",i.anisotropyMapUv?"#define ANISOTROPYMAP_UV "+i.anisotropyMapUv:"",i.clearcoatMapUv?"#define CLEARCOATMAP_UV "+i.clearcoatMapUv:"",i.clearcoatNormalMapUv?"#define CLEARCOAT_NORMALMAP_UV "+i.clearcoatNormalMapUv:"",i.clearcoatRoughnessMapUv?"#define CLEARCOAT_ROUGHNESSMAP_UV "+i.clearcoatRoughnessMapUv:"",i.iridescenceMapUv?"#define IRIDESCENCEMAP_UV "+i.iridescenceMapUv:"",i.iridescenceThicknessMapUv?"#define IRIDESCENCE_THICKNESSMAP_UV "+i.iridescenceThicknessMapUv:"",i.sheenColorMapUv?"#define SHEEN_COLORMAP_UV "+i.sheenColorMapUv:"",i.sheenRoughnessMapUv?"#define SHEEN_ROUGHNESSMAP_UV "+i.sheenRoughnessMapUv:"",i.specularMapUv?"#define SPECULARMAP_UV "+i.specularMapUv:"",i.specularColorMapUv?"#define SPECULAR_COLORMAP_UV "+i.specularColorMapUv:"",i.specularIntensityMapUv?"#define SPECULAR_INTENSITYMAP_UV "+i.specularIntensityMapUv:"",i.transmissionMapUv?"#define TRANSMISSIONMAP_UV "+i.transmissionMapUv:"",i.thicknessMapUv?"#define THICKNESSMAP_UV "+i.thicknessMapUv:"",i.vertexTangents&&!1===i.flatShading?"#define USE_TANGENT":"",i.vertexColors?"#define USE_COLOR":"",i.vertexAlphas?"#define USE_COLOR_ALPHA":"",i.vertexUv1s?"#define USE_UV1":"",i.vertexUv2s?"#define USE_UV2":"",i.vertexUv3s?"#define USE_UV3":"",i.pointsUvs?"#define USE_POINTS_UV":"",i.flatShading?"#define FLAT_SHADED":"",i.skinning?"#define USE_SKINNING":"",i.morphTargets?"#define USE_MORPHTARGETS":"",i.morphNormals&&!1===i.flatShading?"#define USE_MORPHNORMALS":"",i.morphColors?"#define USE_MORPHCOLORS":"",i.morphTargetsCount>0?"#define MORPHTARGETS_TEXTURE_STRIDE "+i.morphTextureStride:"",i.morphTargetsCount>0?"#define MORPHTARGETS_COUNT "+i.morphTargetsCount:"",i.doubleSided?"#define DOUBLE_SIDED":"",i.flipSided?"#define FLIP_SIDED":"",i.shadowMapEnabled?"#define USE_SHADOWMAP":"",i.shadowMapEnabled?"#define "+l:"",i.sizeAttenuation?"#define USE_SIZEATTENUATION":"",i.numLightProbes>0?"#define USE_LIGHT_PROBES":"",i.logarithmicDepthBuffer?"#define USE_LOGARITHMIC_DEPTH_BUFFER":"",i.reversedDepthBuffer?"#define USE_REVERSED_DEPTH_BUFFER":"","uniform mat4 modelMatrix;","uniform mat4 modelViewMatrix;","uniform mat4 projectionMatrix;","uniform mat4 viewMatrix;","uniform mat3 normalMatrix;","uniform vec3 cameraPosition;","uniform bool isOrthographic;","#ifdef USE_INSTANCING","\tattribute mat4 instanceMatrix;","#endif","#ifdef USE_INSTANCING_COLOR","\tattribute vec3 instanceColor;","#endif","#ifdef USE_INSTANCING_MORPH","\tuniform sampler2D morphTexture;","#endif","attribute vec3 position;","attribute vec3 normal;","attribute vec2 uv;","#ifdef USE_UV1","\tattribute vec2 uv1;","#endif","#ifdef USE_UV2","\tattribute vec2 uv2;","#endif","#ifdef USE_UV3","\tattribute vec2 uv3;","#endif","#ifdef USE_TANGENT","\tattribute vec4 tangent;","#endif","#if defined( USE_COLOR_ALPHA )","\tattribute vec4 color;","#elif defined( USE_COLOR )","\tattribute vec3 color;","#endif","#ifdef USE_SKINNING","\tattribute vec4 skinIndex;","\tattribute vec4 skinWeight;","#endif","\n"].filter($o).join("\n"),v=[rl(i),"#define SHADER_TYPE "+i.shaderType,"#define SHADER_NAME "+i.shaderName,m,i.useFog&&i.fog?"#define USE_FOG":"",i.useFog&&i.fogExp2?"#define FOG_EXP2":"",i.alphaToCoverage?"#define ALPHA_TO_COVERAGE":"",i.map?"#define USE_MAP":"",i.matcap?"#define USE_MATCAP":"",i.envMap?"#define USE_ENVMAP":"",i.envMap?"#define "+h:"",i.envMap?"#define "+c:"",i.envMap?"#define "+u:"",d?"#define CUBEUV_TEXEL_WIDTH "+d.texelWidth:"",d?"#define CUBEUV_TEXEL_HEIGHT "+d.texelHeight:"",d?"#define CUBEUV_MAX_MIP "+d.maxMip+".0":"",i.lightMap?"#define USE_LIGHTMAP":"",i.aoMap?"#define USE_AOMAP":"",i.bumpMap?"#define USE_BUMPMAP":"",i.normalMap?"#define USE_NORMALMAP":"",i.normalMapObjectSpace?"#define USE_NORMALMAP_OBJECTSPACE":"",i.normalMapTangentSpace?"#define USE_NORMALMAP_TANGENTSPACE":"",i.emissiveMap?"#define USE_EMISSIVEMAP":"",i.anisotropy?"#define USE_ANISOTROPY":"",i.anisotropyMap?"#define USE_ANISOTROPYMAP":"",i.clearcoat?"#define USE_CLEARCOAT":"",i.clearcoatMap?"#define USE_CLEARCOATMAP":"",i.clearcoatRoughnessMap?"#define USE_CLEARCOAT_ROUGHNESSMAP":"",i.clearcoatNormalMap?"#define USE_CLEARCOAT_NORMALMAP":"",i.dispersion?"#define USE_DISPERSION":"",i.iridescence?"#define USE_IRIDESCENCE":"",i.iridescenceMap?"#define USE_IRIDESCENCEMAP":"",i.iridescenceThicknessMap?"#define USE_IRIDESCENCE_THICKNESSMAP":"",i.specularMap?"#define USE_SPECULARMAP":"",i.specularColorMap?"#define USE_SPECULAR_COLORMAP":"",i.specularIntensityMap?"#define USE_SPECULAR_INTENSITYMAP":"",i.roughnessMap?"#define USE_ROUGHNESSMAP":"",i.metalnessMap?"#define USE_METALNESSMAP":"",i.alphaMap?"#define USE_ALPHAMAP":"",i.alphaTest?"#define USE_ALPHATEST":"",i.alphaHash?"#define USE_ALPHAHASH":"",i.sheen?"#define USE_SHEEN":"",i.sheenColorMap?"#define USE_SHEEN_COLORMAP":"",i.sheenRoughnessMap?"#define USE_SHEEN_ROUGHNESSMAP":"",i.transmission?"#define USE_TRANSMISSION":"",i.transmissionMap?"#define USE_TRANSMISSIONMAP":"",i.thicknessMap?"#define USE_THICKNESSMAP":"",i.vertexTangents&&!1===i.flatShading?"#define USE_TANGENT":"",i.vertexColors||i.instancingColor||i.batchingColor?"#define USE_COLOR":"",i.vertexAlphas?"#define USE_COLOR_ALPHA":"",i.vertexUv1s?"#define USE_UV1":"",i.vertexUv2s?"#define USE_UV2":"",i.vertexUv3s?"#define USE_UV3":"",i.pointsUvs?"#define USE_POINTS_UV":"",i.gradientMap?"#define USE_GRADIENTMAP":"",i.flatShading?"#define FLAT_SHADED":"",i.doubleSided?"#define DOUBLE_SIDED":"",i.flipSided?"#define FLIP_SIDED":"",i.shadowMapEnabled?"#define USE_SHADOWMAP":"",i.shadowMapEnabled?"#define "+l:"",i.premultipliedAlpha?"#define PREMULTIPLIED_ALPHA":"",i.numLightProbes>0?"#define USE_LIGHT_PROBES":"",i.decodeVideoTexture?"#define DECODE_VIDEO_TEXTURE":"",i.decodeVideoTextureEmissive?"#define DECODE_VIDEO_TEXTURE_EMISSIVE":"",i.logarithmicDepthBuffer?"#define USE_LOGARITHMIC_DEPTH_BUFFER":"",i.reversedDepthBuffer?"#define USE_REVERSED_DEPTH_BUFFER":"","uniform mat4 viewMatrix;","uniform vec3 cameraPosition;","uniform bool isOrthographic;",0!==i.toneMapping?"#define TONE_MAPPING":"",0!==i.toneMapping?as.tonemapping_pars_fragment:"",0!==i.toneMapping?qo("toneMapping",i.toneMapping):"",i.dithering?"#define DITHERING":"",i.opaque?"#define OPAQUE":"",as.colorspace_pars_fragment,Xo("linearToOutputTexel",i.outputColorSpace),(Dt.getLuminanceCoefficients(Yo),["float luminance( const in vec3 rgb ) {",`\tconst vec3 weights = vec3( ${Yo.x.toFixed(4)}, ${Yo.y.toFixed(4)}, ${Yo.z.toFixed(4)} );`,"\treturn dot( weights, rgb );","}"].join("\n")),i.useDepthPacking?"#define DEPTH_PACKING "+i.depthPacking:"","\n"].filter($o).join("\n")),s=Jo(s),s=Zo(s,i),s=Ko(s,i),o=Jo(o),o=Zo(o,i),o=Ko(o,i),s=nl(s),o=nl(o),!0!==i.isRawShaderMaterial&&(y="#version 300 es\n",g=[p,"#define attribute in","#define varying out","#define texture2D texture"].join("\n")+"\n"+g,v=["#define varying in",i.glslVersion===Je?"":"layout(location = 0) out highp vec4 pc_fragColor;",i.glslVersion===Je?"":"#define gl_FragColor pc_fragColor","#define gl_FragDepthEXT gl_FragDepth","#define texture2D texture","#define textureCube texture","#define texture2DProj textureProj","#define texture2DLodEXT textureLod","#define texture2DProjLodEXT textureProjLod","#define textureCubeLodEXT textureLod","#define texture2DGradEXT textureGrad","#define texture2DProjGradEXT textureProjGrad","#define textureCubeGradEXT textureGrad"].join("\n")+"\n"+v);const b=y+g+s,M=y+v+o,_=Vo(a,a.VERTEX_SHADER,b),x=Vo(a,a.FRAGMENT_SHADER,M);function S(t){if(e.debug.checkShaderErrors){const i=a.getProgramInfoLog(f)||"",n=a.getShaderInfoLog(_)||"",r=a.getShaderInfoLog(x)||"",s=i.trim(),o=n.trim(),l=r.trim();let h=!0,c=!0;if(!1===a.getProgramParameter(f,a.LINK_STATUS))if(h=!1,"function"==typeof e.debug.onShaderError)e.debug.onShaderError(a,f,_,x);else{const e=jo(a,_,"vertex"),i=jo(a,x,"fragment");lt("THREE.WebGLProgram: Shader Error "+a.getError()+" - VALIDATE_STATUS "+a.getProgramParameter(f,a.VALIDATE_STATUS)+"\n\nMaterial Name: "+t.name+"\nMaterial Type: "+t.type+"\n\nProgram Info Log: "+s+"\n"+e+"\n"+i)}else""!==s?ot("WebGLProgram: Program Info Log:",s):""!==o&&""!==l||(c=!1);c&&(t.diagnostics={runnable:h,programLog:s,vertexShader:{log:o,prefix:g},fragmentShader:{log:l,prefix:v}})}a.deleteShader(_),a.deleteShader(x),w=new Go(a,f),E=function(e,t){const i={},n=e.getProgramParameter(t,e.ACTIVE_ATTRIBUTES);for(let a=0;a<n;a++){const n=e.getActiveAttrib(t,a),r=n.name;let s=1;n.type===e.FLOAT_MAT2&&(s=2),n.type===e.FLOAT_MAT3&&(s=3),n.type===e.FLOAT_MAT4&&(s=4),i[r]={type:n.type,location:e.getAttribLocation(t,r),locationSize:s}}return i}(a,f)}let w,E;a.attachShader(f,_),a.attachShader(f,x),void 0!==i.index0AttributeName?a.bindAttribLocation(f,0,i.index0AttributeName):!0===i.morphTargets&&a.bindAttribLocation(f,0,"position"),a.linkProgram(f),this.getUniforms=function(){return void 0===w&&S(this),w},this.getAttributes=function(){return void 0===E&&S(this),E};let T=!1===i.rendererExtensionParallelShaderCompile;return this.isReady=function(){return!1===T&&(T=a.getProgramParameter(f,37297)),T},this.destroy=function(){n.releaseStatesOfProgram(this),a.deleteProgram(f),this.program=void 0},this.type=i.shaderType,this.name=i.shaderName,this.id=Ho++,this.cacheKey=t,this.usedTimes=1,this.program=f,this.vertexShader=_,this.fragmentShader=x,this}let ol=0;class ll{constructor(){this.shaderCache=new Map,this.materialCache=new Map}update(e){const t=e.vertexShader,i=e.fragmentShader,n=this._getShaderStage(t),a=this._getShaderStage(i),r=this._getShaderCacheForMaterial(e);return!1===r.has(n)&&(r.add(n),n.usedTimes++),!1===r.has(a)&&(r.add(a),a.usedTimes++),this}remove(e){const t=this.materialCache.get(e);for(const e of t)e.usedTimes--,0===e.usedTimes&&this.shaderCache.delete(e.code);return this.materialCache.delete(e),this}getVertexShaderID(e){return this._getShaderStage(e.vertexShader).id}getFragmentShaderID(e){return this._getShaderStage(e.fragmentShader).id}dispose(){this.shaderCache.clear(),this.materialCache.clear()}_getShaderCacheForMaterial(e){const t=this.materialCache;let i=t.get(e);return void 0===i&&(i=new Set,t.set(e,i)),i}_getShaderStage(e){const t=this.shaderCache;let i=t.get(e);return void 0===i&&(i=new hl(e),t.set(e,i)),i}}class hl{constructor(e){this.id=ol++,this.code=e,this.usedTimes=0}}function cl(e,t,i,n,a,r,s){const o=new Di,l=new ll,h=new Set,c=[],u=a.logarithmicDepthBuffer,d=a.vertexTextures;let p=a.precision;const m={MeshDepthMaterial:"depth",MeshDistanceMaterial:"distanceRGBA",MeshNormalMaterial:"normal",MeshBasicMaterial:"basic",MeshLambertMaterial:"lambert",MeshPhongMaterial:"phong",MeshToonMaterial:"toon",MeshStandardMaterial:"physical",MeshPhysicalMaterial:"physical",MeshMatcapMaterial:"matcap",LineBasicMaterial:"basic",LineDashedMaterial:"dashed",PointsMaterial:"points",ShadowMaterial:"shadow",SpriteMaterial:"sprite"};function f(e){return h.add(e),0===e?"uv":`uv${e}`}return{getParameters:function(r,o,c,g,v){const y=g.fog,b=v.geometry,M=r.isMeshStandardMaterial?g.environment:null,_=(r.isMeshStandardMaterial?i:t).get(r.envMap||M),x=_&&_.mapping===L?_.image.height:null,S=m[r.type];null!==r.precision&&(p=a.getMaxPrecision(r.precision),p!==r.precision&&ot("WebGLProgram.getParameters:",r.precision,"not supported, using",p,"instead."));const w=b.morphAttributes.position||b.morphAttributes.normal||b.morphAttributes.color,E=void 0!==w?w.length:0;let T,C,A,P,D=0;if(void 0!==b.morphAttributes.position&&(D=1),void 0!==b.morphAttributes.normal&&(D=2),void 0!==b.morphAttributes.color&&(D=3),S){const e=ss[S];T=e.vertexShader,C=e.fragmentShader}else T=r.vertexShader,C=r.fragmentShader,l.update(r),A=l.getVertexShaderID(r),P=l.getFragmentShaderID(r);const R=e.getRenderTarget(),I=e.state.buffers.depth.getReversed(),B=!0===v.isInstancedMesh,O=!0===v.isBatchedMesh,F=!!r.map,U=!!r.matcap,z=!!_,k=!!r.aoMap,N=!!r.lightMap,G=!!r.bumpMap,V=!!r.normalMap,H=!!r.displacementMap,W=!!r.emissiveMap,j=!!r.metalnessMap,X=!!r.roughnessMap,q=r.anisotropy>0,Y=r.clearcoat>0,$=r.dispersion>0,Z=r.iridescence>0,K=r.sheen>0,Q=r.transmission>0,J=q&&!!r.anisotropyMap,ee=Y&&!!r.clearcoatMap,te=Y&&!!r.clearcoatNormalMap,ie=Y&&!!r.clearcoatRoughnessMap,ne=Z&&!!r.iridescenceMap,ae=Z&&!!r.iridescenceThicknessMap,re=K&&!!r.sheenColorMap,se=K&&!!r.sheenRoughnessMap,oe=!!r.specularMap,le=!!r.specularColorMap,he=!!r.specularIntensityMap,ce=Q&&!!r.transmissionMap,ue=Q&&!!r.thicknessMap,de=!!r.gradientMap,pe=!!r.alphaMap,me=r.alphaTest>0,fe=!!r.alphaHash,ge=!!r.extensions;let ve=0;r.toneMapped&&(null!==R&&!0!==R.isXRRenderTarget||(ve=e.toneMapping));const ye={shaderID:S,shaderType:r.type,shaderName:r.name,vertexShader:T,fragmentShader:C,defines:r.defines,customVertexShaderID:A,customFragmentShaderID:P,isRawShaderMaterial:!0===r.isRawShaderMaterial,glslVersion:r.glslVersion,precision:p,batching:O,batchingColor:O&&null!==v._colorsTexture,instancing:B,instancingColor:B&&null!==v.instanceColor,instancingMorph:B&&null!==v.morphTexture,supportsVertexTextures:d,outputColorSpace:null===R?e.outputColorSpace:!0===R.isXRRenderTarget?R.texture.colorSpace:ke,alphaToCoverage:!!r.alphaToCoverage,map:F,matcap:U,envMap:z,envMapMode:z&&_.mapping,envMapCubeUVHeight:x,aoMap:k,lightMap:N,bumpMap:G,normalMap:V,displacementMap:d&&H,emissiveMap:W,normalMapObjectSpace:V&&1===r.normalMapType,normalMapTangentSpace:V&&0===r.normalMapType,metalnessMap:j,roughnessMap:X,anisotropy:q,anisotropyMap:J,clearcoat:Y,clearcoatMap:ee,clearcoatNormalMap:te,clearcoatRoughnessMap:ie,dispersion:$,iridescence:Z,iridescenceMap:ne,iridescenceThicknessMap:ae,sheen:K,sheenColorMap:re,sheenRoughnessMap:se,specularMap:oe,specularColorMap:le,specularIntensityMap:he,transmission:Q,transmissionMap:ce,thicknessMap:ue,gradientMap:de,opaque:!1===r.transparent&&1===r.blending&&!1===r.alphaToCoverage,alphaMap:pe,alphaTest:me,alphaHash:fe,combine:r.combine,mapUv:F&&f(r.map.channel),aoMapUv:k&&f(r.aoMap.channel),lightMapUv:N&&f(r.lightMap.channel),bumpMapUv:G&&f(r.bumpMap.channel),normalMapUv:V&&f(r.normalMap.channel),displacementMapUv:H&&f(r.displacementMap.channel),emissiveMapUv:W&&f(r.emissiveMap.channel),metalnessMapUv:j&&f(r.metalnessMap.channel),roughnessMapUv:X&&f(r.roughnessMap.channel),anisotropyMapUv:J&&f(r.anisotropyMap.channel),clearcoatMapUv:ee&&f(r.clearcoatMap.channel),clearcoatNormalMapUv:te&&f(r.clearcoatNormalMap.channel),clearcoatRoughnessMapUv:ie&&f(r.clearcoatRoughnessMap.channel),iridescenceMapUv:ne&&f(r.iridescenceMap.channel),iridescenceThicknessMapUv:ae&&f(r.iridescenceThicknessMap.channel),sheenColorMapUv:re&&f(r.sheenColorMap.channel),sheenRoughnessMapUv:se&&f(r.sheenRoughnessMap.channel),specularMapUv:oe&&f(r.specularMap.channel),specularColorMapUv:le&&f(r.specularColorMap.channel),specularIntensityMapUv:he&&f(r.specularIntensityMap.channel),transmissionMapUv:ce&&f(r.transmissionMap.channel),thicknessMapUv:ue&&f(r.thicknessMap.channel),alphaMapUv:pe&&f(r.alphaMap.channel),vertexTangents:!!b.attributes.tangent&&(V||q),vertexColors:r.vertexColors,vertexAlphas:!0===r.vertexColors&&!!b.attributes.color&&4===b.attributes.color.itemSize,pointsUvs:!0===v.isPoints&&!!b.attributes.uv&&(F||pe),fog:!!y,useFog:!0===r.fog,fogExp2:!!y&&y.isFogExp2,flatShading:!0===r.flatShading&&!1===r.wireframe,sizeAttenuation:!0===r.sizeAttenuation,logarithmicDepthBuffer:u,reversedDepthBuffer:I,skinning:!0===v.isSkinnedMesh,morphTargets:void 0!==b.morphAttributes.position,morphNormals:void 0!==b.morphAttributes.normal,morphColors:void 0!==b.morphAttributes.color,morphTargetsCount:E,morphTextureStride:D,numDirLights:o.directional.length,numPointLights:o.point.length,numSpotLights:o.spot.length,numSpotLightMaps:o.spotLightMap.length,numRectAreaLights:o.rectArea.length,numHemiLights:o.hemi.length,numDirLightShadows:o.directionalShadowMap.length,numPointLightShadows:o.pointShadowMap.length,numSpotLightShadows:o.spotShadowMap.length,numSpotLightShadowsWithMaps:o.numSpotLightShadowsWithMaps,numLightProbes:o.numLightProbes,numClippingPlanes:s.numPlanes,numClipIntersection:s.numIntersection,dithering:r.dithering,shadowMapEnabled:e.shadowMap.enabled&&c.length>0,shadowMapType:e.shadowMap.type,toneMapping:ve,decodeVideoTexture:F&&!0===r.map.isVideoTexture&&Dt.getTransfer(r.map.colorSpace)===Ge,decodeVideoTextureEmissive:W&&!0===r.emissiveMap.isVideoTexture&&Dt.getTransfer(r.emissiveMap.colorSpace)===Ge,premultipliedAlpha:r.premultipliedAlpha,doubleSided:2===r.side,flipSided:1===r.side,useDepthPacking:r.depthPacking>=0,depthPacking:r.depthPacking||0,index0AttributeName:r.index0AttributeName,extensionClipCullDistance:ge&&!0===r.extensions.clipCullDistance&&n.has("WEBGL_clip_cull_distance"),extensionMultiDraw:(ge&&!0===r.extensions.multiDraw||O)&&n.has("WEBGL_multi_draw"),rendererExtensionParallelShaderCompile:n.has("KHR_parallel_shader_compile"),customProgramCacheKey:r.customProgramCacheKey()};return ye.vertexUv1s=h.has(1),ye.vertexUv2s=h.has(2),ye.vertexUv3s=h.has(3),h.clear(),ye},getProgramCacheKey:function(t){const i=[];if(t.shaderID?i.push(t.shaderID):(i.push(t.customVertexShaderID),i.push(t.customFragmentShaderID)),void 0!==t.defines)for(const e in t.defines)i.push(e),i.push(t.defines[e]);return!1===t.isRawShaderMaterial&&(function(e,t){e.push(t.precision),e.push(t.outputColorSpace),e.push(t.envMapMode),e.push(t.envMapCubeUVHeight),e.push(t.mapUv),e.push(t.alphaMapUv),e.push(t.lightMapUv),e.push(t.aoMapUv),e.push(t.bumpMapUv),e.push(t.normalMapUv),e.push(t.displacementMapUv),e.push(t.emissiveMapUv),e.push(t.metalnessMapUv),e.push(t.roughnessMapUv),e.push(t.anisotropyMapUv),e.push(t.clearcoatMapUv),e.push(t.clearcoatNormalMapUv),e.push(t.clearcoatRoughnessMapUv),e.push(t.iridescenceMapUv),e.push(t.iridescenceThicknessMapUv),e.push(t.sheenColorMapUv),e.push(t.sheenRoughnessMapUv),e.push(t.specularMapUv),e.push(t.specularColorMapUv),e.push(t.specularIntensityMapUv),e.push(t.transmissionMapUv),e.push(t.thicknessMapUv),e.push(t.combine),e.push(t.fogExp2),e.push(t.sizeAttenuation),e.push(t.morphTargetsCount),e.push(t.morphAttributeCount),e.push(t.numDirLights),e.push(t.numPointLights),e.push(t.numSpotLights),e.push(t.numSpotLightMaps),e.push(t.numHemiLights),e.push(t.numRectAreaLights),e.push(t.numDirLightShadows),e.push(t.numPointLightShadows),e.push(t.numSpotLightShadows),e.push(t.numSpotLightShadowsWithMaps),e.push(t.numLightProbes),e.push(t.shadowMapType),e.push(t.toneMapping),e.push(t.numClippingPlanes),e.push(t.numClipIntersection),e.push(t.depthPacking)}(i,t),function(e,t){o.disableAll(),t.supportsVertexTextures&&o.enable(0),t.instancing&&o.enable(1),t.instancingColor&&o.enable(2),t.instancingMorph&&o.enable(3),t.matcap&&o.enable(4),t.envMap&&o.enable(5),t.normalMapObjectSpace&&o.enable(6),t.normalMapTangentSpace&&o.enable(7),t.clearcoat&&o.enable(8),t.iridescence&&o.enable(9),t.alphaTest&&o.enable(10),t.vertexColors&&o.enable(11),t.vertexAlphas&&o.enable(12),t.vertexUv1s&&o.enable(13),t.vertexUv2s&&o.enable(14),t.vertexUv3s&&o.enable(15),t.vertexTangents&&o.enable(16),t.anisotropy&&o.enable(17),t.alphaHash&&o.enable(18),t.batching&&o.enable(19),t.dispersion&&o.enable(20),t.batchingColor&&o.enable(21),t.gradientMap&&o.enable(22),e.push(o.mask),o.disableAll(),t.fog&&o.enable(0),t.useFog&&o.enable(1),t.flatShading&&o.enable(2),t.logarithmicDepthBuffer&&o.enable(3),t.reversedDepthBuffer&&o.enable(4),t.skinning&&o.enable(5),t.morphTargets&&o.enable(6),t.morphNormals&&o.enable(7),t.morphColors&&o.enable(8),t.premultipliedAlpha&&o.enable(9),t.shadowMapEnabled&&o.enable(10),t.doubleSided&&o.enable(11),t.flipSided&&o.enable(12),t.useDepthPacking&&o.enable(13),t.dithering&&o.enable(14),t.transmission&&o.enable(15),t.sheen&&o.enable(16),t.opaque&&o.enable(17),t.pointsUvs&&o.enable(18),t.decodeVideoTexture&&o.enable(19),t.decodeVideoTextureEmissive&&o.enable(20),t.alphaToCoverage&&o.enable(21),e.push(o.mask)}(i,t),i.push(e.outputColorSpace)),i.push(t.customProgramCacheKey),i.join()},getUniforms:function(e){const t=m[e.type];let i;if(t){const e=ss[t];i=Qn.clone(e.uniforms)}else i=e.uniforms;return i},acquireProgram:function(t,i){let n;for(let e=0,t=c.length;e<t;e++){const t=c[e];if(t.cacheKey===i){n=t,++n.usedTimes;break}}return void 0===n&&(n=new sl(e,i,t,r),c.push(n)),n},releaseProgram:function(e){if(0===--e.usedTimes){const t=c.indexOf(e);c[t]=c[c.length-1],c.pop(),e.destroy()}},releaseShaderCache:function(e){l.remove(e)},programs:c,dispose:function(){l.dispose()}}}function ul(){let e=new WeakMap;return{has:function(t){return e.has(t)},get:function(t){let i=e.get(t);return void 0===i&&(i={},e.set(t,i)),i},remove:function(t){e.delete(t)},update:function(t,i,n){e.get(t)[i]=n},dispose:function(){e=new WeakMap}}}function dl(e,t){return e.groupOrder!==t.groupOrder?e.groupOrder-t.groupOrder:e.renderOrder!==t.renderOrder?e.renderOrder-t.renderOrder:e.material.id!==t.material.id?e.material.id-t.material.id:e.z!==t.z?e.z-t.z:e.id-t.id}function pl(e,t){return e.groupOrder!==t.groupOrder?e.groupOrder-t.groupOrder:e.renderOrder!==t.renderOrder?e.renderOrder-t.renderOrder:e.z!==t.z?t.z-e.z:e.id-t.id}function ml(){const e=[];let t=0;const i=[],n=[],a=[];function r(i,n,a,r,s,o){let l=e[t];return void 0===l?(l={id:i.id,object:i,geometry:n,material:a,groupOrder:r,renderOrder:i.renderOrder,z:s,group:o},e[t]=l):(l.id=i.id,l.object=i,l.geometry=n,l.material=a,l.groupOrder=r,l.renderOrder=i.renderOrder,l.z=s,l.group=o),t++,l}return{opaque:i,transmissive:n,transparent:a,init:function(){t=0,i.length=0,n.length=0,a.length=0},push:function(e,t,s,o,l,h){const c=r(e,t,s,o,l,h);s.transmission>0?n.push(c):!0===s.transparent?a.push(c):i.push(c)},unshift:function(e,t,s,o,l,h){const c=r(e,t,s,o,l,h);s.transmission>0?n.unshift(c):!0===s.transparent?a.unshift(c):i.unshift(c)},finish:function(){for(let i=t,n=e.length;i<n;i++){const t=e[i];if(null===t.id)break;t.id=null,t.object=null,t.geometry=null,t.material=null,t.group=null}},sort:function(e,t){i.length>1&&i.sort(e||dl),n.length>1&&n.sort(t||pl),a.length>1&&a.sort(t||pl)}}}function fl(){let e=new WeakMap;return{get:function(t,i){const n=e.get(t);let a;return void 0===n?(a=new ml,e.set(t,[a])):i>=n.length?(a=new ml,n.push(a)):a=n[i],a},dispose:function(){e=new WeakMap}}}function gl(){const e={};return{get:function(t){if(void 0!==e[t.id])return e[t.id];let i;switch(t.type){case"DirectionalLight":i={direction:new xt,color:new dn};break;case"SpotLight":i={position:new xt,direction:new xt,color:new dn,distance:0,coneCos:0,penumbraCos:0,decay:0};break;case"PointLight":i={position:new xt,color:new dn,distance:0,decay:0};break;case"HemisphereLight":i={direction:new xt,skyColor:new dn,groundColor:new dn};break;case"RectAreaLight":i={color:new dn,position:new xt,halfWidth:new xt,halfHeight:new xt}}return e[t.id]=i,i}}}let vl=0;function yl(e,t){return(t.castShadow?2:0)-(e.castShadow?2:0)+(t.map?1:0)-(e.map?1:0)}function bl(e){const t=new gl,i=function(){const e={};return{get:function(t){if(void 0!==e[t.id])return e[t.id];let i;switch(t.type){case"DirectionalLight":case"SpotLight":i={shadowIntensity:1,shadowBias:0,shadowNormalBias:0,shadowRadius:1,shadowMapSize:new Mt};break;case"PointLight":i={shadowIntensity:1,shadowBias:0,shadowNormalBias:0,shadowRadius:1,shadowMapSize:new Mt,shadowCameraNear:1,shadowCameraFar:1e3}}return e[t.id]=i,i}}}(),n={version:0,hash:{directionalLength:-1,pointLength:-1,spotLength:-1,rectAreaLength:-1,hemiLength:-1,numDirectionalShadows:-1,numPointShadows:-1,numSpotShadows:-1,numSpotMaps:-1,numLightProbes:-1},ambient:[0,0,0],probe:[],directional:[],directionalShadow:[],directionalShadowMap:[],directionalShadowMatrix:[],spot:[],spotLightMap:[],spotShadow:[],spotShadowMap:[],spotLightMatrix:[],rectArea:[],rectAreaLTC1:null,rectAreaLTC2:null,point:[],pointShadow:[],pointShadowMap:[],pointShadowMatrix:[],hemi:[],numSpotLightShadowsWithMaps:0,numLightProbes:0};for(let e=0;e<9;e++)n.probe.push(new xt);const a=new xt,r=new bi,s=new bi;return{setup:function(a){let r=0,s=0,o=0;for(let e=0;e<9;e++)n.probe[e].set(0,0,0);let l=0,h=0,c=0,u=0,d=0,p=0,m=0,f=0,g=0,v=0,y=0;a.sort(yl);for(let e=0,b=a.length;e<b;e++){const b=a[e],M=b.color,_=b.intensity,x=b.distance,S=b.shadow&&b.shadow.map?b.shadow.map.texture:null;if(b.isAmbientLight)r+=M.r*_,s+=M.g*_,o+=M.b*_;else if(b.isLightProbe){for(let e=0;e<9;e++)n.probe[e].addScaledVector(b.sh.coefficients[e],_);y++}else if(b.isDirectionalLight){const e=t.get(b);if(e.color.copy(b.color).multiplyScalar(b.intensity),b.castShadow){const e=b.shadow,t=i.get(b);t.shadowIntensity=e.intensity,t.shadowBias=e.bias,t.shadowNormalBias=e.normalBias,t.shadowRadius=e.radius,t.shadowMapSize=e.mapSize,n.directionalShadow[l]=t,n.directionalShadowMap[l]=S,n.directionalShadowMatrix[l]=b.shadow.matrix,p++}n.directional[l]=e,l++}else if(b.isSpotLight){const e=t.get(b);e.position.setFromMatrixPosition(b.matrixWorld),e.color.copy(M).multiplyScalar(_),e.distance=x,e.coneCos=Math.cos(b.angle),e.penumbraCos=Math.cos(b.angle*(1-b.penumbra)),e.decay=b.decay,n.spot[c]=e;const a=b.shadow;if(b.map&&(n.spotLightMap[g]=b.map,g++,a.updateMatrices(b),b.castShadow&&v++),n.spotLightMatrix[c]=a.matrix,b.castShadow){const e=i.get(b);e.shadowIntensity=a.intensity,e.shadowBias=a.bias,e.shadowNormalBias=a.normalBias,e.shadowRadius=a.radius,e.shadowMapSize=a.mapSize,n.spotShadow[c]=e,n.spotShadowMap[c]=S,f++}c++}else if(b.isRectAreaLight){const e=t.get(b);e.color.copy(M).multiplyScalar(_),e.halfWidth.set(.5*b.width,0,0),e.halfHeight.set(0,.5*b.height,0),n.rectArea[u]=e,u++}else if(b.isPointLight){const e=t.get(b);if(e.color.copy(b.color).multiplyScalar(b.intensity),e.distance=b.distance,e.decay=b.decay,b.castShadow){const e=b.shadow,t=i.get(b);t.shadowIntensity=e.intensity,t.shadowBias=e.bias,t.shadowNormalBias=e.normalBias,t.shadowRadius=e.radius,t.shadowMapSize=e.mapSize,t.shadowCameraNear=e.camera.near,t.shadowCameraFar=e.camera.far,n.pointShadow[h]=t,n.pointShadowMap[h]=S,n.pointShadowMatrix[h]=b.shadow.matrix,m++}n.point[h]=e,h++}else if(b.isHemisphereLight){const e=t.get(b);e.skyColor.copy(b.color).multiplyScalar(_),e.groundColor.copy(b.groundColor).multiplyScalar(_),n.hemi[d]=e,d++}}u>0&&(!0===e.has("OES_texture_float_linear")?(n.rectAreaLTC1=rs.LTC_FLOAT_1,n.rectAreaLTC2=rs.LTC_FLOAT_2):(n.rectAreaLTC1=rs.LTC_HALF_1,n.rectAreaLTC2=rs.LTC_HALF_2)),n.ambient[0]=r,n.ambient[1]=s,n.ambient[2]=o;const b=n.hash;b.directionalLength===l&&b.pointLength===h&&b.spotLength===c&&b.rectAreaLength===u&&b.hemiLength===d&&b.numDirectionalShadows===p&&b.numPointShadows===m&&b.numSpotShadows===f&&b.numSpotMaps===g&&b.numLightProbes===y||(n.directional.length=l,n.spot.length=c,n.rectArea.length=u,n.point.length=h,n.hemi.length=d,n.directionalShadow.length=p,n.directionalShadowMap.length=p,n.pointShadow.length=m,n.pointShadowMap.length=m,n.spotShadow.length=f,n.spotShadowMap.length=f,n.directionalShadowMatrix.length=p,n.pointShadowMatrix.length=m,n.spotLightMatrix.length=f+g-v,n.spotLightMap.length=g,n.numSpotLightShadowsWithMaps=v,n.numLightProbes=y,b.directionalLength=l,b.pointLength=h,b.spotLength=c,b.rectAreaLength=u,b.hemiLength=d,b.numDirectionalShadows=p,b.numPointShadows=m,b.numSpotShadows=f,b.numSpotMaps=g,b.numLightProbes=y,n.version=vl++)},setupView:function(e,t){let i=0,o=0,l=0,h=0,c=0;const u=t.matrixWorldInverse;for(let t=0,d=e.length;t<d;t++){const d=e[t];if(d.isDirectionalLight){const e=n.directional[i];e.direction.setFromMatrixPosition(d.matrixWorld),a.setFromMatrixPosition(d.target.matrixWorld),e.direction.sub(a),e.direction.transformDirection(u),i++}else if(d.isSpotLight){const e=n.spot[l];e.position.setFromMatrixPosition(d.matrixWorld),e.position.applyMatrix4(u),e.direction.setFromMatrixPosition(d.matrixWorld),a.setFromMatrixPosition(d.target.matrixWorld),e.direction.sub(a),e.direction.transformDirection(u),l++}else if(d.isRectAreaLight){const e=n.rectArea[h];e.position.setFromMatrixPosition(d.matrixWorld),e.position.applyMatrix4(u),s.identity(),r.copy(d.matrixWorld),r.premultiply(u),s.extractRotation(r),e.halfWidth.set(.5*d.width,0,0),e.halfHeight.set(0,.5*d.height,0),e.halfWidth.applyMatrix4(s),e.halfHeight.applyMatrix4(s),h++}else if(d.isPointLight){const e=n.point[o];e.position.setFromMatrixPosition(d.matrixWorld),e.position.applyMatrix4(u),o++}else if(d.isHemisphereLight){const e=n.hemi[c];e.direction.setFromMatrixPosition(d.matrixWorld),e.direction.transformDirection(u),c++}}},state:n}}function Ml(e){const t=new bl(e),i=[],n=[],a={lightsArray:i,shadowsArray:n,camera:null,lights:t,transmissionRenderTarget:{}};return{init:function(e){a.camera=e,i.length=0,n.length=0},state:a,setupLights:function(){t.setup(i)},setupLightsView:function(e){t.setupView(i,e)},pushLight:function(e){i.push(e)},pushShadow:function(e){n.push(e)}}}function _l(e){let t=new WeakMap;return{get:function(i,n=0){const a=t.get(i);let r;return void 0===a?(r=new Ml(e),t.set(i,[r])):n>=a.length?(r=new Ml(e),a.push(r)):r=a[n],r},dispose:function(){t=new WeakMap}}}function xl(e,a,r){let s=new Na;const o=new Mt,l=new Mt,h=new Gt,c=new Sr({depthPacking:3201}),u=new wr,d={},p=r.maxTextureSize,m={[t]:1,[i]:0,[n]:2},f=new Jn({defines:{VSM_SAMPLES:8},uniforms:{shadow_pass:{value:null},resolution:{value:new Mt},radius:{value:4}},vertexShader:"void main() {\n\tgl_Position = vec4( position, 1.0 );\n}",fragmentShader:"uniform sampler2D shadow_pass;\nuniform vec2 resolution;\nuniform float radius;\n#include <packing>\nvoid main() {\n\tconst float samples = float( VSM_SAMPLES );\n\tfloat mean = 0.0;\n\tfloat squared_mean = 0.0;\n\tfloat uvStride = samples <= 1.0 ? 0.0 : 2.0 / ( samples - 1.0 );\n\tfloat uvStart = samples <= 1.0 ? 0.0 : - 1.0;\n\tfor ( float i = 0.0; i < samples; i ++ ) {\n\t\tfloat uvOffset = uvStart + i * uvStride;\n\t\t#ifdef HORIZONTAL_PASS\n\t\t\tvec2 distribution = unpackRGBATo2Half( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( uvOffset, 0.0 ) * radius ) / resolution ) );\n\t\t\tmean += distribution.x;\n\t\t\tsquared_mean += distribution.y * distribution.y + distribution.x * distribution.x;\n\t\t#else\n\t\t\tfloat depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( 0.0, uvOffset ) * radius ) / resolution ) );\n\t\t\tmean += depth;\n\t\t\tsquared_mean += depth * depth;\n\t\t#endif\n\t}\n\tmean = mean / samples;\n\tsquared_mean = squared_mean / samples;\n\tfloat std_dev = sqrt( squared_mean - mean * mean );\n\tgl_FragColor = pack2HalfToRGBA( vec2( mean, std_dev ) );\n}"}),g=f.clone();g.defines.HORIZONTAL_PASS=1;const v=new Bn;v.setAttribute("position",new Sn(new Float32Array([-1,-1,.5,3,-1,.5,-1,3,.5]),3));const y=new Xn(v,f),b=this;this.enabled=!1,this.autoUpdate=!0,this.needsUpdate=!1,this.type=1;let M=this.type;function _(t,i){const n=a.update(y);f.defines.VSM_SAMPLES!==t.blurSamples&&(f.defines.VSM_SAMPLES=t.blurSamples,g.defines.VSM_SAMPLES=t.blurSamples,f.needsUpdate=!0,g.needsUpdate=!0),null===t.mapPass&&(t.mapPass=new Ht(o.x,o.y)),f.uniforms.shadow_pass.value=t.map.texture,f.uniforms.resolution.value=t.mapSize,f.uniforms.radius.value=t.radius,e.setRenderTarget(t.mapPass),e.clear(),e.renderBufferDirect(i,null,n,f,y,null),g.uniforms.shadow_pass.value=t.mapPass.texture,g.uniforms.resolution.value=t.mapSize,g.uniforms.radius.value=t.radius,e.setRenderTarget(t.map),e.clear(),e.renderBufferDirect(i,null,n,g,y,null)}function x(t,i,n,a){let r=null;const s=!0===n.isPointLight?t.customDistanceMaterial:t.customDepthMaterial;if(void 0!==s)r=s;else if(r=!0===n.isPointLight?u:c,e.localClippingEnabled&&!0===i.clipShadows&&Array.isArray(i.clippingPlanes)&&0!==i.clippingPlanes.length||i.displacementMap&&0!==i.displacementScale||i.alphaMap&&i.alphaTest>0||i.map&&i.alphaTest>0||!0===i.alphaToCoverage){const e=r.uuid,t=i.uuid;let n=d[e];void 0===n&&(n={},d[e]=n);let a=n[t];void 0===a&&(a=r.clone(),n[t]=a,i.addEventListener("dispose",w)),r=a}return r.visible=i.visible,r.wireframe=i.wireframe,r.side=3===a?null!==i.shadowSide?i.shadowSide:i.side:null!==i.shadowSide?i.shadowSide:m[i.side],r.alphaMap=i.alphaMap,r.alphaTest=!0===i.alphaToCoverage?.5:i.alphaTest,r.map=i.map,r.clipShadows=i.clipShadows,r.clippingPlanes=i.clippingPlanes,r.clipIntersection=i.clipIntersection,r.displacementMap=i.displacementMap,r.displacementScale=i.displacementScale,r.displacementBias=i.displacementBias,r.wireframeLinewidth=i.wireframeLinewidth,r.linewidth=i.linewidth,!0===n.isPointLight&&!0===r.isMeshDistanceMaterial&&(e.properties.get(r).light=n),r}function S(t,i,n,r,o){if(!1===t.visible)return;if(t.layers.test(i.layers)&&(t.isMesh||t.isLine||t.isPoints)&&(t.castShadow||t.receiveShadow&&3===o)&&(!t.frustumCulled||s.intersectsObject(t))){t.modelViewMatrix.multiplyMatrices(n.matrixWorldInverse,t.matrixWorld);const s=a.update(t),l=t.material;if(Array.isArray(l)){const a=s.groups;for(let h=0,c=a.length;h<c;h++){const c=a[h],u=l[c.materialIndex];if(u&&u.visible){const a=x(t,u,r,o);t.onBeforeShadow(e,t,i,n,s,a,c),e.renderBufferDirect(n,null,s,a,t,c),t.onAfterShadow(e,t,i,n,s,a,c)}}}else if(l.visible){const a=x(t,l,r,o);t.onBeforeShadow(e,t,i,n,s,a,null),e.renderBufferDirect(n,null,s,a,t,null),t.onAfterShadow(e,t,i,n,s,a,null)}}const l=t.children;for(let e=0,t=l.length;e<t;e++)S(l[e],i,n,r,o)}function w(e){e.target.removeEventListener("dispose",w);for(const t in d){const i=d[t],n=e.target.uuid;n in i&&(i[n].dispose(),delete i[n])}}this.render=function(t,i,n){if(!1===b.enabled)return;if(!1===b.autoUpdate&&!1===b.needsUpdate)return;if(0===t.length)return;const a=e.getRenderTarget(),r=e.getActiveCubeFace(),c=e.getActiveMipmapLevel(),u=e.state;u.setBlending(0),!0===u.buffers.depth.getReversed()?u.buffers.color.setClear(0,0,0,0):u.buffers.color.setClear(1,1,1,1),u.buffers.depth.setTest(!0),u.setScissorTest(!1);const d=3!==M&&3===this.type,m=3===M&&3!==this.type;for(let a=0,r=t.length;a<r;a++){const r=t[a],c=r.shadow;if(void 0===c){ot("WebGLShadowMap:",r,"has no shadow.");continue}if(!1===c.autoUpdate&&!1===c.needsUpdate)continue;o.copy(c.mapSize);const f=c.getFrameExtents();if(o.multiply(f),l.copy(c.mapSize),(o.x>p||o.y>p)&&(o.x>p&&(l.x=Math.floor(p/f.x),o.x=l.x*f.x,c.mapSize.x=l.x),o.y>p&&(l.y=Math.floor(p/f.y),o.y=l.y*f.y,c.mapSize.y=l.y)),null===c.map||!0===d||!0===m){const e=3!==this.type?{minFilter:U,magFilter:U}:{};null!==c.map&&c.map.dispose(),c.map=new Ht(o.x,o.y,e),c.map.texture.name=r.name+".shadowMap",c.camera.updateProjectionMatrix()}e.setRenderTarget(c.map),e.clear();const g=c.getViewportCount();for(let e=0;e<g;e++){const t=c.getViewport(e);h.set(l.x*t.x,l.y*t.y,l.x*t.z,l.y*t.w),u.viewport(h),c.updateMatrices(r,e),s=c.getFrustum(),S(i,n,c.camera,r,this.type)}!0!==c.isPointLightShadow&&3===this.type&&_(c,n),c.needsUpdate=!1}M=this.type,b.needsUpdate=!1,e.setRenderTarget(a,r,c)}}const Sl={[x]:1,[w]:6,[T]:7,[E]:5,[S]:0,[A]:2,[P]:4,[C]:3};function wl(e,t){const i=new function(){let t=!1;const i=new Gt;let n=null;const a=new Gt(0,0,0,0);return{setMask:function(i){n===i||t||(e.colorMask(i,i,i,i),n=i)},setLocked:function(e){t=e},setClear:function(t,n,r,s,o){!0===o&&(t*=s,n*=s,r*=s),i.set(t,n,r,s),!1===a.equals(i)&&(e.clearColor(t,n,r,s),a.copy(i))},reset:function(){t=!1,n=null,a.set(-1,0,0,0)}}},n=new function(){let i=!1,n=!1,a=null,r=null,s=null;return{setReversed:function(e){if(n!==e){const i=t.get("EXT_clip_control");e?i.clipControlEXT(i.LOWER_LEFT_EXT,i.ZERO_TO_ONE_EXT):i.clipControlEXT(i.LOWER_LEFT_EXT,i.NEGATIVE_ONE_TO_ONE_EXT),n=e;const a=s;s=null,this.setClear(a)}},getReversed:function(){return n},setTest:function(t){t?ae(e.DEPTH_TEST):re(e.DEPTH_TEST)},setMask:function(t){a===t||i||(e.depthMask(t),a=t)},setFunc:function(t){if(n&&(t=Sl[t]),r!==t){switch(t){case 0:e.depthFunc(e.NEVER);break;case 1:e.depthFunc(e.ALWAYS);break;case 2:e.depthFunc(e.LESS);break;case 3:default:e.depthFunc(e.LEQUAL);break;case 4:e.depthFunc(e.EQUAL);break;case 5:e.depthFunc(e.GEQUAL);break;case 6:e.depthFunc(e.GREATER);break;case 7:e.depthFunc(e.NOTEQUAL)}r=t}},setLocked:function(e){i=e},setClear:function(t){s!==t&&(n&&(t=1-t),e.clearDepth(t),s=t)},reset:function(){i=!1,a=null,r=null,s=null,n=!1}}},x=new function(){let t=!1,i=null,n=null,a=null,r=null,s=null,o=null,l=null,h=null;return{setTest:function(i){t||(i?ae(e.STENCIL_TEST):re(e.STENCIL_TEST))},setMask:function(n){i===n||t||(e.stencilMask(n),i=n)},setFunc:function(t,i,s){n===t&&a===i&&r===s||(e.stencilFunc(t,i,s),n=t,a=i,r=s)},setOp:function(t,i,n){s===t&&o===i&&l===n||(e.stencilOp(t,i,n),s=t,o=i,l=n)},setLocked:function(e){t=e},setClear:function(t){h!==t&&(e.clearStencil(t),h=t)},reset:function(){t=!1,i=null,n=null,a=null,r=null,s=null,o=null,l=null,h=null}}},S=new WeakMap,w=new WeakMap;let E={},T={},C=new WeakMap,A=[],P=null,D=!1,R=null,I=null,L=null,B=null,O=null,F=null,U=null,z=new dn(0,0,0),k=0,N=!1,G=null,V=null,H=null,W=null,j=null;const X=e.getParameter(e.MAX_COMBINED_TEXTURE_IMAGE_UNITS);let q=!1,Y=0;const $=e.getParameter(e.VERSION);-1!==$.indexOf("WebGL")?(Y=parseFloat(/^WebGL (\d)/.exec($)[1]),q=Y>=1):-1!==$.indexOf("OpenGL ES")&&(Y=parseFloat(/^OpenGL ES (\d)/.exec($)[1]),q=Y>=2);let Z=null,K={};const Q=e.getParameter(e.SCISSOR_BOX),J=e.getParameter(e.VIEWPORT),ee=(new Gt).fromArray(Q),te=(new Gt).fromArray(J);function ie(t,i,n,a){const r=new Uint8Array(4),s=e.createTexture();e.bindTexture(t,s),e.texParameteri(t,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(t,e.TEXTURE_MAG_FILTER,e.NEAREST);for(let s=0;s<n;s++)t===e.TEXTURE_3D||t===e.TEXTURE_2D_ARRAY?e.texImage3D(i,0,e.RGBA,1,1,a,0,e.RGBA,e.UNSIGNED_BYTE,r):e.texImage2D(i+s,0,e.RGBA,1,1,0,e.RGBA,e.UNSIGNED_BYTE,r);return s}const ne={};function ae(t){!0!==E[t]&&(e.enable(t),E[t]=!0)}function re(t){!1!==E[t]&&(e.disable(t),E[t]=!1)}ne[e.TEXTURE_2D]=ie(e.TEXTURE_2D,e.TEXTURE_2D,1),ne[e.TEXTURE_CUBE_MAP]=ie(e.TEXTURE_CUBE_MAP,e.TEXTURE_CUBE_MAP_POSITIVE_X,6),ne[e.TEXTURE_2D_ARRAY]=ie(e.TEXTURE_2D_ARRAY,e.TEXTURE_2D_ARRAY,1,1),ne[e.TEXTURE_3D]=ie(e.TEXTURE_3D,e.TEXTURE_3D,1,1),i.setClear(0,0,0,1),n.setClear(1),x.setClear(0),ae(e.DEPTH_TEST),n.setFunc(3),he(!1),ce(1),ae(e.CULL_FACE),le(0);const se={[a]:e.FUNC_ADD,[r]:e.FUNC_SUBTRACT,[s]:e.FUNC_REVERSE_SUBTRACT};se[103]=e.MIN,se[104]=e.MAX;const oe={[o]:e.ZERO,[l]:e.ONE,[h]:e.SRC_COLOR,[u]:e.SRC_ALPHA,[v]:e.SRC_ALPHA_SATURATE,[f]:e.DST_COLOR,[p]:e.DST_ALPHA,[c]:e.ONE_MINUS_SRC_COLOR,[d]:e.ONE_MINUS_SRC_ALPHA,[g]:e.ONE_MINUS_DST_COLOR,[m]:e.ONE_MINUS_DST_ALPHA,[y]:e.CONSTANT_COLOR,[b]:e.ONE_MINUS_CONSTANT_COLOR,[M]:e.CONSTANT_ALPHA,[_]:e.ONE_MINUS_CONSTANT_ALPHA};function le(t,i,n,r,s,o,l,h,c,u){if(0!==t){if(!1===D&&(ae(e.BLEND),D=!0),5===t)s=s||i,o=o||n,l=l||r,i===I&&s===O||(e.blendEquationSeparate(se[i],se[s]),I=i,O=s),n===L&&r===B&&o===F&&l===U||(e.blendFuncSeparate(oe[n],oe[r],oe[o],oe[l]),L=n,B=r,F=o,U=l),!1!==h.equals(z)&&c===k||(e.blendColor(h.r,h.g,h.b,c),z.copy(h),k=c),R=t,N=!1;else if(t!==R||u!==N){if(I===a&&O===a||(e.blendEquation(e.FUNC_ADD),I=a,O=a),u)switch(t){case 1:e.blendFuncSeparate(e.ONE,e.ONE_MINUS_SRC_ALPHA,e.ONE,e.ONE_MINUS_SRC_ALPHA);break;case 2:e.blendFunc(e.ONE,e.ONE);break;case 3:e.blendFuncSeparate(e.ZERO,e.ONE_MINUS_SRC_COLOR,e.ZERO,e.ONE);break;case 4:e.blendFuncSeparate(e.DST_COLOR,e.ONE_MINUS_SRC_ALPHA,e.ZERO,e.ONE);break;default:lt("WebGLState: Invalid blending: ",t)}else switch(t){case 1:e.blendFuncSeparate(e.SRC_ALPHA,e.ONE_MINUS_SRC_ALPHA,e.ONE,e.ONE_MINUS_SRC_ALPHA);break;case 2:e.blendFuncSeparate(e.SRC_ALPHA,e.ONE,e.ONE,e.ONE);break;case 3:lt("WebGLState: SubtractiveBlending requires material.premultipliedAlpha = true");break;case 4:lt("WebGLState: MultiplyBlending requires material.premultipliedAlpha = true");break;default:lt("WebGLState: Invalid blending: ",t)}L=null,B=null,F=null,U=null,z.set(0,0,0),k=0,R=t,N=u}}else!0===D&&(re(e.BLEND),D=!1)}function he(t){G!==t&&(t?e.frontFace(e.CW):e.frontFace(e.CCW),G=t)}function ce(t){0!==t?(ae(e.CULL_FACE),t!==V&&(1===t?e.cullFace(e.BACK):2===t?e.cullFace(e.FRONT):e.cullFace(e.FRONT_AND_BACK))):re(e.CULL_FACE),V=t}function ue(t,i,n){t?(ae(e.POLYGON_OFFSET_FILL),W===i&&j===n||(e.polygonOffset(i,n),W=i,j=n)):re(e.POLYGON_OFFSET_FILL)}return{buffers:{color:i,depth:n,stencil:x},enable:ae,disable:re,bindFramebuffer:function(t,i){return T[t]!==i&&(e.bindFramebuffer(t,i),T[t]=i,t===e.DRAW_FRAMEBUFFER&&(T[e.FRAMEBUFFER]=i),t===e.FRAMEBUFFER&&(T[e.DRAW_FRAMEBUFFER]=i),!0)},drawBuffers:function(t,i){let n=A,a=!1;if(t){n=C.get(i),void 0===n&&(n=[],C.set(i,n));const r=t.textures;if(n.length!==r.length||n[0]!==e.COLOR_ATTACHMENT0){for(let t=0,i=r.length;t<i;t++)n[t]=e.COLOR_ATTACHMENT0+t;n.length=r.length,a=!0}}else n[0]!==e.BACK&&(n[0]=e.BACK,a=!0);a&&e.drawBuffers(n)},useProgram:function(t){return P!==t&&(e.useProgram(t),P=t,!0)},setBlending:le,setMaterial:function(t,a){2===t.side?re(e.CULL_FACE):ae(e.CULL_FACE);let r=1===t.side;a&&(r=!r),he(r),1===t.blending&&!1===t.transparent?le(0):le(t.blending,t.blendEquation,t.blendSrc,t.blendDst,t.blendEquationAlpha,t.blendSrcAlpha,t.blendDstAlpha,t.blendColor,t.blendAlpha,t.premultipliedAlpha),n.setFunc(t.depthFunc),n.setTest(t.depthTest),n.setMask(t.depthWrite),i.setMask(t.colorWrite);const s=t.stencilWrite;x.setTest(s),s&&(x.setMask(t.stencilWriteMask),x.setFunc(t.stencilFunc,t.stencilRef,t.stencilFuncMask),x.setOp(t.stencilFail,t.stencilZFail,t.stencilZPass)),ue(t.polygonOffset,t.polygonOffsetFactor,t.polygonOffsetUnits),!0===t.alphaToCoverage?ae(e.SAMPLE_ALPHA_TO_COVERAGE):re(e.SAMPLE_ALPHA_TO_COVERAGE)},setFlipSided:he,setCullFace:ce,setLineWidth:function(t){t!==H&&(q&&e.lineWidth(t),H=t)},setPolygonOffset:ue,setScissorTest:function(t){t?ae(e.SCISSOR_TEST):re(e.SCISSOR_TEST)},activeTexture:function(t){void 0===t&&(t=e.TEXTURE0+X-1),Z!==t&&(e.activeTexture(t),Z=t)},bindTexture:function(t,i,n){void 0===n&&(n=null===Z?e.TEXTURE0+X-1:Z);let a=K[n];void 0===a&&(a={type:void 0,texture:void 0},K[n]=a),a.type===t&&a.texture===i||(Z!==n&&(e.activeTexture(n),Z=n),e.bindTexture(t,i||ne[t]),a.type=t,a.texture=i)},unbindTexture:function(){const t=K[Z];void 0!==t&&void 0!==t.type&&(e.bindTexture(t.type,null),t.type=void 0,t.texture=void 0)},compressedTexImage2D:function(){try{e.compressedTexImage2D(...arguments)}catch(e){e("WebGLState:",e)}},compressedTexImage3D:function(){try{e.compressedTexImage3D(...arguments)}catch(e){e("WebGLState:",e)}},texImage2D:function(){try{e.texImage2D(...arguments)}catch(e){e("WebGLState:",e)}},texImage3D:function(){try{e.texImage3D(...arguments)}catch(e){e("WebGLState:",e)}},updateUBOMapping:function(t,i){let n=w.get(i);void 0===n&&(n=new WeakMap,w.set(i,n));let a=n.get(t);void 0===a&&(a=e.getUniformBlockIndex(i,t.name),n.set(t,a))},uniformBlockBinding:function(t,i){const n=w.get(i).get(t);S.get(i)!==n&&(e.uniformBlockBinding(i,n,t.__bindingPointIndex),S.set(i,n))},texStorage2D:function(){try{e.texStorage2D(...arguments)}catch(e){e("WebGLState:",e)}},texStorage3D:function(){try{e.texStorage3D(...arguments)}catch(e){e("WebGLState:",e)}},texSubImage2D:function(){try{e.texSubImage2D(...arguments)}catch(e){e("WebGLState:",e)}},texSubImage3D:function(){try{e.texSubImage3D(...arguments)}catch(e){e("WebGLState:",e)}},compressedTexSubImage2D:function(){try{e.compressedTexSubImage2D(...arguments)}catch(e){e("WebGLState:",e)}},compressedTexSubImage3D:function(){try{e.compressedTexSubImage3D(...arguments)}catch(e){e("WebGLState:",e)}},scissor:function(t){!1===ee.equals(t)&&(e.scissor(t.x,t.y,t.z,t.w),ee.copy(t))},viewport:function(t){!1===te.equals(t)&&(e.viewport(t.x,t.y,t.z,t.w),te.copy(t))},reset:function(){e.disable(e.BLEND),e.disable(e.CULL_FACE),e.disable(e.DEPTH_TEST),e.disable(e.POLYGON_OFFSET_FILL),e.disable(e.SCISSOR_TEST),e.disable(e.STENCIL_TEST),e.disable(e.SAMPLE_ALPHA_TO_COVERAGE),e.blendEquation(e.FUNC_ADD),e.blendFunc(e.ONE,e.ZERO),e.blendFuncSeparate(e.ONE,e.ZERO,e.ONE,e.ZERO),e.blendColor(0,0,0,0),e.colorMask(!0,!0,!0,!0),e.clearColor(0,0,0,0),e.depthMask(!0),e.depthFunc(e.LESS),n.setReversed(!1),e.clearDepth(1),e.stencilMask(4294967295),e.stencilFunc(e.ALWAYS,0,4294967295),e.stencilOp(e.KEEP,e.KEEP,e.KEEP),e.clearStencil(0),e.cullFace(e.BACK),e.frontFace(e.CCW),e.polygonOffset(0,0),e.activeTexture(e.TEXTURE0),e.bindFramebuffer(e.FRAMEBUFFER,null),e.bindFramebuffer(e.DRAW_FRAMEBUFFER,null),e.bindFramebuffer(e.READ_FRAMEBUFFER,null),e.useProgram(null),e.lineWidth(1),e.scissor(0,0,e.canvas.width,e.canvas.height),e.viewport(0,0,e.canvas.width,e.canvas.height),E={},Z=null,K={},T={},C=new WeakMap,A=[],P=null,D=!1,R=null,I=null,L=null,B=null,O=null,F=null,U=null,z=new dn(0,0,0),k=0,N=!1,G=null,V=null,H=null,W=null,j=null,ee.set(0,0,e.canvas.width,e.canvas.height),te.set(0,0,e.canvas.width,e.canvas.height),i.reset(),n.reset(),x.reset()}}}function El(e,t,i,n,a,r,s){const o=t.has("WEBGL_multisampled_render_to_texture")?t.get("WEBGL_multisampled_render_to_texture"):null,l="undefined"!=typeof navigator&&/OculusBrowser/g.test(navigator.userAgent),h=new Mt,c=new WeakMap;let u;const d=new WeakMap;let p=!1;try{p="undefined"!=typeof OffscreenCanvas&&null!==new OffscreenCanvas(1,1).getContext("2d")}catch(e){}function m(e,t){return p?new OffscreenCanvas(e,t):nt("canvas")}function f(e,t,i){let n=1;const a=se(e);if((a.width>i||a.height>i)&&(n=i/Math.max(a.width,a.height)),n<1){if("undefined"!=typeof HTMLImageElement&&e instanceof HTMLImageElement||"undefined"!=typeof HTMLCanvasElement&&e instanceof HTMLCanvasElement||"undefined"!=typeof ImageBitmap&&e instanceof ImageBitmap||"undefined"!=typeof VideoFrame&&e instanceof VideoFrame){const i=Math.floor(n*a.width),r=Math.floor(n*a.height);void 0===u&&(u=m(i,r));const s=t?m(i,r):u;return s.width=i,s.height=r,s.getContext("2d").drawImage(e,0,0,i,r),ot("WebGLRenderer: Texture has been resized from ("+a.width+"x"+a.height+") to ("+i+"x"+r+")."),s}return"data"in e&&ot("WebGLRenderer: Image in DataTexture is too big ("+a.width+"x"+a.height+")."),e}return e}function g(e){return e.generateMipmaps}function v(t){e.generateMipmap(t)}function y(t){return t.isWebGLCubeRenderTarget?e.TEXTURE_CUBE_MAP:t.isWebGL3DRenderTarget?e.TEXTURE_3D:t.isWebGLArrayRenderTarget||t.isCompressedArrayTexture?e.TEXTURE_2D_ARRAY:e.TEXTURE_2D}function b(i,n,a,r,s=!1){if(null!==i){if(void 0!==e[i])return e[i];ot("WebGLRenderer: Attempt to use non-existing WebGL internal format '"+i+"'")}let o=n;if(n===e.RED&&(a===e.FLOAT&&(o=e.R32F),a===e.HALF_FLOAT&&(o=e.R16F),a===e.UNSIGNED_BYTE&&(o=e.R8)),n===e.RED_INTEGER&&(a===e.UNSIGNED_BYTE&&(o=e.R8UI),a===e.UNSIGNED_SHORT&&(o=e.R16UI),a===e.UNSIGNED_INT&&(o=e.R32UI),a===e.BYTE&&(o=e.R8I),a===e.SHORT&&(o=e.R16I),a===e.INT&&(o=e.R32I)),n===e.RG&&(a===e.FLOAT&&(o=e.RG32F),a===e.HALF_FLOAT&&(o=e.RG16F),a===e.UNSIGNED_BYTE&&(o=e.RG8)),n===e.RG_INTEGER&&(a===e.UNSIGNED_BYTE&&(o=e.RG8UI),a===e.UNSIGNED_SHORT&&(o=e.RG16UI),a===e.UNSIGNED_INT&&(o=e.RG32UI),a===e.BYTE&&(o=e.RG8I),a===e.SHORT&&(o=e.RG16I),a===e.INT&&(o=e.RG32I)),n===e.RGB_INTEGER&&(a===e.UNSIGNED_BYTE&&(o=e.RGB8UI),a===e.UNSIGNED_SHORT&&(o=e.RGB16UI),a===e.UNSIGNED_INT&&(o=e.RGB32UI),a===e.BYTE&&(o=e.RGB8I),a===e.SHORT&&(o=e.RGB16I),a===e.INT&&(o=e.RGB32I)),n===e.RGBA_INTEGER&&(a===e.UNSIGNED_BYTE&&(o=e.RGBA8UI),a===e.UNSIGNED_SHORT&&(o=e.RGBA16UI),a===e.UNSIGNED_INT&&(o=e.RGBA32UI),a===e.BYTE&&(o=e.RGBA8I),a===e.SHORT&&(o=e.RGBA16I),a===e.INT&&(o=e.RGBA32I)),n===e.RGB&&(a===e.UNSIGNED_INT_5_9_9_9_REV&&(o=e.RGB9_E5),a===e.UNSIGNED_INT_10F_11F_11F_REV&&(o=e.R11F_G11F_B10F)),n===e.RGBA){const t=s?Ne:Dt.getTransfer(r);a===e.FLOAT&&(o=e.RGBA32F),a===e.HALF_FLOAT&&(o=e.RGBA16F),a===e.UNSIGNED_BYTE&&(o=t===Ge?e.SRGB8_ALPHA8:e.RGBA8),a===e.UNSIGNED_SHORT_4_4_4_4&&(o=e.RGBA4),a===e.UNSIGNED_SHORT_5_5_5_1&&(o=e.RGB5_A1)}return o!==e.R16F&&o!==e.R32F&&o!==e.RG16F&&o!==e.RG32F&&o!==e.RGBA16F&&o!==e.RGBA32F||t.get("EXT_color_buffer_float"),o}function M(t,i){let n;return t?null===i||i===X||i===K?n=e.DEPTH24_STENCIL8:i===q?n=e.DEPTH32F_STENCIL8:i===W&&(n=e.DEPTH24_STENCIL8,ot("DepthTexture: 16 bit depth attachment is not supported with stencil. Using 24-bit attachment.")):null===i||i===X||i===K?n=e.DEPTH_COMPONENT24:i===q?n=e.DEPTH_COMPONENT32F:i===W&&(n=e.DEPTH_COMPONENT16),n}function _(e,t){return!0===g(e)||e.isFramebufferTexture&&e.minFilter!==U&&e.minFilter!==N?Math.log2(Math.max(t.width,t.height))+1:void 0!==e.mipmaps&&e.mipmaps.length>0?e.mipmaps.length:e.isCompressedTexture&&Array.isArray(e.image)?t.mipmaps.length:1}function x(e){const t=e.target;t.removeEventListener("dispose",x),function(e){const t=n.get(e);if(void 0===t.__webglInit)return;const i=e.source,a=d.get(i);if(a){const n=a[t.__cacheKey];n.usedTimes--,0===n.usedTimes&&w(e),0===Object.keys(a).length&&d.delete(i)}n.remove(e)}(t),t.isVideoTexture&&c.delete(t)}function S(t){const i=t.target;i.removeEventListener("dispose",S),function(t){const i=n.get(t);if(t.depthTexture&&(t.depthTexture.dispose(),n.remove(t.depthTexture)),t.isWebGLCubeRenderTarget)for(let t=0;t<6;t++){if(Array.isArray(i.__webglFramebuffer[t]))for(let n=0;n<i.__webglFramebuffer[t].length;n++)e.deleteFramebuffer(i.__webglFramebuffer[t][n]);else e.deleteFramebuffer(i.__webglFramebuffer[t]);i.__webglDepthbuffer&&e.deleteRenderbuffer(i.__webglDepthbuffer[t])}else{if(Array.isArray(i.__webglFramebuffer))for(let t=0;t<i.__webglFramebuffer.length;t++)e.deleteFramebuffer(i.__webglFramebuffer[t]);else e.deleteFramebuffer(i.__webglFramebuffer);if(i.__webglDepthbuffer&&e.deleteRenderbuffer(i.__webglDepthbuffer),i.__webglMultisampledFramebuffer&&e.deleteFramebuffer(i.__webglMultisampledFramebuffer),i.__webglColorRenderbuffer)for(let t=0;t<i.__webglColorRenderbuffer.length;t++)i.__webglColorRenderbuffer[t]&&e.deleteRenderbuffer(i.__webglColorRenderbuffer[t]);i.__webglDepthRenderbuffer&&e.deleteRenderbuffer(i.__webglDepthRenderbuffer)}const a=t.textures;for(let t=0,i=a.length;t<i;t++){const i=n.get(a[t]);i.__webglTexture&&(e.deleteTexture(i.__webglTexture),s.memory.textures--),n.remove(a[t])}n.remove(t)}(i)}function w(t){const i=n.get(t);e.deleteTexture(i.__webglTexture);const a=t.source;delete d.get(a)[i.__cacheKey],s.memory.textures--}let E=0;function T(t,a){const r=n.get(t);if(t.isVideoTexture&&function(e){const t=s.render.frame;c.get(e)!==t&&(c.set(e,t),e.update())}(t),!1===t.isRenderTargetTexture&&!0!==t.isExternalTexture&&t.version>0&&r.__version!==t.version){const e=t.image;if(null===e)ot("WebGLRenderer: Texture marked for update but no image data found.");else{if(!1!==e.complete)return void L(r,t,a);ot("WebGLRenderer: Texture marked for update but image is incomplete")}}else t.isExternalTexture&&(r.__webglTexture=t.sourceTexture?t.sourceTexture:null);i.bindTexture(e.TEXTURE_2D,r.__webglTexture,e.TEXTURE0+a)}const C={[B]:e.REPEAT,[O]:e.CLAMP_TO_EDGE,[F]:e.MIRRORED_REPEAT},A={[U]:e.NEAREST,[z]:e.NEAREST_MIPMAP_NEAREST,[k]:e.NEAREST_MIPMAP_LINEAR,[N]:e.LINEAR,[G]:e.LINEAR_MIPMAP_NEAREST,[V]:e.LINEAR_MIPMAP_LINEAR},P={[He]:e.NEVER,[Ze]:e.ALWAYS,[We]:e.LESS,[Xe]:e.LEQUAL,[je]:e.EQUAL,[$e]:e.GEQUAL,[qe]:e.GREATER,[Ye]:e.NOTEQUAL};function D(i,r){if(r.type!==q||!1!==t.has("OES_texture_float_linear")||r.magFilter!==N&&r.magFilter!==G&&r.magFilter!==k&&r.magFilter!==V&&r.minFilter!==N&&r.minFilter!==G&&r.minFilter!==k&&r.minFilter!==V||ot("WebGLRenderer: Unable to use linear filtering with floating point textures. OES_texture_float_linear not supported on this device."),e.texParameteri(i,e.TEXTURE_WRAP_S,C[r.wrapS]),e.texParameteri(i,e.TEXTURE_WRAP_T,C[r.wrapT]),i!==e.TEXTURE_3D&&i!==e.TEXTURE_2D_ARRAY||e.texParameteri(i,e.TEXTURE_WRAP_R,C[r.wrapR]),e.texParameteri(i,e.TEXTURE_MAG_FILTER,A[r.magFilter]),e.texParameteri(i,e.TEXTURE_MIN_FILTER,A[r.minFilter]),r.compareFunction&&(e.texParameteri(i,e.TEXTURE_COMPARE_MODE,e.COMPARE_REF_TO_TEXTURE),e.texParameteri(i,e.TEXTURE_COMPARE_FUNC,P[r.compareFunction])),!0===t.has("EXT_texture_filter_anisotropic")){if(r.magFilter===U)return;if(r.minFilter!==k&&r.minFilter!==V)return;if(r.type===q&&!1===t.has("OES_texture_float_linear"))return;if(r.anisotropy>1||n.get(r).__currentAnisotropy){const s=t.get("EXT_texture_filter_anisotropic");e.texParameterf(i,s.TEXTURE_MAX_ANISOTROPY_EXT,Math.min(r.anisotropy,a.getMaxAnisotropy())),n.get(r).__currentAnisotropy=r.anisotropy}}}function R(t,i){let n=!1;void 0===t.__webglInit&&(t.__webglInit=!0,i.addEventListener("dispose",x));const a=i.source;let r=d.get(a);void 0===r&&(r={},d.set(a,r));const o=function(e){const t=[];return t.push(e.wrapS),t.push(e.wrapT),t.push(e.wrapR||0),t.push(e.magFilter),t.push(e.minFilter),t.push(e.anisotropy),t.push(e.internalFormat),t.push(e.format),t.push(e.type),t.push(e.generateMipmaps),t.push(e.premultiplyAlpha),t.push(e.flipY),t.push(e.unpackAlignment),t.push(e.colorSpace),t.join()}(i);if(o!==t.__cacheKey){void 0===r[o]&&(r[o]={texture:e.createTexture(),usedTimes:0},s.memory.textures++,n=!0),r[o].usedTimes++;const a=r[t.__cacheKey];void 0!==a&&(r[t.__cacheKey].usedTimes--,0===a.usedTimes&&w(i)),t.__cacheKey=o,t.__webglTexture=r[o].texture}return n}function I(e,t,i){return Math.floor(Math.floor(e/i)/t)}function L(t,s,o){let l=e.TEXTURE_2D;(s.isDataArrayTexture||s.isCompressedArrayTexture)&&(l=e.TEXTURE_2D_ARRAY),s.isData3DTexture&&(l=e.TEXTURE_3D);const h=R(t,s),c=s.source;i.bindTexture(l,t.__webglTexture,e.TEXTURE0+o);const u=n.get(c);if(c.version!==u.__version||!0===h){i.activeTexture(e.TEXTURE0+o);const t=Dt.getPrimaries(Dt.workingColorSpace),n=s.colorSpace===Ue?null:Dt.getPrimaries(s.colorSpace),d=s.colorSpace===Ue||t===n?e.NONE:e.BROWSER_DEFAULT_WEBGL;e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL,s.flipY),e.pixelStorei(e.UNPACK_PREMULTIPLY_ALPHA_WEBGL,s.premultiplyAlpha),e.pixelStorei(e.UNPACK_ALIGNMENT,s.unpackAlignment),e.pixelStorei(e.UNPACK_COLORSPACE_CONVERSION_WEBGL,d);let p=f(s.image,!1,a.maxTextureSize);p=re(s,p);const m=r.convert(s.format,s.colorSpace),y=r.convert(s.type);let x,S=b(s.internalFormat,m,y,s.colorSpace,s.isVideoTexture);D(l,s);const w=s.mipmaps,E=!0!==s.isVideoTexture,T=void 0===u.__version||!0===h,C=c.dataReady,A=_(s,p);if(s.isDepthTexture)S=M(s.format===ee,s.type),T&&(E?i.texStorage2D(e.TEXTURE_2D,1,S,p.width,p.height):i.texImage2D(e.TEXTURE_2D,0,S,p.width,p.height,0,m,y,null));else if(s.isDataTexture)if(w.length>0){E&&T&&i.texStorage2D(e.TEXTURE_2D,A,S,w[0].width,w[0].height);for(let t=0,n=w.length;t<n;t++)x=w[t],E?C&&i.texSubImage2D(e.TEXTURE_2D,t,0,0,x.width,x.height,m,y,x.data):i.texImage2D(e.TEXTURE_2D,t,S,x.width,x.height,0,m,y,x.data);s.generateMipmaps=!1}else E?(T&&i.texStorage2D(e.TEXTURE_2D,A,S,p.width,p.height),C&&function(t,n,a,r){const s=t.updateRanges;if(0===s.length)i.texSubImage2D(e.TEXTURE_2D,0,0,0,n.width,n.height,a,r,n.data);else{s.sort((e,t)=>e.start-t.start);let o=0;for(let e=1;e<s.length;e++){const t=s[o],i=s[e],a=t.start+t.count,r=I(i.start,n.width,4),l=I(t.start,n.width,4);i.start<=a+1&&r===l&&I(i.start+i.count-1,n.width,4)===r?t.count=Math.max(t.count,i.start+i.count-t.start):(++o,s[o]=i)}s.length=o+1;const l=e.getParameter(e.UNPACK_ROW_LENGTH),h=e.getParameter(e.UNPACK_SKIP_PIXELS),c=e.getParameter(e.UNPACK_SKIP_ROWS);e.pixelStorei(e.UNPACK_ROW_LENGTH,n.width);for(let t=0,o=s.length;t<o;t++){const o=s[t],l=Math.floor(o.start/4),h=Math.ceil(o.count/4),c=l%n.width,u=Math.floor(l/n.width),d=h,p=1;e.pixelStorei(e.UNPACK_SKIP_PIXELS,c),e.pixelStorei(e.UNPACK_SKIP_ROWS,u),i.texSubImage2D(e.TEXTURE_2D,0,c,u,d,p,a,r,n.data)}t.clearUpdateRanges(),e.pixelStorei(e.UNPACK_ROW_LENGTH,l),e.pixelStorei(e.UNPACK_SKIP_PIXELS,h),e.pixelStorei(e.UNPACK_SKIP_ROWS,c)}}(s,p,m,y)):i.texImage2D(e.TEXTURE_2D,0,S,p.width,p.height,0,m,y,p.data);else if(s.isCompressedTexture)if(s.isCompressedArrayTexture){E&&T&&i.texStorage3D(e.TEXTURE_2D_ARRAY,A,S,w[0].width,w[0].height,p.depth);for(let t=0,n=w.length;t<n;t++)if(x=w[t],s.format!==Q)if(null!==m)if(E){if(C)if(s.layerUpdates.size>0){const n=ts(x.width,x.height,s.format,s.type);for(const a of s.layerUpdates){const r=x.data.subarray(a*n/x.data.BYTES_PER_ELEMENT,(a+1)*n/x.data.BYTES_PER_ELEMENT);i.compressedTexSubImage3D(e.TEXTURE_2D_ARRAY,t,0,0,a,x.width,x.height,1,m,r)}s.clearLayerUpdates()}else i.compressedTexSubImage3D(e.TEXTURE_2D_ARRAY,t,0,0,0,x.width,x.height,p.depth,m,x.data)}else i.compressedTexImage3D(e.TEXTURE_2D_ARRAY,t,S,x.width,x.height,p.depth,0,x.data,0,0);else ot("WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()");else E?C&&i.texSubImage3D(e.TEXTURE_2D_ARRAY,t,0,0,0,x.width,x.height,p.depth,m,y,x.data):i.texImage3D(e.TEXTURE_2D_ARRAY,t,S,x.width,x.height,p.depth,0,m,y,x.data)}else{E&&T&&i.texStorage2D(e.TEXTURE_2D,A,S,w[0].width,w[0].height);for(let t=0,n=w.length;t<n;t++)x=w[t],s.format!==Q?null!==m?E?C&&i.compressedTexSubImage2D(e.TEXTURE_2D,t,0,0,x.width,x.height,m,x.data):i.compressedTexImage2D(e.TEXTURE_2D,t,S,x.width,x.height,0,x.data):ot("WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()"):E?C&&i.texSubImage2D(e.TEXTURE_2D,t,0,0,x.width,x.height,m,y,x.data):i.texImage2D(e.TEXTURE_2D,t,S,x.width,x.height,0,m,y,x.data)}else if(s.isDataArrayTexture)if(E){if(T&&i.texStorage3D(e.TEXTURE_2D_ARRAY,A,S,p.width,p.height,p.depth),C)if(s.layerUpdates.size>0){const t=ts(p.width,p.height,s.format,s.type);for(const n of s.layerUpdates){const a=p.data.subarray(n*t/p.data.BYTES_PER_ELEMENT,(n+1)*t/p.data.BYTES_PER_ELEMENT);i.texSubImage3D(e.TEXTURE_2D_ARRAY,0,0,0,n,p.width,p.height,1,m,y,a)}s.clearLayerUpdates()}else i.texSubImage3D(e.TEXTURE_2D_ARRAY,0,0,0,0,p.width,p.height,p.depth,m,y,p.data)}else i.texImage3D(e.TEXTURE_2D_ARRAY,0,S,p.width,p.height,p.depth,0,m,y,p.data);else if(s.isData3DTexture)E?(T&&i.texStorage3D(e.TEXTURE_3D,A,S,p.width,p.height,p.depth),C&&i.texSubImage3D(e.TEXTURE_3D,0,0,0,0,p.width,p.height,p.depth,m,y,p.data)):i.texImage3D(e.TEXTURE_3D,0,S,p.width,p.height,p.depth,0,m,y,p.data);else if(s.isFramebufferTexture){if(T)if(E)i.texStorage2D(e.TEXTURE_2D,A,S,p.width,p.height);else{let t=p.width,n=p.height;for(let a=0;a<A;a++)i.texImage2D(e.TEXTURE_2D,a,S,t,n,0,m,y,null),t>>=1,n>>=1}}else if(w.length>0){if(E&&T){const t=se(w[0]);i.texStorage2D(e.TEXTURE_2D,A,S,t.width,t.height)}for(let t=0,n=w.length;t<n;t++)x=w[t],E?C&&i.texSubImage2D(e.TEXTURE_2D,t,0,0,m,y,x):i.texImage2D(e.TEXTURE_2D,t,S,m,y,x);s.generateMipmaps=!1}else if(E){if(T){const t=se(p);i.texStorage2D(e.TEXTURE_2D,A,S,t.width,t.height)}C&&i.texSubImage2D(e.TEXTURE_2D,0,0,0,m,y,p)}else i.texImage2D(e.TEXTURE_2D,0,S,m,y,p);g(s)&&v(l),u.__version=c.version,s.onUpdate&&s.onUpdate(s)}t.__version=s.version}function j(t,a,s,l,h,c){const u=r.convert(s.format,s.colorSpace),d=r.convert(s.type),p=b(s.internalFormat,u,d,s.colorSpace),m=n.get(a),f=n.get(s);if(f.__renderTarget=a,!m.__hasExternalTextures){const t=Math.max(1,a.width>>c),n=Math.max(1,a.height>>c);h===e.TEXTURE_3D||h===e.TEXTURE_2D_ARRAY?i.texImage3D(h,c,p,t,n,a.depth,0,u,d,null):i.texImage2D(h,c,p,t,n,0,u,d,null)}i.bindFramebuffer(e.FRAMEBUFFER,t),ae(a)?o.framebufferTexture2DMultisampleEXT(e.FRAMEBUFFER,l,h,f.__webglTexture,0,ne(a)):(h===e.TEXTURE_2D||h>=e.TEXTURE_CUBE_MAP_POSITIVE_X&&h<=e.TEXTURE_CUBE_MAP_NEGATIVE_Z)&&e.framebufferTexture2D(e.FRAMEBUFFER,l,h,f.__webglTexture,c),i.bindFramebuffer(e.FRAMEBUFFER,null)}function Y(t,i,n){if(e.bindRenderbuffer(e.RENDERBUFFER,t),i.depthBuffer){const a=i.depthTexture,r=a&&a.isDepthTexture?a.type:null,s=M(i.stencilBuffer,r),l=i.stencilBuffer?e.DEPTH_STENCIL_ATTACHMENT:e.DEPTH_ATTACHMENT,h=ne(i);ae(i)?o.renderbufferStorageMultisampleEXT(e.RENDERBUFFER,h,s,i.width,i.height):n?e.renderbufferStorageMultisample(e.RENDERBUFFER,h,s,i.width,i.height):e.renderbufferStorage(e.RENDERBUFFER,s,i.width,i.height),e.framebufferRenderbuffer(e.FRAMEBUFFER,l,e.RENDERBUFFER,t)}else{const t=i.textures;for(let a=0;a<t.length;a++){const s=t[a],l=r.convert(s.format,s.colorSpace),h=r.convert(s.type),c=b(s.internalFormat,l,h,s.colorSpace),u=ne(i);n&&!1===ae(i)?e.renderbufferStorageMultisample(e.RENDERBUFFER,u,c,i.width,i.height):ae(i)?o.renderbufferStorageMultisampleEXT(e.RENDERBUFFER,u,c,i.width,i.height):e.renderbufferStorage(e.RENDERBUFFER,c,i.width,i.height)}}e.bindRenderbuffer(e.RENDERBUFFER,null)}function $(t,a){if(a&&a.isWebGLCubeRenderTarget)throw new Error("Depth Texture with cube render targets is not supported");if(i.bindFramebuffer(e.FRAMEBUFFER,t),!a.depthTexture||!a.depthTexture.isDepthTexture)throw new Error("renderTarget.depthTexture must be an instance of THREE.DepthTexture");const r=n.get(a.depthTexture);r.__renderTarget=a,r.__webglTexture&&a.depthTexture.image.width===a.width&&a.depthTexture.image.height===a.height||(a.depthTexture.image.width=a.width,a.depthTexture.image.height=a.height,a.depthTexture.needsUpdate=!0),T(a.depthTexture,0);const s=r.__webglTexture,l=ne(a);if(a.depthTexture.format===J)ae(a)?o.framebufferTexture2DMultisampleEXT(e.FRAMEBUFFER,e.DEPTH_ATTACHMENT,e.TEXTURE_2D,s,0,l):e.framebufferTexture2D(e.FRAMEBUFFER,e.DEPTH_ATTACHMENT,e.TEXTURE_2D,s,0);else{if(a.depthTexture.format!==ee)throw new Error("Unknown depthTexture format");ae(a)?o.framebufferTexture2DMultisampleEXT(e.FRAMEBUFFER,e.DEPTH_STENCIL_ATTACHMENT,e.TEXTURE_2D,s,0,l):e.framebufferTexture2D(e.FRAMEBUFFER,e.DEPTH_STENCIL_ATTACHMENT,e.TEXTURE_2D,s,0)}}function Z(t){const a=n.get(t),r=!0===t.isWebGLCubeRenderTarget;if(a.__boundDepthTexture!==t.depthTexture){const e=t.depthTexture;if(a.__depthDisposeCallback&&a.__depthDisposeCallback(),e){const t=()=>{delete a.__boundDepthTexture,delete a.__depthDisposeCallback,e.removeEventListener("dispose",t)};e.addEventListener("dispose",t),a.__depthDisposeCallback=t}a.__boundDepthTexture=e}if(t.depthTexture&&!a.__autoAllocateDepthBuffer){if(r)throw new Error("target.depthTexture not supported in Cube render targets");const e=t.texture.mipmaps;e&&e.length>0?$(a.__webglFramebuffer[0],t):$(a.__webglFramebuffer,t)}else if(r){a.__webglDepthbuffer=[];for(let n=0;n<6;n++)if(i.bindFramebuffer(e.FRAMEBUFFER,a.__webglFramebuffer[n]),void 0===a.__webglDepthbuffer[n])a.__webglDepthbuffer[n]=e.createRenderbuffer(),Y(a.__webglDepthbuffer[n],t,!1);else{const i=t.stencilBuffer?e.DEPTH_STENCIL_ATTACHMENT:e.DEPTH_ATTACHMENT,r=a.__webglDepthbuffer[n];e.bindRenderbuffer(e.RENDERBUFFER,r),e.framebufferRenderbuffer(e.FRAMEBUFFER,i,e.RENDERBUFFER,r)}}else{const n=t.texture.mipmaps;if(n&&n.length>0?i.bindFramebuffer(e.FRAMEBUFFER,a.__webglFramebuffer[0]):i.bindFramebuffer(e.FRAMEBUFFER,a.__webglFramebuffer),void 0===a.__webglDepthbuffer)a.__webglDepthbuffer=e.createRenderbuffer(),Y(a.__webglDepthbuffer,t,!1);else{const i=t.stencilBuffer?e.DEPTH_STENCIL_ATTACHMENT:e.DEPTH_ATTACHMENT,n=a.__webglDepthbuffer;e.bindRenderbuffer(e.RENDERBUFFER,n),e.framebufferRenderbuffer(e.FRAMEBUFFER,i,e.RENDERBUFFER,n)}}i.bindFramebuffer(e.FRAMEBUFFER,null)}const te=[],ie=[];function ne(e){return Math.min(a.maxSamples,e.samples)}function ae(e){const i=n.get(e);return e.samples>0&&!0===t.has("WEBGL_multisampled_render_to_texture")&&!1!==i.__useRenderToTexture}function re(e,t){const i=e.colorSpace,n=e.format,a=e.type;return!0===e.isCompressedTexture||!0===e.isVideoTexture||i!==ke&&i!==Ue&&(Dt.getTransfer(i)===Ge?n===Q&&a===H||ot("WebGLTextures: sRGB encoded textures have to use RGBAFormat and UnsignedByteType."):lt("WebGLTextures: Unsupported texture color space:",i)),t}function se(e){return"undefined"!=typeof HTMLImageElement&&e instanceof HTMLImageElement?(h.width=e.naturalWidth||e.width,h.height=e.naturalHeight||e.height):"undefined"!=typeof VideoFrame&&e instanceof VideoFrame?(h.width=e.displayWidth,h.height=e.displayHeight):(h.width=e.width,h.height=e.height),h}this.allocateTextureUnit=function(){const e=E;return e>=a.maxTextures&&ot("WebGLTextures: Trying to use "+e+" texture units while this GPU supports only "+a.maxTextures),E+=1,e},this.resetTextureUnits=function(){E=0},this.setTexture2D=T,this.setTexture2DArray=function(t,a){const r=n.get(t);!1===t.isRenderTargetTexture&&t.version>0&&r.__version!==t.version?L(r,t,a):(t.isExternalTexture&&(r.__webglTexture=t.sourceTexture?t.sourceTexture:null),i.bindTexture(e.TEXTURE_2D_ARRAY,r.__webglTexture,e.TEXTURE0+a))},this.setTexture3D=function(t,a){const r=n.get(t);!1===t.isRenderTargetTexture&&t.version>0&&r.__version!==t.version?L(r,t,a):i.bindTexture(e.TEXTURE_3D,r.__webglTexture,e.TEXTURE0+a)},this.setTextureCube=function(t,s){const o=n.get(t);t.version>0&&o.__version!==t.version?function(t,s,o){if(6!==s.image.length)return;const l=R(t,s),h=s.source;i.bindTexture(e.TEXTURE_CUBE_MAP,t.__webglTexture,e.TEXTURE0+o);const c=n.get(h);if(h.version!==c.__version||!0===l){i.activeTexture(e.TEXTURE0+o);const t=Dt.getPrimaries(Dt.workingColorSpace),n=s.colorSpace===Ue?null:Dt.getPrimaries(s.colorSpace),u=s.colorSpace===Ue||t===n?e.NONE:e.BROWSER_DEFAULT_WEBGL;e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL,s.flipY),e.pixelStorei(e.UNPACK_PREMULTIPLY_ALPHA_WEBGL,s.premultiplyAlpha),e.pixelStorei(e.UNPACK_ALIGNMENT,s.unpackAlignment),e.pixelStorei(e.UNPACK_COLORSPACE_CONVERSION_WEBGL,u);const d=s.isCompressedTexture||s.image[0].isCompressedTexture,p=s.image[0]&&s.image[0].isDataTexture,m=[];for(let e=0;e<6;e++)m[e]=d||p?p?s.image[e].image:s.image[e]:f(s.image[e],!0,a.maxCubemapSize),m[e]=re(s,m[e]);const y=m[0],M=r.convert(s.format,s.colorSpace),x=r.convert(s.type),S=b(s.internalFormat,M,x,s.colorSpace),w=!0!==s.isVideoTexture,E=void 0===c.__version||!0===l,T=h.dataReady;let C,A=_(s,y);if(D(e.TEXTURE_CUBE_MAP,s),d){w&&E&&i.texStorage2D(e.TEXTURE_CUBE_MAP,A,S,y.width,y.height);for(let t=0;t<6;t++){C=m[t].mipmaps;for(let n=0;n<C.length;n++){const a=C[n];s.format!==Q?null!==M?w?T&&i.compressedTexSubImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X+t,n,0,0,a.width,a.height,M,a.data):i.compressedTexImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X+t,n,S,a.width,a.height,0,a.data):ot("WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()"):w?T&&i.texSubImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X+t,n,0,0,a.width,a.height,M,x,a.data):i.texImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X+t,n,S,a.width,a.height,0,M,x,a.data)}}}else{if(C=s.mipmaps,w&&E){C.length>0&&A++;const t=se(m[0]);i.texStorage2D(e.TEXTURE_CUBE_MAP,A,S,t.width,t.height)}for(let t=0;t<6;t++)if(p){w?T&&i.texSubImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X+t,0,0,0,m[t].width,m[t].height,M,x,m[t].data):i.texImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X+t,0,S,m[t].width,m[t].height,0,M,x,m[t].data);for(let n=0;n<C.length;n++){const a=C[n].image[t].image;w?T&&i.texSubImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X+t,n+1,0,0,a.width,a.height,M,x,a.data):i.texImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X+t,n+1,S,a.width,a.height,0,M,x,a.data)}}else{w?T&&i.texSubImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X+t,0,0,0,M,x,m[t]):i.texImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X+t,0,S,M,x,m[t]);for(let n=0;n<C.length;n++){const a=C[n];w?T&&i.texSubImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X+t,n+1,0,0,M,x,a.image[t]):i.texImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X+t,n+1,S,M,x,a.image[t])}}}g(s)&&v(e.TEXTURE_CUBE_MAP),c.__version=h.version,s.onUpdate&&s.onUpdate(s)}t.__version=s.version}(o,t,s):i.bindTexture(e.TEXTURE_CUBE_MAP,o.__webglTexture,e.TEXTURE0+s)},this.rebindTextures=function(t,i,a){const r=n.get(t);void 0!==i&&j(r.__webglFramebuffer,t,t.texture,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,0),void 0!==a&&Z(t)},this.setupRenderTarget=function(t){const a=t.texture,o=n.get(t),l=n.get(a);t.addEventListener("dispose",S);const h=t.textures,c=!0===t.isWebGLCubeRenderTarget,u=h.length>1;if(u||(void 0===l.__webglTexture&&(l.__webglTexture=e.createTexture()),l.__version=a.version,s.memory.textures++),c){o.__webglFramebuffer=[];for(let t=0;t<6;t++)if(a.mipmaps&&a.mipmaps.length>0){o.__webglFramebuffer[t]=[];for(let i=0;i<a.mipmaps.length;i++)o.__webglFramebuffer[t][i]=e.createFramebuffer()}else o.__webglFramebuffer[t]=e.createFramebuffer()}else{if(a.mipmaps&&a.mipmaps.length>0){o.__webglFramebuffer=[];for(let t=0;t<a.mipmaps.length;t++)o.__webglFramebuffer[t]=e.createFramebuffer()}else o.__webglFramebuffer=e.createFramebuffer();if(u)for(let t=0,i=h.length;t<i;t++){const i=n.get(h[t]);void 0===i.__webglTexture&&(i.__webglTexture=e.createTexture(),s.memory.textures++)}if(t.samples>0&&!1===ae(t)){o.__webglMultisampledFramebuffer=e.createFramebuffer(),o.__webglColorRenderbuffer=[],i.bindFramebuffer(e.FRAMEBUFFER,o.__webglMultisampledFramebuffer);for(let i=0;i<h.length;i++){const n=h[i];o.__webglColorRenderbuffer[i]=e.createRenderbuffer(),e.bindRenderbuffer(e.RENDERBUFFER,o.__webglColorRenderbuffer[i]);const a=r.convert(n.format,n.colorSpace),s=r.convert(n.type),l=b(n.internalFormat,a,s,n.colorSpace,!0===t.isXRRenderTarget),c=ne(t);e.renderbufferStorageMultisample(e.RENDERBUFFER,c,l,t.width,t.height),e.framebufferRenderbuffer(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0+i,e.RENDERBUFFER,o.__webglColorRenderbuffer[i])}e.bindRenderbuffer(e.RENDERBUFFER,null),t.depthBuffer&&(o.__webglDepthRenderbuffer=e.createRenderbuffer(),Y(o.__webglDepthRenderbuffer,t,!0)),i.bindFramebuffer(e.FRAMEBUFFER,null)}}if(c){i.bindTexture(e.TEXTURE_CUBE_MAP,l.__webglTexture),D(e.TEXTURE_CUBE_MAP,a);for(let i=0;i<6;i++)if(a.mipmaps&&a.mipmaps.length>0)for(let n=0;n<a.mipmaps.length;n++)j(o.__webglFramebuffer[i][n],t,a,e.COLOR_ATTACHMENT0,e.TEXTURE_CUBE_MAP_POSITIVE_X+i,n);else j(o.__webglFramebuffer[i],t,a,e.COLOR_ATTACHMENT0,e.TEXTURE_CUBE_MAP_POSITIVE_X+i,0);g(a)&&v(e.TEXTURE_CUBE_MAP),i.unbindTexture()}else if(u){for(let a=0,r=h.length;a<r;a++){const r=h[a],s=n.get(r);let l=e.TEXTURE_2D;(t.isWebGL3DRenderTarget||t.isWebGLArrayRenderTarget)&&(l=t.isWebGL3DRenderTarget?e.TEXTURE_3D:e.TEXTURE_2D_ARRAY),i.bindTexture(l,s.__webglTexture),D(l,r),j(o.__webglFramebuffer,t,r,e.COLOR_ATTACHMENT0+a,l,0),g(r)&&v(l)}i.unbindTexture()}else{let n=e.TEXTURE_2D;if((t.isWebGL3DRenderTarget||t.isWebGLArrayRenderTarget)&&(n=t.isWebGL3DRenderTarget?e.TEXTURE_3D:e.TEXTURE_2D_ARRAY),i.bindTexture(n,l.__webglTexture),D(n,a),a.mipmaps&&a.mipmaps.length>0)for(let i=0;i<a.mipmaps.length;i++)j(o.__webglFramebuffer[i],t,a,e.COLOR_ATTACHMENT0,n,i);else j(o.__webglFramebuffer,t,a,e.COLOR_ATTACHMENT0,n,0);g(a)&&v(n),i.unbindTexture()}t.depthBuffer&&Z(t)},this.updateRenderTargetMipmap=function(e){const t=e.textures;for(let a=0,r=t.length;a<r;a++){const r=t[a];if(g(r)){const t=y(e),a=n.get(r).__webglTexture;i.bindTexture(t,a),v(t),i.unbindTexture()}}},this.updateMultisampleRenderTarget=function(t){if(t.samples>0)if(!1===ae(t)){const a=t.textures,r=t.width,s=t.height;let o=e.COLOR_BUFFER_BIT;const h=t.stencilBuffer?e.DEPTH_STENCIL_ATTACHMENT:e.DEPTH_ATTACHMENT,c=n.get(t),u=a.length>1;if(u)for(let t=0;t<a.length;t++)i.bindFramebuffer(e.FRAMEBUFFER,c.__webglMultisampledFramebuffer),e.framebufferRenderbuffer(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0+t,e.RENDERBUFFER,null),i.bindFramebuffer(e.FRAMEBUFFER,c.__webglFramebuffer),e.framebufferTexture2D(e.DRAW_FRAMEBUFFER,e.COLOR_ATTACHMENT0+t,e.TEXTURE_2D,null,0);i.bindFramebuffer(e.READ_FRAMEBUFFER,c.__webglMultisampledFramebuffer);const d=t.texture.mipmaps;d&&d.length>0?i.bindFramebuffer(e.DRAW_FRAMEBUFFER,c.__webglFramebuffer[0]):i.bindFramebuffer(e.DRAW_FRAMEBUFFER,c.__webglFramebuffer);for(let i=0;i<a.length;i++){if(t.resolveDepthBuffer&&(t.depthBuffer&&(o|=e.DEPTH_BUFFER_BIT),t.stencilBuffer&&t.resolveStencilBuffer&&(o|=e.STENCIL_BUFFER_BIT)),u){e.framebufferRenderbuffer(e.READ_FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.RENDERBUFFER,c.__webglColorRenderbuffer[i]);const t=n.get(a[i]).__webglTexture;e.framebufferTexture2D(e.DRAW_FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,t,0)}e.blitFramebuffer(0,0,r,s,0,0,r,s,o,e.NEAREST),!0===l&&(te.length=0,ie.length=0,te.push(e.COLOR_ATTACHMENT0+i),t.depthBuffer&&!1===t.resolveDepthBuffer&&(te.push(h),ie.push(h),e.invalidateFramebuffer(e.DRAW_FRAMEBUFFER,ie)),e.invalidateFramebuffer(e.READ_FRAMEBUFFER,te))}if(i.bindFramebuffer(e.READ_FRAMEBUFFER,null),i.bindFramebuffer(e.DRAW_FRAMEBUFFER,null),u)for(let t=0;t<a.length;t++){i.bindFramebuffer(e.FRAMEBUFFER,c.__webglMultisampledFramebuffer),e.framebufferRenderbuffer(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0+t,e.RENDERBUFFER,c.__webglColorRenderbuffer[t]);const r=n.get(a[t]).__webglTexture;i.bindFramebuffer(e.FRAMEBUFFER,c.__webglFramebuffer),e.framebufferTexture2D(e.DRAW_FRAMEBUFFER,e.COLOR_ATTACHMENT0+t,e.TEXTURE_2D,r,0)}i.bindFramebuffer(e.DRAW_FRAMEBUFFER,c.__webglMultisampledFramebuffer)}else if(t.depthBuffer&&!1===t.resolveDepthBuffer&&l){const i=t.stencilBuffer?e.DEPTH_STENCIL_ATTACHMENT:e.DEPTH_ATTACHMENT;e.invalidateFramebuffer(e.DRAW_FRAMEBUFFER,[i])}},this.setupDepthRenderbuffer=Z,this.setupFrameBufferTexture=j,this.useMultisampledRTT=ae}function Tl(e,t){return{convert:function(i,n=""){let a;const r=Dt.getTransfer(n);if(i===H)return e.UNSIGNED_BYTE;if(i===$)return e.UNSIGNED_SHORT_4_4_4_4;if(i===Z)return e.UNSIGNED_SHORT_5_5_5_1;if(35902===i)return e.UNSIGNED_INT_5_9_9_9_REV;if(35899===i)return e.UNSIGNED_INT_10F_11F_11F_REV;if(1010===i)return e.BYTE;if(1011===i)return e.SHORT;if(i===W)return e.UNSIGNED_SHORT;if(i===j)return e.INT;if(i===X)return e.UNSIGNED_INT;if(i===q)return e.FLOAT;if(i===Y)return e.HALF_FLOAT;if(1021===i)return e.ALPHA;if(1022===i)return e.RGB;if(i===Q)return e.RGBA;if(i===J)return e.DEPTH_COMPONENT;if(i===ee)return e.DEPTH_STENCIL;if(1028===i)return e.RED;if(i===te)return e.RED_INTEGER;if(i===ie)return e.RG;if(i===ne)return e.RG_INTEGER;if(i===ae)return e.RGBA_INTEGER;if(i===re||i===se||i===oe||i===le)if(r===Ge){if(a=t.get("WEBGL_compressed_texture_s3tc_srgb"),null===a)return null;if(i===re)return a.COMPRESSED_SRGB_S3TC_DXT1_EXT;if(i===se)return a.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;if(i===oe)return a.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;if(i===le)return a.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT}else{if(a=t.get("WEBGL_compressed_texture_s3tc"),null===a)return null;if(i===re)return a.COMPRESSED_RGB_S3TC_DXT1_EXT;if(i===se)return a.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(i===oe)return a.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(i===le)return a.COMPRESSED_RGBA_S3TC_DXT5_EXT}if(i===he||i===ce||i===ue||i===de){if(a=t.get("WEBGL_compressed_texture_pvrtc"),null===a)return null;if(i===he)return a.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;if(i===ce)return a.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;if(i===ue)return a.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;if(i===de)return a.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}if(i===pe||i===me||i===fe){if(a=t.get("WEBGL_compressed_texture_etc"),null===a)return null;if(i===pe||i===me)return r===Ge?a.COMPRESSED_SRGB8_ETC2:a.COMPRESSED_RGB8_ETC2;if(i===fe)return r===Ge?a.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:a.COMPRESSED_RGBA8_ETC2_EAC}if(i===ge||i===ve||i===ye||i===be||i===Me||i===_e||i===xe||i===Se||i===we||i===Ee||i===Te||i===Ce||i===Ae||i===Pe){if(a=t.get("WEBGL_compressed_texture_astc"),null===a)return null;if(i===ge)return r===Ge?a.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:a.COMPRESSED_RGBA_ASTC_4x4_KHR;if(i===ve)return r===Ge?a.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:a.COMPRESSED_RGBA_ASTC_5x4_KHR;if(i===ye)return r===Ge?a.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:a.COMPRESSED_RGBA_ASTC_5x5_KHR;if(i===be)return r===Ge?a.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:a.COMPRESSED_RGBA_ASTC_6x5_KHR;if(i===Me)return r===Ge?a.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:a.COMPRESSED_RGBA_ASTC_6x6_KHR;if(i===_e)return r===Ge?a.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:a.COMPRESSED_RGBA_ASTC_8x5_KHR;if(i===xe)return r===Ge?a.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:a.COMPRESSED_RGBA_ASTC_8x6_KHR;if(i===Se)return r===Ge?a.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:a.COMPRESSED_RGBA_ASTC_8x8_KHR;if(i===we)return r===Ge?a.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:a.COMPRESSED_RGBA_ASTC_10x5_KHR;if(i===Ee)return r===Ge?a.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:a.COMPRESSED_RGBA_ASTC_10x6_KHR;if(i===Te)return r===Ge?a.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:a.COMPRESSED_RGBA_ASTC_10x8_KHR;if(i===Ce)return r===Ge?a.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:a.COMPRESSED_RGBA_ASTC_10x10_KHR;if(i===Ae)return r===Ge?a.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:a.COMPRESSED_RGBA_ASTC_12x10_KHR;if(i===Pe)return r===Ge?a.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:a.COMPRESSED_RGBA_ASTC_12x12_KHR}if(i===De||i===Re||i===Ie){if(a=t.get("EXT_texture_compression_bptc"),null===a)return null;if(i===De)return r===Ge?a.COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:a.COMPRESSED_RGBA_BPTC_UNORM_EXT;if(i===Re)return a.COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT;if(i===Ie)return a.COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT}if(i===Le||i===Be||i===Oe||i===Fe){if(a=t.get("EXT_texture_compression_rgtc"),null===a)return null;if(i===Le)return a.COMPRESSED_RED_RGTC1_EXT;if(i===Be)return a.COMPRESSED_SIGNED_RED_RGTC1_EXT;if(i===Oe)return a.COMPRESSED_RED_GREEN_RGTC2_EXT;if(i===Fe)return a.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT}return i===K?e.UNSIGNED_INT_24_8:void 0!==e[i]?e[i]:null}}}class Cl{constructor(){this.texture=null,this.mesh=null,this.depthNear=0,this.depthFar=0}init(e,t){if(null===this.texture){const i=new hr(e.texture);e.depthNear===t.depthNear&&e.depthFar===t.depthFar||(this.depthNear=e.depthNear,this.depthFar=e.depthFar),this.texture=i}}getMesh(e){if(null!==this.texture&&null===this.mesh){const t=e.cameras[0].viewport,i=new Jn({vertexShader:"\nvoid main() {\n\n\tgl_Position = vec4( position, 1.0 );\n\n}",fragmentShader:"\nuniform sampler2DArray depthColor;\nuniform float depthWidth;\nuniform float depthHeight;\n\nvoid main() {\n\n\tvec2 coord = vec2( gl_FragCoord.x / depthWidth, gl_FragCoord.y / depthHeight );\n\n\tif ( coord.x >= 1.0 ) {\n\n\t\tgl_FragDepth = texture( depthColor, vec3( coord.x - 1.0, coord.y, 1 ) ).r;\n\n\t} else {\n\n\t\tgl_FragDepth = texture( depthColor, vec3( coord.x, coord.y, 0 ) ).r;\n\n\t}\n\n}",uniforms:{depthColor:{value:this.texture},depthWidth:{value:t.z},depthHeight:{value:t.w}}});this.mesh=new Xn(new fr(20,20),i)}return this.mesh}reset(){this.texture=null,this.mesh=null}getDepthTexture(){return this.texture}}class Al extends ct{constructor(e,t){super();const i=this;let n=null,a=1,r=null,s="local-floor",o=1,l=null,h=null,c=null,u=null,d=null,p=null;const m="undefined"!=typeof XRWebGLBinding,f=new Cl,g={},v=t.getContextAttributes();let y=null,b=null;const M=[],_=[],x=new Mt;let S=null;const w=new aa;w.viewport=new Gt;const E=new aa;E.viewport=new Gt;const T=[w,E],C=new Kr;let A=null,P=null;function D(e){const t=_.indexOf(e.inputSource);if(-1===t)return;const i=M[t];void 0!==i&&(i.update(e.inputSource,e.frame,l||r),i.dispatchEvent({type:e.type,data:e.inputSource}))}function R(){n.removeEventListener("select",D),n.removeEventListener("selectstart",D),n.removeEventListener("selectend",D),n.removeEventListener("squeeze",D),n.removeEventListener("squeezestart",D),n.removeEventListener("squeezeend",D),n.removeEventListener("end",R),n.removeEventListener("inputsourceschange",I);for(let e=0;e<M.length;e++){const t=_[e];null!==t&&(_[e]=null,M[e].disconnect(t))}A=null,P=null,f.reset();for(const e in g)delete g[e];e.setRenderTarget(y),d=null,u=null,c=null,n=null,b=null,U.stop(),i.isPresenting=!1,e.setPixelRatio(S),e.setSize(x.width,x.height,!1),i.dispatchEvent({type:"sessionend"})}function I(e){for(let t=0;t<e.removed.length;t++){const i=e.removed[t],n=_.indexOf(i);n>=0&&(_[n]=null,M[n].disconnect(i))}for(let t=0;t<e.added.length;t++){const i=e.added[t];let n=_.indexOf(i);if(-1===n){for(let e=0;e<M.length;e++){if(e>=_.length){_.push(i),n=e;break}if(null===_[e]){_[e]=i,n=e;break}}if(-1===n)break}const a=M[n];a&&a.connect(i)}}this.cameraAutoUpdate=!0,this.enabled=!1,this.isPresenting=!1,this.getController=function(e){let t=M[e];return void 0===t&&(t=new ua,M[e]=t),t.getTargetRaySpace()},this.getControllerGrip=function(e){let t=M[e];return void 0===t&&(t=new ua,M[e]=t),t.getGripSpace()},this.getHand=function(e){let t=M[e];return void 0===t&&(t=new ua,M[e]=t),t.getHandSpace()},this.setFramebufferScaleFactor=function(e){a=e,!0===i.isPresenting&&ot("WebXRManager: Cannot change framebuffer scale while presenting.")},this.setReferenceSpaceType=function(e){s=e,!0===i.isPresenting&&ot("WebXRManager: Cannot change reference space type while presenting.")},this.getReferenceSpace=function(){return l||r},this.setReferenceSpace=function(e){l=e},this.getBaseLayer=function(){return null!==u?u:d},this.getBinding=function(){return null===c&&m&&(c=new XRWebGLBinding(n,t)),c},this.getFrame=function(){return p},this.getSession=function(){return n},this.setSession=async function(h){if(n=h,null!==n){if(y=e.getRenderTarget(),n.addEventListener("select",D),n.addEventListener("selectstart",D),n.addEventListener("selectend",D),n.addEventListener("squeeze",D),n.addEventListener("squeezestart",D),n.addEventListener("squeezeend",D),n.addEventListener("end",R),n.addEventListener("inputsourceschange",I),!0!==v.xrCompatible&&await t.makeXRCompatible(),S=e.getPixelRatio(),e.getSize(x),m&&"createProjectionLayer"in XRWebGLBinding.prototype){let i=null,r=null,s=null;v.depth&&(s=v.stencil?t.DEPTH24_STENCIL8:t.DEPTH_COMPONENT24,i=v.stencil?ee:J,r=v.stencil?K:X);const o={colorFormat:t.RGBA8,depthFormat:s,scaleFactor:a};c=this.getBinding(),u=c.createProjectionLayer(o),n.updateRenderState({layers:[u]}),e.setPixelRatio(1),e.setSize(u.textureWidth,u.textureHeight,!1),b=new Ht(u.textureWidth,u.textureHeight,{format:Q,type:H,depthTexture:new lr(u.textureWidth,u.textureHeight,r,void 0,void 0,void 0,void 0,void 0,void 0,i),stencilBuffer:v.stencil,colorSpace:e.outputColorSpace,samples:v.antialias?4:0,resolveDepthBuffer:!1===u.ignoreDepthValues,resolveStencilBuffer:!1===u.ignoreDepthValues})}else{const i={antialias:v.antialias,alpha:!0,depth:v.depth,stencil:v.stencil,framebufferScaleFactor:a};d=new XRWebGLLayer(n,t,i),n.updateRenderState({baseLayer:d}),e.setPixelRatio(1),e.setSize(d.framebufferWidth,d.framebufferHeight,!1),b=new Ht(d.framebufferWidth,d.framebufferHeight,{format:Q,type:H,colorSpace:e.outputColorSpace,stencilBuffer:v.stencil,resolveDepthBuffer:!1===d.ignoreDepthValues,resolveStencilBuffer:!1===d.ignoreDepthValues})}b.isXRRenderTarget=!0,this.setFoveation(o),l=null,r=await n.requestReferenceSpace(s),U.setContext(n),U.start(),i.isPresenting=!0,i.dispatchEvent({type:"sessionstart"})}},this.getEnvironmentBlendMode=function(){if(null!==n)return n.environmentBlendMode},this.getDepthTexture=function(){return f.getDepthTexture()};const L=new xt,B=new xt;function O(e,t){null===t?e.matrixWorld.copy(e.matrix):e.matrixWorld.multiplyMatrices(t.matrixWorld,e.matrix),e.matrixWorldInverse.copy(e.matrixWorld).invert()}this.updateCamera=function(e){if(null===n)return;let t=e.near,i=e.far;null!==f.texture&&(f.depthNear>0&&(t=f.depthNear),f.depthFar>0&&(i=f.depthFar)),C.near=E.near=w.near=t,C.far=E.far=w.far=i,A===C.near&&P===C.far||(n.updateRenderState({depthNear:C.near,depthFar:C.far}),A=C.near,P=C.far),C.layers.mask=6|e.layers.mask,w.layers.mask=3&C.layers.mask,E.layers.mask=5&C.layers.mask;const a=e.parent,r=C.cameras;O(C,a);for(let e=0;e<r.length;e++)O(r[e],a);2===r.length?function(e,t,i){L.setFromMatrixPosition(t.matrixWorld),B.setFromMatrixPosition(i.matrixWorld);const n=L.distanceTo(B),a=t.projectionMatrix.elements,r=i.projectionMatrix.elements,s=a[14]/(a[10]-1),o=a[14]/(a[10]+1),l=(a[9]+1)/a[5],h=(a[9]-1)/a[5],c=(a[8]-1)/a[0],u=(r[8]+1)/r[0],d=s*c,p=s*u,m=n/(-c+u),f=m*-c;if(t.matrixWorld.decompose(e.position,e.quaternion,e.scale),e.translateX(f),e.translateZ(m),e.matrixWorld.compose(e.position,e.quaternion,e.scale),e.matrixWorldInverse.copy(e.matrixWorld).invert(),-1===a[10])e.projectionMatrix.copy(t.projectionMatrix),e.projectionMatrixInverse.copy(t.projectionMatrixInverse);else{const t=s+m,i=o+m,a=d-f,r=p+(n-f),c=l*o/i*t,u=h*o/i*t;e.projectionMatrix.makePerspective(a,r,c,u,t,i),e.projectionMatrixInverse.copy(e.projectionMatrix).invert()}}(C,w,E):C.projectionMatrix.copy(w.projectionMatrix),function(e,t,i){null===i?e.matrix.copy(t.matrixWorld):(e.matrix.copy(i.matrixWorld),e.matrix.invert(),e.matrix.multiply(t.matrixWorld)),e.matrix.decompose(e.position,e.quaternion,e.scale),e.updateMatrixWorld(!0),e.projectionMatrix.copy(t.projectionMatrix),e.projectionMatrixInverse.copy(t.projectionMatrixInverse),e.isPerspectiveCamera&&(e.fov=2*pt*Math.atan(1/e.projectionMatrix.elements[5]),e.zoom=1)}(e,C,a)},this.getCamera=function(){return C},this.getFoveation=function(){if(null!==u||null!==d)return o},this.setFoveation=function(e){o=e,null!==u&&(u.fixedFoveation=e),null!==d&&void 0!==d.fixedFoveation&&(d.fixedFoveation=e)},this.hasDepthSensing=function(){return null!==f.texture},this.getDepthSensingMesh=function(){return f.getMesh(C)},this.getCameraTexture=function(e){return g[e]};let F=null;const U=new is;U.setAnimationLoop(function(t,a){if(h=a.getViewerPose(l||r),p=a,null!==h){const t=h.views;null!==d&&(e.setRenderTargetFramebuffer(b,d.framebuffer),e.setRenderTarget(b));let a=!1;t.length!==C.cameras.length&&(C.cameras.length=0,a=!0);for(let i=0;i<t.length;i++){const n=t[i];let r=null;if(null!==d)r=d.getViewport(n);else{const t=c.getViewSubImage(u,n);r=t.viewport,0===i&&(e.setRenderTargetTextures(b,t.colorTexture,t.depthStencilTexture),e.setRenderTarget(b))}let s=T[i];void 0===s&&(s=new aa,s.layers.enable(i),s.viewport=new Gt,T[i]=s),s.matrix.fromArray(n.transform.matrix),s.matrix.decompose(s.position,s.quaternion,s.scale),s.projectionMatrix.fromArray(n.projectionMatrix),s.projectionMatrixInverse.copy(s.projectionMatrix).invert(),s.viewport.set(r.x,r.y,r.width,r.height),0===i&&(C.matrix.copy(s.matrix),C.matrix.decompose(C.position,C.quaternion,C.scale)),!0===a&&C.cameras.push(s)}const r=n.enabledFeatures;if(r&&r.includes("depth-sensing")&&"gpu-optimized"==n.depthUsage&&m){c=i.getBinding();const e=c.getDepthInformation(t[0]);e&&e.isValid&&e.texture&&f.init(e,n.renderState)}if(r&&r.includes("camera-access")&&m){e.state.unbindTexture(),c=i.getBinding();for(let e=0;e<t.length;e++){const i=t[e].camera;if(i){let e=g[i];e||(e=new hr,g[i]=e);const t=c.getCameraImage(i);e.sourceTexture=t}}}}for(let e=0;e<M.length;e++){const t=_[e],i=M[e];null!==t&&void 0!==i&&i.update(t,a,l||r)}F&&F(t,a),a.detectedPlanes&&i.dispatchEvent({type:"planesdetected",data:a}),p=null}),this.setAnimationLoop=function(e){F=e},this.dispose=function(){}}}const Pl=new Pi,Dl=new bi;function Rl(e,t){function i(e,t){!0===e.matrixAutoUpdate&&e.updateMatrix(),t.value.copy(e.matrix)}function n(e,n){e.opacity.value=n.opacity,n.color&&e.diffuse.value.copy(n.color),n.emissive&&e.emissive.value.copy(n.emissive).multiplyScalar(n.emissiveIntensity),n.map&&(e.map.value=n.map,i(n.map,e.mapTransform)),n.alphaMap&&(e.alphaMap.value=n.alphaMap,i(n.alphaMap,e.alphaMapTransform)),n.bumpMap&&(e.bumpMap.value=n.bumpMap,i(n.bumpMap,e.bumpMapTransform),e.bumpScale.value=n.bumpScale,1===n.side&&(e.bumpScale.value*=-1)),n.normalMap&&(e.normalMap.value=n.normalMap,i(n.normalMap,e.normalMapTransform),e.normalScale.value.copy(n.normalScale),1===n.side&&e.normalScale.value.negate()),n.displacementMap&&(e.displacementMap.value=n.displacementMap,i(n.displacementMap,e.displacementMapTransform),e.displacementScale.value=n.displacementScale,e.displacementBias.value=n.displacementBias),n.emissiveMap&&(e.emissiveMap.value=n.emissiveMap,i(n.emissiveMap,e.emissiveMapTransform)),n.specularMap&&(e.specularMap.value=n.specularMap,i(n.specularMap,e.specularMapTransform)),n.alphaTest>0&&(e.alphaTest.value=n.alphaTest);const a=t.get(n),r=a.envMap,s=a.envMapRotation;r&&(e.envMap.value=r,Pl.copy(s),Pl.x*=-1,Pl.y*=-1,Pl.z*=-1,r.isCubeTexture&&!1===r.isRenderTargetTexture&&(Pl.y*=-1,Pl.z*=-1),e.envMapRotation.value.setFromMatrix4(Dl.makeRotationFromEuler(Pl)),e.flipEnvMap.value=r.isCubeTexture&&!1===r.isRenderTargetTexture?-1:1,e.reflectivity.value=n.reflectivity,e.ior.value=n.ior,e.refractionRatio.value=n.refractionRatio),n.lightMap&&(e.lightMap.value=n.lightMap,e.lightMapIntensity.value=n.lightMapIntensity,i(n.lightMap,e.lightMapTransform)),n.aoMap&&(e.aoMap.value=n.aoMap,e.aoMapIntensity.value=n.aoMapIntensity,i(n.aoMap,e.aoMapTransform))}return{refreshFogUniforms:function(t,i){i.color.getRGB(t.fogColor.value,Kn(e)),i.isFog?(t.fogNear.value=i.near,t.fogFar.value=i.far):i.isFogExp2&&(t.fogDensity.value=i.density)},refreshMaterialUniforms:function(e,a,r,s,o){a.isMeshBasicMaterial||a.isMeshLambertMaterial?n(e,a):a.isMeshToonMaterial?(n(e,a),function(e,t){t.gradientMap&&(e.gradientMap.value=t.gradientMap)}(e,a)):a.isMeshPhongMaterial?(n(e,a),function(e,t){e.specular.value.copy(t.specular),e.shininess.value=Math.max(t.shininess,1e-4)}(e,a)):a.isMeshStandardMaterial?(n(e,a),function(e,t){e.metalness.value=t.metalness,t.metalnessMap&&(e.metalnessMap.value=t.metalnessMap,i(t.metalnessMap,e.metalnessMapTransform)),e.roughness.value=t.roughness,t.roughnessMap&&(e.roughnessMap.value=t.roughnessMap,i(t.roughnessMap,e.roughnessMapTransform)),t.envMap&&(e.envMapIntensity.value=t.envMapIntensity)}(e,a),a.isMeshPhysicalMaterial&&function(e,t,n){e.ior.value=t.ior,t.sheen>0&&(e.sheenColor.value.copy(t.sheenColor).multiplyScalar(t.sheen),e.sheenRoughness.value=t.sheenRoughness,t.sheenColorMap&&(e.sheenColorMap.value=t.sheenColorMap,i(t.sheenColorMap,e.sheenColorMapTransform)),t.sheenRoughnessMap&&(e.sheenRoughnessMap.value=t.sheenRoughnessMap,i(t.sheenRoughnessMap,e.sheenRoughnessMapTransform))),t.clearcoat>0&&(e.clearcoat.value=t.clearcoat,e.clearcoatRoughness.value=t.clearcoatRoughness,t.clearcoatMap&&(e.clearcoatMap.value=t.clearcoatMap,i(t.clearcoatMap,e.clearcoatMapTransform)),t.clearcoatRoughnessMap&&(e.clearcoatRoughnessMap.value=t.clearcoatRoughnessMap,i(t.clearcoatRoughnessMap,e.clearcoatRoughnessMapTransform)),t.clearcoatNormalMap&&(e.clearcoatNormalMap.value=t.clearcoatNormalMap,i(t.clearcoatNormalMap,e.clearcoatNormalMapTransform),e.clearcoatNormalScale.value.copy(t.clearcoatNormalScale),1===t.side&&e.clearcoatNormalScale.value.negate())),t.dispersion>0&&(e.dispersion.value=t.dispersion),t.iridescence>0&&(e.iridescence.value=t.iridescence,e.iridescenceIOR.value=t.iridescenceIOR,e.iridescenceThicknessMinimum.value=t.iridescenceThicknessRange[0],e.iridescenceThicknessMaximum.value=t.iridescenceThicknessRange[1],t.iridescenceMap&&(e.iridescenceMap.value=t.iridescenceMap,i(t.iridescenceMap,e.iridescenceMapTransform)),t.iridescenceThicknessMap&&(e.iridescenceThicknessMap.value=t.iridescenceThicknessMap,i(t.iridescenceThicknessMap,e.iridescenceThicknessMapTransform))),t.transmission>0&&(e.transmission.value=t.transmission,e.transmissionSamplerMap.value=n.texture,e.transmissionSamplerSize.value.set(n.width,n.height),t.transmissionMap&&(e.transmissionMap.value=t.transmissionMap,i(t.transmissionMap,e.transmissionMapTransform)),e.thickness.value=t.thickness,t.thicknessMap&&(e.thicknessMap.value=t.thicknessMap,i(t.thicknessMap,e.thicknessMapTransform)),e.attenuationDistance.value=t.attenuationDistance,e.attenuationColor.value.copy(t.attenuationColor)),t.anisotropy>0&&(e.anisotropyVector.value.set(t.anisotropy*Math.cos(t.anisotropyRotation),t.anisotropy*Math.sin(t.anisotropyRotation)),t.anisotropyMap&&(e.anisotropyMap.value=t.anisotropyMap,i(t.anisotropyMap,e.anisotropyMapTransform))),e.specularIntensity.value=t.specularIntensity,e.specularColor.value.copy(t.specularColor),t.specularColorMap&&(e.specularColorMap.value=t.specularColorMap,i(t.specularColorMap,e.specularColorMapTransform)),t.specularIntensityMap&&(e.specularIntensityMap.value=t.specularIntensityMap,i(t.specularIntensityMap,e.specularIntensityMapTransform))}(e,a,o)):a.isMeshMatcapMaterial?(n(e,a),function(e,t){t.matcap&&(e.matcap.value=t.matcap)}(e,a)):a.isMeshDepthMaterial?n(e,a):a.isMeshDistanceMaterial?(n(e,a),function(e,i){const n=t.get(i).light;e.referencePosition.value.setFromMatrixPosition(n.matrixWorld),e.nearDistance.value=n.shadow.camera.near,e.farDistance.value=n.shadow.camera.far}(e,a)):a.isMeshNormalMaterial?n(e,a):a.isLineBasicMaterial?(function(e,t){e.diffuse.value.copy(t.color),e.opacity.value=t.opacity,t.map&&(e.map.value=t.map,i(t.map,e.mapTransform))}(e,a),a.isLineDashedMaterial&&function(e,t){e.dashSize.value=t.dashSize,e.totalSize.value=t.dashSize+t.gapSize,e.scale.value=t.scale}(e,a)):a.isPointsMaterial?function(e,t,n,a){e.diffuse.value.copy(t.color),e.opacity.value=t.opacity,e.size.value=t.size*n,e.scale.value=.5*a,t.map&&(e.map.value=t.map,i(t.map,e.uvTransform)),t.alphaMap&&(e.alphaMap.value=t.alphaMap,i(t.alphaMap,e.alphaMapTransform)),t.alphaTest>0&&(e.alphaTest.value=t.alphaTest)}(e,a,r,s):a.isSpriteMaterial?function(e,t){e.diffuse.value.copy(t.color),e.opacity.value=t.opacity,e.rotation.value=t.rotation,t.map&&(e.map.value=t.map,i(t.map,e.mapTransform)),t.alphaMap&&(e.alphaMap.value=t.alphaMap,i(t.alphaMap,e.alphaMapTransform)),t.alphaTest>0&&(e.alphaTest.value=t.alphaTest)}(e,a):a.isShadowMaterial?(e.color.value.copy(a.color),e.opacity.value=a.opacity):a.isShaderMaterial&&(a.uniformsNeedUpdate=!1)}}}function Il(e,t,i,n){let a={},r={},s=[];const o=e.getParameter(e.MAX_UNIFORM_BUFFER_BINDINGS);function l(e,t,i,n){const a=e.value,r=t+"_"+i;if(void 0===n[r])return n[r]="number"==typeof a||"boolean"==typeof a?a:a.clone(),!0;{const e=n[r];if("number"==typeof a||"boolean"==typeof a){if(e!==a)return n[r]=a,!0}else if(!1===e.equals(a))return e.copy(a),!0}return!1}function h(e){const t={boundary:0,storage:0};return"number"==typeof e||"boolean"==typeof e?(t.boundary=4,t.storage=4):e.isVector2?(t.boundary=8,t.storage=8):e.isVector3||e.isColor?(t.boundary=16,t.storage=12):e.isVector4?(t.boundary=16,t.storage=16):e.isMatrix3?(t.boundary=48,t.storage=48):e.isMatrix4?(t.boundary=64,t.storage=64):e.isTexture?ot("WebGLRenderer: Texture samplers can not be part of an uniforms group."):ot("WebGLRenderer: Unsupported uniform value type.",e),t}function c(t){const i=t.target;i.removeEventListener("dispose",c);const n=s.indexOf(i.__bindingPointIndex);s.splice(n,1),e.deleteBuffer(a[i.id]),delete a[i.id],delete r[i.id]}return{bind:function(e,t){const i=t.program;n.uniformBlockBinding(e,i)},update:function(i,u){let d=a[i.id];void 0===d&&(function(e){const t=e.uniforms;let i=0;for(let e=0,n=t.length;e<n;e++){const n=Array.isArray(t[e])?t[e]:[t[e]];for(let e=0,t=n.length;e<t;e++){const t=n[e],a=Array.isArray(t.value)?t.value:[t.value];for(let e=0,n=a.length;e<n;e++){const n=h(a[e]),r=i%16,s=r%n.boundary,o=r+s;i+=s,0!==o&&16-o<n.storage&&(i+=16-o),t.__data=new Float32Array(n.storage/Float32Array.BYTES_PER_ELEMENT),t.__offset=i,i+=n.storage}}}const n=i%16;n>0&&(i+=16-n),e.__size=i,e.__cache={}}(i),d=function(t){const i=function(){for(let e=0;e<o;e++)if(-1===s.indexOf(e))return s.push(e),e;return lt("WebGLRenderer: Maximum number of simultaneously usable uniforms groups reached."),0}();t.__bindingPointIndex=i;const n=e.createBuffer(),a=t.__size,r=t.usage;return e.bindBuffer(e.UNIFORM_BUFFER,n),e.bufferData(e.UNIFORM_BUFFER,a,r),e.bindBuffer(e.UNIFORM_BUFFER,null),e.bindBufferBase(e.UNIFORM_BUFFER,i,n),n}(i),a[i.id]=d,i.addEventListener("dispose",c));const p=u.program;n.updateUBOMapping(i,p);const m=t.render.frame;r[i.id]!==m&&(function(t){const i=a[t.id],n=t.uniforms,r=t.__cache;e.bindBuffer(e.UNIFORM_BUFFER,i);for(let t=0,i=n.length;t<i;t++){const i=Array.isArray(n[t])?n[t]:[n[t]];for(let n=0,a=i.length;n<a;n++){const a=i[n];if(!0===l(a,t,n,r)){const t=a.__offset,i=Array.isArray(a.value)?a.value:[a.value];let n=0;for(let r=0;r<i.length;r++){const s=i[r],o=h(s);"number"==typeof s||"boolean"==typeof s?(a.__data[0]=s,e.bufferSubData(e.UNIFORM_BUFFER,t+n,a.__data)):s.isMatrix3?(a.__data[0]=s.elements[0],a.__data[1]=s.elements[1],a.__data[2]=s.elements[2],a.__data[3]=0,a.__data[4]=s.elements[3],a.__data[5]=s.elements[4],a.__data[6]=s.elements[5],a.__data[7]=0,a.__data[8]=s.elements[6],a.__data[9]=s.elements[7],a.__data[10]=s.elements[8],a.__data[11]=0):(s.toArray(a.__data,n),n+=o.storage/Float32Array.BYTES_PER_ELEMENT)}e.bufferSubData(e.UNIFORM_BUFFER,t,a.__data)}}}e.bindBuffer(e.UNIFORM_BUFFER,null)}(i),r[i.id]=m)},dispose:function(){for(const t in a)e.deleteBuffer(a[t]);s=[],a={},r={}}}}const Ll=new Uint16Array([11481,15204,11534,15171,11808,15015,12385,14843,12894,14716,13396,14600,13693,14483,13976,14366,14237,14171,14405,13961,14511,13770,14605,13598,14687,13444,14760,13305,14822,13066,14876,12857,14923,12675,14963,12517,14997,12379,15025,12230,15049,12023,15070,11843,15086,11687,15100,11551,15111,11433,15120,11330,15127,11217,15132,11060,15135,10922,15138,10801,15139,10695,15139,10600,13012,14923,13020,14917,13064,14886,13176,14800,13349,14666,13513,14526,13724,14398,13960,14230,14200,14020,14383,13827,14488,13651,14583,13491,14667,13348,14740,13132,14803,12908,14856,12713,14901,12542,14938,12394,14968,12241,14992,12017,15010,11822,15024,11654,15034,11507,15041,11380,15044,11269,15044,11081,15042,10913,15037,10764,15031,10635,15023,10520,15014,10419,15003,10330,13657,14676,13658,14673,13670,14660,13698,14622,13750,14547,13834,14442,13956,14317,14112,14093,14291,13889,14407,13704,14499,13538,14586,13389,14664,13201,14733,12966,14792,12758,14842,12577,14882,12418,14915,12272,14940,12033,14959,11826,14972,11646,14980,11490,14983,11355,14983,11212,14979,11008,14971,10830,14961,10675,14950,10540,14936,10420,14923,10315,14909,10204,14894,10041,14089,14460,14090,14459,14096,14452,14112,14431,14141,14388,14186,14305,14252,14130,14341,13941,14399,13756,14467,13585,14539,13430,14610,13272,14677,13026,14737,12808,14790,12617,14833,12449,14869,12303,14896,12065,14916,11845,14929,11655,14937,11490,14939,11347,14936,11184,14930,10970,14921,10783,14912,10621,14900,10480,14885,10356,14867,10247,14848,10062,14827,9894,14805,9745,14400,14208,14400,14206,14402,14198,14406,14174,14415,14122,14427,14035,14444,13913,14469,13767,14504,13613,14548,13463,14598,13324,14651,13082,14704,12858,14752,12658,14795,12483,14831,12330,14860,12106,14881,11875,14895,11675,14903,11501,14905,11351,14903,11178,14900,10953,14892,10757,14880,10589,14865,10442,14847,10313,14827,10162,14805,9965,14782,9792,14757,9642,14731,9507,14562,13883,14562,13883,14563,13877,14566,13862,14570,13830,14576,13773,14584,13689,14595,13582,14613,13461,14637,13336,14668,13120,14704,12897,14741,12695,14776,12516,14808,12358,14835,12150,14856,11910,14870,11701,14878,11519,14882,11361,14884,11187,14880,10951,14871,10748,14858,10572,14842,10418,14823,10286,14801,10099,14777,9897,14751,9722,14725,9567,14696,9430,14666,9309,14702,13604,14702,13604,14702,13600,14703,13591,14705,13570,14707,13533,14709,13477,14712,13400,14718,13305,14727,13106,14743,12907,14762,12716,14784,12539,14807,12380,14827,12190,14844,11943,14855,11727,14863,11539,14870,11376,14871,11204,14868,10960,14858,10748,14845,10565,14829,10406,14809,10269,14786,10058,14761,9852,14734,9671,14705,9512,14674,9374,14641,9253,14608,9076,14821,13366,14821,13365,14821,13364,14821,13358,14821,13344,14821,13320,14819,13252,14817,13145,14815,13011,14814,12858,14817,12698,14823,12539,14832,12389,14841,12214,14850,11968,14856,11750,14861,11558,14866,11390,14867,11226,14862,10972,14853,10754,14840,10565,14823,10401,14803,10259,14780,10032,14754,9820,14725,9635,14694,9473,14661,9333,14627,9203,14593,8988,14557,8798,14923,13014,14922,13014,14922,13012,14922,13004,14920,12987,14919,12957,14915,12907,14909,12834,14902,12738,14894,12623,14888,12498,14883,12370,14880,12203,14878,11970,14875,11759,14873,11569,14874,11401,14872,11243,14865,10986,14855,10762,14842,10568,14825,10401,14804,10255,14781,10017,14754,9799,14725,9611,14692,9445,14658,9301,14623,9139,14587,8920,14548,8729,14509,8562,15008,12672,15008,12672,15008,12671,15007,12667,15005,12656,15001,12637,14997,12605,14989,12556,14978,12490,14966,12407,14953,12313,14940,12136,14927,11934,14914,11742,14903,11563,14896,11401,14889,11247,14879,10992,14866,10767,14851,10570,14833,10400,14812,10252,14789,10007,14761,9784,14731,9592,14698,9424,14663,9279,14627,9088,14588,8868,14548,8676,14508,8508,14467,8360,15080,12386,15080,12386,15079,12385,15078,12383,15076,12378,15072,12367,15066,12347,15057,12315,15045,12253,15030,12138,15012,11998,14993,11845,14972,11685,14951,11530,14935,11383,14920,11228,14904,10981,14887,10762,14870,10567,14850,10397,14827,10248,14803,9997,14774,9771,14743,9578,14710,9407,14674,9259,14637,9048,14596,8826,14555,8632,14514,8464,14471,8317,14427,8182,15139,12008,15139,12008,15138,12008,15137,12007,15135,12003,15130,11990,15124,11969,15115,11929,15102,11872,15086,11794,15064,11693,15041,11581,15013,11459,14987,11336,14966,11170,14944,10944,14921,10738,14898,10552,14875,10387,14850,10239,14824,9983,14794,9758,14762,9563,14728,9392,14692,9244,14653,9014,14611,8791,14569,8597,14526,8427,14481,8281,14436,8110,14391,7885,15188,11617,15188,11617,15187,11617,15186,11618,15183,11617,15179,11612,15173,11601,15163,11581,15150,11546,15133,11495,15110,11427,15083,11346,15051,11246,15024,11057,14996,10868,14967,10687,14938,10517,14911,10362,14882,10206,14853,9956,14821,9737,14787,9543,14752,9375,14715,9228,14675,8980,14632,8760,14589,8565,14544,8395,14498,8248,14451,8049,14404,7824,14357,7630,15228,11298,15228,11298,15227,11299,15226,11301,15223,11303,15219,11302,15213,11299,15204,11290,15191,11271,15174,11217,15150,11129,15119,11015,15087,10886,15057,10744,15024,10599,14990,10455,14957,10318,14924,10143,14891,9911,14856,9701,14820,9516,14782,9352,14744,9200,14703,8946,14659,8725,14615,8533,14568,8366,14521,8220,14472,7992,14423,7770,14374,7578,14315,7408,15260,10819,15260,10819,15259,10822,15258,10826,15256,10832,15251,10836,15246,10841,15237,10838,15225,10821,15207,10788,15183,10734,15151,10660,15120,10571,15087,10469,15049,10359,15012,10249,14974,10041,14937,9837,14900,9647,14860,9475,14820,9320,14779,9147,14736,8902,14691,8688,14646,8499,14598,8335,14549,8189,14499,7940,14448,7720,14397,7529,14347,7363,14256,7218,15285,10410,15285,10411,15285,10413,15284,10418,15282,10425,15278,10434,15272,10442,15264,10449,15252,10445,15235,10433,15210,10403,15179,10358,15149,10301,15113,10218,15073,10059,15033,9894,14991,9726,14951,9565,14909,9413,14865,9273,14822,9073,14777,8845,14730,8641,14682,8459,14633,8300,14583,8129,14531,7883,14479,7670,14426,7482,14373,7321,14305,7176,14201,6939,15305,9939,15305,9940,15305,9945,15304,9955,15302,9967,15298,9989,15293,10010,15286,10033,15274,10044,15258,10045,15233,10022,15205,9975,15174,9903,15136,9808,15095,9697,15053,9578,15009,9451,14965,9327,14918,9198,14871,8973,14825,8766,14775,8579,14725,8408,14675,8259,14622,8058,14569,7821,14515,7615,14460,7435,14405,7276,14350,7108,14256,6866,14149,6653,15321,9444,15321,9445,15321,9448,15320,9458,15317,9470,15314,9490,15310,9515,15302,9540,15292,9562,15276,9579,15251,9577,15226,9559,15195,9519,15156,9463,15116,9389,15071,9304,15025,9208,14978,9023,14927,8838,14878,8661,14827,8496,14774,8344,14722,8206,14667,7973,14612,7749,14556,7555,14499,7382,14443,7229,14385,7025,14322,6791,14210,6588,14100,6409,15333,8920,15333,8921,15332,8927,15332,8943,15329,8965,15326,9002,15322,9048,15316,9106,15307,9162,15291,9204,15267,9221,15244,9221,15212,9196,15175,9134,15133,9043,15088,8930,15040,8801,14990,8665,14938,8526,14886,8391,14830,8261,14775,8087,14719,7866,14661,7664,14603,7482,14544,7322,14485,7178,14426,6936,14367,6713,14281,6517,14166,6348,14054,6198,15341,8360,15341,8361,15341,8366,15341,8379,15339,8399,15336,8431,15332,8473,15326,8527,15318,8585,15302,8632,15281,8670,15258,8690,15227,8690,15191,8664,15149,8612,15104,8543,15055,8456,15001,8360,14948,8259,14892,8122,14834,7923,14776,7734,14716,7558,14656,7397,14595,7250,14534,7070,14472,6835,14410,6628,14350,6443,14243,6283,14125,6135,14010,5889,15348,7715,15348,7717,15348,7725,15347,7745,15345,7780,15343,7836,15339,7905,15334,8e3,15326,8103,15310,8193,15293,8239,15270,8270,15240,8287,15204,8283,15163,8260,15118,8223,15067,8143,15014,8014,14958,7873,14899,7723,14839,7573,14778,7430,14715,7293,14652,7164,14588,6931,14524,6720,14460,6531,14396,6362,14330,6210,14207,6015,14086,5781,13969,5576,15352,7114,15352,7116,15352,7128,15352,7159,15350,7195,15348,7237,15345,7299,15340,7374,15332,7457,15317,7544,15301,7633,15280,7703,15251,7754,15216,7775,15176,7767,15131,7733,15079,7670,15026,7588,14967,7492,14906,7387,14844,7278,14779,7171,14714,6965,14648,6770,14581,6587,14515,6420,14448,6269,14382,6123,14299,5881,14172,5665,14049,5477,13929,5310,15355,6329,15355,6330,15355,6339,15355,6362,15353,6410,15351,6472,15349,6572,15344,6688,15337,6835,15323,6985,15309,7142,15287,7220,15260,7277,15226,7310,15188,7326,15142,7318,15090,7285,15036,7239,14976,7177,14914,7045,14849,6892,14782,6736,14714,6581,14645,6433,14576,6293,14506,6164,14438,5946,14369,5733,14270,5540,14140,5369,14014,5216,13892,5043,15357,5483,15357,5484,15357,5496,15357,5528,15356,5597,15354,5692,15351,5835,15347,6011,15339,6195,15328,6317,15314,6446,15293,6566,15268,6668,15235,6746,15197,6796,15152,6811,15101,6790,15046,6748,14985,6673,14921,6583,14854,6479,14785,6371,14714,6259,14643,6149,14571,5946,14499,5750,14428,5567,14358,5401,14242,5250,14109,5111,13980,4870,13856,4657,15359,4555,15359,4557,15358,4573,15358,4633,15357,4715,15355,4841,15353,5061,15349,5216,15342,5391,15331,5577,15318,5770,15299,5967,15274,6150,15243,6223,15206,6280,15161,6310,15111,6317,15055,6300,14994,6262,14928,6208,14860,6141,14788,5994,14715,5838,14641,5684,14566,5529,14492,5384,14418,5247,14346,5121,14216,4892,14079,4682,13948,4496,13822,4330,15359,3498,15359,3501,15359,3520,15359,3598,15358,3719,15356,3860,15355,4137,15351,4305,15344,4563,15334,4809,15321,5116,15303,5273,15280,5418,15250,5547,15214,5653,15170,5722,15120,5761,15064,5763,15002,5733,14935,5673,14865,5597,14792,5504,14716,5400,14640,5294,14563,5185,14486,5041,14410,4841,14335,4655,14191,4482,14051,4325,13918,4183,13790,4012,15360,2282,15360,2285,15360,2306,15360,2401,15359,2547,15357,2748,15355,3103,15352,3349,15345,3675,15336,4020,15324,4272,15307,4496,15285,4716,15255,4908,15220,5086,15178,5170,15128,5214,15072,5234,15010,5231,14943,5206,14871,5166,14796,5102,14718,4971,14639,4833,14559,4687,14480,4541,14402,4401,14315,4268,14167,4142,14025,3958,13888,3747,13759,3556,15360,923,15360,925,15360,946,15360,1052,15359,1214,15357,1494,15356,1892,15352,2274,15346,2663,15338,3099,15326,3393,15309,3679,15288,3980,15260,4183,15226,4325,15185,4437,15136,4517,15080,4570,15018,4591,14950,4581,14877,4545,14800,4485,14720,4411,14638,4325,14556,4231,14475,4136,14395,3988,14297,3803,14145,3628,13999,3465,13861,3314,13729,3177,15360,263,15360,264,15360,272,15360,325,15359,407,15358,548,15356,780,15352,1144,15347,1580,15339,2099,15328,2425,15312,2795,15292,3133,15264,3329,15232,3517,15191,3689,15143,3819,15088,3923,15025,3978,14956,3999,14882,3979,14804,3931,14722,3855,14639,3756,14554,3645,14470,3529,14388,3409,14279,3289,14124,3173,13975,3055,13834,2848,13701,2658,15360,49,15360,49,15360,52,15360,75,15359,111,15358,201,15356,283,15353,519,15348,726,15340,1045,15329,1415,15314,1795,15295,2173,15269,2410,15237,2649,15197,2866,15150,3054,15095,3140,15032,3196,14963,3228,14888,3236,14808,3224,14725,3191,14639,3146,14553,3088,14466,2976,14382,2836,14262,2692,14103,2549,13952,2409,13808,2278,13674,2154,15360,4,15360,4,15360,4,15360,13,15359,33,15358,59,15357,112,15353,199,15348,302,15341,456,15331,628,15316,827,15297,1082,15272,1332,15241,1601,15202,1851,15156,2069,15101,2172,15039,2256,14970,2314,14894,2348,14813,2358,14728,2344,14640,2311,14551,2263,14463,2203,14376,2133,14247,2059,14084,1915,13930,1761,13784,1609,13648,1464,15360,0,15360,0,15360,0,15360,3,15359,18,15358,26,15357,53,15354,80,15348,97,15341,165,15332,238,15318,326,15299,427,15275,529,15245,654,15207,771,15161,885,15108,994,15046,1089,14976,1170,14900,1229,14817,1266,14731,1284,14641,1282,14550,1260,14460,1223,14370,1174,14232,1116,14066,1050,13909,981,13761,910,13623,839]);let Bl=null;class Ol{constructor(t={}){const{canvas:i=at(),context:n=null,depth:a=!0,stencil:r=!1,alpha:s=!1,antialias:o=!1,premultipliedAlpha:l=!0,preserveDrawingBuffer:h=!1,powerPreference:c="default",failIfMajorPerformanceCaveat:u=!1,reversedDepthBuffer:d=!1}=t;let p;if(this.isWebGLRenderer=!0,null!==n){if("undefined"!=typeof WebGLRenderingContext&&n instanceof WebGLRenderingContext)throw new Error("THREE.WebGLRenderer: WebGL 1 is not supported since r163.");p=n.getContextAttributes().alpha}else p=s;const m=new Set([ae,ne,te]),f=new Set([H,X,W,K,$,Z]),g=new Uint32Array(4),v=new Int32Array(4);let y=null,b=null;const M=[],_=[];this.domElement=i,this.debug={checkShaderErrors:!0,onShaderError:null},this.autoClear=!0,this.autoClearColor=!0,this.autoClearDepth=!0,this.autoClearStencil=!0,this.sortObjects=!0,this.clippingPlanes=[],this.localClippingEnabled=!1,this.toneMapping=0,this.toneMappingExposure=1,this.transmissionResolutionScale=1;const x=this;let S=!1;this._outputColorSpace=ze;let w=0,E=0,T=null,C=-1,A=null;const P=new Gt,D=new Gt;let R=null;const I=new dn(0);let L=0,B=i.width,F=i.height,U=1,z=null,k=null;const G=new Gt(0,0,B,F),j=new Gt(0,0,B,F);let q=!1;const Q=new Na;let J=!1,ee=!1;const re=new bi,se=new xt,oe=new Gt,le={background:null,fog:null,environment:null,overrideMaterial:null,isScene:!0};let he=!1;function ce(){return null===T?U:1}let ue,de,pe,me,fe,ge,ve,ye,be,Me,_e,xe,Se,we,Ee,Te,Ce,Ae,Pe,De,Re,Ie,Le,Be,Oe=n;function Fe(e,t){return i.getContext(e,t)}try{const t={alpha:!0,depth:a,stencil:r,antialias:o,premultipliedAlpha:l,preserveDrawingBuffer:h,powerPreference:c,failIfMajorPerformanceCaveat:u};if("setAttribute"in i&&i.setAttribute("data-engine",`three.js r${e}`),i.addEventListener("webglcontextlost",Ge,!1),i.addEventListener("webglcontextrestored",Ve,!1),i.addEventListener("webglcontextcreationerror",He,!1),null===Oe){const e="webgl2";if(Oe=Fe(e,t),null===Oe)throw Fe(e)?new Error("Error creating WebGL context with your selected attributes."):new Error("Error creating WebGL context.")}}catch(e){throw e("WebGLRenderer: "+e.message),e}function Ue(){ue=new Ds(Oe),ue.init(),Ie=new Tl(Oe,ue),de=new ps(Oe,ue,t,Ie),pe=new wl(Oe,ue),de.reversedDepthBuffer&&d&&pe.buffers.depth.setReversed(!0),me=new Ls(Oe),fe=new ul,ge=new El(Oe,ue,pe,fe,de,Ie,me),ve=new fs(x),ye=new Ps(x),be=new ns(Oe),Le=new us(Oe,be),Me=new Rs(Oe,be,me,Le),_e=new Os(Oe,Me,be,me),Pe=new Bs(Oe,de,ge),Te=new ms(fe),xe=new cl(x,ve,ye,ue,de,Le,Te),Se=new Rl(x,fe),we=new fl,Ee=new _l(ue),Ae=new cs(x,ve,ye,pe,_e,p,l),Ce=new xl(x,_e,de),Be=new Il(Oe,me,de,pe),De=new ds(Oe,ue,me),Re=new Is(Oe,ue,me),me.programs=xe.programs,x.capabilities=de,x.extensions=ue,x.properties=fe,x.renderLists=we,x.shadowMap=Ce,x.state=pe,x.info=me}Ue();const Ne=new Al(x,Oe);function Ge(e){e.preventDefault(),st("WebGLRenderer: Context Lost."),S=!0}function Ve(){st("WebGLRenderer: Context Restored."),S=!1;const e=me.autoReset,t=Ce.enabled,i=Ce.autoUpdate,n=Ce.needsUpdate,a=Ce.type;Ue(),me.autoReset=e,Ce.enabled=t,Ce.autoUpdate=i,Ce.needsUpdate=n,Ce.type=a}function He(e){lt("WebGLRenderer: A WebGL context could not be created. Reason: ",e.statusMessage)}function We(e){const t=e.target;t.removeEventListener("dispose",We),function(e){(function(e){const t=fe.get(e).programs;void 0!==t&&(t.forEach(function(e){xe.releaseProgram(e)}),e.isShaderMaterial&&xe.releaseShaderCache(e))})(e),fe.remove(e)}(t)}function je(e,t,i){!0===e.transparent&&2===e.side&&!1===e.forceSinglePass?(e.side=1,e.needsUpdate=!0,it(e,t,i),e.side=0,e.needsUpdate=!0,it(e,t,i),e.side=2):it(e,t,i)}this.xr=Ne,this.getContext=function(){return Oe},this.getContextAttributes=function(){return Oe.getContextAttributes()},this.forceContextLoss=function(){const e=ue.get("WEBGL_lose_context");e&&e.loseContext()},this.forceContextRestore=function(){const e=ue.get("WEBGL_lose_context");e&&e.restoreContext()},this.getPixelRatio=function(){return U},this.setPixelRatio=function(e){void 0!==e&&(U=e,this.setSize(B,F,!1))},this.getSize=function(e){return e.set(B,F)},this.setSize=function(e,t,n=!0){Ne.isPresenting?ot("WebGLRenderer: Can't change size while VR device is presenting."):(B=e,F=t,i.width=Math.floor(e*U),i.height=Math.floor(t*U),!0===n&&(i.style.width=e+"px",i.style.height=t+"px"),this.setViewport(0,0,e,t))},this.getDrawingBufferSize=function(e){return e.set(B*U,F*U).floor()},this.setDrawingBufferSize=function(e,t,n){B=e,F=t,U=n,i.width=Math.floor(e*n),i.height=Math.floor(t*n),this.setViewport(0,0,e,t)},this.getCurrentViewport=function(e){return e.copy(P)},this.getViewport=function(e){return e.copy(G)},this.setViewport=function(e,t,i,n){e.isVector4?G.set(e.x,e.y,e.z,e.w):G.set(e,t,i,n),pe.viewport(P.copy(G).multiplyScalar(U).round())},this.getScissor=function(e){return e.copy(j)},this.setScissor=function(e,t,i,n){e.isVector4?j.set(e.x,e.y,e.z,e.w):j.set(e,t,i,n),pe.scissor(D.copy(j).multiplyScalar(U).round())},this.getScissorTest=function(){return q},this.setScissorTest=function(e){pe.setScissorTest(q=e)},this.setOpaqueSort=function(e){z=e},this.setTransparentSort=function(e){k=e},this.getClearColor=function(e){return e.copy(Ae.getClearColor())},this.setClearColor=function(){Ae.setClearColor(...arguments)},this.getClearAlpha=function(){return Ae.getClearAlpha()},this.setClearAlpha=function(){Ae.setClearAlpha(...arguments)},this.clear=function(e=!0,t=!0,i=!0){let n=0;if(e){let e=!1;if(null!==T){const t=T.texture.format;e=m.has(t)}if(e){const e=T.texture.type,t=f.has(e),i=Ae.getClearColor(),n=Ae.getClearAlpha(),a=i.r,r=i.g,s=i.b;t?(g[0]=a,g[1]=r,g[2]=s,g[3]=n,Oe.clearBufferuiv(Oe.COLOR,0,g)):(v[0]=a,v[1]=r,v[2]=s,v[3]=n,Oe.clearBufferiv(Oe.COLOR,0,v))}else n|=Oe.COLOR_BUFFER_BIT}t&&(n|=Oe.DEPTH_BUFFER_BIT),i&&(n|=Oe.STENCIL_BUFFER_BIT,this.state.buffers.stencil.setMask(4294967295)),Oe.clear(n)},this.clearColor=function(){this.clear(!0,!1,!1)},this.clearDepth=function(){this.clear(!1,!0,!1)},this.clearStencil=function(){this.clear(!1,!1,!0)},this.dispose=function(){i.removeEventListener("webglcontextlost",Ge,!1),i.removeEventListener("webglcontextrestored",Ve,!1),i.removeEventListener("webglcontextcreationerror",He,!1),Ae.dispose(),we.dispose(),Ee.dispose(),fe.dispose(),ve.dispose(),ye.dispose(),_e.dispose(),Le.dispose(),Be.dispose(),xe.dispose(),Ne.dispose(),Ne.removeEventListener("sessionstart",qe),Ne.removeEventListener("sessionend",Ye),$e.stop()},this.renderBufferDirect=function(e,t,i,n,a,r){null===t&&(t=le);const s=a.isMesh&&a.matrixWorld.determinant()<0,o=function(e,t,i,n,a){!0!==t.isScene&&(t=le),ge.resetTextureUnits();const r=t.fog,s=n.isMeshStandardMaterial?t.environment:null,o=null===T?x.outputColorSpace:!0===T.isXRRenderTarget?T.texture.colorSpace:ke,l=(n.isMeshStandardMaterial?ye:ve).get(n.envMap||s),h=!0===n.vertexColors&&!!i.attributes.color&&4===i.attributes.color.itemSize,c=!!i.attributes.tangent&&(!!n.normalMap||n.anisotropy>0),u=!!i.morphAttributes.position,d=!!i.morphAttributes.normal,p=!!i.morphAttributes.color;let m=0;n.toneMapped&&(null!==T&&!0!==T.isXRRenderTarget||(m=x.toneMapping));const f=i.morphAttributes.position||i.morphAttributes.normal||i.morphAttributes.color,g=void 0!==f?f.length:0,v=fe.get(n),y=b.state.lights;if(!0===J&&(!0===ee||e!==A)){const t=e===A&&n.id===C;Te.setState(n,e,t)}let M=!1;n.version===v.__version?v.needsLights&&v.lightsStateVersion!==y.state.version||v.outputColorSpace!==o||a.isBatchedMesh&&!1===v.batching?M=!0:a.isBatchedMesh||!0!==v.batching?a.isBatchedMesh&&!0===v.batchingColor&&null===a.colorTexture||a.isBatchedMesh&&!1===v.batchingColor&&null!==a.colorTexture||a.isInstancedMesh&&!1===v.instancing?M=!0:a.isInstancedMesh||!0!==v.instancing?a.isSkinnedMesh&&!1===v.skinning?M=!0:a.isSkinnedMesh||!0!==v.skinning?a.isInstancedMesh&&!0===v.instancingColor&&null===a.instanceColor||a.isInstancedMesh&&!1===v.instancingColor&&null!==a.instanceColor||a.isInstancedMesh&&!0===v.instancingMorph&&null===a.morphTexture||a.isInstancedMesh&&!1===v.instancingMorph&&null!==a.morphTexture||v.envMap!==l||!0===n.fog&&v.fog!==r?M=!0:void 0===v.numClippingPlanes||v.numClippingPlanes===Te.numPlanes&&v.numIntersection===Te.numIntersection?(v.vertexAlphas!==h||v.vertexTangents!==c||v.morphTargets!==u||v.morphNormals!==d||v.morphColors!==p||v.toneMapping!==m||v.morphTargetsCount!==g)&&(M=!0):M=!0:M=!0:M=!0:M=!0:(M=!0,v.__version=n.version);let _=v.currentProgram;!0===M&&(_=it(n,t,a));let S=!1,w=!1,E=!1;const P=_.getUniforms(),D=v.uniforms;if(pe.useProgram(_.program)&&(S=!0,w=!0,E=!0),n.id!==C&&(C=n.id,w=!0),S||A!==e){pe.buffers.depth.getReversed()&&!0!==e.reversedDepth&&(e._reversedDepth=!0,e.updateProjectionMatrix()),P.setValue(Oe,"projectionMatrix",e.projectionMatrix),P.setValue(Oe,"viewMatrix",e.matrixWorldInverse);const t=P.map.cameraPosition;void 0!==t&&t.setValue(Oe,se.setFromMatrixPosition(e.matrixWorld)),de.logarithmicDepthBuffer&&P.setValue(Oe,"logDepthBufFC",2/(Math.log(e.far+1)/Math.LN2)),(n.isMeshPhongMaterial||n.isMeshToonMaterial||n.isMeshLambertMaterial||n.isMeshBasicMaterial||n.isMeshStandardMaterial||n.isShaderMaterial)&&P.setValue(Oe,"isOrthographic",!0===e.isOrthographicCamera),A!==e&&(A=e,w=!0,E=!0)}if(a.isSkinnedMesh){P.setOptional(Oe,a,"bindMatrix"),P.setOptional(Oe,a,"bindMatrixInverse");const e=a.skeleton;e&&(null===e.boneTexture&&e.computeBoneTexture(),P.setValue(Oe,"boneTexture",e.boneTexture,ge))}a.isBatchedMesh&&(P.setOptional(Oe,a,"batchingTexture"),P.setValue(Oe,"batchingTexture",a._matricesTexture,ge),P.setOptional(Oe,a,"batchingIdTexture"),P.setValue(Oe,"batchingIdTexture",a._indirectTexture,ge),P.setOptional(Oe,a,"batchingColorTexture"),null!==a._colorsTexture&&P.setValue(Oe,"batchingColorTexture",a._colorsTexture,ge));const R=i.morphAttributes;var I,L;if(void 0===R.position&&void 0===R.normal&&void 0===R.color||Pe.update(a,i,_),(w||v.receiveShadow!==a.receiveShadow)&&(v.receiveShadow=a.receiveShadow,P.setValue(Oe,"receiveShadow",a.receiveShadow)),n.isMeshGouraudMaterial&&null!==n.envMap&&(D.envMap.value=l,D.flipEnvMap.value=l.isCubeTexture&&!1===l.isRenderTargetTexture?-1:1),n.isMeshStandardMaterial&&null===n.envMap&&null!==t.environment&&(D.envMapIntensity.value=t.environmentIntensity),void 0!==D.dfgLUT&&(D.dfgLUT.value=(null===Bl&&(Bl=new Ia(Ll,32,32,ie,Y),Bl.minFilter=N,Bl.magFilter=N,Bl.wrapS=O,Bl.wrapT=O,Bl.generateMipmaps=!1,Bl.needsUpdate=!0),Bl)),w&&(P.setValue(Oe,"toneMappingExposure",x.toneMappingExposure),v.needsLights&&(L=E,(I=D).ambientLightColor.needsUpdate=L,I.lightProbe.needsUpdate=L,I.directionalLights.needsUpdate=L,I.directionalLightShadows.needsUpdate=L,I.pointLights.needsUpdate=L,I.pointLightShadows.needsUpdate=L,I.spotLights.needsUpdate=L,I.spotLightShadows.needsUpdate=L,I.rectAreaLights.needsUpdate=L,I.hemisphereLights.needsUpdate=L),r&&!0===n.fog&&Se.refreshFogUniforms(D,r),Se.refreshMaterialUniforms(D,n,U,F,b.state.transmissionRenderTarget[e.id]),Go.upload(Oe,nt(v),D,ge)),n.isShaderMaterial&&!0===n.uniformsNeedUpdate&&(Go.upload(Oe,nt(v),D,ge),n.uniformsNeedUpdate=!1),n.isSpriteMaterial&&P.setValue(Oe,"center",a.center),P.setValue(Oe,"modelViewMatrix",a.modelViewMatrix),P.setValue(Oe,"normalMatrix",a.normalMatrix),P.setValue(Oe,"modelMatrix",a.matrixWorld),n.isShaderMaterial||n.isRawShaderMaterial){const e=n.uniformsGroups;for(let t=0,i=e.length;t<i;t++){const i=e[t];Be.update(i,_),Be.bind(i,_)}}return _}(e,t,i,n,a);pe.setMaterial(n,s);let l=i.index,h=1;if(!0===n.wireframe){if(l=Me.getWireframeAttribute(i),void 0===l)return;h=2}const c=i.drawRange,u=i.attributes.position;let d=c.start*h,p=(c.start+c.count)*h;null!==r&&(d=Math.max(d,r.start*h),p=Math.min(p,(r.start+r.count)*h)),null!==l?(d=Math.max(d,0),p=Math.min(p,l.count)):null!=u&&(d=Math.max(d,0),p=Math.min(p,u.count));const m=p-d;if(m<0||m===1/0)return;let f;Le.setup(a,n,o,i,l);let g=De;if(null!==l&&(f=be.get(l),g=Re,g.setIndex(f)),a.isMesh)!0===n.wireframe?(pe.setLineWidth(n.wireframeLinewidth*ce()),g.setMode(Oe.LINES)):g.setMode(Oe.TRIANGLES);else if(a.isLine){let e=n.linewidth;void 0===e&&(e=1),pe.setLineWidth(e*ce()),a.isLineSegments?g.setMode(Oe.LINES):a.isLineLoop?g.setMode(Oe.LINE_LOOP):g.setMode(Oe.LINE_STRIP)}else a.isPoints?g.setMode(Oe.POINTS):a.isSprite&&g.setMode(Oe.TRIANGLES);if(a.isBatchedMesh)if(null!==a._multiDrawInstances)ht("WebGLRenderer: renderMultiDrawInstances has been deprecated and will be removed in r184. Append to renderMultiDraw arguments and use indirection."),g.renderMultiDrawInstances(a._multiDrawStarts,a._multiDrawCounts,a._multiDrawCount,a._multiDrawInstances);else if(ue.get("WEBGL_multi_draw"))g.renderMultiDraw(a._multiDrawStarts,a._multiDrawCounts,a._multiDrawCount);else{const e=a._multiDrawStarts,t=a._multiDrawCounts,i=a._multiDrawCount,r=l?be.get(l).bytesPerElement:1,s=fe.get(n).currentProgram.getUniforms();for(let n=0;n<i;n++)s.setValue(Oe,"_gl_DrawID",n),g.render(e[n]/r,t[n])}else if(a.isInstancedMesh)g.renderInstances(d,m,a.count);else if(i.isInstancedBufferGeometry){const e=void 0!==i._maxInstanceCount?i._maxInstanceCount:1/0,t=Math.min(i.instanceCount,e);g.renderInstances(d,m,t)}else g.render(d,m)},this.compile=function(e,t,i=null){null===i&&(i=e),b=Ee.get(i),b.init(t),_.push(b),i.traverseVisible(function(e){e.isLight&&e.layers.test(t.layers)&&(b.pushLight(e),e.castShadow&&b.pushShadow(e))}),e!==i&&e.traverseVisible(function(e){e.isLight&&e.layers.test(t.layers)&&(b.pushLight(e),e.castShadow&&b.pushShadow(e))}),b.setupLights();const n=new Set;return e.traverse(function(e){if(!(e.isMesh||e.isPoints||e.isLine||e.isSprite))return;const t=e.material;if(t)if(Array.isArray(t))for(let a=0;a<t.length;a++){const r=t[a];je(r,i,e),n.add(r)}else je(t,i,e),n.add(t)}),b=_.pop(),n},this.compileAsync=function(e,t,i=null){const n=this.compile(e,t,i);return new Promise(t=>{function i(){n.forEach(function(e){fe.get(e).currentProgram.isReady()&&n.delete(e)}),0!==n.size?setTimeout(i,10):t(e)}null!==ue.get("KHR_parallel_shader_compile")?i():setTimeout(i,10)})};let Xe=null;function qe(){$e.stop()}function Ye(){$e.start()}const $e=new is;function Ze(e,t,i,n){if(!1===e.visible)return;if(e.layers.test(t.layers))if(e.isGroup)i=e.renderOrder;else if(e.isLOD)!0===e.autoUpdate&&e.update(t);else if(e.isLight)b.pushLight(e),e.castShadow&&b.pushShadow(e);else if(e.isSprite){if(!e.frustumCulled||Q.intersectsSprite(e)){n&&oe.setFromMatrixPosition(e.matrixWorld).applyMatrix4(re);const t=_e.update(e),a=e.material;a.visible&&y.push(e,t,a,i,oe.z,null)}}else if((e.isMesh||e.isLine||e.isPoints)&&(!e.frustumCulled||Q.intersectsObject(e))){const t=_e.update(e),a=e.material;if(n&&(void 0!==e.boundingSphere?(null===e.boundingSphere&&e.computeBoundingSphere(),oe.copy(e.boundingSphere.center)):(null===t.boundingSphere&&t.computeBoundingSphere(),oe.copy(t.boundingSphere.center)),oe.applyMatrix4(e.matrixWorld).applyMatrix4(re)),Array.isArray(a)){const n=t.groups;for(let r=0,s=n.length;r<s;r++){const s=n[r],o=a[s.materialIndex];o&&o.visible&&y.push(e,t,o,i,oe.z,s)}}else a.visible&&y.push(e,t,a,i,oe.z,null)}const a=e.children;for(let e=0,r=a.length;e<r;e++)Ze(a[e],t,i,n)}function Ke(e,t,i,n){const{opaque:a,transmissive:r,transparent:s}=e;b.setupLightsView(i),!0===J&&Te.setGlobalState(x.clippingPlanes,i),n&&pe.viewport(P.copy(n)),a.length>0&&Je(a,t,i),r.length>0&&Je(r,t,i),s.length>0&&Je(s,t,i),pe.buffers.depth.setTest(!0),pe.buffers.depth.setMask(!0),pe.buffers.color.setMask(!0),pe.setPolygonOffset(!1)}function Qe(e,t,i,n){if(null!==(!0===i.isScene?i.overrideMaterial:null))return;void 0===b.state.transmissionRenderTarget[n.id]&&(b.state.transmissionRenderTarget[n.id]=new Ht(1,1,{generateMipmaps:!0,type:ue.has("EXT_color_buffer_half_float")||ue.has("EXT_color_buffer_float")?Y:H,minFilter:V,samples:4,stencilBuffer:r,resolveDepthBuffer:!1,resolveStencilBuffer:!1,colorSpace:Dt.workingColorSpace}));const a=b.state.transmissionRenderTarget[n.id],s=n.viewport||P;a.setSize(s.z*x.transmissionResolutionScale,s.w*x.transmissionResolutionScale);const o=x.getRenderTarget(),l=x.getActiveCubeFace(),h=x.getActiveMipmapLevel();x.setRenderTarget(a),x.getClearColor(I),L=x.getClearAlpha(),L<1&&x.setClearColor(16777215,.5),x.clear(),he&&Ae.render(i);const c=x.toneMapping;x.toneMapping=0;const u=n.viewport;if(void 0!==n.viewport&&(n.viewport=void 0),b.setupLightsView(n),!0===J&&Te.setGlobalState(x.clippingPlanes,n),Je(e,i,n),ge.updateMultisampleRenderTarget(a),ge.updateRenderTargetMipmap(a),!1===ue.has("WEBGL_multisampled_render_to_texture")){let e=!1;for(let a=0,r=t.length;a<r;a++){const r=t[a],{object:s,geometry:o,material:l,group:h}=r;if(2===l.side&&s.layers.test(n.layers)){const t=l.side;l.side=1,l.needsUpdate=!0,tt(s,i,n,o,l,h),l.side=t,l.needsUpdate=!0,e=!0}}!0===e&&(ge.updateMultisampleRenderTarget(a),ge.updateRenderTargetMipmap(a))}x.setRenderTarget(o,l,h),x.setClearColor(I,L),void 0!==u&&(n.viewport=u),x.toneMapping=c}function Je(e,t,i){const n=!0===t.isScene?t.overrideMaterial:null;for(let a=0,r=e.length;a<r;a++){const r=e[a],{object:s,geometry:o,group:l}=r;let h=r.material;!0===h.allowOverride&&null!==n&&(h=n),s.layers.test(i.layers)&&tt(s,t,i,o,h,l)}}function tt(e,t,i,n,a,r){e.onBeforeRender(x,t,i,n,a,r),e.modelViewMatrix.multiplyMatrices(i.matrixWorldInverse,e.matrixWorld),e.normalMatrix.getNormalMatrix(e.modelViewMatrix),a.onBeforeRender(x,t,i,n,e,r),!0===a.transparent&&2===a.side&&!1===a.forceSinglePass?(a.side=1,a.needsUpdate=!0,x.renderBufferDirect(i,t,n,a,e,r),a.side=0,a.needsUpdate=!0,x.renderBufferDirect(i,t,n,a,e,r),a.side=2):x.renderBufferDirect(i,t,n,a,e,r),e.onAfterRender(x,t,i,n,a,r)}function it(e,t,i){!0!==t.isScene&&(t=le);const n=fe.get(e),a=b.state.lights,r=b.state.shadowsArray,s=a.state.version,o=xe.getParameters(e,a.state,r,t,i),l=xe.getProgramCacheKey(o);let h=n.programs;n.environment=e.isMeshStandardMaterial?t.environment:null,n.fog=t.fog,n.envMap=(e.isMeshStandardMaterial?ye:ve).get(e.envMap||n.environment),n.envMapRotation=null!==n.environment&&null===e.envMap?t.environmentRotation:e.envMapRotation,void 0===h&&(e.addEventListener("dispose",We),h=new Map,n.programs=h);let c=h.get(l);if(void 0!==c){if(n.currentProgram===c&&n.lightsStateVersion===s)return rt(e,o),c}else o.uniforms=xe.getUniforms(e),e.onBeforeCompile(o,x),c=xe.acquireProgram(o,l),h.set(l,c),n.uniforms=o.uniforms;const u=n.uniforms;return(e.isShaderMaterial||e.isRawShaderMaterial)&&!0!==e.clipping||(u.clippingPlanes=Te.uniform),rt(e,o),n.needsLights=function(e){return e.isMeshLambertMaterial||e.isMeshToonMaterial||e.isMeshPhongMaterial||e.isMeshStandardMaterial||e.isShadowMaterial||e.isShaderMaterial&&!0===e.lights}(e),n.lightsStateVersion=s,n.needsLights&&(u.ambientLightColor.value=a.state.ambient,u.lightProbe.value=a.state.probe,u.directionalLights.value=a.state.directional,u.directionalLightShadows.value=a.state.directionalShadow,u.spotLights.value=a.state.spot,u.spotLightShadows.value=a.state.spotShadow,u.rectAreaLights.value=a.state.rectArea,u.ltc_1.value=a.state.rectAreaLTC1,u.ltc_2.value=a.state.rectAreaLTC2,u.pointLights.value=a.state.point,u.pointLightShadows.value=a.state.pointShadow,u.hemisphereLights.value=a.state.hemi,u.directionalShadowMap.value=a.state.directionalShadowMap,u.directionalShadowMatrix.value=a.state.directionalShadowMatrix,u.spotShadowMap.value=a.state.spotShadowMap,u.spotLightMatrix.value=a.state.spotLightMatrix,u.spotLightMap.value=a.state.spotLightMap,u.pointShadowMap.value=a.state.pointShadowMap,u.pointShadowMatrix.value=a.state.pointShadowMatrix),n.currentProgram=c,n.uniformsList=null,c}function nt(e){if(null===e.uniformsList){const t=e.currentProgram.getUniforms();e.uniformsList=Go.seqWithValue(t.seq,e.uniforms)}return e.uniformsList}function rt(e,t){const i=fe.get(e);i.outputColorSpace=t.outputColorSpace,i.batching=t.batching,i.batchingColor=t.batchingColor,i.instancing=t.instancing,i.instancingColor=t.instancingColor,i.instancingMorph=t.instancingMorph,i.skinning=t.skinning,i.morphTargets=t.morphTargets,i.morphNormals=t.morphNormals,i.morphColors=t.morphColors,i.morphTargetsCount=t.morphTargetsCount,i.numClippingPlanes=t.numClippingPlanes,i.numIntersection=t.numClipIntersection,i.vertexAlphas=t.vertexAlphas,i.vertexTangents=t.vertexTangents,i.toneMapping=t.toneMapping}$e.setAnimationLoop(function(e){Xe&&Xe(e)}),"undefined"!=typeof self&&$e.setContext(self),this.setAnimationLoop=function(e){Xe=e,Ne.setAnimationLoop(e),null===e?$e.stop():$e.start()},Ne.addEventListener("sessionstart",qe),Ne.addEventListener("sessionend",Ye),this.render=function(e,t){if(void 0!==t&&!0!==t.isCamera)return void lt("WebGLRenderer.render: camera is not an instance of THREE.Camera.");if(!0===S)return;if(!0===e.matrixWorldAutoUpdate&&e.updateMatrixWorld(),null===t.parent&&!0===t.matrixWorldAutoUpdate&&t.updateMatrixWorld(),!0===Ne.enabled&&!0===Ne.isPresenting&&(!0===Ne.cameraAutoUpdate&&Ne.updateCamera(t),t=Ne.getCamera()),!0===e.isScene&&e.onBeforeRender(x,e,t,T),b=Ee.get(e,_.length),b.init(t),_.push(b),re.multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse),Q.setFromProjectionMatrix(re,et,t.reversedDepth),ee=this.localClippingEnabled,J=Te.init(this.clippingPlanes,ee),y=we.get(e,M.length),y.init(),M.push(y),!0===Ne.enabled&&!0===Ne.isPresenting){const e=x.xr.getDepthSensingMesh();null!==e&&Ze(e,t,-1/0,x.sortObjects)}Ze(e,t,0,x.sortObjects),y.finish(),!0===x.sortObjects&&y.sort(z,k),he=!1===Ne.enabled||!1===Ne.isPresenting||!1===Ne.hasDepthSensing(),he&&Ae.addToRenderList(y,e),this.info.render.frame++,!0===J&&Te.beginShadows();const i=b.state.shadowsArray;Ce.render(i,e,t),!0===J&&Te.endShadows(),!0===this.info.autoReset&&this.info.reset();const n=y.opaque,a=y.transmissive;if(b.setupLights(),t.isArrayCamera){const i=t.cameras;if(a.length>0)for(let t=0,r=i.length;t<r;t++)Qe(n,a,e,i[t]);he&&Ae.render(e);for(let t=0,n=i.length;t<n;t++){const n=i[t];Ke(y,e,n,n.viewport)}}else a.length>0&&Qe(n,a,e,t),he&&Ae.render(e),Ke(y,e,t);null!==T&&0===E&&(ge.updateMultisampleRenderTarget(T),ge.updateRenderTargetMipmap(T)),!0===e.isScene&&e.onAfterRender(x,e,t),Le.resetDefaultState(),C=-1,A=null,_.pop(),_.length>0?(b=_[_.length-1],!0===J&&Te.setGlobalState(x.clippingPlanes,b.state.camera)):b=null,M.pop(),y=M.length>0?M[M.length-1]:null},this.getActiveCubeFace=function(){return w},this.getActiveMipmapLevel=function(){return E},this.getRenderTarget=function(){return T},this.setRenderTargetTextures=function(e,t,i){const n=fe.get(e);n.__autoAllocateDepthBuffer=!1===e.resolveDepthBuffer,!1===n.__autoAllocateDepthBuffer&&(n.__useRenderToTexture=!1),fe.get(e.texture).__webglTexture=t,fe.get(e.depthTexture).__webglTexture=n.__autoAllocateDepthBuffer?void 0:i,n.__hasExternalTextures=!0},this.setRenderTargetFramebuffer=function(e,t){const i=fe.get(e);i.__webglFramebuffer=t,i.__useDefaultFramebuffer=void 0===t};const ct=Oe.createFramebuffer();this.setRenderTarget=function(e,t=0,i=0){T=e,w=t,E=i;let n=!0,a=null,r=!1,s=!1;if(e){const o=fe.get(e);if(void 0!==o.__useDefaultFramebuffer)pe.bindFramebuffer(Oe.FRAMEBUFFER,null),n=!1;else if(void 0===o.__webglFramebuffer)ge.setupRenderTarget(e);else if(o.__hasExternalTextures)ge.rebindTextures(e,fe.get(e.texture).__webglTexture,fe.get(e.depthTexture).__webglTexture);else if(e.depthBuffer){const t=e.depthTexture;if(o.__boundDepthTexture!==t){if(null!==t&&fe.has(t)&&(e.width!==t.image.width||e.height!==t.image.height))throw new Error("WebGLRenderTarget: Attached DepthTexture is initialized to the incorrect size.");ge.setupDepthRenderbuffer(e)}}const l=e.texture;(l.isData3DTexture||l.isDataArrayTexture||l.isCompressedArrayTexture)&&(s=!0);const h=fe.get(e).__webglFramebuffer;e.isWebGLCubeRenderTarget?(a=Array.isArray(h[t])?h[t][i]:h[t],r=!0):a=e.samples>0&&!1===ge.useMultisampledRTT(e)?fe.get(e).__webglMultisampledFramebuffer:Array.isArray(h)?h[i]:h,P.copy(e.viewport),D.copy(e.scissor),R=e.scissorTest}else P.copy(G).multiplyScalar(U).floor(),D.copy(j).multiplyScalar(U).floor(),R=q;if(0!==i&&(a=ct),pe.bindFramebuffer(Oe.FRAMEBUFFER,a)&&n&&pe.drawBuffers(e,a),pe.viewport(P),pe.scissor(D),pe.setScissorTest(R),r){const n=fe.get(e.texture);Oe.framebufferTexture2D(Oe.FRAMEBUFFER,Oe.COLOR_ATTACHMENT0,Oe.TEXTURE_CUBE_MAP_POSITIVE_X+t,n.__webglTexture,i)}else if(s){const n=t;for(let t=0;t<e.textures.length;t++){const a=fe.get(e.textures[t]);Oe.framebufferTextureLayer(Oe.FRAMEBUFFER,Oe.COLOR_ATTACHMENT0+t,a.__webglTexture,i,n)}}else if(null!==e&&0!==i){const t=fe.get(e.texture);Oe.framebufferTexture2D(Oe.FRAMEBUFFER,Oe.COLOR_ATTACHMENT0,Oe.TEXTURE_2D,t.__webglTexture,i)}C=-1},this.readRenderTargetPixels=function(e,t,i,n,a,r,s,o=0){if(!e||!e.isWebGLRenderTarget)return void lt("WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");let l=fe.get(e).__webglFramebuffer;if(e.isWebGLCubeRenderTarget&&void 0!==s&&(l=l[s]),l){pe.bindFramebuffer(Oe.FRAMEBUFFER,l);try{const s=e.textures[o],l=s.format,h=s.type;if(!de.textureFormatReadable(l))return void lt("WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.");if(!de.textureTypeReadable(h))return void lt("WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.");t>=0&&t<=e.width-n&&i>=0&&i<=e.height-a&&(e.textures.length>1&&Oe.readBuffer(Oe.COLOR_ATTACHMENT0+o),Oe.readPixels(t,i,n,a,Ie.convert(l),Ie.convert(h),r))}finally{const e=null!==T?fe.get(T).__webglFramebuffer:null;pe.bindFramebuffer(Oe.FRAMEBUFFER,e)}}},this.readRenderTargetPixelsAsync=async function(e,t,i,n,a,r,s,o=0){if(!e||!e.isWebGLRenderTarget)throw new Error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");let l=fe.get(e).__webglFramebuffer;if(e.isWebGLCubeRenderTarget&&void 0!==s&&(l=l[s]),l){if(t>=0&&t<=e.width-n&&i>=0&&i<=e.height-a){pe.bindFramebuffer(Oe.FRAMEBUFFER,l);const s=e.textures[o],h=s.format,c=s.type;if(!de.textureFormatReadable(h))throw new Error("THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in RGBA or implementation defined format.");if(!de.textureTypeReadable(c))throw new Error("THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in UnsignedByteType or implementation defined type.");const u=Oe.createBuffer();Oe.bindBuffer(Oe.PIXEL_PACK_BUFFER,u),Oe.bufferData(Oe.PIXEL_PACK_BUFFER,r.byteLength,Oe.STREAM_READ),e.textures.length>1&&Oe.readBuffer(Oe.COLOR_ATTACHMENT0+o),Oe.readPixels(t,i,n,a,Ie.convert(h),Ie.convert(c),0);const d=null!==T?fe.get(T).__webglFramebuffer:null;pe.bindFramebuffer(Oe.FRAMEBUFFER,d);const p=Oe.fenceSync(Oe.SYNC_GPU_COMMANDS_COMPLETE,0);return Oe.flush(),await function(e,t){return new Promise(function(i,n){setTimeout(function a(){switch(e.clientWaitSync(t,e.SYNC_FLUSH_COMMANDS_BIT,0)){case e.WAIT_FAILED:n();break;case e.TIMEOUT_EXPIRED:setTimeout(a,4);break;default:i()}},4)})}(Oe,p),Oe.bindBuffer(Oe.PIXEL_PACK_BUFFER,u),Oe.getBufferSubData(Oe.PIXEL_PACK_BUFFER,0,r),Oe.deleteBuffer(u),Oe.deleteSync(p),r}throw new Error("THREE.WebGLRenderer.readRenderTargetPixelsAsync: requested read bounds are out of range.")}},this.copyFramebufferToTexture=function(e,t=null,i=0){const n=Math.pow(2,-i),a=Math.floor(e.image.width*n),r=Math.floor(e.image.height*n),s=null!==t?t.x:0,o=null!==t?t.y:0;ge.setTexture2D(e,0),Oe.copyTexSubImage2D(Oe.TEXTURE_2D,i,0,0,s,o,a,r),pe.unbindTexture()};const ut=Oe.createFramebuffer(),dt=Oe.createFramebuffer();this.copyTextureToTexture=function(e,t,i=null,n=null,a=0,r=null){let s,o,l,h,c,u,d,p,m;null===r&&(0!==a?(ht("WebGLRenderer: copyTextureToTexture function signature has changed to support src and dst mipmap levels."),r=a,a=0):r=0);const f=e.isCompressedTexture?e.mipmaps[r]:e.image;if(null!==i)s=i.max.x-i.min.x,o=i.max.y-i.min.y,l=i.isBox3?i.max.z-i.min.z:1,h=i.min.x,c=i.min.y,u=i.isBox3?i.min.z:0;else{const t=Math.pow(2,-a);s=Math.floor(f.width*t),o=Math.floor(f.height*t),l=e.isDataArrayTexture?f.depth:e.isData3DTexture?Math.floor(f.depth*t):1,h=0,c=0,u=0}null!==n?(d=n.x,p=n.y,m=n.z):(d=0,p=0,m=0);const g=Ie.convert(t.format),v=Ie.convert(t.type);let y;t.isData3DTexture?(ge.setTexture3D(t,0),y=Oe.TEXTURE_3D):t.isDataArrayTexture||t.isCompressedArrayTexture?(ge.setTexture2DArray(t,0),y=Oe.TEXTURE_2D_ARRAY):(ge.setTexture2D(t,0),y=Oe.TEXTURE_2D),Oe.pixelStorei(Oe.UNPACK_FLIP_Y_WEBGL,t.flipY),Oe.pixelStorei(Oe.UNPACK_PREMULTIPLY_ALPHA_WEBGL,t.premultiplyAlpha),Oe.pixelStorei(Oe.UNPACK_ALIGNMENT,t.unpackAlignment);const b=Oe.getParameter(Oe.UNPACK_ROW_LENGTH),M=Oe.getParameter(Oe.UNPACK_IMAGE_HEIGHT),_=Oe.getParameter(Oe.UNPACK_SKIP_PIXELS),x=Oe.getParameter(Oe.UNPACK_SKIP_ROWS),S=Oe.getParameter(Oe.UNPACK_SKIP_IMAGES);Oe.pixelStorei(Oe.UNPACK_ROW_LENGTH,f.width),Oe.pixelStorei(Oe.UNPACK_IMAGE_HEIGHT,f.height),Oe.pixelStorei(Oe.UNPACK_SKIP_PIXELS,h),Oe.pixelStorei(Oe.UNPACK_SKIP_ROWS,c),Oe.pixelStorei(Oe.UNPACK_SKIP_IMAGES,u);const w=e.isDataArrayTexture||e.isData3DTexture,E=t.isDataArrayTexture||t.isData3DTexture;if(e.isDepthTexture){const i=fe.get(e),n=fe.get(t),f=fe.get(i.__renderTarget),g=fe.get(n.__renderTarget);pe.bindFramebuffer(Oe.READ_FRAMEBUFFER,f.__webglFramebuffer),pe.bindFramebuffer(Oe.DRAW_FRAMEBUFFER,g.__webglFramebuffer);for(let i=0;i<l;i++)w&&(Oe.framebufferTextureLayer(Oe.READ_FRAMEBUFFER,Oe.COLOR_ATTACHMENT0,fe.get(e).__webglTexture,a,u+i),Oe.framebufferTextureLayer(Oe.DRAW_FRAMEBUFFER,Oe.COLOR_ATTACHMENT0,fe.get(t).__webglTexture,r,m+i)),Oe.blitFramebuffer(h,c,s,o,d,p,s,o,Oe.DEPTH_BUFFER_BIT,Oe.NEAREST);pe.bindFramebuffer(Oe.READ_FRAMEBUFFER,null),pe.bindFramebuffer(Oe.DRAW_FRAMEBUFFER,null)}else if(0!==a||e.isRenderTargetTexture||fe.has(e)){const i=fe.get(e),n=fe.get(t);pe.bindFramebuffer(Oe.READ_FRAMEBUFFER,ut),pe.bindFramebuffer(Oe.DRAW_FRAMEBUFFER,dt);for(let e=0;e<l;e++)w?Oe.framebufferTextureLayer(Oe.READ_FRAMEBUFFER,Oe.COLOR_ATTACHMENT0,i.__webglTexture,a,u+e):Oe.framebufferTexture2D(Oe.READ_FRAMEBUFFER,Oe.COLOR_ATTACHMENT0,Oe.TEXTURE_2D,i.__webglTexture,a),E?Oe.framebufferTextureLayer(Oe.DRAW_FRAMEBUFFER,Oe.COLOR_ATTACHMENT0,n.__webglTexture,r,m+e):Oe.framebufferTexture2D(Oe.DRAW_FRAMEBUFFER,Oe.COLOR_ATTACHMENT0,Oe.TEXTURE_2D,n.__webglTexture,r),0!==a?Oe.blitFramebuffer(h,c,s,o,d,p,s,o,Oe.COLOR_BUFFER_BIT,Oe.NEAREST):E?Oe.copyTexSubImage3D(y,r,d,p,m+e,h,c,s,o):Oe.copyTexSubImage2D(y,r,d,p,h,c,s,o);pe.bindFramebuffer(Oe.READ_FRAMEBUFFER,null),pe.bindFramebuffer(Oe.DRAW_FRAMEBUFFER,null)}else E?e.isDataTexture||e.isData3DTexture?Oe.texSubImage3D(y,r,d,p,m,s,o,l,g,v,f.data):t.isCompressedArrayTexture?Oe.compressedTexSubImage3D(y,r,d,p,m,s,o,l,g,f.data):Oe.texSubImage3D(y,r,d,p,m,s,o,l,g,v,f):e.isDataTexture?Oe.texSubImage2D(Oe.TEXTURE_2D,r,d,p,s,o,g,v,f.data):e.isCompressedTexture?Oe.compressedTexSubImage2D(Oe.TEXTURE_2D,r,d,p,f.width,f.height,g,f.data):Oe.texSubImage2D(Oe.TEXTURE_2D,r,d,p,s,o,g,v,f);Oe.pixelStorei(Oe.UNPACK_ROW_LENGTH,b),Oe.pixelStorei(Oe.UNPACK_IMAGE_HEIGHT,M),Oe.pixelStorei(Oe.UNPACK_SKIP_PIXELS,_),Oe.pixelStorei(Oe.UNPACK_SKIP_ROWS,x),Oe.pixelStorei(Oe.UNPACK_SKIP_IMAGES,S),0===r&&t.generateMipmaps&&Oe.generateMipmap(y),pe.unbindTexture()},this.initRenderTarget=function(e){void 0===fe.get(e).__webglFramebuffer&&ge.setupRenderTarget(e)},this.initTexture=function(e){e.isCubeTexture?ge.setTextureCube(e,0):e.isData3DTexture?ge.setTexture3D(e,0):e.isDataArrayTexture||e.isCompressedArrayTexture?ge.setTexture2DArray(e,0):ge.setTexture2D(e,0),pe.unbindTexture()},this.resetState=function(){w=0,E=0,T=null,pe.reset(),Le.reset()},"undefined"!=typeof __THREE_DEVTOOLS__&&__THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("observe",{detail:this}))}get coordinateSystem(){return et}get outputColorSpace(){return this._outputColorSpace}set outputColorSpace(e){this._outputColorSpace=e;const t=this.getContext();t.drawingBufferColorSpace=Dt._getDrawingBufferColorSpace(e),t.unpackColorSpace=Dt._getUnpackColorSpace()}}const Fl={name:"CopyShader",uniforms:{tDiffuse:{value:null},opacity:{value:1}},vertexShader:"\n\n\t\tvarying vec2 vUv;\n\n\t\tvoid main() {\n\n\t\t\tvUv = uv;\n\t\t\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n\t\t}",fragmentShader:"\n\n\t\tuniform float opacity;\n\n\t\tuniform sampler2D tDiffuse;\n\n\t\tvarying vec2 vUv;\n\n\t\tvoid main() {\n\n\t\t\tvec4 texel = texture2D( tDiffuse, vUv );\n\t\t\tgl_FragColor = opacity * texel;\n\n\n\t\t}"};class Ul{constructor(){this.isPass=!0,this.enabled=!0,this.needsSwap=!0,this.clear=!1,this.renderToScreen=!1}setSize(){}render(){console.error("THREE.Pass: .render() must be implemented in derived pass.")}dispose(){}}const zl=new qr(-1,1,1,-1,0,1),kl=new class extends Bn{constructor(){super(),this.setAttribute("position",new Tn([-1,3,0,-1,-1,0,3,-1,0],3)),this.setAttribute("uv",new Tn([0,2,0,0,2,0],2))}};class Nl{constructor(e){this._mesh=new Xn(kl,e)}dispose(){this._mesh.geometry.dispose()}render(e){e.render(this._mesh,zl)}get material(){return this._mesh.material}set material(e){this._mesh.material=e}}class Gl extends Ul{constructor(e,t="tDiffuse"){super(),this.textureID=t,this.uniforms=null,this.material=null,e instanceof Jn?(this.uniforms=e.uniforms,this.material=e):e&&(this.uniforms=Qn.clone(e.uniforms),this.material=new Jn({name:void 0!==e.name?e.name:"unspecified",defines:Object.assign({},e.defines),uniforms:this.uniforms,vertexShader:e.vertexShader,fragmentShader:e.fragmentShader})),this._fsQuad=new Nl(this.material)}render(e,t,i){this.uniforms[this.textureID]&&(this.uniforms[this.textureID].value=i.texture),this._fsQuad.material=this.material,this.renderToScreen?(e.setRenderTarget(null),this._fsQuad.render(e)):(e.setRenderTarget(t),this.clear&&e.clear(e.autoClearColor,e.autoClearDepth,e.autoClearStencil),this._fsQuad.render(e))}dispose(){this.material.dispose(),this._fsQuad.dispose()}}class Vl extends Ul{constructor(e,t){super(),this.scene=e,this.camera=t,this.clear=!0,this.needsSwap=!1,this.inverse=!1}render(e,t,i){const n=e.getContext(),a=e.state;let r,s;a.buffers.color.setMask(!1),a.buffers.depth.setMask(!1),a.buffers.color.setLocked(!0),a.buffers.depth.setLocked(!0),this.inverse?(r=0,s=1):(r=1,s=0),a.buffers.stencil.setTest(!0),a.buffers.stencil.setOp(n.REPLACE,n.REPLACE,n.REPLACE),a.buffers.stencil.setFunc(n.ALWAYS,r,4294967295),a.buffers.stencil.setClear(s),a.buffers.stencil.setLocked(!0),e.setRenderTarget(i),this.clear&&e.clear(),e.render(this.scene,this.camera),e.setRenderTarget(t),this.clear&&e.clear(),e.render(this.scene,this.camera),a.buffers.color.setLocked(!1),a.buffers.depth.setLocked(!1),a.buffers.color.setMask(!0),a.buffers.depth.setMask(!0),a.buffers.stencil.setLocked(!1),a.buffers.stencil.setFunc(n.EQUAL,1,4294967295),a.buffers.stencil.setOp(n.KEEP,n.KEEP,n.KEEP),a.buffers.stencil.setLocked(!0)}}class Hl extends Ul{constructor(){super(),this.needsSwap=!1}render(e){e.state.buffers.stencil.setLocked(!1),e.state.buffers.stencil.setTest(!1)}}class Wl{constructor(e,t){if(this.renderer=e,this._pixelRatio=e.getPixelRatio(),void 0===t){const i=e.getSize(new Mt);this._width=i.width,this._height=i.height,(t=new Ht(this._width*this._pixelRatio,this._height*this._pixelRatio,{type:Y})).texture.name="EffectComposer.rt1"}else this._width=t.width,this._height=t.height;this.renderTarget1=t,this.renderTarget2=t.clone(),this.renderTarget2.texture.name="EffectComposer.rt2",this.writeBuffer=this.renderTarget1,this.readBuffer=this.renderTarget2,this.renderToScreen=!0,this.passes=[],this.copyPass=new Gl(Fl),this.copyPass.material.blending=0,this.clock=new Qr}swapBuffers(){const e=this.readBuffer;this.readBuffer=this.writeBuffer,this.writeBuffer=e}addPass(e){this.passes.push(e),e.setSize(this._width*this._pixelRatio,this._height*this._pixelRatio)}insertPass(e,t){this.passes.splice(t,0,e),e.setSize(this._width*this._pixelRatio,this._height*this._pixelRatio)}removePass(e){const t=this.passes.indexOf(e);-1!==t&&this.passes.splice(t,1)}isLastEnabledPass(e){for(let t=e+1;t<this.passes.length;t++)if(this.passes[t].enabled)return!1;return!0}render(e){void 0===e&&(e=this.clock.getDelta());const t=this.renderer.getRenderTarget();let i=!1;for(let t=0,n=this.passes.length;t<n;t++){const n=this.passes[t];if(!1!==n.enabled){if(n.renderToScreen=this.renderToScreen&&this.isLastEnabledPass(t),n.render(this.renderer,this.writeBuffer,this.readBuffer,e,i),n.needsSwap){if(i){const t=this.renderer.getContext(),i=this.renderer.state.buffers.stencil;i.setFunc(t.NOTEQUAL,1,4294967295),this.copyPass.render(this.renderer,this.writeBuffer,this.readBuffer,e),i.setFunc(t.EQUAL,1,4294967295)}this.swapBuffers()}void 0!==Vl&&(n instanceof Vl?i=!0:n instanceof Hl&&(i=!1))}}this.renderer.setRenderTarget(t)}reset(e){if(void 0===e){const t=this.renderer.getSize(new Mt);this._pixelRatio=this.renderer.getPixelRatio(),this._width=t.width,this._height=t.height,(e=this.renderTarget1.clone()).setSize(this._width*this._pixelRatio,this._height*this._pixelRatio)}this.renderTarget1.dispose(),this.renderTarget2.dispose(),this.renderTarget1=e,this.renderTarget2=e.clone(),this.writeBuffer=this.renderTarget1,this.readBuffer=this.renderTarget2}setSize(e,t){this._width=e,this._height=t;const i=this._width*this._pixelRatio,n=this._height*this._pixelRatio;this.renderTarget1.setSize(i,n),this.renderTarget2.setSize(i,n);for(let e=0;e<this.passes.length;e++)this.passes[e].setSize(i,n)}setPixelRatio(e){this._pixelRatio=e,this.setSize(this._width,this._height)}dispose(){this.renderTarget1.dispose(),this.renderTarget2.dispose(),this.copyPass.dispose()}}class jl extends Ul{constructor(e,t,i=null,n=null,a=null){super(),this.scene=e,this.camera=t,this.overrideMaterial=i,this.clearColor=n,this.clearAlpha=a,this.clear=!0,this.clearDepth=!1,this.needsSwap=!1,this._oldClearColor=new dn}render(e,t,i){const n=e.autoClear;let a,r;e.autoClear=!1,null!==this.overrideMaterial&&(r=this.scene.overrideMaterial,this.scene.overrideMaterial=this.overrideMaterial),null!==this.clearColor&&(e.getClearColor(this._oldClearColor),e.setClearColor(this.clearColor,e.getClearAlpha())),null!==this.clearAlpha&&(a=e.getClearAlpha(),e.setClearAlpha(this.clearAlpha)),1==this.clearDepth&&e.clearDepth(),e.setRenderTarget(this.renderToScreen?null:i),!0===this.clear&&e.clear(e.autoClearColor,e.autoClearDepth,e.autoClearStencil),e.render(this.scene,this.camera),null!==this.clearColor&&e.setClearColor(this._oldClearColor),null!==this.clearAlpha&&e.setClearAlpha(a),null!==this.overrideMaterial&&(this.scene.overrideMaterial=r),e.autoClear=n}}new Mt(.5,.5),new Mt(.5,.5);class Xl extends Ul{constructor(e,t,i,n){super(),this.strength=void 0!==t?t:1,this.radius=i,this.threshold=n,this.resolution=void 0!==e?new Mt(e.x,e.y):new Mt(256,256);const a={minFilter:N,magFilter:N,format:Q,type:Y};this.renderTargetsHorizontal=[],this.renderTargetsVertical=[],this.nMips=5;let r=Math.round(.75*this.resolution.x),s=Math.round(.75*this.resolution.y);this.renderTargetBright=new Ht(r,s,a),this.renderTargetBright.texture.name="UnrealBloomPassAlpha.bright",this.renderTargetBright.texture.generateMipmaps=!1;for(let e=0;e<this.nMips;e++){const t=new Ht(r,s,a);t.texture.name=`UnrealBloomPassAlpha.h${e}`,t.texture.generateMipmaps=!1,this.renderTargetsHorizontal.push(t);const i=new Ht(r,s,a);i.texture.name=`UnrealBloomPassAlpha.v${e}`,i.texture.generateMipmaps=!1,this.renderTargetsVertical.push(i),r=Math.round(r/2),s=Math.round(s/2)}this.highPassUniforms={tDiffuse:{value:null},luminosityThreshold:{value:n},smoothWidth:{value:.01}},this.materialHighPassFilter=new Jn({uniforms:this.highPassUniforms,vertexShader:"\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }",fragmentShader:"\n uniform sampler2D tDiffuse;\n uniform float luminosityThreshold;\n uniform float smoothWidth;\n varying vec2 vUv;\n\n void main() {\n vec4 texel = texture2D(tDiffuse, vUv);\n vec3 luma = vec3(0.299, 0.587, 0.114);\n float v = dot(texel.xyz, luma);\n float alpha = smoothstep(luminosityThreshold, luminosityThreshold + smoothWidth, v);\n\n // CRITICAL: Preserve original alpha, only filter by luminosity\n gl_FragColor = vec4(texel.rgb * alpha, texel.a);\n }"}),this.separableBlurMaterials=[];const o=[3,5,7,9,11];r=Math.round(.75*this.resolution.x),s=Math.round(.75*this.resolution.y);for(let e=0;e<this.nMips;e++)this.separableBlurMaterials.push(this.getSeperableBlurMaterial(o[e])),this.separableBlurMaterials[e].uniforms.texSize.value=new Mt(r,s),r=Math.round(r/2),s=Math.round(s/2);this.compositeMaterial=this.getCompositeMaterial(this.nMips),this.compositeMaterial.uniforms.blurTexture1.value=this.renderTargetsVertical[0].texture,this.compositeMaterial.uniforms.blurTexture2.value=this.renderTargetsVertical[1].texture,this.compositeMaterial.uniforms.blurTexture3.value=this.renderTargetsVertical[2].texture,this.compositeMaterial.uniforms.blurTexture4.value=this.renderTargetsVertical[3].texture,this.compositeMaterial.uniforms.blurTexture5.value=this.renderTargetsVertical[4].texture,this.compositeMaterial.uniforms.bloomStrength.value=t,this.compositeMaterial.uniforms.bloomRadius.value=.1,this.compositeMaterial.uniforms.bloomFactors.value=[1,.8,.6,.4,.2],this.bloomTintColors=[new xt(1,1,1),new xt(1,1,1),new xt(1,1,1),new xt(1,1,1),new xt(1,1,1)],this.compositeMaterial.uniforms.bloomTintColors.value=this.bloomTintColors,this.materialCopy=new Jn({uniforms:{tDiffuse:{value:null}},vertexShader:"\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }",fragmentShader:"\n uniform sampler2D tDiffuse;\n varying vec2 vUv;\n void main() {\n gl_FragColor = texture2D(tDiffuse, vUv);\n }",blending:2,depthTest:!1,depthWrite:!1,transparent:!0}),this.enabled=!0,this.needsSwap=!1,this._oldClearColor=new dn,this.oldClearAlpha=1,this.clearColor=new dn(0,0,0),this.basic=new gn({transparent:!0,depthTest:!1,depthWrite:!1}),this.fsQuad=new Nl(null)}dispose(){if(this.renderTargetsHorizontal)for(let e=0;e<this.renderTargetsHorizontal.length;e++)this.renderTargetsHorizontal[e]?.dispose();if(this.renderTargetsVertical)for(let e=0;e<this.renderTargetsVertical.length;e++)this.renderTargetsVertical[e]?.dispose();if(this.renderTargetBright?.dispose(),this.separableBlurMaterials)for(let e=0;e<this.separableBlurMaterials.length;e++)this.separableBlurMaterials[e]?.dispose();this.compositeMaterial?.dispose(),this.blendMaterial?.dispose(),this.basic?.dispose(),this.fsQuad?.dispose()}clearBloomBuffers(e){const t=e.getRenderTarget(),i=e.getClearColor(this._oldClearColor),n=e.getClearAlpha();e.setClearColor(0,0),e.setRenderTarget(this.renderTargetBright),e.clear();for(let t=0;t<this.renderTargetsHorizontal.length;t++)e.setRenderTarget(this.renderTargetsHorizontal[t]),e.clear();for(let t=0;t<this.renderTargetsVertical.length;t++)e.setRenderTarget(this.renderTargetsVertical[t]),e.clear();e.setRenderTarget(t),e.setClearColor(i,n)}setSize(e,t){let i=Math.round(.75*e),n=Math.round(.75*t);this.renderTargetBright.setSize(i,n);for(let e=0;e<this.nMips;e++)this.renderTargetsHorizontal[e].setSize(i,n),this.renderTargetsVertical[e].setSize(i,n),this.separableBlurMaterials[e].uniforms.texSize.value=new Mt(i,n),i=Math.round(i/2),n=Math.round(n/2)}render(e,t,i,n,a){e.getClearColor(this._oldClearColor),this.oldClearAlpha=e.getClearAlpha();const r=e.autoClear;e.autoClear=!1,e.setClearColor(this.clearColor,0),a&&e.state.buffers.stencil.setTest(!1),this.renderToScreen&&!this.skipBaseCopy&&(this.fsQuad.material=this.basic,this.basic.map=i.texture,e.setRenderTarget(null),this.fsQuad.render(e)),this.highPassUniforms.tDiffuse.value=i.texture,this.highPassUniforms.luminosityThreshold.value=this.threshold,this.fsQuad.material=this.materialHighPassFilter,e.setRenderTarget(this.renderTargetBright),e.clear(),this.fsQuad.render(e);let s=this.renderTargetBright;for(let t=0;t<this.nMips;t++)this.fsQuad.material=this.separableBlurMaterials[t],this.separableBlurMaterials[t].uniforms.colorTexture.value=s.texture,this.separableBlurMaterials[t].uniforms.direction.value=Xl.BlurDirectionX,e.setRenderTarget(this.renderTargetsHorizontal[t]),e.clear(),this.fsQuad.render(e),this.separableBlurMaterials[t].uniforms.colorTexture.value=this.renderTargetsHorizontal[t].texture,this.separableBlurMaterials[t].uniforms.direction.value=Xl.BlurDirectionY,e.setRenderTarget(this.renderTargetsVertical[t]),e.clear(),this.fsQuad.render(e),s=this.renderTargetsVertical[t];this.fsQuad.material=this.compositeMaterial,this.compositeMaterial.uniforms.bloomStrength.value=this.strength,this.compositeMaterial.uniforms.bloomRadius.value=this.radius,this.compositeMaterial.uniforms.bloomTintColors.value=this.bloomTintColors,e.setRenderTarget(this.renderTargetsHorizontal[0]),e.clear(),this.fsQuad.render(e),this.fsQuad.material=this.materialCopy,this.materialCopy.uniforms.tDiffuse.value=this.renderTargetsHorizontal[0].texture,a&&e.state.buffers.stencil.setTest(!0),this.renderToScreen?(e.setRenderTarget(null),this.fsQuad.render(e)):(e.setRenderTarget(i),this.fsQuad.render(e)),e.setClearColor(this._oldClearColor,this.oldClearAlpha),e.autoClear=r}getSeperableBlurMaterial(e){return new Jn({defines:{MAX_RADIUS:e},uniforms:{colorTexture:{value:null},texSize:{value:new Mt(.5,.5)},direction:{value:new Mt(.5,.5)},kernelRadius:{value:1}},vertexShader:"\n varying vec2 vUv;\n\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n }",fragmentShader:"\n #include <common>\n varying vec2 vUv;\n uniform sampler2D colorTexture;\n uniform vec2 texSize;\n uniform vec2 direction;\n uniform float kernelRadius;\n\n float gaussianPdf(in float x, in float sigma) {\n return 0.39894 * exp( -0.5 * x * x / ( sigma * sigma ) ) / sigma;\n }\n\n void main() {\n vec2 invSize = 1.0 / texSize;\n float sigma = kernelRadius / 2.0;\n float weightSum = gaussianPdf(0.0, sigma);\n\n // CRITICAL: Accumulate RGB and alpha SEPARATELY\n // Include center pixel for BOTH RGB and alpha\n vec4 centerPixel = texture2D(colorTexture, vUv);\n vec3 diffuseSum = centerPixel.rgb * weightSum;\n float alphaSum = centerPixel.a * weightSum;\n\n vec2 delta = direction * invSize * kernelRadius / float(MAX_RADIUS);\n\n for( int i = 1; i < MAX_RADIUS; i ++ ) {\n float x = kernelRadius * float(i) / float(MAX_RADIUS);\n float w = gaussianPdf(x, sigma);\n\n vec2 uvOffset = delta * float(i);\n vec4 sample1 = texture2D(colorTexture, vUv + uvOffset);\n vec4 sample2 = texture2D(colorTexture, vUv - uvOffset);\n\n // Accumulate RGB and alpha separately\n diffuseSum += (sample1.rgb + sample2.rgb) * w;\n alphaSum += (sample1.a + sample2.a) * w;\n weightSum += 2.0 * w;\n }\n\n // Output with separately normalized alpha\n gl_FragColor = vec4(diffuseSum / weightSum, alphaSum / weightSum);\n }"})}getCompositeMaterial(e){return new Jn({uniforms:{blurTexture1:{value:null},blurTexture2:{value:null},blurTexture3:{value:null},blurTexture4:{value:null},blurTexture5:{value:null},bloomStrength:{value:1},bloomFactors:{value:null},bloomTintColors:{value:null},bloomRadius:{value:0}},vertexShader:"\n varying vec2 vUv;\n\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n }",fragmentShader:"\n varying vec2 vUv;\n uniform sampler2D blurTexture1;\n uniform sampler2D blurTexture2;\n uniform sampler2D blurTexture3;\n uniform sampler2D blurTexture4;\n uniform sampler2D blurTexture5;\n uniform float bloomStrength;\n uniform float bloomRadius;\n uniform float bloomFactors[5];\n uniform vec3 bloomTintColors[5];\n\n float lerpBloomFactor(const in float factor) {\n float mirrorFactor = 1.2 - factor;\n return mix(factor, mirrorFactor, bloomRadius);\n }\n\n void main() {\n // ALPHA PRESERVATION: Sample all textures and preserve their alpha\n vec4 sample1 = texture2D(blurTexture1, vUv);\n vec4 sample2 = texture2D(blurTexture2, vUv);\n vec4 sample3 = texture2D(blurTexture3, vUv);\n vec4 sample4 = texture2D(blurTexture4, vUv);\n vec4 sample5 = texture2D(blurTexture5, vUv);\n\n // Apply tint to RGB only, preserve alpha from samples\n vec4 color = bloomStrength * (\n lerpBloomFactor(bloomFactors[0]) * vec4(sample1.rgb * bloomTintColors[0], sample1.a) +\n lerpBloomFactor(bloomFactors[1]) * vec4(sample2.rgb * bloomTintColors[1], sample2.a) +\n lerpBloomFactor(bloomFactors[2]) * vec4(sample3.rgb * bloomTintColors[2], sample3.a) +\n lerpBloomFactor(bloomFactors[3]) * vec4(sample4.rgb * bloomTintColors[3], sample4.a) +\n lerpBloomFactor(bloomFactors[4]) * vec4(sample5.rgb * bloomTintColors[4], sample5.a)\n );\n\n gl_FragColor = color;\n }"})}}Xl.BlurDirectionX=new Mt(1,0),Xl.BlurDirectionY=new Mt(0,1);const ql={type:"change"},Yl={type:"start"},$l={type:"end"},Zl=new yi,Kl=new Fa,Ql=Math.cos(70*bt),Jl=new xt,eh=2*Math.PI,th=-1,ih=1e-6;class nh extends es{constructor(e,t=null){super(e,t),this.state=th,this.target=new xt,this.cursor=new xt,this.minDistance=0,this.maxDistance=1/0,this.minZoom=0,this.maxZoom=1/0,this.minTargetRadius=0,this.maxTargetRadius=1/0,this.minPolarAngle=0,this.maxPolarAngle=Math.PI,this.minAzimuthAngle=-1/0,this.maxAzimuthAngle=1/0,this.enableDamping=!1,this.dampingFactor=.05,this.enableZoom=!0,this.zoomSpeed=1,this.enableRotate=!0,this.rotateSpeed=1,this.keyRotateSpeed=1,this.enablePan=!0,this.panSpeed=1,this.screenSpacePanning=!0,this.keyPanSpeed=7,this.zoomToCursor=!1,this.autoRotate=!1,this.autoRotateSpeed=2,this.keys={LEFT:"ArrowLeft",UP:"ArrowUp",RIGHT:"ArrowRight",BOTTOM:"ArrowDown"},this.mouseButtons={LEFT:0,MIDDLE:1,RIGHT:2},this.touches={ONE:0,TWO:2},this.target0=this.target.clone(),this.position0=this.object.position.clone(),this.zoom0=this.object.zoom,this._domElementKeyEvents=null,this._lastPosition=new xt,this._lastQuaternion=new _t,this._lastTargetPosition=new xt,this._quat=(new _t).setFromUnitVectors(e.up,new xt(0,1,0)),this._quatInverse=this._quat.clone().invert(),this._spherical=new Jr,this._sphericalDelta=new Jr,this._scale=1,this._panOffset=new xt,this._rotateStart=new Mt,this._rotateEnd=new Mt,this._rotateDelta=new Mt,this._panStart=new Mt,this._panEnd=new Mt,this._panDelta=new Mt,this._dollyStart=new Mt,this._dollyEnd=new Mt,this._dollyDelta=new Mt,this._dollyDirection=new xt,this._mouse=new Mt,this._performCursorZoom=!1,this._pointers=[],this._pointerPositions={},this._controlActive=!1,this._onPointerMove=rh.bind(this),this._onPointerDown=ah.bind(this),this._onPointerUp=sh.bind(this),this._onContextMenu=ph.bind(this),this._onMouseWheel=hh.bind(this),this._onKeyDown=ch.bind(this),this._onTouchStart=uh.bind(this),this._onTouchMove=dh.bind(this),this._onMouseDown=oh.bind(this),this._onMouseMove=lh.bind(this),this._interceptControlDown=mh.bind(this),this._interceptControlUp=fh.bind(this),null!==this.domElement&&this.connect(this.domElement),this.update()}connect(e){super.connect(e),this.domElement.addEventListener("pointerdown",this._onPointerDown),this.domElement.addEventListener("pointercancel",this._onPointerUp),this.domElement.addEventListener("contextmenu",this._onContextMenu),this.domElement.addEventListener("wheel",this._onMouseWheel,{passive:!1}),this.domElement.getRootNode().addEventListener("keydown",this._interceptControlDown,{passive:!0,capture:!0}),this.domElement.style.touchAction="none"}disconnect(){this.domElement.removeEventListener("pointerdown",this._onPointerDown),this.domElement.removeEventListener("pointermove",this._onPointerMove),this.domElement.removeEventListener("pointerup",this._onPointerUp),this.domElement.removeEventListener("pointercancel",this._onPointerUp),this.domElement.removeEventListener("wheel",this._onMouseWheel),this.domElement.removeEventListener("contextmenu",this._onContextMenu),this.stopListenToKeyEvents(),this.domElement.getRootNode().removeEventListener("keydown",this._interceptControlDown,{capture:!0}),this.domElement.style.touchAction="auto"}dispose(){this.disconnect()}getPolarAngle(){return this._spherical.phi}getAzimuthalAngle(){return this._spherical.theta}getDistance(){return this.object.position.distanceTo(this.target)}listenToKeyEvents(e){e.addEventListener("keydown",this._onKeyDown),this._domElementKeyEvents=e}stopListenToKeyEvents(){null!==this._domElementKeyEvents&&(this._domElementKeyEvents.removeEventListener("keydown",this._onKeyDown),this._domElementKeyEvents=null)}saveState(){this.target0.copy(this.target),this.position0.copy(this.object.position),this.zoom0=this.object.zoom}reset(){this.target.copy(this.target0),this.object.position.copy(this.position0),this.object.zoom=this.zoom0,this.object.updateProjectionMatrix(),this.dispatchEvent(ql),this.update(),this.state=th}update(e=null){const t=this.object.position;Jl.copy(t).sub(this.target),Jl.applyQuaternion(this._quat),this._spherical.setFromVector3(Jl),this.autoRotate&&this.state===th&&this._rotateLeft(this._getAutoRotationAngle(e)),this.enableDamping?(this._spherical.theta+=this._sphericalDelta.theta*this.dampingFactor,this._spherical.phi+=this._sphericalDelta.phi*this.dampingFactor):(this._spherical.theta+=this._sphericalDelta.theta,this._spherical.phi+=this._sphericalDelta.phi);let i=this.minAzimuthAngle,n=this.maxAzimuthAngle;isFinite(i)&&isFinite(n)&&(i<-Math.PI?i+=eh:i>Math.PI&&(i-=eh),n<-Math.PI?n+=eh:n>Math.PI&&(n-=eh),this._spherical.theta=i<=n?Math.max(i,Math.min(n,this._spherical.theta)):this._spherical.theta>(i+n)/2?Math.max(i,this._spherical.theta):Math.min(n,this._spherical.theta)),this._spherical.phi=Math.max(this.minPolarAngle,Math.min(this.maxPolarAngle,this._spherical.phi)),this._spherical.makeSafe(),!0===this.enableDamping?this.target.addScaledVector(this._panOffset,this.dampingFactor):this.target.add(this._panOffset),this.target.sub(this.cursor),this.target.clampLength(this.minTargetRadius,this.maxTargetRadius),this.target.add(this.cursor);let a=!1;if(this.zoomToCursor&&this._performCursorZoom||this.object.isOrthographicCamera)this._spherical.radius=this._clampDistance(this._spherical.radius);else{const e=this._spherical.radius;this._spherical.radius=this._clampDistance(this._spherical.radius*this._scale),a=e!=this._spherical.radius}if(Jl.setFromSpherical(this._spherical),Jl.applyQuaternion(this._quatInverse),t.copy(this.target).add(Jl),this.object.lookAt(this.target),!0===this.enableDamping?(this._sphericalDelta.theta*=1-this.dampingFactor,this._sphericalDelta.phi*=1-this.dampingFactor,this._panOffset.multiplyScalar(1-this.dampingFactor)):(this._sphericalDelta.set(0,0,0),this._panOffset.set(0,0,0)),this.zoomToCursor&&this._performCursorZoom){let e=null;if(this.object.isPerspectiveCamera){const t=Jl.length();e=this._clampDistance(t*this._scale);const i=t-e;this.object.position.addScaledVector(this._dollyDirection,i),this.object.updateMatrixWorld(),a=!!i}else if(this.object.isOrthographicCamera){const t=new xt(this._mouse.x,this._mouse.y,0);t.unproject(this.object);const i=this.object.zoom;this.object.zoom=Math.max(this.minZoom,Math.min(this.maxZoom,this.object.zoom/this._scale)),this.object.updateProjectionMatrix(),a=i!==this.object.zoom;const n=new xt(this._mouse.x,this._mouse.y,0);n.unproject(this.object),this.object.position.sub(n).add(t),this.object.updateMatrixWorld(),e=Jl.length()}else console.warn("WARNING: OrbitControls.js encountered an unknown camera type - zoom to cursor disabled."),this.zoomToCursor=!1;null!==e&&(this.screenSpacePanning?this.target.set(0,0,-1).transformDirection(this.object.matrix).multiplyScalar(e).add(this.object.position):(Zl.origin.copy(this.object.position),Zl.direction.set(0,0,-1).transformDirection(this.object.matrix),Math.abs(this.object.up.dot(Zl.direction))<Ql?this.object.lookAt(this.target):(Kl.setFromNormalAndCoplanarPoint(this.object.up,this.target),Zl.intersectPlane(Kl,this.target))))}else if(this.object.isOrthographicCamera){const e=this.object.zoom;this.object.zoom=Math.max(this.minZoom,Math.min(this.maxZoom,this.object.zoom/this._scale)),e!==this.object.zoom&&(this.object.updateProjectionMatrix(),a=!0)}return this._scale=1,this._performCursorZoom=!1,!!(a||this._lastPosition.distanceToSquared(this.object.position)>ih||8*(1-this._lastQuaternion.dot(this.object.quaternion))>ih||this._lastTargetPosition.distanceToSquared(this.target)>ih)&&(this.dispatchEvent(ql),this._lastPosition.copy(this.object.position),this._lastQuaternion.copy(this.object.quaternion),this._lastTargetPosition.copy(this.target),!0)}_getAutoRotationAngle(e){return null!==e?eh/60*this.autoRotateSpeed*e:eh/60/60*this.autoRotateSpeed}_getZoomScale(e){const t=Math.abs(.01*e);return Math.pow(.95,this.zoomSpeed*t)}_rotateLeft(e){this._sphericalDelta.theta-=e}_rotateUp(e){this._sphericalDelta.phi-=e}_panLeft(e,t){Jl.setFromMatrixColumn(t,0),Jl.multiplyScalar(-e),this._panOffset.add(Jl)}_panUp(e,t){!0===this.screenSpacePanning?Jl.setFromMatrixColumn(t,1):(Jl.setFromMatrixColumn(t,0),Jl.crossVectors(this.object.up,Jl)),Jl.multiplyScalar(e),this._panOffset.add(Jl)}_pan(e,t){const i=this.domElement;if(this.object.isPerspectiveCamera){const n=this.object.position;Jl.copy(n).sub(this.target);let a=Jl.length();a*=Math.tan(this.object.fov/2*Math.PI/180),this._panLeft(2*e*a/i.clientHeight,this.object.matrix),this._panUp(2*t*a/i.clientHeight,this.object.matrix)}else this.object.isOrthographicCamera?(this._panLeft(e*(this.object.right-this.object.left)/this.object.zoom/i.clientWidth,this.object.matrix),this._panUp(t*(this.object.top-this.object.bottom)/this.object.zoom/i.clientHeight,this.object.matrix)):(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled."),this.enablePan=!1)}_dollyOut(e){this.object.isPerspectiveCamera||this.object.isOrthographicCamera?this._scale/=e:(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."),this.enableZoom=!1)}_dollyIn(e){this.object.isPerspectiveCamera||this.object.isOrthographicCamera?this._scale*=e:(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."),this.enableZoom=!1)}_updateZoomParameters(e,t){if(!this.zoomToCursor)return;this._performCursorZoom=!0;const i=this.domElement.getBoundingClientRect(),n=e-i.left,a=t-i.top,r=i.width,s=i.height;this._mouse.x=n/r*2-1,this._mouse.y=-a/s*2+1,this._dollyDirection.set(this._mouse.x,this._mouse.y,1).unproject(this.object).sub(this.object.position).normalize()}_clampDistance(e){return Math.max(this.minDistance,Math.min(this.maxDistance,e))}_handleMouseDownRotate(e){this._rotateStart.set(e.clientX,e.clientY)}_handleMouseDownDolly(e){this._updateZoomParameters(e.clientX,e.clientX),this._dollyStart.set(e.clientX,e.clientY)}_handleMouseDownPan(e){this._panStart.set(e.clientX,e.clientY)}_handleMouseMoveRotate(e){this._rotateEnd.set(e.clientX,e.clientY),this._rotateDelta.subVectors(this._rotateEnd,this._rotateStart).multiplyScalar(this.rotateSpeed);const t=this.domElement;this._rotateLeft(eh*this._rotateDelta.x/t.clientHeight),this._rotateUp(eh*this._rotateDelta.y/t.clientHeight),this._rotateStart.copy(this._rotateEnd),this.update()}_handleMouseMoveDolly(e){this._dollyEnd.set(e.clientX,e.clientY),this._dollyDelta.subVectors(this._dollyEnd,this._dollyStart),this._dollyDelta.y>0?this._dollyOut(this._getZoomScale(this._dollyDelta.y)):this._dollyDelta.y<0&&this._dollyIn(this._getZoomScale(this._dollyDelta.y)),this._dollyStart.copy(this._dollyEnd),this.update()}_handleMouseMovePan(e){this._panEnd.set(e.clientX,e.clientY),this._panDelta.subVectors(this._panEnd,this._panStart).multiplyScalar(this.panSpeed),this._pan(this._panDelta.x,this._panDelta.y),this._panStart.copy(this._panEnd),this.update()}_handleMouseWheel(e){this._updateZoomParameters(e.clientX,e.clientY),e.deltaY<0?this._dollyIn(this._getZoomScale(e.deltaY)):e.deltaY>0&&this._dollyOut(this._getZoomScale(e.deltaY)),this.update()}_handleKeyDown(e){let t=!1;switch(e.code){case this.keys.UP:e.ctrlKey||e.metaKey||e.shiftKey?this.enableRotate&&this._rotateUp(eh*this.keyRotateSpeed/this.domElement.clientHeight):this.enablePan&&this._pan(0,this.keyPanSpeed),t=!0;break;case this.keys.BOTTOM:e.ctrlKey||e.metaKey||e.shiftKey?this.enableRotate&&this._rotateUp(-eh*this.keyRotateSpeed/this.domElement.clientHeight):this.enablePan&&this._pan(0,-this.keyPanSpeed),t=!0;break;case this.keys.LEFT:e.ctrlKey||e.metaKey||e.shiftKey?this.enableRotate&&this._rotateLeft(eh*this.keyRotateSpeed/this.domElement.clientHeight):this.enablePan&&this._pan(this.keyPanSpeed,0),t=!0;break;case this.keys.RIGHT:e.ctrlKey||e.metaKey||e.shiftKey?this.enableRotate&&this._rotateLeft(-eh*this.keyRotateSpeed/this.domElement.clientHeight):this.enablePan&&this._pan(-this.keyPanSpeed,0),t=!0}t&&(e.preventDefault(),this.update())}_handleTouchStartRotate(e){if(1===this._pointers.length)this._rotateStart.set(e.pageX,e.pageY);else{const t=this._getSecondPointerPosition(e),i=.5*(e.pageX+t.x),n=.5*(e.pageY+t.y);this._rotateStart.set(i,n)}}_handleTouchStartPan(e){if(1===this._pointers.length)this._panStart.set(e.pageX,e.pageY);else{const t=this._getSecondPointerPosition(e),i=.5*(e.pageX+t.x),n=.5*(e.pageY+t.y);this._panStart.set(i,n)}}_handleTouchStartDolly(e){const t=this._getSecondPointerPosition(e),i=e.pageX-t.x,n=e.pageY-t.y,a=Math.sqrt(i*i+n*n);this._dollyStart.set(0,a)}_handleTouchStartDollyPan(e){this.enableZoom&&this._handleTouchStartDolly(e),this.enablePan&&this._handleTouchStartPan(e)}_handleTouchStartDollyRotate(e){this.enableZoom&&this._handleTouchStartDolly(e),this.enableRotate&&this._handleTouchStartRotate(e)}_handleTouchMoveRotate(e){if(1==this._pointers.length)this._rotateEnd.set(e.pageX,e.pageY);else{const t=this._getSecondPointerPosition(e),i=.5*(e.pageX+t.x),n=.5*(e.pageY+t.y);this._rotateEnd.set(i,n)}this._rotateDelta.subVectors(this._rotateEnd,this._rotateStart).multiplyScalar(this.rotateSpeed);const t=this.domElement;this._rotateLeft(eh*this._rotateDelta.x/t.clientHeight),this._rotateUp(eh*this._rotateDelta.y/t.clientHeight),this._rotateStart.copy(this._rotateEnd)}_handleTouchMovePan(e){if(1===this._pointers.length)this._panEnd.set(e.pageX,e.pageY);else{const t=this._getSecondPointerPosition(e),i=.5*(e.pageX+t.x),n=.5*(e.pageY+t.y);this._panEnd.set(i,n)}this._panDelta.subVectors(this._panEnd,this._panStart).multiplyScalar(this.panSpeed),this._pan(this._panDelta.x,this._panDelta.y),this._panStart.copy(this._panEnd)}_handleTouchMoveDolly(e){const t=this._getSecondPointerPosition(e),i=e.pageX-t.x,n=e.pageY-t.y,a=Math.sqrt(i*i+n*n);this._dollyEnd.set(0,a),this._dollyDelta.set(0,Math.pow(this._dollyEnd.y/this._dollyStart.y,this.zoomSpeed)),this._dollyOut(this._dollyDelta.y),this._dollyStart.copy(this._dollyEnd);const r=.5*(e.pageX+t.x),s=.5*(e.pageY+t.y);this._updateZoomParameters(r,s)}_handleTouchMoveDollyPan(e){this.enableZoom&&this._handleTouchMoveDolly(e),this.enablePan&&this._handleTouchMovePan(e)}_handleTouchMoveDollyRotate(e){this.enableZoom&&this._handleTouchMoveDolly(e),this.enableRotate&&this._handleTouchMoveRotate(e)}_addPointer(e){this._pointers.push(e.pointerId)}_removePointer(e){delete this._pointerPositions[e.pointerId];for(let t=0;t<this._pointers.length;t++)if(this._pointers[t]==e.pointerId)return void this._pointers.splice(t,1)}_isTrackingPointer(e){for(let t=0;t<this._pointers.length;t++)if(this._pointers[t]==e.pointerId)return!0;return!1}_trackPointer(e){let t=this._pointerPositions[e.pointerId];void 0===t&&(t=new Mt,this._pointerPositions[e.pointerId]=t),t.set(e.pageX,e.pageY)}_getSecondPointerPosition(e){const t=e.pointerId===this._pointers[0]?this._pointers[1]:this._pointers[0];return this._pointerPositions[t]}_customWheelEvent(e){const t=e.deltaMode,i={clientX:e.clientX,clientY:e.clientY,deltaY:e.deltaY};switch(t){case 1:i.deltaY*=16;break;case 2:i.deltaY*=100}return e.ctrlKey&&!this._controlActive&&(i.deltaY*=10),i}}function ah(e){!1!==this.enabled&&(0===this._pointers.length&&(this.domElement.setPointerCapture(e.pointerId),this.domElement.addEventListener("pointermove",this._onPointerMove),this.domElement.addEventListener("pointerup",this._onPointerUp)),this._isTrackingPointer(e)||(this._addPointer(e),"touch"===e.pointerType?this._onTouchStart(e):this._onMouseDown(e)))}function rh(e){!1!==this.enabled&&("touch"===e.pointerType?this._onTouchMove(e):this._onMouseMove(e))}function sh(e){switch(this._removePointer(e),this._pointers.length){case 0:this.domElement.releasePointerCapture(e.pointerId),this.domElement.removeEventListener("pointermove",this._onPointerMove),this.domElement.removeEventListener("pointerup",this._onPointerUp),this.dispatchEvent($l),this.state=th;break;case 1:const t=this._pointers[0],i=this._pointerPositions[t];this._onTouchStart({pointerId:t,pageX:i.x,pageY:i.y})}}function oh(e){let t;switch(e.button){case 0:t=this.mouseButtons.LEFT;break;case 1:t=this.mouseButtons.MIDDLE;break;case 2:t=this.mouseButtons.RIGHT;break;default:t=-1}switch(t){case 1:if(!1===this.enableZoom)return;this._handleMouseDownDolly(e),this.state=1;break;case 0:if(e.ctrlKey||e.metaKey||e.shiftKey){if(!1===this.enablePan)return;this._handleMouseDownPan(e),this.state=2}else{if(!1===this.enableRotate)return;this._handleMouseDownRotate(e),this.state=0}break;case 2:if(e.ctrlKey||e.metaKey||e.shiftKey){if(!1===this.enableRotate)return;this._handleMouseDownRotate(e),this.state=0}else{if(!1===this.enablePan)return;this._handleMouseDownPan(e),this.state=2}break;default:this.state=th}this.state!==th&&this.dispatchEvent(Yl)}function lh(e){switch(this.state){case 0:if(!1===this.enableRotate)return;this._handleMouseMoveRotate(e);break;case 1:if(!1===this.enableZoom)return;this._handleMouseMoveDolly(e);break;case 2:if(!1===this.enablePan)return;this._handleMouseMovePan(e)}}function hh(e){!1!==this.enabled&&!1!==this.enableZoom&&this.state===th&&(e.preventDefault(),this.dispatchEvent(Yl),this._handleMouseWheel(this._customWheelEvent(e)),this.dispatchEvent($l))}function ch(e){!1!==this.enabled&&this._handleKeyDown(e)}function uh(e){switch(this._trackPointer(e),this._pointers.length){case 1:switch(this.touches.ONE){case 0:if(!1===this.enableRotate)return;this._handleTouchStartRotate(e),this.state=3;break;case 1:if(!1===this.enablePan)return;this._handleTouchStartPan(e),this.state=4;break;default:this.state=th}break;case 2:switch(this.touches.TWO){case 2:if(!1===this.enableZoom&&!1===this.enablePan)return;this._handleTouchStartDollyPan(e),this.state=5;break;case 3:if(!1===this.enableZoom&&!1===this.enableRotate)return;this._handleTouchStartDollyRotate(e),this.state=6;break;default:this.state=th}break;default:this.state=th}this.state!==th&&this.dispatchEvent(Yl)}function dh(e){switch(this._trackPointer(e),this.state){case 3:if(!1===this.enableRotate)return;this._handleTouchMoveRotate(e),this.update();break;case 4:if(!1===this.enablePan)return;this._handleTouchMovePan(e),this.update();break;case 5:if(!1===this.enableZoom&&!1===this.enablePan)return;this._handleTouchMoveDollyPan(e),this.update();break;case 6:if(!1===this.enableZoom&&!1===this.enableRotate)return;this._handleTouchMoveDollyRotate(e),this.update();break;default:this.state=th}}function ph(e){!1!==this.enabled&&e.preventDefault()}function mh(e){"Control"===e.key&&(this._controlActive=!0,this.domElement.getRootNode().addEventListener("keyup",this._interceptControlUp,{passive:!0,capture:!0}))}function fh(e){"Control"===e.key&&(this._controlActive=!1,this.domElement.getRootNode().removeEventListener("keyup",this._interceptControlUp,{passive:!0,capture:!0}))}function gh(e,t=.5){const[i,n,a]=e,r=e=>e<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4),s=r(i),o=r(n),l=r(a),h=.2126*s+.7152*o+.0722*l,c=t/Math.max(h,.001);let u=s*c,d=o*c,p=l*c;const m=Math.max(u,d,p);m>1&&(u/=m,d/=m,p/=m);const f=e=>e<=.0031308?12.92*e:1.055*Math.pow(e,1/2.4)-.055;return{r:Math.min(1,Math.max(0,f(u))),g:Math.min(1,Math.max(0,f(d))),b:Math.min(1,Math.max(0,f(p)))}}function vh(e,t=0,i="glow"){const n=function(e){const t=parseInt(e.slice(1,3),16)/255,i=parseInt(e.slice(3,5),16)/255,n=parseInt(e.slice(5,7),16)/255,a=e=>e<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4);return.2126*a(t)+.7152*a(i)+.0722*a(n)}(e),a=(.5+t)/Math.max(n,.05);return Math.max(.3,Math.min(10,a))}class yh{constructor(e){this.renderer=e,this.glowAmount=0,this.targetGlowAmount=0,this.glowColor=new dn(1,1,1),this.targetGlowColor=new dn(1,1,1),this.worldPosition=new xt(0,0,0),this.time=0,this.ringPhase=0,this.scene=new da,this.camera=new qr(-1,1,1,-1,.1,10),this.camera.position.z=1,this.createGlowMesh(),this._tempVector=new xt,this._tempColor=new dn}createGlowMesh(){const e=new fr(2,2),t=new Jn({uniforms:{glowAmount:{value:0},glowColor:{value:new dn(1,1,1)},centerUV:{value:new Mt(.5,.5)},time:{value:0},ringPhase:{value:0},aspectRatio:{value:1}},vertexShader:"\n varying vec2 vUv;\n\n void main() {\n vUv = uv;\n gl_Position = vec4(position.xy, 0.0, 1.0);\n }\n ",fragmentShader:"\n uniform float glowAmount;\n uniform vec3 glowColor;\n uniform vec2 centerUV;\n uniform float time;\n uniform float ringPhase;\n uniform float aspectRatio;\n\n varying vec2 vUv;\n\n void main() {\n // Aspect-correct UV coordinates - apply aspect to Y instead\n // This prevents horizontal clipping on wide screens\n vec2 centeredUV = vUv - centerUV;\n // Don't multiply by aspect - let glow be circular in screen space\n\n float dist = length(centeredUV);\n\n // Ring parameters that evolve with ringPhase\n // MUCH LARGER radii to prevent clipping - glow can extend to screen edges\n // At ringPhase=0: tight ring close to center\n // At ringPhase=1: expanded ring that can fill most of screen\n float innerRadius = mix(0.02, 0.08, ringPhase);\n float outerRadius = mix(0.15, 1.2, ringPhase); // Can extend beyond screen!\n float peakRadius = mix(0.06, 0.25, ringPhase);\n\n // Create soft ring falloff\n // Inner falloff: 0 at center, 1 at peak\n float innerFalloff = smoothstep(innerRadius * 0.3, peakRadius, dist);\n\n // Outer falloff: 1 at peak, 0 at outer edge (very gradual fade)\n float outerFalloff = 1.0 - smoothstep(peakRadius, outerRadius, dist);\n\n // Combine for ring shape\n float ringIntensity = innerFalloff * outerFalloff;\n\n // Add subtle shimmer/undulation\n float shimmer = 0.9 + 0.1 * sin(time * 3.0 + dist * 20.0);\n\n // Final intensity with glow amount control\n float intensity = ringIntensity * glowAmount * shimmer;\n\n // Soft glow color with intensity\n // Use HDR values (>1.0) for bloom pickup\n vec3 color = glowColor * intensity * 2.0;\n\n // Alpha for blending\n float alpha = intensity * 0.6;\n\n gl_FragColor = vec4(color, alpha);\n }\n ",transparent:!0,blending:2,depthTest:!1,depthWrite:!1});this.glowMesh=new Xn(e,t),this.scene.add(this.glowMesh)}setGlow(e,t,i){this.targetGlowAmount=Math.max(0,e),t&&(Array.isArray(t)?this.targetGlowColor.setRGB(t[0],t[1],t[2]):this.targetGlowColor.copy(t)),i&&this.worldPosition.copy(i)}update(e,t){const i=e/1e3;this.time+=i,this.glowAmount+=(this.targetGlowAmount-this.glowAmount)*Math.min(1,8*i),this.glowColor.lerp(this.targetGlowColor,Math.min(1,8*i));const n=Math.min(1,this.glowAmount);if(this.ringPhase+=(n-this.ringPhase)*Math.min(1,4*i),t){this._tempVector.copy(this.worldPosition),this._tempVector.project(t);const e=(this._tempVector.x+1)/2,i=(this._tempVector.y+1)/2;this.glowMesh.material.uniforms.centerUV.value.set(e,i)}this.glowMesh.material.uniforms.glowAmount.value=this.glowAmount,this.glowMesh.material.uniforms.glowColor.value.copy(this.glowColor),this.glowMesh.material.uniforms.time.value=this.time,this.glowMesh.material.uniforms.ringPhase.value=this.ringPhase;const a=this.renderer.domElement;this.glowMesh.material.uniforms.aspectRatio.value=a.width/a.height}render(e){if(this.glowAmount<.001)return;const{autoClear:t}=e;e.autoClear=!1,e.render(this.scene,this.camera),e.autoClear=t}isActive(){return this.glowAmount>.001||this.targetGlowAmount>0}dispose(){this.glowMesh&&(this.glowMesh.geometry.dispose(),this.glowMesh.material.dispose(),this.scene.remove(this.glowMesh),this.glowMesh=null),this.scene=null,this.camera=null,this._tempVector=null,this._tempColor=null}}const bh=e=>({front:{x:0,y:0,z:e},side:{x:e,y:0,z:0},top:{x:0,y:e,z:0},angle:{x:.67*e,y:.5*e,z:.67*e},back:{x:0,y:0,z:-e},bottom:{x:0,y:-e,z:0}});class Mh{constructor(e,t,i=3){this.camera=e,this.controls=t,this.cameraDistance=i,this.animationId=null}getAvailablePresets(){return Object.keys(bh(this.cameraDistance))}setPreset(e,t=1e3,i=!1){if(!this.controls)return;const n=bh(this.cameraDistance)[e];if(!n)return void console.warn(`Unknown camera preset: ${e}`);this.cancelAnimation();const a=i?this.controls.target.clone():null;0!==t?this._animateTo(n,t,a,i):this._setInstant(n,a)}_setInstant(e,t){this.controls.reset(),this.camera.position.set(e.x,e.y,e.z),t?(this.controls.target.copy(t),this.camera.lookAt(t)):(this.controls.target.set(0,0,0),this.camera.lookAt(0,0,0)),this.controls.update()}_animateTo(e,t,i,n){n||this.controls.target.set(0,0,0);const a=this.camera.position.clone(),r=new xt(e.x,e.y,e.z),s=performance.now(),o=e=>{const i=e-s,n=Math.min(i/t,1),l=1-Math.pow(1-n,3);this.camera.position.lerpVectors(a,r,l),this.camera.lookAt(0,0,0),this.controls.update(),this.animationId=n<1?requestAnimationFrame(o):null};this.animationId=requestAnimationFrame(o)}isAnimating(){return null!==this.animationId}cancelAnimation(){null!==this.animationId&&(cancelAnimationFrame(this.animationId),this.animationId=null)}reset(e=1e3){this.setPreset("front",e)}setCameraDistance(e){this.cameraDistance=e}dispose(){this.cancelAnimation(),this.camera=null,this.controls=null}}class _h{constructor(e,t={}){this.canvas=e,this.options=t,this._destroyed=!1,this.scene=new da,this.scene.background=null,this.renderer=new Ol({canvas:e,alpha:!0,premultipliedAlpha:!1,antialias:!0,powerPreference:"high-performance",preserveDrawingBuffer:!1,precision:"highp",logarithmicDepthBuffer:!1,stencil:!1}),this.renderer.outputColorSpace=ze,this.renderer.toneMapping=0,this.renderer.toneMappingExposure=1,this.renderer.setClearColor(0,0),this.renderer.clear(),this.renderer.autoClear=!1,this.renderer.setPixelRatio(Math.min(window.devicePixelRatio,1.5)),this.renderer.setSize(e.width,e.height,!1),t.enableShadows&&(this.renderer.shadowMap.enabled=!0,this.renderer.shadowMap.type=2),this._contextLost=!1,this._boundHandleContextLost=this.handleContextLost.bind(this),this._boundHandleContextRestored=this.handleContextRestored.bind(this),e.addEventListener("webglcontextlost",this._boundHandleContextLost,!1),e.addEventListener("webglcontextrestored",this._boundHandleContextRestored,!1);const i=void 0!==t.fov?t.fov:45;this.camera=new aa(i,e.width/e.height,.1,100),this.cameraDistance=void 0!==t.cameraDistance?t.cameraDistance:3,this.camera.position.set(0,0,this.cameraDistance),this.camera.lookAt(0,0,0),!1!==t.enableControls&&this.setupCameraControls(),this.setupLights(),!1!==t.enablePostProcessing&&this.setupPostProcessing(),this.coreMesh=null,this.materialMode="glow",this.glowMaterial=null,this.glassMaterial=null,this.mixer=null,this.clock=new Qr,this._tempColor=new dn,this._tempColor2=new dn,this._white=new dn(1,1,1),this._tempQuat=new _t,this._tempEuler=new Pi,this._quatX=new _t,this._quatY=new _t,this._quatZ=new _t,this._rollQuat=new _t,this._meshQuat=new _t,this._xAxis=new xt(1,0,0),this._yAxis=new xt(0,1,0),this._zAxis=new xt(0,0,1),this._cameraToMesh=new xt,this._cameraDir=new xt}setupCameraControls(){this.controls=new nh(this.camera,this.renderer.domElement),this.controls.enableDamping=!0,this.controls.dampingFactor=.1;const e=void 0!==this.options.minZoom?this.options.minZoom:.5*this.cameraDistance,t=void 0!==this.options.maxZoom?this.options.maxZoom:2*this.cameraDistance;this.controls.minDistance=e,this.controls.maxDistance=t,this.controls.enablePan=!1,this.controls.autoRotate=!0===this.options.autoRotate,this.controls.autoRotateSpeed=void 0!==this.options.autoRotateSpeed?this.options.autoRotateSpeed:.5,this.controls.minPolarAngle=.2*Math.PI,this.controls.maxPolarAngle=.8*Math.PI,this.controls.rotateSpeed=.8,this.controls.zoomSpeed=1.5,("ontouchstart"in window||navigator.maxTouchPoints>0)&&(this.controls.rotateSpeed=1,this.controls.zoomSpeed=1.2),this.renderer.domElement.style.touchAction="none";const i=()=>{this.controls&&this.controls.update()};this.renderer.domElement.addEventListener("pointermove",i,{passive:!0}),this.renderer.domElement.addEventListener("pointerdown",i,{passive:!0}),this.cameraPresetManager=new Mh(this.camera,this.controls,this.cameraDistance)}setupLights(){this.ambientLight=new Zr(16777215,.3),this.ambientLight.name="ambientLight",this.scene.add(this.ambientLight),this.keyLight=new $r(16777215,.8),this.keyLight.position.set(2,2,2),this.keyLight.name="keyLight",this.options.enableShadows&&(this.keyLight.castShadow=!0,this.keyLight.shadow.mapSize.width=1024,this.keyLight.shadow.mapSize.height=1024,this.keyLight.shadow.camera.near=.5,this.keyLight.shadow.camera.far=10),this.scene.add(this.keyLight),this.fillLight=new $r(16777215,.5),this.fillLight.position.set(-2,1,1),this.fillLight.name="fillLight",this.scene.add(this.fillLight),this.rimLight=new $r(16777215,.7),this.rimLight.position.set(0,1,-2),this.rimLight.name="rimLight",this.scene.add(this.rimLight),this.accentLight1=new Xr(54527,.3,10),this.accentLight1.position.set(-3,0,1),this.accentLight1.name="accentLight1",this.scene.add(this.accentLight1),this.accentLight2=new Xr(16716947,.2,10),this.accentLight2.position.set(3,0,1),this.accentLight2.name="accentLight2",this.scene.add(this.accentLight2),this.accentLight3=new Xr(16739125,.2,10),this.accentLight3.position.set(0,3,-1),this.accentLight3.name="accentLight3",this.scene.add(this.accentLight3),this.createEnvironmentMap()}async createEnvironmentMap(){if(this._destroyed)return;this._envMapLoading=!0;try{const{HDRLoader:e}=await Promise.resolve().then(function(){return kp});if(this._destroyed)return;const t=new ws(this.renderer);t.compileEquirectangularShader();try{const i=new e,n=["/hdri/studio_1k.hdr","/site/public/hdri/studio_1k.hdr"];let a=null;for(const e of n)try{if(a=await i.loadAsync(e),a&&a.image)break}catch(e){}if(!a||!a.image)throw new Error("HDR texture not found at any path");return this._destroyed?(a.dispose(),void t.dispose()):(a.mapping=I,this.envMap=t.fromEquirectangular(a).texture,a.dispose(),t.dispose(),this._envMapLoading=!1,void console.log("[Emotive] HDRI environment map loaded"))}catch(e){t.dispose()}}catch(e){}if(this._destroyed)return;const e=new la(512),t=new da,i=new dn(5609983),n=new dn(16739229),a=new dn(1710638),r=new Ur(i,a,1.5);t.add(r);const s=new Xr(54527,2,20);s.position.set(-5,2,-5),t.add(s);const o=new Xr(16716947,2,20);o.position.set(5,2,-5),t.add(o);const l=new Xr(16755200,1.5,20);l.position.set(0,5,0),t.add(l),t.background=n;const h=new sa(.1,100,e);h.update(this.renderer,t),this.envMap=e.texture,this._envCubeRenderTarget=e,this._envScene=t,this._envCubeCamera=h,this._envMapLoading=!1}setupPostProcessing(){const e=new Mt;this.renderer.getDrawingBufferSize(e);const t=new Ht(e.x,e.y,{format:Q,type:Y,minFilter:N,magFilter:N,stencilBuffer:!1,depthBuffer:!0});this.composer=new Wl(this.renderer,t),this.renderer.setRenderTarget(t),this.renderer.clear(),this.renderer.setRenderTarget(this.composer.readBuffer),this.renderer.clear(),this.renderer.setRenderTarget(this.composer.writeBuffer),this.renderer.clear(),this.renderer.setRenderTarget(null);const i=new jl(this.scene,this.camera);i.clearColor=new dn(0),i.clearAlpha=0,this.composer.addPass(i);const n="ontouchstart"in window||navigator.maxTouchPoints>0?.5:1,a=new Mt(Math.floor(e.x*n),Math.floor(e.y*n));this.bloomPass=new Xl(a,1.2,.8,.3),this.bloomPass.name="bloomPass",this.bloomPass.enabled=!0,this.bloomPass.renderToScreen=!0,this.composer.addPass(this.bloomPass),this.bloomPass.clearBloomBuffers(this.renderer),this.particleRenderTarget=new Ht(e.x,e.y,{format:Q,type:Y,minFilter:N,magFilter:N,stencilBuffer:!1,depthBuffer:!0}),this.renderer.setRenderTarget(this.particleRenderTarget),this.renderer.clear(),this.renderer.setRenderTarget(null),this.particleBloomPass=new Xl(a,.5,.4,.3),this.particleBloomPass.name="particleBloomPass",this.particleBloomPass.enabled=!0,this.particleBloomPass.clearColor=new dn(1,1,1),this.particleBloomPass.skipBaseCopy=!0,this.particleBloomPass.clearBloomBuffers(this.renderer),this.soulRenderTarget=new Ht(e.x,e.y,{format:Q,type:Y,minFilter:N,magFilter:N,stencilBuffer:!1,depthBuffer:!0}),this.renderer.setRenderTarget(this.soulRenderTarget),this.renderer.clear(),this.renderer.setRenderTarget(null),this.particleCompositeShader={uniforms:{tDiffuse:{value:null},tParticles:{value:null}},vertexShader:"\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n ",fragmentShader:"\n uniform sampler2D tDiffuse;\n uniform sampler2D tParticles;\n varying vec2 vUv;\n\n void main() {\n vec4 base = texture2D(tDiffuse, vUv);\n vec4 particles = texture2D(tParticles, vUv);\n\n // Alpha-preserving composite: particles over base\n // Use particle alpha to blend\n vec3 blended = mix(base.rgb, particles.rgb, particles.a);\n float alpha = base.a + particles.a * (1.0 - base.a);\n\n gl_FragColor = vec4(blended, alpha);\n }\n "},this.glowLayer=new yh(this.renderer)}handleContextLost(e){e.preventDefault(),this._contextLost=!0,console.warn("⚠️ WebGL context lost - rendering paused"),this.cameraAnimationId&&(cancelAnimationFrame(this.cameraAnimationId),this.cameraAnimationId=null)}handleContextRestored(){this._contextLost=!1,this.recreateResources()}recreateResources(){this.createEnvironmentMap(),"glow"===this.materialMode?(this.glowMaterial=this.createGlowMaterial(),this.coreMesh&&(this.coreMesh.material=this.glowMaterial)):"glass"===this.materialMode&&(this.glassMaterial=this.createGlassMaterial(),this.coreMesh&&(this.coreMesh.material=this.glassMaterial),this.coreMesh&&this.createInnerCore())}createCoreMesh(e,t=null){if(this.coreMesh&&(this.scene.remove(this.coreMesh),this.coreMesh.isGroup?this.coreMesh.traverse(e=>{e.geometry&&e.geometry.dispose(),e.material&&this.disposeMaterial(e.material)}):(this.coreMesh.geometry&&this.coreMesh.geometry.dispose(),this.coreMesh.material&&this.disposeMaterial(this.coreMesh.material)),this.coreMesh=null),e.isGroup)return this.coreMesh=e,this.coreMesh.name="coreMascot",this.options.enableShadows&&this.coreMesh.traverse(e=>{e.isMesh&&(e.castShadow=!0,e.receiveShadow=!0)}),this.scene.add(this.coreMesh),this.coreMesh;let i;return t?i=t:(this.glowMaterial||(this.glowMaterial=this.createGlowMaterial()),i="glass"===this.materialMode?this.glassMaterial||this.createGlassMaterial():this.glowMaterial),this.coreMesh=new Xn(e,i),this.coreMesh.name="coreMascot",this.options.enableShadows&&(this.coreMesh.castShadow=!0,this.coreMesh.receiveShadow=!0),this.scene.add(this.coreMesh),"glass"===this.materialMode&&this.createInnerCore(),this.coreMesh}swapGeometry(e,t=null){if(!this.coreMesh)return;this.bloomPass&&this.bloomPass.clearBloomBuffers(this.renderer),this.particleBloomPass&&this.particleBloomPass.clearBloomBuffers(this.renderer);const i=this.coreMesh.geometry;if(i&&i.dispose(),this.coreMesh.geometry=e,t){if(this.coreMesh.material&&this.coreMesh.material!==this.glowMaterial&&this.coreMesh.material!==this.glassMaterial&&this.disposeMaterial(this.coreMesh.material),this.coreMesh.material=t,t.uniforms?.resolution){const e=this.renderer.getDrawingBufferSize(new Mt);t.uniforms.resolution.value.set(e.x,e.y)}}else{const e="glass"===this.materialMode?this.glassMaterial||this.createGlassMaterial():this.glowMaterial;this.coreMesh.material!==e&&(this.coreMesh.material&&this.coreMesh.material!==this.glowMaterial&&this.coreMesh.material!==this.glassMaterial&&this.disposeMaterial(this.coreMesh.material),this.coreMesh.material=e)}"glass"!==this.materialMode||t||this.createInnerCore()}createGlowMaterial(){return new Jn({uniforms:{glowColor:{value:new dn(1,1,1)},glowIntensity:{value:1},coreColor:{value:new dn(1,1,1)},fresnelPower:{value:3}},vertexShader:"\n varying vec3 vNormal;\n varying vec3 vViewPosition;\n\n void main() {\n // Transform normal to view space\n vNormal = normalize(normalMatrix * normal);\n\n // Calculate view space position\n vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);\n vViewPosition = -mvPosition.xyz;\n\n // Output clip space position\n gl_Position = projectionMatrix * mvPosition;\n }\n ",fragmentShader:"\n uniform vec3 glowColor;\n uniform vec3 coreColor;\n uniform float glowIntensity;\n uniform float fresnelPower;\n\n varying vec3 vNormal;\n varying vec3 vViewPosition;\n\n void main() {\n // Fresnel effect: edges glow more than center\n vec3 viewDir = normalize(vViewPosition);\n float fresnel = pow(1.0 - abs(dot(vNormal, viewDir)), fresnelPower);\n\n // Combine white core with colored glow\n // Both core and glow respect glowIntensity for proper on/off toggle\n vec3 finalColor = (coreColor * glowIntensity) + (glowColor * glowIntensity * fresnel);\n\n gl_FragColor = vec4(finalColor, 1.0);\n }\n ",transparent:!1,side:0})}createGlassMaterial(){this.glassEmissiveMultiplier=.6;const e=new _r({transmission:1,thickness:2.7,roughness:.37,metalness:0,ior:1.5,reflectivity:.5,envMapIntensity:1.2,side:2,transparent:!0,opacity:1,color:16777215,emissive:16777215,emissiveIntensity:.6,clearcoat:.8,clearcoatRoughness:.05,iridescence:.4,iridescenceIOR:1.3,iridescenceThicknessRange:[100,400]});return this.envMap&&(e.envMap=this.envMap),e}createInnerCore(){if(this.innerCore&&(this.coreMesh&&this.coreMesh.remove(this.innerCore),this.innerCore.geometry.dispose(),this.disposeMaterial(this.innerCore.material),this.innerCore=null,this.innerCoreMaterial=null),!this.coreMesh||!this.coreMesh.geometry)return;const e=this.coreMesh.geometry;let t;if("TorusGeometry"===e.type||void 0!==e.parameters?.tube){const i=e.parameters,n=i.radius||1,a=.25*(i.tube||.4),r=i.radialSegments||16,s=i.tubularSegments||100;t=new br(n,a,r,s)}else if("SphereGeometry"===e.type){const i=.2*(e.parameters.radius||1);t=new vr(i,32,32)}else if("BoxGeometry"===e.type){const i=e.parameters,n=.2*(i.width||1),a=.2*(i.height||1),r=.2*(i.depth||1);t=new Yn(n,a,r)}else if("IcosahedronGeometry"===e.type||"OctahedronGeometry"===e.type){const i=e.parameters,n=.2*(i.radius||1),a=i.detail||2;t="IcosahedronGeometry"===e.type?new pr(n,a):new mr(n,a)}else t=new pr(.2,2);const i=e.userData?.geometryType,n="IcosahedronGeometry"===e.type||"OctahedronGeometry"===e.type||"crystal"===i||"diamond"===i,a=new Mr({emissive:16777215,emissiveIntensity:n?3.5:2,color:16777215,transparent:!1,opacity:1});this.innerCoreMaterial=a,this.innerCore=new Xn(t,a),this.innerCore.name="innerCore",this.coreMesh.add(this.innerCore)}setMaterialMode(e){if(!this.coreMesh)return console.warn("Cannot set material mode: core mesh not created yet"),void(this.materialMode=e);if(e===this.materialMode)return;this.materialMode=e,"glass"!==e||this.glassMaterial?"glow"!==e||this.glowMaterial||(this.glowMaterial=this.createGlowMaterial()):this.glassMaterial=this.createGlassMaterial();const t="glass"===e?this.glassMaterial:this.glowMaterial;this.coreMesh.material=t,"glass"===e?this.createInnerCore():this.innerCore&&(this.coreMesh.remove(this.innerCore),this.innerCore.geometry.dispose(),this.disposeMaterial(this.innerCore.material),this.innerCore=null,this.innerCoreMaterial=null)}updateGlassProperties(e){this.glassMaterial&&(void 0!==e.transmission&&(this.glassMaterial.transmission=e.transmission,this.glassMaterial.needsUpdate=!0),void 0!==e.thickness&&(this.glassMaterial.thickness=e.thickness,this.glassMaterial.needsUpdate=!0),void 0!==e.roughness&&(this.glassMaterial.roughness=e.roughness,this.glassMaterial.needsUpdate=!0),void 0!==e.emissiveMultiplier&&(this.glassEmissiveMultiplier=e.emissiveMultiplier))}updateLighting(e,t,i=.15){if(!t||!t.visual)return;const n=t.visual.glowColor||"#FFFFFF";this._tempColor.set(n);const a=t.visual.glowIntensity||1;if(this.keyLight&&(this.keyLight.color.lerp(this._tempColor,i),this.keyLight.intensity+=(.8*a-this.keyLight.intensity)*i),this.fillLight&&(this._tempColor2.copy(this._tempColor).lerp(this._white,.7),this.fillLight.color.lerp(this._tempColor2,.5*i),this.fillLight.intensity+=(.3*a-this.fillLight.intensity)*i),this.ambientLight){const e=.4*a;this.ambientLight.intensity+=(e-this.ambientLight.intensity)*i}}normalizeIntensity(e){return.8+Math.log(e+1)/Math.log(11)*.4}calculateColorLuminance(e,t,i){const n=e=>e<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4);return.2126*n(e)+.7152*n(t)+.0722*n(i)}updateBloom(e,t=.1,i=null){if(this.bloomPass){const n=this.normalizeIntensity(e);let a,r,s;"sun"===i?(r=1.5,s=.4,a=.3):"crystal"===i||"rough"===i||"heart"===i?(r=1.8,s=.7,a=.35):"glass"===this.materialMode?(r=.3,s=.2,a=.85):(r=1+.8*n,s=.4,a=.85),this.bloomPass.strength+=(r-this.bloomPass.strength)*t,this.bloomPass.threshold+=(a-this.bloomPass.threshold)*t,this.bloomPass.radius=s}}setCameraPreset(e,t=1e3,i=!1){if(!this.controls)return;const n=this.cameraDistance,a={front:{x:0,y:0,z:n},side:{x:n,y:0,z:0},top:{x:0,y:n,z:0},angle:{x:.67*n,y:.5*n,z:.67*n},back:{x:0,y:0,z:-n},bottom:{x:0,y:-n,z:0}}[e];if(!a)return void console.warn(`Unknown camera preset: ${e}`);const r=i?this.controls.target.clone():null;if(0===t)return this.controls.reset(),this.camera.position.set(a.x,a.y,a.z),r?(this.controls.target.copy(r),this.camera.lookAt(r)):(this.controls.target.set(0,0,0),this.camera.lookAt(0,0,0)),void this.controls.update();i||this.controls.target.set(0,0,0);const s=this.camera.position.clone(),o=new xt(a.x,a.y,a.z),l=performance.now(),h=e=>{const i=e-l,n=Math.min(i/t,1),a=1-Math.pow(1-n,3);this.camera.position.lerpVectors(s,o,a),this.camera.lookAt(0,0,0),this.controls.update(),this.cameraAnimationId=n<1?requestAnimationFrame(h):null};this.cameraAnimationId=requestAnimationFrame(h)}resetCamera(){this.setCameraPreset("front",1e3)}toggleAutoRotate(e){this.controls&&(this.controls.autoRotate=void 0!==e?e:!this.controls.autoRotate)}isAutoRotateEnabled(){return!!this.controls&&this.controls.autoRotate}render(e={}){if(this._destroyed)return void console.log("[ThreeRenderer] render() BLOCKED - destroyed");if(!this.scene||!this.camera||!this.renderer)return void console.log(`[ThreeRenderer] render() BLOCKED - scene=${!!this.scene}, camera=${!!this.camera}, renderer=${!!this.renderer}`);if(!this.coreMesh)return;if(this._envMapLoading)return;if(!this._firstFrameRendered)return this._firstFrameRendered=!0,this.renderer.setRenderTarget(null),this.renderer.setClearColor(0,0),void this.renderer.clear();const t=(e,i)=>{if(!e||!e.children)return!0;for(let n=0;n<e.children.length;n++){const a=e.children[n];null!=a?null!==a.visible&&void 0!==a.visible?t(a,`${i}.children[${n}]`):(console.error(`[ThreeRenderer] child.visible is NULL at ${i}.children[${n}] name=${a.name} - REMOVING!`),e.children.splice(n,1),n--):(console.error(`[ThreeRenderer] NULL CHILD at ${i}.children[${n}] - REMOVING!`),e.children.splice(n,1),n--)}return!0};t(this.scene,"scene");const{position:i=[0,0,0],rotation:n=[0,0,0],scale:a=1,glowColor:r=[1,1,1],glowIntensity:s=1,glowColorHex:o=null,hasActiveGesture:l=!1,calibrationRotation:h=[0,0,0],cameraRoll:c=0,solarEclipse:u=null,deltaTime:d=0,morphProgress:p=null}=e;if(this.controls&&this.controls.update(),this.coreMesh){if(this.coreMesh.position.set(...i),this._tempEuler.set(n[0],n[1],n[2],"XYZ"),this._tempQuat.setFromEuler(this._tempEuler),this._quatX.setFromAxisAngle(this._xAxis,h[0]),this._quatY.setFromAxisAngle(this._yAxis,h[1]),this._cameraToMesh.subVectors(this.coreMesh.position,this.camera.position).normalize(),this._quatZ.setFromAxisAngle(this._cameraToMesh,h[2]),this._tempQuat.multiply(this._quatX),this._tempQuat.multiply(this._quatY),this._tempQuat.multiply(this._quatZ),this.coreMesh.rotation.setFromQuaternion(this._tempQuat),0!==c&&(this._cameraDir.subVectors(this.coreMesh.position,this.camera.position).normalize(),this._rollQuat.setFromAxisAngle(this._cameraDir,c),this._meshQuat.setFromEuler(this.coreMesh.rotation),this._meshQuat.premultiply(this._rollQuat),this.coreMesh.rotation.setFromQuaternion(this._meshQuat)),this.coreMesh.scale.setScalar(a),u&&u.update(this.camera,this.coreMesh,d,p),this.coreMesh.material&&this.coreMesh.material.uniforms){if(this.coreMesh.material.uniforms.glowColor&&(this._tempColor.setRGB(...r),this.coreMesh.material.uniforms.glowColor.value.lerp(this._tempColor,.15)),this.coreMesh.material.uniforms.glowIntensity){let e;e=0===s?0:l?s:this.normalizeIntensity(s);const t=this.coreMesh.material.uniforms.glowIntensity.value,i=l?.5:.15;this.coreMesh.material.uniforms.glowIntensity.value+=(e-t)*i}}else if(this.coreMesh.material&&this.coreMesh.material.emissive){this._tempColor.setRGB(...r),this.coreMesh.material.emissive.lerp(this._tempColor,.15);const e=.15*s,t=this.coreMesh.material.emissiveIntensity,i=l?.5:.15;this.coreMesh.material.emissiveIntensity+=(e-t)*i,this.coreMesh.material.color.lerp(this._white,.15)}this.innerCore&&(this.innerCore.visible=s>0,this.innerCoreMaterial&&(this._tempColor.setRGB(...r),this.innerCoreMaterial.emissive.lerp(this._tempColor,.15)))}if(this.mixer){const e=this.clock.getDelta();this.mixer.update(e)}if(this.renderer.clear(),this.composer){if(this.soulRenderTarget){let e=null;if(this.scene.traverse(t=>{"crystalSoul"===t.name&&(e=t)}),this.renderer.setRenderTarget(this.soulRenderTarget),this.renderer.setClearColor(0,0),this.renderer.clear(),this.camera.layers.set(2),this.renderer.render(this.scene,this.camera),this.coreMesh?.material?.uniforms?.soulTexture&&(this.coreMesh.material.uniforms.soulTexture.value=this.soulRenderTarget.texture,this.coreMesh.material.uniforms.soulTextureSize&&this.coreMesh.material.uniforms.soulTextureSize.value.set(this.soulRenderTarget.width,this.soulRenderTarget.height),this.coreMesh.material.uniforms.soulScreenCenter&&e)){const t=e.position.clone().project(this.camera),i=.5*(t.x+1),n=.5*(t.y+1);this.coreMesh.material.uniforms.soulScreenCenter.value.set(i,n)}this.renderer.setRenderTarget(null),this.renderer.setClearColor(0,0)}if(this.camera.layers.set(0),this.composer.render(),this.particleRenderTarget&&this.particleBloomPass){this.renderer.setRenderTarget(this.particleRenderTarget),this.renderer.setClearColor(16777215,0),this.renderer.clear(),this.camera.layers.set(0);const e=this._depthOnlyMaterial||(this._depthOnlyMaterial=new gn({colorWrite:!1,depthWrite:!0}));this.scene.overrideMaterial=e,this.renderer.render(this.scene,this.camera),this.scene.overrideMaterial=null,this.camera.layers.set(1),this.renderer.render(this.scene,this.camera);const t=this.particleRenderTarget;this.particleBloomPass.renderToScreen=!0,this.particleBloomPass.render(this.renderer,null,t,0,!1),this.renderer.setClearColor(0,0),this.renderer.setRenderTarget(null)}else this.camera.layers.set(1),this.renderer.render(this.scene,this.camera);this.camera.layers.enableAll(),this.glowLayer&&this.glowLayer.isActive()&&this.glowLayer.render(this.renderer)}else this.renderer.render(this.scene,this.camera),this.glowLayer&&this.glowLayer.isActive()&&this.glowLayer.render(this.renderer)}updateGlowLayer(e,t,i,n){this.glowLayer&&(this.glowLayer.setGlow(e,t,i),this.glowLayer.update(n,this.camera))}resize(e,t){if(this.camera.aspect=e/t,this.camera.updateProjectionMatrix(),this.renderer.setSize(e,t,!1),this.composer){const e=new Mt;this.renderer.getDrawingBufferSize(e),this.composer.setSize(e.x,e.y),this.bloomPass&&this.bloomPass.resolution&&this.bloomPass.resolution.set(e.x,e.y),this.particleRenderTarget&&this.particleRenderTarget.setSize(e.x,e.y),this.particleBloomPass&&this.particleBloomPass.setSize(e.x,e.y),this.soulRenderTarget&&this.soulRenderTarget.setSize(e.x,e.y),this.coreMesh?.material?.uniforms?.resolution&&this.coreMesh.material.uniforms.resolution.value.set(e.x,e.y)}}disposeMaterial(e){e&&(["map","lightMap","bumpMap","normalMap","specularMap","envMap","alphaMap","aoMap","displacementMap","emissiveMap","gradientMap","metalnessMap","roughnessMap"].forEach(t=>{e[t]&&e[t].dispose()}),e.uniforms&&Object.values(e.uniforms).forEach(e=>{e.value&&(e.value.isTexture?(e.value.dispose(),e.value=null):(e.value.isColor||e.value.isVector2||e.value.isVector3||e.value.isVector4)&&(e.value=null))}),e.dispose())}destroy(){console.log(`[ThreeRenderer] destroy() CALLED, scene children=${this.scene?.children?.length}`),this._destroyed=!0,this.canvas&&(this.canvas.removeEventListener("webglcontextlost",this._boundHandleContextLost,!1),this.canvas.removeEventListener("webglcontextrestored",this._boundHandleContextRestored,!1)),this.cameraAnimationId&&(cancelAnimationFrame(this.cameraAnimationId),this.cameraAnimationId=null),this.innerCore&&(this.coreMesh&&this.coreMesh.remove(this.innerCore),this.innerCore.geometry.dispose(),this.disposeMaterial(this.innerCore.material),this.innerCore=null,this.innerCoreMaterial=null),this.coreMesh&&(this.scene.remove(this.coreMesh),this.coreMesh.geometry.dispose(),this.disposeMaterial(this.coreMesh.material),this.coreMesh=null),this.glowMaterial&&(this.disposeMaterial(this.glowMaterial),this.glowMaterial=null),this.glassMaterial&&(this.disposeMaterial(this.glassMaterial),this.glassMaterial=null),this.composer&&(this.composer.dispose(),this.composer=null),this.particleRenderTarget&&(this.particleRenderTarget.dispose(),this.particleRenderTarget=null),this.particleBloomPass&&(this.particleBloomPass.dispose(),this.particleBloomPass=null),this.soulRenderTarget&&(this.soulRenderTarget.dispose(),this.soulRenderTarget=null),this.glowLayer&&(this.glowLayer.dispose(),this.glowLayer=null),this.cameraPresetManager&&(this.cameraPresetManager.dispose(),this.cameraPresetManager=null),this.controls&&(this.controls.dispose(),this.controls=null),this.keyLight?.shadow?.map&&this.keyLight.shadow.map.dispose(),this.fillLight?.shadow?.map&&this.fillLight.shadow.map.dispose(),this.rimLight?.shadow?.map&&this.rimLight.shadow.map.dispose(),this.keyLight=null,this.fillLight=null,this.rimLight=null,this.ambientLight=null,this.accentLight1=null,this.accentLight2=null,this.accentLight3=null,this.envMap&&(this.envMap.dispose(),this.envMap=null),this._envCubeRenderTarget&&(this._envCubeRenderTarget.dispose(),this._envCubeRenderTarget=null),this._envScene&&(this._envScene.traverse(e=>{e.geometry&&e.geometry.dispose(),e.material&&this.disposeMaterial(e.material)}),this._envScene.clear(),this._envScene=null),this._envCubeCamera&&(this._envCubeCamera=null),this.renderer&&(this.renderer.dispose(),this.renderer=null),this.scene.clear(),this.mixer&&(this.mixer.stopAllAction(),this.mixer=null),this.clock=null,this.camera=null,this._tempColor=null,this._tempColor2=null,this._white=null,this._tempQuat=null,this._tempEuler=null,this._quatX=null,this._quatY=null,this._quatZ=null,this._rollQuat=null,this._meshQuat=null,this._xAxis=null,this._yAxis=null,this._zAxis=null,this._cameraToMesh=null,this._cameraDir=null}}const xh=/^[og]\s*(.+)?/,Sh=/^mtllib /,wh=/^usemtl /,Eh=/^usemap /,Th=/\s+/,Ch=new xt,Ah=new xt,Ph=new xt,Dh=new xt,Rh=new xt,Ih=new dn;function Lh(){const e={objects:[],object:{},vertices:[],normals:[],colors:[],uvs:[],materials:{},materialLibraries:[],startObject:function(e,t){if(this.object&&!1===this.object.fromDeclaration)return this.object.name=e,void(this.object.fromDeclaration=!1!==t);const i=this.object&&"function"==typeof this.object.currentMaterial?this.object.currentMaterial():void 0;if(this.object&&"function"==typeof this.object._finalize&&this.object._finalize(!0),this.object={name:e||"",fromDeclaration:!1!==t,geometry:{vertices:[],normals:[],colors:[],uvs:[],hasUVIndices:!1},materials:[],smooth:!0,startMaterial:function(e,t){const i=this._finalize(!1);i&&(i.inherited||i.groupCount<=0)&&this.materials.splice(i.index,1);const n={index:this.materials.length,name:e||"",mtllib:Array.isArray(t)&&t.length>0?t[t.length-1]:"",smooth:void 0!==i?i.smooth:this.smooth,groupStart:void 0!==i?i.groupEnd:0,groupEnd:-1,groupCount:-1,inherited:!1,clone:function(e){const t={index:"number"==typeof e?e:this.index,name:this.name,mtllib:this.mtllib,smooth:this.smooth,groupStart:0,groupEnd:-1,groupCount:-1,inherited:!1};return t.clone=this.clone.bind(t),t}};return this.materials.push(n),n},currentMaterial:function(){if(this.materials.length>0)return this.materials[this.materials.length-1]},_finalize:function(e){const t=this.currentMaterial();if(t&&-1===t.groupEnd&&(t.groupEnd=this.geometry.vertices.length/3,t.groupCount=t.groupEnd-t.groupStart,t.inherited=!1),e&&this.materials.length>1)for(let e=this.materials.length-1;e>=0;e--)this.materials[e].groupCount<=0&&this.materials.splice(e,1);return e&&0===this.materials.length&&this.materials.push({name:"",smooth:this.smooth}),t}},i&&i.name&&"function"==typeof i.clone){const e=i.clone(0);e.inherited=!0,this.object.materials.push(e)}this.objects.push(this.object)},finalize:function(){this.object&&"function"==typeof this.object._finalize&&this.object._finalize(!0)},parseVertexIndex:function(e,t){const i=parseInt(e,10);return 3*(i>=0?i-1:i+t/3)},parseNormalIndex:function(e,t){const i=parseInt(e,10);return 3*(i>=0?i-1:i+t/3)},parseUVIndex:function(e,t){const i=parseInt(e,10);return 2*(i>=0?i-1:i+t/2)},addVertex:function(e,t,i){const n=this.vertices,a=this.object.geometry.vertices;a.push(n[e+0],n[e+1],n[e+2]),a.push(n[t+0],n[t+1],n[t+2]),a.push(n[i+0],n[i+1],n[i+2])},addVertexPoint:function(e){const t=this.vertices;this.object.geometry.vertices.push(t[e+0],t[e+1],t[e+2])},addVertexLine:function(e){const t=this.vertices;this.object.geometry.vertices.push(t[e+0],t[e+1],t[e+2])},addNormal:function(e,t,i){const n=this.normals,a=this.object.geometry.normals;a.push(n[e+0],n[e+1],n[e+2]),a.push(n[t+0],n[t+1],n[t+2]),a.push(n[i+0],n[i+1],n[i+2])},addFaceNormal:function(e,t,i){const n=this.vertices,a=this.object.geometry.normals;Ch.fromArray(n,e),Ah.fromArray(n,t),Ph.fromArray(n,i),Rh.subVectors(Ph,Ah),Dh.subVectors(Ch,Ah),Rh.cross(Dh),Rh.normalize(),a.push(Rh.x,Rh.y,Rh.z),a.push(Rh.x,Rh.y,Rh.z),a.push(Rh.x,Rh.y,Rh.z)},addColor:function(e,t,i){const n=this.colors,a=this.object.geometry.colors;void 0!==n[e]&&a.push(n[e+0],n[e+1],n[e+2]),void 0!==n[t]&&a.push(n[t+0],n[t+1],n[t+2]),void 0!==n[i]&&a.push(n[i+0],n[i+1],n[i+2])},addUV:function(e,t,i){const n=this.uvs,a=this.object.geometry.uvs;a.push(n[e+0],n[e+1]),a.push(n[t+0],n[t+1]),a.push(n[i+0],n[i+1])},addDefaultUV:function(){const e=this.object.geometry.uvs;e.push(0,0),e.push(0,0),e.push(0,0)},addUVLine:function(e){const t=this.uvs;this.object.geometry.uvs.push(t[e+0],t[e+1])},addFace:function(e,t,i,n,a,r,s,o,l){const h=this.vertices.length;let c=this.parseVertexIndex(e,h),u=this.parseVertexIndex(t,h),d=this.parseVertexIndex(i,h);if(this.addVertex(c,u,d),this.addColor(c,u,d),void 0!==s&&""!==s){const e=this.normals.length;c=this.parseNormalIndex(s,e),u=this.parseNormalIndex(o,e),d=this.parseNormalIndex(l,e),this.addNormal(c,u,d)}else this.addFaceNormal(c,u,d);if(void 0!==n&&""!==n){const e=this.uvs.length;c=this.parseUVIndex(n,e),u=this.parseUVIndex(a,e),d=this.parseUVIndex(r,e),this.addUV(c,u,d),this.object.geometry.hasUVIndices=!0}else this.addDefaultUV()},addPointGeometry:function(e){this.object.geometry.type="Points";const t=this.vertices.length;for(let i=0,n=e.length;i<n;i++){const n=this.parseVertexIndex(e[i],t);this.addVertexPoint(n),this.addColor(n)}},addLineGeometry:function(e,t){this.object.geometry.type="Line";const i=this.vertices.length,n=this.uvs.length;for(let t=0,n=e.length;t<n;t++)this.addVertexLine(this.parseVertexIndex(e[t],i));for(let e=0,i=t.length;e<i;e++)this.addUVLine(this.parseUVIndex(t[e],n))}};return e.startObject("",!1),e}class Bh extends Ar{constructor(e){super(e),this.materials=null}load(e,t,i,n){const a=this,r=new Rr(this.manager);r.setPath(this.path),r.setRequestHeader(this.requestHeader),r.setWithCredentials(this.withCredentials),r.load(e,function(i){try{t(a.parse(i))}catch(t){n?n(t):console.error(t),a.manager.itemError(e)}},i,n)}setMaterials(e){return this.materials=e,this}parse(e){const t=new Lh;-1!==e.indexOf("\r\n")&&(e=e.replace(/\r\n/g,"\n")),-1!==e.indexOf("\\\n")&&(e=e.replace(/\\\n/g,""));const i=e.split("\n");let n=[];for(let e=0,a=i.length;e<a;e++){const a=i[e].trimStart();if(0===a.length)continue;const r=a.charAt(0);if("#"!==r)if("v"===r){const e=a.split(Th);switch(e[0]){case"v":t.vertices.push(parseFloat(e[1]),parseFloat(e[2]),parseFloat(e[3])),e.length>=7?(Ih.setRGB(parseFloat(e[4]),parseFloat(e[5]),parseFloat(e[6]),ze),t.colors.push(Ih.r,Ih.g,Ih.b)):t.colors.push(void 0,void 0,void 0);break;case"vn":t.normals.push(parseFloat(e[1]),parseFloat(e[2]),parseFloat(e[3]));break;case"vt":t.uvs.push(parseFloat(e[1]),parseFloat(e[2]))}}else if("f"===r){const e=a.slice(1).trim().split(Th),i=[];for(let t=0,n=e.length;t<n;t++){const n=e[t];if(n.length>0){const e=n.split("/");i.push(e)}}const n=i[0];for(let e=1,a=i.length-1;e<a;e++){const a=i[e],r=i[e+1];t.addFace(n[0],a[0],r[0],n[1],a[1],r[1],n[2],a[2],r[2])}}else if("l"===r){const e=a.substring(1).trim().split(" ");let i=[];const n=[];if(-1===a.indexOf("/"))i=e;else for(let t=0,a=e.length;t<a;t++){const a=e[t].split("/");""!==a[0]&&i.push(a[0]),""!==a[1]&&n.push(a[1])}t.addLineGeometry(i,n)}else if("p"===r){const e=a.slice(1).trim().split(" ");t.addPointGeometry(e)}else if(null!==(n=xh.exec(a))){const e=(" "+n[0].slice(1).trim()).slice(1);t.startObject(e)}else if(wh.test(a))t.object.startMaterial(a.substring(7).trim(),t.materialLibraries);else if(Sh.test(a))t.materialLibraries.push(a.substring(7).trim());else if(Eh.test(a))console.warn('THREE.OBJLoader: Rendering identifier "usemap" not supported. Textures must be defined in MTL files.');else if("s"===r){if(n=a.split(" "),n.length>1){const e=n[1].trim().toLowerCase();t.object.smooth="0"!==e&&"off"!==e}else t.object.smooth=!0;const e=t.object.currentMaterial();e&&(e.smooth=t.object.smooth)}else{if("\0"===a)continue;console.warn('THREE.OBJLoader: Unexpected line: "'+a+'"')}}t.finalize();const a=new ha;if(a.materialLibraries=[].concat(t.materialLibraries),!0==!(1===t.objects.length&&0===t.objects[0].geometry.vertices.length))for(let e=0,i=t.objects.length;e<i;e++){const i=t.objects[e],n=i.geometry,r=i.materials,s="Line"===n.type,o="Points"===n.type;let l=!1;if(0===n.vertices.length)continue;const h=new Bn;h.setAttribute("position",new Tn(n.vertices,3)),n.normals.length>0&&h.setAttribute("normal",new Tn(n.normals,3)),n.colors.length>0&&(l=!0,h.setAttribute("color",new Tn(n.colors,3))),!0===n.hasUVIndices&&h.setAttribute("uv",new Tn(n.uvs,2));const c=[];for(let e=0,i=r.length;e<i;e++){const i=r[e],n=i.name+"_"+i.smooth+"_"+l;let a=t.materials[n];if(null!==this.materials)if(a=this.materials.create(i.name),!s||!a||a instanceof Ga){if(o&&a&&!(a instanceof er)){const e=new er({size:10,sizeAttenuation:!1});fn.prototype.copy.call(e,a),e.color.copy(a.color),e.map=a.map,a=e}}else{const e=new Ga;fn.prototype.copy.call(e,a),e.color.copy(a.color),a=e}void 0===a&&(a=s?new Ga:o?new er({size:1,sizeAttenuation:!1}):new xr,a.name=i.name,a.flatShading=!i.smooth,a.vertexColors=l,t.materials[n]=a),c.push(a)}let u;if(c.length>1){for(let e=0,t=r.length;e<t;e++){const t=r[e];h.addGroup(t.groupStart,t.groupCount,e)}u=s?new Ja(h,c):o?new rr(h,c):new Xn(h,c)}else u=s?new Ja(h,c[0]):o?new rr(h,c[0]):new Xn(h,c[0]);u.name=i.name,a.add(u)}else if(t.vertices.length>0){const e=new er({size:1,sizeAttenuation:!1}),i=new Bn;i.setAttribute("position",new Tn(t.vertices,3)),t.colors.length>0&&void 0!==t.colors[0]&&(i.setAttribute("color",new Tn(t.colors,3)),e.vertexColors=!0);const n=new rr(i,e);a.add(n)}return a}}const Oh="\n/**\n * Apply a single blend mode to two colors\n * @param base - Base color (RGB, 0.0-1.0 range)\n * @param blend - Blend color (RGB, 0.0-1.0 range)\n * @param mode - Blend mode index (0-17)\n * @return Blended color (RGB, 0.0-1.0 range)\n *\n * Blend Mode Reference:\n * 0 = Multiply (darkening)\n * 1 = Linear Burn (darkening, linear)\n * 2 = Color Burn (darkening, intense)\n * 3 = Color Dodge (brightening, intense)\n * 4 = Screen (brightening)\n * 5 = Overlay (contrast, screen/multiply hybrid)\n * 6 = Add (brightening, additive glow)\n * 7 = Soft Light (contrast, gentle)\n * 8 = Hard Light (contrast, strong)\n * 9 = Vivid Light (contrast, saturation boost)\n * 10 = Linear Light (contrast, linear)\n * 11 = Difference (inversion)\n * 12 = Exclusion (soft inversion)\n * 13 = Darken (comparison, darker)\n * 14 = Lighten (comparison, lighter)\n * 15 = Subtract (darkening, deep shadows)\n * 16 = Divide (brightening, ethereal glow)\n * 17 = Pin Light (posterization)\n */\nvec3 applyBlendMode(vec3 base, vec3 blend, int mode) {\n if (mode == 0) {\n // MULTIPLY: base * blend\n return base * blend;\n } else if (mode == 1) {\n // LINEAR BURN: base + blend - 1\n return max(base + blend - vec3(1.0), vec3(0.0));\n } else if (mode == 2) {\n // COLOR BURN: (blend==0.0) ? 0.0 : max((1.0-((1.0-base)/blend)), 0.0)\n return vec3(\n blend.r == 0.0 ? 0.0 : max(1.0 - ((1.0 - base.r) / blend.r), 0.0),\n blend.g == 0.0 ? 0.0 : max(1.0 - ((1.0 - base.g) / blend.g), 0.0),\n blend.b == 0.0 ? 0.0 : max(1.0 - ((1.0 - base.b) / blend.b), 0.0)\n );\n } else if (mode == 3) {\n // COLOR DODGE: (blend==1.0) ? 1.0 : min(base/(1.0-blend), 1.0)\n return vec3(\n blend.r == 1.0 ? 1.0 : min(base.r / (1.0 - blend.r), 1.0),\n blend.g == 1.0 ? 1.0 : min(base.g / (1.0 - blend.g), 1.0),\n blend.b == 1.0 ? 1.0 : min(base.b / (1.0 - blend.b), 1.0)\n );\n } else if (mode == 4) {\n // SCREEN: 1 - (1 - base) * (1 - blend)\n return vec3(1.0) - (vec3(1.0) - base) * (vec3(1.0) - blend);\n } else if (mode == 5) {\n // OVERLAY: base < 0.5 ? (2 * base * blend) : (1 - 2 * (1 - base) * (1 - blend))\n return vec3(\n base.r < 0.5 ? (2.0 * base.r * blend.r) : (1.0 - 2.0 * (1.0 - base.r) * (1.0 - blend.r)),\n base.g < 0.5 ? (2.0 * base.g * blend.g) : (1.0 - 2.0 * (1.0 - base.g) * (1.0 - blend.g)),\n base.b < 0.5 ? (2.0 * base.b * blend.b) : (1.0 - 2.0 * (1.0 - base.b) * (1.0 - blend.b))\n );\n } else if (mode == 6) {\n // ADD (LINEAR DODGE): base + blend\n return min(base + blend, vec3(1.0));\n } else if (mode == 7) {\n // SOFT LIGHT: blend < 0.5 ? (2*base*blend + base^2*(1-2*blend)) : (sqrt(base)*(2*blend-1) + 2*base*(1-blend))\n return vec3(\n blend.r < 0.5 ? (2.0 * base.r * blend.r + base.r * base.r * (1.0 - 2.0 * blend.r)) : (sqrt(base.r) * (2.0 * blend.r - 1.0) + 2.0 * base.r * (1.0 - blend.r)),\n blend.g < 0.5 ? (2.0 * base.g * blend.g + base.g * base.g * (1.0 - 2.0 * blend.g)) : (sqrt(base.g) * (2.0 * blend.g - 1.0) + 2.0 * base.g * (1.0 - blend.g)),\n blend.b < 0.5 ? (2.0 * base.b * blend.b + base.b * base.b * (1.0 - 2.0 * blend.b)) : (sqrt(base.b) * (2.0 * blend.b - 1.0) + 2.0 * base.b * (1.0 - blend.b))\n );\n } else if (mode == 8) {\n // HARD LIGHT: blend < 0.5 ? (2 * base * blend) : (1 - 2 * (1 - base) * (1 - blend))\n return vec3(\n blend.r < 0.5 ? (2.0 * base.r * blend.r) : (1.0 - 2.0 * (1.0 - base.r) * (1.0 - blend.r)),\n blend.g < 0.5 ? (2.0 * base.g * blend.g) : (1.0 - 2.0 * (1.0 - base.g) * (1.0 - blend.g)),\n blend.b < 0.5 ? (2.0 * base.b * blend.b) : (1.0 - 2.0 * (1.0 - base.b) * (1.0 - blend.b))\n );\n } else if (mode == 9) {\n // VIVID LIGHT: blend < 0.5 ? ColorBurn(base, 2*blend) : ColorDodge(base, 2*(blend-0.5))\n return vec3(\n blend.r < 0.5 ? (blend.r == 0.0 ? 0.0 : max(1.0 - ((1.0 - base.r) / (2.0 * blend.r)), 0.0)) : (blend.r == 1.0 ? 1.0 : min(base.r / (2.0 * (1.0 - blend.r)), 1.0)),\n blend.g < 0.5 ? (blend.g == 0.0 ? 0.0 : max(1.0 - ((1.0 - base.g) / (2.0 * blend.g)), 0.0)) : (blend.g == 1.0 ? 1.0 : min(base.g / (2.0 * (1.0 - blend.g)), 1.0)),\n blend.b < 0.5 ? (blend.b == 0.0 ? 0.0 : max(1.0 - ((1.0 - base.b) / (2.0 * blend.b)), 0.0)) : (blend.b == 1.0 ? 1.0 : min(base.b / (2.0 * (1.0 - blend.b)), 1.0))\n );\n } else if (mode == 10) {\n // LINEAR LIGHT: blend < 0.5 ? LinearBurn(base, 2*blend) : LinearDodge(base, 2*(blend-0.5))\n return vec3(\n blend.r < 0.5 ? max(base.r + 2.0 * blend.r - 1.0, 0.0) : min(base.r + 2.0 * (blend.r - 0.5), 1.0),\n blend.g < 0.5 ? max(base.g + 2.0 * blend.g - 1.0, 0.0) : min(base.g + 2.0 * (blend.g - 0.5), 1.0),\n blend.b < 0.5 ? max(base.b + 2.0 * blend.b - 1.0, 0.0) : min(base.b + 2.0 * (blend.b - 0.5), 1.0)\n );\n } else if (mode == 11) {\n // DIFFERENCE: abs(base - blend)\n return abs(base - blend);\n } else if (mode == 12) {\n // EXCLUSION: base + blend - 2 * base * blend\n return base + blend - 2.0 * base * blend;\n } else if (mode == 13) {\n // DARKEN: min(base, blend)\n return min(base, blend);\n } else if (mode == 14) {\n // LIGHTEN: max(base, blend)\n return max(base, blend);\n } else if (mode == 15) {\n // SUBTRACT: max(base - blend, 0)\n return max(base - blend, vec3(0.0));\n } else if (mode == 16) {\n // DIVIDE: base / (blend + epsilon)\n return min(base / (blend + vec3(0.001)), vec3(1.0));\n } else {\n // PIN LIGHT (mode 17): Replaces colors based on blend brightness\n float blendLum = (blend.r + blend.g + blend.b) / 3.0;\n if (blendLum > 0.5) {\n // Lighten: replace pixels darker than blend\n return max(base, 2.0 * blend - vec3(1.0));\n } else {\n // Darken: replace pixels lighter than blend\n return min(base, 2.0 * blend);\n }\n }\n}\n",Fh=["Multiply","Linear Burn","Color Burn","Color Dodge","Screen","Overlay","Add","Soft Light","Hard Light","Vivid Light","Linear Light","Difference","Exclusion","Darken","Lighten","Subtract","Divide","Pin Light"];function Uh(e){return Fh[e]||"Unknown"}function zh(e){const t=Fh.indexOf(e);return-1!==t?t:0}const kh=`\n/**\n * Moon Fragment Shader with Blend Layers\n *\n * Supports up to 4 sequential blend mode layers for complex color grading\n * using universal Photoshop-style blend modes\n */\n\nuniform sampler2D colorMap;\nuniform sampler2D normalMap;\nuniform vec2 shadowOffset;\nuniform float shadowCoverage;\nuniform float shadowSoftness;\nuniform vec3 glowColor;\nuniform float glowIntensity;\nuniform float opacity;\n\n// Lunar Eclipse (Blood Moon) uniforms\nuniform float eclipseProgress;\nuniform float eclipseIntensity;\nuniform vec3 bloodMoonColor;\nuniform float emissiveStrength;\nuniform vec2 eclipseShadowPos; // Shadow center position (-2 to 1)\nuniform float eclipseShadowRadius; // Shadow radius\n\n// Eclipse Color Grading (from color pickers)\nuniform vec3 eclipseShadowColor;\nuniform vec3 eclipseMidtoneColor;\nuniform vec3 eclipseHighlightColor;\nuniform vec3 eclipseGlowColor;\n\n// Brightness model toggle (0 = centeredness-based, 1 = edge-based)\nuniform float eclipseBrightnessModel;\n\n// Shadow darkness control (0.0 = no darkening, 1.0 = maximum darkening)\nuniform float shadowDarkness;\n\n// Blend Layer Uniforms (up to 4 layers)\nuniform float layer1Mode;\nuniform float layer1Strength;\nuniform float layer1Enabled;\n\nuniform float layer2Mode;\nuniform float layer2Strength;\nuniform float layer2Enabled;\n\nuniform float layer3Mode;\nuniform float layer3Strength;\nuniform float layer3Enabled;\n\nuniform float layer4Mode;\nuniform float layer4Strength;\nuniform float layer4Enabled;\n\nvarying vec3 vPosition;\nvarying vec3 vWorldPosition;\nvarying vec3 vViewNormal;\nvarying vec3 vViewPosition;\nvarying vec2 vUv;\n\n// ═══════════════════════════════════════════════════════════════════════════\n// UNIVERSAL BLEND MODES (injected from utils/blendModes.js)\n// ═══════════════════════════════════════════════════════════════════════════\n${Oh}\n\nvoid main() {\n // DIRECTIONAL SHADOW in VIEW SPACE - camera-relative moon phase\n // Shadow stays fixed relative to screen; rotating moon doesn't change which side is lit\n vec3 viewNormal = normalize(vViewNormal);\n\n float lightX = shadowOffset.x;\n float lightY = shadowOffset.y;\n float offsetMagnitude = length(vec2(lightX, lightY));\n float lightZ = 1.0 - pow(offsetMagnitude, 1.5);\n vec3 lightDir = normalize(vec3(lightX, lightY, lightZ));\n\n // Light direction is in view space (camera-relative)\n float facing = dot(viewNormal, lightDir);\n float edgeWidth = max(fwidth(facing) * 4.0, shadowSoftness * 3.0);\n float shadowFactor = smoothstep(-edgeWidth, edgeWidth, facing);\n\n // Sample moon surface texture\n vec4 texColor = texture2D(colorMap, vUv);\n float brightness = texColor.r + texColor.g + texColor.b;\n if (brightness < 0.03) {\n texColor = vec4(0.5, 0.5, 0.5, 1.0);\n }\n\n // VIEW DIRECTION (for eclipse rim effects only, NOT for general lighting)\n vec3 viewDir = normalize(-vViewPosition);\n float rimFactor = dot(viewNormal, viewDir);\n\n // EARTHSHINE - faint blue glow on shadowed side\n vec3 earthshine = texColor.rgb * 0.01 * vec3(0.35, 0.4, 0.6);\n\n // Apply shadow transition (moon phase only - NOT camera-based)\n // The moon texture is uniformly visible; only the phase shadow creates darkness\n float litFactor = pow(shadowFactor, 2.0);\n vec3 detailEnhanced = texColor.rgb * 1.08;\n float textureLuminance = dot(texColor.rgb, vec3(0.299, 0.587, 0.114));\n detailEnhanced = mix(texColor.rgb * 0.95, texColor.rgb * 1.12, smoothstep(0.3, 0.7, textureLuminance));\n\n // Lit areas show texture; shadowed areas show earthshine\n // NO camera-based limb darkening - moon rotates, texture stays uniformly lit\n vec3 shadowedColor = mix(earthshine, detailEnhanced, litFactor);\n\n vec3 emissive = vec3(0.02, 0.02, 0.02) * shadowFactor;\n vec3 emotionGlow = glowColor * glowIntensity * 0.02 * shadowFactor;\n vec3 finalColor = shadowedColor + emissive + emotionGlow;\n\n // ═══════════════════════════════════════════════════════════════════════════\n // LUNAR ECLIPSE EFFECT (Earth's Shadow Sweep)\n // Shadow position drives everything - automatically transitions from dark sharp shadow to red glow\n // ═══════════════════════════════════════════════════════════════════════════\n // Only apply eclipse if shadow is actually near the moon (shadowX > -1.5)\n if (eclipseProgress > 0.001 && eclipseShadowPos.x > -1.5) {\n // Eclipse progress is now pre-modulated by UI based on shadow position\n // No need for shader-side modulation\n float effectiveProgress = eclipseProgress;\n\n // Calculate distance from shadow center using VIEW-SPACE position (3D spherical)\n // This creates a proper circular shadow on the sphere, not a flat UV-based cutoff\n // viewNormal.xy ranges -1 to 1, scale to match UV range (0 to 0.5 from center)\n vec2 shadowCenter = vec2(eclipseShadowPos.x, eclipseShadowPos.y);\n vec2 spherePos = viewNormal.xy * 0.5; // Scale to UV-equivalent range\n float distFromShadow = length(spherePos - shadowCenter);\n\n // TOTALITY FACTOR: Based on how centered the shadow is on the moon\n // When shadowX near 0.0 (centered), we're at totality - brightens and reddens\n // When shadowX far from 0.0 (off to side), we're partial - stays dark and diffuse\n float shadowCenteredness = 1.0 - smoothstep(0.0, 0.6, abs(eclipseShadowPos.x));\n float totalityFactor = shadowCenteredness;\n\n // Earth's umbra (full shadow) - DIFFUSE at partials, sharper at totality\n float umbraRadius = eclipseShadowRadius * 0.7;\n // Edge softness: very diffuse at partials (0.25), sharp at totality (0.05)\n float umbraEdge = mix(0.25, 0.05, totalityFactor);\n float umbra = 1.0 - smoothstep(umbraRadius - umbraEdge, umbraRadius + umbraEdge, distFromShadow);\n\n // Earth's penumbra (partial shadow) - wider and softer\n // Penumbra extends further at partials, tighter at totality\n float penumbraRadius = eclipseShadowRadius * mix(1.4, 1.1, totalityFactor);\n float penumbraEdge = mix(0.3, 0.15, totalityFactor);\n float penumbra = 1.0 - smoothstep(penumbraRadius - penumbraEdge, penumbraRadius + penumbraEdge, distFromShadow);\n\n // UMBRA DARKENING: Much darker at partials, lighter at totality\n // Partials: 85% darkening (very dark shadow)\n // Totality: 30% darkening (blood moon glow visible)\n float baseDarkening = mix(0.85, 0.30, totalityFactor);\n float umbraDarkeningAmount = baseDarkening * shadowDarkness;\n float umbraDarkening = umbra * effectiveProgress;\n\n // Apply base darkening first\n finalColor *= (1.0 - umbraDarkening * umbraDarkeningAmount);\n\n // PENUMBRA: Darker gradient at partials, lighter at totality\n float penumbraDarkening = (penumbra - umbra) * effectiveProgress;\n float penumbraDarkenAmount = mix(0.50, 0.20, totalityFactor); // 50% at partials, 20% at totality\n finalColor *= (1.0 - penumbraDarkening * penumbraDarkenAmount);\n\n // BLOOD MOON COLOR: Applied throughout entire eclipse, not just totality\n // Matches real lunar eclipse behavior - color present at all phases\n // Use totality factor to control BRIGHTNESS, not color presence\n float colorStrength = umbra; // Color appears wherever umbra shadow is present\n vec3 bloodMoonTint = mix(vec3(1.0), eclipseMidtoneColor, colorStrength);\n finalColor *= bloodMoonTint;\n\n // REALISTIC ECLIPSE PROGRESSION (corrected):\n // Shadow sweeps LEFT → RIGHT but NEVER fully covers moon during partials\n // A bright crescent ALWAYS remains visible (shadow stops before covering moon)\n // Just before totality: shadow nearly covers moon, blood moon glow appears\n // The glow spreads FROM the visible bright crescent INTO the shadowed area\n // During totality: shadow finally covers entire moon, full blood moon\n\n // Use view-space normal for spherical position (not UV)\n // Scale to match UV range\n float pixelX = viewNormal.x * 0.5;\n\n // THE LIT CRESCENT: Always visible during partial phases\n // During partials, the moon is partially lit (outside umbra)\n // Only during totality does the shadow fully cover the moon\n\n // Where is the bright crescent? Opposite side from shadow\n // Approaching (shadowX < 0): crescent on RIGHT (positive X)\n // Leaving (shadowX > 0): crescent on LEFT (negative X)\n float crescentSide = -sign(eclipseShadowPos.x);\n\n // CRESCENT EDGE: Where shadow meets lit surface\n // This is always VISIBLE during partials - never goes to zero\n float umbraEdgeX = eclipseShadowPos.x + (umbraRadius * crescentSide);\n\n // Distance from this pixel to the lit crescent edge\n // Positive = inside shadow, negative = in lit crescent\n float distFromLitEdge = (pixelX - umbraEdgeX) * crescentSide;\n\n // GRADIENT: Blood moon glow spreads from the LIT CRESCENT\n // Only pixels INSIDE the shadow get the gradient\n // Gradient is strongest at the umbra edge (where crescent is)\n float crescentGradient = smoothstep(0.5, 0.0, distFromLitEdge);\n\n // BRIGHTNESS CONTROL: Glow only appears near totality\n // When shadow is far from center: stays dark\n // When shadow approaches center: glow spreads from crescent\n float brightnessControl = umbra * crescentGradient * totalityFactor;\n\n // During full totality (shadowX ≈ 0), switch to uniform brightness\n brightnessControl = mix(brightnessControl, umbra * totalityFactor, totalityFactor);\n\n // EMISSIVE GLOW: Blood moon color spreading from crescent\n float glowStrength = mix(0.0, 1.0, brightnessControl);\n vec3 atmosphereGlow = eclipseMidtoneColor * emissiveStrength * glowStrength * umbra;\n finalColor += atmosphereGlow;\n\n // RIM GLOW: Atmospheric limb brightening\n float limbGlowStrength = mix(0.0, 1.5, brightnessControl);\n float limbGlow = pow(1.0 - rimFactor, 3.0) * umbra;\n vec3 rimColor = mix(eclipseGlowColor, eclipseHighlightColor, 0.5);\n finalColor += rimColor * limbGlow * emissiveStrength * limbGlowStrength;\n\n // ═══════════════════════════════════════════════════════════════════════════\n // ECLIPSE BLEND LAYERS (Applied AFTER blood moon color)\n // Applied throughout eclipse wherever umbra is present\n // Strength modulated by totality factor for smooth brightness transitions\n // ═══════════════════════════════════════════════════════════════════════════\n\n // Layer 1: Linear Burn @ 0.634\n if (layer1Enabled > 0.5 && effectiveProgress > 0.1) {\n vec3 blendColor1 = vec3(min(layer1Strength, 1.0));\n int mode1 = int(layer1Mode + 0.5);\n vec3 blended1 = clamp(applyBlendMode(finalColor, blendColor1, mode1), 0.0, 1.0);\n // Apply at FULL strength wherever umbra exists\n finalColor = clamp(mix(finalColor, blended1, umbra), 0.0, 1.0);\n }\n\n // Layer 2: Multiply @ 3.086 - Brightness enhancement\n if (layer2Enabled > 0.5 && effectiveProgress > 0.1) {\n // Apply full brightness boost wherever umbra exists\n vec3 brightened = clamp(finalColor * min(layer2Strength, 5.0), 0.0, 1.0);\n finalColor = mix(finalColor, brightened, umbra);\n }\n\n // Layer 3: Hard Light @ 0.351\n if (layer3Enabled > 0.5 && effectiveProgress > 0.1) {\n vec3 blendColor3 = vec3(min(layer3Strength, 1.0));\n int mode3 = int(layer3Mode + 0.5);\n vec3 blended3 = clamp(applyBlendMode(finalColor, blendColor3, mode3), 0.0, 1.0);\n // Apply at FULL strength wherever umbra exists\n finalColor = clamp(mix(finalColor, blended3, umbra), 0.0, 1.0);\n }\n\n // Layer 4: Manual UI layer\n if (layer4Enabled > 0.5 && effectiveProgress > 0.1) {\n vec3 blendColor4 = vec3(min(layer4Strength, 1.0));\n int mode4 = int(layer4Mode + 0.5);\n vec3 blended4 = clamp(applyBlendMode(finalColor, blendColor4, mode4), 0.0, 1.0);\n finalColor = clamp(mix(finalColor, blended4, umbra), 0.0, 1.0);\n }\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // UNIVERSAL BLEND MODE LAYERS (Only applied when eclipse is OFF)\n // These are manual UI-driven color grading tools\n // NOTE: These are DISABLED by default - they're NEVER used since the multiplexer\n // demo doesn't enable them. This section exists for potential future manual control.\n // ═══════════════════════════════════════════════════════════════════════════\n // INTENTIONALLY COMMENTED OUT - these would interfere with eclipse blend layers\n // if (eclipseProgress < 0.001) {\n // // Layer 1 - manual UI control only\n // if (layer1Enabled > 0.5) {\n // vec3 blendColor1 = vec3(layer1Strength);\n // int mode1 = int(layer1Mode + 0.5);\n // finalColor = applyBlendMode(finalColor, blendColor1, mode1);\n // }\n // }\n\n gl_FragColor = vec4(finalColor, opacity);\n}\n`,Nh=55.5,Gh=-85,Vh=-60.5,Hh={enabled:!0,strength:1,lockedFace:[0,0,1],lerpSpeed:10},Wh={new:{x:200,y:0,coverage:0},"waxing-crescent":{x:1.5,y:0,coverage:.25},"first-quarter":{x:1,y:0,coverage:.5},"waxing-gibbous":{x:.7,y:0,coverage:.75},full:{x:0,y:0,coverage:1},"waning-gibbous":{x:-.7,y:0,coverage:.75},"last-quarter":{x:-1,y:0,coverage:.5},"waning-crescent":{x:-1.5,y:0,coverage:.25}};function jh(){return Object.keys(Wh)}function Xh(e){const t=(e%1+1)%1;let i;if(t<=.5){const e=2*t;i=10*Math.pow(1-e,2.5)}else{const e=2*(t-.5);if(e<=.25)i=e/.25*-.3;else if(e<=.5)i=-.3-(e-.25)/.25*.7;else if(e<=.75)i=-1-(e-.5)/.25*2;else{const t=(e-.75)/.25;i=13*Math.pow(t,.4)-3}}return{x:i,y:0,coverage:1-2*Math.abs(t-.5)}}function qh(e=64,t=64){const i=new vr(.5,e,t);return i.userData.tracked=!0,i}function Yh(e){if(e&&(e.geometry&&e.geometry.dispose(),e.material)){const{material:t}=e;t.userData&&t.userData.pendingTextures&&(t.userData.pendingTextures.forEach(({texture:e})=>{e&&e.dispose()}),t.userData.pendingTextures.clear()),t.map&&t.map.dispose(),t.normalMap&&t.normalMap.dispose(),t.uniforms&&(t.uniforms.colorMap&&t.uniforms.colorMap.value&&t.uniforms.colorMap.value.dispose(),t.uniforms.normalMap&&t.uniforms.normalMap.value&&t.uniforms.normalMap.value.dispose()),t.dispose()}}function $h(e,t={}){const i=t.resolution||"4k",n=t.assetBasePath||"/assets",a=`${n}/textures/Moon/moon-color-${i}.jpg`,r=`${n}/textures/Moon/moon-normal-${i}.jpg`,s=new Map;s.set(a,{texture:null});const o=e.load(a,e=>{const t=s.get(a);t&&(t.texture=e),s.delete(a)},void 0,e=>{console.error(`❌ Failed to load moon color texture (${i}):`,e),s.delete(a)});s.set(r,{texture:null});const l=e.load(r,e=>{const t=s.get(r);t&&(t.texture=e),s.delete(r)},void 0,e=>{console.error(`❌ Failed to load moon normal map (${i}):`,e),s.delete(r)});o.wrapS=o.wrapT=B,l.wrapS=l.wrapT=B,o.anisotropy=16,l.anisotropy=16;const h=new Mr({map:o,normalMap:l,normalScale:new Mt(1.5,1.5),roughness:.7,metalness:0,emissive:new dn(.3,.3,.3),emissiveIntensity:.5,transparent:!1,side:0});return h.userData.pendingTextures=s,h}function Zh(e=new dn(16777215),t=0){return new Mr({color:15263976,roughness:.9,metalness:0,emissive:e,emissiveIntensity:t})}function Kh(e,t={}){const i=t.resolution||"4k",n=t.glowColor||new dn(1,1,1),a=t.glowIntensity||1,r=t.shadowType||"crescent",s=t.assetBasePath||"/assets";let o,l;if(void 0!==t.shadowOffsetX)({shadowOffsetX:o}=t),l=void 0!==t.shadowOffsetY?t.shadowOffsetY:0;else if(void 0!==t.moonPhase){let e;"string"==typeof t.moonPhase?([e]=[Wh[t.moonPhase]],e||(console.warn(`Unknown moon phase: ${t.moonPhase}, using waxing-crescent`),e=Wh["waxing-crescent"])):e="number"==typeof t.moonPhase?Xh(t.moonPhase):Wh["waxing-crescent"],o=e.x,l=e.y}else{const e=Wh["waxing-crescent"];o=e.x,l=e.y}const h=void 0!==t.shadowCoverage?t.shadowCoverage:.85,c=`${s}/textures/Moon/moon-color-${i}.jpg`,u=`${s}/textures/Moon/moon-normal-${i}.jpg`,{vertexShader:d,fragmentShader:p}=function(e){return"crescent"===e||console.warn(`Unknown shadow type: ${e}, defaulting to crescent`),{vertexShader:"\n/**\n * Moon Crescent Vertex Shader\n * Passes world-space normal to fragment shader for realistic lighting\n */\n\nvarying vec3 vPosition; // LOCAL position\nvarying vec3 vWorldPosition;\nvarying vec3 vWorldNormal; // WORLD SPACE normal (rotates with moon)\nvarying vec3 vViewPosition;\nvarying vec2 vUv;\n\nvoid main() {\n vUv = uv;\n vPosition = position;\n\n // Transform normal to WORLD space (not view space)\n // This makes the shadow rotate with the moon geometry\n vWorldNormal = normalize(mat3(modelMatrix) * normal);\n\n vec4 worldPosition = modelMatrix * vec4(position, 1.0);\n vWorldPosition = worldPosition.xyz;\n vec4 viewPosition = viewMatrix * worldPosition;\n vViewPosition = viewPosition.xyz;\n gl_Position = projectionMatrix * viewPosition;\n}\n",fragmentShader:"\n/**\n * Moon Crescent Fragment Shader\n *\n * Uses directional half-space test in WORLD SPACE to create realistic terminator:\n * - Light direction fixed in world space (like the sun)\n * - Normals rotate with moon geometry (in world space)\n * - dot(normal, lightDir) < 0 = shadow side\n * - dot(normal, lightDir) > 0 = lit side\n * - Smooth terminator with earthshine on dark side\n */\n\nuniform sampler2D colorMap;\nuniform sampler2D normalMap;\nuniform vec2 shadowOffset; // Controls light direction (x=horizontal, y=vertical)\nuniform float shadowCoverage; // Unused for directional shadow\nuniform float shadowSoftness; // Terminator edge softness (default: 0.05)\nuniform vec3 glowColor;\nuniform float glowIntensity;\nuniform float opacity; // Fade in opacity (0-1) to prevent gray flash during texture load\n\n// Lunar Eclipse (Blood Moon) uniforms\nuniform float eclipseProgress; // 0.0 = no eclipse, 1.0 = totality\nuniform float eclipseIntensity; // Darkening strength (0.0-1.0)\nuniform vec3 bloodMoonColor; // Deep reddish-orange for total eclipse\nuniform float blendMode; // 0=Multiply, 1=LinearBurn, 2=ColorBurn, 3=ColorDodge, 4=Screen, 5=Overlay\nuniform float blendStrength; // Blend strength multiplier (0.0-5.0)\nuniform float emissiveStrength; // Emissive glow strength (0.0-1.0)\n\nvarying vec3 vPosition;\nvarying vec3 vWorldPosition;\nvarying vec3 vWorldNormal; // WORLD SPACE normal (rotates with moon)\nvarying vec3 vViewPosition;\nvarying vec2 vUv;\n\nvoid main() {\n // DIRECTIONAL SHADOW in WORLD SPACE - realistic moon phase lighting\n // Light direction is fixed in world space, shadow rotates with moon\n\n // Use world-space normal (rotates with moon geometry)\n vec3 worldNormal = normalize(vWorldNormal);\n\n // Light direction in WORLD SPACE\n // shadowOffset.x controls horizontal angle (left/right)\n // shadowOffset.y controls vertical angle (up/down)\n // For thin crescents, we need extreme angles (light from the side or behind)\n\n float lightX = shadowOffset.x;\n float lightY = shadowOffset.y;\n\n // Adaptive Z component with LOGARITHMIC scaling for wider angular range\n // Goal: Spread phases across full 0° to 180° instead of plateauing at 135°\n //\n // Target angles after normalization:\n // - Full moon (x=0): 0° (light from front)\n // - Quarter moon (x=1): 90° (light from side)\n // - Crescent (x=3): 120° (thin crescent)\n // - New moon (x=10): 170° (nearly behind)\n\n float offsetMagnitude = length(vec2(lightX, lightY));\n\n // Use exponential decay for Z to spread angular range\n // Formula: Z = 1.0 - offsetMagnitude^1.5 for better distribution\n float lightZ = 1.0 - pow(offsetMagnitude, 1.5);\n\n // Normalize the light direction vector\n vec3 lightDir = normalize(vec3(lightX, lightY, lightZ));\n\n // Calculate how much this fragment faces the light source\n float facing = dot(worldNormal, lightDir);\n\n // Smooth transition at terminator (shadow boundary)\n // Softer edge for realistic lunar terminator (like real moon photography)\n // Use fwidth() for automatic screen-space anti-aliasing\n float edgeWidth = max(fwidth(facing) * 4.0, shadowSoftness * 3.0);\n float shadowFactor = smoothstep(-edgeWidth, edgeWidth, facing);\n\n // Sample moon surface texture\n vec4 texColor = texture2D(colorMap, vUv);\n\n // Fallback to gray if texture not loaded yet\n float brightness = texColor.r + texColor.g + texColor.b;\n if (brightness < 0.03) {\n texColor = vec4(0.5, 0.5, 0.5, 1.0);\n }\n\n // LIMB DARKENING: Moon gets darker at edges (spherical falloff)\n vec3 viewDir = normalize(-vViewPosition);\n float rimFactor = dot(worldNormal, viewDir);\n float limbDarkening = smoothstep(0.0, 0.6, rimFactor); // Subtle edge darkening\n\n // DIFFUSE LIGHTING: Vary brightness across lit surface (not uniform)\n // More realistic Lambertian diffuse reflection\n float diffuse = max(facing, 0.0);\n float diffuseLighting = mix(0.7, 1.0, diffuse); // Subtle variation\n\n // EARTHSHINE: Almost invisible (~1% for ultimate realism)\n vec3 earthshine = texColor.rgb * 0.01 * vec3(0.35, 0.4, 0.6);\n\n // Apply dramatic shadow transition with maximum contrast\n float litFactor = pow(shadowFactor, 2.0); // Maximum contrast\n\n // TEXTURE ENHANCEMENT: Boost surface detail contrast\n // Slightly darken dark areas, brighten bright areas of texture\n vec3 detailEnhanced = texColor.rgb * 1.08; // Subtle boost\n float textureLuminance = dot(texColor.rgb, vec3(0.299, 0.587, 0.114));\n detailEnhanced = mix(texColor.rgb * 0.95, texColor.rgb * 1.12, smoothstep(0.3, 0.7, textureLuminance));\n\n // Combine enhanced texture with diffuse lighting\n vec3 litColor = detailEnhanced * diffuseLighting;\n vec3 shadowedColor = mix(earthshine, litColor, litFactor);\n\n // Apply limb darkening (slightly stronger for more depth)\n shadowedColor *= mix(0.6, 1.0, limbDarkening);\n\n // Nearly zero emissive for pure realism\n vec3 emissive = vec3(0.02, 0.02, 0.02) * shadowFactor;\n\n // Emotion glow (almost invisible)\n vec3 emotionGlow = glowColor * glowIntensity * 0.02 * shadowFactor;\n\n // Combine all lighting components\n vec3 finalColor = shadowedColor + emissive + emotionGlow;\n\n // ═══════════════════════════════════════════════════════════════════════════\n // LUNAR ECLIPSE (BLOOD MOON) EFFECT\n // ═══════════════════════════════════════════════════════════════════════════\n // Simulates Earth's umbral shadow with Rayleigh scattering (reddish glow)\n if (eclipseProgress > 0.001) {\n // Calculate gradient from lit edge to dark center\n // Use rim factor (view angle) to create radial gradient\n float gradientFactor = rimFactor; // 1.0 at edges, 0.0 at center\n\n // Darken the moon (Earth's shadow)\n float darkeningFactor = 1.0 - eclipseIntensity;\n finalColor *= darkeningFactor;\n\n // ═══════════════════════════════════════════════════════════════════\n // PHOTOSHOP-STYLE BLEND MODES: Multiple modes for deep saturation control\n // ═══════════════════════════════════════════════════════════════════\n\n // Define blood moon gradient colors\n vec3 deepRed = vec3(0.6, 0.2, 0.12); // Dark burnt red-orange (center)\n vec3 brightOrange = vec3(0.95, 0.45, 0.22); // Bright burnt orange (edges)\n\n // Create radial gradient from center (dark) to edge (bright)\n vec3 bloodGradient = mix(deepRed, brightOrange, pow(gradientFactor, 1.8));\n\n // Apply blend strength multiplier\n vec3 blendColor = bloodGradient * blendStrength;\n\n // Calculate all blend modes\n vec3 finalBlend;\n int mode = int(blendMode + 0.5); // Round to nearest int\n\n if (mode == 0) {\n // MULTIPLY: base * blend\n finalBlend = finalColor * blendColor;\n } else if (mode == 1) {\n // LINEAR BURN: base + blend - 1\n finalBlend = max(finalColor + blendColor - vec3(1.0), vec3(0.0));\n } else if (mode == 2) {\n // COLOR BURN: (blend==0.0) ? 0.0 : max((1.0-((1.0-base)/blend)), 0.0)\n finalBlend = vec3(\n blendColor.r == 0.0 ? 0.0 : max(1.0 - ((1.0 - finalColor.r) / blendColor.r), 0.0),\n blendColor.g == 0.0 ? 0.0 : max(1.0 - ((1.0 - finalColor.g) / blendColor.g), 0.0),\n blendColor.b == 0.0 ? 0.0 : max(1.0 - ((1.0 - finalColor.b) / blendColor.b), 0.0)\n );\n } else if (mode == 3) {\n // COLOR DODGE: (blend==1.0) ? 1.0 : min(base/(1.0-blend), 1.0)\n finalBlend = vec3(\n blendColor.r == 1.0 ? 1.0 : min(finalColor.r / (1.0 - blendColor.r), 1.0),\n blendColor.g == 1.0 ? 1.0 : min(finalColor.g / (1.0 - blendColor.g), 1.0),\n blendColor.b == 1.0 ? 1.0 : min(finalColor.b / (1.0 - blendColor.b), 1.0)\n );\n } else if (mode == 4) {\n // SCREEN: 1 - (1 - base) * (1 - blend)\n finalBlend = vec3(1.0) - (vec3(1.0) - finalColor) * (vec3(1.0) - blendColor);\n } else {\n // OVERLAY: base < 0.5 ? (2 * base * blend) : (1 - 2 * (1 - base) * (1 - blend))\n finalBlend = vec3(\n finalColor.r < 0.5 ? (2.0 * finalColor.r * blendColor.r) : (1.0 - 2.0 * (1.0 - finalColor.r) * (1.0 - blendColor.r)),\n finalColor.g < 0.5 ? (2.0 * finalColor.g * blendColor.g) : (1.0 - 2.0 * (1.0 - finalColor.g) * (1.0 - blendColor.g)),\n finalColor.b < 0.5 ? (2.0 * finalColor.b * blendColor.b) : (1.0 - 2.0 * (1.0 - finalColor.b) * (1.0 - blendColor.b))\n );\n }\n\n // Apply blood moon effect\n finalColor = mix(finalColor, finalBlend, eclipseProgress);\n\n // Add emissive glow for visibility\n finalColor += bloodGradient * emissiveStrength * eclipseProgress;\n\n // Add bright rim glow during totality (refracted atmosphere light)\n if (eclipseProgress > 0.7) {\n float rimIntensity = pow(gradientFactor, 2.5); // Sharp falloff from edge\n vec3 rimGlow = brightOrange * rimIntensity * (eclipseProgress - 0.7) * 2.5;\n finalColor += rimGlow;\n }\n }\n\n // Apply fade-in opacity to prevent gray flash during texture load\n gl_FragColor = vec4(finalColor, opacity);\n}\n"}}(r),m=new Jn({uniforms:{colorMap:{value:null},normalMap:{value:null},shadowOffset:{value:new Mt(o,l)},shadowCoverage:{value:h},shadowSoftness:{value:.05},glowColor:{value:n},glowIntensity:{value:a},opacity:{value:0},eclipseProgress:{value:0},eclipseIntensity:{value:0},bloodMoonColor:{value:[.85,.18,.08]},blendMode:{value:0},blendStrength:{value:2},emissiveStrength:{value:.39},eclipseShadowPos:{value:[-2,0]},eclipseShadowRadius:{value:1.2},eclipseShadowColor:{value:[.85,.08,.02]},eclipseMidtoneColor:{value:[1,.12,.03]},eclipseHighlightColor:{value:[1,.35,.08]},eclipseGlowColor:{value:[1,.4,.1]}},vertexShader:d,fragmentShader:p,transparent:!0,side:0}),f=new Map;f.set(c,{texture:null});const g=e.load(c,e=>{m.uniforms.colorMap.value=e;const t=performance.now(),i=()=>{const e=performance.now()-t,n=Math.min(e/300,1);m.uniforms.opacity.value=n,m.needsUpdate=!0,n<1&&requestAnimationFrame(i)};i();const n=f.get(c);n&&(n.texture=e),f.delete(c)},void 0,e=>{console.error("❌ Failed to load moon crescent color texture:",e),f.delete(c)});f.set(u,{texture:null});const v=e.load(u,e=>{m.uniforms.normalMap.value=e,m.needsUpdate=!0;const t=f.get(u);t&&(t.texture=e),f.delete(u)},void 0,e=>{console.error("❌ Failed to load moon crescent normal map:",e),f.delete(u)});return g.wrapS=g.wrapT=B,v.wrapS=v.wrapT=B,g.anisotropy=16,v.anisotropy=16,m.userData.pendingTextures=f,m}function Qh(e,t={}){return Kh(e,{...t,shadowType:"crescent"})}function Jh(e,t){if(!e.uniforms||!e.uniforms.shadowOffset)return console.warn("Material does not have shadowOffset uniform"),!1;let i;if("string"==typeof t){if(i=Wh[t],!i)return console.warn(`Unknown moon phase: ${t}`),!1}else{if("number"!=typeof t)return console.warn("Phase must be a string or number"),!1;i=Xh(t)}return e.uniforms.shadowOffset.value.set(i.x,i.y),!0}function ec(e,t,i=2e3){let n=null,a=!1;const r=new Promise((r,s)=>{if(!e.uniforms||!e.uniforms.shadowOffset)return void s(new Error("Material does not have shadowOffset uniform"));let o;if("string"==typeof t){if(o=Wh[t],!o)return void s(new Error(`Unknown moon phase: ${t}`))}else{if("number"!=typeof t)return void s(new Error("Phase must be a string or number"));o=Xh(t)}const l=e.uniforms.shadowOffset.value.x,h=e.uniforms.shadowOffset.value.y,c=o.x,u=o.y,d=Date.now(),p=()=>{if(a)return void r({cancelled:!0});const t=Date.now()-d,s=Math.min(t/i,1),o=s<.5?4*s*s*s:1-Math.pow(-2*s+2,3)/2,m=l+(c-l)*o,f=h+(u-h)*o;e.uniforms.shadowOffset.value.set(m,f),s<1?n=requestAnimationFrame(p):r({cancelled:!1})};p()});return{promise:r,cancel:()=>{a=!0,null!==n&&(cancelAnimationFrame(n),n=null)}}}function tc(e,t,i){e.emissive&&(e.emissive.copy(t),e.emissiveIntensity=i),e.uniforms&&e.uniforms.glowColor&&(e.uniforms.glowColor.value.copy(t),e.uniforms.glowIntensity.value=i)}function ic(e,t,i,n){e.uniforms&&e.uniforms.shadowOffset&&(e.uniforms.shadowOffset.value.set(t,i),e.uniforms.shadowCoverage.value=n)}function nc(e,t={}){const{resolution:i="4k",glowColor:n=new dn(16777215),glowIntensity:a=1,assetBasePath:r="/assets"}=t,{vertexShader:s,fragmentShader:o}={vertexShader:"\n/**\n * Moon Vertex Shader\n * Passes view-space normal for camera-relative moon phase shadows\n */\n\nvarying vec3 vPosition; // LOCAL position (object space)\nvarying vec3 vWorldPosition;\nvarying vec3 vViewNormal; // VIEW SPACE normal (fixed relative to camera)\nvarying vec3 vViewPosition;\nvarying vec2 vUv;\n\nvoid main() {\n vUv = uv;\n vPosition = position;\n\n // Transform normal to VIEW space (camera-relative)\n // This keeps the moon phase shadow fixed relative to camera view\n // When you rotate the moon, the texture rotates but the phase shadow stays put\n vViewNormal = normalize(normalMatrix * normal);\n\n vec4 worldPosition = modelMatrix * vec4(position, 1.0);\n vWorldPosition = worldPosition.xyz;\n vec4 viewPosition = viewMatrix * worldPosition;\n vViewPosition = viewPosition.xyz;\n gl_Position = projectionMatrix * viewPosition;\n}\n",fragmentShader:kh},l=new Jn({uniforms:{colorMap:{value:null},normalMap:{value:null},shadowOffset:{value:new Mt(0,0)},shadowCoverage:{value:.5},shadowSoftness:{value:.05},glowColor:{value:n},glowIntensity:{value:a},opacity:{value:0},eclipseProgress:{value:0},eclipseIntensity:{value:0},bloodMoonColor:{value:[.85,.18,.08]},emissiveStrength:{value:.39},eclipseShadowPos:{value:[-2,0]},eclipseShadowRadius:{value:1.2},eclipseShadowColor:{value:[1,.58,0]},eclipseMidtoneColor:{value:[.71,.43,.03]},eclipseHighlightColor:{value:[1,.28,.1]},eclipseGlowColor:{value:[.09,.09,.09]},eclipseBrightnessModel:{value:0},shadowDarkness:{value:.53},layer1Mode:{value:9},layer1Strength:{value:.322},layer1Enabled:{value:1},layer2Mode:{value:0},layer2Strength:{value:2.785},layer2Enabled:{value:1},layer3Mode:{value:7},layer3Strength:{value:.199},layer3Enabled:{value:1},layer4Mode:{value:0},layer4Strength:{value:0},layer4Enabled:{value:0}},vertexShader:s,fragmentShader:o,transparent:!0,depthWrite:!0,side:0}),h=`${r}/textures/Moon/moon-color-${i}.jpg`,c=`${r}/textures/Moon/moon-normal-${i}.jpg`;return e.load(h,e=>{l.uniforms.colorMap.value=e;const t=performance.now(),i=()=>{const e=performance.now()-t,n=Math.min(e/300,1);l.uniforms.opacity.value=n,l.needsUpdate=!0,n<1&&requestAnimationFrame(i)};i()}),e.load(c,e=>{l.uniforms.normalMap.value=e}),l}const ac=`\n/**\n * Sun Fragment Shader with Blend Layers and Solar Eclipse\n *\n * Supports solar eclipse effects with moon's shadow darkening the sun\n * and up to 4 sequential blend mode layers for eclipse appearance adjustment\n */\n\nuniform float time;\nuniform sampler2D colorMap;\nuniform sampler2D normalMap;\nuniform vec3 baseColor;\nuniform float emissiveIntensity;\nuniform vec2 shadowOffset;\nuniform float shadowCoverage;\nuniform float shadowSoftness;\nuniform float opacity;\n\n// Solar Eclipse uniforms (moon's shadow covering sun)\nuniform float eclipseProgress; // Eclipse progress (0 = no eclipse, 1 = totality)\nuniform vec2 eclipseShadowPos; // Shadow center position in UV space\nuniform float eclipseShadowRadius; // Moon's shadow radius\nuniform float shadowDarkness; // How much to darken the sun (0-1)\n\n// Blend Layer Uniforms (up to 4 layers)\nuniform float layer1Mode;\nuniform float layer1Strength;\nuniform float layer1Enabled;\n\nuniform float layer2Mode;\nuniform float layer2Strength;\nuniform float layer2Enabled;\n\nuniform float layer3Mode;\nuniform float layer3Strength;\nuniform float layer3Enabled;\n\nuniform float layer4Mode;\nuniform float layer4Strength;\nuniform float layer4Enabled;\n\nvarying vec2 vUv;\nvarying vec3 vNormal;\nvarying vec3 vPosition;\nvarying vec3 vWorldPosition;\nvarying vec3 vViewPosition; // View-space position (camera-relative)\n\n// ═══════════════════════════════════════════════════════════════════════════\n// UNIVERSAL BLEND MODES (injected from utils/blendModes.js)\n// ═══════════════════════════════════════════════════════════════════════════\n${Oh}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// SIMPLEX NOISE (for fire animation - from original sun shader)\n// ═══════════════════════════════════════════════════════════════════════════\nvec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }\nvec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }\nvec4 permute(vec4 x) { return mod289(((x*34.0)+1.0)*x); }\nvec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; }\n\nfloat snoise(vec3 v) {\n const vec2 C = vec2(1.0/6.0, 1.0/3.0);\n const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);\n\n vec3 i = floor(v + dot(v, C.yyy));\n vec3 x0 = v - i + dot(i, C.xxx);\n\n vec3 g = step(x0.yzx, x0.xyz);\n vec3 l = 1.0 - g;\n vec3 i1 = min(g.xyz, l.zxy);\n vec3 i2 = max(g.xyz, l.zxy);\n\n vec3 x1 = x0 - i1 + C.xxx;\n vec3 x2 = x0 - i2 + C.yyy;\n vec3 x3 = x0 - D.yyy;\n\n i = mod289(i);\n vec4 p = permute(permute(permute(\n i.z + vec4(0.0, i1.z, i2.z, 1.0))\n + i.y + vec4(0.0, i1.y, i2.y, 1.0))\n + i.x + vec4(0.0, i1.x, i2.x, 1.0));\n\n float n_ = 0.142857142857;\n vec3 ns = n_ * D.wyz - D.xzx;\n\n vec4 j = p - 49.0 * floor(p * ns.z * ns.z);\n\n vec4 x_ = floor(j * ns.z);\n vec4 y_ = floor(j - 7.0 * x_);\n\n vec4 x = x_ *ns.x + ns.yyyy;\n vec4 y = y_ *ns.x + ns.yyyy;\n vec4 h = 1.0 - abs(x) - abs(y);\n\n vec4 b0 = vec4(x.xy, y.xy);\n vec4 b1 = vec4(x.zw, y.zw);\n\n vec4 s0 = floor(b0)*2.0 + 1.0;\n vec4 s1 = floor(b1)*2.0 + 1.0;\n vec4 sh = -step(h, vec4(0.0));\n\n vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy;\n vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww;\n\n vec3 p0 = vec3(a0.xy, h.x);\n vec3 p1 = vec3(a0.zw, h.y);\n vec3 p2 = vec3(a1.xy, h.z);\n vec3 p3 = vec3(a1.zw, h.w);\n\n vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2,p2), dot(p3,p3)));\n p0 *= norm.x;\n p1 *= norm.y;\n p2 *= norm.z;\n p3 *= norm.w;\n\n vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);\n m = m * m;\n return 42.0 * dot(m*m, vec4(dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3)));\n}\n\nvoid main() {\n // ═══════════════════════════════════════════════════════════════════════════\n // BASE SUN RENDERING (photosphere texture + fire animation)\n // ═══════════════════════════════════════════════════════════════════════════\n\n // Sample base photosphere texture\n vec4 texColor = texture2D(colorMap, vUv);\n\n // Optimized single-octave noise for subtle fire\n vec3 noiseCoord = vPosition * 30.0 + vec3(0.0, time * 0.025, 0.0);\n float fireNoise = snoise(noiseCoord);\n\n // Simple threshold - fire appears only in specific noise ranges\n float fireMask = fireNoise * 0.5 + 0.5; // Remap -1..1 to 0..1\n fireMask = step(0.45, fireMask) * (1.0 - step(0.55, fireMask)); // Only 0.45-0.55 range\n\n // Almost imperceptible warmth shift\n vec3 fireColor = vec3(1.01, 1.0, 0.99);\n\n // Microscopic blending\n vec3 finalColor = mix(texColor.rgb, fireColor, fireMask * 0.008);\n\n // Apply base color tinting\n finalColor *= baseColor;\n\n // Apply emissive intensity for HDR bloom\n finalColor *= emissiveIntensity;\n\n // ═══════════════════════════════════════════════════════════════════════════\n // LIMB DARKENING (realistic solar effect - edges appear darker than center)\n // ═══════════════════════════════════════════════════════════════════════════\n\n // Calculate distance from center (0 at center, 1 at edge)\n float distFromCenterLimb = length(vWorldPosition.xy) / 0.5; // normalize by sun radius (0.5)\n distFromCenterLimb = clamp(distFromCenterLimb, 0.0, 1.0);\n\n // Limb darkening formula: I(μ) = 1 - u*(1-μ) where μ = cos(viewing angle)\n // Simplified using distance: darker at edges, brighter at center\n float mu = sqrt(1.0 - distFromCenterLimb * distFromCenterLimb); // cos approximation\n // EXTREME limb darkening for visibility\n float limbDarkeningCoeff = 0.98; // 98% darkening at edges\n float limbBrightness = 1.0 - limbDarkeningCoeff * (1.0 - mu);\n limbBrightness = pow(limbBrightness, 0.4); // Very aggressive power curve\n\n // Clamp to prevent over-darkening\n limbBrightness = max(limbBrightness, 0.02); // Edges at least 2% brightness\n\n // Apply limb darkening (BEFORE bloom processing)\n finalColor *= limbBrightness;\n\n // ═══════════════════════════════════════════════════════════════════════════\n // SOLAR ECLIPSE EFFECT (Moon Occulting Sun)\n // ═══════════════════════════════════════════════════════════════════════════\n // Solar eclipse: Moon passes BETWEEN viewer and sun, blocking our view\n // The moon appears as a dark circular disk that covers parts of the sun\n // From Earth, moon and sun appear same angular size (0.5°)\n\n // Only apply eclipse if there's a moon to occlude (radius > 0)\n if (eclipseShadowRadius > 0.01) {\n // Only occlude FRONT-FACING parts of the sun (vViewPosition.z < 0 faces camera in view space)\n // Back of sun should not be affected by moon\n if (vViewPosition.z < 0.1) {\n // Project to screen space - camera-relative, independent of sun rotation\n // vViewPosition.xy is already in camera space, just normalize to sun radius\n // Sun radius in view space is approximately 0.5 at typical camera distance\n vec2 screenPos = vViewPosition.xy;\n\n // Moon center position in screen space (same coordinate system)\n vec2 moonCenter = eclipseShadowPos;\n\n // Distance from this sun point to moon center (2D screen space)\n float distToMoon = length(screenPos - moonCenter);\n\n // Moon's angular size (appears same size as sun from Earth)\n // In normalized screen space, sun radius = 1.0, moon radius = 1.0 for total eclipse\n float moonRadius = eclipseShadowRadius;\n float moonEdge = 0.01; // Sharp edge for moon silhouette\n\n // Check if moon blocks this point (moon is in front of sun)\n float moonOcclusion = 1.0 - smoothstep(moonRadius - moonEdge, moonRadius + moonEdge, distToMoon);\n\n // Only apply if moon is actually occluding something\n if (moonOcclusion > 0.001) {\n // Moon completely blocks sun where it overlaps (no light gets through)\n finalColor *= (1.0 - moonOcclusion);\n\n // Subtle penumbra around moon edge (diffraction)\n float penumbraRadius = moonRadius * 1.02;\n float penumbraEdge = 0.03;\n float penumbra = 1.0 - smoothstep(penumbraRadius - penumbraEdge, penumbraRadius + penumbraEdge, distToMoon);\n float penumbraBlocking = (penumbra - moonOcclusion) * 0.2;\n finalColor *= (1.0 - penumbraBlocking);\n }\n }\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // BLEND LAYERS (Applied globally to entire sun)\n // These allow adjusting the appearance of the sun\n // ═══════════════════════════════════════════════════════════════════════════\n\n // Layer 1\n if (layer1Enabled > 0.5) {\n vec3 blendColor1 = vec3(min(layer1Strength, 1.0));\n int mode1 = int(layer1Mode + 0.5);\n vec3 blended1 = clamp(applyBlendMode(finalColor, blendColor1, mode1), 0.0, 1.0);\n finalColor = clamp(blended1, 0.0, 1.0);\n }\n\n // Layer 2\n if (layer2Enabled > 0.5) {\n vec3 blendColor2 = vec3(min(layer2Strength, 1.0));\n int mode2 = int(layer2Mode + 0.5);\n vec3 blended2 = clamp(applyBlendMode(finalColor, blendColor2, mode2), 0.0, 1.0);\n finalColor = clamp(blended2, 0.0, 1.0);\n }\n\n // Layer 3\n if (layer3Enabled > 0.5) {\n vec3 blendColor3 = vec3(min(layer3Strength, 1.0));\n int mode3 = int(layer3Mode + 0.5);\n vec3 blended3 = clamp(applyBlendMode(finalColor, blendColor3, mode3), 0.0, 1.0);\n finalColor = clamp(blended3, 0.0, 1.0);\n }\n\n // Layer 4\n if (layer4Enabled > 0.5) {\n vec3 blendColor4 = vec3(min(layer4Strength, 1.0));\n int mode4 = int(layer4Mode + 0.5);\n vec3 blended4 = clamp(applyBlendMode(finalColor, blendColor4, mode4), 0.0, 1.0);\n finalColor = clamp(blended4, 0.0, 1.0);\n }\n\n // Apply fade-in opacity to prevent texture flash during load\n gl_FragColor = vec4(finalColor, opacity);\n}\n`,rc={baseSpeed:.01,axes:[0,1,0]};function sc(e,t={}){const i=t.resolution||"4k",n=t.glowColor||[1,1,1],a=t.glowIntensity||1,r=t.materialVariant||null,s=t.assetBasePath||"/assets",o=`${s}/textures/Sun/sun-photosphere-${i}.jpg`,l=`${s}/textures/Sun/sun-photosphere-normal-${i}.jpg`,h=1+2*a,c=new dn(h*n[0],h*n[1],h*n[2]*.95),u=new Map;u.set(o,{texture:null});const d=e.load(o,e=>{v.uniforms?.opacity&&(v.uniforms.opacity.value=1);const t=u.get(o);t&&(t.texture=e),u.delete(o)},void 0,e=>{console.warn(`⚠️ Failed to load sun texture (${i}), using color fallback:`,e),u.delete(o)});u.set(l,{texture:null});const p=e.load(l,e=>{const t=u.get(l);t&&(t.texture=e),u.delete(l)},void 0,e=>{console.warn(`⚠️ Sun normal map not found (${i}), continuing without surface detail:`,e),u.delete(l)});let m,f;d.wrapS=d.wrapT=B,p.wrapS=p.wrapT=B,d.anisotropy=16,p.anisotropy=16;let g={};if("multiplexer"===r){const{vertexShader:e,fragmentShader:t}={vertexShader:"\n/**\n * Sun Vertex Shader\n * Passes view-space position for camera-relative eclipse shadow calculations\n */\n\nvarying vec2 vUv;\nvarying vec3 vNormal;\nvarying vec3 vPosition;\nvarying vec3 vWorldPosition;\nvarying vec3 vViewPosition; // View-space position (camera-relative)\n\nvoid main() {\n vUv = uv;\n vNormal = normalize(normalMatrix * normal);\n vPosition = position;\n vWorldPosition = (modelMatrix * vec4(position, 1.0)).xyz;\n\n // Calculate view-space position (camera-relative, always faces camera)\n vec4 viewPos = modelViewMatrix * vec4(position, 1.0);\n vViewPosition = viewPos.xyz;\n\n gl_Position = projectionMatrix * viewPos;\n}\n",fragmentShader:ac};m=e,f=t,g={eclipseProgress:{value:0},eclipseShadowPos:{value:[-2,0]},eclipseShadowRadius:{value:.882},shadowDarkness:{value:1},layer1Mode:{value:0},layer1Strength:{value:.23},layer1Enabled:{value:1},layer2Mode:{value:0},layer2Strength:{value:0},layer2Enabled:{value:0},layer3Mode:{value:0},layer3Strength:{value:0},layer3Enabled:{value:0},layer4Mode:{value:0},layer4Strength:{value:0},layer4Enabled:{value:0}}}else m="\n varying vec2 vUv;\n varying vec3 vNormal;\n varying vec3 vPosition;\n varying vec3 vWorldPosition;\n\n void main() {\n vUv = uv;\n vNormal = normalize(normalMatrix * normal);\n vPosition = position;\n vWorldPosition = (modelMatrix * vec4(position, 1.0)).xyz;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n ",f="\n uniform float time;\n uniform sampler2D colorMap;\n uniform sampler2D normalMap;\n uniform vec3 baseColor;\n uniform float emissiveIntensity;\n uniform vec2 shadowOffset;\n uniform float shadowCoverage;\n uniform float shadowSoftness;\n uniform float opacity; // Fade in opacity (0-1) to prevent texture flash\n\n varying vec2 vUv;\n varying vec3 vNormal;\n varying vec3 vPosition;\n varying vec3 vWorldPosition;\n\n // Simplex noise for fire animation (Ashima Arts)\n vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }\n vec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }\n vec4 permute(vec4 x) { return mod289(((x*34.0)+1.0)*x); }\n vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; }\n\n float snoise(vec3 v) {\n const vec2 C = vec2(1.0/6.0, 1.0/3.0);\n const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);\n\n vec3 i = floor(v + dot(v, C.yyy));\n vec3 x0 = v - i + dot(i, C.xxx);\n\n vec3 g = step(x0.yzx, x0.xyz);\n vec3 l = 1.0 - g;\n vec3 i1 = min(g.xyz, l.zxy);\n vec3 i2 = max(g.xyz, l.zxy);\n\n vec3 x1 = x0 - i1 + C.xxx;\n vec3 x2 = x0 - i2 + C.yyy;\n vec3 x3 = x0 - D.yyy;\n\n i = mod289(i);\n vec4 p = permute(permute(permute(\n i.z + vec4(0.0, i1.z, i2.z, 1.0))\n + i.y + vec4(0.0, i1.y, i2.y, 1.0))\n + i.x + vec4(0.0, i1.x, i2.x, 1.0));\n\n float n_ = 0.142857142857;\n vec3 ns = n_ * D.wyz - D.xzx;\n\n vec4 j = p - 49.0 * floor(p * ns.z * ns.z);\n\n vec4 x_ = floor(j * ns.z);\n vec4 y_ = floor(j - 7.0 * x_);\n\n vec4 x = x_ *ns.x + ns.yyyy;\n vec4 y = y_ *ns.x + ns.yyyy;\n vec4 h = 1.0 - abs(x) - abs(y);\n\n vec4 b0 = vec4(x.xy, y.xy);\n vec4 b1 = vec4(x.zw, y.zw);\n\n vec4 s0 = floor(b0)*2.0 + 1.0;\n vec4 s1 = floor(b1)*2.0 + 1.0;\n vec4 sh = -step(h, vec4(0.0));\n\n vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy;\n vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww;\n\n vec3 p0 = vec3(a0.xy, h.x);\n vec3 p1 = vec3(a0.zw, h.y);\n vec3 p2 = vec3(a1.xy, h.z);\n vec3 p3 = vec3(a1.zw, h.w);\n\n vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2,p2), dot(p3,p3)));\n p0 *= norm.x;\n p1 *= norm.y;\n p2 *= norm.z;\n p3 *= norm.w;\n\n vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);\n m = m * m;\n return 42.0 * dot(m*m, vec4(dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3)));\n }\n\n void main() {\n // Sample base photosphere texture\n vec4 texColor = texture2D(colorMap, vUv);\n\n // Optimized single-octave noise for subtle fire (was 2 FBM calls with 3 octaves each)\n // Using position-based noise with time offset for animation\n vec3 noiseCoord = vPosition * 30.0 + vec3(0.0, time * 0.025, 0.0);\n float fireNoise = snoise(noiseCoord);\n\n // Simple threshold - fire appears only in specific noise ranges\n // Using step functions instead of smoothstep for performance\n float fireMask = fireNoise * 0.5 + 0.5; // Remap -1..1 to 0..1\n fireMask = step(0.45, fireMask) * (1.0 - step(0.55, fireMask)); // Only 0.45-0.55 range\n\n // Almost imperceptible warmth shift (same visual as before)\n vec3 fireColor = vec3(1.01, 1.0, 0.99);\n\n // Microscopic blending - nearly invisible (same blend factor)\n vec3 finalColor = mix(texColor.rgb, fireColor, fireMask * 0.008);\n\n // Apply base color tinting\n finalColor *= baseColor;\n\n // Apply emissive intensity for HDR bloom\n finalColor *= emissiveIntensity;\n\n // ═══════════════════════════════════════════════════════════════════════════\n // LIMB DARKENING (realistic solar effect - edges appear darker than center)\n // ═══════════════════════════════════════════════════════════════════════════\n\n // Calculate distance from center (0 at center, 1 at edge)\n float distFromCenterLimb = length(vWorldPosition.xy) / 0.5; // normalize by sun radius (0.5)\n distFromCenterLimb = clamp(distFromCenterLimb, 0.0, 1.0);\n\n // Limb darkening formula: I(μ) = 1 - u*(1-μ) where μ = cos(viewing angle)\n // Simplified using distance: darker at edges, brighter at center\n float mu = sqrt(1.0 - distFromCenterLimb * distFromCenterLimb); // cos approximation\n float limbDarkeningCoeff = 0.6; // NASA solar data: ~60% darkening at limb\n float limbBrightness = 1.0 - limbDarkeningCoeff * (1.0 - mu);\n\n // Apply limb darkening (preserves bright core for bloom)\n finalColor *= limbBrightness;\n\n // ═══════════════════════════════════════════════════════════════════════════\n // SHADOW DARKENING (applied AFTER bloom intensity so it doesn't affect bloom)\n // ═══════════════════════════════════════════════════════════════════════════\n\n // Sun sphere center (world space origin)\n float sunRadius = 0.5; // Matches geometry radius\n\n // Shadow sphere center (offset from sun center)\n vec3 shadowCenter = vec3(shadowOffset.x, shadowOffset.y, 0.0);\n\n // Calculate distance from fragment to shadow sphere center\n float distToShadow = distance(vWorldPosition, shadowCenter);\n\n // Shadow threshold (shadow sphere radius adjusted by coverage)\n float shadowRadius = sunRadius * shadowCoverage;\n\n // Calculate shadow factor (0 = full shadow, 1 = no shadow)\n float shadowFactor = smoothstep(shadowRadius - shadowSoftness, shadowRadius + shadowSoftness, distToShadow);\n\n // Darken ONLY the final color output (not the bloom calculation)\n float shadowDarkness = 0.05; // How dark the shadow gets (5% brightness)\n finalColor *= mix(shadowDarkness, 1.0, shadowFactor);\n\n // ═══════════════════════════════════════════════════════════════════════════\n // RADIAL CORONA WAVES (applied AFTER shadow, visible around eclipse edge)\n // ═══════════════════════════════════════════════════════════════════════════\n\n // Calculate angle from sun center in world space XY plane\n float angle = atan(vWorldPosition.y, vWorldPosition.x);\n\n // Create radial wave pattern (16 petals for finer detail, rotating slowly)\n float wave = sin(angle * 16.0 + time * 0.3) * 0.5 + 0.5;\n\n // Apply waves to visible (non-shadowed) edges\n float distFromCenter = length(vWorldPosition.xy);\n\n // Edge factor: strong at sun's edge where bloom will amplify it\n float edgeFactor = smoothstep(0.35, 0.5, distFromCenter);\n\n // Only apply waves to non-shadowed areas (visible during eclipse)\n // Combine with shadow factor so waves appear around shadow edge\n float waveStrength = edgeFactor * shadowFactor;\n\n // Very strong modulation (2x variation) for dramatic eclipse corona\n float coronaModulation = 1.0 + (wave * 2.0 - 1.0) * waveStrength;\n finalColor *= coronaModulation;\n\n // Apply fade-in opacity to prevent texture flash during load\n gl_FragColor = vec4(finalColor, opacity);\n }\n ";const v=new Jn({uniforms:{time:{value:0},colorMap:{value:d},normalMap:{value:p},baseColor:{value:c},emissiveIntensity:{value:1.2},glowColor:{value:new dn(1,1,1)},glowIntensity:{value:1},shadowOffset:{value:new Mt(200,0)},shadowCoverage:{value:.5},shadowSoftness:{value:.1},opacity:{value:0},...g},vertexShader:m,fragmentShader:f,transparent:!0,toneMapped:!1});return v.userData.uniforms=v.uniforms,v.userData.pendingTextures=u,v}function oc(e=null,t={}){const i=t.glowColor||[1,1,1],n=t.glowIntensity||1,a=t.resolution||"4k",r=t.materialVariant||null,s=new vr(.5,128,128);let o;if(s.userData.tracked=!0,e)o=sc(e,{glowColor:i,glowIntensity:n,resolution:a,materialVariant:r});else{const e=1+2*n,t=new dn(e*i[0],e*i[1],e*i[2]*.95);o=new gn({color:t,toneMapped:!1})}const l=new Xn(s,o);return l.castShadow=!1,l.receiveShadow=!1,l}function lc(e,t,i=1,n=0){if(!e||!e.material)return;const{material:a}=e;if(a.uniforms&&a.uniforms.baseColor){const{uniforms:e}=a;n>0&&(e.time.value=(e.time.value+n)%(2*Math.PI));const t=1+2*i;e.baseColor.value.setRGB(t,t,.95*t),e.emissiveIntensity.value=1.2}else if(a.color){const e=1+2*i;a.color.setRGB(e,e,.95*e)}}function hc(e){if(e&&(e.geometry&&e.geometry.dispose(),e.material)){const{material:t}=e;t.userData&&t.userData.pendingTextures&&(t.userData.pendingTextures.forEach(({texture:e})=>{e&&e.dispose()}),t.userData.pendingTextures.clear()),t.uniforms&&(t.uniforms.colorMap&&t.uniforms.colorMap.value&&t.uniforms.colorMap.value.dispose(),t.uniforms.normalMap&&t.uniforms.normalMap.value&&t.uniforms.normalMap.value.dispose()),t.map&&t.map.dispose(),t.normalMap&&t.normalMap.dispose(),t.dispose()}}function cc(){const e=new vr(.5,32,32),t=e.attributes.position;for(let e=0;e<t.count;e++){let i=t.getX(e);const n=t.getY(e);let a=t.getZ(e);const r=1+.3*Math.max(0,n);if(i*=r,a*=.8*r,n<-.3){const e=(-n-.3)/.2;i*=1-.8*e,a*=1-.8*e}t.setXYZ(e,i,n,a)}return e.computeVertexNormals(),e}function uc(){const e=new dr(.5,0);return e.computeVertexNormals(),e}function dc(){const e=new Bn,t=[],i=[];t.push(0,2.3,0);for(let e=0;e<6;e++){const i=e/6*Math.PI*2;t.push(1*Math.cos(i),1.5,1*Math.sin(i))}for(let e=0;e<6;e++){const i=e/6*Math.PI*2;t.push(1*Math.cos(i),-1.5,1*Math.sin(i))}t.push(0,-2.3,0);for(let e=0;e<6;e++){const t=(e+1)%6;i.push(0,1+e,1+t)}for(let e=0;e<6;e++){const t=(e+1)%6;i.push(1+e,7+e,1+t),i.push(1+t,7+e,7+t)}for(let e=0;e<6;e++){const t=(e+1)%6;i.push(13,7+t,7+e)}e.setAttribute("position",new Tn(t,3)),e.setIndex(i);const n=1.6/4.6;return e.scale(n,n,n),e.computeVertexNormals(),e}function pc(e=.4,t=.15,i=32,n=64){return new br(e,t,i,n)}function mc(e=.5,t=1){return new pr(e,t)}const fc={sphere:{geometry:function(e=64,t=64){return new vr(.5,e,t)}(64,64),blink:{type:"vertical-squish",duration:150,scaleAxis:[1,.3,1],curve:"sine",playful:{anticipation:.03,overshoot:.05}}},torus:{geometry:pc(),blink:{type:"vertical-squish",duration:150,scaleAxis:[1,.4,1],rotation:[0,0,Math.PI/8],curve:"sine"}},icosahedron:{geometry:mc(.5,1),blink:{type:"geometric-pulse",duration:130,scaleAxis:[.7,.7,.7],curve:"sine"}},octahedron:{geometry:function(e=.5,t=0){return new mr(e,t)}(.5,0),blink:{type:"geometric-pulse",duration:130,scaleAxis:[.7,.7,.7],curve:"sine"}},tetrahedron:{geometry:function(e=.5,t=0){return new yr(e,t)}(.5,0),blink:{type:"geometric-pulse",duration:110,scaleAxis:[.75,.75,.75],rotation:[Math.PI/6,0,0],curve:"sine"}},dodecahedron:{geometry:function(e=.5,t=0){return new dr(e,t)}(.5,0),blink:{type:"facet-flash",duration:140,scaleAxis:[.75,.75,.75],glowBoost:.4,curve:"sine"}},"smooth-icosahedron":{geometry:mc(.5,2),blink:{type:"geometric-pulse",duration:140,scaleAxis:[.75,.75,.75],curve:"sine"}},"faceted-icosahedron":{geometry:mc(.5,0),blink:{type:"facet-flash",duration:120,scaleAxis:[.7,.7,.7],glowBoost:.3,curve:"sine"}},ring:{geometry:pc(.4,.1,16,64),blink:{type:"vertical-squish",duration:140,scaleAxis:[1,.5,1],curve:"sine"}},moon:{geometry:qh(64,64),material:"custom",blink:{type:"gentle-pulse",duration:180,scaleAxis:[.95,.95,.95],glowBoost:.2,curve:"sine"},particleRadiusMultiplier:1.4},sun:{geometry:new vr(.5,64,64),material:"emissive",blink:{type:"radial-pulse",duration:200,scaleAxis:[1.05,1.05,1.05],glowBoost:.5,curve:"sine"},particleRadiusMultiplier:1.5},crystal:{geometry:null,geometryLoader:function(e="/assets"){return new Promise((t,i)=>{(new Bh).load(`${e}/models/Crystal/crystal.obj`,e=>{let i=null;if(e.traverse(e=>{e.isMesh&&e.geometry&&({geometry:i}=e)}),i){i.computeBoundingBox();const e=new xt;i.boundingBox.getCenter(e),i.translate(-e.x,-e.y,-e.z);const n=new xt;i.boundingBox.getSize(n);const a=1.6/Math.max(n.x,n.y,n.z);i.scale(a,a,a),i.attributes.normal||i.computeVertexNormals(),i.computeBoundingBox();const r=new xt;i.boundingBox.getSize(r);let s=i;s.computeVertexNormals(),t(s)}else{console.warn("💎 [CRYSTAL] No mesh in OBJ, using fallback");const e=dc();t(e)}},e=>{},e=>{console.warn("💎 [CRYSTAL] OBJ load FAILED:",e);const i=dc();t(i)})})},material:"custom",blink:{type:"facet-flash",duration:160,scaleAxis:[.95,.95,.95],glowBoost:.4,curve:"sine"},particleRadiusMultiplier:1.4},rough:{geometry:null,geometryLoader:function(e="/assets"){return new Promise(t=>{(new Bh).load(`${e}/models/Crystal/rough.obj`,e=>{let i=null;if(e.traverse(e=>{e.isMesh&&e.geometry&&({geometry:i}=e)}),i){i.computeBoundingBox();const e=new xt;i.boundingBox.getCenter(e),i.translate(-e.x,-e.y,-e.z);const n=new xt;i.boundingBox.getSize(n);const a=1.6/Math.max(n.x,n.y,n.z);i.scale(a,a,a),i.computeVertexNormals(),i.computeBoundingBox(),t(i)}else console.warn("💎 [ROUGH] No mesh in OBJ, using fallback sphere"),t(new vr(.5,32,32))},void 0,e=>{console.warn("💎 [ROUGH] OBJ load failed:",e),t(new vr(.5,32,32))})})},material:"custom",blink:{type:"facet-flash",duration:150,scaleAxis:[.95,.95,.95],glowBoost:.5,curve:"sine"},particleRadiusMultiplier:1.3},heart:{geometry:null,geometryLoader:function(e="/assets"){return new Promise(t=>{(new Bh).load(`${e}/models/Crystal/heart.obj`,e=>{let i=null;if(e.traverse(e=>{e.isMesh&&e.geometry&&({geometry:i}=e)}),i){i.computeBoundingBox();const e=new xt;i.boundingBox.getCenter(e),i.translate(-e.x,-e.y,-e.z);const n=new xt;i.boundingBox.getSize(n);const a=1.2/Math.max(n.x,n.y,n.z);i.scale(a,a,a),i.computeVertexNormals(),i.computeBoundingBox(),i.attributes.uv||function(e){e.computeBoundingBox();const t=e.boundingBox,i=e.attributes.position,n=new Float32Array(2*i.count),a=t.max.x-t.min.x,r=t.max.y-t.min.y;for(let e=0;e<i.count;e++){const s=i.getX(e),o=i.getY(e);n[2*e]=(s-t.min.x)/a,n[2*e+1]=(o-t.min.y)/r}e.setAttribute("uv",new Sn(n,2))}(i),t(i)}else console.warn("💗 [HEART] No mesh in OBJ, using fallback"),t(cc())},void 0,e=>{console.warn("💗 [HEART] OBJ load failed:",e),t(cc())})})},material:"custom",blink:{type:"gentle-pulse",duration:180,scaleAxis:[.92,.92,.92],glowBoost:.6,curve:"sine"},particleRadiusMultiplier:1.3},star:{geometry:null,geometryLoader:function(e="/assets"){return new Promise(t=>{(new Bh).load(`${e}/models/Crystal/star.obj`,e=>{let i=null;if(e.traverse(e=>{e.isMesh&&e.geometry&&({geometry:i}=e)}),i){i.computeBoundingBox();const e=new xt;i.boundingBox.getCenter(e),i.translate(-e.x,-e.y,-e.z);const n=new xt;i.boundingBox.getSize(n);const a=1.4/Math.max(n.x,n.y,n.z);i.scale(a,a,a),i.computeVertexNormals(),i.computeBoundingBox(),i.attributes.uv||function(e){e.computeBoundingBox();const t=e.boundingBox,i=e.attributes.position,n=new Float32Array(2*i.count),a=t.max.x-t.min.x,r=t.max.y-t.min.y;for(let e=0;e<i.count;e++){const s=i.getX(e),o=i.getY(e);n[2*e]=(s-t.min.x)/a,n[2*e+1]=(o-t.min.y)/r}e.setAttribute("uv",new Sn(n,2))}(i),t(i)}else console.warn("⭐ [STAR] No mesh in OBJ, using fallback"),t(uc())},void 0,e=>{console.warn("⭐ [STAR] OBJ load failed:",e),t(uc())})})},material:"custom",blink:{type:"facet-flash",duration:150,scaleAxis:[.93,.93,.93],glowBoost:.5,curve:"sine"},particleRadiusMultiplier:1.4}};class gc{constructor(){this.currentAnimation=null,this.animations=[],this.time=0}playEmotion(e,t={}){const i=this.createEmotionAnimation(e);this.startAnimation(i,t)}playGesture(e,t={}){const i=this.createGestureAnimation(e);this.startAnimation(i,t)}playMorph(e,t,i={}){const n=this.createMorphAnimation(e,t);this.startAnimation(n,i)}update(e){this.time+=e;for(let e=this.animations.length-1;e>=0;e--){const t=this.animations[e],i=t.duration;Math.min((this.time-t.startTime)/i,1)>=1&&(t.callbacks&&t.callbacks.onComplete&&t.callbacks.onComplete(),this.animations.splice(e,1))}}createEmotionAnimation(e){const t={joy:{duration:.6,evaluate:e=>({scale:1+.15*Math.sin(e*Math.PI),glowIntensity:1+.15*Math.sin(e*Math.PI)})},love:{duration:1.2,evaluate:e=>({scale:1+.08*Math.sin(e*Math.PI*2),glowIntensity:1+.1*Math.sin(e*Math.PI*2)})},curiosity:{duration:.8,evaluate:e=>({rotation:[0,.1*Math.sin(e*Math.PI*4),0],scale:1+.05*Math.sin(e*Math.PI),glowIntensity:1})},sadness:{duration:1.5,evaluate:e=>({scale:1-.1*e,glowIntensity:1-.15*Math.sin(e*Math.PI)})},anger:{duration:.4,evaluate:e=>{const t=.15*Math.sin(e*Math.PI*8);return{rotation:[t,t,0],scale:1.1+.1*Math.sin(e*Math.PI),glowIntensity:1+.15*Math.sin(e*Math.PI*8)}}},fear:{duration:.5,evaluate:e=>{const t=.08*Math.sin(e*Math.PI*10);return{scale:.9+t,rotation:[t,0,t],glowIntensity:1+.1*Math.sin(e*Math.PI*10)}}},surprise:{duration:.4,evaluate:e=>({scale:1+.25*(1-Math.cos(e*Math.PI)),glowIntensity:1+.2*(1-Math.cos(e*Math.PI))})},neutral:{duration:.5,evaluate:e=>({scale:1,glowIntensity:1})}};return t[e]||t.neutral}createGestureAnimation(e){const t={bounce:{duration:.8,evaluate:e=>{const t=Math.abs(Math.sin(e*Math.PI));return{position:[0,.5*t,0],scale:1+.1*t}}},pulse:{duration:.6,evaluate:e=>{const t=Math.sin(e*Math.PI);return{scale:1+.2*t,glowIntensity:1+.5*t}}},spin:{duration:1,evaluate:e=>({rotation:[0,e*Math.PI*2,0]})},wobble:{duration:1,evaluate:e=>{const t=Math.sin(e*Math.PI*3);return{rotation:[.3*t,0,.2*t]}}},float:{duration:2,evaluate:e=>({position:[0,.3*Math.sin(e*Math.PI),0]})},shake:{duration:.5,evaluate:e=>{const t=Math.sin(e*Math.PI*6)*(1-e);return{position:[.2*t,0,0],rotation:[0,0,.1*t]}}},nod:{duration:.8,evaluate:e=>({rotation:[.3*Math.sin(e*Math.PI*2),0,0]})}};return t[e]||t.pulse}createMorphAnimation(e,t){return{duration:1,fromShape:e,toShape:t,evaluate:e=>({morphProgress:e,scale:1+.1*Math.sin(e*Math.PI),rotation:[0,e*Math.PI*.5,0]})}}startAnimation(e,t){this.animations.push({...e,startTime:this.time,callbacks:t||{}}),this.currentAnimation=e}stopAll(){this.animations=[],this.currentAnimation=null}destroy(){this.stopAll(),this.animations=null,this.currentAnimation=null,this.time=0}easeInOutCubic(e){return e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2}getIdleAnimation(){return{duration:3,loop:!0,evaluate:e=>{const t=Math.sin(e*Math.PI*2),i=Math.sin(e*Math.PI);return{scale:1+.02*t,position:[.05*i,.03*t,0],rotation:[0,.05*i,0],glowIntensity:1+.1*t}}}}isPlaying(){return this.animations.length>0}}class vc{constructor(){this.breathingSpeed=1,this.breathingDepth=.03,this.breathingPhase=0,this.breathRate=1,this.breathDepth=.03,this.breathRateMult=1,this.breathDepthMult=1,this.emotionBreathPatterns={happy:{rate:1.1,depth:1.2},sad:{rate:.8,depth:.7},angry:{rate:1.4,depth:1.3},calm:{rate:.7,depth:.9},excited:{rate:1.5,depth:1.4},focused:{rate:.9,depth:.6},neutral:{rate:1,depth:1},love:{rate:1.2,depth:1.3},surprised:{rate:1.3,depth:1.1},confused:{rate:1.1,depth:.9},amused:{rate:1.2,depth:1.1},bored:{rate:.6,depth:.8},tired:{rate:.5,depth:1.2},anxious:{rate:1.6,depth:.9},determined:{rate:1.1,depth:1},proud:{rate:.9,depth:1.3},content:{rate:.8,depth:1},hopeful:{rate:1,depth:1.1},zen:{rate:.4,depth:1.5},intrigued:{rate:1.1,depth:.8},embarrassed:{rate:1.3,depth:.7},grateful:{rate:.9,depth:1.1},inspired:{rate:1,depth:1.3},silly:{rate:1.4,depth:1.2},sleepy:{rate:.3,depth:1.4}}}update(e,t,i=null){const n=this.emotionBreathPatterns[t]||{rate:1,depth:1};i&&i["3d"]&&i["3d"].scale?(this.breathRateMult=i["3d"].scale.breathRateMultiplier||1,this.breathDepthMult=i["3d"].scale.breathDepthMultiplier||1):(this.breathRateMult=1,this.breathDepthMult=1),this.breathRate=n.rate*this.breathRateMult,this.breathDepth=this.breathingDepth*n.depth*this.breathDepthMult;const a=this.breathingSpeed*this.breathRate*(e/1e3);this.breathingPhase+=a,this.breathingPhase>2*Math.PI&&(this.breathingPhase-=2*Math.PI)}getBreathingScale(){return 1+Math.sin(this.breathingPhase)*this.breathDepth}setEmotion(e,t=null){const i=this.emotionBreathPatterns[e]||{rate:1,depth:1};t&&t["3d"]&&t["3d"].scale?(this.breathRateMult=t["3d"].scale.breathRateMultiplier||1,this.breathDepthMult=t["3d"].scale.breathDepthMultiplier||1):(this.breathRateMult=1,this.breathDepthMult=1),this.breathRate=i.rate*this.breathRateMult,this.breathDepth=this.breathingDepth*i.depth*this.breathDepthMult}reset(){this.breathingPhase=0,this.breathRate=1,this.breathDepth=this.breathingDepth,this.breathRateMult=1,this.breathDepthMult=1}getBreathingInfo(){return{phase:this.breathingPhase,rate:this.breathRate,depth:this.breathDepth,scale:this.getBreathingScale(),rateMult:this.breathRateMult,depthMult:this.breathDepthMult}}destroy(){this.emotionBreathPatterns=null}}class yc{constructor(){this.tempEuler=new Pi,this.tempQuat=new _t,this.accumulatedRotationQuat=new _t,this.finalQuaternion=new _t}blend(e,t,i,n,a){this.accumulatedRotationQuat.identity();const r={position:[0,0,0],rotationQuat:this.accumulatedRotationQuat,scale:1,glowIntensity:1,glowBoost:0};for(const i of e)if(i.evaluate){const e=t-i.startTime,n=i.duration,a=Math.min(e/n,1),s=i.evaluate(a);s&&(s.position&&(r.position[0]+=s.position[0],r.position[1]+=s.position[1],r.position[2]+=s.position[2]),s.rotation&&(this.tempEuler.set(s.rotation[0],s.rotation[1],s.rotation[2],"XYZ"),this.tempQuat.setFromEuler(this.tempEuler),r.rotationQuat.multiply(this.tempQuat)),void 0!==s.scale&&(r.scale*=s.scale),void 0!==s.glowIntensity&&(r.glowIntensity*=s.glowIntensity),void 0!==s.glowBoost&&(r.glowBoost+=s.glowBoost))}this.finalQuaternion.copy(i).multiply(r.rotationQuat),this.tempEuler.setFromQuaternion(this.finalQuaternion,"XYZ");const s=[this.tempEuler.x,this.tempEuler.y,this.tempEuler.z],o=n*r.scale,l=a*r.glowIntensity;return{position:r.position,rotation:s,scale:o,glowIntensity:l,glowBoost:r.glowBoost,gestureQuaternion:r.rotationQuat}}destroy(){this.tempEuler=null,this.tempQuat=null,this.accumulatedRotationQuat=null,this.finalQuaternion=null}}const bc=new Map;var Mc=function(e){return bc.get(e)||null},_c=function(){return Array.from(bc.keys())},xc={name:"suspicion",emoji:"🤨",description:"Paranoid watchfulness with surveillance scanning",visual:{glowColor:"#6B46C1",particleRate:4,minParticles:6,maxParticles:12,particleBehavior:"surveillance",particleSpeed:.2,breathRate:.6,breathDepth:.04,coreJitter:.02,blinkRate:1.1,blinkSpeed:1,particleColors:[{color:"#6B46C1",weight:30},{color:"#4A5568",weight:25},{color:"#8B4789",weight:20},{color:"#9F7AEA",weight:15},{color:"#2D3748",weight:10}],threatLevel:0,getGlowIntensity(){return.3+.7*this.threatLevel},getParticleSpeed(){return.2+.8*this.threatLevel},getGlowColor(){const e=this.threatLevel||0,t=Math.round(107+113*e),i=Math.round(70+-32*e),n=Math.round(193+-66*e),a=e=>e.toString(16).padStart(2,"0");return`#${a(t)}${a(i)}${a(n)}`}},modifiers:{speed:.4,amplitude:.6,intensity:1.2,smoothness:.3,regularity:.2,focus:1.5,addWobble:!0},typicalGestures:["scan","twitch","peek","tilt","hold"],transitions:{duration:500,easing:"linear",priority:4},special:{coreSquint:.6,scanInterval:2e3,scanDuration:1200,scanAngle:60,twitchChance:.02,peekInterval:4e3,maxThreatDistance:300,alertThreshold:.7},"3d":{rotation:{type:"suspicious",speed:1,axes:[0,0,0],musicSync:!1},glow:{color:"#6B46C1",intensity:.85,pulse:{speed:.6,range:[.7,1]}},scale:{base:1,breathe:{enabled:!0,depth:.04,rate:.6}}},soulAnimation:{driftSpeed:.9,shimmerSpeed:1.8,turbulence:.4}},Sc={name:"calm",emoji:"😌",description:"Serene, peaceful state with gentle movements",visual:{glowColor:"#66D9CC",particleRate:6,minParticles:10,maxParticles:50,particleBehavior:"zen",breathRate:.4,breathDepth:.12,coreJitter:!1,blinkRate:.8,blinkSpeed:1,particleColors:[{color:"#66D9CC",weight:35},{color:"#99E6D9",weight:25},{color:"#40BFB3",weight:20},{color:"#B3F2E6",weight:15},{color:"#339980",weight:5}]},modifiers:{speed:.5,amplitude:.3,intensity:.4,smoothness:2,regularity:1.5,addWeight:!1,floatHeight:.2,swayAmount:.15,duration:1.5},typicalGestures:["breathe","float","drift","idle"],transitions:{duration:800,easing:"easeInOutSine",priority:1},movement:{floatPattern:"sine_slow",floatPeriod:6e3,floatAmplitude:8,swayPattern:"gentle",swayPeriod:8e3,swayAmplitude:5,microMovements:!1},getCoreParams(e){const t=e.time||Date.now(),i=.5*Math.sin(6e-4*t)+.5;return{scaleX:1-.02*i,scaleY:1-.02*i,eyeOpenness:.85,eyeExpression:"serene",pupilOffset:{x:2*Math.sin(3e-4*t),y:1*Math.cos(4e-4*t)},glowPulse:.95+.05*i}},updateParticle(e,t){e.x+=.1*Math.sin(.001*e.life),e.y-=.02*t,e.opacity=.3*Math.sin(.002*e.life)+.2,e.size=e.baseSize*(1+.2*Math.sin(.001*e.life))},renderCore:(e,t,i,n)=>!1,"3d":{rotation:{type:"gentle",speed:.5,axes:[0,.3,0],musicSync:!0},glow:{color:"#66D9CC",intensity:.6,pulse:{speed:.4,range:[.5,.7]}},scale:{base:1,breathe:{enabled:!0,depth:.12,rate:.4}}},soulAnimation:{driftSpeed:.3,shimmerSpeed:.4,turbulence:.1}};const wc=new Map,Ec={happy:"joy",peaceful:"calm",curious:"surprise",frustrated:"anger",sad:"sadness",excitement:"excited"};function Tc(e){const t=Ec[e]||e,i=wc.get(t);if(i)return i;return Mc(t)||null}function Cc(e){const t=Tc(e);if(!t)return Tc("neutral").visual;if(!t.visual)return{};const{visual:i}=t,n={};for(const e in i)"function"!=typeof i[e]&&(n[e]=i[e]);return"function"==typeof i.getGlowIntensity&&(n.glowIntensity=i.getGlowIntensity()),"function"==typeof i.getParticleSpeed&&(n.particleSpeed=i.getParticleSpeed()),"function"==typeof i.getParticleRate&&(n.particleRate=i.getParticleRate()),"function"==typeof i.getGlowColor&&(n.glowColor=i.getGlowColor()),n}function Ac(e){const t=Tc(e);return t?t.modifiers:Tc("neutral").modifiers}function Pc(e,t){const i=Tc(e),n=Tc(t);return i&&n?n.transitions&&n.transitions[e]?n.transitions[e]:{duration:1e3,easing:"ease-in-out",gesture:n.transitions?.defaultGesture||null}:{duration:1e3,easing:"ease-in-out"}}[{name:"neutral",emoji:"😐",description:"Calm, balanced emotional state",visual:{glowColor:"#00BCD4",particleRate:2,minParticles:8,maxParticles:10,particleBehavior:"ambient",breathRate:1,breathDepth:.08,coreJitter:!1,blinkRate:1,blinkSpeed:1,particleColors:[{color:"#00BCD4",weight:25},{color:"#00ACC1",weight:20},{color:"#26C6DA",weight:15},{color:"#B2EBF2",weight:15},{color:"#0097A7",weight:10},{color:"#80DEEA",weight:10},{color:"#E0F7FA",weight:5}]},modifiers:{speed:1,amplitude:1,intensity:1,smoothness:1,regularity:1},typicalGestures:["breathe","float","idle","blink"],transitions:{duration:500,easing:"easeInOut",priority:0},getCoreParams:e=>({scaleX:1,scaleY:1,eyeOpenness:1,eyeExpression:"neutral",pupilOffset:{x:0,y:0}}),renderCore:(e,t,i,n)=>!1,"3d":{rotation:{type:"gentle",speed:1,axes:[0,.3,0],musicSync:!1},glow:{color:"#00BCD4",intensity:.9,pulse:{speed:1,range:[.8,1]}},scale:{base:1,breathe:{enabled:!0,depth:.08,rate:1}}},soulAnimation:{driftSpeed:.5,shimmerSpeed:.5,turbulence:.2}},{name:"joy",emoji:"😊",description:"Playful happiness and celebration",visual:{glowColor:"#FFEB3B",particleRate:8,minParticles:0,maxParticles:50,particleBehavior:"popcorn",breathRate:1.5,breathDepth:.1,coreJitter:!1,blinkRate:1.3,blinkSpeed:1.1,particleColors:[{color:"#FFEB3B",weight:25},{color:"#FFC107",weight:20},{color:"#FFFF00",weight:15},{color:"#FFD700",weight:15},{color:"#FFF59D",weight:10},{color:"#FF9800",weight:10},{color:"#FFFDE7",weight:5}]},modifiers:{speed:1.8,amplitude:1.9,intensity:1.1,smoothness:1,regularity:.9,addBounce:!0},typicalGestures:["bounce","spin","wave","expand","shake","float"],transitions:{duration:400,easing:"easeOutBack",priority:5,burstOnEntry:!0},getCoreParams:e=>({scaleX:1,scaleY:1,eyeOpenness:1,eyeExpression:"happy",pupilOffset:{x:0,y:-.1},sparkle:!0}),"3d":{rotation:{type:"rhythmic",speed:1.8,axes:[0,.3,0],musicSync:!0},glow:{color:"#FFEB3B",intensity:1.6,pulse:{speed:1.5,range:[1.2,1.8]}},scale:{base:1,breathe:{enabled:!0,depth:.1,rate:1.5}}},soulAnimation:{driftSpeed:1.2,shimmerSpeed:1.5,turbulence:.3}},{name:"sadness",emoji:"😢",description:"Deep melancholic sorrow",visual:{glowColor:"#4169E1",particleRate:6,minParticles:0,maxParticles:50,particleBehavior:"falling",breathRate:.6,breathDepth:.12,coreJitter:!1,blinkRate:.6,blinkSpeed:.8,particleColors:[{color:"#4169E1",weight:25},{color:"#1E90FF",weight:20},{color:"#6495ED",weight:15},{color:"#B0C4DE",weight:15},{color:"#191970",weight:10},{color:"#87CEEB",weight:10},{color:"#2F4F4F",weight:5}]},modifiers:{speed:.7,amplitude:.6,intensity:.8,smoothness:1.3,regularity:1.1,addGravity:!0},typicalGestures:["droop","sway","contract","drift","sink"],transitions:{duration:800,easing:"easeInOut",priority:3},"3d":{rotation:{type:"gentle",speed:.7,axes:[0,.2,0],musicSync:!1},glow:{color:"#4169E1",intensity:.65,pulse:{speed:.6,range:[.5,.8]}},scale:{base:1,breathe:{enabled:!0,depth:.12,rate:.6}}},soulAnimation:{driftSpeed:.2,shimmerSpeed:.3,turbulence:.1}},{name:"anger",emoji:"😠",description:"Intense rage and aggression",visual:{glowColor:"#DC143C",particleRate:8,minParticles:8,maxParticles:50,particleBehavior:"aggressive",breathRate:2.2,breathDepth:.15,coreJitter:!0,blinkRate:1.6,blinkSpeed:1.3,particleColors:[{color:"#DC143C",weight:25},{color:"#FF0000",weight:20},{color:"#B22222",weight:15},{color:"#FF4500",weight:15},{color:"#8B0000",weight:10},{color:"#FF6347",weight:10},{color:"#660000",weight:5}]},modifiers:{speed:1.5,amplitude:1.4,intensity:1.3,smoothness:.3,regularity:.7,addShake:!0},typicalGestures:["shake","vibrate","expand","pulse","flicker","strike"],transitions:{duration:300,easing:"easeOutExpo",priority:8,shakeOnEntry:!0},special:{screenShake:!0,particleTrails:"fire",glowPulse:!0,temperatureEffect:"hot"},"3d":{rotation:{type:"unstable",speed:1.5,axes:[0,.3,0],shake:{amplitude:.02,frequency:7},eruption:{enabled:!0,interval:3e3,speedMultiplier:3.5,duration:400},musicSync:!1},glow:{color:"#DC143C",intensity:1.8,pulse:{speed:2.2,range:[.8,2]}},scale:{base:1,breathe:{enabled:!0,depth:.15,rate:2.2}}},soulAnimation:{driftSpeed:2,shimmerSpeed:.8,turbulence:.8}},{name:"fear",emoji:"😨",description:"Anxious state with fleeing particles",visual:{glowColor:"#8A2BE2",particleRate:8,minParticles:8,maxParticles:50,particleBehavior:"scattering",breathRate:2.5,breathDepth:.06,coreJitter:!0,blinkRate:1.7,blinkSpeed:1.4,particleColors:[{color:"#8A2BE2",weight:25},{color:"#4B0082",weight:20},{color:"#9400D3",weight:15},{color:"#6B46C1",weight:15},{color:"#9932CC",weight:10},{color:"#E6E6FA",weight:8},{color:"#301934",weight:7}]},modifiers:{speed:1.4,amplitude:.8,intensity:1.2,smoothness:.5,regularity:.5,addJitter:!0},typicalGestures:["shake","vibrate","contract","flicker","retreat"],transitions:{duration:400,easing:"easeOut",priority:7},"3d":{rotation:{type:"unstable",speed:1.4,axes:[0,.3,0],shake:{amplitude:.015,frequency:3.5},musicSync:!1},glow:{color:"#8A2BE2",intensity:.9,pulse:{speed:2.5,range:[.6,1.2]}},scale:{base:1,breathe:{enabled:!0,depth:.06,rate:2.5}}},soulAnimation:{driftSpeed:1.8,shimmerSpeed:2.5,turbulence:.6}},{name:"surprise",emoji:"😲",description:"Sudden shock with explosive particles",visual:{glowColor:"#FFD700",particleRate:5,minParticles:0,maxParticles:15,particleBehavior:"burst",breathRate:.3,breathDepth:.18,coreJitter:!1,blinkRate:1.4,blinkSpeed:1.2,particleColors:[{color:"#FFD700",weight:25},{color:"#FFA500",weight:20},{color:"#FFFF00",weight:15},{color:"#FF6347",weight:15},{color:"#FFE4B5",weight:10},{color:"#FF4500",weight:10},{color:"#FFFACD",weight:5}]},modifiers:{speed:1.6,amplitude:1.5,intensity:1.4,smoothness:.7,regularity:.8,addPop:!0},typicalGestures:["expand","bounce","flash","pulse","pop"],transitions:{duration:200,easing:"easeOutBack",priority:6},"3d":{rotation:{type:"unstable",speed:1.6,axes:[0,.45,0],shake:{amplitude:.01,frequency:3},musicSync:!1},glow:{color:"#FFD700",intensity:1.8,pulse:{speed:.3,range:[1,2.2]}},scale:{base:1,breathe:{enabled:!0,depth:.18,rate:.3}}},soulAnimation:{driftSpeed:1.5,shimmerSpeed:2,turbulence:.5}},{name:"disgust",emoji:"🤢",description:"Revulsion with repelling particles",visual:{glowColor:"#9ACD32",particleRate:4,minParticles:5,maxParticles:12,particleBehavior:"repelling",breathRate:.7,breathDepth:.04,coreJitter:!1,blinkRate:.9,blinkSpeed:.9,particleColors:[{color:"#9ACD32",weight:25},{color:"#ADFF2F",weight:20},{color:"#7FFF00",weight:15},{color:"#BDB76B",weight:15},{color:"#6B8E23",weight:10},{color:"#CCFF00",weight:8},{color:"#556B2F",weight:7}]},modifiers:{speed:.9,amplitude:.7,intensity:.9,smoothness:.8,regularity:1,addRecoil:!0},typicalGestures:["contract","shake","recoil","wobble"],transitions:{duration:600,easing:"easeIn",priority:4},"3d":{rotation:{type:"gentle",speed:.9,axes:[0,.25,0],musicSync:!1},glow:{color:"#9ACD32",intensity:1,pulse:{speed:.7,range:[.7,1.2]}},scale:{base:1,breathe:{enabled:!0,depth:.04,rate:.7}}},soulAnimation:{driftSpeed:.4,shimmerSpeed:.6,turbulence:.35}},{name:"love",emoji:"💕",description:"Warm affection with orbiting particles",visual:{glowColor:"#FF1493",particleRate:6,minParticles:15,maxParticles:50,particleBehavior:"orbiting",breathRate:.75,breathDepth:.15,coreJitter:!1,blinkRate:1.2,blinkSpeed:1,particleColors:[{color:"#FF1493",weight:30},{color:"#FF69B4",weight:25},{color:"#FF007F",weight:15},{color:"#FFB6C1",weight:10},{color:"#FF45A0",weight:10},{color:"#E91E63",weight:5},{color:"#FFC0CB",weight:5}]},modifiers:{speed:.9,amplitude:1.1,intensity:1.2,smoothness:1.4,regularity:1.2,addWarmth:!0},typicalGestures:["pulse","sway","orbit","glow","breathe","float"],transitions:{duration:700,easing:"easeInOut",priority:5},"3d":{rotation:{type:"gentle",speed:.9,axes:[0,.28,0],musicSync:!0},glow:{color:"#FF1493",intensity:1.8,pulse:{speed:.75,range:[1.3,2]}},scale:{base:1,breathe:{enabled:!0,depth:.15,rate:.75}}},soulAnimation:{driftSpeed:.8,shimmerSpeed:1.2,turbulence:.2}},xc,{name:"excited",emoji:"🤩",description:"High energy with rapid particles",visual:{glowColor:"#FF6B35",particleRate:8,minParticles:10,maxParticles:50,particleBehavior:"burst",breathRate:2,breathDepth:.14,coreJitter:!0,blinkRate:1.5,blinkSpeed:1.2,particleColors:[{color:"#FF6B35",weight:25},{color:"#FF1744",weight:20},{color:"#FFC107",weight:15},{color:"#FF9100",weight:15},{color:"#FFEB3B",weight:10},{color:"#FF5722",weight:10},{color:"#FFF59D",weight:5}]},modifiers:{speed:1.4,amplitude:1.3,intensity:1.3,smoothness:.8,regularity:.7,addVibration:!0},typicalGestures:["bounce","spin","vibrate","expand","shake","pulse"],transitions:{duration:300,easing:"easeOutElastic",priority:6},"3d":{rotation:{type:"unstable",speed:1.4,axes:[0,.4,0],shake:{amplitude:.01,frequency:4},musicSync:!1},glow:{color:"#FF6B35",intensity:1.5,pulse:{speed:2,range:[1,1.8]}},scale:{base:1,breathe:{enabled:!0,depth:.14,rate:2}}},soulAnimation:{driftSpeed:1.5,shimmerSpeed:2,turbulence:.5}},{name:"resting",emoji:"😴",description:"Deep relaxation with slow drift",visual:{glowColor:"#9370DB",particleRate:1,minParticles:3,maxParticles:5,particleBehavior:"resting",breathRate:.8,breathDepth:.12,coreJitter:!1,blinkRate:.4,blinkSpeed:.7,particleColors:[{color:"#9370DB",weight:30},{color:"#A591C4",weight:20},{color:"#B366FF",weight:20},{color:"#B8A1E6",weight:15},{color:"#674D9B",weight:15}]},modifiers:{speed:.5,amplitude:.4,intensity:.5,smoothness:1.4,regularity:.9,addWeight:!0},typicalGestures:["breathe","drift","sway","float"],transitions:{duration:1e3,easing:"easeInOut",priority:2},"3d":{rotation:{type:"gentle",speed:.5,axes:[0,.15,0],musicSync:!1},glow:{color:"#9370DB",intensity:.8,pulse:{speed:.8,range:[.6,1]}},scale:{base:1,breathe:{enabled:!0,depth:.12,rate:.8}}},soulAnimation:{driftSpeed:.15,shimmerSpeed:.1,turbulence:.05}},{name:"euphoria",emoji:"🌟",description:"Radiant hope and new beginnings",visual:{glowColor:"#FFB6C1",particleRate:6,minParticles:15,maxParticles:30,particleBehavior:"radiant",breathRate:1.3,breathDepth:.25,coreJitter:!1,blinkRate:1.4,blinkSpeed:1.1,particleColors:[{color:"#FFB6C1",weight:20},{color:"#FFD700",weight:18},{color:"#87CEEB",weight:15},{color:"#DDA0DD",weight:15},{color:"#98FB98",weight:12},{color:"#FFA07A",weight:10},{color:"#E6E6FA",weight:8},{color:"#FFFFFF",weight:2}]},modifiers:{speed:1.4,amplitude:1.5,intensity:1.6,smoothness:1.3,regularity:.8,addWarmth:!0,addLift:!0},typicalGestures:["expand","radiate","pulse","glow","float","bloom"],transitions:{duration:600,easing:"easeOutExpo",priority:8},"3d":{rotation:{type:"rhythmic",speed:1.4,axes:[0,.35,0],musicSync:!0},glow:{color:"#FFB6C1",intensity:1.2,pulse:{speed:1.3,range:[.9,1.5]}},scale:{base:1,breathe:{enabled:!0,depth:.25,rate:1.3}}},soulAnimation:{driftSpeed:1.8,shimmerSpeed:2.5,turbulence:.7}},{name:"focused",emoji:"🎯",description:"Intense concentration with directed flow",visual:{glowColor:"#00CED1",particleRate:4,minParticles:5,maxParticles:12,particleBehavior:"directed",breathRate:1.2,breathDepth:.08,coreJitter:!0,blinkRate:.7,blinkSpeed:1,particleColors:[{color:"#00CED1",weight:30},{color:"#4A9FA0",weight:20},{color:"#00FFFF",weight:20},{color:"#5FE5E7",weight:15},{color:"#006B6D",weight:15}],eyeOpenness:.7,microAdjustments:!0},modifiers:{speed:1,amplitude:.9,intensity:1.1,smoothness:1.1,regularity:1.2,addPrecision:!0},typicalGestures:["track","lock","scan","pulse","vibrate"],transitions:{duration:400,easing:"easeIn",priority:5},getCoreParams:e=>({scaleX:1.1,scaleY:.7,eyeOpenness:.7,eyeExpression:"focused",pupilOffset:{x:0,y:0},microAdjustments:!0}),"3d":{rotation:{type:"still",speed:.5,axes:[0,.1,0],musicSync:!1},glow:{color:"#00CED1",intensity:1.2,pulse:{speed:1.2,range:[1,1.3]}},scale:{base:1,breathe:{enabled:!0,depth:.08,rate:1.2}}},soulAnimation:{driftSpeed:.6,shimmerSpeed:.2,turbulence:.1}},{name:"glitch",emoji:"🌈",description:"Surprised sadness with rainbow colors and glitch wiggle",visual:{primaryColor:"#FF6B9D",glowColor:"#4169E1",glowIntensity:1.2,particleRate:5,minParticles:5,maxParticles:15,particleBehavior:"burst",particleSpeed:1,breathRate:.4,breathDepth:.15,coreJitter:!1,coreSize:1,eyeOpenness:.8,blinkRate:1.3,blinkSpeed:1.2,particleColors:[{color:"#FF0080",weight:18},{color:"#00FF80",weight:18},{color:"#8000FF",weight:18},{color:"#FF8000",weight:15},{color:"#0080FF",weight:15},{color:"#FFFF00",weight:10},{color:"#FF6B9D",weight:6}],particleGlitchWiggle:!0,glitchWiggleIntensity:.3,glitchWiggleFrequency:.1},modifiers:{speed:1.1,amplitude:1,intensity:1.1,smoothness:.8,regularity:.7,focus:.6},typicalGestures:["bounce","sway","pulse","drift","flash"],transitions:{duration:300,easing:"easeInOut",priority:5},"3d":{rotation:{type:"unstable",speed:1.1,axes:[0,.35,0],shake:{amplitude:.02,frequency:5},musicSync:!1},glow:{color:"#FF6B9D",intensity:1.2,pulse:{speed:.4,range:[.8,1.6]}},scale:{base:1,breathe:{enabled:!0,depth:.15,rate:.4}}}},Sc].forEach(e=>{e&&e.name&&wc.set(e.name,e)});class Dc{constructor(e,t={}){this.blinkConfig=e.blink||this.getDefaultBlinkConfig(),this.currentGeometryType=null,this.baseDuration=this.blinkConfig.duration||150,this.baseMinInterval=3e3,this.baseMaxInterval=7e3,this.emotionBlinkRate=1,this.emotionBlinkSpeed=1,this.isBlinking=!1,this.blinkTimer=0,this.nextBlinkTime=this.getRandomBlinkTime(),this.enabled=!0,this.blinkProgress=0}setEmotion(e){const t=Tc(e);this.emotionBlinkRate=t?.visual?.blinkRate||1,this.emotionBlinkSpeed=t?.visual?.blinkSpeed||1}setGeometry(e){this.blinkConfig=e.blink||this.getDefaultBlinkConfig(),this.baseDuration=this.blinkConfig.duration||150}update(e){if(!this.enabled)return this.getIdleState();if(this.isBlinking){this.blinkTimer+=e;const t=this.baseDuration/this.emotionBlinkSpeed;if(this.blinkTimer>=t)return this.completeBlink(),this.getIdleState();const i=this.blinkTimer/t;return this.blinkProgress=i,this.getBlinkState()}return Date.now()>=this.nextBlinkTime?(this.startBlink(),this.getBlinkState()):this.getIdleState()}startBlink(){this.enabled&&(this.isBlinking=!0,this.blinkTimer=0,this.blinkProgress=0)}completeBlink(){this.isBlinking=!1,this.blinkTimer=0,this.blinkProgress=0,this.nextBlinkTime=Date.now()+this.getRandomBlinkTime()}getRandomBlinkTime(){const e=this.baseMinInterval/this.emotionBlinkRate,t=this.baseMaxInterval/this.emotionBlinkRate;return e+Math.random()*(t-e)}getBlinkState(){const e=this.blinkConfig,t=Math.sin(this.blinkProgress*Math.PI);let i=1;if(e.playful)if(this.blinkProgress<.1){const t=this.blinkProgress/.1;i-=Math.sin(t*Math.PI)*e.playful.anticipation}else if(this.blinkProgress>.8){const t=(this.blinkProgress-.8)/.2;i+=Math.sin(t*Math.PI)*e.playful.overshoot}const n=t*i,a=[1-(1-e.scaleAxis[0])*n,1-(1-e.scaleAxis[1])*n,1-(1-e.scaleAxis[2])*n];let r=null;e.rotation&&(r=[e.rotation[0]*n,e.rotation[1]*n,e.rotation[2]*n]);let s=0;return e.glowBoost&&(s=e.glowBoost*n),{isBlinking:!0,progress:this.blinkProgress,scale:a,rotation:r,glowBoost:s}}getIdleState(){return{isBlinking:!1,progress:0,scale:[1,1,1],rotation:null,glowBoost:0}}getDefaultBlinkConfig(){return{type:"vertical-squish",duration:150,scaleAxis:[1,.3,1],curve:"sine"}}pause(){this.enabled=!1,this.isBlinking&&this.completeBlink()}resume(){this.enabled=!0,this.nextBlinkTime=Date.now()+this.getRandomBlinkTime()}getState(){return{isBlinking:this.isBlinking,enabled:this.enabled,blinkProgress:this.blinkProgress,emotionBlinkRate:this.emotionBlinkRate,emotionBlinkSpeed:this.emotionBlinkSpeed,nextBlinkTime:this.nextBlinkTime}}destroy(){this.blinkConfig=null,this.enabled=!1,this.isBlinking=!1}}let Rc;"undefined"!=typeof window&&window.__emotiveRhythmEngine?Rc=window.__emotiveRhythmEngine:(Rc=new class{constructor(){this.bpm=120,this.timeSignature=[4,4],this.isPlaying=!1,this.startTime=0,this.currentBeat=0,this.currentBar=0,this.beatProgress=0,this.barProgress=0,this.beatDuration=6e4/this.bpm,this.barDuration=this.beatDuration*this.timeSignature[0],this.lastBeatTime=0,this.nextBeatTime=0,this.listeners=new Map,this.beatCallbacks=new Set,this.barCallbacks=new Set,this.subdivisions={sixteenth:0,eighth:0,triplet:0,swing:0},this.audioSync=null,this.syncOffset=0,this.autoSync=!1,this.intensity=1,this.groove=0,this.humanize=.05,this.patterns=new Map,this.currentPattern=null,this.initializePatterns()}initializePatterns(){this.patterns.set("4/4",{name:"4/4",description:"Common time - 4 beats per bar",timeSignature:[4,4],groove:0,accents:[1,.5,.7,.5]}),this.patterns.set("straight",{name:"straight",description:"Straight, even timing",groove:0,accents:[1,.5,.7,.5]}),this.patterns.set("swing",{name:"swing",description:"Swing/shuffle timing",groove:.67,accents:[1,.3,.8,.3]}),this.patterns.set("3/4",{name:"3/4",description:"Waltz time - 3 beats per bar",timeSignature:[3,4],accents:[1,.5,.5]}),this.patterns.set("waltz",{name:"waltz",description:"3/4 waltz timing",timeSignature:[3,4],accents:[1,.5,.5]}),this.patterns.set("6/8",{name:"6/8",description:"Compound duple time",timeSignature:[6,8],accents:[1,.3,.3,.7,.3,.3]}),this.patterns.set("5/4",{name:"5/4",description:"Complex meter - 5 beats per bar",timeSignature:[5,4],accents:[1,.5,.6,.5,.7]}),this.patterns.set("7/8",{name:"7/8",description:"Irregular meter",timeSignature:[7,8],accents:[1,.5,.5,.7,.5,.5,.6]}),this.patterns.set("dubstep",{name:"dubstep",description:"Dubstep half-time feel",accents:[.2,.2,1,.2],subdivisions:{wobble:!0}}),this.patterns.set("breakbeat",{name:"breakbeat",description:"Broken beat pattern",accents:[1,.2,.7,.9,.2,.8,.4,.2]})}start(){this.isPlaying||(this.isPlaying=!0,this.isRunning=!0,this.startTime=performance.now(),this.lastBeatTime=this.startTime,this.nextBeatTime=this.startTime+this.beatDuration,this.currentBeat=0,this.currentBar=0,this.emit("start",{bpm:this.bpm,timeSignature:this.timeSignature,pattern:this.currentPattern}),this.update())}stop(){this.isPlaying&&(this.isPlaying=!1,this.emit("stop",{totalBeats:this.currentBeat,totalBars:this.currentBar}))}update(){if(!this.isPlaying)return;const e=(performance.now()-this.startTime)/this.beatDuration,t=Math.floor(e);this.beatProgress=e%1,t>this.currentBeat&&this.onBeat(t);const i=Math.floor(t/this.timeSignature[0]);i>this.currentBar&&this.onBar(i),this.currentBeat=t,this.currentBar=i,this.barProgress=t%this.timeSignature[0]/this.timeSignature[0],this.updateSubdivisions(),this.emit("update",this.getTimeInfo()),this.isPlaying&&requestAnimationFrame(()=>this.update())}onBeat(e){const t=e%this.timeSignature[0],i=this.getAccent(t),n=this.humanize*(Math.random()-.5)*this.beatDuration,a={beat:e,beatInBar:t,bar:this.currentBar,accent:i,intensity:this.intensity*i,humanTiming:n,timestamp:performance.now()};this.emit("beat",a),this.beatCallbacks.forEach(e=>e(a)),this.lastBeatTime=performance.now(),this.nextBeatTime=this.lastBeatTime+this.beatDuration}onBar(e){const t={bar:e,timeSignature:this.timeSignature,pattern:this.currentPattern,timestamp:performance.now()};this.emit("bar",t),this.barCallbacks.forEach(e=>e(t))}updateSubdivisions(){if(this.subdivisions.sixteenth=4*this.beatProgress%1,this.subdivisions.eighth=2*this.beatProgress%1,this.subdivisions.triplet=3*this.beatProgress%1,this.groove>0){const e=.5+.17*this.groove;this.subdivisions.eighth<.5?this.subdivisions.swing=this.subdivisions.eighth/e:this.subdivisions.swing=.5+(this.subdivisions.eighth-.5)/(1-e)}else this.subdivisions.swing=this.subdivisions.eighth}getAccent(e){if(this.currentPattern&&this.patterns.has(this.currentPattern)){const t=this.patterns.get(this.currentPattern);if(t.accents&&void 0!==t.accents[e])return t.accents[e]}return 0===e?1:2===e&&4===this.timeSignature[0]?.7:.5}getTimeInfo(){return{elapsed:performance.now()-this.startTime,beat:this.currentBeat,bar:this.currentBar,beatInBar:this.currentBeat%this.timeSignature[0],beatProgress:this.beatProgress,barProgress:this.barProgress,subdivisions:{...this.subdivisions},bpm:this.bpm,beatDuration:this.beatDuration,timeSignature:[...this.timeSignature],intensity:this.intensity,groove:this.groove,pattern:this.currentPattern,nextBeatIn:this.nextBeatTime-performance.now(),accent:this.getAccent(this.currentBeat%this.timeSignature[0])}}setBPM(e){this.bpm=Math.max(20,Math.min(360,e)),this.beatDuration=6e4/this.bpm,this.barDuration=this.beatDuration*this.timeSignature[0],this.emit("tempoChange",{bpm:this.bpm})}setTimeSignature(e,t){this.timeSignature=[e,t],this.barDuration=this.beatDuration*e,this.emit("timeSignatureChange",{timeSignature:this.timeSignature})}setPattern(e){if(!this.patterns.has(e))return;const t=this.patterns.get(e);this.currentPattern=e,t.timeSignature&&this.setTimeSignature(...t.timeSignature),void 0!==t.groove&&(this.groove=t.groove),this.emit("patternChange",{pattern:e})}onBeatCallback(e){return this.beatCallbacks.add(e),()=>this.beatCallbacks.delete(e)}onBarCallback(e){return this.barCallbacks.add(e),()=>this.barCallbacks.delete(e)}emit(e,t){this.listeners.has(e)&&this.listeners.get(e).forEach(e=>e(t))}on(e,t){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t),()=>{this.listeners.has(e)&&this.listeners.get(e).delete(t)}}syncToAudio(e,t){this.audioSync={context:e,source:t}}getAdapter(){return{getTimeInfo:()=>this.getTimeInfo(),isOnBeat:(e=.1)=>this.beatProgress<e||this.beatProgress>1-e,isOnSubdivision:(e,t=.1)=>{const i=this.subdivisions[e]||0;return i<t||i>1-t},getBeatSync:(e=0,t=1,i="linear")=>{let n=this.beatProgress;switch(i){case"ease":n=.5-Math.cos(n*Math.PI)/2;break;case"bounce":n=Math.abs(Math.sin(n*Math.PI));break;case"pulse":n=Math.pow(Math.sin(n*Math.PI),2)}return e+(t-e)*n},getAccentedValue:(e,t=2)=>e*(1+(this.getAccent(this.currentBeat%this.timeSignature[0])-.5)*t),onBeat:e=>this.onBeatCallback(e),onBar:e=>this.onBarCallback(e),beatsToMs:e=>e*this.beatDuration,msToBeats:e=>e/this.beatDuration,isPlaying:()=>this.isPlaying,getBPM:()=>this.bpm,getPattern:()=>this.currentPattern}}},"undefined"!=typeof window&&(window.__emotiveRhythmEngine=Rc));class Ic{constructor(){this.enabled=!1,this.adapter=null,this.beatProgress=0,this.barProgress=0,this.accent=.5,this.intensity=1,this.bpm=120,this.isOnBeat=!1,this.pattern=null,this.grooveEnabled=!0,this.grooveTime=0,this._lastBeatProgress=0,this._staleFrameCount=0,this.modulation={scaleMultiplier:1,glowMultiplier:1,positionMultiplier:1,rotationMultiplier:1,accentBoost:0,grooveOffset:[0,0,0],grooveScale:1,grooveRotation:[0,0,0]},this._target={scaleMultiplier:1,glowMultiplier:1,positionMultiplier:1,rotationMultiplier:1,accentBoost:0,grooveOffset:[0,0,0],grooveScale:1,grooveRotation:[0,0,0]},this.config={beatSyncStrength:.3,accentMultiplier:1.5,grooveBounceAmount:.02,grooveSwayAmount:.015,groovePulseAmount:.03,grooveRotationAmount:.02,smoothingSpeed:8,grooveSmoothingSpeed:6}}_lerp(e,t,i,n){return e+(t-e)*(1-Math.exp(-i*n))}_lerpArray(e,t,i,n){const a=1-Math.exp(-i*n);return e.map((e,i)=>e+(t[i]-e)*a)}initialize(){this.adapter=Rc.getAdapter(),this.enabled=!0,this.adapter.onBeat(e=>{this.accent=e.accent,this.isOnBeat=!0,setTimeout(()=>{this.isOnBeat=!1},100)})}start(e=120,t="straight"){this.enabled||this.initialize(),e&&Rc.setBPM(e),t&&Rc.setPattern(t),Rc.start()}stop(){Rc.stop()}setBPM(e){Rc.setBPM(e),this.bpm=e}setPattern(e){Rc.setPattern(e),this.pattern=e}update(e){const t=e/1e3;if(this.adapter||(this.adapter=Rc.getAdapter()),!this.adapter)return void this.resetModulation(t);if(!this.adapter.isPlaying())return void this.resetModulation(t);this.enabled=!0;const i=this.adapter.getTimeInfo();if(Math.abs(i.beatProgress-this._lastBeatProgress)<.001?this._staleFrameCount++:(this._staleFrameCount=0,this._lastBeatProgress=i.beatProgress),this._staleFrameCount>10){const e=(i.bpm||this.bpm||120)/60;this.grooveTime+=t,this.beatProgress=this.grooveTime*e%1,this.barProgress=this.grooveTime*e/4%1}else this.beatProgress=i.beatProgress,this.barProgress=i.barProgress,this.grooveTime+=t;this.intensity=i.intensity,this.bpm=i.bpm||this.bpm,this.pattern=i.pattern,this.computeModulation(),this.applySmoothing(t)}computeModulation(){const{beatSyncStrength:e,accentMultiplier:t}=this.config,i=this.beatProgress*Math.PI*2,n=.5*(Math.cos(i)+1);this._target.scaleMultiplier=1+n*e*.4,this._target.glowMultiplier=1+n*e*.8,this._target.positionMultiplier=1+n*e*.2,this._target.rotationMultiplier=1+n*e*.15,this._target.accentBoost=this.isOnBeat?(this.accent-.5)*t:0,this.grooveEnabled?this.computeGroove():(this._target.grooveOffset=[0,0,0],this._target.grooveScale=1,this._target.grooveRotation=[0,0,0])}computeGroove(){const{grooveBounceAmount:e,grooveSwayAmount:t,groovePulseAmount:i,grooveRotationAmount:n}=this.config,a=this.beatProgress*Math.PI*2,r=Math.sin(a)*e,s=this.barProgress*Math.PI*2,o=Math.sin(s)*t,l=1+Math.sin(a)*i,h=Math.sin(s)*n;this._target.grooveOffset=[o,r,0],this._target.grooveScale=l,this._target.grooveRotation=[0,0,h]}applySmoothing(e){const{smoothingSpeed:t,grooveSmoothingSpeed:i}=this.config;this.modulation.scaleMultiplier=this._lerp(this.modulation.scaleMultiplier,this._target.scaleMultiplier,t,e),this.modulation.glowMultiplier=this._lerp(this.modulation.glowMultiplier,this._target.glowMultiplier,t,e),this.modulation.positionMultiplier=this._lerp(this.modulation.positionMultiplier,this._target.positionMultiplier,t,e),this.modulation.rotationMultiplier=this._lerp(this.modulation.rotationMultiplier,this._target.rotationMultiplier,t,e),this.modulation.accentBoost=this._lerp(this.modulation.accentBoost,this._target.accentBoost,.5*t,e),this.modulation.grooveOffset=this._lerpArray(this.modulation.grooveOffset,this._target.grooveOffset,i,e),this.modulation.grooveScale=this._lerp(this.modulation.grooveScale,this._target.grooveScale,i,e),this.modulation.grooveRotation=this._lerpArray(this.modulation.grooveRotation,this._target.grooveRotation,i,e)}resetModulation(e=.016){this._target.scaleMultiplier=1,this._target.glowMultiplier=1,this._target.positionMultiplier=1,this._target.rotationMultiplier=1,this._target.accentBoost=0,this._target.grooveOffset=[0,0,0],this._target.grooveScale=1,this._target.grooveRotation=[0,0,0],this.modulation.scaleMultiplier=this._lerp(this.modulation.scaleMultiplier,1,4,e),this.modulation.glowMultiplier=this._lerp(this.modulation.glowMultiplier,1,4,e),this.modulation.positionMultiplier=this._lerp(this.modulation.positionMultiplier,1,4,e),this.modulation.rotationMultiplier=this._lerp(this.modulation.rotationMultiplier,1,4,e),this.modulation.accentBoost=this._lerp(this.modulation.accentBoost,0,4,e),this.modulation.grooveOffset=this._lerpArray(this.modulation.grooveOffset,[0,0,0],4,e),this.modulation.grooveScale=this._lerp(this.modulation.grooveScale,1,4,e),this.modulation.grooveRotation=this._lerpArray(this.modulation.grooveRotation,[0,0,0],4,e)}getModulation(){return this.modulation}getMusicalDuration(e,t=null){if(!this.enabled||!this.adapter||!this.adapter.isPlaying())return e;if(t?.durationSync){const e=t.durationSync;if("beats"===e.mode&&e.beats)return this.adapter.beatsToMs(e.beats);if("bars"===e.mode&&e.bars)return this.adapter.beatsToMs(4*e.bars)}return e}isOnBeatNow(e=.1){return!(!this.enabled||!this.adapter)&&this.adapter.isOnBeat(e)}isOnAccent(e=.7){return this.isOnBeat&&this.accent>=e}getBeatSync(e,t,i="pulse"){return this.enabled&&this.adapter?this.adapter.getBeatSync(e,t,i):e}getAccentedValue(e,t=2){return this.enabled&&this.adapter?this.adapter.getAccentedValue(e,t):e}setGrooveEnabled(e){this.grooveEnabled=e,e||(this._target.grooveOffset=[0,0,0],this._target.grooveScale=1,this._target.grooveRotation=[0,0,0])}setGrooveConfig(e){Object.assign(this.config,e)}setBeatSyncStrength(e){this.config.beatSyncStrength=Math.max(0,Math.min(1,e))}isPlaying(){return this.enabled&&this.adapter&&this.adapter.isPlaying()}getBPM(){return this.bpm}getPattern(){return this.pattern}destroy(){this.enabled=!1,this.adapter=null,this.resetModulation()}}const Lc=new Ic;class Bc{constructor(){this.isTransitioning=!1,this.currentGeometryType=null,this.targetGeometryType=null,this.morphStartTime=0,this.morphDuration=1e3,this.morphProgress=0,this.visualProgress=0,this.hasSwappedGeometry=!1,this.isPausedAtSwap=!1,this.pausedAtTime=0,this.easing="easeInOutCubic"}startMorph(e,t,i=1e3){if(e===t&&!this.isTransitioning)return!1;if(this.isTransitioning&&this.targetGeometryType===t)return!1;if(this.isTransitioning){const e=this.calculateScaleMultiplier(this.visualProgress);if(this.hasSwappedGeometry){this.morphStartTime=Date.now(),this.morphDuration=i;const n=e>0?Math.sqrt(1-Math.min(e,1))/2:.5;this.morphProgress=n,this.visualProgress=n,this.hasSwappedGeometry=!1,this.targetGeometryType=t,this._interruptedTarget=t,this.isPausedAtSwap=!1,this.isGrowIn=!1;const a=n*i;return this.morphStartTime=Date.now()-a,!0}return this.targetGeometryType=t,this._interruptedTarget=t,!0}return this.currentGeometryType=e,this.targetGeometryType=t,this.morphStartTime=Date.now(),this.morphDuration=i,this.morphProgress=0,this.visualProgress=0,this.isTransitioning=!0,this.hasSwappedGeometry=!1,this.isPausedAtSwap=!1,this.pausedAtTime=0,this.isGrowIn=!1,this._interruptedTarget=null,!0}getInterruptedTarget(){const e=this._interruptedTarget;return this._interruptedTarget=null,e}growIn(e,t=500){return!this.isTransitioning&&(this.currentGeometryType=e,this.targetGeometryType=e,this.morphStartTime=Date.now(),this.morphDuration=t,this.morphProgress=0,this.visualProgress=0,this.isTransitioning=!0,this.hasSwappedGeometry=!0,this.isPausedAtSwap=!1,this.pausedAtTime=0,this.isGrowIn=!0,!0)}pauseAtSwap(){this.isTransitioning&&!this.isPausedAtSwap&&(this.isPausedAtSwap=!0,this.pausedAtTime=Date.now())}resumeFromSwap(){if(this.isPausedAtSwap){const e=Date.now()-this.pausedAtTime;this.morphStartTime+=e,this.isPausedAtSwap=!1,this.pausedAtTime=0}}update(e){if(!this.isTransitioning)return{isTransitioning:!1,progress:0,visualProgress:0,scaleMultiplier:1};if(this.isPausedAtSwap)return{isTransitioning:!0,progress:.5,visualProgress:.5,scaleMultiplier:0,waitingForGeometry:!0};const t=Date.now()-this.morphStartTime,i=Math.min(t/this.morphDuration,1);this.morphProgress=this.applyEasing(i),this.visualProgress=.6*this.visualProgress+.4*this.morphProgress,Math.abs(this.visualProgress-this.morphProgress)<.01&&(this.visualProgress=this.morphProgress);const n=this.calculateScaleMultiplier(this.visualProgress);let a=!1;return!this.hasSwappedGeometry&&this.morphProgress>=.5&&(this.hasSwappedGeometry=!0,a=!0),this.morphProgress>=1?(this.completeMorph(),{isTransitioning:!1,progress:1,visualProgress:1,scaleMultiplier:1,completed:!0}):{isTransitioning:!0,progress:this.morphProgress,visualProgress:this.visualProgress,scaleMultiplier:n,shouldSwapGeometry:a}}calculateScaleMultiplier(e){if(this.isGrowIn){const t=1.70158,i=1+(t+1)*Math.pow(e-1,3)+t*Math.pow(e-1,2);return Math.max(0,i)}if(e<=.5){const t=2*e;return 1-t*t}{const t=2*(e-.5);return t*(2-t)}}completeMorph(){this.currentGeometryType=this.targetGeometryType,this.targetGeometryType=null,this.isTransitioning=!1,this.morphProgress=0,this.visualProgress=0}applyEasing(e){switch(this.easing){case"linear":return e;case"easeInQuad":return e*e;case"easeOutQuad":return e*(2-e);case"easeInOutQuad":return e<.5?2*e*e:(4-2*e)*e-1;case"easeInOutSine":return-(Math.cos(Math.PI*e)-1)/2;default:return e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2}}getState(){return{isTransitioning:this.isTransitioning,currentGeometryType:this.currentGeometryType,targetGeometryType:this.targetGeometryType,progress:this.morphProgress,visualProgress:this.visualProgress}}cancel(){this.isTransitioning=!1,this.targetGeometryType=null,this.morphProgress=0,this.visualProgress=0}}class Oc{constructor(e={},t=null,i=null){if(this.config=e,this.rhythmEngine=t,this.geometryRotation=i,this.type=e.type||"gentle",this.speed=e.speed||1,i&&void 0!==i.baseSpeed){const e=i.baseSpeed,t=i.axes||[0,1,0];this.axes=[t[0]*e*this.speed,t[1]*e*this.speed,t[2]*e*this.speed]}else this.axes=e.axes||[0,.01,0];this.shake=e.shake||{amplitude:0,frequency:0},this.wobbleEnabled=!0,this.eruption=e.eruption||{enabled:!1},this.eruption.enabled&&(this.eruption.interval=this.eruption.interval||3e3,this.eruption.speedMultiplier=this.eruption.speedMultiplier||3,this.eruption.duration=this.eruption.duration||400,this.eruption.nextEruptionTime=this.eruption.interval,this.eruption.eruptionStartTime=-1),this.musicSync=void 0!==e.musicSync&&e.musicSync,this.time=0,this.episodicWobble={enabled:!1,minInterval:2e3,maxInterval:5e3,amplitude:.05,duration:200,nextWobbleTime:0,wobbleStartTime:-1,wobbleTarget:[0,0,0]}}update(e,t){switch(this.time+=e,this.episodicWobble.enabled&&this.wobbleEnabled&&this._applyEpisodicWobble(e,t),this.type){case"gentle":default:return this._evaluateGentle(e,t);case"unstable":return this._evaluateUnstable(e,t);case"rhythmic":return this._evaluateRhythmic(e,t);case"orbital":return this._evaluateOrbital(e,t);case"still":return this._evaluateStill(e,t);case"suspicious":return this._evaluateSuspicious(e,t)}}_evaluateGentle(e,t){const i=.001*e;return t[0]+=this.axes[0]*this.speed*i,t[1]+=this.axes[1]*this.speed*i,t[2]+=this.axes[2]*this.speed*i,t}_evaluateUnstable(e,t){const i=.001*e;let n=1;if(this.eruption.enabled&&(this.eruption.eruptionStartTime<0&&this.time>=this.eruption.nextEruptionTime&&(this.eruption.eruptionStartTime=this.time),this.eruption.eruptionStartTime>=0)){const e=this.time-this.eruption.eruptionStartTime;if(e<this.eruption.duration){const t=e/this.eruption.duration,i=Math.sin(t*Math.PI);n=1+(this.eruption.speedMultiplier-1)*i}else this.eruption.eruptionStartTime=-1,this.eruption.nextEruptionTime=this.time+this.eruption.interval}const a=this.speed*n;if(t[0]+=this.axes[0]*a*i,t[1]+=this.axes[1]*a*i,t[2]+=this.axes[2]*a*i,this.wobbleEnabled){const e=.001*this.time,i=this.shake.frequency||8,n=this.shake.amplitude||.02,a=.02,r=Math.min(n,a),s=Math.sin(e*i*Math.PI*2)*r*.7,o=Math.sin(e*i*Math.PI*2*1.3)*r*.5,l=Math.sin(e*i*Math.PI*2*.9)*r*.8;t[0]+=s,t[1]+=o,t[2]+=l}return t}_evaluateRhythmic(e,t){const i=.001*e;if(!this.musicSync||!this.rhythmEngine)return this._evaluateGentle(e,t);{const e=60/(this.rhythmEngine.bpm||120),n=.001*this.time%e,a=1+.3*Math.sin(n/e*Math.PI*2);t[0]+=this.axes[0]*this.speed*a*i,t[1]+=this.axes[1]*this.speed*a*i,t[2]+=this.axes[2]*this.speed*a*i}return t}_evaluateOrbital(e,t){const i=.001*e,n=.001*this.time,a=.5*this.speed,r=.1*Math.sin(n*a*Math.PI*2),s=.05*Math.sin(n*a*Math.PI*2*.5);return t[0]+=r*i,t[1]+=this.axes[1]*this.speed*i,t[2]+=s*i,t}_evaluateStill(e,t){const i=.001*e;return t[0]+=.1*this.axes[0]*i,t[1]+=.1*this.axes[1]*i,t[2]+=.1*this.axes[2]*i,t}_evaluateSuspicious(e,t){const i=.001*e,n=.001*this.time,a=4/this.speed,r=n%a/a;let s;if(r<.85)s=r/.85*Math.PI;else{const e=(r-.85)/.15;s=Math.PI*(1-e)}const o=s-t[1];return t[1]+=3*o*i,t}reset(){this.time=0}_applyEpisodicWobble(e,t){const i=this.episodicWobble;if(-1===i.wobbleStartTime&&this.time>=i.nextWobbleTime){i.wobbleStartTime=this.time,i.wobbleTarget=[(Math.random()-.5)*i.amplitude,(Math.random()-.5)*i.amplitude,(Math.random()-.5)*i.amplitude];const e=i.minInterval+Math.random()*(i.maxInterval-i.minInterval);i.nextWobbleTime=this.time+e}if(-1!==i.wobbleStartTime){const e=this.time-i.wobbleStartTime,n=Math.min(e/i.duration,1);if(n<1){const e=Math.sin(n*Math.PI);t[0]+=i.wobbleTarget[0]*e,t[1]+=i.wobbleTarget[1]*e,t[2]+=i.wobbleTarget[2]*e}else i.wobbleStartTime=-1}}updateConfig(e){if(this.config=e,this.type=e.type||"gentle",this.speed=e.speed||1,this.geometryRotation&&void 0!==this.geometryRotation.baseSpeed){const e=this.geometryRotation.baseSpeed,t=this.geometryRotation.axes||[0,1,0];this.axes=[t[0]*e*this.speed,t[1]*e*this.speed,t[2]*e*this.speed]}else this.axes=e.axes||[0,.01,0];this.shake=e.shake||{amplitude:0,frequency:0},this.musicSync=void 0!==e.musicSync&&e.musicSync}applyUndertoneMultipliers(e){if(void 0!==e.speedMultiplier&&(this.speed*=e.speedMultiplier),void 0!==e.shakeMultiplier&&this.shake.amplitude&&(this.shake.amplitude*=e.shakeMultiplier),void 0!==e.enableEpisodicWobble&&(this.episodicWobble.enabled=e.enableEpisodicWobble,this.episodicWobble.enabled&&0===this.episodicWobble.nextWobbleTime)){const e=this.episodicWobble.minInterval+Math.random()*(this.episodicWobble.maxInterval-this.episodicWobble.minInterval);this.episodicWobble.nextWobbleTime=this.time+e}}setWobbleEnabled(e){this.wobbleEnabled=e}}class Fc{constructor(e={}){this.config=e,this.strength=void 0!==e.strength?e.strength:.5,this.damping=void 0!==e.damping?e.damping:.8,this.centerOfMass=e.centerOfMass||[0,-.3,0],this.axes=e.axes||{pitch:!0,roll:!0,yaw:!1},this.angularVelocity={x:0,y:0,z:0}}update(e,t){if(0===this.strength)return t;const i=.001*e,n=t[0],a=t[1],r=t[2];if(this.axes.pitch){const e=-n*this.strength;this.angularVelocity.x+=e*i,this.angularVelocity.x*=1-this.damping,t[0]+=this.angularVelocity.x*i}if(this.axes.roll){const e=-r*this.strength;this.angularVelocity.z+=e*i,this.angularVelocity.z*=1-this.damping,t[2]+=this.angularVelocity.z*i}if(this.axes.yaw){const e=-a*this.strength;this.angularVelocity.y+=e*i,this.angularVelocity.y*=1-this.damping,t[1]+=this.angularVelocity.y*i}return t}reset(){this.angularVelocity={x:0,y:0,z:0}}updateConfig(e){this.config=e,this.strength=void 0!==e.strength?e.strength:this.strength,this.damping=void 0!==e.damping?e.damping:this.damping,this.centerOfMass=e.centerOfMass||this.centerOfMass,this.axes=e.axes||this.axes}applyUndertoneMultipliers(e){void 0!==e.strengthMultiplier&&(this.strength*=e.strengthMultiplier)}}class Uc{constructor(e={},t=null){this.config=e,this.camera=t,this.strength=void 0!==e.strength?e.strength:1,this.lockedFace=e.lockedFace||[0,0,1],this.calibrationRotation=e.calibrationRotation||[0,0,0],this.lerpSpeed=void 0!==e.lerpSpeed?e.lerpSpeed:1,this.tempVector=new xt,this.tempQuaternion=new _t,this.targetQuaternion=new _t,this.calibrationQuaternion=new _t,this.currentQuaternion=new _t,this._lockedFaceVec=new xt,this._targetMatrix=new bi,this._lookAtOrigin=new xt(0,0,0),this._upVector=new xt(0,1,0),this._tempEuler=new Pi(0,0,0,"XYZ"),this._defaultPosition=new xt(0,0,0)}update(e,t,i){if(0===this.strength||!this.camera)return t;const n=i||this._defaultPosition,a=.001*e;this.tempVector.copy(this.camera.position).sub(n),this.tempVector.lengthSq()<1e-4&&this.tempVector.set(0,0,1),this.tempVector.normalize(),this._lockedFaceVec.set(this.lockedFace[0],this.lockedFace[1],this.lockedFace[2]).normalize(),this._targetMatrix.lookAt(this.tempVector,this._lookAtOrigin,this._upVector),this.targetQuaternion.setFromRotationMatrix(this._targetMatrix),0===this.calibrationRotation[0]&&0===this.calibrationRotation[1]&&0===this.calibrationRotation[2]||(this._tempEuler.set(this.calibrationRotation[0],this.calibrationRotation[1],this.calibrationRotation[2],"XYZ"),this.calibrationQuaternion.setFromEuler(this._tempEuler),this.targetQuaternion.multiply(this.calibrationQuaternion)),this._tempEuler.set(t[0],t[1],t[2],"XYZ"),this.currentQuaternion.setFromEuler(this._tempEuler);const r=Math.min(1,this.strength*this.lerpSpeed*a*60);return this.currentQuaternion.slerp(this.targetQuaternion,r),this._tempEuler.setFromQuaternion(this.currentQuaternion,"XYZ"),t[0]=this._tempEuler.x,t[1]=this._tempEuler.y,t[2]=this._tempEuler.z,t}setCamera(e){this.camera=e}setCalibrationRotation(e){this.calibrationRotation=e}updateConfig(e){this.config=e,this.strength=void 0!==e.strength?e.strength:this.strength,this.lockedFace=e.lockedFace||this.lockedFace,this.calibrationRotation=e.calibrationRotation||this.calibrationRotation,this.lerpSpeed=void 0!==e.lerpSpeed?e.lerpSpeed:this.lerpSpeed}dispose(){this.camera=null,this.tempVector=null,this.tempQuaternion=null,this.targetQuaternion=null,this.calibrationQuaternion=null,this.currentQuaternion=null}}const zc=new Map;var kc=function(e){return zc.get(e)||null},Nc={name:"bounce",emoji:"⬆️",type:"blending",description:"Vertical oscillation with smooth easing",config:{duration:800,musicalDuration:{musical:!0,beats:2},amplitude:30,frequency:2,axis:"vertical",damping:!0,easing:"sine",strength:.6,particleMotion:{type:"bounce",axis:"vertical",strength:.6,frequency:2}},rhythm:{enabled:!0,syncMode:"beat",timingSync:"nextBeat",interruptible:!0,priority:3,blendable:!0,crossfadePoint:"anyBeat",amplitudeSync:{onBeat:1.8,offBeat:.6,curve:"bounce"},frequencySync:{mode:"tempo",multiplier:1},durationSync:{mode:"beats",beats:4},accentResponse:{enabled:!0,multiplier:1.5},patternOverrides:{waltz:{frequencySync:{multiplier:.75},durationSync:{beats:3}},swing:{amplitudeSync:{onBeat:2,offBeat:.4,curve:"ease"}},dubstep:{amplitudeSync:{onBeat:1.5,dropBeat:3,curve:"pulse"}},breakbeat:{frequencySync:{multiplier:1.5},amplitudeSync:{onBeat:2.2,offBeat:.3}}}},initialize(e,t){e.gestureData||(e.gestureData={}),e.gestureData.bounce={startY:e.y,startX:e.x,startVx:e.vx,startVy:e.vy,initialized:!0}},apply(e,t,i,n,a,r){e.gestureData?.bounce?.initialized||this.initialize(e,i);const s={...this.config,...i},o=s.strength||this.config.strength||1,l=this.easeInOutCubic(t);let{frequency:h}=s;const c=i.phase||0;let u=s.amplitude*o*e.scaleFactor;i.rhythmModulation&&(u*=i.rhythmModulation.amplitudeMultiplier||1,u*=i.rhythmModulation.accentMultiplier||1,i.rhythmModulation.frequencyMultiplier&&(h*=i.rhythmModulation.frequencyMultiplier));const d=Math.sin((l+c)*Math.PI*2*h);if(s.damping&&t>.7&&(u*=1-(t-.7)/.3*.8),"vertical"===s.axis?(e.vy+=d*u*.01*n,t>.9&&(e.vx*=.98)):"horizontal"===s.axis&&(e.vx+=d*u*.01*n,t>.9&&(e.vy*=.98)),t>.9){const i=1-10*(t-.9);e.vx=e.vx*(.95+.05*i),e.vy=e.vy*(.95+.05*i)}},cleanup(e){e.gestureData?.bounce&&delete e.gestureData.bounce},easeInOutCubic:e=>e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2,"3d":{evaluate(e,t){const i=t||{},n=i.amplitude||30,a=i.frequency||2,r=.003*n*(i.strength||.6),s=(e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2)*Math.PI*a,o=Math.abs(Math.sin(s));let l=r;return e>.7&&(l*=1-(e-.7)/.3*.8),{position:[0,o*l,0],rotation:[0,0,0],scale:1+.08*o}}}},Gc={name:"pulse",emoji:"💗",type:"blending",description:"Radial expansion and contraction from center",config:{duration:600,amplitude:30,frequency:1,holdPeak:.1,easing:"sine",scaleAmount:.2,glowAmount:.3,strength:.15,direction:"outward",particleMotion:{type:"pulse",strength:.15,direction:"outward",frequency:1}},rhythm:{enabled:!0,syncMode:"beat",amplitudeSync:{onBeat:1.6,offBeat:.8,curve:"pulse"},frequencySync:{mode:"locked",subdivision:"quarter"},durationSync:{mode:"beats",beats:1},accentResponse:{enabled:!0,multiplier:2},patternOverrides:{waltz:{amplitudeSync:{onBeat:2,offBeat:.5},durationSync:{beats:3}},swing:{amplitudeSync:{onBeat:1.8,offBeat:.6,curve:"ease"},frequencySync:{subdivision:"swing"}},dubstep:{amplitudeSync:{onBeat:1.2,dropBeat:4,curve:"pulse"}},breakbeat:{frequencySync:{mode:"random",range:[.5,2]},amplitudeSync:{onBeat:2.5,offBeat:.3}}}},initialize(e,t,i,n){e.gestureData||(e.gestureData={});const a=e.x-i,r=e.y-n,s=Math.sqrt(a*a+r*r),o=Math.atan2(r,a);e.gestureData.pulse={baseDistance:s,angle:o,startX:e.x,startY:e.y,initialized:!0}},apply(e,t,i,n,a,r){e.gestureData?.pulse?.initialized||this.initialize(e,i,a,r);const s=e.gestureData.pulse,o={...this.config,...i},l=i.strength||1,h=this.easeInOutSine(t);let c,{frequency:u}=o,{amplitude:d}=o;i.rhythmModulation&&(d*=i.rhythmModulation.amplitudeMultiplier||1,d*=i.rhythmModulation.accentMultiplier||1,i.rhythmModulation.frequencyMultiplier&&(u*=i.rhythmModulation.frequencyMultiplier));const p=h*u*2%2;c=o.holdPeak>0&&p>1-o.holdPeak&&p<1+o.holdPeak?1:Math.sin(h*Math.PI*2*u);const m=c*d*l*e.scaleFactor,f=s.baseDistance+m,g=a+Math.cos(s.angle)*f,v=r+Math.sin(s.angle)*f,y=.15*n;if(e.vx+=(g-e.x)*y*.1,e.vy+=(v-e.y)*y*.1,t>.9){const i=1-10*(t-.9);e.vx*=.9+.1*i,e.vy*=.9+.1*i}},cleanup(e){e.gestureData?.pulse&&delete e.gestureData.pulse},easeInOutSine:e=>-(Math.cos(Math.PI*e)-1)/2,"3d":{evaluate(e,t){const i=t||{},n=i.frequency||1,a=i.strength||.15,r=i.scaleAmount||.2,s=i.glowAmount||.3,o=-(Math.cos(Math.PI*e)-1)/2,l=Math.sin(o*Math.PI*2*n);return{position:[0,0,0],rotation:[0,0,0],scale:1+l*r*a,glowIntensity:1+Math.max(-.3,Math.min(.3,l*s*a*2)),glowBoost:Math.max(0,.8*l)}}}},Vc={name:"shake",emoji:"🫨",type:"blending",description:"Random jitter movement for vibration effects",config:{duration:400,amplitude:15,frequency:15,decay:.9,smoothing:.1,axes:"both",easing:"linear",strength:3,particleMotion:{type:"shake",strength:3,frequency:15,decay:!1}},rhythm:{enabled:!0,syncMode:"subdivision",amplitudeSync:{subdivision:"sixteenth",onBeat:2.5,offBeat:.7,curve:"pulse"},frequencySync:{mode:"tempo",baseFrequency:15,scaling:"linear"},durationSync:{mode:"beats",beats:2},patternOverrides:{breakbeat:{amplitudeSync:{onBeat:3,offBeat:.2},frequencySync:{mode:"random",range:[8,20]}},dubstep:{amplitudeSync:{subdivision:"eighth",onBeat:4,dropBeat:6,curve:"pulse"}},swing:{amplitudeSync:{onBeat:1.8,offBeat:1,curve:"ease"}}}},initialize(e,t){e.gestureData||(e.gestureData={}),e.gestureData.shake={originalX:e.x,originalY:e.y,randomAngle:Math.random()*Math.PI*2,initialized:!0}},apply(e,t,i,n,a,r){e.gestureData?.shake?.initialized||this.initialize(e,i);const s=e.gestureData.shake,o={...this.config,...i},l=o.strength||this.config.strength||1;let{amplitude:h}=o,{frequency:c}=o;i.rhythmModulation&&(h*=i.rhythmModulation.amplitudeMultiplier||1,h*=i.rhythmModulation.accentMultiplier||1,i.rhythmModulation.frequencyMultiplier&&(c*=i.rhythmModulation.frequencyMultiplier));const u=o.decay?1-t:1,d=Math.sin(t*Math.PI*c)*h*u*l*e.scaleFactor,p=d*Math.cos(s.randomAngle),m=d*Math.sin(s.randomAngle);e.x=s.originalX+p,e.y=s.originalY+m},pseudoRandom(e){const t=1e4*Math.sin(e);return t-Math.floor(t)},cleanup(e){e.gestureData?.shake&&(e.x=e.gestureData.shake.originalX,e.y=e.gestureData.shake.originalY,delete e.gestureData.shake)},"3d":{evaluate(e,t){const i=t||{},n=.015*(i.amplitude||15),a=i.frequency||15,r=i.strength||1,s=i.decay?1-e:1,o=Math.sin(e*Math.PI*a)*n*s*r,l=Math.floor(e*a);return{position:[o*(1e4*Math.sin(l)%1-.5)*2,0,o*(1e4*Math.sin(1.3*l)%1-.5)*2],rotation:[0,0,o*(1e4*Math.sin(1.7*l)%1-.5)*.5],scale:1}}}},Hc={name:"nod",emoji:"🙂",type:"blending",description:"Vertical nodding motion",config:{duration:500,amplitude:15,frequency:2,easing:"sine",strength:.4,particleMotion:{type:"bounce",axis:"vertical",strength:.4,frequency:2,phase:0}},rhythm:{enabled:!0,syncMode:"beat",timingSync:"nextBeat",interruptible:!1,priority:5,blendable:!1,minDuration:"halfBar",frequencySync:{mode:"subdivision",subdivision:"half",multiplier:1},amplitudeSync:{onBeat:1.4,offBeat:.8,curve:"ease"},durationSync:{mode:"beats",beats:2},patternOverrides:{waltz:{frequencySync:{subdivision:"quarter"},amplitudeSync:{onBeat:1.6,curve:"ease"}},swing:{amplitudeSync:{onBeat:1.5,offBeat:.9}},dubstep:{amplitudeSync:{onBeat:1.2,dropBeat:3,curve:"pulse"}}}},initialize(e,t){e.gestureData||(e.gestureData={}),e.gestureData.nod={startY:e.y,initialized:!0}},apply(e,t,i,n,a,r){e.gestureData?.nod?.initialized||this.initialize(e,i);const s={...this.config,...i},o=s.strength||this.config.strength||1;let{frequency:l}=s,{amplitude:h}=s;i.rhythmModulation&&(h*=i.rhythmModulation.amplitudeMultiplier||1,h*=i.rhythmModulation.accentMultiplier||1,i.rhythmModulation.frequencyMultiplier&&(l*=i.rhythmModulation.frequencyMultiplier));const c=Math.sin(t*Math.PI*2*l);h=h*o*e.scaleFactor,e.vy+=c*h*.01*n,t>.9&&(e.vy*=.95)},cleanup(e){e.gestureData?.nod&&delete e.gestureData.nod},"3d":{evaluate(e,t){const i={...this.config,...t};let{frequency:n}=i,{amplitude:a}=i;t.rhythmModulation&&(a*=t.rhythmModulation.amplitudeMultiplier||1,a*=t.rhythmModulation.accentMultiplier||1,t.rhythmModulation.frequencyMultiplier&&(n*=t.rhythmModulation.frequencyMultiplier));const r=Math.sin(e*Math.PI),s=e>.9?.95:1;return{position:[0,0,r*(.1*a)*.015*s],rotation:[r*(.08*a)*s,0,0],scale:1}}}},Wc={name:"vibrate",emoji:"📳",type:"blending",description:"High frequency vibration",config:{duration:500,frequency:20,amplitude:8,easing:"linear",strength:2,particleMotion:{type:"shake",strength:2,frequency:20,amplitude:8}},rhythm:{enabled:!0,syncMode:"subdivision",frequencySync:{subdivision:"thirty-second",baseFrequency:20,tempoScaling:!0},amplitudeSync:{onBeat:1.5,offBeat:.8,curve:"pulse"},durationSync:{mode:"beats",beats:1},patternOverrides:{dubstep:{frequencySync:{subdivision:"sixteenth"},amplitudeSync:{onBeat:2,dropBeat:3}},breakbeat:{frequencySync:{mode:"random",range:[15,30]}}}},initialize(e,t){e.gestureData||(e.gestureData={}),e.gestureData.vibrate={timer:0,seed:1e3*Math.random(),initialized:!0}},apply(e,t,i,n,a,r){e.gestureData?.vibrate?.initialized||this.initialize(e,i);const s=e.gestureData.vibrate,o={...this.config,...i},l=o.strength||this.config.strength||1;let{amplitude:h}=o,{frequency:c}=o;i.rhythmModulation&&(h*=i.rhythmModulation.amplitudeMultiplier||1,h*=i.rhythmModulation.accentMultiplier||1,i.rhythmModulation.frequencyMultiplier&&(c*=i.rhythmModulation.frequencyMultiplier)),s.timer+=n*c;const u=(Math.random()-.5)*h*l,d=(Math.random()-.5)*h*l;if(e.vx+=.5*u*n,e.vy+=.5*d*n,e.vx*=.9,e.vy*=.9,t>.8){const i=1-5*(t-.8);e.vx*=i,e.vy*=i}},cleanup(e){e.gestureData?.vibrate&&delete e.gestureData.vibrate},"3d":{evaluate(e,t){const i={...this.config,...t};let{amplitude:n}=i;const a=i.strength||this.config.strength||1;t.rhythmModulation&&(n*=t.rhythmModulation.amplitudeMultiplier||1,n*=t.rhythmModulation.accentMultiplier||1);const r=Math.sin(e*Math.PI),s=n*a*.003*r;return{position:[(Math.random()-.5)*s,(Math.random()-.5)*s,(Math.random()-.5)*s],rotation:[.01*(Math.random()-.5)*r,.01*(Math.random()-.5)*r,.01*(Math.random()-.5)*r],scale:1+.01*(Math.random()-.5)*r}}}},jc={name:"orbit",emoji:"🪐",description:"3D orbital motion around center",type:"override",config:{speed:1,rotations:1,zRotations:1,smoothness:.15,verticalOscillation:0,centripetal:!1},rhythm:{enabled:!0,syncMode:"bar",speedSync:{mode:"tempo",baseSpeed:1,scaling:"linear"},rotationSync:{mode:"bars",rotationsPerBar:1,zSync:!0},radiusSync:{subdivision:"quarter",pulsAmount:.1,curve:"ease"},patternOverrides:{waltz:{rotationSync:{rotationsPerBar:.75},radiusSync:{pulsAmount:.15}},swing:{speedSync:{mode:"swing",ratio:.67},verticalOscillation:.2},dubstep:{radiusSync:{subdivision:"eighth",pulsAmount:.3,dropMultiplier:2}},breakbeat:{speedSync:{mode:"random",range:[.5,2]},centripetal:!0}}},apply:function(e,t,i,n,a,r){e.gestureData||(e.gestureData={});const s=e.gestureData,o=i,l=i.amplitude||1;if(!s.initialized){s.originalX=e.x,s.originalY=e.y,s.originalZ=e.z||0,s.originalVx=e.vx||0,s.originalVy=e.vy||0;const t=e.x-a,i=e.y-r;s.radius=Math.sqrt(t*t+i*i),s.radius<50&&(s.radius=50+100*Math.random()),s.initialAngle=Math.atan2(i,t),s.orbitSpeed=o.speed*(.8+.4*Math.random()),s.orbitTilt=.3*Math.random(),s.initialized=!0}let{rotations:h}=o,c=.05;o.rhythmModulation&&(o.rhythmModulation.speedMultiplier&&(s.orbitSpeed*=o.rhythmModulation.speedMultiplier),o.rhythmModulation.rotationMultiplier&&(h*=o.rhythmModulation.rotationMultiplier),o.rhythmModulation.radiusPulse&&(c=o.rhythmModulation.radiusPulse));let u=1,d=1;t<.15?(u=t/.15,u=u*u*(3-2*u),d=u):t>.85&&(u=(1-t)/.15,u=u*u*(3-2*u),d=u);const p=s.initialAngle+t*Math.PI*2*h*u,m=1+Math.sin(t*Math.PI*4)*c*u,f=s.radius*l*m*u,g=a+Math.cos(p)*f,v=r+Math.sin(p)*f,y=p*o.zRotations;if(e.z=.8*Math.sin(y)*u+s.originalZ*(1-u),t<.15){const t=.3*u;e.x=s.originalX+(g-s.originalX)*t,e.y=s.originalY+(v-s.originalY)*t;const i=-Math.sin(p)*f*s.orbitSpeed,n=Math.cos(p)*f*s.orbitSpeed;e.vx=s.originalVx+(i-s.originalVx)*d,e.vy=s.originalVy+(n-s.originalVy)*d}else if(t>.85){e.x=g+(s.originalX-g)*(1-u),e.y=v+(s.originalY-v)*(1-u);const t=-Math.sin(p)*f*s.orbitSpeed,i=Math.cos(p)*f*s.orbitSpeed;e.vx=t*d+s.originalVx*(1-d),e.vy=i*d+s.originalVy*(1-d)}else{if(o.verticalOscillation>0){const t=Math.sin(2*p)*o.verticalOscillation*l;e.y=v+t,e.x=g}else{const t=o.smoothness||.1;e.x+=(g-e.x)*t,e.y+=(v-e.y)*t}e.vx=-Math.sin(p)*f*s.orbitSpeed,e.vy=Math.cos(p)*f*s.orbitSpeed}if(o.centripetal){const i=1+.3*(1-Math.abs(e.z)),n=s.initialAngle+t*Math.PI*2*o.rotations*i;e.x=a+Math.cos(n)*f,e.y=r+Math.sin(n)*f}},emotions:["zen","love","excited","surprise"],features:{uses3D:!0,smooth:!0,looping:!0,dramatic:!0},"3d":{evaluate(e,t){const i={...this.config,...t};let{rotations:n}=i;const{zRotations:a}=i;t.rhythmModulation&&t.rhythmModulation.rotationMultiplier&&(n*=t.rhythmModulation.rotationMultiplier);let r=1;e<.15?(r=e/.15,r=r*r*(3-2*r)):e>.85&&(r=(1-e)/.15,r=r*r*(3-2*r));const s=e*Math.PI*2*n*r,o=s*a,l=.1*Math.sin(s)*r,h=.05*Math.cos(s)*r,c=.05*Math.sin(o)*r;return{position:[0,0,.2*Math.sin(o)*r],rotation:[h,l,c],scale:1+.03*Math.sin(2*s)*r}}}},Xc={name:"twitch",emoji:"⚡",type:"blending",description:"Nervous, paranoid twitching",config:{intensity:8,frequency:.08,duration:100,recovery:200,maxOffset:15,sharpness:.9},rhythm:{enabled:!0,syncMode:"subdivision",probabilitySync:{subdivision:"sixteenth",onBeat:.3,offBeat:.05,accentBoost:2},intensitySync:{onBeat:2,offBeat:.8,curve:"pulse"},patternOverrides:{breakbeat:{probabilitySync:{onBeat:.5,offBeat:.1},intensitySync:{onBeat:3,offBeat:.5}},dubstep:{intensitySync:{onBeat:1.5,dropBeat:5,curve:"pulse"}}}},apply(e,t,i,n,a,r){e.gestureData||(e.gestureData={}),e.gestureData.twitch||(e.gestureData.twitch={twitchOffset:{x:0,y:0},targetOffset:{x:0,y:0},isTwitching:!1,twitchTimer:0,cooldownTimer:0,lastTwitch:0});const s=e.gestureData.twitch,{config:o}=this;let l=i.intensity||o.intensity;i.rhythmModulation&&(l*=i.rhythmModulation.amplitudeMultiplier||1,l*=i.rhythmModulation.accentMultiplier||1,i.rhythmModulation.probabilityMultiplier);const h=Date.now();if(!s.isTwitching&&s.cooldownTimer<=0&&Math.random()<(i.frequency||o.frequency)){s.isTwitching=!0,s.twitchTimer=o.duration,s.cooldownTimer=o.recovery;const e=Math.random()*Math.PI*2,t=.5*o.maxOffset+Math.random()*(.5*o.maxOffset);s.targetOffset={x:Math.cos(e)*t*l/8,y:Math.sin(e)*t*l/8},s.lastTwitch=h}if(s.cooldownTimer>0&&(s.cooldownTimer-=16*n),s.isTwitching)if(s.twitchTimer-=16*n,s.twitchTimer>0){const{sharpness:e}=o;s.twitchOffset.x+=(s.targetOffset.x-s.twitchOffset.x)*e,s.twitchOffset.y+=(s.targetOffset.y-s.twitchOffset.y)*e}else s.isTwitching=!1;else s.twitchOffset.x*=.85,s.twitchOffset.y*=.85;e.vx+=s.twitchOffset.x*n*.5,e.vy+=s.twitchOffset.y*n*.5,Math.random()<.1&&(e.vx+=(Math.random()-.5)*l*.3,e.vy+=(Math.random()-.5)*l*.3)},cleanup(e){e.gestureData?.twitch&&delete e.gestureData.twitch},"3d":{evaluate(e,t){const i=t.config||{};let n=i.intensity||8;const a=i.maxOffset||15,r=i.frequency||.08;t.rhythmModulation&&(n*=t.rhythmModulation.amplitudeMultiplier||1,n*=t.rhythmModulation.accentMultiplier||1);const s=9999*Math.floor(10*e),o=e=>{const t=1e4*Math.sin(s+e);return t-Math.floor(t)};if(o(0)<3*r){const e=o(1)*Math.PI*2,t=a*n/8*.005;return{position:[Math.cos(e)*t*o(2),Math.sin(e)*t*o(3),(o(4)-.5)*t],rotation:[.2*(o(5)-.5),.2*(o(6)-.5),.2*(o(7)-.5)],scale:1+.1*(o(8)-.5)}}{const e=.5;return{position:[(o(10)-.5)*e,(o(11)-.5)*e,(o(12)-.5)*e],rotation:[.01*(o(13)-.5),.01*(o(14)-.5),.01*(o(15)-.5)],scale:1}}}}},qc={name:"sway",type:"blending",emoji:"🌊",description:"Gentle side-to-side swaying motion",config:{duration:2e3,amplitude:20,frequency:1,strength:.5},rhythm:{enabled:!0,syncMode:"bar",amplitudeSync:{onBeat:1.2,offBeat:.9,curve:"ease"},durationSync:{mode:"bars",bars:1},patternOverrides:{waltz:{durationSync:{bars:1},amplitudeSync:{onBeat:1.5,curve:"ease"}},swing:{amplitudeSync:{onBeat:1.3,offBeat:.7,curve:"bounce"}}}},apply(e,t,i,n,a,r){const s={...this.config,...i},o=s.amplitude||this.config.amplitude,l=s.frequency||this.config.frequency,h=s.strength||this.config.strength,c=Math.sin(t*Math.PI*2*l)*o;e.vx+=.01*c*n*h,e.vy+=.5*Math.cos(t*Math.PI*4)*n*h},cleanup(e){},"3d":{evaluate(e,t){const i={...this.config,...t};let n=i.amplitude||this.config.amplitude;const a=i.frequency||this.config.frequency,r=i.strength||this.config.strength;t.rhythmModulation&&(n*=t.rhythmModulation.amplitudeMultiplier||1,n*=t.rhythmModulation.accentMultiplier||1);const s=Math.sin(e*Math.PI*2*a),o=n*r*.3*.01,l=.15*s*r,h=.08*s*r;return{position:[s*o,.3*Math.cos(e*Math.PI*4)*o,Math.sin(e*Math.PI*a)*o*.5],rotation:[0,h,l],scale:1}}}},Yc={name:"float",type:"blending",emoji:"🎈",description:"Gentle floating upward motion",config:{duration:2e3,amplitude:80,wobbleAmount:20,strength:1},rhythm:{enabled:!0,syncMode:"beat",amplitudeSync:{onBeat:1.5,offBeat:.8,curve:"bounce"},wobbleSync:{subdivision:"eighth",intensity:.7},durationSync:{mode:"bars",bars:2},accentResponse:{enabled:!0,multiplier:1.3},patternOverrides:{waltz:{wobbleSync:{subdivision:"quarter",intensity:.9}},dubstep:{amplitudeSync:{onBeat:2,curve:"pulse"}}}},apply(e,t,i,n,a,r){e.gestureData||(e.gestureData={}),e.gestureData.float||(e.gestureData.float={originalSize:e.size,originalOpacity:e.opacity||1});const s={...this.config,...i};let o=s.amplitude||this.config.amplitude,l=s.wobbleAmount||this.config.wobbleAmount;const h=s.strength||this.config.strength;i.rhythmModulation&&(o*=i.rhythmModulation.amplitudeMultiplier||1,o*=i.rhythmModulation.accentMultiplier||1,l*=i.rhythmModulation.wobbleMultiplier||1);const c=Math.sin(t*Math.PI*4)*l;e.vy-=.01*o*n*h*(1-.5*t),e.vx+=.01*c*n*h,e.size=e.baseSize*(1+.1*t),e.opacity=1-.3*t},cleanup(e){e.gestureData?.float?(e.opacity=e.gestureData.float.originalOpacity,e.size=e.gestureData.float.originalSize,delete e.gestureData.float):(e.opacity=1,e.size=e.baseSize),e.vx*=.5,e.vy*=.5},"3d":{evaluate(e,t){const i={...this.config,...t};let n=i.amplitude||this.config.amplitude,a=i.wobbleAmount||this.config.wobbleAmount;const r=i.strength||this.config.strength;t.rhythmModulation&&(n*=t.rhythmModulation.amplitudeMultiplier||1,n*=t.rhythmModulation.accentMultiplier||1,a*=t.rhythmModulation.wobbleMultiplier||1);const s=Math.sin(e*Math.PI),o=n*s*r*.005,l=Math.sin(e*Math.PI*4)*a*.3*.005,h=Math.sin(e*Math.PI)*Math.PI*.5*r,c=Math.sin(e*Math.PI);return{position:[l,o,0],rotation:[c*Math.sin(e*Math.PI*2)*.1,h,c*Math.cos(e*Math.PI*3)*.08],scale:1+.1*s}}}},$c={name:"jitter",type:"blending",emoji:"🫨",description:"Nervous jittery movement",config:{duration:1e3,intensity:15,frequency:30,strength:1},rhythm:{enabled:!0,syncMode:"beat",amplitudeSync:{onBeat:2,offBeat:.5,curve:"pulse"},patternOverrides:{breakbeat:{amplitudeSync:{onBeat:3,offBeat:.3}},dubstep:{amplitudeSync:{onBeat:5,offBeat:.1,curve:"pulse"}}}},apply(e,t,i,n,a,r){e.gestureData||(e.gestureData={}),e.gestureData.jitter||(e.gestureData.jitter={originalSize:e.size});const s={...this.config,...i};let o=s.intensity||this.config.intensity;const l=s.strength||this.config.strength;i.rhythmModulation&&(o*=i.rhythmModulation.amplitudeMultiplier||1,o*=i.rhythmModulation.accentMultiplier||1);const h=(Math.random()-.5)*o*l,c=(Math.random()-.5)*o*l,u=1-.5*t;e.vx+=.1*h*n*u,e.vy+=.1*c*n*u,e.size=e.baseSize*(1+.1*(Math.random()-.5))},cleanup(e){e.gestureData?.jitter?(e.size=e.gestureData.jitter.originalSize,delete e.gestureData.jitter):e.size=e.baseSize,e.vx*=.7,e.vy*=.7},"3d":{evaluate(e,t){const i={...this.config,...t};let n=i.intensity||this.config.intensity;const a=i.strength||this.config.strength;t.rhythmModulation&&(n*=t.rhythmModulation.amplitudeMultiplier||1,n*=t.rhythmModulation.accentMultiplier||1);const r=Math.sin(e*Math.PI),s=n*a*.002*r;return{position:[(Math.random()-.5)*s,(Math.random()-.5)*s,(Math.random()-.5)*s],rotation:[.005*(Math.random()-.5)*r,.005*(Math.random()-.5)*r,.005*(Math.random()-.5)*r],scale:1+.02*(Math.random()-.5)*r}}}},Zc={name:"wiggle",emoji:"〰️",type:"additive",description:"Rapid side-to-side oscillation",config:{duration:600,musicalDuration:{musical:!0,beats:1},amplitude:15,frequency:6,strength:1,damping:.3,easing:"linear",particleMotion:{type:"wiggle",strength:1,amplitude:15,frequency:6}},rhythm:{enabled:!0,syncMode:"beat",frequencySync:{subdivision:"sixteenth",wigglePerBeat:4},amplitudeSync:{onBeat:1.5,offBeat:.8,curve:"bounce"},durationSync:{mode:"beats",beats:1}},apply(e,t,i,n,a,r,s){const o=(i.amplitude||this.config.amplitude)*a,l=i.frequency||this.config.frequency,h=1-n*(i.damping||this.config.damping),c=Math.sin(n*Math.PI*l)*o*h;e.vx+=.5*c;const u=Math.cos(n*Math.PI*l*2)*o*.1*h;e.vy+=.3*u},"3d":{evaluate(e,t){const i=t.config||{},n=t.strength||1,a=i.amplitude||15,r=i.frequency||6,s=i.damping||.3,o=Math.sin(e*Math.PI*r),l=1-e*s;return{position:[o*a*.008*n*l,0,0],rotation:[0,.25*o*n*l,0],scale:1}}}},Kc={name:"headBob",emoji:"🎧",type:"additive",description:"Rhythmic vertical bobbing to music",config:{duration:600,musicalDuration:{musical:!0,beats:1},amplitude:12,frequency:2,strength:1,damping:.1,easing:"linear",particleMotion:{type:"headBob",strength:1,amplitude:12,frequency:2}},rhythm:{enabled:!0,syncMode:"beat",frequencySync:{subdivision:"eighth",bobsPerBeat:2},amplitudeSync:{onBeat:1.3,offBeat:1,curve:"pulse"},durationSync:{mode:"beats",beats:1}},apply(e,t,i,n,a,r,s){const o=(i.amplitude||this.config.amplitude)*a,l=i.frequency||this.config.frequency,h=1-n*(i.damping||this.config.damping),c=Math.sin(n*Math.PI*2*l)*o*h;e.vy+=.5*c;const u=Math.cos(n*Math.PI*2*l*1.5)*o*.05*h;e.vx+=.2*u},"3d":{evaluate(e,t){const i=t.config||{},n=t.strength||1,a=i.amplitude||12,r=i.frequency||2,s=i.damping||.1,o=Math.sin(e*Math.PI*2*r),l=1-e*s;return{position:[0,-o*a*.008*n*l,0],rotation:[o*(.045*a)*n*l,0,0],scale:1}}}},Qc={name:"lean",emoji:"↗️",type:"blending",description:"Diagonal tilting motion with smooth return",config:{duration:1200,musicalDuration:{musical:!0,beats:2},amplitude:10,frequency:1,direction:"right",strength:.7,particleMotion:{type:"lean",direction:"right",strength:.7,frequency:1}},rhythm:{enabled:!0,syncMode:"beat",timingSync:"nextBeat",interruptible:!0,priority:3,blendable:!0,crossfadePoint:"anyBeat",amplitudeSync:{onBeat:1.3,offBeat:.8,curve:"ease"},durationSync:{mode:"beats",beats:2},accentResponse:{enabled:!0,multiplier:1.4},patternOverrides:{waltz:{durationSync:{beats:3},amplitudeSync:{onBeat:1.5,offBeat:.6}},swing:{amplitudeSync:{onBeat:1.6,offBeat:.5,curve:"bounce"}}}},initialize(e,t){e.gestureData||(e.gestureData={}),e.gestureData.lean={startX:e.x,startY:e.y,startVx:e.vx,startVy:e.vy,initialized:!0}},apply(e,t,i,n,a,r){e.gestureData?.lean?.initialized||this.initialize(e,i);const s={...this.config,...i},o=s.strength||this.config.strength||1,l=this.easeInOutCubic(t),h=s.frequency||this.config.frequency;let c=s.amplitude*o*e.scaleFactor;i.rhythmModulation&&(c*=i.rhythmModulation.amplitudeMultiplier||1,c*=i.rhythmModulation.accentMultiplier||1);const u=Math.sin(l*Math.PI*h),d="left"===s.direction?-1:1;if(e.vx+=u*c*.015*n*d,e.vy+=u*c*.01*n*d*.5,t>.9){const i=1-10*(t-.9);e.vx=e.vx*(.95+.05*i),e.vy=e.vy*(.95+.05*i)}},cleanup(e){e.gestureData?.lean&&delete e.gestureData.lean},easeInOutCubic:e=>e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2,"3d":{evaluate(e,t){const i=t||{},n=i.amplitude||10,a=i.frequency||1,r=i.strength||.7,s=i.direction||"right",o=.003*n*r,l=e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2,h=Math.sin(l*Math.PI*a),c="left"===s?-1:1;return{position:[h*o*c,0,0],rotation:[0,0,.35*h*c],scale:1}}}},Jc={name:"point",emoji:"👉",type:"blending",description:"Directional pointing motion with forward momentum",config:{duration:1e3,musicalDuration:{musical:!0,beats:2},amplitude:15,direction:"right",strength:.8,particleMotion:{type:"point",direction:"right",strength:.8}},rhythm:{enabled:!0,syncMode:"beat",timingSync:"nextBeat",interruptible:!0,priority:4,blendable:!0,crossfadePoint:"anyBeat",amplitudeSync:{onBeat:1.5,offBeat:.7,curve:"ease"},durationSync:{mode:"beats",beats:2},accentResponse:{enabled:!0,multiplier:1.6},patternOverrides:{march:{amplitudeSync:{onBeat:2,offBeat:.5,curve:"pulse"}},swing:{amplitudeSync:{onBeat:1.4,offBeat:.8,curve:"bounce"}}}},initialize(e,t){e.gestureData||(e.gestureData={}),e.gestureData.point={startX:e.x,startY:e.y,startVx:e.vx,startVy:e.vy,initialized:!0}},apply(e,t,i,n,a,r){e.gestureData?.point?.initialized||this.initialize(e,i);const s={...this.config,...i},o=s.strength||this.config.strength||1,l=this.easeInOutCubic(t);let h=s.amplitude*o*e.scaleFactor;i.rhythmModulation&&(h*=i.rhythmModulation.amplitudeMultiplier||1,h*=i.rhythmModulation.accentMultiplier||1);const c=Math.sin(l*Math.PI);let u=0,d=0;switch(s.direction||"right"){case"right":u=1;break;case"left":u=-1;break;case"up":d=-1;break;case"down":d=1}if(e.vx+=c*h*.02*n*u,e.vy+=c*h*.02*n*d,t>.9){const i=1-10*(t-.9);e.vx=e.vx*(.95+.05*i),e.vy=e.vy*(.95+.05*i)}},cleanup(e){e.gestureData?.point&&delete e.gestureData.point},easeInOutCubic:e=>e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2,"3d":{evaluate(e,t){const i=t||{},n=i.amplitude||15,a=i.strength||.8,r=i.direction||"right",s=.005*n*a,o=e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2,l=Math.sin(o*Math.PI);let h=0,c=0;switch(r){case"right":h=l*s,c=.25*l;break;case"left":h=-l*s,c=.25*-l;break;case"up":case"down":c=0}return{position:[h,0,0],rotation:[0,c,0],scale:1}}}},eu={name:"reach",emoji:"🙌",type:"blending",description:"Upward reaching motion with scale increase",config:{duration:1400,musicalDuration:{musical:!0,beats:2},amplitude:25,strength:.9,scaleMax:1.05,particleMotion:{type:"reach",strength:.9,scaleMax:1.05}},rhythm:{enabled:!0,syncMode:"beat",timingSync:"nextBeat",interruptible:!0,priority:4,blendable:!0,crossfadePoint:"anyBeat",amplitudeSync:{onBeat:1.4,offBeat:.9,curve:"ease"},durationSync:{mode:"beats",beats:2},accentResponse:{enabled:!0,multiplier:1.5},patternOverrides:{uplifting:{amplitudeSync:{onBeat:1.8,offBeat:.7,curve:"ease"},durationSync:{beats:3}},ambient:{amplitudeSync:{onBeat:1.2,offBeat:1,curve:"linear"}}}},initialize(e,t){e.gestureData||(e.gestureData={}),e.gestureData.reach={startY:e.y,startVy:e.vy,originalSize:e.size,initialized:!0}},apply(e,t,i,n,a,r){e.gestureData?.reach?.initialized||this.initialize(e,i);const s={...this.config,...i},o=s.strength||this.config.strength||1,l=s.scaleMax||this.config.scaleMax||1.05,h=this.easeInOutCubic(t);let c=s.amplitude*o*e.scaleFactor;i.rhythmModulation&&(c*=i.rhythmModulation.amplitudeMultiplier||1,c*=i.rhythmModulation.accentMultiplier||1);const u=Math.sin(h*Math.PI);e.vy-=u*c*.015*n;const d=1+u*(l-1);if(e.size=e.baseSize*d,t>.9){const i=1-10*(t-.9);e.vy=e.vy*(.95+.05*i)}},cleanup(e){e.gestureData?.reach&&(e.gestureData.reach.originalSize?e.size=e.gestureData.reach.originalSize:e.size=e.baseSize,delete e.gestureData.reach)},easeInOutCubic:e=>e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2,"3d":{evaluate(e,t){const i=t||{},n=i.amplitude||25,a=i.strength||.9,r=i.scaleMax||1.05,s=.004*n*a,o=e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2,l=Math.sin(o*Math.PI);return{position:[0,l*s,0],rotation:[.1*l,0,0],scale:1+l*(r-1)}}}},tu={name:"spin",emoji:"🌀",type:"override",description:"Orbital rotation around center point",config:{duration:600,musicalDuration:{musical:!0,beats:1},rotations:1,direction:"random",radiusMultiplier:1,spiralOut:!1,accelerate:!0,maintainDistance:!0,scaleAmount:.1,easing:"linear",strength:.7,particleMotion:{type:"spin",strength:.7,rotations:1,radius:1}},rhythm:{enabled:!0,syncMode:"bar",rotationSync:{mode:"bars",rotationsPerBar:1,accelerateOnBeat:!0},radiusSync:{subdivision:"quarter",expandOnBeat:1.2,contractOffBeat:.9,curve:"bounce"},durationSync:{mode:"beats",beats:4},patternOverrides:{waltz:{rotationSync:{rotationsPerBar:.75},radiusSync:{curve:"ease"}},swing:{rotationSync:{accelerateOnBeat:!1},direction:"alternating"},dubstep:{radiusSync:{subdivision:"eighth",expandOnBeat:1.5,dropMultiplier:2},spiralOut:!0},breakbeat:{rotationSync:{mode:"random",range:[.5,2]},direction:"random"}}},initialize(e,t,i,n){e.gestureData||(e.gestureData={});const a=e.x-i,r=e.y-n;let s=t.direction||this.config.direction;"random"===s&&(s=Math.random()<.5?"clockwise":"counter-clockwise"),e.gestureData.spin={startAngle:Math.atan2(r,a),startRadius:Math.sqrt(a*a+r*r)||30,originalX:e.x,originalY:e.y,originalVx:e.vx,originalVy:e.vy,direction:s,initialized:!0}},apply(e,t,i,n,a,r){e.gestureData?.spin?.initialized||this.initialize(e,i,a,r);const s=e.gestureData.spin,o={...this.config,...i},l=i.strength||1;let{rotations:h}=o,{radiusMultiplier:c}=o;i.rhythmModulation&&(i.rhythmModulation.rotationMultiplier&&(h*=i.rhythmModulation.rotationMultiplier),i.rhythmModulation.radiusMultiplier&&(c*=i.rhythmModulation.radiusMultiplier));let u=t;o.accelerate&&(u=t<.5?.5*this.easeInQuad(2*t):.5+.5*this.easeOutQuad(2*(t-.5)));const d=h*Math.PI*2*l,p="counter-clockwise"===s.direction?-1:1,m=s.startAngle+d*u*p;let f=s.startRadius;o.spiralOut&&(f*=1+.5*t),1!==c&&(f*=1+(c-1)*Math.sin(t*Math.PI));const g=a+Math.cos(m)*f,v=r+Math.sin(m)*f;if(e.x+=.25*(g-e.x),e.y+=.25*(v-e.y),e.vx=.5*(g-e.x),e.vy=.5*(v-e.y),t>.9){const i=10*(1-t);e.vx=e.vx*i+s.originalVx*(1-i),e.vy=e.vy*i+s.originalVy*(1-i)}},cleanup(e){if(e.gestureData?.spin){const t=e.gestureData.spin;e.vx=t.originalVx,e.vy=t.originalVy,delete e.gestureData.spin}},easeInQuad:e=>e*e,easeOutQuad:e=>e*(2-e),"3d":{evaluate(e,t){const{particle:i}=t;if(!i||!i.gestureData?.spin)return{position:[0,0,0],rotation:[0,0,0],scale:1};const n=i.gestureData.spin,a=t.config||{},r=t.strength||1;let s=e;a.accelerate&&(s=e<.5?e*e*4*.5:.5+(e-.5)*(2-(e-.5))*.5);const o=(a.rotations||1)*Math.PI*2*r,l="counter-clockwise"===n.direction?-1:1;return{position:[0,0,0],rotation:[0,o*Math.sin(s*Math.PI)*l,0],scale:1+(a.scaleAmount||.1)*Math.sin(e*Math.PI)*r}}}},iu={name:"jump",emoji:"🦘",type:"override",description:"Squash, leap, and land with classic animation principles",config:{duration:800,jumpHeight:60,squashAmount:.8,stretchAmount:1.2,anticipation:.2,hangTime:.1,landingImpact:!0,driftOutward:!0,easing:"quad",particleMotion:{type:"jump",strength:.9,jumpHeight:60,squash:.8,stretch:1.2}},rhythm:{enabled:!0,syncMode:"beat",phaseSync:{anticipation:"eighth",jump:"beat",landing:"sixteenth"},heightSync:{onBeat:1.5,offBeat:.8,accent:2,curve:"exponential"},deformationSync:{squashOnBeat:.6,stretchOnBeat:1.4,timing:"anticipatory"},hangTimeSync:{mode:"tempo",baseDuration:.1,scaling:"inverse"},dynamics:{forte:{jumpHeight:80,stretch:1.3},piano:{jumpHeight:30,stretch:1.1}}},initialize(e,t,i,n){e.gestureData||(e.gestureData={}),e.gestureData.jump={startX:e.x,startY:e.y,startSize:e.size,originalVx:e.vx,originalVy:e.vy,driftDirection:.1*(e.x-i),initialized:!0}},apply(e,t,i,n,a,r){e.gestureData?.jump?.initialized||this.initialize(e,i,a,r);const s=e.gestureData.jump,o={...this.config,...i},l=i.strength||1,h=o.jumpHeight*l*e.scaleFactor,c=o.squashAmount,u=o.stretchAmount,d=o.anticipation,p=1-.5*o.anticipation;if(t<d){const i=t/d,n=this.easeOutQuad(i);e.size=s.startSize*(1-(1-c)*n),e.y=s.startY+5*n*e.scaleFactor,e.vx=0,e.vy=0}else if(t<p){const i=(t-d)/(p-d);let n=Math.sin(i*Math.PI);if(o.hangTime>0&&i>.4&&i<.6){const e=(i-.4)/.2;n=.95+.05*this.easeInOutCubic(e)}if(e.y=s.startY-n*h,o.driftOutward&&(e.x=s.startX+n*s.driftDirection),i<.5){const t=2*i;e.size=s.startSize*(c+(u-c)*t)}else{const t=2*(i-.5);e.size=s.startSize*(u-(u-1)*t*.8)}e.vx=.5*s.driftDirection,e.vy=-Math.cos(i*Math.PI)*h*.1}else{const i=(t-p)/(1-p),n=this.easeOutBounce(i);if(e.y=s.startY,o.landingImpact)if(i<.3){const t=i/.3;e.size=s.startSize*(1-(1-.8*c)*(1-t))}else{const t=(i-.3)/.7;e.size=s.startSize*(.8*c+(1-.8*c)*t)}else e.size=s.startSize*(c+(1-c)*n);e.vx=s.originalVx*n,e.vy=s.originalVy*n}},cleanup(e){if(e.gestureData?.jump){const t=e.gestureData.jump;e.size=t.startSize,e.vx=t.originalVx,e.vy=t.originalVy,delete e.gestureData.jump}},easeOutQuad:e=>e*(2-e),easeInOutCubic:e=>e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2,easeOutBounce(e){const t=7.5625,i=2.75;return e<1/i?t*e*e:e<2/i?t*(e-=1.5/i)*e+.75:e<2.5/i?t*(e-=2.25/i)*e+.9375:t*(e-=2.625/i)*e+.984375},"3d":{evaluate(e,t){const i=t.config||t||{},n=t.strength||1,a=.004*(i.jumpHeight||60)*n,r=i.squashAmount||.8,s=i.stretchAmount||1.2,o=i.anticipation||.2,l=1-.5*o;let h=0,c=1,u=0;if(e<o){const t=e/o,i=t*(2-t);c=1-(1-r)*i,h=.02*-i}else if(e<l){const t=(e-o)/(l-o);h=Math.sin(t*Math.PI)*a,c=t<.5?r+2*t*(s-r):s-2*(t-.5)*(s-1)*.8,u=.05*Math.sin(t*Math.PI)}else{const t=(e-l)/(1-l);if(t<.5){const e=2*t;h=-Math.sin(e*Math.PI)*a*.15}else h=0;c=!1!==i.landingImpact?t<.3?1-(1-.8*r)*(1-t/.3):.8*r+(t-.3)/.7*(1-.8*r):r+(1-r)*t}return{position:[0,h,0],rotation:[u,0,0],scale:c}}}},nu={name:"morph",emoji:"✨",type:"override",description:"Form geometric patterns and shapes",config:{musicalDuration:{musical:!0,beats:2,minBeats:1,maxBeats:8},phases:[{name:"gather",beats:.25},{name:"form",beats:.75},{name:"hold",beats:.5},{name:"dissolve",beats:.5}],morphType:"fluid",pattern:"star",points:5,innerRadius:.4,size:80,amplitude:20,rotation:0,smooth:!0,randomizeOrder:!1,easing:"sine",strength:1.2,particleMotion:{type:"morph",pattern:"star",strength:1.2,smooth:!0,points:5}},rhythm:{enabled:!0,syncMode:"phrase",patternSync:{verse:"circle",chorus:"star",bridge:"heart",drop:"explosion"},timingSync:{formationBeat:1,holdBeats:2,dissolveBeat:4,curve:"anticipatory"},sizeSync:{onBeat:1.2,offBeat:.95,subdivision:"quarter",curve:"elastic"},rotationSync:{mode:"continuous",degreesPerBar:90,direction:"clockwise"},dynamics:{forte:{points:8,size:100},piano:{points:3,size:60}}},initialize(e,t,i,n,a){e.gestureData||(e.gestureData={});const r={...this.config,...t},s=e.x,o=e.y,l=Math.atan2(e.y-n,e.x-i),h=Math.random()<.5?1:-1;let c,u;const d=r.size*e.scaleFactor,p=(r.rotation||0)*Math.PI/180*h;switch(r.pattern){case"star":c=i,u=n,this.calculateStarPosition(e,l,d,r.points,r.innerRadius,p,i,n);break;case"heart":this.calculateHeartPosition(e,l,d,p,i,n);break;case"square":this.calculateSquarePosition(e,l,d,p,i,n);break;case"triangle":this.calculateTrianglePosition(e,l,d,p,i,n);break;default:{const e=d;c=i+Math.cos(l+p)*e,u=n+Math.sin(l+p)*e;break}}e.gestureData.morph={startX:s,startY:o,targetX:e.gestureData.morphTargetX||c,targetY:e.gestureData.morphTargetY||u,originalVx:e.vx,originalVy:e.vy,rotationDirection:h,initialized:!0}},calculateStarPosition(e,t,i,n,a,r,s,o){const l=((t+Math.PI)%(2*Math.PI)+2*Math.PI)%(2*Math.PI),h=Math.floor(l/(2*Math.PI)*10),c=h%2==0,u=Math.floor(h/2);let d;d=c?72*u*Math.PI/180:(72*u+36)*Math.PI/180,d+=r;const p=c?i:i*a;e.gestureData.morphTargetX=s+Math.cos(d)*p,e.gestureData.morphTargetY=o+Math.sin(d)*p},calculateHeartPosition(e,t,i,n,a,r){const s=(t+Math.PI)/(2*Math.PI),o=.05*i,l=16*Math.pow(Math.sin(s*Math.PI*2),3),h=-(13*Math.cos(s*Math.PI*2)-5*Math.cos(2*s*Math.PI*2)-2*Math.cos(3*s*Math.PI*2)-Math.cos(4*s*Math.PI*2)),c=Math.cos(n),u=Math.sin(n),d=l*c-h*u,p=l*u+h*c;e.gestureData.morphTargetX=a+d*o,e.gestureData.morphTargetY=r+p*o},calculateSquarePosition(e,t,i,n,a,r){const s=((t+n)%(2*Math.PI)+2*Math.PI)%(2*Math.PI);let o,l;const h=i;s<Math.PI/4||s>=7*Math.PI/4?(o=h,l=h*Math.tan(s)):s<3*Math.PI/4?(o=h/Math.tan(s),l=h):s<5*Math.PI/4?(o=-h,l=-h*Math.tan(s)):(o=-h/Math.tan(s),l=-h);const c=Math.cos(n),u=Math.sin(n),d=o*c-l*u,p=o*u+l*c;e.gestureData.morphTargetX=a+d,e.gestureData.morphTargetY=r+p},calculateTrianglePosition(e,t,i,n,a,r){const s=[{x:0,y:-i},{x:.866*-i,y:.5*i},{x:.866*i,y:.5*i}],o=Math.floor((t+Math.PI)/(2*Math.PI)*3)%3,l=(o+1)%3,h=Math.random(),c=s[o].x+(s[l].x-s[o].x)*h,u=s[o].y+(s[l].y-s[o].y)*h,d=Math.cos(n),p=Math.sin(n),m=c*d-u*p,f=c*p+u*d;e.gestureData.morphTargetX=a+m,e.gestureData.morphTargetY=r+f},apply(e,t,i,n,a,r){e.gestureData?.morph?.initialized||this.initialize(e,i,a,r);const s=e.gestureData.morph,o={...this.config,...i};let l,h,c=t;if(o.holdTime>0){const e=.5-o.holdTime/2,i=.5+o.holdTime/2;c=t<e?t/e*.5:t<i?.5:.5+(t-i)/(1-i)*.5}if(c<=.5){const e=2*c;l=s.startX+(s.targetX-s.startX)*this.easeOutQuad(e),h=s.startY+(s.targetY-s.startY)*this.easeOutQuad(e)}else{const e=2*(c-.5);l=s.targetX+(s.startX-s.targetX)*this.easeInQuad(e),h=s.targetY+(s.startY-s.targetY)*this.easeInQuad(e)}if(o.smooth){const t=.2;e.x+=(l-e.x)*t,e.y+=(h-e.y)*t}else e.x=l,e.y=h;if(e.vx=.5*(l-e.x),e.vy=.5*(h-e.y),t>.9){const i=10*(1-t);e.vx=e.vx*i+s.originalVx*(1-i),e.vy=e.vy*i+s.originalVy*(1-i)}},cleanup(e){if(e.gestureData?.morph){const t=e.gestureData.morph;e.vx=t.originalVx,e.vy=t.originalVy,delete e.gestureData.morph,delete e.gestureData.morphTargetX,delete e.gestureData.morphTargetY}},easeInOutCubic:e=>e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2,easeOutQuad:e=>e*(2-e),easeInQuad:e=>e*e,"3d":{evaluate(e,t){const i=t?.strength||1,n=Math.sin(e*Math.PI);let a;if(e<=.5){const t=2*e;a=1+t*(2-t)*.25*i}else{const t=2*(e-.5);a=1.25*i+t*t*(1-1.25*i),a=Math.max(1,a)}return{position:[0,0,0],rotation:[0,n*Math.PI*.3*i,.1*Math.sin(e*Math.PI*2)*i],scale:a,glowIntensity:1+.4*n*i,glowBoost:1.5*n*i}}}},au={name:"stretch",emoji:"↔️",type:"override",description:"Scale particles along X and Y axes",config:{duration:2e3,scaleX:1.3,scaleY:.9,alternate:!1,elastic:!0,overshoot:.1,frequency:1,easing:"sine",strength:1,particleMotion:{type:"stretch",scaleX:1.8,scaleY:.6,strength:1},centerBased:!0,preserveArea:!1},rhythm:{enabled:!0,syncMode:"beat",scaleSync:{onBeat:{x:1.5,y:.7},offBeat:{x:.8,y:1.3},subdivision:"eighth",curve:"elastic"},alternateSync:{pattern:"XYXY",beatsPerChange:1,overlap:.1},overshootSync:{normal:.1,accent:.3,downbeat:.2,curve:"spring"},preservationSync:{verse:!0,chorus:!1,bridge:!0},dynamics:{forte:{scaleX:2,scaleY:.5,overshoot:.4},piano:{scaleX:1.1,scaleY:.95,overshoot:.05}}},initialize(e,t,i,n){e.gestureData||(e.gestureData={});const a=e.x-i,r=e.y-n;e.gestureData.stretch={offsetX:a,offsetY:r,startX:e.x,startY:e.y,originalVx:e.vx,originalVy:e.vy,initialized:!0}},apply(e,t,i,n,a,r){e.gestureData?.stretch?.initialized||this.initialize(e,i,a,r);const s=e.gestureData.stretch,o={...this.config,...i},l=i.strength||1;let h,c,{scaleX:u}=o,{scaleY:d}=o;if(o.preserveArea&&1!==u&&1!==d){const e=u*d,t=Math.sqrt(1/e);u*=t,d*=t}if(o.alternate)if(t<.5){const e=2*t;u=1+(u-1)*this.getElasticProgress(e,o),d=1+(1/u-1)*(o.preserveArea?1:0)}else{const e=2*(t-.5);u+=(1-u)*this.getElasticProgress(e,o),d=1+(d-1)*this.getElasticProgress(e,o)}else{const e=this.getElasticProgress(t,o);u=1+(u-1)*e*l,d=1+(d-1)*e*l}if(o.centerBased?(h=a+s.offsetX*u,c=r+s.offsetY*d):(h=s.startX*u,c=s.startY*d),e.x=h,e.y=c,e.vx=s.offsetX*(u-1)*l*.1,e.vy=s.offsetY*(d-1)*l*.1,t>.9){const i=10*(1-t);e.vx=e.vx*i+s.originalVx*(1-i),e.vy=e.vy*i+s.originalVy*(1-i)}},getElasticProgress(e,t){if(!t.elastic)return this.easeInOutCubic(e);if(0===e)return 0;if(1===e)return 1;const i=t.overshoot||.1;if(e<.5){const t=2*e;return.5*this.easeInElastic(t,i)}{const t=2*(e-.5);return.5+.5*this.easeOutElastic(t,i)}},cleanup(e){if(e.gestureData?.stretch){const t=e.gestureData.stretch;e.vx=t.originalVx,e.vy=t.originalVy,delete e.gestureData.stretch}},easeInOutCubic:e=>e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2,easeInElastic:(e,t)=>0===e?0:1===e?1:-Math.pow(2,10*(e-1))*Math.sin((e-1-.075)*(2*Math.PI)/.3)*(1+t),easeOutElastic:(e,t)=>0===e?0:1===e?1:Math.pow(2,-10*e)*Math.sin((e-.075)*(2*Math.PI)/.3)*(1+t)+1,"3d":{evaluate(e,t){const{particle:i}=t;if(!i||!i.gestureData?.stretch)return{position:[0,0,0],rotation:[0,0,0],scale:1};const n=t.config||{},a=t.strength||1;let r,s=n.scaleX||1.3,o=n.scaleY||.9;if(n.preserveArea&&1!==s&&1!==o){const e=s*o,t=Math.sqrt(1/e);s*=t,o*=t}if(n.elastic){const t=n.overshoot||.1;if(e<.5){const i=2*e,n=.3,a=n/4;r=-Math.pow(2,10*(i-1))*Math.sin((i-1-a)*(2*Math.PI)/n)*(1+t)*.5}else{const i=2*(e-.5),n=.3,a=n/4;r=.5+.5*(Math.pow(2,-10*i)*Math.sin((i-a)*(2*Math.PI)/n)*(1+t)+1)}}else r=e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2;let l,h=1;if(e>.8){const t=(e-.8)/(1-.8);h=1-t*t*t}l=n.alternate?e<.5?2*e*.8:.8-2*(e-.5)*1.4:1*r*a;const c=1+l*h;return{position:[0,0,0],rotation:[0,0,.1*Math.sin(e*Math.PI*4)*r*h],scale:c}}}},ru={name:"tilt",emoji:"🤔",type:"override",description:"Gather particles then tilt as unified group",config:{duration:500,gatherPhase:.2,tiltAngle:45,swayAmount:80,liftAmount:60,frequency:3,homeRadius:20,easing:"sine",strength:2.5,particleMotion:{type:"tilt",strength:2.5,frequency:3,swayAmount:80,liftAmount:60},smoothness:.25},rhythm:{enabled:!0,syncMode:"swing",angleSync:{onBeat:45,offBeat:-30,swing:15,subdivision:"triplet",curve:"ease-in-out"},gatherSync:{beatsBefore:.5,releaseAfter:.25,intensity:"dynamic"},swaySync:{verse:60,chorus:100,bridge:80,syncopated:!0},liftSync:{upOnTilt:!0,heightOnAccent:80,normalHeight:40,curve:"bounce"},dynamics:{forte:{tiltAngle:60,swayAmount:120,frequency:4},piano:{tiltAngle:20,swayAmount:40,frequency:2}}},initialize(e,t,i,n){e.gestureData||(e.gestureData={});const a=e.x-i,r=e.y-n,s=Math.atan2(r,a),o=Math.sqrt(a*a+r*r),l=Math.random(),h=({...this.config,...t}.homeRadius+20*Math.random())*e.scaleFactor;e.gestureData.tilt={startX:e.x,startY:e.y,originalVx:e.vx,originalVy:e.vy,angle:s,distance:o,homeRadius:h,homeX:i+Math.cos(s)*h,homeY:n+Math.sin(s)*h,role:l,initialized:!0}},apply(e,t,i,n,a,r){e.gestureData?.tilt?.initialized||this.initialize(e,i,a,r);const s=e.gestureData.tilt,o={...this.config,...i},l=i.strength||1;let h,c;if(t<o.gatherPhase){const i=t/o.gatherPhase,n=this.easeInOutCubic(i);h=s.startX+(s.homeX-s.startX)*n,c=s.startY+(s.homeY-s.startY)*n;const a=.6;e.x+=(h-e.x)*a,e.y+=(c-e.y)*a}else{const i=(t-o.gatherPhase)/(1-o.gatherPhase)*Math.PI*o.frequency,n=Math.sin(i),u=o.tiltAngle*Math.PI/180*l,d=s.angle+n*u,p=Math.abs(n)*o.liftAmount*e.scaleFactor,m=s.homeRadius+p;h=a+Math.cos(d)*m,c=r+Math.sin(d)*m-.3*p;const f=o.smoothness+.1*s.role;e.x+=(h-e.x)*f,e.y+=(c-e.y)*f;const g=-Math.sin(d),v=Math.cos(d);e.vx=g*n*2,e.vy=v*n*2}if(t<o.gatherPhase&&(e.vx=.25*(h-e.x),e.vy=.25*(c-e.y)),t>.9){const i=10*(1-t),n=s.startX+(e.x-s.startX)*i,a=s.startY+(e.y-s.startY)*i;e.x=n,e.y=a,e.vx=e.vx*i+s.originalVx*(1-i),e.vy=e.vy*i+s.originalVy*(1-i)}},cleanup(e){if(e.gestureData?.tilt){const t=e.gestureData.tilt;e.vx=t.originalVx,e.vy=t.originalVy,delete e.gestureData.tilt}},easeInOutCubic:e=>e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2,"3d":{evaluate(e,t){const i=t.config||{},n=t.strength||1,a=i.gatherPhase||.2,r=i.frequency||3,s=i.tiltAngle||45;let o=0;if(e>=a){const t=(e-a)/(1-a)*Math.PI*r;o=Math.sin(t)*(s*Math.PI/180*n*.4)}return{position:[0,0,0],rotation:[0,0,o],scale:1}}}},su={name:"orbital",emoji:"🪐",type:"override",description:"Orbital motion around center",config:{speed:.02,maintainRadius:!0,elliptical:!1,use3D:!0,zPhaseOffset:0,verticalOscillation:0,duration:3e3,particleMotion:{type:"orbital",strength:1}},rhythm:{enabled:!0,syncMode:"harmonic",speedSync:{tonic:.02,fifth:.03,octave:.04,third:.025,curve:"smooth"},radiusSync:{bass:150,mid:100,treble:50,scaling:"logarithmic"},depthSync:{major:{z:1,phase:0},minor:{z:-1,phase:Math.PI},diminished:{z:.5,phase:Math.PI/2},augmented:{z:.8,phase:-Math.PI/2}},phaseSync:{mode:"harmonic",intervals:[1,1.5,2],drift:.05},dynamics:{forte:{speed:.04,maintainRadius:!1},piano:{speed:.01,maintainRadius:!0}}},initialize(e,t,i,n){e.gestureData||(e.gestureData={});const a=e.x-i,r=e.y-n,s=Math.sqrt(a*a+r*r),o=Math.random()<.5?1:-1,l=Math.max(s,100+180*Math.random()),h=s<5?Math.random()*Math.PI*2:Math.atan2(r,a);e.gestureData.orbital={radius:l,targetRadius:l,angle:h,initialAngle:h,originalVx:e.vx,originalVy:e.vy,originalZ:e.z||0,zPhase:Math.random()*Math.PI*2,direction:o}},apply(e,t,i,n,a,r){e.gestureData?.orbital||this.initialize(e,i,a,r);const s=e.gestureData.orbital,o=(i.speed||this.config.speed)*(i.strength||1);s.angle+=o*n*s.direction;let{radius:l}=s;if(i.maintainRadius||(l=s.radius*(1+.1*Math.sin(t*Math.PI*2))),e.x=a+Math.cos(s.angle)*l,e.y=r+Math.sin(s.angle)*l,!1!==i.use3D){const t=s.angle+s.zPhase+(i.zPhaseOffset||0);if(e.z=.8*Math.sin(t),i.verticalOscillation){const n=Math.cos(t)*i.verticalOscillation*l*.1;e.y+=n}}if(e.vx=-Math.sin(s.angle)*l*o,e.vy=Math.cos(s.angle)*l*o,t>.9){const i=10*(1-t);e.vx=e.vx*i+s.originalVx*(1-i),e.vy=e.vy*i+s.originalVy*(1-i)}},cleanup(e){if(e.gestureData?.orbital){const t=e.gestureData.orbital;e.vx=t.originalVx,e.vy=t.originalVy,e.z=t.originalZ,delete e.gestureData.orbital}},"3d":{evaluate(e,t){const{particle:i}=t;if(!i||!i.gestureData?.orbital)return{position:[0,0,0],rotation:[0,0,0],scale:1};const n=i.gestureData.orbital;t.config;let a=1;e<.15?(a=e/.15,a=Math.sin(a*Math.PI*.5)):e>.85&&(a=(1-e)/.15,a=Math.sin(a*Math.PI*.5));const r=n.initialAngle+e*Math.PI*2*n.direction,s=.3*Math.cos(r)*a,o=.3*Math.sin(r)*a,l=(r+Math.PI/2-(n.initialAngle+Math.PI/2))*a,h=i.z||0;return{position:[s,0,o+.1*h*a],rotation:[0,l,0],scale:1+.15*h*a}}}},ou={name:"hula",emoji:"🌀",type:"override",description:"Hula-hoop motion with vertical waves",config:{speed:.015,maintainRadius:!1,elliptical:!0,use3D:!0,zPhaseOffset:Math.PI/4,verticalOscillation:.3,wobbleAmount:.15,duration:2500,particleMotion:{type:"hula",strength:1,verticalOscillation:.3}},rhythm:{enabled:!0,syncMode:"bar",speedSync:{mode:"tempo",baseSpeed:.015,scaling:"proportional"},wobbleSync:{onBeat:.25,offBeat:.1,curve:"sine"},verticalSync:{subdivision:"quarter",amplitude:.4,phase:"sequential"},dynamics:{forte:{wobbleAmount:.3,speed:1.2},piano:{wobbleAmount:.05,speed:.8}}},initialize(e,t,i,n){e.gestureData||(e.gestureData={});const a=e.x-i,r=e.y-n,s=Math.sqrt(a*a+r*r),o=Math.random()<.5?1:-1,l=Math.max(s,100+180*Math.random()),h=s<5?Math.random()*Math.PI*2:Math.atan2(r,a);e.gestureData.hula={radius:l,angle:h,initialAngle:h,originalVx:e.vx,originalVy:e.vy,originalZ:e.z||0,zPhase:Math.random()*Math.PI*2,wobblePhase:Math.random()*Math.PI*2,direction:o}},apply(e,t,i,n,a,r){e.gestureData?.hula||this.initialize(e,i,a,r);const s=e.gestureData.hula,o=(i.speed||this.config.speed)*(i.strength||1);let l=1;t<.1?(l=t/.1,l=Math.sin(l*Math.PI*.5)):t>.9&&(l=(1-t)/.1,l=Math.sin(l*Math.PI*.5)),s.angle+=o*n*s.direction*l;const h=Math.sin(2*s.angle+s.wobblePhase)*(i.wobbleAmount||this.config.wobbleAmount)*l,c=s.radius*(1+h)*l,u=s.radius*(.7+h)*l,d=a+Math.cos(s.angle)*c,p=r+Math.sin(s.angle)*u;if(t<.1){const t=e.x-a,i=e.y-r;Math.sqrt(t*t+i*i)<50?(e.x=a+Math.cos(s.angle)*c,e.y=r+Math.sin(s.angle)*u):(e.x=e.x+(d-e.x)*l*.5,e.y=e.y+(p-e.y)*l*.5)}else e.x=d,e.y=p;const m=s.angle+s.zPhase+(i.zPhaseOffset||this.config.zPhaseOffset);e.z=.9*Math.sin(m)*l;const f=i.verticalOscillation||this.config.verticalOscillation,g=Math.cos(2*m)*f*s.radius*.2*l;e.y+=g;const v=e.z*s.radius*.1;e.y-=v;const y=-Math.sin(s.angle)*c*o,b=Math.cos(s.angle)*u*o;t<.1?(e.vx=s.originalVx+(y-s.originalVx)*l,e.vy=s.originalVy+(b-s.originalVy)*l):t>.9?(e.vx=y*l+s.originalVx*(1-l),e.vy=b*l+s.originalVy*(1-l),e.z=e.z*l+s.originalZ*(1-l)):(e.vx=y,e.vy=b)},cleanup(e){if(e.gestureData?.hula){const t=e.gestureData.hula;e.vx=t.originalVx,e.vy=t.originalVy,e.z=t.originalZ,delete e.gestureData.hula}},"3d":{evaluate(e,t){const{particle:i}=t;if(!i||!i.gestureData?.hula)return{position:[0,0,0],rotation:[0,0,0],scale:1};const n=i.gestureData.hula,a=t.config||{};let r=1;e<.15?(r=e/.15,r=Math.sin(r*Math.PI*.5)):e>.85&&(r=(1-e)/.15,r=Math.sin(r*Math.PI*.5));const s=n.initialAngle+e*Math.PI*2*n.direction,o=.25*Math.cos(s)*r,l=.25*Math.sin(s)*r,h=a.verticalOscillation||.3;return{position:[o,Math.sin(2*s+n.wobblePhase)*h*r,l],rotation:[0,(s-n.initialAngle)*r,0],scale:1+.15*Math.abs(Math.sin(s))*r}}}},lu={name:"twist",emoji:"🌀",type:"override",description:"Twisting dance motion with alternating rotation",config:{duration:1200,rotationAngle:45,contractionFactor:.8,twistFrequency:2,easing:"smooth",strength:.8,particleMotion:{type:"twist",rotationAngle:45,contractionFactor:.8,twistFrequency:2}},rhythm:{enabled:!0,syncMode:"beat",timingSync:"nextBeat",interruptible:!0,priority:4,blendable:!1,crossfadePoint:"anyBeat",amplitudeSync:{onBeat:1.5,offBeat:.7,curve:"elastic"},patternOverrides:{funk:{rotationAngle:60,contractionFactor:.7},disco:{twistFrequency:3,rotationAngle:50},latin:{rotationAngle:35,contractionFactor:.85,twistFrequency:2.5}}},initialize(e,t){e.gestureData||(e.gestureData={}),e.gestureData.twist={startX:e.x,startY:e.y,startAngle:Math.atan2(e.y-t.centerY,e.x-t.centerX),startDistance:Math.sqrt(Math.pow(e.x-t.centerX,2)+Math.pow(e.y-t.centerY,2)),initialized:!0}},apply(e,t,i,n,a,r){e.gestureData?.twist?.initialized||this.initialize(e,{...i,centerX:a,centerY:r});const s={...this.config,...i},o=e.gestureData.twist,l=s.strength||this.config.strength||1,h=t*s.twistFrequency*Math.PI*2,c=Math.sin(h)*l;let{rotationAngle:u}=s,{contractionFactor:d}=s;i.rhythmModulation&&(u*=i.rhythmModulation.amplitudeMultiplier||1,d=1-(1-d)*(i.rhythmModulation.amplitudeMultiplier||1));const p=u*Math.PI/180*c,m=1-(1-d)*Math.abs(c),f=o.startAngle+p,g=o.startDistance*m,v=a+Math.cos(f)*g,y=r+Math.sin(f)*g,b=.15*l;e.x+=(v-e.x)*b,e.y+=(y-e.y)*b,e.vx=.05*(v-e.x),e.vy=.05*(y-e.y);const M=5*Math.sin(t*Math.PI*4)*l;if(e.y+=.1*M,t>.9){const i=1-10*(t-.9);e.vx*=i,e.vy*=i}},cleanup(e){e.gestureData?.twist&&delete e.gestureData.twist},"3d":{evaluate(e,t){const{particle:i}=t;if(!i||!i.gestureData?.twist)return{position:[0,0,0],rotation:[0,0,0],scale:1};const n=i.gestureData.twist,a=t.config||{},r=a.strength||1,s=e>.85?(1-e)/.15:1,o=e*(a.twistFrequency||2)*Math.PI*2,l=Math.sin(o)*r*s,h=l*((a.rotationAngle||45)*Math.PI/180),c=n.startAngle+h,u=(a.contractionFactor||.8)*n.startDistance;return{position:[Math.cos(c)*u*.1*s*.01,0,Math.sin(c)*u*.1*s*.01],rotation:[.1*Math.cos(o)*r*s,h,.15*Math.sin(.5*o)*r*s],scale:1-(1-(a.contractionFactor||.8))*Math.abs(l)}}}},hu={name:"wave",emoji:"🌊",type:"override",description:"Infinity pattern flow with phasing",config:{musicalDuration:{musical:!0,bars:1,minBeats:4,maxBeats:16},phases:[{name:"gather",beats:.5},{name:"rise",beats:.5},{name:"waveLeft",beats:1},{name:"waveRight",beats:1},{name:"settle",beats:1}],amplitude:40,frequency:1,phaseShift:.3,liftHeight:20,fadeInOut:!0,smoothness:.1,easing:"sine",strength:1,particleMotion:{type:"wave",strength:1,amplitude:50}},rhythm:{enabled:!0,syncMode:"wave",amplitudeSync:{onWave:65,onStatic:25,curve:"flowing"},frequencySync:{mode:"phrase",slow:.7,fast:1.8,curve:"melodic"},durationSync:{mode:"bars",adaptToPhrase:!0,sustain:!0},phaseSync:{enabled:!0,multiplier:.5,type:"ensemble"},melodicResponse:{enabled:!0,multiplier:1.4,type:"amplitude"},patternOverrides:{ambient:{amplitudeSync:{onWave:80,onStatic:40,curve:"hypnotic"},frequencySync:{slow:.5,fast:1.2},durationSync:{minBeats:16,maxBeats:64}},ocean:{amplitudeSync:{onWave:90,onStatic:20,curve:"natural"},phaseSync:{multiplier:.8},melodicResponse:{multiplier:1.8}},electronic:{amplitudeSync:{onWave:70,onStatic:30,curve:"digital"},frequencySync:{slow:.8,fast:2.5,curve:"precise"}},orchestral:{amplitudeSync:{onWave:75,onStatic:35},phaseSync:{multiplier:.7},melodicResponse:{multiplier:2}}},dynamics:{forte:{amplitudeSync:{onWave:{multiplier:1.8},onStatic:{multiplier:1.4}},frequencySync:{multiplier:1.3},melodicResponse:{multiplier:2.2}},piano:{amplitudeSync:{onWave:{multiplier:.6},onStatic:{multiplier:.4}},frequencySync:{multiplier:.7},melodicResponse:{multiplier:1.1}}}},initialize(e,t,i,n){e.gestureData||(e.gestureData={});const a=e.x-i,r=e.y-n,s=Math.atan2(r,a),o=Math.sqrt(a*a+r*r),l=Math.random()<.5?1:-1;e.gestureData.wave={startX:e.x,startY:e.y,originalVx:e.vx,originalVy:e.vy,baseOpacity:e.opacity||e.life||1,angle:s,radius:o,offset:Math.random()*Math.PI*2,role:Math.random(),direction:l,initialized:!0}},apply(e,t,i,n,a,r){e.gestureData?.wave?.initialized||this.initialize(e,i,a,r);const s=e.gestureData.wave,o={...this.config,...i},l=i.strength||1,h=this.easeInOutSine(t),c=s.role*o.phaseShift,u=Math.max(0,h-c),d=u*Math.PI*2*o.frequency*s.direction+s.offset,p=.5+s.radius/100*.5,m=o.amplitude*p*l*e.scaleFactor,f=a+Math.sin(d)*m,g=r+Math.sin(2*d)*m*.3+-Math.abs(Math.sin(h*Math.PI))*o.liftHeight*e.scaleFactor,v=o.smoothness+.12*s.role;if(e.x+=(f-e.x)*v,e.y+=(g-e.y)*v,e.vx=.3*(f-e.x),e.vy=.3*(g-e.y),o.fadeInOut){let t;t=u<.1?u/.1:u>.9?(1-u)/.1:.5+.5*Math.sin(u*Math.PI),e.opacity=s.baseOpacity*(.3+.7*t),void 0!==e.life&&(e.life=e.opacity)}if(t>=.95){const i=20*(1-t);e.vx=e.vx*i+s.originalVx*(1-i),e.vy=e.vy*i+s.originalVy*(1-i),o.fadeInOut&&(e.opacity=s.baseOpacity*i,void 0!==e.life&&(e.life=e.opacity))}},cleanup(e){if(e.gestureData?.wave){const t=e.gestureData.wave;e.vx=t.originalVx,e.vy=t.originalVy,e.opacity=t.baseOpacity,void 0!==e.life&&(e.life=t.baseOpacity),delete e.gestureData.wave}},easeInOutSine:e=>-(Math.cos(Math.PI*e)-1)/2,"3d":{evaluate(e,t){const i=t?.strength||1,n=t?.frequency||1,a=-(Math.cos(Math.PI*e)-1)/2,r=a*Math.PI*2*n,s=.12*Math.sin(r)*i,o=.06*Math.sin(2*r)*i,l=.03*Math.sin(r)*i,h=.08*Math.sin(2*r)*i,c=.05*Math.sin(r)*i,u=1+.08*Math.abs(Math.sin(a*Math.PI))*i,d=Math.abs(Math.sin(r));return{position:[s,o,l],rotation:[h,0,c],scale:u,glowIntensity:1+.3*d*i,glowBoost:.6*d*i}}}},cu={name:"drift",emoji:"☁️",type:"override",description:"Controlled floating with fade effects",config:{duration:800,distance:50,angle:45,returnToOrigin:!0,fadeOut:!1,holdTime:.2,turbulence:.1,angleSpread:45,smoothness:.08,easing:"ease",strength:1,particleMotion:{type:"drift",strength:1,distance:60}},rhythm:{enabled:!0,syncMode:"ambient",distanceSync:{quiet:30,loud:80,crescendo:"expand",diminuendo:"contract"},angleSync:{major:45,minor:225,modulation:"smooth",cadence:"return"},holdSync:{shortPhrase:.1,longPhrase:.4,fermata:"sustain"},accentResponse:{enabled:!0,multiplier:1.3,type:"distance"},patternOverrides:{ambient:{distanceSync:{quiet:40,loud:100},holdSync:{shortPhrase:.3,longPhrase:.6}},classical:{angleSync:{major:30,minor:210},distanceSync:{quiet:25,loud:60}},jazz:{angleSync:{major:60,minor:240,swing:!0,syncopated:!0}},new_age:{distanceSync:{quiet:35,loud:70},holdSync:{shortPhrase:.4,longPhrase:.8},angleSync:{modulation:"gradual"}}},dynamics:{forte:{distanceSync:{quiet:{multiplier:1.5},loud:{multiplier:1.8}},holdSync:{multiplier:1.2},accentResponse:{multiplier:1.6}},piano:{distanceSync:{quiet:{multiplier:.6},loud:{multiplier:.8}},holdSync:{multiplier:.8},accentResponse:{multiplier:1.1}}}},initialize(e,t,i,n){e.gestureData||(e.gestureData={});const a=e.x-i,r=e.y-n;let s=Math.atan2(r,a);const o={...this.config,...t}.angleSpread*Math.PI/180,l=(Math.random()-.5)*o;s+=l;const h=30+30*Math.random();e.gestureData.drift={startX:e.x,startY:e.y,originalVx:e.vx,originalVy:e.vy,baseOpacity:e.opacity||e.life||1,driftAngle:s,angleOffset:l,homeRadius:h*e.scaleFactor,homeX:i+Math.cos(s)*h,homeY:n+Math.sin(s)*h,role:Math.random(),turbulencePhase:Math.random()*Math.PI*2,initialized:!0}},apply(e,t,i,n,a,r){e.gestureData?.drift?.initialized||this.initialize(e,i,a,r);const s=e.gestureData.drift,o={...this.config,...i},l=i.strength||1,h=this.easeInOutCubic(t),c=Math.max(0,h-.1*s.role);let u,d,p;if(o.returnToOrigin)if(c<.4){const e=c/.4,t=this.easeOutQuad(e);u=s.startX+(s.homeX-s.startX)*t,d=s.startY+(s.homeY-s.startY)*t}else if(c<.6+o.holdTime){const t=(c-.4)/(.2+o.holdTime);p=s.homeRadius+Math.sin(t*Math.PI*.5)*o.distance*l*e.scaleFactor}else{const t=(c-.6-o.holdTime)/(.4-o.holdTime);p=s.homeRadius+Math.cos(t*Math.PI*.5)*o.distance*l*e.scaleFactor}else{const t=c;p=s.homeRadius+t*o.distance*l*e.scaleFactor}if(void 0!==p){s.turbulencePhase+=o.turbulence*n;const e=Math.sin(s.turbulencePhase)*o.turbulence*10,t=Math.cos(1.3*s.turbulencePhase)*o.turbulence*10,i=s.driftAngle+s.angleOffset;u=a+Math.cos(i)*p+e,d=r+Math.sin(i)*p+t}const m=o.smoothness+.08*s.role;if(e.x+=(u-e.x)*m,e.y+=(d-e.y)*m,e.vx=.25*(u-e.x),e.vy=.25*(d-e.y),o.fadeOut){let i;i=t<.25?.3+t/.25*.7:t<.75?.7+.3*Math.sin((t-.25)*Math.PI/.5):4*(1-t),e.opacity=s.baseOpacity*i,void 0!==e.life&&(e.life=e.opacity)}t>=.99&&(e.vx=.1*s.originalVx,e.vy=.1*s.originalVy,o.fadeOut&&(e.opacity=s.baseOpacity,void 0!==e.life&&(e.life=s.baseOpacity)))},cleanup(e){if(e.gestureData?.drift){const t=e.gestureData.drift;e.vx=t.originalVx,e.vy=t.originalVy,e.opacity=t.baseOpacity,void 0!==e.life&&(e.life=t.baseOpacity),delete e.gestureData.drift}},easeInOutCubic:e=>e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2,easeOutQuad:e=>e*(2-e),"3d":{evaluate(e,t){const i={...this.config,...t},n=t.strength||1,a=(i.angle||45)*Math.PI/180,r=i.returnToOrigin?e<.5?2*e:2*(1-e):e;return{position:[Math.cos(a)*r*.3*n,Math.sin(a)*r*.3*n,.15*Math.sin(e*Math.PI)*n],rotation:[0,10*r*n,0],scale:1+.03*Math.sin(e*Math.PI),glowIntensity:1-.1*r}}}},uu={name:"flicker",emoji:"⚡",type:"blending",description:"Rapid opacity changes with motion jitter",config:{duration:800,flickerRate:15,frequency:6,minOpacity:.3,maxOpacity:1,jitterAmount:2,colorShift:!1,strobe:!1,pulseMode:!1,groupFlicker:.3,easing:"linear",strength:.7,particleMotion:{type:"flicker",strength:.7,frequency:6}},rhythm:{enabled:!0,syncMode:"subdivision",rateSync:{subdivision:"sixteenth",onBeat:30,offBeat:10,triplet:20,curve:"step"},opacitySync:{pattern:"HLMH",subdivision:"eighth",onAccent:.1,regular:.5},jitterSync:{onBeat:5,offBeat:1,accent:10,curve:"random"},strobeSync:{verse:!1,chorus:!0,drop:"intense",pattern:"XOXO"},dynamics:{forte:{flickerRate:25,jitterAmount:5,minOpacity:.1},piano:{flickerRate:8,jitterAmount:1,minOpacity:.5}}},initialize(e,t){e.gestureData||(e.gestureData={});const i={...this.config,...t},n=Math.random()<i.groupFlicker;e.gestureData.flicker={baseOpacity:e.opacity||e.life||1,baseColor:e.color,baseX:e.x,baseY:e.y,flickerTimer:0,lastFlicker:0,flickerState:!0,isGrouped:n,groupId:n?Math.floor(3*Math.random()):-1,phase:Math.random()*Math.PI*2,colorHue:0,initialized:!0}},apply(e,t,i,n,a,r){e.gestureData?.flicker?.initialized||this.initialize(e,i);const s=e.gestureData.flicker,o={...this.config,...i},l=i.strength||1;let h;if(s.flickerTimer+=n*o.flickerRate,o.strobe)h=(s.flickerTimer+s.phase)%1<.5?1:o.minOpacity;else if(o.pulseMode){const e=s.flickerTimer+s.phase;h=o.minOpacity+(o.maxOpacity-o.minOpacity)*(.5*Math.sin(e)+.5)}else{if(s.flickerTimer-s.lastFlicker>1)if(s.lastFlicker=s.flickerTimer,s.isGrouped){const e=Math.floor(s.flickerTimer)%3;s.flickerState=e===s.groupId}else s.flickerState=Math.random()>.3;const t=s.flickerState?o.maxOpacity:o.minOpacity+.3*Math.random(),i=e.opacity/s.baseOpacity;h=i+.3*(t-i)}const c=s.baseOpacity*(1+(h-1)*l);if(e.opacity=Math.max(0,Math.min(1,c)),void 0!==e.life&&(e.life=e.opacity),o.jitterAmount>0&&h>o.minOpacity){const t=o.jitterAmount*l*e.scaleFactor,i=(Math.random()-.5)*t*h,a=(Math.random()-.5)*t*h;e.vx+=.1*i*n,e.vy+=.1*a*n}if(o.colorShift&&e.color){s.colorHue+=.01*n;const t=30*Math.sin(s.colorHue);e.color=this.shiftHue(s.baseColor,t*l)}let u=1;t<.1?u=t/.1:t>.9&&(u=(1-t)/.1),e.opacity*=u,void 0!==e.life&&(e.life=e.opacity),t>.8&&(e.vx*=.95,e.vy*=.95)},shiftHue(e,t){if(!e||!e.startsWith("#"))return e;const i=e.slice(1),n=parseInt(i.substr(0,2),16)/255,a=parseInt(i.substr(2,2),16)/255,r=parseInt(i.substr(4,2),16)/255,s=t*Math.PI/180,o=Math.cos(s),l=Math.sin(s),h=n*l+a*o,c=r,u=e=>Math.max(0,Math.min(255,Math.round(255*e))).toString(16).padStart(2,"0");return`#${u(n*o-a*l)}${u(h)}${u(c)}`},cleanup(e){if(e.gestureData?.flicker){const t=e.gestureData.flicker;e.opacity=t.baseOpacity,e.color=t.baseColor,void 0!==e.life&&(e.life=t.baseOpacity),delete e.gestureData.flicker}},"3d":{evaluate(e,t){const i=t.config||{},n=t.strength||.7,a=i.flickerRate||15;i.minOpacity;const r=e*a,s=Math.sin(r*Math.PI*2),o=Math.floor(10*r),l=.3*s+.5*(Math.sin(123.456*o)+1)*.7,h=.6+.8*l,c=i.jitterAmount||2,u=.003*n*h,d=(Math.random()-.5)*c*u,p=(Math.random()-.5)*c*u,m=.03*(Math.random()-.5)*n*h;return{position:[d,p,0],rotation:[.5*m,0,m],scale:1+.08*(h-1),glowIntensity:h,glowBoost:1.2*l}}}},du={name:"burst",emoji:"💥",type:"blending",description:"Explosive outward burst from center",config:{decay:.5,strength:2},rhythm:{enabled:!0,syncMode:"beat",strengthSync:{onBeat:3.5,offBeat:1,curve:"explosion"},decaySync:{mode:"tempo",fast:.8,slow:.3,curve:"exponential"},durationSync:{mode:"beats",beats:.5,sustain:!1},accentResponse:{enabled:!0,multiplier:2.5,type:"strength"},patternOverrides:{rock:{strengthSync:{onBeat:4,offBeat:1.5},decaySync:{fast:.6,slow:.4}},electronic:{strengthSync:{onBeat:3.8,offBeat:.8,curve:"sharp"},decaySync:{fast:.9,slow:.7}},jazz:{strengthSync:{onBeat:2.8,offBeat:1.8,swing:!0},decaySync:{fast:.5,slow:.2}},orchestral:{strengthSync:{onBeat:3.2,offBeat:.5},accentResponse:{multiplier:3}}},dynamics:{forte:{strengthSync:{onBeat:{multiplier:2},offBeat:{multiplier:1.5}},decaySync:{multiplier:.7},accentResponse:{multiplier:3.5}},piano:{strengthSync:{onBeat:{multiplier:.6},offBeat:{multiplier:.3}},decaySync:{multiplier:1.3},accentResponse:{multiplier:1.8}}}},apply(e,t,i,n,a,r){const s=i.decay||this.config.decay,o=(i.strength||this.config.strength)*(1-t*s),l=e.x-a,h=e.y-r,c=Math.sqrt(l*l+h*h);c>1&&(e.vx+=l/c*o*2*n,e.vy+=h/c*o*2*n)},"3d":{evaluate(e,t){const i={...this.config,...t}.decay||.5,n=e<.3?.3-e:0;return{position:[0,0,0],rotation:[0,0,0],scale:1+(e<.2?5*e:1.5*(1-e))*((t.strength||2)*(1-e*i)),glowIntensity:1+Math.min(1*n,.3),glowBoost:2.5*n}}}},pu={name:"directional",emoji:"➡️",type:"blending",description:"Move particles in a specific direction",config:{angle:0,returnToOrigin:!1,strength:1},rhythm:{enabled:!0,syncMode:"flow",angleSync:{verse:0,chorus:90,bridge:180,outro:270,transition:"smooth"},strengthSync:{onBeat:1.8,offBeat:.6,curve:"wave"},returnSync:{enabled:!0,onSectionChange:!0,duration:"transition",strength:1.2},accentResponse:{enabled:!0,multiplier:2,type:"strength"},patternOverrides:{march:{angleSync:{verse:0,chorus:0},strengthSync:{onBeat:2.5,offBeat:1}},waltz:{angleSync:{verse:45,chorus:135,bridge:225,outro:315,transition:"circular"}},swing:{strengthSync:{onBeat:1.6,offBeat:1.4,swing:!0}},electronic:{angleSync:{transition:"instant"},strengthSync:{onBeat:2.2,offBeat:.4,curve:"sharp"}}},dynamics:{forte:{strengthSync:{onBeat:{multiplier:1.6},offBeat:{multiplier:1.2}},angleSync:{transition:"sharp"},accentResponse:{multiplier:2.5}},piano:{strengthSync:{onBeat:{multiplier:.7},offBeat:{multiplier:.8}},angleSync:{transition:"gradual"},accentResponse:{multiplier:1.4}}}},initialize(e){e.gestureData||(e.gestureData={}),e.gestureData.directional={initialX:e.x,initialY:e.y}},apply(e,t,i,n,a,r){e.gestureData?.directional||this.initialize(e);const s=(i.angle||this.config.angle)*Math.PI/180,o=i.strength||this.config.strength;if(e.vx+=Math.cos(s)*o*.3*n,e.vy+=Math.sin(s)*o*.3*n,i.returnToOrigin&&t>.5){const i=2*(t-.5),a=e.gestureData.directional,r=a.initialX-e.x,s=a.initialY-e.y;e.vx+=r*i*.02*n,e.vy+=s*i*.02*n}},"3d":{evaluate(e,t){const i={...this.config,...t},n=(i.angle||0)*Math.PI/180,a=t.strength||1,r=i.returnToOrigin?e<.5?2*e:2*(1-e):e;return{position:[Math.cos(n)*r*.4*a,Math.sin(n)*r*.4*a,0],rotation:[0,0,0],scale:1,glowIntensity:1}}}},mu={name:"settle",emoji:"🍃",type:"blending",description:"Gradually settle particles to rest",config:{damping:.02,threshold:.01},rhythm:{enabled:!0,syncMode:"resolution",dampingSync:{onResolution:.035,onTension:.015,curve:"gradual"},thresholdSync:{mode:"dynamics",forte:.02,piano:.005,curve:"exponential"},durationSync:{mode:"phrase",minBeats:2,maxBeats:12,sustain:!0},cadenceResponse:{enabled:!0,multiplier:1.6,type:"damping"},patternOverrides:{ambient:{dampingSync:{onResolution:.025,onTension:.008,curve:"atmospheric"},durationSync:{minBeats:8,maxBeats:32}},jazz:{dampingSync:{onResolution:.04,onTension:.02},cadenceResponse:{multiplier:1.8}},classical:{dampingSync:{onResolution:.045,onTension:.012,curve:"expressive"},cadenceResponse:{multiplier:2}},minimalist:{dampingSync:{onResolution:.02,onTension:.005},durationSync:{minBeats:16,maxBeats:64}}},dynamics:{forte:{dampingSync:{onResolution:{multiplier:1.4},onTension:{multiplier:.8}},thresholdSync:{multiplier:2},cadenceResponse:{multiplier:2.2}},piano:{dampingSync:{onResolution:{multiplier:.7},onTension:{multiplier:1.2}},thresholdSync:{multiplier:.5},cadenceResponse:{multiplier:1.3}}}},apply(e,t,i,n,a,r){const s=i.damping||this.config.damping,o=i.threshold||this.config.threshold;e.vx*=Math.max(0,1-s*n*60),e.vy*=Math.max(0,1-s*n*60),Math.abs(e.vx)<o&&(e.vx=0),Math.abs(e.vy)<o&&(e.vy=0)},"3d":{evaluate(e,t){const i=1-Math.pow(1-e,2),n=.01*(1-i);return{position:[Math.sin(e*Math.PI*2)*n,Math.cos(e*Math.PI*3)*n*.5,0],rotation:[0,0,0],scale:1-.03*i,glowIntensity:1-.15*i}}}},fu={name:"fade",emoji:"👻",type:"blending",description:"Fade particle opacity",config:{duration:2e3,fadeIn:!0,fadeOut:!0,minOpacity:0,maxOpacity:1},rhythm:{enabled:!0,syncMode:"dynamic",opacitySync:{onBeat:.9,offBeat:.3,subdivision:"eighth",curve:"exponential"},fadePhaseSync:{verse:{fadeIn:!0,fadeOut:!1},chorus:{fadeIn:!1,fadeOut:!1},bridge:{fadeIn:!0,fadeOut:!0},outro:{fadeIn:!1,fadeOut:!0}},pulseSync:{enabled:!0,frequency:"quarter",intensity:.2,onAccent:.4},dynamics:{forte:{minOpacity:.5,maxOpacity:1},piano:{minOpacity:0,maxOpacity:.4}}},initialize(e){e.gestureData||(e.gestureData={}),e.gestureData.fade={baseOpacity:e.opacity||e.life||1}},apply(e,t,i,n,a,r){e.gestureData?.fade||this.initialize(e);const s=e.gestureData.fade,o={...this.config,...i};let l;l=o.fadeIn&&!o.fadeOut?o.minOpacity+(o.maxOpacity-o.minOpacity)*t:o.fadeOut&&!o.fadeIn?o.maxOpacity-(o.maxOpacity-o.minOpacity)*t:t<.5?o.minOpacity+(o.maxOpacity-o.minOpacity)*(2*t):o.maxOpacity-(o.maxOpacity-o.minOpacity)*(2*(t-.5)),e.opacity=s.baseOpacity*l,void 0!==e.life&&(e.life=e.opacity)},cleanup(e){e.gestureData?.fade&&(e.opacity=e.gestureData.fade.baseOpacity,void 0!==e.life&&(e.life=e.opacity),delete e.gestureData.fade)},"3d":{evaluate(e,t){const i={...this.config,...t};let n;const a=i.minOpacity??0,r=i.maxOpacity??1;return n=i.fadeIn&&!i.fadeOut?a+(r-a)*e:i.fadeOut&&!i.fadeIn?r-(r-a)*e:e<.5?r-2*e*(r-a):a+2*(e-.5)*(r-a),{position:[0,0,0],rotation:[0,0,0],scale:1,glowIntensity:n}}}},gu={name:"hold",emoji:"⏸️",type:"override",description:"Hold particles in current position",config:{holdStrength:.95,allowDrift:!1},rhythm:{enabled:!0,syncMode:"rest",holdSync:{onRest:.98,onSound:.8,curve:"immediate"},durationSync:{mode:"rests",minBeats:.5,maxBeats:8,sustain:!0},pauseResponse:{enabled:!0,multiplier:1.5,type:"strength"},patternOverrides:{classical:{holdSync:{onRest:.99,onSound:.75,curve:"dramatic"},pauseResponse:{multiplier:2}},minimal:{holdSync:{onRest:.95,onSound:.85},durationSync:{minBeats:2,maxBeats:16}},jazz:{holdSync:{onRest:.9,onSound:.7},allowDrift:!0},electronic:{holdSync:{onRest:.99,onSound:.6,curve:"digital"},pauseResponse:{multiplier:1.2}}},dynamics:{forte:{holdSync:{onRest:{multiplier:1.02},onSound:{multiplier:.9}},pauseResponse:{multiplier:2.2}},piano:{holdSync:{onRest:{multiplier:.97},onSound:{multiplier:.85}},pauseResponse:{multiplier:1.3}}}},initialize(e){e.gestureData||(e.gestureData={}),e.gestureData.hold={holdX:e.x,holdY:e.y,originalVx:e.vx,originalVy:e.vy}},apply(e,t,i,n,a,r){e.gestureData?.hold||this.initialize(e);const s=e.gestureData.hold,o=i.holdStrength||this.config.holdStrength;if(i.allowDrift?(e.vx*=o,e.vy*=o):(e.x+=(s.holdX-e.x)*(1-o),e.y+=(s.holdY-e.y)*(1-o),e.vx=0,e.vy=0),t>.9){const i=10*(t-.9);e.vx=e.vx*(1-i)+s.originalVx*i,e.vy=e.vy*(1-i)+s.originalVy*i}},cleanup(e){if(e.gestureData?.hold){const t=e.gestureData.hold;e.vx=t.originalVx,e.vy=t.originalVy,delete e.gestureData.hold}},"3d":{evaluate:(e,t)=>({position:[0,0,0],rotation:[0,0,0],scale:1,glowIntensity:1})}},vu={name:"breathe",emoji:"🫁",type:"blending",description:"Breathing rhythm with inhale and exhale",config:{musicalDuration:{musical:!0,bars:1,minBeats:2,maxBeats:16},phases:[{name:"inhale",beats:1.5},{name:"hold_in",beats:.5},{name:"exhale",beats:1.5},{name:"hold_out",beats:.5}],inhaleRadius:1.5,exhaleRadius:.3,breathRate:.3,spiralStrength:.002,scaleAmount:.25,glowAmount:.4,frequency:1,easing:"sine",strength:.8,particleMotion:{type:"breathe",strength:.8,inhaleRadius:1.5,exhaleRadius:.3}},rhythm:{enabled:!0,syncMode:"phrase",breathRateSync:{mode:"tempo",bpm:"auto",subdivision:"whole",curve:"sine"},radiusSync:{inhale:{onUpbeat:1.8,onDownbeat:1.4,curve:"ease-in"},exhale:{onUpbeat:.2,onDownbeat:.4,curve:"ease-out"}},durationSync:{mode:"phrases",phrases:2,hold:"fermata"},accentResponse:{enabled:!0,multiplier:1.5,type:"expansion"},patternOverrides:{ballad:{breathRateSync:{subdivision:"double-whole"},radiusSync:{inhale:{onUpbeat:2.2,onDownbeat:1.8},exhale:{onUpbeat:.1,onDownbeat:.2}}},uptempo:{breathRateSync:{subdivision:"half"},radiusSync:{inhale:{onUpbeat:1.4,onDownbeat:1.2},exhale:{onUpbeat:.3,onDownbeat:.4}}},ambient:{breathRateSync:{subdivision:"whole",curve:"ease"},radiusSync:{inhale:{onUpbeat:1.6,onDownbeat:1.6},exhale:{onUpbeat:.2,onDownbeat:.2}}}},dynamics:{forte:{radiusSync:{inhale:{multiplier:1.8},exhale:{multiplier:.5}},spiralStrength:.004,scaleAmount:.4},piano:{radiusSync:{inhale:{multiplier:1.2},exhale:{multiplier:.8}},spiralStrength:.001,scaleAmount:.1}}},initialize(e,t,i,n){e.gestureData||(e.gestureData={});const a=e.x-i,r=e.y-n;e.gestureData.breathe={startX:e.x,startY:e.y,angle:Math.atan2(r,a),baseRadius:Math.sqrt(a*a+r*r),phaseOffset:.2*Math.random()-.1}},apply(e,t,i,n,a,r){e.gestureData?.breathe||this.initialize(e,i,a,r);const s={...this.config,...i},o=(Math.sin(t*Math.PI*2*s.breathRate)+1)/2,l=100*(e.scaleFactor||1),h=s.inhaleRadius*l,c=s.exhaleRadius*l,u=c+(h-c)*o,d=e.x-a,p=e.y-r,m=Math.sqrt(d*d+p*p),f=u-m,g=.05*(i.strength||.8)*n;if(m>0){const t=d/m*f*g,a=p/m*f*g;e.vx+=t,e.vy+=a;const r=s.spiralStrength*n*(i.strength||1),l=-p/m,h=d/m;e.vx+=l*r*o,e.vy+=h*r*o}e.vx*=.98,e.vy*=.98},cleanup(e){e.gestureData?.breathe&&delete e.gestureData.breathe},"3d":{evaluate(e,t){const i=(t.config||{}).breathRate||.3,n=Math.sin(e*Math.PI*2*i);let a=1;if(e>.8){const t=(e-.8)/(1-.8);a=1-t*t*t}const r=.2*n*a;return{position:[0,.05*n*a,0],rotation:[0,0,0],scale:1+.35*n*a,glowIntensity:1+r,glowBoost:Math.max(0,2*r)}}}},yu={name:"expand",emoji:"💫",type:"blending",description:"Radial expansion from center",config:{duration:600,scaleAmount:3,scaleTarget:3,glowAmount:.5,easing:"back",strength:3,particleMotion:{type:"pulse",strength:3,direction:"outward",persist:!0}},rhythm:{enabled:!0,syncMode:"crescendo",strengthSync:{pianissimo:1.5,fortissimo:5,crescendo:"build",sforzando:"burst"},scaleTargetSync:{verse:2,chorus:4.5,climax:6,curve:"exponential"},durationSync:{mode:"phrases",build:1.2,release:.8,sustain:"hold"},accentResponse:{enabled:!0,multiplier:2.8,type:"strength"},patternOverrides:{orchestral:{strengthSync:{pianissimo:2,fortissimo:6.5,crescendo:"dramatic"},scaleTargetSync:{climax:8}},rock:{strengthSync:{pianissimo:1.8,fortissimo:5.5,curve:"power"},accentResponse:{multiplier:3.2}},ambient:{strengthSync:{pianissimo:1.2,fortissimo:3.5,crescendo:"organic"},durationSync:{build:1.8,release:1.2}},electronic:{strengthSync:{pianissimo:1.6,fortissimo:4.8,curve:"digital"},scaleTargetSync:{curve:"linear"}}},dynamics:{forte:{strengthSync:{pianissimo:{multiplier:1.4},fortissimo:{multiplier:1.8}},scaleTargetSync:{multiplier:1.6},accentResponse:{multiplier:3.5}},piano:{strengthSync:{pianissimo:{multiplier:.8},fortissimo:{multiplier:1.2}},scaleTargetSync:{multiplier:.7},accentResponse:{multiplier:2}}}},initialize(e,t,i,n){e.gestureData||(e.gestureData={});const a=e.x-i,r=e.y-n;e.gestureData.expand={startX:e.x,startY:e.y,angle:Math.atan2(r,a),baseRadius:Math.sqrt(a*a+r*r),initialized:!0}},apply(e,t,i,n,a,r){e.gestureData?.expand?.initialized||this.initialize(e,i,a,r);const s=e.gestureData.expand,o={...this.config,...i},l=o.strength||1,h=1+(o.scaleTarget-1)*t*l,c=s.baseRadius*h,u=a+Math.cos(s.angle)*c,d=r+Math.sin(s.angle)*c,p=u-e.x,m=d-e.y;e.vx+=.8*p*n,e.vy+=.8*m*n,e.vx*=.95,e.vy*=.95},cleanup(e){e.gestureData?.expand&&delete e.gestureData.expand},"3d":{evaluate(e,t){const i={...this.config,...t},n=i.strength||3;return{position:[0,0,0],rotation:[0,0,0],scale:1+e*(i.scaleAmount||3)*(n/3),glowIntensity:1+.25*e,glowBoost:.8*e}}}},bu={name:"contract",emoji:"🌀",type:"blending",description:"Radial contraction toward center",config:{duration:600,scaleAmount:.2,scaleTarget:.2,glowAmount:-.2,easing:"cubic",strength:2.5,particleMotion:{type:"pulse",strength:2.5,direction:"inward",persist:!0}},rhythm:{enabled:!0,syncMode:"tension",strengthSync:{onTension:4,onRelease:1.5,curve:"magnetic"},scaleTargetSync:{forte:.1,piano:.4,crescendo:"gradual",diminuendo:"ease"},durationSync:{mode:"phrases",shortPhrase:.8,longPhrase:1.5,hold:"sustain"},accentResponse:{enabled:!0,multiplier:2.2,type:"strength"},patternOverrides:{classical:{strengthSync:{onTension:3.5,onRelease:1.8},scaleTargetSync:{forte:.15,piano:.35}},metal:{strengthSync:{onTension:5,onRelease:2,curve:"sharp"},scaleTargetSync:{forte:.05,piano:.25}},ambient:{strengthSync:{onTension:2.8,onRelease:1.2,curve:"ease"},durationSync:{shortPhrase:1.2,longPhrase:2}},trap:{strengthSync:{onTension:4.5,onRelease:1,dropBeat:6},scaleTargetSync:{forte:.08,piano:.3}}},dynamics:{forte:{strengthSync:{onTension:{multiplier:1.8},onRelease:{multiplier:1.4}},scaleTargetSync:{multiplier:.6},accentResponse:{multiplier:2.8}},piano:{strengthSync:{onTension:{multiplier:.7},onRelease:{multiplier:.8}},scaleTargetSync:{multiplier:1.4},accentResponse:{multiplier:1.6}}}},initialize(e,t,i,n){e.gestureData||(e.gestureData={});const a=e.x-i,r=e.y-n;e.gestureData.contract={startX:e.x,startY:e.y,angle:Math.atan2(r,a),baseRadius:Math.sqrt(a*a+r*r),initialized:!0}},apply(e,t,i,n,a,r){e.gestureData?.contract?.initialized||this.initialize(e,i,a,r);const s=e.gestureData.contract,o={...this.config,...i},l=o.strength||1,h=1-(1-o.scaleTarget)*t*l,c=s.baseRadius*h,u=a+Math.cos(s.angle)*c,d=r+Math.sin(s.angle)*c,p=u-e.x,m=d-e.y;e.vx+=.5*p*n,e.vy+=.5*m*n,e.vx*=.95,e.vy*=.95},cleanup(e){e.gestureData?.contract&&delete e.gestureData.contract},"3d":{evaluate(e,t){const i={...this.config,...t},n=i.strength||2.5,a=i.scaleTarget||.2,r=1-e*(1-a)*(n/2.5),s=1-.15*e;return{position:[0,0,0],rotation:[0,0,0],scale:Math.max(a,r),glowIntensity:s}}}},Mu={name:"flash",emoji:"⚡",type:"blending",description:"Bright flash burst effect",config:{duration:400,glowAmount:2.5,glowPeak:3,scalePeak:1.1,easing:"cubic",strength:1,particleMotion:{type:"burst",strength:1,decay:.3}},rhythm:{enabled:!0,syncMode:"beat",timingSync:"immediate",interruptible:!0,priority:8,blendable:!0,intensitySync:{onBeat:3.5,offBeat:1,accent:5,subdivision:"quarter",curve:"exponential"},durationSync:{mode:"tempo",baseDuration:400,scaling:"inverse"},scaleSync:{onBeat:1.2,offBeat:1,accent:1.4,curve:"elastic"},strobeSync:{enabled:!1,pattern:"XXOX",subdivision:"sixteenth"},dynamics:{forte:{glowPeak:4,scalePeak:1.3,duration:300},piano:{glowPeak:2,scalePeak:1.05,duration:500}}},initialize(e,t){e.gestureData||(e.gestureData={}),e.gestureData.flash={originalOpacity:e.opacity,originalSize:e.size,initialized:!0}},apply(e,t,i,n,a,r){e.gestureData?.flash?.initialized||this.initialize(e,i);const s=e.gestureData.flash,o={...this.config,...i},l=o.strength||1;let h;if(h=t<.3?t/.3*o.glowPeak:o.glowPeak*(1-(t-.3)/.7),e.opacity=Math.min(1,s.originalOpacity*(1+h*l)),e.size=s.originalSize*(1+(o.scalePeak-1)*h*l*.1),t<.2){const i=(1-t/.2)*l,s=Math.atan2(e.y-r,e.x-a);e.vx+=Math.cos(s)*i*2*n,e.vy+=Math.sin(s)*i*2*n}e.vx*=1-.1*o.particleMotion.decay,e.vy*=1-.1*o.particleMotion.decay},cleanup(e){e.gestureData?.flash&&(e.opacity=e.gestureData.flash.originalOpacity,e.size=e.gestureData.flash.originalSize,delete e.gestureData.flash)},"3d":{evaluate(e,t){const i={...this.config,...t};let n;t.strength,n=e<.3?e/.3:1-(e-.3)/.7;const a=1+.4*n;return{position:[0,0,0],rotation:[0,0,0],scale:1+n*((i.scalePeak||1.1)-1),glowIntensity:a,glowBoost:2*n}}}},_u={name:"glow",emoji:"✨",type:"blending",description:"Pure luminous glow without movement",config:{duration:1500,amplitude:0,frequency:1,holdPeak:.3,easing:"sine",scaleAmount:.1,glowAmount:.8,strength:0,direction:"none",particleMotion:{type:"glow",strength:0,direction:"none",frequency:1}},rhythm:{enabled:!0,syncMode:"phrase",amplitudeSync:{onBeat:2,offBeat:1.2,curve:"smooth"},frequencySync:{mode:"phrase",subdivision:"bar"},durationSync:{mode:"bars",bars:2},accentResponse:{enabled:!0,multiplier:2.5},patternOverrides:{ambient:{amplitudeSync:{onBeat:2.5,offBeat:1.8},durationSync:{bars:4}},electronic:{amplitudeSync:{onBeat:3,offBeat:.5,curve:"sharp"},frequencySync:{subdivision:"quarter"}}}},initialize(e,t,i,n){e.gestureData||(e.gestureData={}),e.gestureData.glow={startOpacity:e.opacity,startGlow:e.glowSizeMultiplier||0,initialized:!0}},apply(e,t,i,n,a,r){e.gestureData?.glow?.initialized||this.initialize(e,i,a,r);const s={...this.config,...i},o=this.easeInOutSine(t);let l,{frequency:h}=s,{glowAmount:c}=s;i.rhythmModulation&&(c*=i.rhythmModulation.amplitudeMultiplier||1,c*=i.rhythmModulation.accentMultiplier||1,i.rhythmModulation.frequencyMultiplier&&(h*=i.rhythmModulation.frequencyMultiplier));const u=o*h*2%2;l=s.holdPeak>0&&u>1-s.holdPeak&&u<1+s.holdPeak?1:Math.sin(o*Math.PI*2*h);let d=1;t>.9&&(d=.5+.5*(1-10*(t-.9))),e.glowIntensity=1+l*c*d},cleanup(e){e.gestureData?.glow&&(e.glowIntensity=1,delete e.gestureData.glow)},easeInOutSine:e=>-(Math.cos(Math.PI*e)-1)/2,"3d":{evaluate(e,t){const i={...this.config,...t},n=-(Math.cos(Math.PI*e)-1)/2,a=Math.sin(n*Math.PI);let r=i.glowAmount||.8;t.rhythmModulation&&(r*=t.rhythmModulation.amplitudeMultiplier||1,r*=t.rhythmModulation.accentMultiplier||1);const s=1+a*r;return{position:[0,0,0],rotation:[0,0,0],scale:1+a*(i.scaleAmount||.1)*.5,glowIntensity:s,glowBoost:1.5*a}}}},xu={name:"peek",emoji:"👀",type:"effect",description:"Quick peek and hide motion",config:{peekDistance:40,peekSpeed:.15,holdDuration:200,hideSpeed:.25,stagger:!0,duration:1500},rhythm:{enabled:!0,syncMode:"accent",distanceSync:{onAccent:60,offAccent:25,curve:"quick"},speedSync:{mode:"tempo",fast:.25,slow:.1,hideMultiplier:1.8},durationSync:{mode:"subdivision",beats:.25,staggerBeats:.125,sustain:!1},syncopationResponse:{enabled:!0,multiplier:1.8,type:"distance"},patternOverrides:{funk:{distanceSync:{onAccent:70,offAccent:35,curve:"funky"},syncopationResponse:{multiplier:2.2}},latin:{speedSync:{fast:.3,slow:.12},durationSync:{beats:.5,staggerBeats:.25}},breakbeat:{distanceSync:{onAccent:55,offAccent:40},syncopationResponse:{multiplier:2.5}},classical:{distanceSync:{onAccent:45,offAccent:20,curve:"elegant"},speedSync:{fast:.18,slow:.08}}},dynamics:{forte:{distanceSync:{onAccent:{multiplier:1.6},offAccent:{multiplier:1.3}},speedSync:{multiplier:1.4},syncopationResponse:{multiplier:2.8}},piano:{distanceSync:{onAccent:{multiplier:.6},offAccent:{multiplier:.4}},speedSync:{multiplier:.7},syncopationResponse:{multiplier:1.2}}}},apply(e,t,i,n,a,r){if(e.gestureData||(e.gestureData={}),!e.gestureData.peek){const t=e.x-a,i=e.y-r,n=Math.atan2(i,t),s=Math.sqrt(t*t+i*i);e.gestureData.peek={originalX:e.x,originalY:e.y,peekAngle:n,originalDistance:s,staggerDelay:this.config.stagger?.3*Math.random():0,phase:"waiting",phaseTimer:0,peekOffset:{x:0,y:0}}}const s=e.gestureData.peek,{config:o}=this,l=Math.max(0,Math.min(1,(t-s.staggerDelay)/(1-s.staggerDelay)));0===l?s.phase="waiting":l<.3?s.phase="peeking":l<.6?s.phase="holding":l<1&&(s.phase="hiding");let h=0;switch(s.phase){case"peeking":{const e=l/.3;h=this.easeOutCubic(e)*o.peekDistance;break}case"holding":h=o.peekDistance,Math.random()<.1&&(s.peekOffset.x+=2*(Math.random()-.5),s.peekOffset.y+=2*(Math.random()-.5));break;case"hiding":{const e=(l-.6)/.4;h=(1-this.easeInCubic(e))*o.peekDistance;break}}if("waiting"!==s.phase){const t=Math.cos(s.peekAngle)*h,i=Math.sin(s.peekAngle)*h;s.peekOffset.x+=(t-s.peekOffset.x)*o.peekSpeed,s.peekOffset.y+=(i-s.peekOffset.y)*o.peekSpeed,e.x=s.originalX+s.peekOffset.x,e.y=s.originalY+s.peekOffset.y}void 0!==e.alpha&&("peeking"===s.phase||"holding"===s.phase?e.alpha=.7+.3*Math.random():e.alpha=1)},easeOutCubic:e=>1-Math.pow(1-e,3),easeInCubic:e=>e*e*e,cleanup(e){e.gestureData?.peek&&(e.x=e.gestureData.peek.originalX,e.y=e.gestureData.peek.originalY,void 0!==e.alpha&&(e.alpha=1),delete e.gestureData.peek)},"3d":{evaluate(e,t){const i=.01*({...this.config,...t}.peekDistance||40);let n=0,a=1;if(e<.3){const t=e/.3;n=(1-Math.pow(1-t,3))*i}else if(e<.6)n=i,a=.7+.3*Math.random();else{const t=(e-.6)/.4;n=(1-Math.pow(t,3))*i}return{position:[n,0,0],rotation:[0,0,0],scale:1,glowIntensity:a}}}},Su={name:"runningman",emoji:"🏃",type:"effect",description:"Hip-hop running man shuffle",config:{duration:2e3,slideDistance:30,stepHeight:15,speed:1.2,strength:.8,particleMotion:{type:"runningman",strength:.7}},rhythm:{enabled:!0,syncToBeat:!0,beatMultiplier:1,accentBeats:[1,3]},apply:(e,t,i,n,a,r)=>!1,blend:(e,t,i)=>!1,"3d":{evaluate(e,t){const i={...this.config,...t}.strength||.8;return{position:[.1*Math.sin(e*Math.PI*4)*i,.05*Math.abs(Math.sin(e*Math.PI*8))*i,0],rotation:[0,0,.035*Math.sin(e*Math.PI*4)*i],scale:1-.035*Math.abs(Math.sin(e*Math.PI*8))*i,glowIntensity:1+.25*Math.abs(Math.sin(e*Math.PI*8)),glowBoost:.35*Math.max(0,Math.abs(Math.sin(e*Math.PI*8)))}}}},wu={name:"charleston",emoji:"🕺",type:"effect",description:"Hip-hop Charleston shuffle with crisscross",config:{duration:2500,kickDistance:35,swivelRange:40,bounceHeight:12,strength:.9,particleMotion:{type:"charleston",strength:.8}},rhythm:{enabled:!0,syncToBeat:!0,beatMultiplier:2,accentBeats:[1,2.5,3,4.5]},apply:(e,t,i,n,a,r)=>!1,blend:(e,t,i)=>!1,"3d":{evaluate(e,t){const i={...this.config,...t}.strength||.9;return{position:[.12*Math.sin(e*Math.PI*8)*i,.05*Math.abs(Math.sin(e*Math.PI*8))*i,0],rotation:[0,0,.05*Math.sin(e*Math.PI*8)*i],scale:1-.04*Math.abs(Math.sin(e*Math.PI*8))*i,glowIntensity:1+.3*Math.abs(Math.sin(e*Math.PI*8)),glowBoost:.4*Math.max(0,Math.abs(Math.sin(e*Math.PI*8)))}}}};const Eu=[Nc,Gc,Vc,Hc,Wc,jc,Xc,qc,Yc,$c,{name:"sparkle",emoji:"✨",type:"blending",description:"Bright twinkling sparkle bursts",config:{duration:800,musicalDuration:{musical:!0,beats:2}},rhythm:{enabled:!0,syncMode:"beat",timingSync:"nextBeat",durationSync:{mode:"beats",beats:2},interruptible:!0,priority:5,blendable:!0},apply:(e,t,i)=>!1,blend:(e,t,i)=>!1,"3d":{evaluate(e,t){const i=t?.strength||1,n=Math.pow(Math.max(0,Math.sin(e*Math.PI*6)),3),a=Math.pow(Math.max(0,Math.sin(e*Math.PI*8+1)),3),r=Math.pow(Math.max(0,Math.sin(e*Math.PI*10+2)),3),s=Math.max(n,a,r)*Math.sin(e*Math.PI);return{position:[0,0,0],rotation:[0,0,0],scale:1+.08*s*i,glowIntensity:1+.5*s*i,glowBoost:2*s*i}}}},{name:"shimmer",emoji:"🌟",type:"particle",description:"Shimmer effect with sparkling particles",config:{duration:2e3,musicalDuration:{musical:!0,bars:1},particleMotion:"radiant"},rhythm:{enabled:!0,syncType:"beat",durationSync:{mode:"bars",bars:1},intensity:.8},override:(e,t,i)=>(e.shimmerEffect=!0,e.shimmerProgress=t,!0),blend:(e,t,i)=>!1,"3d":{evaluate(e,t){const i=t?.strength||1,n=(.4*Math.sin(e*Math.PI*4)+.35*Math.sin(e*Math.PI*6+.5)+.25*Math.sin(e*Math.PI*10+1)+1)/2;return{position:[0,0,0],rotation:[0,0,0],scale:1+.05*n*i,glowIntensity:1+.3*n*i,glowBoost:1*n*i}}}},Zc,((e,t="✨")=>({name:e,emoji:t,type:"blending",description:`${e} animation`,config:{duration:1e3,musicalDuration:{musical:!0,beats:2}},rhythm:{enabled:!0,syncMode:"beat",timingSync:"nextBeat",durationSync:{mode:"beats",beats:2},interruptible:!0,priority:3,blendable:!0,crossfadePoint:"anyBeat",maxQueue:3},apply:(e,t,i)=>!1,blend:(e,t,i)=>!1}))("groove","🎵"),Jc,Qc,eu,Kc,{name:"rain",emoji:"🌧️",type:"particle",description:"Rain effect with falling particles",config:{duration:3e3,musicalDuration:{musical:!0,bars:2},particleMotion:"falling"},rhythm:{enabled:!0,syncType:"off-beat",durationSync:{mode:"bars",bars:2},intensity:.8},apply:(e,t,i)=>(e.rainEffect=!0,e.rainProgress=t,!0),blend:(e,t,i)=>!1}],Tu=[tu,iu,nu,au,ru,su,ou,lu],Cu=[hu,cu,uu,du,pu,mu,fu,gu,vu,yu,bu,Mu,_u,xu,Su,wu],Au={};function Pu(e){if(Au[e])return Au[e];return kc(e)||null}[...Eu,...Tu,...Cu].forEach(e=>{Au[e.name]=e}),Eu.map(e=>e.name),Tu.map(e=>e.name),Cu.map(e=>e.name);const Du={none:{speed:1,amplitude:1,intensity:1,smoothness:1,regularity:1,"3d":{rotation:{speedMultiplier:1,shakeMultiplier:1},glow:{intensityMultiplier:1,pulseSpeedMultiplier:1},scale:{breathDepthMultiplier:1,breathRateMultiplier:1},righting:{strengthMultiplier:1}}},clear:{speed:1,amplitude:1,intensity:1,smoothness:1,regularity:1,"3d":{rotation:{speedMultiplier:1,shakeMultiplier:1},glow:{intensityMultiplier:1,pulseSpeedMultiplier:1},scale:{breathDepthMultiplier:1,breathRateMultiplier:1},righting:{strengthMultiplier:1}}},nervous:{speed:1.2,amplitude:.9,intensity:1.1,smoothness:.7,regularity:.6,addFlutter:!0,addMicroShake:!0,"3d":{rotation:{speedMultiplier:1.5,shakeMultiplier:3.5,enableEpisodicWobble:!0},glow:{intensityMultiplier:1.25,pulseSpeedMultiplier:2},scale:{breathDepthMultiplier:.5,breathRateMultiplier:1.8},righting:{strengthMultiplier:.7}}},confident:{speed:.9,amplitude:1.3,intensity:1.2,smoothness:1.1,regularity:1.2,addPower:!0,addHold:!0,"3d":{rotation:{speedMultiplier:.7,shakeMultiplier:.2},glow:{intensityMultiplier:1.4,pulseSpeedMultiplier:.7},scale:{breathDepthMultiplier:1.5,breathRateMultiplier:.7},righting:{strengthMultiplier:1.6}}},tired:{speed:.7,amplitude:.7,intensity:.8,smoothness:1.3,regularity:.8,addDroop:!0,addPause:!0,"3d":{rotation:{speedMultiplier:.4,shakeMultiplier:.15},glow:{intensityMultiplier:.5,pulseSpeedMultiplier:.5},scale:{breathDepthMultiplier:1.3,breathRateMultiplier:.5},righting:{strengthMultiplier:.6}}},intense:{speed:1.3,amplitude:1.2,intensity:1.4,smoothness:.6,regularity:.9,addPulse:!0,addFocus:!0,"3d":{rotation:{speedMultiplier:1.6,shakeMultiplier:2.5},glow:{intensityMultiplier:1.8,pulseSpeedMultiplier:2.2},scale:{breathDepthMultiplier:1.6,breathRateMultiplier:1.8},righting:{strengthMultiplier:1.3}}},subdued:{speed:.8,amplitude:.8,intensity:.7,smoothness:1.2,regularity:1.1,addSoftness:!0,addFade:!0,"3d":{rotation:{speedMultiplier:.5,shakeMultiplier:.1},glow:{intensityMultiplier:.55,pulseSpeedMultiplier:.6},scale:{breathDepthMultiplier:.7,breathRateMultiplier:.6},righting:{strengthMultiplier:1.4}}}};function Ru(e){return e&&""!==e&&"clear"!==e&&Du[e]||Du.clear}function Iu(e){return 3===(e=e.replace("#","")).length&&(e=e.split("").map(e=>e+e).join("")),{r:parseInt(e.substr(0,2),16),g:parseInt(e.substr(2,2),16),b:parseInt(e.substr(4,2),16)}}const Lu={intense:1.6,confident:1.3,nervous:1.15,clear:1,tired:.8,subdued:.5};function Bu(e,t){if(!t||"clear"===t)return e;const i=Lu[t.toLowerCase()];return i&&1!==i?function(e,t){const i=Iu(e),n=function(e,t,i){e/=255,t/=255,i/=255;const n=Math.max(e,t,i),a=Math.min(e,t,i),r=(n+a)/2;let s,o;if(n===a)s=o=0;else{const l=n-a;switch(o=r>.5?l/(2-n-a):l/(n+a),n){case e:s=(t-i)/l+(t<i?6:0);break;case t:s=(i-e)/l+2;break;case i:s=(e-t)/l+4}s/=6}return{h:360*s,s:100*o,l:100*r}}(i.r,i.g,i.b);n.s=Math.max(0,Math.min(100,n.s*t));const a=function(e,t,i){e/=360,i/=100;const n=(e,t,i)=>(i<0&&(i+=1),i>1&&(i-=1),i<1/6?e+6*(t-e)*i:i<.5?t:i<2/3?e+(t-e)*(2/3-i)*6:e);let a,r,s;if(0==(t/=100))a=r=s=i;else{const o=i<.5?i*(1+t):i+t-i*t,l=2*i-o;a=n(l,o,e+1/3),r=n(l,o,e),s=n(l,o,e-1/3)}return{r:Math.round(255*a),g:Math.round(255*r),b:Math.round(255*s)}}(n.h,n.s,n.l);return function(e,t,i){const n=e=>{const t=Math.round(Math.max(0,Math.min(255,e))).toString(16);return 1===t.length?`0${t}`:t};return`#${n(e)}${n(t)}${n(i)}`}(a.r,a.g,a.b)}(e,i):e}Object.fromEntries(Object.entries({neutral:"#B0B0B0",joy:"#FFD700",sadness:"#4169E1",anger:"#DC143C",fear:"#8B008B",surprise:"#FF8C00",disgust:"#9ACD32",love:"#FF69B4"}).map(([e,t])=>{const i=Iu(t);return[e,`${i.r}, ${i.g}, ${i.b}`]}));const Ou=new class{constructor(){this.enabled=!1,this.adapter=null,this.subsystemConfigs=new Map,this.activeModulations=new Map}initialize(){this.adapter=Rc.getAdapter(),this.enabled=!0,this.adapter.onBeat(this.handleBeat.bind(this)),this.adapter.onBar(this.handleBar.bind(this))}updateBPM(e){if(e>=60&&e<=220){if(window.rhythmManuallyStoppedForCurrentAudio)return;if(!Rc.isRunning)return this.start(e,"straight"),void(window.rhythmSyncVisualizer&&!window.rhythmSyncVisualizer.state.active&&window.rhythmSyncVisualizer.start());Rc.setBPM(e)}}registerConfig(e,t,i){if(!i.rhythm||!i.rhythm.enabled)return;const n=`${e}:${t}`;this.subsystemConfigs.set(n,{type:e,name:t,rhythmConfig:i.rhythm,originalConfig:i})}applyGestureRhythm(e,t,i,n){if(!this.enabled||!e.rhythm?.enabled)return{};const a=e.rhythm,r={};if(a.amplitudeSync){const e=a.amplitudeSync,t=this.adapter.getBeatSync(e.offBeat||.8,e.onBeat||1.5,e.curve||"linear");r.amplitudeMultiplier=t}if(a.wobbleSync){const e=a.wobbleSync;this.adapter.isOnSubdivision(e.subdivision,.1)?r.wobbleMultiplier=1+e.intensity:r.wobbleMultiplier=1}if(a.accentResponse?.enabled){const e=this.adapter.getAccentedValue(1,a.accentResponse.multiplier||1.5);r.accentMultiplier=e}const s=this.adapter.getPattern();return s&&a.patternOverrides?.[s]&&Object.assign(r,a.patternOverrides[s]),r}applyParticleRhythm(e,t){if(!this.enabled||!e.rhythm?.enabled)return{};const i=this.adapter.getTimeInfo(),n=e.rhythm,a={};if(n.particleEmission){const e=n.particleEmission;"beat"===e.syncMode&&this.adapter.isOnBeat(.1)?a.emitBurst=e.burstSize||3:void 0!==e.offBeatRate&&(a.emissionRate=e.offBeatRate)}if(n.glowSync){const e=n.glowSync,t=this.adapter.getBeatSync(e.intensityRange[0]||1,e.intensityRange[1]||2,"pulse");a.glowIntensity=t}if("bars"===n.breathSync?.mode){const e=n.breathSync,t=i.bar%e.barsPerBreath/e.barsPerBreath;a.breathPhase=t*Math.PI*2}return a}applyBehaviorRhythm(e,t,i){if(!this.enabled||!e.rhythm?.enabled)return{};const n=this.adapter.getTimeInfo(),a=e.rhythm,r={};if(a.glitchTiming){const e=a.glitchTiming;if(this.adapter.isOnSubdivision(e.subdivision,.05)&&Math.random()<e.probability){const t=this.adapter.isOnBeat()?e.intensityOnBeat:e.intensityOffBeat;r.triggerGlitch=!0,r.glitchIntensity=t}}if(a.orbitRhythm){const e=a.orbitRhythm;"tempo"===e.baseSpeed&&(r.speedMultiplier=this.adapter.getBPM()/120),e.beatAcceleration&&this.adapter.isOnBeat(.1)&&(r.speedBoost=e.beatAcceleration),e.barReset&&0===n.beatInBar&&(r.resetOrbit=!0)}if(a.stutterSync){const e=a.stutterSync,t=this.adapter.getPattern();if(t&&e.patterns?.[t]){const i=e.patterns[t];i.freezeOnDrop&&2===n.beatInBar?(r.freeze=!0,r.freezeDuration=i.dropDuration):i.randomFreeze&&Math.random()<i.randomFreeze&&(r.freeze=!0,r.freezeDuration=i.duration)}}return r}handleBeat(e){this.lastBeatInfo=e}handleBar(e){this.lastBarInfo=e}getMusicalDuration(e,t){if(!this.enabled||!e?.durationSync)return t;const i=e.durationSync;return"bars"===i.mode?this.adapter.beatsToMs(4*i.bars):"beats"===i.mode?this.adapter.beatsToMs(i.beats):t}isEnabled(){return this.enabled&&this.adapter.isPlaying()}start(e=120,t="straight"){e&&Rc.setBPM(e),t&&Rc.setPattern(t),Rc.start(),this.enabled=!0}stop(){Rc.stop(),this.enabled=!1,this.bpmLocked=!1,this.lockedBPM=null}setPattern(e){Rc.setPattern(e)}setBPM(e){Rc.setBPM(e),this.bpmLocked&&(this.lockedBPM=e)}resampleBPM(){this.bpmLocked=!1,this.lockedBPM=null}setTimeSignature(e){this.timeSignature=e;const t=document.getElementById("time-sig-display");t&&(t.textContent=e),"3/4"===e&&Rc.getPattern()}syncToAudio(e,t){Rc.syncToAudio(e,t)}},Fu=new class{constructor(){this.emotionCache=new Map,this.visualParamsCache=new Map,this.modifiersCache=new Map,this.transitionCache=new Map,this.stats={hits:0,misses:0,loadTime:0,cacheSize:0},this.isInitialized=!1,this.loadStartTime=0,this.initialize()}initialize(){this.loadStartTime=performance.now();try{const e=[...Array.from(wc.keys()),..._c()];e.forEach(e=>{this.cacheEmotion(e)}),this.cacheCommonTransitions(e),this.isInitialized=!0,this.stats.loadTime=performance.now()-this.loadStartTime,this.stats.cacheSize=this.emotionCache.size}catch(e){console.error("[EmotionCache] Initialization failed:",e),this.isInitialized=!1}}cacheEmotion(e){try{const t=Tc(e);t&&this.emotionCache.set(e,t);const i=Cc(e);this.visualParamsCache.set(e,i);const n=Ac(e);this.modifiersCache.set(e,n)}catch(t){console.warn(`[EmotionCache] Failed to cache emotion '${e}':`,t)}}cacheCommonTransitions(e){[["neutral","joy"],["neutral","sadness"],["neutral","anger"],["joy","sadness"],["sadness","joy"],["anger","calm"],["calm","anger"]].forEach(([t,i])=>{if(e.includes(t)&&e.includes(i))try{const e=Pc(t,i),n=`${t}->${i}`;this.transitionCache.set(n,e)}catch(e){console.warn(`[EmotionCache] Failed to cache transition '${t}->${i}':`,e)}})}getEmotion(e){if(!this.isInitialized)return console.warn("[EmotionCache] Cache not initialized, falling back to direct access"),Tc(e);const t=this.emotionCache.get(e);return t?(this.stats.hits++,t):(this.stats.misses++,console.warn(`[EmotionCache] Cache miss for emotion '${e}', consider adding to pre-cache`),Tc(e))}getVisualParams(e){if(!this.isInitialized)return Cc(e);const t=this.visualParamsCache.get(e);return t?(this.stats.hits++,t):(this.stats.misses++,Cc(e))}getModifiers(e){if(!this.isInitialized)return Ac(e);const t=this.modifiersCache.get(e);return t?(this.stats.hits++,t):(this.stats.misses++,Ac(e))}getTransitionParams(e,t){if(!this.isInitialized)return Pc(e,t);const i=`${e}->${t}`,n=this.transitionCache.get(i);return n?(this.stats.hits++,n):(this.stats.misses++,Pc(e,t))}hasEmotion(e){return this.emotionCache.has(e)}getStats(){const e=this.stats.hits+this.stats.misses,t=e>0?(this.stats.hits/e*100).toFixed(2):0;return{isInitialized:this.isInitialized,loadTime:this.stats.loadTime,cacheSize:this.stats.cacheSize,hits:this.stats.hits,misses:this.stats.misses,hitRate:`${t}%`,emotions:this.emotionCache.size,visualParams:this.visualParamsCache.size,modifiers:this.modifiersCache.size,transitions:this.transitionCache.size}}clear(){this.emotionCache.clear(),this.visualParamsCache.clear(),this.modifiersCache.clear(),this.transitionCache.clear(),this.isInitialized=!1,this.stats={hits:0,misses:0,loadTime:0,cacheSize:0}}reinitialize(){this.clear(),this.initialize()}};function Uu(e){if(!e||0===e.length)return"#FFFFFF";let t=0,i=0;const n=[];for(const a of e)"string"==typeof a?(n.push({color:a,weight:null}),i++):a&&"object"==typeof a&&a.color&&(n.push({color:a.color,weight:a.weight||null}),a.weight?t+=a.weight:i++);const a=Math.max(0,100-t),r=i>0?a/i:0,s=[];let o=0;for(const e of n)o+=null!==e.weight?e.weight:r,s.push({color:e.color,threshold:o});const l=Math.random()*o;for(const e of s)if(l<=e.threshold)return e.color;return n[n.length-1].color}var zu={name:"ambient",emoji:"☁️",description:"Gentle upward drift like smoke",initialize:function(e){e.vx=0,e.vy=-.04-.02*Math.random(),e.lifeDecay=.002,e.emotionColors&&e.emotionColors.length>0&&(e.color=Uu(e.emotionColors)),e.behaviorData={upwardSpeed:5e-4,waviness:0,friction:.998}},update:function(e,t,i,n){const a=e.behaviorData;e.vy*=Math.pow(a.friction,t),e.vy-=a.upwardSpeed*t,e.vx=0}};const ku=2*Math.PI;var Nu={name:"orbiting",emoji:"💕",description:"Romantic firefly dance around the orb",initialize:function(e){e.lifeDecay=.001+.002*Math.random(),e.emotionColors&&e.emotionColors.length>0&&(e.color=Uu(e.emotionColors)),e.isSparkle="#FFE4E1"===e.color||"#FFCCCB"===e.color||"#FFC0CB"===e.color;const t=40*(e.scaleFactor||1)*(1.3+.9*Math.random());e.blinkPhase=Math.random()*ku,e.blinkSpeed=.3+1.2*Math.random(),e.blinkIntensity=.6+.4*Math.random(),e.fadePhase=Math.random()*ku,e.fadeSpeed=.1+.3*Math.random(),e.minOpacity=.2+.2*Math.random(),e.maxOpacity=.8+.2*Math.random(),e.isSparkle&&(e.blinkSpeed*=2,e.blinkIntensity=1,e.minOpacity=0,e.maxOpacity=1),e.behaviorData={angle:Math.random()*ku,radius:t,baseRadius:t,angularVelocity:8e-4+.0017*Math.random(),swayAmount:3+7*Math.random(),swaySpeed:.2+.5*Math.random(),floatOffset:Math.random()*ku,floatSpeed:.3+.7*Math.random(),floatAmount:2+6*Math.random(),twinklePhase:Math.random()*ku,twinkleSpeed:2+3*Math.random()}},update:function(e,t,i,n){const a=e.behaviorData;a.angle+=a.angularVelocity*t;const r=Math.sin(a.angle*a.swaySpeed)*a.swayAmount,s=6*Math.sin(1.5*a.angle),o=(a.radius||a.baseRadius)+s+.2*r,l=i+Math.cos(a.angle)*o,h=n+Math.sin(a.angle)*o;a.floatOffset+=a.floatSpeed*t*.001;const c=Math.sin(a.floatOffset)*a.floatAmount;e.vx=.1*(l-e.x),e.vy=.1*(h+c-e.y),e.fadePhase+=e.fadeSpeed*t*.001;const u=.5*Math.sin(e.fadePhase)+.5,d=e.minOpacity+(e.maxOpacity-e.minOpacity)*u;let p;e.blinkPhase+=e.blinkSpeed*t*.002,e.isSparkle?(a.twinklePhase+=a.twinkleSpeed*t*.001,p=.7*Math.pow(Math.sin(a.twinklePhase),16)+.2*Math.sin(5*e.blinkPhase)+.1):p=.4*Math.sin(e.blinkPhase)+.3*Math.sin(3*e.blinkPhase)+.2*Math.sin(7*e.blinkPhase)+.1*Math.sin(11*e.blinkPhase);const m=.5*(p+1),f=.2+m*e.blinkIntensity*.8;e.opacity=e.baseOpacity*d*f,e.isSparkle?e.size=e.baseSize*(.5+1*m):e.size=e.baseSize*(.8+.3*m),e.isSparkle&&(e.tempColor=m>.85?"#FFFFFF":e.color)}},Gu={name:"rising",emoji:"🎈",description:"Buoyant upward movement like balloons",initialize:function(e){e.vx=.02*(Math.random()-.5),e.vy=-.05-.03*Math.random(),e.lifeDecay=.002,e.baseOpacity=.7+.3*Math.random(),e.emotionColors&&e.emotionColors.length>0&&(e.color=Uu(e.emotionColors)),e.behaviorData={buoyancy:.001,driftAmount:.005}},update:function(e,t,i,n){const a=e.behaviorData;e.vy-=a.buoyancy*t,e.vx+=(Math.random()-.5)*a.driftAmount*t,e.vx*=Math.pow(.995,t),e.vy*=Math.pow(.998,t)}},Vu={name:"falling",emoji:"💧",description:"Heavy downward drift like tears",initialize:function(e){e.vx=0,e.vy=.04+.02*Math.random(),e.lifeDecay=.002,e.emotionColors&&e.emotionColors.length>0&&(e.color=Uu(e.emotionColors));const t=Math.random(),i=Math.random(),n=t*Math.PI*2,a=2*i-1,r=Math.sqrt(1-a*a);e.behaviorData={downwardSpeed:5e-4,friction:.998,fallingDir:{x:r*Math.cos(n),y:a,z:r*Math.sin(n)},orbitDistanceRatio:.7+.4*Math.random()}},update:function(e,t,i,n){const a=e.behaviorData;e.vy*=Math.pow(a.friction,t),e.vy+=a.downwardSpeed*t,e.vx=0}};const Hu=2e3,Wu=3,ju=8,Xu=.7;var qu={name:"popcorn",emoji:"🍿",description:"Spontaneous popping with gravity and bounces",initialize:function(e){if(e.vx=.1*(Math.random()-.5),e.vy=.1*(Math.random()-.5),e.lifeDecay=.008+.012*Math.random(),e.emotionColors&&e.emotionColors.length>0)e.color=Uu(e.emotionColors);else{const t=["#FFFFFF","#FFFACD","#FFF8DC","#FFFFE0","#FAFAD2"];e.color=Uu(t)}e.size=Math.random()<.3?(8+4*Math.random())*e.scaleFactor*e.particleSizeMultiplier:(2+4*Math.random())*e.scaleFactor*e.particleSizeMultiplier,e.baseSize=e.size,e.hasGlow=Math.random()<.2,e.glowSizeMultiplier=e.hasGlow?1.2:0,e.behaviorData={popDelay:Math.random()*Hu,hasPopped:!1,popStrength:Wu+Math.random()*(ju-Wu),gravity:.098,bounceDamping:Xu,bounceCount:0,maxBounces:2+Math.floor(2*Math.random()),spinRate:10*(Math.random()-.5),lifetime:0}},update:function(e,t,i,n){const a=e.behaviorData;if(a.lifetime+=16.67*t,!a.hasPopped&&a.lifetime>a.popDelay){a.hasPopped=!0;const t=Math.random()*Math.PI*2;e.vx=Math.cos(t)*a.popStrength*1.5,e.vy=Math.sin(t)*a.popStrength-.3,e.size=1.25*e.baseSize}if(a.hasPopped){e.vy+=a.gravity*t;const i=n+100*e.scaleFactor;e.y>i&&a.bounceCount<a.maxBounces&&(e.y=i,e.vy=-Math.abs(e.vy)*a.bounceDamping,e.vx*=.9,a.bounceCount++,e.size=e.baseSize*(1.5-.1*a.bounceCount)),a.bounceCount>=a.maxBounces&&(e.lifeDecay=.03+.02*Math.random(),e.size*=.95),Math.sqrt(e.vx*e.vx+e.vy*e.vy)<.5&&(e.lifeDecay*=1.5)}}},Yu={name:"burst",emoji:"💥",description:"Explosive expansion from center",initialize:function(e){const t="suspicion"===e.emotion,i="surprise"===e.emotion,n="glitch"===e.emotion,a=Math.random()*ku,r=t?1+.8*Math.random():i?7+5*Math.random():n?2+1.5*Math.random():3.5+2.5*Math.random();e.vx=Math.cos(a)*r,e.vy=Math.sin(a)*r,e.lifeDecay=t?.01:i?.006+.008*Math.random():n?.012:.015,e.emotionColors&&e.emotionColors.length>0&&(e.color=Uu(e.emotionColors)),t&&(e.size=(6+4*Math.random())*(e.scaleFactor||1)*(e.particleSizeMultiplier||1),e.baseSize=e.size,e.opacity=1,e.baseOpacity=e.opacity),e.behaviorData={isSuspicion:t,isSurprise:i,isGlitch:n,age:0,fadeStart:t?.3:.2,glitchPhase:Math.random()*Math.PI*2,glitchIntensity:n?.3:0,glitchFrequency:n?.1:0}},update:function(e,t,i,n){const a=e.behaviorData;if(a.isSurprise)if(a.age+=.016*t,a.age<.15){const i=.98;e.vx*=Math.pow(i,t),e.vy*=Math.pow(i,t)}else if(a.age<.25){const i=.85;e.vx*=Math.pow(i,t),e.vy*=Math.pow(i,t)}else{const i=.99;e.vx*=Math.pow(i,t),e.vy*=Math.pow(i,t),e.vx+=.01*(Math.random()-.5)*t,e.vy+=.01*(Math.random()-.5)*t}else{const i=a.isSuspicion?.99:a.isGlitch?.97:.95;e.vx*=Math.pow(i,t),e.vy*=Math.pow(i,t)}if(a.isSuspicion){const i=.001*Date.now();e.vx+=.01*Math.sin(2*i+e.id)*t}if(a.isGlitch){a.age+=.016*t,a.glitchPhase+=a.glitchFrequency*t;const i=Math.sin(a.glitchPhase)*a.glitchIntensity*t,n=Math.cos(1.3*a.glitchPhase)*a.glitchIntensity*t;if(e.vx+=i,e.vy+=n,Math.random()<.02){const t=Math.random()*Math.PI*2,i=.5+.5*Math.random();e.vx+=Math.cos(t)*i,e.vy+=Math.sin(t)*i}}}},$u={name:"aggressive",emoji:"⚡",description:"Sharp, chaotic movement with violent bursts",initialize:function(e){const t=Math.random()*ku,i=1.5+2*Math.random();e.vx=Math.cos(t)*i,e.vy=Math.sin(t)*i,e.lifeDecay=.015,e.emotionColors&&e.emotionColors.length>0&&(e.color=Uu(e.emotionColors)),e.behaviorData={acceleration:.05,jitter:.3,speedDecay:.95}},update:function(e,t,i,n){const a=e.behaviorData;if(e.vx+=(Math.random()-.5)*a.jitter*t,e.vy+=(Math.random()-.5)*a.jitter*t,e.vx*=Math.pow(a.speedDecay,t),e.vy*=Math.pow(a.speedDecay,t),Math.random()<Math.min(.05*t,.5)){const t=Math.random()*ku;e.vx+=Math.cos(t)*a.acceleration,e.vy+=Math.sin(t)*a.acceleration}}},Zu={name:"scattering",emoji:"😨",description:"Particles flee from center in panic",initialize:function(e){e.vx=0,e.vy=0,e.lifeDecay=.008,e.emotionColors&&e.emotionColors.length>0&&(e.color=Uu(e.emotionColors)),e.behaviorData={fleeSpeed:2,panicFactor:1.2,initialized:!1}},update:function(e,t,i,n){const a=e.behaviorData;if(!a.initialized){const t=e.x-i,r=e.y-n,s=Math.sqrt(t*t+r*r);if(s>0)e.vx=t/s*a.fleeSpeed,e.vy=r/s*a.fleeSpeed;else{const t=Math.random()*ku;e.vx=Math.cos(t)*a.fleeSpeed,e.vy=Math.sin(t)*a.fleeSpeed}a.initialized=!0}const r=e.x-i,s=e.y-n,o=Math.sqrt(r*r+s*s);o>0&&(e.vx+=r/o*a.panicFactor*.01*t,e.vy+=s/o*a.panicFactor*.01*t),e.vx+=.1*(Math.random()-.5)*t,e.vy+=.1*(Math.random()-.5)*t,e.vx*=Math.pow(.98,t),e.vy*=Math.pow(.98,t)}},Ku={name:"repelling",emoji:"🚫",description:"Particles pushed away from center, maintaining distance",initialize:function(e){e.vx=0,e.vy=0,e.lifeDecay=.01,e.emotionColors&&e.emotionColors.length>0&&(e.color=Uu(e.emotionColors)),e.behaviorData={repelStrength:.8,minDistance:50,initialized:!1}},update:function(e,t,i,n){const a=e.behaviorData,r=e.x-i,s=e.y-n,o=Math.sqrt(r*r+s*s);if(!a.initialized||o<a.minDistance){if(o>0){const i=a.repelStrength/Math.max(o,5);e.vx+=r/o*i*t,e.vy+=s/o*i*t}a.initialized=!0}e.vx*=Math.pow(.99,t),e.vy*=Math.pow(.99,t)}},Qu={name:"connecting",emoji:"🔗",description:"Chaotic movement with center attraction for social states",initialize:function(e){const t=Math.random()*ku,i=2+5*Math.random();e.vx=Math.cos(t)*i,e.vy=Math.sin(t)*i,e.lifeDecay=.012,e.emotionColors&&e.emotionColors.length>0&&(e.color=Uu(e.emotionColors)),e.behaviorData={attractionForce:.008,chaosFactor:1,friction:.95}},update:function(e,t,i,n){const a=e.behaviorData;e.vx*=Math.pow(a.friction,t),e.vy*=Math.pow(a.friction,t);const r=(i-e.x)*a.attractionForce,s=(n-e.y)*a.attractionForce,o=(Math.random()-.5)*a.chaosFactor,l=(Math.random()-.5)*a.chaosFactor;e.vx+=r+o,e.vy+=s+l}},Ju={name:"resting",emoji:"😴",description:"Ultra-slow vertical drift for deep rest states",initialize:function(e){e.vx=0,e.vy=-.01,e.lifeDecay=.001,e.emotionColors&&e.emotionColors.length>0&&(e.color=Uu(e.emotionColors)),e.behaviorData={upwardSpeed:2e-5,friction:.999}},update:function(e,t,i,n){const a=e.behaviorData;e.vy*=Math.pow(a.friction,t),e.vy-=a.upwardSpeed*t,e.vx=0}},ed={name:"radiant",emoji:"☀️",description:"Particles radiate outward like sunbeams",initialize:function(e){const t=Math.random()*ku,i=.8+.4*Math.random();if(e.vx=Math.cos(t)*i,e.vy=Math.sin(t)*i,e.lifeDecay=.006,e.emotionColors&&e.emotionColors.length>0)e.color=Uu(e.emotionColors);else{const t=["#FFD700","#FFB347","#FFA500","#FF69B4"];e.color=Uu(t)}e.hasGlow=Math.random()<.7,e.glowSizeMultiplier=e.hasGlow?1.5+.5*Math.random():0,e.behaviorData={radialSpeed:.02,shimmer:Math.random()*ku,shimmerSpeed:.1,friction:.99}},update:function(e,t,i,n){const a=e.behaviorData,r=e.x-i,s=e.y-n,o=Math.sqrt(r*r+s*s);if(o>0){const i=r/o,n=s/o;e.vx+=i*a.radialSpeed*t,e.vy+=n*a.radialSpeed*t}a.shimmer+=a.shimmerSpeed*t;const l=Math.sin(a.shimmer);e.size=e.baseSize*(1+.2*l),e.opacity=e.baseOpacity*(1+.3*l),e.vx*=Math.pow(a.friction,t),e.vy*=Math.pow(a.friction,t)}};function td(e){e.vx=.02*(Math.random()-.5),e.vy=-.03-.02*Math.random(),e.lifeDecay=8e-4,e.size=(6+6*Math.random())*(e.scaleFactor||1)*(e.particleSizeMultiplier||1)*1.33,e.baseSize=e.size,e.baseOpacity=.2+.2*Math.random(),e.emotionColors&&e.emotionColors.length>0&&(e.color=Uu(e.emotionColors)),e.behaviorData={ascensionSpeed:3e-4,waveFactor:.5,waveFrequency:.001,friction:.998,fadeStartDistance:100}}var id={name:"ascending",emoji:"🧘",description:"Slow steady upward float like incense smoke",initialize:td,update:function(e,t,i,n){const a=e.behaviorData;if(!a)return void td(e);e.vx*=Math.pow(a.friction,t),e.vy*=Math.pow(a.friction,t),e.vy-=a.ascensionSpeed*t;const r=Math.sin(e.age*a.waveFrequency*1e3)*a.waveFactor;e.vx+=.001*r*t,void 0===e.initialY&&(e.initialY=e.y);const s=e.initialY-e.y;if(s>a.fadeStartDistance){const t=(s-a.fadeStartDistance)/100,i=Math.max(0,1-t);e.baseOpacity*=.995,i<.5&&(e.lifeDecay*=1.02)}Math.abs(e.vx)>.05&&(e.vx*=Math.pow(.95,t)),e.vy<-.1&&(e.vy=-.1)}},nd={name:"erratic",emoji:"😰",description:"Nervous jittery movement for anxious states",initialize:function(e){const t=Math.random()*ku,i=.1+.15*Math.random();e.vx=Math.cos(t)*i,e.vy=Math.sin(t)*i,e.lifeDecay=.004,e.size=(2+4*Math.random())*(e.scaleFactor||1)*(e.particleSizeMultiplier||1),e.baseSize=e.size,e.baseOpacity=.4+.3*Math.random(),e.emotionColors&&e.emotionColors.length>0&&(e.color=Uu(e.emotionColors)),e.behaviorData={jitterStrength:.02,directionChangeRate:.1,speedVariation:.3,spinRate:.05+.1*Math.random()}},update:function(e,t){const i=e.behaviorData;if(e.vx+=(Math.random()-.5)*i.jitterStrength*t,e.vy+=(Math.random()-.5)*i.jitterStrength*t,Math.random()<Math.min(i.directionChangeRate*t,.5)){const t=Math.random()*ku,i=Math.sqrt(e.vx*e.vx+e.vy*e.vy);e.vx=Math.cos(t)*i,e.vy=Math.sin(t)*i}const n=1+(Math.random()-.5)*i.speedVariation*t;e.vx*=n,e.vy*=n;const a=e.age*i.spinRate*1e3;e.size=e.baseSize*(1+.2*Math.sin(a)),e.opacity=e.baseOpacity*(.8+.4*Math.random()),e.vx*=Math.pow(.98,t),e.vy*=Math.pow(.98,t);const r=Math.sqrt(e.vx*e.vx+e.vy*e.vy);r>.5&&(e.vx=e.vx/r*.5,e.vy=e.vy/r*.5)}},ad={name:"cautious",emoji:"🤨",description:"Slow careful movement with watchful pauses",initialize:function(e){const t=Math.random()*ku,i=.02+.03*Math.random();e.vx=Math.cos(t)*i,e.vy=Math.sin(t)*i,e.lifeDecay=.001,e.life=1,e.size=(4+4*Math.random())*(e.scaleFactor||1)*(e.particleSizeMultiplier||1),e.baseSize=e.size,e.baseOpacity=.8+.2*Math.random(),e.opacity=e.baseOpacity,e.emotionColors&&e.emotionColors.length>0&&(e.color=Uu(e.emotionColors)),e.behaviorData={pauseTimer:2*Math.random(),pauseDuration:.5+.5*Math.random(),moveDuration:1+.5*Math.random(),isMoving:Math.random()>.5,moveTimer:0,originalVx:e.vx,originalVy:e.vy,watchRadius:50+30*Math.random()}},update:function(e,t,i,n){const a=e.behaviorData;if(a.moveTimer+=t,a.isMoving)a.moveTimer>a.moveDuration?(a.isMoving=!1,a.moveTimer=0,e.vx=0,e.vy=0):(e.vx=a.originalVx,e.vy=a.originalVy);else if(a.moveTimer>a.pauseDuration){a.isMoving=!0,a.moveTimer=0;const t=Math.random()*ku,i=.02+.03*Math.random();e.vx=Math.cos(t)*i,e.vy=Math.sin(t)*i,a.originalVx=e.vx,a.originalVy=e.vy}const r=e.x-i,s=e.y-n,o=Math.sqrt(r*r+s*s);if(o>a.watchRadius){const i=.02;e.vx-=r/o*i*t,e.vy-=s/o*i*t}e.vx*=Math.pow(.995,t),e.vy*=Math.pow(.995,t),a.isMoving?e.opacity=e.baseOpacity:e.opacity=e.baseOpacity*(.9+.1*Math.sin(5*e.age))}},rd={name:"surveillance",emoji:"👁️",description:"Searchlight scanning with paranoid watchfulness",initialize(e,t){e.emotionColors&&e.emotionColors.length>0&&(e.color=Uu(e.emotionColors)),e.behaviorState={scanAngle:Math.random()*Math.PI-Math.PI/2,scanDirection:Math.random()<.5?1:-1,scanSpeed:.3+.2*Math.random(),scanRange:Math.PI/3+Math.random()*Math.PI/4,scanCenter:Math.random()*Math.PI*2,pauseTimer:0,pauseDuration:500+500*Math.random(),mode:"scanning",modeTimer:0,nextModeChange:2e3+3e3*Math.random(),dartTarget:{x:0,y:0},dartSpeed:0,patrolRadius:150+100*Math.random(),patrolAngle:Math.random()*Math.PI*2,alertLevel:0,lastPosition:{x:e.x,y:e.y}};const i=Math.random();i<.7?e.behaviorState.primaryRole="scanner":i<.9?(e.behaviorState.primaryRole="patroller",e.behaviorState.mode="patrolling"):(e.behaviorState.primaryRole="watcher",e.behaviorState.mode="frozen")},update(e,t,i){const n=e.behaviorState;if(n){switch(n.modeTimer+=16*t,n.modeTimer>n.nextModeChange&&(this.changeMode(e,n,i),n.modeTimer=0,n.nextModeChange=2e3+4e3*Math.random()),n.mode){case"scanning":this.updateScanning(e,t,n,i);break;case"darting":this.updateDarting(e,t,n,i);break;case"frozen":this.updateFrozen(e,t,n,i);break;case"patrolling":this.updatePatrolling(e,t,n,i)}e.vy+=.05*t,e.x+=e.vx*t,e.y+=e.vy*t,n.lastPosition.x=e.x,n.lastPosition.y=e.y}},updateScanning(e,t,i,n){i.pauseTimer>0?(i.pauseTimer-=16*t,e.vx*=.9,e.vy*=.9):(i.scanAngle+=i.scanDirection*i.scanSpeed*t*.02,Math.abs(i.scanAngle)>i.scanRange/2&&(i.scanDirection*=-1,i.pauseTimer=i.pauseDuration,i.scanAngle=Math.sign(i.scanAngle)*i.scanRange/2));const a=i.scanCenter+i.scanAngle,r=.8+.5*i.alertLevel;e.vx=Math.cos(a)*r,e.vy=Math.sin(a)*r*.3},updateDarting(e,t,i,n){const a=i.dartTarget.x-e.x,r=i.dartTarget.y-e.y,s=Math.sqrt(a*a+r*r);s>5?(e.vx=a/s*i.dartSpeed,e.vy=r/s*i.dartSpeed):(i.mode="scanning",i.modeTimer=0)},updateFrozen(e,t,i,n){e.vx*=.95,e.vy*=.95,Math.random()<.01&&(e.vx+=.5*(Math.random()-.5),e.vy+=.5*(Math.random()-.5))},updatePatrolling(e,t,i,n){i.patrolAngle+=.01*t;const a=n.corePosition?.x??n.canvasWidth/2,r=n.corePosition?.y??n.canvasHeight/2,s=a+Math.cos(i.patrolAngle)*i.patrolRadius,o=r+Math.sin(i.patrolAngle)*i.patrolRadius,l=s-e.x,h=o-e.y;e.vx=.02*l,e.vy=.02*h},changeMode(e,t,i){const n=Math.random(),a=i?.corePosition?.x??(i?.canvasWidth/2||e.x),r=i?.corePosition?.y??(i?.canvasHeight/2||e.y);"scanner"===t.primaryRole?n<.1?(t.mode="darting",t.dartTarget={x:a+200*(Math.random()-.5),y:r+200*(Math.random()-.5)},t.dartSpeed=3+2*Math.random()):t.mode=n<.2?"frozen":"scanning":"patroller"===t.primaryRole?t.mode=n<.1?"frozen":"patrolling":t.mode=n<.3?"scanning":"frozen"}},sd={name:"glitchy",emoji:"⚡",description:"Digital glitch with stuttering orbits and corruption",rhythm:{enabled:!0,glitchTiming:{mode:"subdivision",subdivision:"sixteenth",probability:.3,intensityOnBeat:2,intensityOffBeat:.5},stutterSync:{mode:"pattern",patterns:{dubstep:{freezeOnDrop:!0,dropDuration:100},breakbeat:{randomFreeze:.1,duration:50}}},orbitRhythm:{baseSpeed:"tempo",wobbleSync:"eighth",beatAcceleration:1.5,barReset:!0},rgbSync:{enabled:!0,amount:"intensity",direction:"beat",maxSplit:10},noiseRhythm:{trigger:"accent",duration:50,intensity:"drop"}},initialize(e,t,i,n){e.emotionColors&&e.emotionColors.length>0&&(e.color=Uu(e.emotionColors)),e.behaviorState={orbitAngle:Math.random()*Math.PI*2,orbitRadius:300+400*Math.random(),orbitSpeed:.01+.02*Math.random(),glitchTimer:0,nextGlitch:500*Math.random()+100,isGlitching:!1,glitchDuration:0,glitchOffset:{x:0,y:0},stutterTimer:0,nextStutter:200*Math.random()+50,isFrozen:!1,frozenPosition:{x:0,y:0},frozenVelocity:{x:0,y:0},hasGhost:Math.random()<.3,ghostOffset:20*Math.random()+10,ghostAngle:Math.random()*Math.PI*2,rgbSplit:Math.random()<.4,rgbPhase:Math.random()*Math.PI*2,noiseLevel:0,noiseBurst:!1,beatPhase:Math.random()*Math.PI*2,beatFrequency:.05+.03*Math.random(),dropIntensity:0},e.lifeDecay=.0015,e.hasGlow=!0,e.glowSizeMultiplier=3+2*Math.random()},update(e,t,i,n){const a=e.behaviorState;if(!a)return;a.glitchTimer+=16*t,a.stutterTimer+=16*t,a.stutterTimer>a.nextStutter&&(a.isFrozen?(a.isFrozen=!1,a.stutterTimer=0,a.nextStutter=100+300*Math.random(),Math.random()<.3&&(e.x+=60*(Math.random()-.5),e.y+=60*(Math.random()-.5))):(a.isFrozen=!0,a.frozenPosition={x:e.x,y:e.y},a.frozenVelocity={x:e.vx,y:e.vy},a.stutterTimer=0,a.nextStutter=20+40*Math.random())),a.glitchTimer>a.nextGlitch&&!a.isGlitching&&(a.isGlitching=!0,a.glitchDuration=50+100*Math.random(),a.glitchOffset={x:80*(Math.random()-.5),y:80*(Math.random()-.5)},a.glitchTimer=0,Math.random()<.5&&e.emotionColors&&(e.color=Uu(e.emotionColors))),a.isGlitching&&a.glitchTimer>a.glitchDuration&&(a.isGlitching=!1,a.glitchTimer=0,a.nextGlitch=200+800*Math.random(),a.glitchOffset={x:0,y:0}),a.beatPhase+=a.beatFrequency*t;const r=.5*Math.sin(a.beatPhase)+.5;if(a.beatPhase%(4*Math.PI)<.5*Math.PI?a.dropIntensity=Math.min(1,a.dropIntensity+.1*t):a.dropIntensity=Math.max(0,a.dropIntensity-.05*t),a.isFrozen)e.vx=.5*(Math.random()-.5),e.vy=.5*(Math.random()-.5);else{a.orbitAngle+=a.orbitSpeed*t*(1+.5*r);const s=a.orbitRadius*(1+.3*a.dropIntensity*Math.sin(4*a.beatPhase));let o=i+Math.cos(a.orbitAngle)*s,l=n+Math.sin(a.orbitAngle)*s*.6;if(a.isGlitching&&(o+=a.glitchOffset.x*Math.random()*.8,l+=a.glitchOffset.y*Math.random()*.8),a.rgbSplit){const e=3*(1+a.dropIntensity);o+=Math.sin(a.rgbPhase)*e,l+=Math.cos(a.rgbPhase)*e,a.rgbPhase+=.1*t}a.dropIntensity>.8&&Math.random()<.1&&(o+=30*(Math.random()-.5),l+=30*(Math.random()-.5));const h=a.isGlitching?.02:.03;e.vx=(o-e.x)*h,e.vy=(l-e.y)*h,e.vx+=(Math.random()-.5)*r*2,e.vy+=(Math.random()-.5)*r*2}e.x+=e.vx*t,e.y+=e.vy*t,Math.random()<.02&&(e.opacity=.1+.9*Math.random()),e.size=e.baseSize*(1+.3*r+.5*a.dropIntensity)}},od={name:"spaz",description:"Ultra-aggressive particles with explosive spread and chaotic motion",initialize(e,t,i,n){e.x=i,e.y=n,e.life=1,e.size=3+4*Math.random();const a=Math.random()*Math.PI*2,r=200+300*Math.random();e.vx=Math.cos(a)*r,e.vy=Math.sin(a)*r,e.behaviorState={explosionPhase:0,explosionTimer:0,explosionDuration:1e3+2e3*Math.random(),chaosTimer:0,nextChaosChange:100+200*Math.random(),chaosAngle:a,chaosSpeed:50+100*Math.random(),spazIntensity:.8+.4*Math.random(),zigzagPattern:Math.random()<.5,spiralPattern:Math.random()<.3,teleportChance:.02,sizePulse:!0,sizePulseSpeed:.1+.05*Math.random(),sizePulsePhase:Math.random()*Math.PI*2,colorShift:Math.random()<.3,colorShiftSpeed:.05+.03*Math.random()},e.lifeDecay=8e-4,e.hasGlow=!0,e.glowSizeMultiplier=4+3*Math.random(),e.glowIntensity=1.5+.5*Math.random()},update(e,t,i,n){const a=e.behaviorState;if(a.explosionTimer+=t,a.chaosTimer+=t,0===a.explosionPhase&&a.explosionTimer<500)e.vx*=.98,e.vy*=.98,Math.random()<.1&&(e.vx+=100*(Math.random()-.5),e.vy+=100*(Math.random()-.5));else if(0===a.explosionPhase&&a.explosionTimer>=500)a.explosionPhase=1,a.chaosAngle=Math.random()*Math.PI*2,a.chaosSpeed=30+70*Math.random();else if(1===a.explosionPhase){a.chaosTimer>=a.nextChaosChange&&(a.chaosAngle=Math.random()*Math.PI*2,a.chaosSpeed=20+80*Math.random(),a.nextChaosChange=50+150*Math.random(),a.chaosTimer=0);const t=Math.cos(a.chaosAngle)*a.chaosSpeed,i=Math.sin(a.chaosAngle)*a.chaosSpeed;if(e.vx=.7*e.vx+.3*t,e.vy=.7*e.vy+.3*i,a.zigzagPattern){const t=.01*a.chaosTimer;e.vx+=20*Math.sin(t),e.vy+=20*Math.cos(t)}if(a.spiralPattern){const t=.005*a.chaosTimer,i=50+30*Math.sin(.003*a.chaosTimer);e.vx+=Math.cos(t)*i*.1,e.vy+=Math.sin(t)*i*.1}}if(Math.random()<a.teleportChance){const t=Math.random()*Math.PI*2,a=200+400*Math.random();e.x=i+Math.cos(t)*a,e.y=n+Math.sin(t)*a,e.vx=200*(Math.random()-.5),e.vy=200*(Math.random()-.5)}if(e.x+=e.vx*(t/1e3),e.y+=e.vy*(t/1e3),a.sizePulse){a.sizePulsePhase+=a.sizePulseSpeed*t;const i=1+.5*Math.sin(a.sizePulsePhase);e.size=(3+4*Math.random())*i}a.colorShift&&(a.colorShiftPhase=(a.colorShiftPhase||0)+a.colorShiftSpeed*t),e.vx*=.995,e.vy*=.995,e.life-=e.lifeDecay*t,(e.life<=0||Math.abs(e.x-i)>2e3||Math.abs(e.y-n)>2e3)&&(e.life=0)},getSpawnPosition(e,t){const i=Math.random()*Math.PI*2,n=100+200*Math.random();return{x:e+Math.cos(i)*n,y:t+Math.sin(i)*n}},getVisualProperties:()=>({glowColor:"#FF00AA",glowIntensity:2,particleColors:[{color:"#FF00AA",weight:30},{color:"#00FFAA",weight:25},{color:"#FFAA00",weight:20},{color:"#AA00FF",weight:15},{color:"#00AAFF",weight:10}]})},ld={name:"directed",emoji:"🎯",description:"Focused, straight-line movement toward target",config:{speed:3,acceleration:.15,focusStrength:.8,randomness:.1,edgeBuffer:50},initialize(e,t,i,n,a){const r=t-e.x,s=i-e.y,o=Math.sqrt(r*r+s*s);if(o>0)e.vx=r/o*this.config.speed,e.vy=s/o*this.config.speed;else{const t=Math.random()*Math.PI*2;e.vx=Math.cos(t)*this.config.speed,e.vy=Math.sin(t)*this.config.speed}e.targetX=t,e.targetY=i,e.directedPhase=0},update(e,t,i,n,a,r){e.directedPhase+=.05*t;const s=e.targetX-e.x,o=e.targetY-e.y,l=Math.sqrt(s*s+o*o);if(l>10){const i=s/l*this.config.speed,n=o/l*this.config.speed;e.vx+=(i-e.vx)*this.config.acceleration*t,e.vy+=(n-e.vy)*this.config.acceleration*t,e.vx+=(Math.random()-.5)*this.config.randomness,e.vy+=(Math.random()-.5)*this.config.randomness}else{const t=Math.random()*Math.PI*2,s=100+200*Math.random();e.targetX=i+Math.cos(t)*s,e.targetY=n+Math.sin(t)*s,e.targetX=Math.max(this.config.edgeBuffer,Math.min(a-this.config.edgeBuffer,e.targetX)),e.targetY=Math.max(this.config.edgeBuffer,Math.min(r-this.config.edgeBuffer,e.targetY))}e.x+=e.vx*t,e.y+=e.vy*t,(e.x<=0||e.x>=a)&&(e.vx*=-.8,e.x=Math.max(0,Math.min(a,e.x)),e.targetX=i+300*(Math.random()-.5)),(e.y<=0||e.y>=r)&&(e.vy*=-.8,e.y=Math.max(0,Math.min(r,e.y)),e.targetY=n+300*(Math.random()-.5))},visuals:{trailLength:"medium",opacity:.9,sizeMultiplier:1,blurAmount:.2}},hd={name:"fizzy",emoji:"🫧",description:"Bubbly, effervescent movement like carbonation",config:{baseRiseSpeed:2.5,wobbleAmplitude:30,wobbleFrequency:.15,popChance:.002,popForce:8,fizziness:.3,gravity:-.05},initialize(e,t,i,n,a){e.vx=2*(Math.random()-.5),e.vy=-this.config.baseRiseSpeed-2*Math.random(),e.wobblePhase=Math.random()*Math.PI*2,e.wobbleSpeed=this.config.wobbleFrequency*(.8+.4*Math.random()),e.bubbleSize=.5+.5*Math.random(),e.popTimer=0,e.isFizzing=!0},update(e,t,i,n,a,r){e.wobblePhase+=e.wobbleSpeed*t;const s=Math.sin(e.wobblePhase)*this.config.wobbleAmplitude;if(e.vx=.05*s+(Math.random()-.5)*this.config.fizziness,e.vy+=this.config.gravity*t,e.vy+=(Math.random()-.5)*this.config.fizziness,Math.random()<this.config.popChance){const t=Math.random()*Math.PI*2;e.vx=Math.cos(t)*this.config.popForce,e.vy=Math.sin(t)*this.config.popForce*.7,e.popTimer=1,e.bubbleSize=.3+.7*Math.random()}e.popTimer>0&&(e.popTimer-=.05*t,e.vx*=.95,e.vy*=.95),e.x+=e.vx*t,e.y+=e.vy*t,e.y<-50&&(e.y=r+50,e.x=i+300*(Math.random()-.5),e.vy=-this.config.baseRiseSpeed-2*Math.random(),e.bubbleSize=.5+.5*Math.random()),(e.x<=0||e.x>=a)&&(e.vx*=-.5,e.x=Math.max(0,Math.min(a,e.x))),e.y>r+50&&(e.y=r,e.vy=1.5*-this.config.baseRiseSpeed),e.size=e.baseSize*e.bubbleSize*(1+.1*Math.sin(2*e.wobblePhase))},visuals:{trailLength:"short",opacity:.6,sizeMultiplier:1.2,blurAmount:.5,sparkle:!0}};var cd={name:"zen",emoji:"☯️",description:"Peaceful orbital movement like a hovering aura",initialize:function(e){e.vx=.5*(Math.random()-.5),e.vy=.5*(Math.random()-.5),e.lifeDecay=.003,e.emotionColors&&e.emotionColors.length>0&&(e.color=Uu(e.emotionColors)),e.behaviorData={orbitAngle:Math.random()*Math.PI*2,orbitRadius:40+60*Math.random(),orbitSpeed:8e-4+6e-4*Math.random(),floatOffset:Math.random()*Math.PI*2,breathingOffset:Math.random()*Math.PI*2,lifetime:0}},update:function(e,t,i,n){const a=e.behaviorData;if(!a)return;a.lifetime+=t;const r=(a.lifetime+8e3*a.breathingOffset)/8e3,s=.5*Math.sin(r*Math.PI*2)+.5;e.size=e.baseSize*(.95+.05*s),a.orbitAngle+=a.orbitSpeed*t;const o=10*Math.sin(1e-4*a.lifetime+a.floatOffset),l=a.orbitRadius+o,h=i+Math.cos(a.orbitAngle)*l,c=n+Math.sin(a.orbitAngle)*l,u=15*Math.sin(3e-4*a.lifetime+a.breathingOffset),d=h-e.x,p=c+u-e.y;e.vx=.03*d,e.vy=.03*p,e.vx+=.02*(Math.random()-.5),e.vy+=.02*(Math.random()-.5),e.vx*=.98,e.vy*=.98}};const ud=new Map;var dd=function(e){return ud.get(e)||null},pd=function(){return Array.from(ud.keys())};const md={};function fd(e){if(md[e])return md[e];return dd(e)||null}function gd(e,t){const i=fd(t);return i&&i.initialize?(i.initialize(e),!0):"ambient"!==t&&(console.warn(`⚠️ Behavior '${t}' not found, falling back to ambient`),gd(e,"ambient"))}function vd(e,t,i,n,a){const r=fd(t);return!(!r||!r.update||(r.update(e,i,n,a),0))}[zu,ld,hd,Nu,Gu,Vu,qu,Yu,$u,Zu,Ku,Qu,Ju,ed,id,nd,ad,rd,sd,od,cd].forEach(e=>{md[e.name]=e}),"undefined"!=typeof window&&window.DEBUG_PARTICLES&&(window.ParticleBehaviors={registry:md,list:function(){return[...Object.values(md).map(e=>({name:e.name,emoji:e.emoji||"🎯",description:e.description||"No description",type:"core"})),...pd().map(e=>{const t=dd(e);return{name:t.name,emoji:t.emoji||"🔌",description:t.description||"Plugin behavior",type:"plugin"}})]},get:fd});class yd{constructor(e,t,i="ambient",n=1,a=1,r=null){const s=Math.random();this.z=s<1/13?.5+.5*Math.random():.9*Math.random()-1;const o=this.z>0?(20+20*Math.random())*n:3*n,l=Math.random()*Math.PI*2;this.x=e+Math.cos(l)*o,this.y=t+Math.sin(l)*o,this.vx=0,this.vy=0,this.vz=0,this.life=0,this.maxLife=1,this.lifeDecay=.01,this.fadeInTime=.15,this.fadeOutTime=.3,this.isFadingOut=!1,this.age=0,this.scaleFactor=n,this.particleSizeMultiplier=a,this.size=(4+6*Math.random())*n*a,this.baseSize=this.size,this.emotionColors=r,this.color="#ffffff",this.opacity=1,this.hasGlow=Math.random()<.333,this.glowSizeMultiplier=this.hasGlow?1.33+.33*Math.random():0,this.isCellShaded=Math.random()<.333,this.baseOpacity=.3+.4*Math.random(),this.cachedColors=new Map,this.maxCachedColors=20,this.colorAccessOrder=[],this.lastColor=null,this.lastOpacity=-1,this.behavior=i,this.behaviorData={},this.gestureData={initialX:e,initialY:t},gd(this,i)}update(e,t,i,n=null,a=null,r=0,s=null){const o=Math.min(e,50)/16.67,l=a&&a.type&&r>0&&function(e){const t=Pu(e);return!!t&&"override"===t.type}(a.type);let h,c;if(l?this.applyGestureMotion(a,r,o,t,i):"falling"===this.gestureBehavior?vd(this,"falling",o,t,i):"radiant"===this.gestureBehavior?vd(this,"radiant",o,t,i):(vd(this,this.behavior,o,t,i),a&&r>0&&this.applyGestureMotion(a,r,o,t,i)),l||(this.x+=this.vx*o,this.y+=this.vy*o),s)h=s.width,c=s.height;else{const e=document.getElementById("card-mascot")||document.getElementById("cherokee-guide-mascot")||document.querySelector("canvas");h=e?e.width:2*t,c=e?e.height:2*i}const u=t-h/2+20,d=t+h/2-20,p=i-c/2+20,m=i+c/2-20;this.x-this.size<u?(this.x=u+this.size,this.vx=.5*Math.abs(this.vx)):this.x+this.size>d&&(this.x=d-this.size,this.vx=.5*-Math.abs(this.vx)),this.y-this.size<p?(this.y=p+this.size,this.vy=.5*Math.abs(this.vy)):this.y+this.size>m&&(this.y=m-this.size,this.vy=.5*-Math.abs(this.vy)),this.age+=this.lifeDecay*o,this.age<this.fadeInTime?this.life=this.age/this.fadeInTime:this.age<1-this.fadeOutTime?this.life=1:(this.life=(1-this.age)/this.fadeOutTime,this.isFadingOut=!0,"popcorn"===this.behavior&&(this.size=this.baseSize*(.5+.5*this.life))),this.life=Math.max(0,Math.min(1,this.life)),"falling"===this.behavior?this.opacity=this.life:this.opacity=this.easeInOutCubic(this.life),"burst"===this.behavior&&this.behaviorData&&this.life<this.behaviorData.fadeStart&&(this.size=this.baseSize*(this.life/this.behaviorData.fadeStart))}applyUndertoneModifier(e,t){}applyGestureMotion(e,t,i,n,a){!function(e,t,i,n,a,r){if(!i||!i.type||n>=1)return;e.gestureData||(e.gestureData={originalVx:e.vx,originalVy:e.vy,initialX:e.x,initialY:e.y,startAngle:Math.atan2(e.y-r,e.x-a),startRadius:Math.sqrt(Math.pow(e.x-a,2)+Math.pow(e.y-r,2))});const s=Pu(i.type);if(!s)return;let o=i;if(Ou.isEnabled()&&s.rhythm?.enabled){const a=Ou.applyGestureRhythm(s,e,n,t);o={...i,amplitude:(i.amplitude||1)*(a.amplitudeMultiplier||1)*(a.accentMultiplier||1),wobbleAmount:(i.wobbleAmount||0)*(a.wobbleMultiplier||1),rhythmModulation:a}}s.apply&&s.apply(e,n,o,t,a,r),n>=.99&&s.cleanup&&(s.cleanup(e),e.gestureData=null)}(this,i,e,t,n,a)}isOutOfBounds(e,t){return this.x<-50||this.x>e+50||this.y<-50||this.y>t+50}isAlive(){return this.life>0}setOutwardVelocity(e){if(this.behaviorData&&void 0!==this.behaviorData.outwardSpeed){const t=this.behaviorData.outwardSpeed;this.vx=Math.cos(e)*t,this.vy=Math.sin(e)*t+(this.behaviorData.upwardBias||0)}}getDepthAdjustedSize(){const e=1+.2*this.z;return this.size*e}getState(){return{position:{x:this.x,y:this.y,z:this.z},velocity:{x:this.vx,y:this.vy,z:this.vz},life:this.life,behavior:this.behavior,size:this.size,opacity:this.opacity}}reset(e,t,i="ambient",n=1,a=1,r=null){const s=Math.random();this.z=s<1/13?.5+.5*Math.random():.9*Math.random()-1;const o=this.z>0?(20+20*Math.random())*n:3*n,l=Math.random()*Math.PI*2;if(this.x=e+Math.cos(l)*o,this.y=t+Math.sin(l)*o,this.vx=0,this.vy=0,this.vz=0,this.life=0,this.age=0,this.scaleFactor=n,this.particleSizeMultiplier=a,this.size=(4+6*Math.random())*n*a,this.baseSize=this.size,this.emotionColors=r,this.cachedColors.clear(),this.colorAccessOrder=[],this.opacity=0,this.isFadingOut=!1,this.baseOpacity=.3+.4*Math.random(),this.color="#ffffff",this.behavior=i,this.gestureData=null,this.behaviorData)for(const e in this.behaviorData)delete this.behaviorData[e];else this.behaviorData={};gd(this,i)}getCachedColor(e,t){const i=Math.round(100*t)/100,n=`${e}_${i}`;if(this.cachedColors.has(n)){const e=this.colorAccessOrder.indexOf(n);-1!==e&&this.colorAccessOrder.splice(e,1),this.colorAccessOrder.push(n)}else{if(this.cachedColors.size>=this.maxCachedColors){const e=this.colorAccessOrder.shift();this.cachedColors.delete(e)}this.cachedColors.set(n,this.hexToRgba(e,i)),this.colorAccessOrder.push(n)}return this.cachedColors.get(n)}hexToRgba(e,t){const i=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return i?`rgba(${parseInt(i[1],16)}, ${parseInt(i[2],16)}, ${parseInt(i[3],16)}, ${t})`:`rgba(255, 255, 255, ${t})`}easeInOutCubic(e){return e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2}render(e,t="#ffffff"){if(this.life<=0)return;if(!isFinite(this.x)||!isFinite(this.y))return;const i=this.x,n=this.y,a=Math.max(.1,this.size),r=this.tempColor||this.color||t;if(e.save(),this.isCellShaded){e.strokeStyle=this.getCachedColor(r,.9*this.opacity),e.lineWidth=2,e.beginPath(),e.arc(i,n,a,0,2*Math.PI),e.stroke();const t=Math.floor(3*this.opacity)/3;e.fillStyle=this.getCachedColor(r,t*(this.baseOpacity||.5)*.5),e.beginPath(),e.arc(i,n,Math.max(.1,a-1),0,2*Math.PI),e.fill(),t>.5&&(e.fillStyle=this.getCachedColor("#FFFFFF",.3),e.beginPath(),e.arc(i-.3*a,n-.3*a,.3*a,0,2*Math.PI),e.fill())}else{const t=e.createRadialGradient(i,n,0,i,n,a);if(t.addColorStop(0,this.getCachedColor(r,this.opacity*(this.baseOpacity||.5))),t.addColorStop(.5,this.getCachedColor(r,this.opacity*(this.baseOpacity||.5)*.5)),t.addColorStop(1,this.getCachedColor(r,0)),e.fillStyle=t,e.beginPath(),e.arc(i,n,a,0,2*Math.PI),e.fill(),this.hasGlow&&this.glowSizeMultiplier>0){const t=a*this.glowSizeMultiplier,s=e.createRadialGradient(i,n,.5*a,i,n,t),o=.3,l=Math.max(o,this.opacity),h=Math.min(1,this.glowSizeMultiplier/3);s.addColorStop(0,this.getCachedColor(r,Math.max(.5,.8*l)*h)),s.addColorStop(.25,this.getCachedColor(r,Math.max(.3,.6*l)*h)),s.addColorStop(.5,this.getCachedColor(r,Math.max(.2,.4*l)*h)),s.addColorStop(.75,this.getCachedColor(r,Math.max(.1,.2*l)*h)),s.addColorStop(1,this.getCachedColor(r,0)),e.save(),e.globalCompositeOperation="screen",e.fillStyle=s,e.beginPath(),e.arc(i,n,t,0,2*Math.PI),e.fill(),e.restore()}}e.restore()}}class bd{constructor(e=50){this.poolSize=Math.min(e,50),this.pool=[],this.totalParticlesCreated=0,this.totalParticlesDestroyed=0,this.poolHits=0,this.poolMisses=0}getParticle(e,t,i,n,a,r,s,o=null){let l;return this.pool.length>0?(l=this.pool.pop(),l.reset(e,t,i,n,a,r),this.poolHits++):(l=new yd(e,t,i,n,a,r),this.poolMisses++,this.totalParticlesCreated++),l.emotion=s,o&&(l.gestureBehavior=o),l}returnParticle(e){if(this.pool.length<this.poolSize){if(e.cachedGradient=null,e.cachedGradientKey=null,e.behaviorData)for(const t in e.behaviorData)delete e.behaviorData[t];this.pool.push(e)}else this.totalParticlesDestroyed++}refreshPool(){const e=this.pool.length-this.poolSize;e>0&&(this.pool.splice(this.poolSize),this.totalParticlesDestroyed+=e)}getStats(){return{poolSize:this.pool.length,poolHits:this.poolHits,poolMisses:this.poolMisses,totalCreated:this.totalParticlesCreated,totalDestroyed:this.totalParticlesDestroyed}}clear(){this.pool=[],this.poolHits=0,this.poolMisses=0,this.totalParticlesCreated=0,this.totalParticlesDestroyed=0}}class Md{constructor(){this.spawnAccumulator=0}getSpawnPosition(e,t,i,n,a,r=null){const s=Math.min(n,a)/12,o=2.5*s,l=1.1*o,h=Math.min(t-30,n-t-30),c=Math.min(i-30,a-i-30),u=Math.min(1.5*o,h,c);switch(e){case"ambient":case"resting":{const e=Math.random()*Math.PI*2,n=.9*o;return{x:t+Math.cos(e)*n,y:i+Math.sin(e)*n,angle:e}}case"rising":{const e=Math.random()*Math.PI*2,n=l+Math.random()*(u-l);return{x:t+Math.cos(e)*n,y:i+Math.sin(e)*n}}case"falling":{const e=Math.random()*Math.PI*2,n=.9*o;return{x:t+Math.cos(e)*n,y:i+Math.sin(e)*n,angle:e}}case"aggressive":{const e=Math.random()*Math.PI*2,n=o+Math.random()*s;return{x:t+Math.cos(e)*n,y:i+Math.sin(e)*n}}case"scattering":default:return{x:t,y:i};case"burst":{const e=Math.random()*Math.PI*2;if("suspicion"===r){const n=1.5*s;return{x:t+Math.cos(e)*n,y:i+Math.sin(e)*n}}if("surprise"===r){const n=1.2*s;return{x:t+Math.cos(e)*n,y:i+Math.sin(e)*n}}return{x:t,y:i}}case"repelling":{const e=Math.random()*Math.PI*2,n=.9*o;return{x:t+Math.cos(e)*n,y:i+Math.sin(e)*n}}case"orbiting":{const e=Math.random()*Math.PI*2,n=1.2*o+Math.random()*o*.5;return{x:t+Math.cos(e)*n,y:i+Math.sin(e)*n}}case"glitchy":{const e=Math.random()*Math.PI*2,n=3*o+Math.random()*o*4;return{x:t+Math.cos(e)*n,y:i+Math.sin(e)*n}}case"spaz":{const e=Math.random()*Math.PI*2,n=2*o+Math.random()*o*3;return{x:t+Math.cos(e)*n,y:i+Math.sin(e)*n}}}}clampToCanvas(e,t,i,n,a=30){return{x:Math.max(a,Math.min(i-a,e)),y:Math.max(a,Math.min(n-a,t))}}calculateSpawnRate(e,t){if(e<=0)return 0;const i=Math.min(t,50),n=e/1e3;this.spawnAccumulator+=n*i,this.spawnAccumulator=Math.min(this.spawnAccumulator,3);let a=0;for(;this.spawnAccumulator>=1;)a++,this.spawnAccumulator-=1;return a}resetAccumulator(){this.spawnAccumulator=0}}class _d{render(e,t,i="#ffffff",n=null){const a=[];for(const e of t)e.life<=0||a.push(e);this._renderParticles(e,a,i,n)}renderLayer(e,t,i="#ffffff",n=!1,a=null){const r=[],s=e.canvas.width,o=e.canvas.height;for(const e of t)e.z>=0===n&&(e.x<-50||e.x>s+50||e.y<-50||e.y>o+50||e.life<=0||r.push(e));return r.sort((e,t)=>e.isCellShaded!==t.isCellShaded?e.isCellShaded?-1:1:e.hasGlow!==t.hasGlow?e.hasGlow?-1:1:0),this._renderParticles(e,r,i,a),r}_renderParticles(e,t,i,n=null){e.save();let a=null;for(const r of t)if(r.isCellShaded)r.render(e,i),a=null;else{const t=r.color||i;if(t!==a&&(e.fillStyle=t,a=t),!isFinite(r.x)||!isFinite(r.y))continue;const s=r.getDepthAdjustedSize?r.getDepthAdjustedSize():r.size;let o=Math.max(.1,s),l=1;if(n&&n.fireflyEffect){const e=(.01*r.x+.01*r.y+.1*r.size)%(2*Math.PI),t=n.fireflyTime||.001*Date.now(),i=n.particleGlow||2;l=.3+Math.max(0,Math.sin(3*t+e))*i}if(n&&n.flickerEffect){const e=(.02*r.x+.02*r.y)%(2*Math.PI),t=n.flickerTime||.001*Date.now(),i=n.particleGlow||2;l=.5+Math.sin(12*t+e)*i*.5}if(n&&n.shimmerEffect){const t=r.x-e.canvas.width/2,i=r.y-e.canvas.height/2,a=Math.sqrt(t*t+i*i)/200,s=n.shimmerTime||.001*Date.now(),o=n.shimmerWave||0,h=n.particleGlow||1.2;l=1+.15*Math.sin(3*s-a+o)*h}if(n&&n.glowEffect){const t=n.glowProgress||0,i=n.particleGlow||2,a=r.x-e.canvas.width/2,s=r.y-e.canvas.height/2,l=Math.sqrt(a*a+s*s)/300,h=Math.min(.3*l,.5),c=Math.max(0,(t-h)/(1-h)),u=Math.sin(c*Math.PI);r._originalGlow||(r._originalGlow={hasGlow:r.hasGlow,glowSizeMultiplier:r.glowSizeMultiplier||0}),r.hasGlow=!0,r.glowSizeMultiplier=Math.max(3,r._originalGlow.glowSizeMultiplier)+u*i*3,o*=1+.3*u,t>=.99&&r._originalGlow&&(r.hasGlow=r._originalGlow.hasGlow,r.glowSizeMultiplier=r._originalGlow.glowSizeMultiplier,delete r._originalGlow)}if(r.hasGlow||l>1){const t=Math.max(.1,o*(r.glowSizeMultiplier||1.5)*l),i=e.globalCompositeOperation;e.globalCompositeOperation="screen",e.globalAlpha=.15*r.opacity*l,e.beginPath(),e.arc(r.x,r.y,t,0,2*Math.PI),e.fill(),e.globalAlpha=.25*r.opacity*l,e.beginPath(),e.arc(r.x,r.y,.6*t,0,2*Math.PI),e.fill(),e.globalCompositeOperation=i}e.globalAlpha=r.opacity*(r.baseOpacity||.5)*.6*Math.min(2,l),e.beginPath(),e.arc(r.x,r.y,o,0,2*Math.PI),e.fill()}e.restore()}}class xd{constructor(e=50,t=null){this.errorBoundary=t,this.maxParticles=e,this.absoluteMaxParticles=2*e,this.particles=[],this.particlePool=new bd(e),this.particleSpawner=new Md,this.particleRenderer=new _d,this.containmentBounds=null,this.stateChangeCount=0,this.lastMemoryCheck=Date.now(),this.lastLeakedCount=0,this.particleCount=0,this.cleanupTimer=0,this.cleanupInterval=5e3}get pool(){return this.particlePool.pool}get poolSize(){return this.particlePool.poolSize}get poolHits(){return this.particlePool.poolHits}get poolMisses(){return this.particlePool.poolMisses}get totalParticlesCreated(){return this.particlePool.totalParticlesCreated}get totalParticlesDestroyed(){return this.particlePool.totalParticlesDestroyed}get spawnAccumulator(){return this.particleSpawner.spawnAccumulator}set spawnAccumulator(e){this.particleSpawner.spawnAccumulator=e}getParticleFromPool(e,t,i){return this.particlePool.getParticle(e,t,i,this.scaleFactor||1,this.particleSizeMultiplier||1,this.currentEmotionColors,this.currentEmotion,this.gestureBehavior)}returnParticleToPool(e){this.particlePool.returnParticle(e)}spawn(e,t,i,n,a,r,s=null,o=0,l=10,h=1,c=1,u=null,d=null){if(this.scaleFactor=h,this.particleSizeMultiplier=c,this.errorBoundary)return this.errorBoundary.wrap(()=>{this._spawn(e,t,i,n,a,r,s,o,l,u,d)},"particle-spawn")();this._spawn(e,t,i,n,a,r,s,o,l,u,d)}resetAccumulator(){this.particleSpawner.resetAccumulator()}_spawn(e,t,i,n,a,r,s,o=0,l=10,h=null,c=null){this.currentEmotion=t,this.baseEmotionColors=h,this.currentUndertone=c,this.currentEmotionColors=h&&c?function(e,t){return e&&Array.isArray(e)&&t&&"clear"!==t?e.map(e=>"string"==typeof e?Bu(e,t):e&&"object"==typeof e&&e.color?{...e,color:Bu(e.color,t)}:e):e}(h,c):h;let u=i;if(Ou.isEnabled()){const i=Fu&&Fu.isInitialized?Fu.getEmotion(t):Tc(t);if(i){const t=Ou.applyParticleRhythm(i,this);if(t.emitBurst)for(let i=0;i<t.emitBurst&&this.particles.length<l;i++)this.spawnSingleParticle(e,n,a);void 0!==t.emissionRate&&(u*=t.emissionRate)}}if(null!==s){for(let t=0;t<s&&this.particles.length<this.maxParticles;t++)this.spawnSingleParticle(e,n,a);return}if(this.skipSpawnThisFrame)return;for(;this.particles.length<o&&this.particles.length<this.maxParticles;)this.spawnSingleParticle(e,n,a);if(this.particles.length>=l)return;if(u<=0)return;const d=this.particleSpawner.calculateSpawnRate(u,r);for(let t=0;t<d&&this.particles.length<l;t++)this.spawnSingleParticle(e,n,a)}getSpawnPosition(e,t,i,n,a){return this.particleSpawner.getSpawnPosition(e,t,i,n,a,this.currentEmotion)}clampToCanvas(e,t,i,n,a=30){return this.particleSpawner.clampToCanvas(e,t,i,n,a)}spawnSingleParticle(e,t,i){if(this.particles.length>=this.absoluteMaxParticles)return;const n=this.canvasWidth||2*t,a=this.canvasHeight||2*i,r=this.particleSpawner.getSpawnPosition(e,t,i,n,a,this.currentEmotion),s=this.particleSpawner.clampToCanvas(r.x,r.y,n,a);r.x=s.x,r.y=s.y;const o=this.getParticleFromPool(r.x,r.y,e);"meditation_swirl"===e&&r.palmCenter&&(o.palmCenter=r.palmCenter,o.swirlAngle=r.swirlAngle),this.particles.push(o),this.particleCount++}update(e,t,i,n=null,a=0,r=null){if(this.errorBoundary)return this.errorBoundary.wrap((e,t,i,n,a,r)=>this._update(e,t,i,n,a,r),"particle-update")(e,t,i,n,a,r);this._update(e,t,i,n,a,r)}_update(e,t,i,n=null,a=0,r=null){for(this.particles=this.particles.filter(s=>(s.update(e,t,i,r,n,a,this.containmentBounds),s.isAlive()));this.particles.length>this.maxParticles;)this.removeParticle(0)}setGestureBehavior(e,t){this.gestureBehavior=t?e:null,t?this.particles.forEach(t=>{t.gestureBehavior=e}):this.particles.forEach(e=>{e.gestureBehavior=null})}removeParticle(e){if(e>=0&&e<this.particles.length){const t=this.particles.splice(e,1)[0];t.cachedGradient=null,t.cachedGradientKey=null,this.returnParticleToPool(t),this.particleCount=Math.max(0,this.particleCount-1)}}render(e,t="#ffffff",i=null){if(this.errorBoundary)return this.errorBoundary.wrap(()=>{this._render(e,t,i)},"particle-render")();this._render(e,t,i)}renderBackground(e,t="#ffffff",i=null){if(this.errorBoundary)return this.errorBoundary.wrap(()=>{this._renderLayer(e,t,!1,i)},"particle-render-bg")();this._renderLayer(e,t,!1,i)}renderForeground(e,t="#ffffff",i=null){if(this.errorBoundary)return this.errorBoundary.wrap(()=>{this._renderLayer(e,t,!0,i)},"particle-render-fg")();this._renderLayer(e,t,!0,i)}_renderLayer(e,t,i,n=null){this.particleRenderer.renderLayer(e,this.particles,t,i,n)}_render(e,t,i=null){this.particleRenderer.render(e,this.particles,t,i)}clear(){for(this.stateChangeCount++;this.particles.length>0;){const e=this.particles.pop();if(e.cachedColors&&e.cachedColors.clear(),e.behaviorData)for(const t in e.behaviorData)delete e.behaviorData[t];this.pool.length<this.poolSize&&!this.pool.includes(e)&&this.pool.push(e)}if(this.particles.length=0,this.particleCount=0,this.spawnAccumulator=0,this.pool.length>this.poolSize){const e=this.pool.length-this.poolSize;this.pool.splice(this.poolSize,e)}}burst(e,t,i,n){if(this.errorBoundary)return this.errorBoundary.wrap(()=>{this._burst(e,t,i,n)},"particle-burst")();this._burst(e,t,i,n)}_burst(e,t,i,n){const a=Math.min(e,this.maxParticles-this.particles.length);for(let e=0;e<a;e++)this.spawnSingleParticle(t,i,n)}performCleanup(){if(this.pool.length>this.poolSize){const e=this.pool.length-this.poolSize;for(let t=0;t<e;t++){const e=this.pool.pop();e&&(e.cachedGradient=null,e.cachedGradientKey=null,e.behaviorData=null)}}for(const e of this.particles)e.cachedGradient&&e.life<.5&&(e.cachedGradient=null,e.cachedGradientKey=null)}getStats(){return{activeParticles:this.particles.length,maxParticles:this.maxParticles,poolSize:this.pool.length,poolHits:this.poolHits,poolMisses:this.poolMisses,poolEfficiency:this.poolHits/Math.max(1,this.poolHits+this.poolMisses),spawnAccumulator:this.spawnAccumulator}}setMaxParticles(e){for(this.originalMaxParticles=this.originalMaxParticles||this.maxParticles,this.maxParticles=Math.max(1,e);this.particles.length>this.maxParticles;)this.removeParticle(0)}cleanupDeadParticles(){const e=this.particles.length;this.particles=this.particles.filter(e=>e.isAlive());const t=e-this.particles.length;return this.pool.length>20&&(this.pool.length=20),t}getParticlesByBehavior(e){return this.particles.filter(t=>t.behavior===e)}validateParticles(){for(const e of this.particles)if(!e.isAlive()||e.life<0||e.life>1)return!1;return!0}cleanup(){for(let e=this.particles.length-1;e>=0;e--)this.particles[e].isAlive()||this.removeParticle(e)}refreshPool(){this.particlePool.clear();for(const e of this.particles)e.life=0}setContainmentBounds(e){this.containmentBounds=e}destroy(){this.clear(),this.particlePool.clear()}}class Sd{constructor(e={}){this.worldScale=e.worldScale||.2,this.baseRadius=e.baseRadius||.15,this.depthScale=e.depthScale||.75,this.verticalScale=e.verticalScale||1,this.coreRadius3D=e.coreRadius3D||1,this.tempVec3=new xt,this.tempVec3_2=new xt,this.behaviorTranslators=this._initBehaviorTranslators(),this.currentGestureData=null}setCoreRadius3D(e){this.coreRadius3D=e}updateRotationState(e,t,i=null){this.rotationState=e,this.deltaTime=t,this.currentGestureData=i}_initBehaviorTranslators(){return{ambient:this._translateAmbient.bind(this),orbiting:this._translateOrbiting.bind(this),rising:this._translateRising.bind(this),falling:this._translateFalling.bind(this),popcorn:this._translatePopcorn.bind(this),burst:this._translateBurst.bind(this),aggressive:this._translateAggressive.bind(this),scattering:this._translateScattering.bind(this),repelling:this._translateRepelling.bind(this),connecting:this._translateConnecting.bind(this),resting:this._translateResting.bind(this),radiant:this._translateRadiant.bind(this),ascending:this._translateAscending.bind(this),erratic:this._translateErratic.bind(this),cautious:this._translateCautious.bind(this),surveillance:this._translateSurveillance.bind(this),glitchy:this._translateGlitchy.bind(this),spaz:this._translateSpaz.bind(this),directed:this._translateDirected.bind(this),fizzy:this._translateFizzy.bind(this),zen:this._translateZen.bind(this),gravitationalAccretion:this._translateGravitationalAccretion.bind(this)}}translate2DTo3D(e,t,i){const n=(this.behaviorTranslators[e.behavior]||this._translateDefault.bind(this))(e,t,i);return this.currentGestureData&&"spin"===this.currentGestureData.gestureName?this._applySpinRotation(n,t,this.currentGestureData.progress):n}_applySpinRotation(e,t,i){const n=e.x-t.x,a=e.y-t.y,r=e.z-t.z,s=Math.sin(i*Math.PI)*Math.PI*2,o=Math.cos(s),l=Math.sin(s),h=n*o-r*l,c=n*l+r*o;return this.tempVec3.set(t.x+h,t.y+a,t.z+c)}_canvasToWorld(e,t,i,n,a,r){const s=(e-n)/n,o=-(t-a)/a,l=1+i*this.depthScale,h=s*this.worldScale*l+r.x,c=o*this.worldScale*this.verticalScale*l+r.y,u=i*this.worldScale*.5+r.z;return this.tempVec3.set(h,c,u)}_hash(e){const t=43758.5453123*Math.sin(e);return t-Math.floor(t)}_getUniformDirection3D(e){const t=e.behaviorData||{};if(t.direction3D)return t.direction3D;const i=127.1*e.x+311.7*e.y+74.7*(e.vx||0)+159.3*(e.vy||0),n=this._hash(i),a=this._hash(i+1),r=n*Math.PI*2,s=2*a-1,o=Math.sqrt(1-s*s),l=o*Math.cos(r),h=s,c=o*Math.sin(r);return t.direction3D={x:l,y:h,z:c},t.direction3D}_toSpherical(e,t,i,n){const a=e-n.x,r=t-n.y,s=i-n.z,o=Math.sqrt(a*a+r*r+s*s);return{radius:o,theta:Math.atan2(s,a),phi:Math.acos(r/(o||1))}}_toCartesian(e,t,i,n){const a=e*Math.sin(i)*Math.cos(t)+n.x,r=e*Math.cos(i)+n.y,s=e*Math.sin(i)*Math.sin(t)+n.z;return this.tempVec3_2.set(a,r,s)}_translateDefault(e,t,i){return this._canvasToWorld(e.x,e.y,e.z,i.width/2,i.height/2,t)}_translateAmbient(e,t,i){const n=this._getUniformDirection3D(e),a=i.width/2,r=i.height/2,s=e.x-a,o=e.y-r,l=Math.sqrt(s*s+o*o)/a,h=.6*this.coreRadius3D,c=h+l*(1.2*this.coreRadius3D-h),u=.5*e.age,d=.03*this.coreRadius3D,p=Math.cos(u)*d,m=Math.sin(u)*d;return this.tempVec3.set(t.x+n.x*c+p,t.y+n.y*c*this.verticalScale,t.z+n.z*c+m)}_translateOrbiting(e,t,i){const n=e.behaviorData||{};if(!n.orbitPlane){const t=e.x+.5*e.y,i=.7*e.x+e.y;n.orbitPlane={inclination:.5*(Math.sin(.1*t)+1)*Math.PI,rotation:.5*(Math.sin(.1*i)+1)*Math.PI*2}}const{inclination:a,rotation:r}=n.orbitPlane,s=n.angle||0,o=.01*(n.radius||100)*this.baseRadius*.25*(1+e.z*this.depthScale),l=Math.cos(s)*o,h=Math.sin(s)*o,c=Math.cos(a),u=Math.sin(a),d=Math.cos(r),p=Math.sin(r),m=l*d-h*c*p,f=h*u,g=l*p+h*c*d;return this.tempVec3.set(t.x+m,t.y+f*this.verticalScale,t.z+g)}_translateRising(e,t,i){const n=this._canvasToWorld(e.x,e.y,e.z,i.width/2,i.height/2,t),a=-.01*e.vy;return n.y+=a,n}_translateFalling(e,t,i){const n=this._getUniformDirection3D(e),a=i.width/2,r=i.height/2,s=e.x-a,o=e.y-r,l=Math.sqrt(s*s+o*o)/a,h=.6*this.coreRadius3D,c=h+l*(1.2*this.coreRadius3D-h),u=.6*e.age*this.coreRadius3D;return this.tempVec3.set(t.x+n.x*c,t.y+n.y*c*this.verticalScale-u,t.z+n.z*c)}_translatePopcorn(e,t,i){const n=i.width/2,a=i.height/2,r=e.behaviorData||{},s=this._getUniformDirection3D(e);if(!r.hasPopped){const e=.7*this.coreRadius3D;return this.tempVec3.set(t.x+s.x*e,t.y+s.y*e*this.verticalScale,t.z+s.z*e)}const o=e.x-n,l=e.y-a,h=Math.sqrt(o*o+l*l),c=Math.min(h/n,1.5),u=1.2*this.coreRadius3D,d=u+c*(4*this.coreRadius3D-u);return this.tempVec3.set(t.x+s.x*d,t.y+s.y*d*this.verticalScale,t.z+s.z*d)}_translateBurst(e,t,i){const n=this._getUniformDirection3D(e),a=1-e.life,r=this.coreRadius3D*(1+1*a);return this.tempVec3.set(t.x+n.x*r,t.y+n.y*r*this.verticalScale,t.z+n.z*r)}_translateAggressive(e,t,i){const n=this._getUniformDirection3D(e),a=i.width/2,r=i.height/2,s=e.x-a,o=e.y-r,l=Math.sqrt(s*s+o*o)/a,h=.3*this.coreRadius3D,c=h+l*(.55*this.coreRadius3D-h),u=.04*this.coreRadius3D,d=Math.sin(10*e.age+.1*e.x)*u,p=Math.cos(12*e.age+.1*e.y)*u,m=Math.sin(8*e.age+.1*e.vx)*u;return this.tempVec3.set(t.x+n.x*c+d,t.y+n.y*c*this.verticalScale+p,t.z+n.z*c+m)}_translateScattering(e,t,i){const n=this._getUniformDirection3D(e),a=Math.min(.8*e.age,1),r=this.coreRadius3D*(.3+.3*a);return this.tempVec3.set(t.x+n.x*r,t.y+n.y*r*this.verticalScale,t.z+n.z*r)}_translateRepelling(e,t,i){const n=this._getUniformDirection3D(e),a=Math.min(.6*e.age,1),r=this.coreRadius3D*(.3+.3*a);return this.tempVec3.set(t.x+n.x*r,t.y+n.y*r*this.verticalScale,t.z+n.z*r)}_translateConnecting(e,t,i){const n=this._canvasToWorld(e.x,e.y,e.z,i.width/2,i.height/2,t),a=.3*(1-e.life),r=this.tempVec3_2.set(t.x-n.x,t.y-n.y,t.z-n.z).normalize();return n.add(r.multiplyScalar(a)),n}_translateResting(e,t,i){const n=this._getUniformDirection3D(e),a=i.width/2,r=i.height/2,s=e.x-a,o=e.y-r,l=Math.sqrt(s*s+o*o)/a,h=.25*this.coreRadius3D,c=h+l*(.45*this.coreRadius3D-h),u=.3*e.age,d=Math.sin(u)*this.coreRadius3D*.01;return this.tempVec3.set(t.x+n.x*c,t.y+n.y*c*this.verticalScale+d,t.z+n.z*c)}_translateRadiant(e,t,i){const n=this._getUniformDirection3D(e),a=1-e.life,r=this.coreRadius3D*(1+.8*a);return this.tempVec3.set(t.x+n.x*r,t.y+n.y*r*this.verticalScale,t.z+n.z*r)}_translateAscending(e,t,i){const n=e.behaviorData||{},a=n.spiralAngle||0,r=.01*(n.spiralRadius||50)*this.coreRadius3D,s=e.age*this.coreRadius3D*.5,o=Math.cos(a)*r+t.x,l=s+t.y,h=Math.sin(a)*r+t.z;return this.tempVec3.set(o,l,h)}_translateErratic(e,t,i){const n=this._canvasToWorld(e.x,e.y,e.z,i.width/2,i.height/2,t),a=10*e.age;return n.x+=.1*Math.sin(1.1*a),n.y+=.1*Math.cos(1.3*a),n.z+=.1*Math.sin(1.7*a),n}_translateCautious(e,t,i){return this._translateAmbient(e,t,i)}_translateSurveillance(e,t,i){const n=this._getUniformDirection3D(e),a=.5*e.age,r=1.2*this.coreRadius3D,s={x:0*n.y-1*n.z,y:0*n.z-0*n.x,z:1*n.x-0*n.y},o=Math.sqrt(s.x*s.x+s.y*s.y+s.z*s.z);o>0&&(s.x/=o,s.y/=o,s.z/=o);const l=Math.cos(a)*n.x+Math.sin(a)*s.x,h=Math.cos(a)*n.y+Math.sin(a)*s.y,c=Math.cos(a)*n.z+Math.sin(a)*s.z;return this.tempVec3.set(t.x+l*r,t.y+h*r*this.verticalScale,t.z+c*r)}_translateGlitchy(e,t,i){const n=this._canvasToWorld(e.x,e.y,e.z,i.width/2,i.height/2,t);return Math.floor(10*e.age)%3==0&&(n.x+=.3*(Math.random()-.5),n.y+=.3*(Math.random()-.5),n.z+=.3*(Math.random()-.5)),n}_translateSpaz(e,t,i){const n=this._canvasToWorld(e.x,e.y,e.z,i.width/2,i.height/2,t),a=.15,r=20*e.age;return n.x+=Math.sin(2.1*r)*a,n.y+=Math.cos(2.3*r)*a,n.z+=Math.sin(2.7*r)*a,n}_translateDirected(e,t,i){const n=e.behaviorData||{};if(void 0!==n.targetX&&void 0!==n.targetY){const a=this._canvasToWorld(n.targetX,n.targetY,e.z,i.width/2,i.height/2,t),r=this._canvasToWorld(e.x,e.y,e.z,i.width/2,i.height/2,t),s=1-e.life;return this.tempVec3.lerpVectors(r,a,s)}const a=this._getUniformDirection3D(e),r=i.width/2,s=i.height/2,o=e.x-r,l=e.y-s,h=Math.sqrt(o*o+l*l)/r,c=1*this.coreRadius3D,u=c+h*(1.6*this.coreRadius3D-c);return this.tempVec3.set(t.x+a.x*u,t.y+a.y*u*this.verticalScale,t.z+a.z*u)}_translateFizzy(e,t,i){const n=this._canvasToWorld(e.x,e.y,e.z,i.width/2,i.height/2,t),a=.05*Math.sin(8*e.age);return n.x+=a,n.z+=.05*Math.cos(8*e.age),n.y+=.5*e.age,n}_translateZen(e,t,i){const n=this._getUniformDirection3D(e),a=.2*e.age,r=1.4*this.coreRadius3D,s={x:0*n.y-1*n.z,y:0*n.z-0*n.x,z:1*n.x-0*n.y},o=Math.sqrt(s.x*s.x+s.y*s.y+s.z*s.z);o>0&&(s.x/=o,s.y/=o,s.z/=o);const l=Math.cos(a)*n.x+Math.sin(a)*s.x,h=Math.cos(a)*n.y+Math.sin(a)*s.y,c=Math.cos(a)*n.z+Math.sin(a)*s.z;return this.tempVec3.set(t.x+l*r,t.y+h*r*this.verticalScale,t.z+c*r)}_translateGravitationalAccretion(e,t,i){const n=e.behaviorData||{},a=.25;if(n.orbitRadius||(e.x,e.y,n.orbitRadius=a*(2.5+5.5*Math.random()),n.orbitAngle=Math.PI+Math.random()*Math.PI,n.diskInclination=.1*(Math.random()-.5),n.angularVelocity=.5/Math.sqrt(n.orbitRadius/a),n.tidalStretch={x:1,y:1,z:1}),n.orbitRadius-=1e-4*this.baseRadius,n.angularVelocity=.5/Math.sqrt(n.orbitRadius/a),n.orbitAngle+=n.angularVelocity*(this.deltaTime||16)*.001,n.orbitAngle=n.orbitAngle%(2*Math.PI),n.orbitAngle<0&&(n.orbitAngle+=2*Math.PI),n.orbitAngle<Math.PI)return e.isAlive=!1,e.life=0,this.tempVec3.set(t.x,t.y,t.z);const r=n.orbitRadius/a;if(r<=1)e.isAlive=!1,e.life=0;else if(r<=1.5)n.tidalStretch.x=.3,n.tidalStretch.y=3,n.tidalStretch.z=.3;else if(r<=2.5){const e=(2.5-r)/1;n.tidalStretch.x=1-.7*e,n.tidalStretch.y=1+2*e,n.tidalStretch.z=1-.7*e}else n.tidalStretch.x=1,n.tidalStretch.y=1,n.tidalStretch.z=1;const s=Math.cos(n.orbitAngle)*n.orbitRadius,o=Math.sin(n.orbitAngle)*n.orbitRadius,l=.025*Math.sin(3*n.orbitAngle+e.x)*Math.sin(n.diskInclination),h=s*n.tidalStretch.x,c=l*n.tidalStretch.y,u=o*n.tidalStretch.z,d=.25;return this.tempVec3.set(t.x+h*d,t.y+c*d,t.z+u*d)}setWorldScale(e){this.worldScale=e}setBaseRadius(e){this.baseRadius=e}cleanupParticleCaches(e){for(const t of e)!t.isAlive&&t.behaviorData&&(t.behaviorData.direction3D&&(t.behaviorData.direction3D=null),t.behaviorData.orbitPlane&&(t.behaviorData.orbitPlane=null),t.behaviorData.orbitPath&&(t.behaviorData.orbitPath=null),t.behaviorData.orbitRadius&&(t.behaviorData.orbitRadius=null,t.behaviorData.orbitAngle=null,t.behaviorData.diskInclination=null,t.behaviorData.angularVelocity=null,t.behaviorData.tidalStretch=null))}dispose(){this.tempVec3=null,this.tempVec3_2=null,this.rotationState=null,this.currentGestureData=null}}let wd=null,Ed=null;const Td=`\n uniform float time;\n uniform vec3 emotionColor;\n uniform float energyIntensity;\n uniform float driftEnabled;\n uniform float driftSpeed;\n uniform float crossWaveEnabled;\n uniform float crossWaveSpeed;\n uniform float ghostMode; // 0.0 = solid, 1.0 = ghost (only visible through bloom)\n uniform float baseOpacity; // Base opacity when not in ghost mode (default 1.0)\n uniform float phaseOffset1; // Phase offset for primary drift (radians)\n uniform float phaseOffset2; // Phase offset for secondary drift (radians)\n uniform float phaseOffset3; // Phase offset for crosswave (radians)\n\n // Blend layer uniforms\n uniform float blendLayer1Mode;\n uniform float blendLayer1Strength;\n uniform float blendLayer1Enabled;\n uniform float blendLayer2Mode;\n uniform float blendLayer2Strength;\n uniform float blendLayer2Enabled;\n\n varying vec3 vPosition;\n varying vec3 vNormal;\n\n // Blend modes (injected from blendModesGLSL)\n ${Oh}\n\n // Smooth noise function\n float noise3D(vec3 p) {\n vec3 i = floor(p);\n vec3 f = fract(p);\n f = f * f * (3.0 - 2.0 * f);\n float n = i.x + i.y * 157.0 + i.z * 113.0;\n vec4 v = fract(sin(vec4(n, n+1.0, n+157.0, n+158.0)) * 43758.5453);\n return mix(mix(v.x, v.y, f.x), mix(v.z, v.w, f.x), f.y);\n }\n\n void main() {\n // Drifting energy clouds - slow, ethereal movement\n // Start with zero energy - only effects add to it\n float driftEnergy = 0.0;\n float crossWaveEnergy = 0.0;\n\n // Spatially triangulated fire bands - each owns a 120° wedge of the geometry\n // Bands can never overlap because they're physically separated\n float angle = atan(vPosition.x, vPosition.z); // -π to π\n float normalizedAngle = (angle + 3.14159) / 6.28318; // 0 to 1\n\n // Determine which zone this fragment belongs to (0, 1, or 2)\n float zone = floor(normalizedAngle * 3.0);\n float zonePos = fract(normalizedAngle * 3.0); // Position within zone (0-1)\n\n // Time-based phase for each zone (120° offset in time)\n float phaseSpeed = 0.15;\n float t = time * phaseSpeed;\n float phase1Time = sin(t + phaseOffset1) * 0.5 + 0.5;\n float phase2Time = sin(t + phaseOffset2) * 0.5 + 0.5;\n float phase3Time = sin(t + phaseOffset3) * 0.5 + 0.5;\n\n // Only ONE phase affects this fragment - the one that owns this spatial zone\n float activePhase = zone < 1.0 ? phase1Time : (zone < 2.0 ? phase2Time : phase3Time);\n\n float primaryDrift = 0.0;\n float secondaryDrift = 0.0;\n\n if (driftEnabled > 0.5) {\n float t = time * driftSpeed;\n // Primary drift - moving in one direction\n float drift1 = noise3D(vPosition * 2.0 + vec3(t, t * 0.7, t * 0.3));\n float drift2 = noise3D(vPosition * 3.0 - vec3(t * 0.5, t, t * 0.8));\n // Use max instead of multiply to avoid near-zero products\n primaryDrift = max(drift1, drift2);\n primaryDrift = max(0.0, primaryDrift - 0.4) * 2.0; // Rescale after threshold\n\n // Secondary drift - offset in opposite direction to fill gaps\n float drift3 = noise3D(vPosition * 2.5 - vec3(t * 0.8, t * 0.4, t));\n float drift4 = noise3D(vPosition * 1.8 + vec3(t * 0.6, t * 0.9, t * 0.2));\n secondaryDrift = max(drift3, drift4);\n secondaryDrift = max(0.0, secondaryDrift - 0.4) * 2.0;\n\n driftEnergy = primaryDrift + secondaryDrift;\n }\n\n // Horizontal cross wave - thin bands sweeping across\n float rawCrossWave = 0.0;\n if (crossWaveEnabled > 0.5) {\n float t = time * crossWaveSpeed;\n float wave = sin(vPosition.x * 4.0 + vPosition.z * 2.0 - t) * 0.5 + 0.5;\n // pow(4) for thin bright bands\n rawCrossWave = pow(wave, 4.0);\n crossWaveEnergy = rawCrossWave;\n }\n\n // Mix the effects - normalize to prevent blowout\n // driftEnergy can be 0-2 (two drifts), rawCrossWave is 0-1\n float normalizedDrift = min(1.0, driftEnergy * 0.5);\n float normalizedWave = rawCrossWave;\n\n // activePhase is 0-1, remap to visibility range\n // 0.53 floor (just above 0.52 threshold), 0.58 ceiling (subtle glow)\n float remappedPhase = 0.53 + activePhase * 0.05;\n\n // Effects add subtle variation (max 0.05)\n float effectContrib = (normalizedDrift * 0.03) + (normalizedWave * 0.02);\n float phasedActivity = remappedPhase + effectContrib;\n\n // Keep unclamped for visibility threshold check (ghost mode needs full range)\n float rawEffectActivity = phasedActivity;\n // Clamp for color intensity (floor: guaranteed visible, ceiling: no blowout)\n float effectActivity = clamp(phasedActivity, 0.53, 0.60);\n\n // Total energy for color calculation (reduced for subtler bloom)\n float totalEnergy = 0.25 + effectActivity * 0.55; // Base glow + effect contribution\n\n // Edge glow - adds rim lighting\n vec3 viewDir = normalize(-vPosition);\n float edgeGlow = 1.0 - abs(dot(vNormal, viewDir));\n edgeGlow = pow(edgeGlow, 2.0) * 0.4;\n\n // Final color before blend layers\n vec3 coreColor = emotionColor * totalEnergy * energyIntensity;\n coreColor += emotionColor * edgeGlow * 0.3;\n\n // Apply blend layers to the entire soul color\n if (blendLayer1Enabled > 0.5) {\n int mode = int(blendLayer1Mode + 0.5);\n vec3 blendResult = applyBlendMode(coreColor, emotionColor * blendLayer1Strength, mode);\n coreColor = mix(coreColor, blendResult, blendLayer1Strength);\n }\n if (blendLayer2Enabled > 0.5) {\n int mode = int(blendLayer2Mode + 0.5);\n vec3 blendResult = applyBlendMode(coreColor, emotionColor * blendLayer2Strength, mode);\n coreColor = mix(coreColor, blendResult, blendLayer2Strength);\n }\n\n // Ghost mode: ONLY the traveling fire bands are visible\n // Everything below the threshold is completely invisible\n float alpha = baseOpacity;\n if (ghostMode > 0.01) {\n // High threshold - only the peaks of the thin bands pass through\n float threshold = 0.4 + ghostMode * 0.4; // 0.4-0.8 range\n float visibility = smoothstep(threshold, threshold + 0.05, rawEffectActivity);\n\n // Hard cutoff - only bright fire bands visible\n alpha = visibility * baseOpacity;\n\n // Discard everything that isn't a bright fire band\n if (alpha < 0.05) {\n discard;\n }\n\n // Boost color intensity for visible fire\n coreColor *= 1.2 + visibility * 0.6;\n }\n\n // Output the computed core color\n gl_FragColor = vec4(coreColor, alpha);\n }\n`;class Cd{constructor(e={}){this.radius=e.radius||.15,this.detail=e.detail||1,this.geometryType=e.geometryType||"crystal",this.renderer=e.renderer||null,this.assetBasePath=e.assetBasePath||"/assets",this.mesh=null,this.material=null,this.parentMesh=null,this.baseScale=1,this._pendingParent=null,this._disposed=!1,this._createMesh()}static _loadInclusionGeometry(e="/assets"){return wd?Promise.resolve(wd.clone()):Ed?Ed.then(e=>e.clone()):(Ed=new Promise(t=>{(new Bh).load(`${e}/models/Crystal/inclusion.obj`,e=>{let i=null;if(e.traverse(e=>{e.isMesh&&e.geometry&&({geometry:i}=e)}),i){i.computeBoundingBox();const e=new xt;i.boundingBox.getCenter(e),i.translate(-e.x,-e.y,-e.z),i.rotateX(Math.PI/2),i.computeBoundingBox();const n=new xt;i.boundingBox.getSize(n);const a=.3/Math.max(n.x,n.y,n.z);i.scale(a,a,a),i.computeVertexNormals(),wd=i,t(i.clone())}else console.warn("[🔮 SOUL] No mesh in inclusion.obj, using fallback"),t(null)},void 0,e=>{console.warn("[🔮 SOUL] Failed to load inclusion.obj:",e),t(null)})}),Ed)}_createMesh(){let e;console.log(`[CrystalSoul] _createMesh() START, inclusionGeometryCache=${!!wd}`),this.material=new Jn({uniforms:{time:{value:0},emotionColor:{value:new dn(1,1,1)},energyIntensity:{value:1.5},driftEnabled:{value:1},driftSpeed:{value:.5},crossWaveEnabled:{value:1},crossWaveSpeed:{value:.4},ghostMode:{value:.36},baseOpacity:{value:1},phaseOffset1:{value:0},phaseOffset2:{value:2.094},phaseOffset3:{value:4.189},blendLayer1Mode:{value:2},blendLayer1Strength:{value:2.3},blendLayer1Enabled:{value:1},blendLayer2Mode:{value:0},blendLayer2Strength:{value:1},blendLayer2Enabled:{value:1}},vertexShader:"\n varying vec3 vPosition;\n varying vec3 vNormal;\n\n void main() {\n vPosition = position;\n vNormal = normalize(normalMatrix * normal);\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n",fragmentShader:Td,transparent:!0,depthWrite:!0,depthTest:!0,side:0}),e=wd?wd.clone():new mr(this.radius,this.detail),this.mesh=new Xn(e,this.material),this.mesh.name="crystalSoul",this.mesh.renderOrder=0,this.mesh.layers.set(2)}attachTo(e,t){this._disposed||(e?this.mesh?(this.mesh.parent&&this.mesh.parent.remove(this.mesh),this.parentMesh=e,this._scene=t,t&&!this.mesh.parent&&t.add(this.mesh),this._syncPosition(),this.mesh.visible=!0):console.warn("[CrystalSoul] Cannot attach - mesh is null"):console.warn("[CrystalSoul] Cannot attach to null parent"))}_syncPosition(){this.parentMesh&&this.mesh&&(this.parentMesh.getWorldPosition(this.mesh.position),this.parentMesh.getWorldQuaternion(this.mesh.quaternion))}detach(){this.mesh&&(this.mesh.visible=!1,this.parentMesh=null)}update(e,t,i=1){if(!this.material||!this.material.uniforms)return;this._syncPosition();const{uniforms:n}=this.material;n.time&&(n.time.value+=e/1e3),n.emotionColor&&t&&n.emotionColor.value.setRGB(t[0],t[1],t[2]),n.energyIntensity&&(n.energyIntensity.value=.8),this.mesh&&this.mesh.scale.setScalar(this.baseScale*i)}setSize(e){if(!this.mesh)return;const t=.05+.95*e;this.baseScale=t,this.mesh.scale.setScalar(t)}setEffects(e={}){if(!this.material||!this.material.uniforms)return;const{uniforms:t}=this.material;void 0!==e.driftEnabled&&t.driftEnabled&&(t.driftEnabled.value=e.driftEnabled?1:0),void 0!==e.driftSpeed&&t.driftSpeed&&(t.driftSpeed.value=Math.max(.1,Math.min(3,e.driftSpeed))),void 0!==e.crossWaveEnabled&&t.crossWaveEnabled&&(t.crossWaveEnabled.value=e.crossWaveEnabled?1:0),void 0!==e.crossWaveSpeed&&t.crossWaveSpeed&&(t.crossWaveSpeed.value=Math.max(.1,Math.min(3,e.crossWaveSpeed))),void 0!==e.phaseOffset1&&t.phaseOffset1&&(t.phaseOffset1.value=e.phaseOffset1),void 0!==e.phaseOffset2&&t.phaseOffset2&&(t.phaseOffset2.value=e.phaseOffset2),void 0!==e.phaseOffset3&&t.phaseOffset3&&(t.phaseOffset3.value=e.phaseOffset3)}setColor(e){this.material&&this.material.uniforms&&this.material.uniforms.emotionColor&&this.material.uniforms.emotionColor.value.setRGB(e[0],e[1],e[2])}setBlendLayers(e){if(!this.material||!this.material.uniforms)return;const t=this.material.uniforms;e[0]?(t.blendLayer1Mode&&(t.blendLayer1Mode.value=e[0].mode??0),t.blendLayer1Strength&&(t.blendLayer1Strength.value=e[0].strength??0),t.blendLayer1Enabled&&(t.blendLayer1Enabled.value=e[0].enabled?1:0)):t.blendLayer1Enabled&&(t.blendLayer1Enabled.value=0),e[1]?(t.blendLayer2Mode&&(t.blendLayer2Mode.value=e[1].mode??0),t.blendLayer2Strength&&(t.blendLayer2Strength.value=e[1].strength??0),t.blendLayer2Enabled&&(t.blendLayer2Enabled.value=e[1].enabled?1:0)):t.blendLayer2Enabled&&(t.blendLayer2Enabled.value=0)}isAttached(){return null!==this.parentMesh&&null!==this.mesh&&null!==this.mesh.parent}setVisible(e){this.mesh&&(this.mesh.visible=e)}setGhostMode(e){this.material&&this.material.uniforms&&this.material.uniforms.ghostMode&&(this.material.uniforms.ghostMode.value=e?1:0)}setBaseOpacity(e){this.material&&this.material.uniforms&&this.material.uniforms.baseOpacity&&(this.material.uniforms.baseOpacity.value=Math.max(0,Math.min(1,e)))}dispose(){if(this._disposed)return;this._disposed=!0,this.detach();const e=this.mesh,t=this.material;this.mesh=null,this.material=null,this.parentMesh=null,requestAnimationFrame(()=>{e?.parent&&e.parent.remove(e),e?.geometry&&e.geometry.dispose(),t&&t.dispose()})}}class Ad{constructor(e=50,t={}){this.maxParticles=e,this.options=t,this.geometry=null,this.material=null,this.points=null,this.positions=null,this.sizes=null,this.colors=null,this.alphas=null,this.glowIntensities=null,this.depths=null,this.styles=null,this.particleCount=0,this.gestureEffects={firefly:!1,flicker:!1,shimmer:!1,glow:!1,time:0},this._initGeometry(),this._initMaterial(),this._initPoints()}_initGeometry(){this.geometry=new Bn;const{maxParticles:e}=this;this.positions=new Float32Array(3*e),this.sizes=new Float32Array(e),this.colors=new Float32Array(3*e),this.alphas=new Float32Array(e),this.glowIntensities=new Float32Array(e),this.depths=new Float32Array(e),this.styles=new Float32Array(e),this.geometry.setAttribute("position",new Sn(this.positions,3)),this.geometry.setAttribute("size",new Sn(this.sizes,1)),this.geometry.setAttribute("customColor",new Sn(this.colors,3)),this.geometry.setAttribute("alpha",new Sn(this.alphas,1)),this.geometry.setAttribute("glowIntensity",new Sn(this.glowIntensities,1)),this.geometry.setAttribute("depth",new Sn(this.depths,1)),this.geometry.setAttribute("style",new Sn(this.styles,1)),this.geometry.attributes.position.setUsage(Qe),this.geometry.attributes.size.setUsage(Qe),this.geometry.attributes.customColor.setUsage(Qe),this.geometry.attributes.alpha.setUsage(Qe),this.geometry.attributes.glowIntensity.setUsage(Qe),this.geometry.attributes.depth.setUsage(Qe),this.geometry.attributes.style.setUsage(Qe),this.geometry.setDrawRange(0,0)}_initMaterial(){this.material=new Jn({uniforms:{coreScale:{value:1},viewportHeight:{value:600},pixelRatio:{value:1}},vertexShader:"\n/**\n * Particle Vertex Shader - Simple 2D-style particles in 3D space\n * Matches the 2D canvas particle appearance\n */\n\n// Per-particle attributes\nattribute float size;\nattribute vec3 customColor;\nattribute float alpha;\nattribute float glowIntensity;\nattribute float style; // 0.0 = solid/gradient, 1.0 = cell-shaded (ring with transparent center)\n\n// Uniforms\nuniform float coreScale;\nuniform float viewportHeight;\nuniform float pixelRatio;\n\n// Varying to fragment shader\nvarying vec3 vColor;\nvarying float vAlpha;\nvarying float vGlowIntensity;\nvarying float vStyle;\n\nvoid main() {\n // Pass attributes to fragment shader\n vColor = customColor;\n vAlpha = alpha;\n vGlowIntensity = glowIntensity;\n vStyle = style;\n\n // Calculate position in clip space\n vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);\n\n // Calculate point size with perspective scaling\n float perspectiveScale = coreScale * (75.0 / length(mvPosition.xyz)) * (viewportHeight / 600.0) / pixelRatio;\n gl_PointSize = size * perspectiveScale;\n\n // Final position\n gl_Position = projectionMatrix * mvPosition;\n}\n",fragmentShader:"\n/**\n * Particle Fragment Shader - Solid colored circles matching 2D appearance\n * Uses premultiplied alpha for proper blending\n */\n\nvarying vec3 vColor;\nvarying float vAlpha;\nvarying float vGlowIntensity;\nvarying float vStyle;\n\nvoid main() {\n // Distance from center (0 at center, 0.5 at edge)\n vec2 center = gl_PointCoord - vec2(0.5);\n float dist = length(center);\n\n // Hard circle cutoff - discard everything outside\n if (dist > 0.45) {\n discard;\n }\n\n vec3 finalColor = vColor;\n\n // Base opacity from particle (already includes baseOpacity variation)\n float alpha = vAlpha;\n\n // Gesture glow boost\n if (vGlowIntensity >= 2.0) {\n float gestureBoost = (vGlowIntensity - 2.0) / 13.0;\n finalColor *= (1.0 + gestureBoost * 0.5);\n alpha = min(alpha * (1.0 + gestureBoost * 0.3), 1.0);\n }\n\n // Cell-shaded particles are slightly more opaque\n float opacityBoost = vStyle > 0.5 ? 1.0 : 0.85;\n alpha *= opacityBoost;\n\n // Output with proper alpha for blending\n // Premultiply alpha for correct compositing\n gl_FragColor = vec4(finalColor * alpha, alpha);\n}\n",transparent:!0,blending:5,blendSrc:201,blendDst:d,blendSrcAlpha:201,blendDstAlpha:d,depthWrite:!1,depthTest:!0})}_initPoints(){this.points=new rr(this.geometry,this.material),this.points.frustumCulled=!0}updateParticles(e,t,i,n,a,r,s,o,l){this.particleCount=Math.min(e.length,this.maxParticles),void 0!==o&&(this.material.uniforms.coreScale.value=o),n&&n.height&&(this.material.uniforms.viewportHeight.value=n.height),this.options.renderer&&(this.material.uniforms.pixelRatio.value=this.options.renderer.getPixelRatio()),this.gestureEffects.time+=.016,this.gestureEffects.time>2*Math.PI&&(this.gestureEffects.time=this.gestureEffects.time%(2*Math.PI)),a&&r&&t.updateRotationState(a,r,s);for(let a=0;a<this.particleCount;a++){const r=e[a];if(!r.isAlive()){this.alphas[a]=0;continue}const s=t.translate2DTo3D(r,i,n);if(("crystal"===l||"heart"===l||"rough"===l)&&s.z>.15){this.alphas[a]=0;continue}const o=3*a;this.positions[o+0]=s.x,this.positions[o+1]=s.y,this.positions[o+2]=s.z;const h=r.getDepthAdjustedSize?r.getDepthAdjustedSize():r.size,c="popcorn"===r.behavior?1.2:.85;this.sizes[a]=h*c;const u=this._parseColor(r.color||"#ffffff"),d=3*a;this.colors[d+0]=u.r,this.colors[d+1]=u.g,this.colors[d+2]=u.b,this.alphas[a]=r.opacity*(r.baseOpacity||1);let p=r.hasGlow?1*(r.glowSizeMultiplier||1.5):0;p=this._applyGestureEffects(r,p,a),this.glowIntensities[a]=p;const m=.5*(1-r.z);this.depths[a]=Math.max(0,Math.min(1,m)),this.styles[a]=r.isCellShaded?1:0}this.geometry.attributes.position.needsUpdate=!0,this.geometry.attributes.size.needsUpdate=!0,this.geometry.attributes.customColor.needsUpdate=!0,this.geometry.attributes.alpha.needsUpdate=!0,this.geometry.attributes.glowIntensity.needsUpdate=!0,this.geometry.attributes.depth.needsUpdate=!0,this.geometry.attributes.style.needsUpdate=!0,this.geometry.setDrawRange(0,this.particleCount)}_applyGestureEffects(e,t,i){let n=t;if(this.gestureEffects.firefly){const t=(.01*e.x+.01*e.y+.1*e.size)%(2*Math.PI),i=2+.5*(Math.sin(3*this.gestureEffects.time+t)+1)*10;n=Math.max(n,i)}if(this.gestureEffects.flicker){const t=(.02*e.x+.02*e.y)%(2*Math.PI),a=15*this.gestureEffects.time,r=.5*(Math.sin(a+t)+1),s=Math.floor(10*a+i),o=2+10*(.3*r+.5*(Math.sin(123.456*s)+1)*.7);n=Math.max(n,o)}if(this.gestureEffects.shimmer){const t=e.x-(this.gestureEffects.centerX||0),i=e.y-(this.gestureEffects.centerY||0),a=Math.sqrt(t*t+i*i)/200,r=2+.5*(Math.sin(3*this.gestureEffects.time-a)+1)*8;n=Math.max(n,r)}if(this.gestureEffects.glow){const e=this.gestureEffects.glowProgress||0,t=3+12*Math.sin(e*Math.PI);n=Math.max(n,t)}return n}_parseColor(e){const t=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return t?{r:parseInt(t[1],16)/255,g:parseInt(t[2],16)/255,b:parseInt(t[3],16)/255}:{r:1,g:1,b:1}}setGestureEffects(e){if(!e)return this.gestureEffects.firefly=!1,this.gestureEffects.flicker=!1,this.gestureEffects.shimmer=!1,void(this.gestureEffects.glow=!1);this.gestureEffects.firefly=e.fireflyEffect||!1,this.gestureEffects.flicker=e.flickerEffect||!1,this.gestureEffects.shimmer=e.shimmerEffect||!1,this.gestureEffects.glow=e.glowEffect||!1,this.gestureEffects.glowProgress=e.glowProgress,this.gestureEffects.centerX=e.centerX,this.gestureEffects.centerY=e.centerY}getPoints(){return this.points}setVisible(e){this.points.visible=e}resize(e){e!==this.maxParticles&&(this.geometry&&this.geometry.dispose(),this.maxParticles=e,this._initGeometry(),this.points&&(this.points.geometry=this.geometry))}cleanupParticleStates(e){for(const t of e)!t.isAlive()&&t.behaviorData&&(t.behaviorData.direction3D&&(t.behaviorData.direction3D=null),t.behaviorData.orbitPlane&&(t.behaviorData.orbitPlane=null),t.behaviorData.orbitPath&&(t.behaviorData.orbitPath=null),t.behaviorData=null)}dispose(){this.geometry&&this.geometry.dispose(),this.material&&this.material.dispose(),this.positions=null,this.sizes=null,this.colors=null,this.alphas=null,this.glowIntensities=null,this.depths=null,this.styles=null}}class Pd{constructor(){this.cachedConfigs=new Map,this.maxCacheSize=100}calculate(e,t=null){const i=`${e}:${t||"none"}`;if(this.cachedConfigs.has(i))return this.cachedConfigs.get(i);const n=Tc(e);if(!n)return console.warn(`[ParticleEmotionCalculator] Unknown emotion: ${e}`),this._getDefaultConfig();const a=this._extractBaseConfig(n,e),r=this._applyUndertoneModifiers(a,t),s=this._applySpecialBehaviors(r,e);if(this.cachedConfigs.size>=this.maxCacheSize){const e=this.cachedConfigs.keys().next().value;this.cachedConfigs.delete(e)}return this.cachedConfigs.set(i,s),s}_extractBaseConfig(e,t){const i=e.visual||{};return{behavior:i.particleBehavior||"ambient",rate:i.particleRate||1,min:void 0!==i.minParticles?i.minParticles:0,max:void 0!==i.maxParticles?i.maxParticles:10,colors:i.particleColors||null,emotion:t}}_applyUndertoneModifiers(e,t){if(!t)return e;const i=Ru(t);if(!i||!i.particles)return e;const n=i.particles,a={...e};return n.behaviorOverride&&(a.behavior=n.behaviorOverride),n.rateMultiplier&&(a.rate=e.rate*n.rateMultiplier,a.max=Math.floor(e.max*n.rateMultiplier)),void 0!==n.minParticles&&(a.min=n.minParticles),void 0!==n.maxParticles&&(a.max=n.maxParticles),a}_applySpecialBehaviors(e,t){return"zen"===t?{...e,specialBehavior:"zen-mixing"}:e}selectZenBehavior(){return Math.random()<.6?"falling":"orbiting"}_getDefaultConfig(){return{behavior:"ambient",rate:1,min:0,max:10,colors:null,emotion:"neutral"}}clearCache(){this.cachedConfigs.clear()}getCacheSize(){return this.cachedConfigs.size}}class Dd{constructor(){this.previousGesture=null}extract(e,t){if(!e||0===e.length)return this.previousGesture=null,null;const i=e[0],n=this._calculateProgress(i,t);if(n>=1)return this.previousGesture=null,null;const a=this._extractGestureName(i);if(!a)return null;const r=this._buildGestureMotion(i,a);return this.previousGesture=a,{motion:r,progress:n,config:i.config||{},gestureName:a,animation:i}}_calculateProgress(e,t){const i=(t-e.startTime)/e.duration;return Math.max(0,Math.min(1,i))}_extractGestureName(e){return e.gestureName||e.name||e.config?.gestureName||null}_buildGestureMotion(e,t){const i=e.config||{};return{type:t,amplitude:i.amplitude||1,strength:i.strength||1,wobbleAmount:i.wobbleAmount||0,duration:e.duration}}hasGestureChanged(e){return!(!e&&!this.previousGesture||(e||!this.previousGesture)&&(!e||this.previousGesture)&&e.gestureName===this.previousGesture)}extractAll(e,t){if(!e||0===e.length)return[];const i=[];for(const n of e){const e=this._calculateProgress(n,t);if(e>=1)continue;const a=this._extractGestureName(n);if(!a)continue;const r=this._buildGestureMotion(n,a);i.push({motion:r,progress:e,config:n.config||{},gestureName:a,animation:n})}return i}reset(){this.previousGesture=null}}class Rd{constructor(){this.effectMap={sparkle:this.buildFireflyEffect.bind(this),twinkle:this.buildFireflyEffect.bind(this),flicker:this.buildFlickerEffect.bind(this),shimmer:this.buildShimmerEffect.bind(this),glow:this.buildGlowEffect.bind(this),burst:this.buildGlowEffect.bind(this),flash:this.buildFlickerEffect.bind(this)}}build(e,t,i){if(!e||!e.motion)return null;const{gestureName:n}=e,a=this.effectMap[n];return a?a(e,t,i):null}buildFireflyEffect(e,t,i){const n=e.config||{};return{fireflyEffect:!0,fireflyTime:.001*Date.now(),particleGlow:n.particleGlow||2,centerX:t,centerY:i}}buildFlickerEffect(e,t,i){const n=e.config||{};return{flickerEffect:!0,flickerTime:.001*Date.now(),particleGlow:n.particleGlow||2,centerX:t,centerY:i}}buildShimmerEffect(e,t,i){const n=e.config||{},a=e.progress||0;return{shimmerEffect:!0,shimmerTime:.001*Date.now(),shimmerWave:a*Math.PI*2,particleGlow:n.particleGlow||1.2,centerX:t,centerY:i}}buildGlowEffect(e,t,i){const n=e.config||{};return{glowEffect:!0,glowProgress:e.progress||0,particleGlow:n.particleGlow||2,centerX:t,centerY:i}}registerEffect(e,t){this.effectMap[e]=t.bind(this)}hasEffect(e){return!!this.effectMap[e]}getEffectGestures(){return Object.keys(this.effectMap)}buildAll(e,t,i){if(!e||0===e.length)return[];const n=[];for(const a of e){const e=this.build(a,t,i);e&&n.push(e)}return n}mergeEffects(e){if(!e||0===e.length)return null;if(1===e.length)return e[0];const t={};for(const i of e)Object.assign(t,i);return t}destroy(){this.effectMap=null}}class Id{constructor(e,t,i){this.particleSystem=e,this.translator=t,this.renderer=i,this.emotionCalculator=new Pd,this.gestureExtractor=new Dd,this.effectsBuilder=new Rd,this.currentEmotion=null,this.currentUndertone=null,this.currentConfig=null}update(e,t,i,n,a,r,s,o,l,h){void 0!==h&&this.translator.setCoreRadius3D(h);const c=this._updateEmotionConfig(t,i),u=this.gestureExtractor.extract(n,a);this._spawnParticles(c,e,s),this._updatePhysics(c,u,e,s,i),this._updateRendering(u,r,s,o,e,l)}_updateEmotionConfig(e,t){return this.currentEmotion===e&&this.currentUndertone===t||(this.currentEmotion=e,this.currentUndertone=t,this.currentConfig=this.emotionCalculator.calculate(e,t),this.particleSystem.clear()),this.currentConfig}_spawnParticles(e,t,i){const n=i.width/2,a=i.height/2;let r=e.behavior;"zen-mixing"===e.specialBehavior&&(r=this.emotionCalculator.selectZenBehavior()),this.particleSystem.spawn(r,e.emotion,e.rate,n,a,t,null,e.min,e.max,1,1,e.colors,this.currentUndertone)}_updatePhysics(e,t,i,n,a){const r=n.width/2,s=n.height/2,o=a?{undertone:a}:null;this.particleSystem.update(i,r,s,t?t.motion:null,t?t.progress:0,o)}_updateRendering(e,t,i,n,a,r){const s=i.width/2,o=i.height/2,l=e?this.effectsBuilder.build(e,s,o):null;this.renderer.updateParticles(this.particleSystem.particles,this.translator,t,i,n,a,e,r,this.geometryType),this.renderer.setGestureEffects(l)}setEmotion(e,t=null){this.currentEmotion=null,this.currentUndertone=null}setGeometryType(e){this.geometryType=e}clear(){this.particleSystem.clear()}setEnabled(e){this.renderer.setVisible(e),e||this.clear()}getParticleCount(){return this.particleSystem.particles.length}getCurrentConfig(){return this.currentConfig}registerEffect(e,t){this.effectsBuilder.registerEffect(e,t)}destroy(){this.particleSystem.destroy(),this.renderer.dispose(),this.translator&&(this.translator.dispose?.(),this.translator=null),this.emotionCalculator.clearCache(),this.emotionCalculator=null,this.gestureExtractor.reset(),this.gestureExtractor=null,this.effectsBuilder&&(this.effectsBuilder.destroy?.(),this.effectsBuilder=null)}}const Ld={quartz:{sssStrength:.8,sssAbsorption:[2.8,2.9,3],sssScatterDistance:[.2,.2,.25],sssThicknessBias:.6,sssThicknessScale:1.8,sssCurvatureScale:3,sssAmbient:.12,frostiness:.15,innerGlowStrength:.2,fresnelIntensity:1.5,causticIntensity:1.2},emerald:{sssStrength:2,sssAbsorption:[.05,4,.1],sssScatterDistance:[.1,.5,.1],sssThicknessBias:.65,sssThicknessScale:1.8,sssCurvatureScale:3,sssAmbient:.1,frostiness:.2,innerGlowStrength:.15,fresnelIntensity:1.2,emotionColorBleed:.35},ruby:{sssStrength:1.8,sssAbsorption:[4,.03,.08],sssScatterDistance:[.4,.04,.08],sssThicknessBias:.65,sssThicknessScale:1.9,sssCurvatureScale:2.5,sssAmbient:.08,frostiness:.12,innerGlowStrength:.12,fresnelIntensity:1.2,causticIntensity:1.15,emotionColorBleed:.35},sapphire:{sssStrength:2.2,sssAbsorption:[.15,.4,4],sssScatterDistance:[.1,.15,.5],sssThicknessBias:.65,sssThicknessScale:1.8,sssCurvatureScale:3,sssAmbient:.1,frostiness:.18,innerGlowStrength:.15,fresnelIntensity:1.3,emotionColorBleed:.35},amethyst:{sssStrength:2.5,sssAbsorption:[3,.05,4.5],sssScatterDistance:[.4,.05,.5],sssThicknessBias:.7,sssThicknessScale:2,sssCurvatureScale:3,sssAmbient:.08,frostiness:.18,innerGlowStrength:.12,fresnelIntensity:1.4,emotionColorBleed:.35}},Bd=`\nuniform float time;\nuniform vec3 emotionColor;\nuniform float glowIntensity;\nuniform float opacity;\n\n// Crystal appearance controls\nuniform float frostiness; // 0 = clear glass, 1 = fully frosted (default: 0.7)\nuniform float fresnelPower; // Edge brightness falloff (default: 3.0)\nuniform float fresnelIntensity; // Edge brightness strength (default: 1.2)\nuniform float innerGlowStrength; // How much inner soul shows through (default: 0.8)\nuniform float surfaceRoughness; // Surface texture variation (default: 0.3)\n\n// Enhanced lighting controls\nuniform float shadowDarkness; // How dark shadows can get (0-1, default: 0.4)\nuniform float specularIntensity; // Edge highlight brightness (default: 0.8)\nuniform float specularPower; // Specular falloff sharpness (default: 32.0)\nuniform float transmissionContrast; // Thin/thick brightness ratio (default: 1.5)\nuniform float minBrightness; // Minimum brightness floor (default: 0.05)\n\n// Noise scale controls\nuniform float surfaceNoiseScale; // Scale of surface frost pattern (default: 1.5)\nuniform float noiseFrequency; // Frequency of hash noise pattern (default: 1.0)\n\n// Internal caustics - light pooling inside the gem\nuniform float causticIntensity; // Brightness of internal caustics (default: 0.4)\nuniform float causticScale; // Scale of caustic pattern (default: 3.0)\nuniform float causticSpeed; // Animation speed of caustics (default: 0.15)\n\n// Texture\nuniform sampler2D crystalTexture;\nuniform float textureStrength; // How much texture affects appearance (default: 0.5)\n\n// Soul refraction - samples soul rendered to texture with optical distortion\nuniform sampler2D soulTexture; // Soul mesh rendered to texture\nuniform vec2 resolution; // Screen resolution for UV calculation\nuniform vec2 soulTextureSize; // Soul render target size (may differ from screen)\nuniform vec2 soulScreenCenter; // Soul center projected to screen UV (0-1 range)\nuniform float refractionIndex; // Index of refraction (1.5 glass, 2.4 diamond)\nuniform float refractionStrength; // Distortion magnitude (0.1-0.5)\n\n// Physically-based subsurface scattering\nuniform float sssStrength; // Overall SSS intensity (0-1)\nuniform vec3 sssAbsorption; // Absorption coefficients per RGB channel\nuniform vec3 sssScatterDistance; // Mean free path / scatter radius per RGB\nuniform float sssThicknessBias; // Thickness offset (0-1)\nuniform float sssThicknessScale; // Thickness multiplier\nuniform float sssCurvatureScale; // How much curvature affects SSS\nuniform float sssAmbient; // Ambient SSS contribution\nuniform vec3 sssLightDir; // Primary light direction for SSS\nuniform vec3 sssLightColor; // Light color for SSS\n\n// Emotion color bleed - how much soul color tints the gem material\nuniform float emotionColorBleed; // 0 = gem color only, 1 = full emotion tint (default: 0.0)\n\n// Component-specific blend layers\n// Shell layers - affect the frosted crystal shell\nuniform float shellLayer1Mode;\nuniform float shellLayer1Strength;\nuniform float shellLayer1Enabled;\nuniform float shellLayer2Mode;\nuniform float shellLayer2Strength;\nuniform float shellLayer2Enabled;\n\n// Soul layers - affect the inner glowing soul color\nuniform float soulLayer1Mode;\nuniform float soulLayer1Strength;\nuniform float soulLayer1Enabled;\nuniform float soulLayer2Mode;\nuniform float soulLayer2Strength;\nuniform float soulLayer2Enabled;\n\n// Rim layers - affect the fresnel rim glow\nuniform float rimLayer1Mode;\nuniform float rimLayer1Strength;\nuniform float rimLayer1Enabled;\nuniform float rimLayer2Mode;\nuniform float rimLayer2Strength;\nuniform float rimLayer2Enabled;\n\n// SSS layers - affect subsurface scattering contribution\nuniform float sssLayer1Mode;\nuniform float sssLayer1Strength;\nuniform float sssLayer1Enabled;\nuniform float sssLayer2Mode;\nuniform float sssLayer2Strength;\nuniform float sssLayer2Enabled;\n\nvarying vec3 vPosition;\nvarying vec3 vNormal;\nvarying vec3 vViewPosition;\nvarying vec2 vUv;\n\n// ═══════════════════════════════════════════════════════════════════════════\n// NOISE FUNCTIONS for surface variation and frosted effect\n// ═══════════════════════════════════════════════════════════════════════════\n\n// Simple 3D noise for frosted surface\nfloat hash(vec3 p) {\n p = p * noiseFrequency; // Apply frequency control\n p = fract(p * vec3(443.8975, 397.2973, 491.1871));\n p += dot(p.zxy, p.yxz + 19.19);\n return fract(p.x * p.y * p.z);\n}\n\nfloat noise3D(vec3 p) {\n vec3 i = floor(p);\n vec3 f = fract(p);\n f = f * f * (3.0 - 2.0 * f); // Smoothstep\n\n float n = mix(\n mix(\n mix(hash(i), hash(i + vec3(1, 0, 0)), f.x),\n mix(hash(i + vec3(0, 1, 0)), hash(i + vec3(1, 1, 0)), f.x),\n f.y\n ),\n mix(\n mix(hash(i + vec3(0, 0, 1)), hash(i + vec3(1, 0, 1)), f.x),\n mix(hash(i + vec3(0, 1, 1)), hash(i + vec3(1, 1, 1)), f.x),\n f.y\n ),\n f.z\n );\n return n;\n}\n\n// Fractal Brownian Motion for natural-looking frosted texture\nfloat fbm(vec3 p) {\n float value = 0.0;\n float amplitude = 0.5;\n float frequency = 1.0;\n\n for (int i = 0; i < 3; i++) {\n value += amplitude * noise3D(p * frequency);\n frequency *= 2.0;\n amplitude *= 0.5;\n }\n return value;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// BLEND MODES (from universal library)\n// ═══════════════════════════════════════════════════════════════════════════\n${Oh}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// ENHANCED LIGHTING FUNCTIONS\n// ═══════════════════════════════════════════════════════════════════════════\n\n// Calculate ambient occlusion from geometry\nfloat calculateAO(vec3 normal, vec3 viewDir, vec3 position) {\n // Faces pointing away from view are in shadow\n float viewAO = max(0.0, dot(normal, viewDir));\n\n // Use light direction for directional shadow instead of gravity\n // This creates shadows on the side away from light\n vec3 lightDir = normalize(vec3(0.5, 1.0, 0.8)); // Match sssLightDir default\n float lightAO = dot(normal, lightDir) * 0.5 + 0.5;\n\n // Combine AO factors - no gravity term\n return viewAO * 0.5 + lightAO * 0.5;\n}\n\n// Calculate specular highlights on facet edges\nfloat calculateFacetSpecular(vec3 normal, vec3 viewDir, vec3 lightDir, float power) {\n // Detect facet edges from normal discontinuities\n float edgeDetect = length(fwidth(normal)) * 15.0;\n edgeDetect = smoothstep(0.1, 0.5, edgeDetect);\n\n // Standard Blinn-Phong specular\n vec3 halfVec = normalize(lightDir + viewDir);\n float specular = pow(max(0.0, dot(normal, halfVec)), power);\n\n // Boost specular on edges\n specular += edgeDetect * 0.5;\n\n return specular;\n}\n\n// Calculate "fire" - intense sparkle points that real gems exhibit\n// These are concentrated, view-dependent highlights from light dispersion\nfloat calculateFire(vec3 normal, vec3 viewDir, vec3 lightDir) {\n // Primary fire highlight - VERY sharp falloff for pinpoint sparkles\n vec3 reflectDir = reflect(-lightDir, normal);\n float fire1 = pow(max(0.0, dot(reflectDir, viewDir)), 512.0);\n\n // Secondary fire from different light angle (simulates environment)\n vec3 lightDir2 = normalize(vec3(-0.3, 0.8, 0.5));\n vec3 reflectDir2 = reflect(-lightDir2, normal);\n float fire2 = pow(max(0.0, dot(reflectDir2, viewDir)), 384.0);\n\n // Third fire point for more sparkle\n vec3 lightDir3 = normalize(vec3(0.7, 0.4, -0.6));\n vec3 reflectDir3 = reflect(-lightDir3, normal);\n float fire3 = pow(max(0.0, dot(reflectDir3, viewDir)), 256.0);\n\n // Combine fire points - only keep the brightest peaks\n float fire = fire1 + fire2 * 0.7 + fire3 * 0.5;\n\n // Facet edges catch more fire\n float edgeFactor = length(fwidth(normal)) * 20.0;\n fire *= (1.0 + edgeFactor * 2.0);\n\n return fire;\n}\n\n// Calculate bright lines along facet edges where bevels catch light\nfloat calculateFacetEdgeLines(vec3 normal, vec3 viewDir, vec3 lightDir) {\n // Detect edges from normal discontinuities\n float edgeMag = length(fwidth(normal));\n\n // Sharp threshold to create distinct lines\n float edgeLine = smoothstep(0.02, 0.08, edgeMag);\n\n // Modulate by light angle - edges facing light are brighter\n float lightFacing = max(0.0, dot(normal, lightDir));\n edgeLine *= (0.3 + lightFacing * 0.7);\n\n // View-dependent - edges perpendicular to view are more visible\n float viewPerp = 1.0 - abs(dot(normal, viewDir));\n edgeLine *= (0.5 + viewPerp * 0.5);\n\n return edgeLine;\n}\n\n// Calculate light transmission based on thickness\nfloat calculateTransmission(vec3 position, vec3 normal, vec3 viewDir, float contrast) {\n // Thickness estimation - edges are thin, center is thick\n float distFromCenter = length(position);\n float thickness = smoothstep(0.0, 0.6, distFromCenter);\n\n // View angle affects perceived thickness\n float viewThickness = 1.0 - abs(dot(normal, viewDir));\n thickness = mix(thickness, viewThickness, 0.5);\n\n // Thin areas transmit more light (brighter), thick areas are darker\n float transmission = 1.0 - thickness * contrast * 0.5;\n\n return clamp(transmission, 0.3, 1.5);\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// PHYSICALLY-BASED SUBSURFACE SCATTERING\n// ═══════════════════════════════════════════════════════════════════════════\n\n// ═══════════════════════════════════════════════════════════════════════════\n// PHYSICALLY-BASED SUBSURFACE SCATTERING\n// Based on Disney's Burley Normalized Diffusion (2015)\n// ═══════════════════════════════════════════════════════════════════════════\n\n// SSS Uniforms - declare these in your shader\n// uniform float sssStrength; // Overall SSS intensity (0-1)\n// uniform vec3 sssAbsorption; // Absorption coefficients per RGB channel\n// uniform vec3 sssScatterDistance; // Mean free path / scatter radius per RGB\n// uniform float sssThicknessBias; // Thickness offset (0-1)\n// uniform float sssThicknessScale; // Thickness multiplier\n// uniform float sssCurvatureScale; // How much curvature affects SSS\n// uniform float sssAmbient; // Ambient SSS contribution\n// uniform vec3 sssLightDir; // Primary light direction for SSS\n// uniform vec3 sssLightColor; // Light color for SSS\n\n/**\n * Estimate local thickness from geometry\n * Uses the relationship between view angle and surface normal\n * Combined with a simple depth approximation\n *\n * @param normal - Surface normal in view space\n * @param viewDir - View direction\n * @param position - Vertex position (for depth-based estimation)\n * @param thicknessBias - Base thickness value\n * @param thicknessScale - Thickness multiplier\n * @return Estimated thickness (0-1)\n */\nfloat estimateThickness(vec3 normal, vec3 viewDir, vec3 position, float thicknessBias, float thicknessScale) {\n // Method 1: View-dependent thickness\n // Surfaces facing away from viewer are "thicker" (light travels further)\n float viewThickness = 1.0 - abs(dot(normal, viewDir));\n\n // Method 2: Position-based depth (simple spherical assumption)\n // Objects are thinner at edges, thicker in center\n float posDepth = 1.0 - length(position) * 0.5;\n posDepth = clamp(posDepth, 0.0, 1.0);\n\n // Method 3: Curvature hint from normal variation\n // High-frequency normal changes indicate thin areas (edges, details)\n // This is approximated by the gradient of the normal\n float curvatureHint = length(fwidth(normal)) * 10.0;\n curvatureHint = 1.0 - clamp(curvatureHint, 0.0, 1.0);\n\n // Combine methods with weighting\n float thickness = viewThickness * 0.4 + posDepth * 0.4 + curvatureHint * 0.2;\n\n // Apply bias and scale\n thickness = thicknessBias + thickness * thicknessScale;\n\n return clamp(thickness, 0.01, 1.0);\n}\n\n/**\n * Beer's Law absorption - light attenuates exponentially through material\n * Different wavelengths absorb at different rates, creating color shifts\n *\n * @param thickness - Distance light travels through material\n * @param absorption - Absorption coefficients per RGB (higher = more absorbed)\n * @return Transmittance per RGB channel (0-1)\n */\nvec3 beersLawAbsorption(float thickness, vec3 absorption) {\n // Beer-Lambert Law: T = e^(-σ * d)\n // Where σ is absorption coefficient, d is distance\n return exp(-absorption * thickness * 4.0);\n}\n\n/**\n * Burley Normalized Diffusion Profile\n * Disney's approximation of the full BSSRDF, energy-conserving\n *\n * R(r) = A * s * (e^(-s*r) + e^(-s*r/3)) / (8πr)\n *\n * @param radius - Distance from entry point (normalized)\n * @param scatterDist - Mean free path / diffusion length\n * @return Diffusion weight at this radius\n */\nfloat burleyDiffusionProfile(float radius, float scatterDist) {\n // Prevent division by zero\n float r = max(radius, 0.001);\n float s = 1.0 / max(scatterDist, 0.001);\n\n // Burley's two-term approximation\n float term1 = exp(-s * r);\n float term2 = exp(-s * r / 3.0);\n\n // Normalized profile (simplified, without 8πr for real-time)\n float profile = (term1 + term2) * s * 0.25;\n\n return profile;\n}\n\n/**\n * Christensen-Burley Normalized Diffusion\n * Improved version with better energy conservation\n *\n * @param radius - Distance from entry point\n * @param A - Surface albedo\n * @param d - Diffusion length (mean free path)\n * @return RGB diffusion weights\n */\nvec3 christensenBurleyDiffusion(float radius, vec3 A, vec3 d) {\n vec3 result = vec3(0.0);\n\n // Per-channel diffusion (different scatter distances for RGB)\n for (int i = 0; i < 3; i++) {\n float s = 1.9 - A[i] + 3.5 * (A[i] - 0.8) * (A[i] - 0.8);\n s = 1.0 / (s * max(d[i], 0.001));\n\n float r = max(radius, 0.001);\n\n // Two-exponential fit\n float profile = s * (exp(-s * r) + exp(-s * r / 3.0)) / (8.0 * 3.14159 * r);\n\n result[i] = profile;\n }\n\n return result;\n}\n\n/**\n * Calculate curvature factor for SSS intensity\n * SSS is more visible on curved surfaces (fingers, ears, edges)\n *\n * @param normal - Surface normal\n * @return Curvature factor (higher = more curved)\n */\nfloat calculateCurvature(vec3 normal) {\n // Use screen-space derivatives to estimate curvature\n vec3 dx = dFdx(normal);\n vec3 dy = dFdy(normal);\n\n // Curvature magnitude\n float curvature = length(dx) + length(dy);\n\n // Normalize to useful range\n return clamp(curvature * 5.0, 0.0, 1.0);\n}\n\n/**\n * Full physically-based SSS calculation\n * Combines all components for realistic translucent materials\n *\n * @param normal - Surface normal (view space)\n * @param viewDir - View direction\n * @param position - Vertex position\n * @param lightDir - Light direction\n * @param lightColor - Light color\n * @param baseColor - Material base/albedo color\n * @param sssStrength - Overall SSS strength\n * @param absorption - Absorption coefficients RGB (inverted: higher = MORE of that color)\n * @param scatterDist - Scatter distance RGB (higher = more scatter)\n * @param thicknessBias - Base thickness\n * @param thicknessScale - Thickness multiplier\n * @param curvatureScale - Curvature influence\n * @param ambient - Ambient SSS contribution\n * @return Final SSS color contribution\n */\nvec3 calculatePhysicalSSS(\n vec3 normal,\n vec3 viewDir,\n vec3 position,\n vec3 lightDir,\n vec3 lightColor,\n vec3 baseColor,\n float sssStrength,\n vec3 absorption,\n vec3 scatterDist,\n float thicknessBias,\n float thicknessScale,\n float curvatureScale,\n float ambient\n) {\n if (sssStrength < 0.001) {\n return vec3(0.0);\n }\n\n // ─────────────────────────────────────────────────────────────────────\n // THICKNESS ESTIMATION\n // ─────────────────────────────────────────────────────────────────────\n float thickness = estimateThickness(normal, viewDir, position, thicknessBias, thicknessScale);\n\n // ─────────────────────────────────────────────────────────────────────\n // ABSORPTION COLOR (Beer's Law with artist-friendly values)\n // Creates the characteristic color of translucent materials\n // absorption values: high value = MORE of that color passes through (transmitted)\n // This is inverted from physics but intuitive: jade has high green absorption\n // ─────────────────────────────────────────────────────────────────────\n // Use absorption directly as transmittance - higher = more of that color shows\n // Normalize to prevent any channel from dominating\n float maxAbsorption = max(absorption.r, max(absorption.g, absorption.b));\n vec3 normalizedTransmit = absorption / max(maxAbsorption, 0.001);\n\n // Apply thickness-based falloff - thin areas show more color\n float thicknessFactor = 1.0 - thickness * 0.3;\n vec3 colorShift = normalizedTransmit * thicknessFactor;\n\n // Ensure minimum color presence\n colorShift = max(colorShift, vec3(0.15));\n\n // ─────────────────────────────────────────────────────────────────────\n // SCATTER INTENSITY\n // How much light scatters based on material properties\n // ─────────────────────────────────────────────────────────────────────\n // Higher scatter distance = more light gets through, but keep it subtle\n vec3 scatterIntensity = scatterDist * 0.8;\n scatterIntensity = clamp(scatterIntensity, vec3(0.1), vec3(1.0));\n\n // ─────────────────────────────────────────────────────────────────────\n // LIGHTING TERMS - Boosted for visibility\n // ─────────────────────────────────────────────────────────────────────\n\n // Back-lighting: light passing through from behind (strongest SSS cue)\n float NdotL = dot(normal, lightDir);\n float backLight = max(0.0, -NdotL);\n backLight = pow(backLight, 1.2) * 1.5; // Boosted\n\n // Wrap lighting: soft diffuse that wraps around\n float wrapLight = (NdotL + 1.0) * 0.5; // Full wrap, 0-1 range\n wrapLight = wrapLight * wrapLight;\n\n // View-dependent translucency (looking through thin parts)\n float VdotL = dot(viewDir, -lightDir);\n float translucency = pow(max(0.0, VdotL), 1.5) * 1.2; // Boosted\n\n // Edge glow (fresnel-like SSS at silhouettes)\n float edgeGlow = pow(1.0 - abs(dot(normal, viewDir)), 2.0);\n\n // ─────────────────────────────────────────────────────────────────────\n // THICKNESS-BASED TRANSMISSION\n // Thin areas let more light through\n // ─────────────────────────────────────────────────────────────────────\n float thinTransmission = 1.0 - thickness * 0.5;\n thinTransmission = max(thinTransmission, 0.3);\n\n // ─────────────────────────────────────────────────────────────────────\n // CURVATURE ENHANCEMENT\n // ─────────────────────────────────────────────────────────────────────\n float curvature = calculateCurvature(normal);\n float curvatureFactor = 1.0 + curvature * curvatureScale;\n\n // ─────────────────────────────────────────────────────────────────────\n // COMBINE ALL TERMS\n // ─────────────────────────────────────────────────────────────────────\n\n // Total light contribution (more additive for visibility)\n float totalLight = backLight + translucency * 0.8 + wrapLight * 0.4 + edgeGlow * 0.5;\n totalLight *= curvatureFactor * thinTransmission;\n\n // Base SSS color - colorShift IS the tint (e.g., green for jade)\n // Don't multiply by baseColor to avoid washing out with emotionColor\n vec3 sssColor = colorShift * scatterIntensity;\n\n // Ambient SSS (always visible, gives material its translucent look)\n vec3 ambientSSS = sssColor * ambient;\n\n // Direct SSS from lighting - subtle contribution\n vec3 directSSS = sssColor * lightColor * totalLight * 0.5;\n\n // Final combination\n vec3 finalSSS = directSSS + ambientSSS;\n\n // Apply overall strength (linear, no boost to prevent blowout)\n return finalSSS * sssStrength;\n}\n\n/**\n * Simplified SSS for performance-critical scenarios\n * Uses pre-computed approximations\n *\n * @param normal - Surface normal\n * @param viewDir - View direction\n * @param lightDir - Light direction\n * @param thickness - Pre-computed or approximated thickness\n * @param baseColor - Material color\n * @param scatterColor - Scatter tint color\n * @param strength - SSS strength\n * @return SSS color contribution\n */\nvec3 calculateSimpleSSS(\n vec3 normal,\n vec3 viewDir,\n vec3 lightDir,\n float thickness,\n vec3 baseColor,\n vec3 scatterColor,\n float strength\n) {\n if (strength < 0.001) {\n return vec3(0.0);\n }\n\n // Back-lighting\n float backLight = pow(max(0.0, dot(viewDir, -lightDir)), 2.0);\n\n // Transmittance (simplified Beer's law)\n float transmit = exp(-thickness * 2.0);\n\n // Edge enhancement\n float edge = pow(1.0 - abs(dot(normal, viewDir)), 2.0);\n\n // Combine\n float sssIntensity = (backLight * transmit + edge * 0.3) * strength;\n\n return mix(baseColor, scatterColor, 0.5) * sssIntensity;\n}\n\n\nvoid main() {\n vec3 normal = normalize(vNormal);\n vec3 viewDir = normalize(vViewPosition);\n\n // ═══════════════════════════════════════════════════════════════════════\n // FRESNEL EFFECT - Colored rim at edges (cyan-tinted)\n // ═══════════════════════════════════════════════════════════════════════\n float fresnel = pow(1.0 - abs(dot(normal, viewDir)), fresnelPower);\n fresnel *= fresnelIntensity;\n\n // ═══════════════════════════════════════════════════════════════════════\n // AMBIENT OCCLUSION - Dark shadows for depth\n // ═══════════════════════════════════════════════════════════════════════\n float ao = calculateAO(normal, viewDir, vPosition);\n float shadowFactor = mix(1.0, ao, shadowDarkness);\n\n // ═══════════════════════════════════════════════════════════════════════\n // SPECULAR HIGHLIGHTS - Bright catches on facet edges\n // ═══════════════════════════════════════════════════════════════════════\n vec3 lightDir = normalize(sssLightDir);\n float specular = calculateFacetSpecular(normal, viewDir, lightDir, specularPower);\n specular *= specularIntensity;\n\n // ═══════════════════════════════════════════════════════════════════════\n // LIGHT TRANSMISSION - Thin areas glow, thick areas darken\n // ═══════════════════════════════════════════════════════════════════════\n float transmission = calculateTransmission(vPosition, normal, viewDir, transmissionContrast);\n\n // ═══════════════════════════════════════════════════════════════════════\n // TEXTURE SAMPLING - Crystal surface detail from UV-mapped texture\n // ═══════════════════════════════════════════════════════════════════════\n vec4 texColor = texture2D(crystalTexture, vUv);\n float texValue = (texColor.r + texColor.g + texColor.b) / 3.0; // Grayscale\n\n // ═══════════════════════════════════════════════════════════════════════\n // FROSTED SURFACE - Subtle cloudy variation (not opaque white!)\n // ═══════════════════════════════════════════════════════════════════════\n float surfaceNoise = fbm(vPosition * surfaceNoiseScale + time * 0.02);\n surfaceNoise = surfaceNoise * surfaceRoughness;\n\n // ═══════════════════════════════════════════════════════════════════════\n // INNER SOUL GLOW - The glowing core visible through the crystal\n // ═══════════════════════════════════════════════════════════════════════\n\n // Animated internal glow - subtle pulsing\n float glowPulse = sin(time * 0.5) * 0.15 + 0.85;\n\n // Core glow - strongest in center, fades toward edges with sharper falloff\n float distFromCenter = length(vPosition);\n float coreGlow = exp(-distFromCenter * 2.5) * glowPulse;\n\n // ═══════════════════════════════════════════════════════════════════════\n // INTERNAL CAUSTICS - Light refraction pools inside the gem\n // Creates bright concentrated spots that shift with viewing angle\n // Real caustics form where refracted light rays converge inside the gem\n // Now with CHROMATIC ABERRATION - different wavelengths refract differently\n // ═══════════════════════════════════════════════════════════════════════\n\n // Refract view direction through gem surface with different IOR per wavelength\n // Red refracts less (higher IOR ratio), blue refracts more (lower IOR ratio)\n // Chromatic separation is REDUCED for colored gems to avoid color contamination\n // Quartz (low sssStrength) gets full rainbow, colored gems get subtle dispersion\n float chromaticStrength = 1.0 - clamp((sssStrength - 0.5) * 0.8, 0.0, 0.8);\n float iorR = mix(0.57, 0.70, chromaticStrength); // Red - approaches green for colored gems\n float iorB = mix(0.57, 0.44, chromaticStrength); // Blue - approaches green for colored gems\n vec3 refractDirR = refract(-viewDir, normal, iorR);\n vec3 refractDirG = refract(-viewDir, normal, 0.57); // Green - always medium\n vec3 refractDirB = refract(-viewDir, normal, iorB);\n\n // Animated drift\n float causticTime = time * causticSpeed;\n vec3 drift = vec3(causticTime * 0.3, causticTime * 0.2, causticTime * 0.1);\n\n // Sample positions for each color channel\n // Offset is also reduced for colored gems to minimize chromatic contamination\n float spatialOffset = mix(1.0, 3.0, chromaticStrength);\n vec3 causticPosR = vPosition * causticScale + refractDirR * spatialOffset + drift;\n vec3 causticPosG = vPosition * causticScale + refractDirG * spatialOffset + drift;\n vec3 causticPosB = vPosition * causticScale + refractDirB * spatialOffset + drift;\n\n // Create caustic pattern for each channel\n // Red channel\n float waveR1 = sin(causticPosR.x * 2.0 + causticPosR.y * 1.5 + causticPosR.z);\n float waveR2 = sin(causticPosR.y * 2.3 - causticPosR.x * 1.2 + causticPosR.z * 1.8);\n float waveR3 = sin(causticPosR.z * 1.9 + causticPosR.x * 0.8 - causticPosR.y * 1.4);\n float interferenceR = (waveR1 + waveR2 + waveR3) / 3.0;\n float causticR = smoothstep(0.3, 0.8, interferenceR);\n\n // Green channel\n float waveG1 = sin(causticPosG.x * 2.0 + causticPosG.y * 1.5 + causticPosG.z);\n float waveG2 = sin(causticPosG.y * 2.3 - causticPosG.x * 1.2 + causticPosG.z * 1.8);\n float waveG3 = sin(causticPosG.z * 1.9 + causticPosG.x * 0.8 - causticPosG.y * 1.4);\n float interferenceG = (waveG1 + waveG2 + waveG3) / 3.0;\n float causticG = smoothstep(0.3, 0.8, interferenceG);\n\n // Blue channel\n float waveB1 = sin(causticPosB.x * 2.0 + causticPosB.y * 1.5 + causticPosB.z);\n float waveB2 = sin(causticPosB.y * 2.3 - causticPosB.x * 1.2 + causticPosB.z * 1.8);\n float waveB3 = sin(causticPosB.z * 1.9 + causticPosB.x * 0.8 - causticPosB.y * 1.4);\n float interferenceB = (waveB1 + waveB2 + waveB3) / 3.0;\n float causticB = smoothstep(0.3, 0.8, interferenceB);\n\n // Combine into RGB caustic with chromatic separation\n vec3 causticRGB = vec3(causticR, causticG, causticB);\n\n // Add noise variation to break up uniformity\n float noiseVar = noise3D(causticPosG * 0.5);\n causticRGB *= (0.7 + noiseVar * 0.6);\n\n // Clamp caustic peaks to prevent hot spot blobs\n // This keeps caustics subtle and distributed rather than concentrated\n causticRGB = min(causticRGB, vec3(0.6));\n\n // Caustics are MORE visible in thick areas (center) where light has more\n // material to refract through and pool\n float thickness = abs(dot(normal, viewDir)); // 1 at center, 0 at edges\n causticRGB *= (0.3 + thickness * 0.7);\n\n // Apply intensity control\n causticRGB *= causticIntensity;\n\n // Boost caustic visibility for colored gems to compensate for reduced chromatic spread\n // Colored gems (high sssStrength) have suppressed chromatic aberration, so boost their\n // monochromatic caustics to maintain internal "life" and sparkle\n float causticBoost = 1.0 + clamp((sssStrength - 0.5) * 0.8, 0.0, 0.6);\n causticRGB *= causticBoost;\n\n // Also keep a scalar caustic for compatibility\n float caustic = (causticRGB.r + causticRGB.g + causticRGB.b) / 3.0;\n\n // Animation pattern (0-1 range) - core glow + caustic hot spots\n float animationPattern = coreGlow * 0.7 + caustic * 0.3;\n\n // Soul intensity controls overall brightness with more dramatic falloff\n // Brighter near core, darker at edges\n float baseLevel = 0.1; // Lower base for more contrast\n float patternContrast = 0.9; // Higher contrast for more variation\n float soulIntensity = (baseLevel + animationPattern * patternContrast) * innerGlowStrength;\n\n // Apply transmission to soul - thin areas glow brighter\n soulIntensity *= transmission;\n\n // Soul color from emotion\n // NOTE: emotionColor is pre-normalized by normalizeColorLuminance() in Core3DManager\n // This ensures consistent perceived brightness across all emotions (yellow won't wash out, blue stays visible)\n // Reduced intensity to prevent blowout - soul should be visible but not white\n float glowCurve = sqrt(innerGlowStrength * glowIntensity) * 0.5;\n vec3 soulColor = emotionColor * soulIntensity * glowCurve;\n // Clamp soul color to prevent blowout\n soulColor = min(soulColor, vec3(0.8));\n\n // ═══════════════════════════════════════════════════════════════════════\n // REFRACTED SOUL SAMPLING - True optical lensing through crystal\n // The soul is rendered to a texture, then sampled with refraction distortion\n // This creates the effect of looking at the soul through a crystal lens\n // ═══════════════════════════════════════════════════════════════════════\n\n // ═══════════════════════════════════════════════════════════════════\n // REFRACTED SOUL SAMPLING\n // Sample the soul texture with physical refraction distortion\n // Creates the "looking through glass" lensing effect\n // ═══════════════════════════════════════════════════════════════════\n vec3 refractedSoulColor = vec3(0.0);\n float refractedSoulAlpha = 0.0;\n\n if (soulTextureSize.x > 0.0 && soulScreenCenter.x >= 0.0) {\n // Fragment's screen UV position\n vec2 fragUV = gl_FragCoord.xy / soulTextureSize;\n\n // Calculate refraction offset using Snell's law\n float ior = refractionIndex;\n vec3 refractedDir = refract(-viewDir, normal, 1.0 / ior);\n\n // Apply refraction distortion toward the soul center\n // This creates the magnifying glass effect - bending light toward center\n vec2 refractionOffset = refractedDir.xy * refractionStrength * 0.1;\n\n // Sample at fragment position with refraction offset\n // The soul texture contains the soul rendered at its actual screen position\n vec2 soulUV = fragUV + refractionOffset;\n\n // Clamp to valid UV range\n soulUV = clamp(soulUV, 0.0, 1.0);\n\n // Sample the soul texture\n vec4 soulSample = texture2D(soulTexture, soulUV);\n\n // Store for later use in final composition\n refractedSoulColor = soulSample.rgb;\n refractedSoulAlpha = soulSample.a;\n\n // Also blend into soulColor for existing pipeline\n soulColor = mix(soulColor, soulSample.rgb, soulSample.a * 0.5);\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // SOUL BLEND LAYERS - Apply before combining with shell\n // ═══════════════════════════════════════════════════════════════════════\n if (soulLayer1Enabled > 0.5) {\n int mode = int(soulLayer1Mode + 0.5);\n vec3 blendResult = applyBlendMode(soulColor, emotionColor * soulLayer1Strength, mode);\n soulColor = mix(soulColor, blendResult, soulLayer1Strength);\n }\n if (soulLayer2Enabled > 0.5) {\n int mode = int(soulLayer2Mode + 0.5);\n vec3 blendResult = applyBlendMode(soulColor, emotionColor * soulLayer2Strength, mode);\n soulColor = mix(soulColor, blendResult, soulLayer2Strength);\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // FROSTED SHELL - Milky white layer with INTERNAL lighting model\n // Lit from inside: thin edges bright, thick center dark\n // ═══════════════════════════════════════════════════════════════════════\n\n // Frosted glass base - will be modulated by thickness\n // Lower base values allow for darker thick areas while maintaining bright edges\n vec3 frostBase = vec3(0.45, 0.48, 0.55) * frostiness;\n\n // THICKNESS-BASED DARKNESS (internal lighting model)\n // Face-on facets are THICK (light travels far through) = DARK\n // Edge-on facets are THIN (light escapes easily) = BRIGHT\n float edgeThinness = 1.0 - abs(dot(normal, viewDir)); // 1 at edges, 0 facing camera\n\n // Apply curve to make face-on areas darker more aggressively\n float thinness = pow(edgeThinness, 0.7); // Push more area toward dark\n\n // Thickness multiplier: thin edges=bright (1.0), thick face-on=dark (0.01 for near-black)\n float thicknessMultiplier = 0.01 + thinness * 0.99;\n frostBase *= thicknessMultiplier;\n\n // Surface variation adds subtle texture\n frostBase += vec3(surfaceNoise * 0.03);\n\n // Specular highlights on facet edges (external light catch)\n float facetHighlight = pow(max(0.0, dot(normal, normalize(vec3(0.5, 1.0, 0.8)))), 16.0);\n frostBase += vec3(facetHighlight * 0.2);\n\n // SOUL BLEED - Inner glow illuminates the shell from inside\n // Use gentler falloff so color reaches the shell surface\n float soulBleed = exp(-distFromCenter * 1.2) * innerGlowStrength;\n // Stronger color contribution - tint the frost with emotion color\n frostBase = mix(frostBase, frostBase + emotionColor * 0.4, soulBleed);\n\n // ═══════════════════════════════════════════════════════════════════════\n // SHELL BLEND LAYERS - Apply to frosted shell\n // ═══════════════════════════════════════════════════════════════════════\n if (shellLayer1Enabled > 0.5) {\n int mode = int(shellLayer1Mode + 0.5);\n vec3 blendResult = applyBlendMode(frostBase, emotionColor * shellLayer1Strength, mode);\n frostBase = mix(frostBase, blendResult, shellLayer1Strength);\n }\n if (shellLayer2Enabled > 0.5) {\n int mode = int(shellLayer2Mode + 0.5);\n vec3 blendResult = applyBlendMode(frostBase, emotionColor * shellLayer2Strength, mode);\n frostBase = mix(frostBase, blendResult, shellLayer2Strength);\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // FRESNEL RIM - Bright emotion-colored edge glow\n // ═══════════════════════════════════════════════════════════════════════\n vec3 rimColor = mix(vec3(0.5, 0.9, 1.0), emotionColor, 0.6);\n vec3 rimGlow = rimColor * fresnel * 1.2;\n\n // ═══════════════════════════════════════════════════════════════════════\n // RIM BLEND LAYERS - Apply to fresnel rim glow\n // ═══════════════════════════════════════════════════════════════════════\n if (rimLayer1Enabled > 0.5) {\n int mode = int(rimLayer1Mode + 0.5);\n vec3 blendResult = applyBlendMode(rimGlow, emotionColor * rimLayer1Strength, mode);\n rimGlow = mix(rimGlow, blendResult, rimLayer1Strength);\n }\n if (rimLayer2Enabled > 0.5) {\n int mode = int(rimLayer2Mode + 0.5);\n vec3 blendResult = applyBlendMode(rimGlow, emotionColor * rimLayer2Strength, mode);\n rimGlow = mix(rimGlow, blendResult, rimLayer2Strength);\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // PHYSICALLY-BASED SUBSURFACE SCATTERING\n // Uses BSSRDF with Beer's Law absorption and Burley diffusion profile\n // ═══════════════════════════════════════════════════════════════════════\n vec3 sss = calculatePhysicalSSS(\n normal,\n viewDir,\n vPosition,\n normalize(sssLightDir),\n sssLightColor,\n emotionColor,\n sssStrength,\n sssAbsorption,\n sssScatterDistance,\n sssThicknessBias,\n sssThicknessScale,\n sssCurvatureScale,\n sssAmbient\n );\n\n // ═══════════════════════════════════════════════════════════════════════\n // SSS BLEND LAYERS - Apply to subsurface scattering contribution\n // ═══════════════════════════════════════════════════════════════════════\n if (sssLayer1Enabled > 0.5) {\n int mode = int(sssLayer1Mode + 0.5);\n vec3 blendResult = applyBlendMode(sss, emotionColor * sssLayer1Strength, mode);\n sss = mix(sss, blendResult, sssLayer1Strength);\n }\n if (sssLayer2Enabled > 0.5) {\n int mode = int(sssLayer2Mode + 0.5);\n vec3 blendResult = applyBlendMode(sss, emotionColor * sssLayer2Strength, mode);\n sss = mix(sss, blendResult, sssLayer2Strength);\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // COMBINE - Frosted shell base + soul glow (soul adds to shell, doesn't replace)\n // ═══════════════════════════════════════════════════════════════════════\n\n // Start with shell as base - preserves dark shadows\n vec3 finalColor = frostBase;\n\n // Add soul glow on top (additive, not replacement) - concentrated in center\n // Soul should illuminate dark areas but not wash out entirely\n float soulBlendFactor = soulIntensity * 0.6;\n finalColor += soulColor * soulBlendFactor;\n\n // Apply texture - blend based on texture brightness and strength\n vec3 texContribution = texColor.rgb * textureStrength;\n finalColor = mix(finalColor, finalColor + texContribution, textureStrength);\n\n // Apply SSS material color - PRESERVE BRIGHTNESS, only change HUE\n // The sssAbsorption values define the material color hue\n // But thickness-based darkness must be preserved for gemstone look\n if (sssStrength > 0.01) {\n // Get current brightness (this includes thickness darkening)\n float currentLum = dot(finalColor, vec3(0.299, 0.587, 0.114));\n\n // Normalize absorption to get hue direction (0-1 range)\n vec3 absorption = sssAbsorption;\n float maxAbs = max(max(absorption.r, absorption.g), absorption.b);\n vec3 hue = absorption / max(maxAbs, 0.001);\n\n // Create material color that PRESERVES current brightness\n // This keeps dark areas dark while tinting them with the gem color\n float hueLum = dot(hue, vec3(0.299, 0.587, 0.114));\n vec3 materialColor = hue * currentLum / max(hueLum, 0.001);\n\n // Clamp to prevent blowout on bright areas\n materialColor = min(materialColor, vec3(1.0));\n\n // Add subtle variation from SSS lighting calculation\n float sssLum = dot(sss, vec3(0.299, 0.587, 0.114));\n materialColor *= (0.9 + sssLum * 0.2);\n\n // Replace crystal color with material color\n float replaceAmount = sssStrength * 0.7;\n finalColor = mix(finalColor, materialColor, replaceAmount);\n }\n\n // Add rim glow, tinted toward material color\n if (sssStrength > 0.01) {\n vec3 absorption = sssAbsorption;\n float maxAbs = max(max(absorption.r, absorption.g), absorption.b);\n vec3 hue = absorption / max(maxAbs, 0.001);\n // Stronger tint for colored gems - use gem hue directly\n float rimTintStrength = clamp(sssStrength * 0.6, 0.0, 0.95);\n vec3 tintedRim = rimGlow * mix(vec3(1.0), hue * 1.2, rimTintStrength);\n // Cap rim to prevent bloom\n tintedRim = min(tintedRim, vec3(0.5));\n finalColor += tintedRim;\n } else {\n finalColor += rimGlow;\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // SPECULAR HIGHLIGHTS - Add bright hot spots\n // Tinted by gem color for colored gems to prevent white bloom\n // ═══════════════════════════════════════════════════════════════════════\n vec3 specularColor = vec3(1.0, 0.98, 0.95); // Warm white highlights for clear gems\n float specularIntensityMod = 1.0;\n\n if (sssStrength > 0.5) {\n // Tint specular by gem color to prevent white bloom\n vec3 absorption = sssAbsorption;\n float maxAbs = max(max(absorption.r, absorption.g), absorption.b);\n vec3 gemHue = absorption / max(maxAbs, 0.001);\n float colorStrength = clamp((sssStrength - 0.5) * 0.5, 0.0, 1.0);\n // Use gem hue for specular color\n specularColor = mix(specularColor, gemHue * 1.3, colorStrength);\n // Also reduce specular intensity for colored gems\n specularIntensityMod = mix(1.0, 0.4, colorStrength);\n }\n\n vec3 specularContrib = specularColor * specular * transmission * specularIntensityMod;\n specularContrib = min(specularContrib, vec3(0.5)); // Cap specular to prevent bloom\n finalColor += specularContrib;\n\n // ═══════════════════════════════════════════════════════════════════════\n // FACET EDGE LINES - Bright catches along beveled edges\n // ═══════════════════════════════════════════════════════════════════════\n float edgeLines = calculateFacetEdgeLines(normal, viewDir, lightDir);\n finalColor += vec3(edgeLines * 0.15) * transmission;\n\n // ═══════════════════════════════════════════════════════════════════════\n // SATURATION BOOST AT THIN EDGES\n // Real gems have MORE saturated color at thin edges where light escapes\n // ═══════════════════════════════════════════════════════════════════════\n if (sssStrength > 0.01) {\n // thinness: 1 at edges, 0 facing camera\n float satBoost = thinness * 0.4; // Up to 40% saturation boost at edges\n\n // Get current color's saturation\n float maxC = max(max(finalColor.r, finalColor.g), finalColor.b);\n float minC = min(min(finalColor.r, finalColor.g), finalColor.b);\n float currentSat = maxC > 0.001 ? (maxC - minC) / maxC : 0.0;\n\n // Boost saturation at thin areas\n if (maxC > 0.001 && currentSat > 0.01) {\n // Calculate luminance\n float lum = dot(finalColor, vec3(0.299, 0.587, 0.114));\n // Increase saturation by moving away from gray toward the color\n vec3 gray = vec3(lum);\n float newSat = min(currentSat + satBoost, 1.0);\n float satRatio = currentSat > 0.001 ? newSat / currentSat : 1.0;\n finalColor = gray + (finalColor - gray) * satRatio;\n }\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // FINAL THICKNESS APPLICATION - Apply AFTER all additive terms\n // This ensures thick areas stay dark even with glow added\n // ═══════════════════════════════════════════════════════════════════════\n // thicknessMultiplier: 0.15 in thick center, 1.0 at thin edges\n finalColor *= thicknessMultiplier;\n\n // ═══════════════════════════════════════════════════════════════════════\n // INTERNAL CAUSTICS - Bright spots from light concentration inside gem\n // Now with chromatic aberration for rainbow dispersion effect\n // Applied AFTER thickness darkening so they punch through dark areas\n // ═══════════════════════════════════════════════════════════════════════\n if (causticIntensity > 0.01) {\n // Get material hue for tinting caustics\n vec3 causticTint = vec3(1.0); // Default white\n float causticTintStrength = 0.4; // Default for clear gems\n if (sssStrength > 0.5) {\n vec3 absorption = sssAbsorption;\n float maxAbs = max(max(absorption.r, absorption.g), absorption.b);\n vec3 hue = absorption / max(maxAbs, 0.001);\n // Stronger tint for colored gems to prevent white bloom\n causticTintStrength = clamp((sssStrength - 0.5) * 0.8 + 0.4, 0.4, 0.9);\n causticTint = mix(vec3(1.0), hue * 1.2, causticTintStrength);\n }\n // Add RGB caustic with chromatic aberration\n // Reduce raw RGB blend for colored gems\n float rawBlend = mix(0.3, 0.1, clamp((sssStrength - 0.5) * 0.5, 0.0, 1.0));\n vec3 causticFinal = causticRGB * causticTint + causticRGB * rawBlend;\n causticFinal = min(causticFinal, vec3(0.4)); // Cap to prevent bloom\n finalColor += causticFinal;\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // FIRE - Intense sparkle points from light dispersion in facets\n // The "fire" effect that makes gems sparkle brilliantly\n // ═══════════════════════════════════════════════════════════════════════\n float fire = calculateFire(normal, viewDir, lightDir);\n\n // Tint fire by gem color - colored gems should have tinted highlights\n // Pure white fire only for quartz/clear gems (low sssStrength)\n vec3 fireColor = vec3(1.0, 0.99, 0.97); // Base warm white\n float fireIntensity = 0.3; // Base intensity for clear gems\n float fireClamp = 1.5; // Max fire value for clear gems\n\n if (sssStrength > 0.5) {\n // Get gem hue from absorption - this IS the gem's color\n vec3 absorption = sssAbsorption;\n float maxAbs = max(max(absorption.r, absorption.g), absorption.b);\n vec3 gemHue = absorption / max(maxAbs, 0.001);\n\n // For colored gems, fire should BE the gem color, not white\n // The more colored the gem (higher sssStrength), the more the fire matches the gem\n float colorStrength = clamp((sssStrength - 0.5) * 0.5, 0.0, 1.0);\n\n // Use gem hue directly as fire color - NOT mixed with white\n // This ensures fire can never bloom to white\n fireColor = gemHue * 1.2; // Slight brightness boost but stay saturated\n\n // Reduce fire intensity AND clamp for colored gems to prevent bloom washout\n // Colored gems should have subtle, saturated fire, not bright white spots\n fireIntensity = mix(0.3, 0.08, colorStrength); // Much lower for colored gems\n fireClamp = mix(1.5, 0.5, colorStrength); // Much lower clamp for colored gems\n }\n\n // Apply fire clamp BEFORE multiplying by color\n fire = min(fire, fireClamp);\n\n // Calculate fire contribution and clamp to prevent any channel from blooming\n vec3 fireContribution = fireColor * fire * fireIntensity;\n fireContribution = min(fireContribution, vec3(0.4)); // Hard cap on fire brightness\n finalColor += fireContribution;\n\n // Ensure minimum brightness - allow near-black for gemstones\n // minBrightness of 0.01 allows true darks while preventing total black\n finalColor = max(finalColor, vec3(minBrightness));\n\n // ═══════════════════════════════════════════════════════════════════════\n // ALPHA - More opaque for visibility\n // ═══════════════════════════════════════════════════════════════════════\n\n // Higher base opacity\n float baseAlpha = 0.6 + frostiness * 0.25;\n\n // Fresnel makes edges solid\n float rimAlpha = fresnel * 0.3;\n\n // Soul glow adds opacity\n float glowAlpha = soulIntensity * 0.15;\n\n float finalAlpha = min(baseAlpha + rimAlpha + glowAlpha, 0.95) * opacity;\n\n // ═══════════════════════════════════════════════════════════════════════\n // REFRACTED SOUL - Add the soul visible through the crystal\n // This is the actual soul mesh rendered to texture and sampled with refraction\n // ═══════════════════════════════════════════════════════════════════════\n if (refractedSoulAlpha > 0.01) {\n // The soul should glow through the crystal, tinted by the crystal's color\n // Use additive blending so the soul illuminates the crystal from within\n vec3 soulGlow = refractedSoulColor * refractedSoulAlpha;\n\n // Tint the soul by the crystal's SSS color for colored gems\n // emotionColorBleed controls how much pure emotion color comes through\n // 0 = fully tinted by gem color, 1 = pure emotion color\n if (sssStrength > 0.01) {\n vec3 absorption = sssAbsorption;\n float maxAbs = max(max(absorption.r, absorption.g), absorption.b);\n vec3 gemHue = absorption / max(maxAbs, 0.001);\n float tintAmount = sssStrength * 0.5 * (1.0 - emotionColorBleed);\n soulGlow *= mix(vec3(1.0), gemHue, tintAmount);\n }\n\n // Add soul glow to final color\n finalColor += soulGlow * 0.8;\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // EMOTION COLOR BLEED - Additional inner glow from soul emotion\n // Adds pure emotion color as light shining through the gem from the soul\n // ═══════════════════════════════════════════════════════════════════════\n if (emotionColorBleed > 0.001 && sssStrength > 0.01) {\n // Inner glow based on thickness - thinner areas show more soul light\n float innerGlow = 1.0 - abs(dot(normal, viewDir)); // Edges are thin\n innerGlow = pow(innerGlow, 1.5) * emotionColorBleed;\n\n // Also add glow near the core\n float coreProximity = exp(-distFromCenter * 2.0);\n innerGlow += coreProximity * emotionColorBleed * 0.5;\n\n // Add pure emotion color as inner light\n finalColor += emotionColor * innerGlow * 0.4;\n }\n\n gl_FragColor = vec4(finalColor, finalAlpha);\n}\n`,Od={time:0,glowIntensity:1,opacity:1,frostiness:.55,fresnelPower:2.8,fresnelIntensity:.35,innerGlowStrength:.55,surfaceRoughness:.12,shadowDarkness:.6,specularIntensity:.9,specularPower:28,transmissionContrast:1,minBrightness:.005,surfaceNoiseScale:1.5,noiseFrequency:1.33,causticIntensity:.8,causticScale:2,causticSpeed:.12,textureStrength:.55,refractionIndex:1.5,refractionStrength:.5,resolution:[1920,1080],soulTextureSize:[1920,1080],soulScreenCenter:[.5,.5],sssStrength:.65,sssAbsorption:[2.4,2.5,2.8],sssScatterDistance:[.35,.4,.45],sssThicknessBias:.18,sssThicknessScale:.6,sssCurvatureScale:1.8,sssAmbient:.3,sssLightDir:[.5,1,.8],sssLightColor:[1,.98,.95],shellLayer1Mode:0,shellLayer1Strength:0,shellLayer1Enabled:0,shellLayer2Mode:0,shellLayer2Strength:0,shellLayer2Enabled:0,soulLayer1Mode:0,soulLayer1Strength:0,soulLayer1Enabled:0,soulLayer2Mode:0,soulLayer2Strength:0,soulLayer2Enabled:0,rimLayer1Mode:0,rimLayer1Strength:0,rimLayer1Enabled:0,rimLayer2Mode:0,rimLayer2Strength:0,rimLayer2Enabled:0,sssLayer1Mode:0,sssLayer1Strength:0,sssLayer1Enabled:0,sssLayer2Mode:0,sssLayer2Strength:0,sssLayer2Enabled:0};function Fd(e,t,i={}){const{glowColor:n=[1,1,.95],glowIntensity:a=1,materialVariant:r=null,emotionData:s=null,assetBasePath:o="/assets"}=i;return"custom"===t.material?function(e,t,i,n,a,r){const s=new Or;switch(e){case"moon":return function(e,t,i,n=null,a="/assets"){const r=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)?"2k":"4k";if("multiplexer"===n)return{material:nc(e,{resolution:r,glowColor:new dn(t[0],t[1],t[2]),glowIntensity:i,assetBasePath:a}),type:"moon-multiplexer"};return{material:Kh(e,{resolution:r,glowColor:new dn(t[0],t[1],t[2]),glowIntensity:i,moonPhase:"full",assetBasePath:a}),type:"moon"}}(s,t,i,n,r);case"crystal":return Ud(t,i,"crystal",{sssPreset:"quartz"},r);case"rough":return Ud(t,i,"rough",{frostiness:.05,innerGlowStrength:0,fresnelIntensity:1.6},r);case"heart":return Ud(t,i,"heart",{frostiness:.475,innerGlowStrength:.117,fresnelIntensity:1.206},r);case"star":return Ud(t,i,"star",{sssPreset:"citrine"},r);default:return console.warn("Unknown custom material type:",e),null}}(e,n,a,r,0,o):"emissive"===t.material?function(e,t,i,n,a,r){const s=new Or;return"sun"===e?function(e,t,i,n=null,a=null,r="/assets"){return{material:sc(e,{glowColor:t,glowIntensity:i,resolution:"4k",materialVariant:n,assetBasePath:r}),type:"sun"}}(s,t,i,n,a,r):(console.warn("Unknown emissive material type:",e),null)}(e,n,a,r,s,o):null}function Ud(e,t,i="crystal",n={},a="/assets"){const{vertexShader:r,fragmentShader:s}={vertexShader:"\nvarying vec3 vPosition;\nvarying vec3 vNormal;\nvarying vec3 vViewPosition;\nvarying vec2 vUv;\n\nvoid main() {\n vUv = uv;\n vPosition = position;\n vNormal = normalize(normalMatrix * normal);\n\n vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);\n vViewPosition = -mvPosition.xyz;\n\n gl_Position = projectionMatrix * mvPosition;\n}\n",fragmentShader:Bd};let o=null;if(i){const e=new Or,t={crystal:`${a}/textures/Crystal/crystal.png`,rough:`${a}/textures/Crystal/rough.png`,heart:`${a}/textures/Crystal/heart.png`,star:`${a}/textures/Crystal/star.png`},n=t[i]||t.crystal;o=e.load(n,void 0,e=>console.warn(`💎 ${i} texture failed to load:`,e))}const l=n.sssPreset?Ld[n.sssPreset]:null;return{material:new Jn({uniforms:{time:{value:0},emotionColor:{value:new dn(e[0],e[1],e[2])},glowIntensity:{value:t},opacity:{value:1},frostiness:{value:n.frostiness??Od.frostiness},fresnelPower:{value:n.fresnelPower??Od.fresnelPower},fresnelIntensity:{value:n.fresnelIntensity??Od.fresnelIntensity},innerGlowStrength:{value:n.innerGlowStrength??Od.innerGlowStrength},surfaceRoughness:{value:Od.surfaceRoughness},shadowDarkness:{value:n.shadowDarkness??Od.shadowDarkness},specularIntensity:{value:n.specularIntensity??Od.specularIntensity},specularPower:{value:n.specularPower??Od.specularPower},transmissionContrast:{value:n.transmissionContrast??Od.transmissionContrast},minBrightness:{value:n.minBrightness??Od.minBrightness},surfaceNoiseScale:{value:Od.surfaceNoiseScale},noiseFrequency:{value:Od.noiseFrequency},causticIntensity:{value:n.causticIntensity??Od.causticIntensity},causticScale:{value:n.causticScale??Od.causticScale},causticSpeed:{value:n.causticSpeed??Od.causticSpeed},crystalTexture:{value:o},textureStrength:{value:"heart"===i?.35:i?Od.textureStrength:0},soulTexture:{value:null},resolution:{value:new Mt(Od.resolution[0],Od.resolution[1])},soulTextureSize:{value:new Mt(Od.soulTextureSize[0],Od.soulTextureSize[1])},soulScreenCenter:{value:new Mt(Od.soulScreenCenter[0],Od.soulScreenCenter[1])},refractionIndex:{value:n.refractionIndex??Od.refractionIndex},refractionStrength:{value:n.refractionStrength??Od.refractionStrength},sssStrength:{value:n.sssStrength??l?.sssStrength??Od.sssStrength},sssAbsorption:{value:new xt(...n.sssAbsorption??l?.sssAbsorption??Od.sssAbsorption)},sssScatterDistance:{value:new xt(...n.sssScatterDistance??l?.sssScatterDistance??Od.sssScatterDistance)},sssThicknessBias:{value:n.sssThicknessBias??l?.sssThicknessBias??Od.sssThicknessBias},sssThicknessScale:{value:n.sssThicknessScale??l?.sssThicknessScale??Od.sssThicknessScale},sssCurvatureScale:{value:n.sssCurvatureScale??l?.sssCurvatureScale??Od.sssCurvatureScale},sssAmbient:{value:n.sssAmbient??l?.sssAmbient??Od.sssAmbient},sssLightDir:{value:new xt(...n.sssLightDir??Od.sssLightDir)},sssLightColor:{value:new xt(...n.sssLightColor??Od.sssLightColor)},emotionColorBleed:{value:n.emotionColorBleed??l?.emotionColorBleed??0},shellLayer1Mode:{value:Od.shellLayer1Mode},shellLayer1Strength:{value:Od.shellLayer1Strength},shellLayer1Enabled:{value:Od.shellLayer1Enabled},shellLayer2Mode:{value:Od.shellLayer2Mode},shellLayer2Strength:{value:Od.shellLayer2Strength},shellLayer2Enabled:{value:Od.shellLayer2Enabled},soulLayer1Mode:{value:Od.soulLayer1Mode},soulLayer1Strength:{value:Od.soulLayer1Strength},soulLayer1Enabled:{value:Od.soulLayer1Enabled},soulLayer2Mode:{value:Od.soulLayer2Mode},soulLayer2Strength:{value:Od.soulLayer2Strength},soulLayer2Enabled:{value:Od.soulLayer2Enabled},rimLayer1Mode:{value:Od.rimLayer1Mode},rimLayer1Strength:{value:Od.rimLayer1Strength},rimLayer1Enabled:{value:Od.rimLayer1Enabled},rimLayer2Mode:{value:Od.rimLayer2Mode},rimLayer2Strength:{value:Od.rimLayer2Strength},rimLayer2Enabled:{value:Od.rimLayer2Enabled},sssLayer1Mode:{value:Od.sssLayer1Mode},sssLayer1Strength:{value:Od.sssLayer1Strength},sssLayer1Enabled:{value:Od.sssLayer1Enabled},sssLayer2Mode:{value:Od.sssLayer2Mode},sssLayer2Strength:{value:Od.sssLayer2Strength},sssLayer2Enabled:{value:Od.sssLayer2Enabled}},vertexShader:r,fragmentShader:s,transparent:!0,side:2,depthWrite:!1,blending:1}),type:"crystal"}}function zd(e){e&&(e.map&&e.map.dispose(),e.normalMap&&e.normalMap.dispose(),e.emissiveMap&&e.emissiveMap.dispose(),e.roughnessMap&&e.roughnessMap.dispose(),e.metalnessMap&&e.metalnessMap.dispose())}const kd=new Map;async function Nd(e,t={}){if(kd.has(e)){const t=kd.get(e);if(t.loaded)return t}const i=fc[e];if(!i)return console.warn(`[GeometryCache] Unknown geometry type: ${e}`),null;const n={geometry:null,material:null,materialType:null,config:i,loaded:!1};if(i.geometryLoader?n.geometry=await i.geometryLoader(t.assetBasePath):n.geometry=i.geometry,"custom"===i.material||"emissive"===i.material){const a=Fd(e,i,{glowColor:t.glowColor||[1,1,.95],glowIntensity:t.glowIntensity||1,materialVariant:t.materialVariant,emotionData:t.emotionData,assetBasePath:t.assetBasePath});a&&(n.material=a.material,n.materialType=a.type)}return n.loaded=!0,kd.set(e,n),n}async function Gd(e={}){await Promise.all(["crystal","rough","heart","moon","sun"].map(t=>Nd(t,e)))}function Vd(){for(const[e,t]of kd.entries())t.material&&(zd(t.material),t.material.dispose());kd.clear()}var Hd={preload:Nd,preloadAll:Gd,get:function(e){const t=kd.get(e);return t&&t.loaded?t:null},has:function(e){const t=kd.get(e);return t&&t.loaded},updateMaterialOptions:function(e,t){const i=kd.get(e);if(!i||!i.material)return;const{uniforms:n}=i.material;n&&(t.glowColor&&n.glowColor&&n.glowColor.value.set(...t.glowColor),void 0!==t.glowIntensity&&n.glowIntensity&&(n.glowIntensity.value=t.glowIntensity))},dispose:Vd,getStatus:function(){const e={};for(const[t,i]of kd.entries())e[t]={loaded:i.loaded,hasGeometry:!!i.geometry,hasMaterial:!!i.material,materialType:i.materialType};return e}};class Wd{constructor(e,t){this.animator=e,this.gestureBlender=t,this.virtualParticlePool=this._createVirtualParticlePool(5),this.nextPoolIndex=0}_createVirtualParticlePool(e){const t=[];for(let i=0;i<e;i++)t.push({x:0,y:0,vx:0,vy:0,size:1,baseSize:1,opacity:1,scaleFactor:1,gestureData:null});return t}getVirtualParticleFromPool(){const e=this.virtualParticlePool[this.nextPoolIndex];return this.nextPoolIndex=(this.nextPoolIndex+1)%this.virtualParticlePool.length,e.x=0,e.y=0,e.vx=0,e.vy=0,e.size=1,e.baseSize=1,e.opacity=1,e.scaleFactor=1,e.gestureData=null,e}playGesture(e,t={}){const i=Pu(e);if(!i)return console.warn(`Unknown gesture: ${e}`),!1;const n=this.getVirtualParticleFromPool(),a=i.config||{},r=a.musicalDuration?.musical?500*(a.musicalDuration.beats||2):a.duration||800,s=this.animator.time;if(this.animator.animations.length>=10){const e=this.animator.animations.shift();console.warn(`Animation limit reached (10), removed oldest: ${e.gestureName||"unknown"}`)}const o={initialized:!1};return this.animator.animations.push({gestureName:e,duration:r,startTime:s,config:a,evaluate:e=>{n.x=0,n.y=0,n.vx=0,n.vy=0,n.size=1,n.opacity=1,i.apply&&i.apply(n,o,a,e,1,0,0);const t={...a,particle:n,config:a,strength:a.strength||1};return i["3d"]&&i["3d"].evaluate?i["3d"].evaluate.call(i,e,t):{position:[0,0,0],rotation:[0,0,0],scale:1}},callbacks:{onUpdate:t.onUpdate||null,onComplete:()=>{i.cleanup&&i.cleanup(n),t.onComplete&&t.onComplete()}}}),!0}update(e){this.animator.update(e)}blend(e,t,i){return this.gestureBlender.blend(this.animator.animations,this.animator.time,e,t,i)}hasActiveAnimations(){return this.animator.animations.length>0}getActiveAnimationCount(){return this.animator.animations.length}getTime(){return this.animator.time}getActiveAnimations(){return this.animator.animations}stopAll(){this.animator.stopAll()}playEmotion(e){this.animator.playEmotion(e)}dispose(){this.stopAll(),this.virtualParticlePool&&(this.virtualParticlePool.length=0,this.virtualParticlePool=null),this.animator=null,this.gestureBlender=null,this.tempEuler=null,this.gestureQuaternion=null}}const jd="off",Xd="annular",qd="total",Yd={[jd]:{shadowCoverage:0,coronaIntensity:1,coronaRaysEnabled:!1,baileyBeadsEnabled:!1,baileyBeadsCount:0,baileyBeadsSize:0},[Xd]:{shadowCoverage:.95,coronaIntensity:.8,coronaRaysEnabled:!1,baileyBeadsEnabled:!0,baileyBeadsCount:12,baileyBeadsSize:.015},[qd]:{shadowCoverage:1.019,coronaIntensity:4,coronaRaysEnabled:!0,baileyBeadsEnabled:!0,baileyBeadsCount:6,baileyBeadsSize:.025}};function $d(e){return Yd[e]||Yd[jd]}class Zd{constructor(e,t){this.scene=e,this.sunRadius=t,this.heroBeadCount=3,this.supportBeadCount=15,this.beadCount=this.heroBeadCount+this.supportBeadCount,this.beads=[],this.visible=!1,this._directionToCamera=new xt,this._up=new xt(0,1,0),this._right=new xt,this._upVector=new xt,this._beadOffset=new xt,this._tempColor=new dn,this.sharedTexture=null,this.createBeads()}createBeads(){const e=document.createElement("canvas");e.width=64,e.height=64;const t=e.getContext("2d"),i=t.createRadialGradient(32,32,0,32,32,32);i.addColorStop(0,"rgba(255, 255, 255, 1.0)"),i.addColorStop(.1,"rgba(255, 255, 255, 0.9)"),i.addColorStop(.3,"rgba(255, 240, 200, 0.6)"),i.addColorStop(.6,"rgba(255, 220, 150, 0.2)"),i.addColorStop(1,"rgba(255, 200, 100, 0.0)"),t.fillStyle=i,t.fillRect(0,0,64,64);const n=new or(e);n.needsUpdate=!0,this.sharedTexture=n;const a=this.generateLunarValleys();for(let e=0;e<this.beadCount;e++){const t=new ha,i=new ga({map:n.clone(),blending:2,transparent:!0,depthWrite:!1,opacity:0,color:this._tempColor.setRGB(1,.3,.3)}),r=new Da(i);r.scale.set(.08,.08,1),t.add(r);const s=new ga({map:n.clone(),blending:2,transparent:!0,depthWrite:!1,opacity:0,color:this._tempColor.setRGB(.8,1,.8)}),o=new Da(s);o.scale.set(.08,.08,1),t.add(o);const l=new ga({map:n,blending:2,transparent:!0,depthWrite:!1,opacity:0,color:this._tempColor.setRGB(.3,.5,1)}),h=new Da(l);h.scale.set(.08,.08,1),t.add(h),t.userData={angle:a[e].angle,depth:a[e].depth,baseIntensity:a[e].baseIntensity,isHero:a[e].isHero,sizeMultiplier:a[e].isHero?1.5:1,targetOpacity:0,currentOpacity:0,redSprite:r,greenSprite:o,blueSprite:h},this.beads.push(t),this.scene.add(t)}}generateLunarValleys(){const e=[];let t=12345;const i=()=>(t=(9301*t+49297)%233280,t/233280),n=i()*Math.PI*2;for(let t=0;t<this.heroBeadCount;t++){const a=n+t*Math.PI*2/3;e.push({angle:a,depth:.8+.2*i(),baseIntensity:.8+.2*i(),isHero:!0})}for(let t=0;t<this.supportBeadCount;t++){const a=n+Math.floor(t/(this.supportBeadCount/3))*Math.PI*2/3,r=1.2*(i()-.5);e.push({angle:a+r,depth:.3+.5*i(),baseIntensity:.4+.4*i(),isHero:!1})}return e}update(e,t,i,n,a=1){const r=this.sunRadius*a*1,s=e.position;this._directionToCamera.subVectors(s,t).normalize(),this._right.crossVectors(this._directionToCamera,this._up).normalize(),this._upVector.crossVectors(this._right,this._directionToCamera).normalize();for(const e of this.beads){const{angle:i,redSprite:n,greenSprite:s,blueSprite:o,sizeMultiplier:l}=e.userData,h=Math.cos(i)*r,c=Math.sin(i)*r;this._beadOffset.set(0,0,0),this._beadOffset.addScaledVector(this._right,h),this._beadOffset.addScaledVector(this._upVector,c),this._beadOffset.addScaledVector(this._directionToCamera,.01*r);const u=t.x+this._beadOffset.x,d=t.y+this._beadOffset.y,p=t.z+this._beadOffset.z,m=.008*a,f=Math.cos(i)*m,g=Math.sin(i)*m;n.position.set(f,g,.001),s.position.set(0,0,0),o.position.set(-f,-g,-.001),e.position.set(u,d,p),e.updateMatrixWorld(!0);const v=.15*a*l;n.scale.set(v,v,1),s.scale.set(v,v,1),o.scale.set(v,v,1)}if(this.visible){const e=.9,t=.97,n=1;for(const a of this.beads){let r=0;if(i>=e&&i<n){const s=(i-e)/(n-e)*Math.PI*2,o=Math.abs((a.userData.angle-s+Math.PI)%(2*Math.PI)-Math.PI);let l=1;i<t&&(l=(i-e)/(t-e)),r=Math.max(0,1-o/1)*a.userData.baseIntensity*l*a.userData.depth,r*=200}a.userData.targetOpacity=r}}else for(const e of this.beads)e.userData.targetOpacity=0;for(const e of this.beads){const{redSprite:t,greenSprite:i,blueSprite:a}=e.userData,r=e.userData.targetOpacity-e.userData.currentOpacity;e.userData.currentOpacity+=3*r*(n/1e3),e.userData.currentOpacity<.001&&(e.userData.currentOpacity=0),t.material.opacity=.7*e.userData.currentOpacity,i.material.opacity=1*e.userData.currentOpacity,a.material.opacity=.7*e.userData.currentOpacity}}setVisible(e){this.visible=e}dispose(){for(const e of this.beads){const{redSprite:t,greenSprite:i,blueSprite:n}=e.userData;t.material.map&&t.material.map.dispose(),t.material.dispose(),i.material.map&&i.material.map.dispose(),i.material.dispose(),n.material.map&&n.material.map.dispose(),n.material.dispose(),this.scene.remove(e)}this.beads=[],this.sharedTexture&&(this.sharedTexture.dispose(),this.sharedTexture=null),this._directionToCamera=null,this._up=null,this._right=null,this._upVector=null,this._beadOffset=null,this._tempColor=null,this.scene=null}}class Kd{constructor(e,t,i=null){this.scene=e,this.sunRadius=t,this.sunMesh=i,this.eclipseType=jd,this.previousEclipseType=jd,this.enabled=!1,this.time=0,this.randomSeed=12345,this.isTransitioning=!1,this.transitionProgress=0,this.transitionDuration=400,this.transitionDirection="in",this.manualControl=!1,this.customShadowCoverage=void 0,this._directionToCamera=new xt,this._up=new xt(0,1,0),this._right=new xt,this._upVector=new xt,this._tempOffset=new xt,this._tempColor=new dn,this.createShadowDisk(),this.createCoronaDisk(),this.createCounterCoronaDisk(),this.sunMesh&&(this.scene.remove(this.coronaDisk),this.scene.remove(this.counterCoronaDisk),this.sunMesh.add(this.coronaDisk),this.sunMesh.add(this.counterCoronaDisk)),this.baileysBeads=new Zd(e,t)}createShadowDisk(){const e=this.sunRadius,t=new cr(e,256),i=new gn({color:0,transparent:!0,opacity:1,blending:4,premultipliedAlpha:!0,side:2,depthWrite:!1,depthTest:!1,fog:!1});this.shadowDisk=new Xn(t,i),this.shadowDisk.renderOrder=1e4,this.shadowDisk.position.set(200,0,0),this.scene.add(this.shadowDisk)}createCoronaDisk(){const e=2.05*this.sunRadius,t=.6*this.sunRadius,i=new gr(t,e,256),n=new Jn({uniforms:{time:{value:0},glowColor:{value:new dn(.9,.95,1)},intensity:{value:2.4},randomSeed:{value:this.randomSeed},uvRotation:{value:0},rayElongation:{value:1},uberHeroElongation:{value:1},isTotalEclipse:{value:0},layer1Mode:{value:11},layer1Strength:{value:2.155},layer1Enabled:{value:1},layer2Mode:{value:5},layer2Strength:{value:.695},layer2Enabled:{value:1},layer3Mode:{value:0},layer3Strength:{value:1},layer3Enabled:{value:0},layer4Mode:{value:0},layer4Strength:{value:1},layer4Enabled:{value:0}},vertexShader:"\n uniform float uvRotation;\n varying vec2 vUv;\n\n void main() {\n // Rotate UVs around center (0.5, 0.5)\n vec2 centeredUV = uv - 0.5;\n float cosRot = cos(uvRotation);\n float sinRot = sin(uvRotation);\n mat2 rotMatrix = mat2(cosRot, -sinRot, sinRot, cosRot);\n vec2 rotatedUV = rotMatrix * centeredUV;\n vUv = rotatedUV + 0.5;\n\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n ",fragmentShader:`\n uniform float time;\n uniform vec3 glowColor;\n uniform float intensity;\n uniform float randomSeed;\n uniform float rayElongation;\n uniform float uberHeroElongation;\n uniform float isTotalEclipse;\n\n // Blend Layer Uniforms (up to 4 layers)\n uniform float layer1Mode;\n uniform float layer1Strength;\n uniform float layer1Enabled;\n\n uniform float layer2Mode;\n uniform float layer2Strength;\n uniform float layer2Enabled;\n\n uniform float layer3Mode;\n uniform float layer3Strength;\n uniform float layer3Enabled;\n\n uniform float layer4Mode;\n uniform float layer4Strength;\n uniform float layer4Enabled;\n\n varying vec2 vUv;\n\n // ═══════════════════════════════════════════════════════════════════════════\n // UNIVERSAL BLEND MODES (injected from utils/blendModes.js)\n // ═══════════════════════════════════════════════════════════════════════════\n ${Oh}\n\n // Hash function for pseudo-random variation\n float hash(float n) {\n return fract(sin(n) * 43758.5453123);\n }\n\n // 2D hash for more variation\n float hash2(vec2 p) {\n return fract(sin(dot(p, vec2(12.9898 + randomSeed, 78.233 + randomSeed))) * 43758.5453);\n }\n\n void main() {\n // Calculate distance and angle from center\n vec2 center = vec2(0.5, 0.5);\n vec2 toCenter = vUv - center;\n float dist = length(toCenter) * 2.0; // Normalize to 0-1 range\n float angle = atan(toCenter.y, toCenter.x); // UVs are already rotated in vertex shader\n\n // Shadow edge - where corona rays start\n // Ring inner edge is at (sunRadius*0.85)/coronaRadius = 0.765/1.845 = 0.415\n // Start rays at sun's geometric edge (0.488) so they don't show inside sun\n float shadowEdge = 0.488;\n\n // Varied radial streamer pattern with artistic composition\n float rayIntensity = 0.0;\n\n // RULE OF THIRDS: Place 3 hero rays at compositionally strong points\n // Golden angles based on rule of thirds: 1/3, 2/3, and offset positions\n float heroAngles[3];\n heroAngles[0] = hash(randomSeed * 1.234) * 6.28318; // First hero ray (random rotation)\n heroAngles[1] = heroAngles[0] + 2.0944; // 120° apart (1/3 circle)\n heroAngles[2] = heroAngles[0] + 4.1888; // 240° apart (2/3 circle)\n\n // Process hero rays first (3 extra-long dramatic rays)\n for (int h = 0; h < 3; h++) {\n float rayAngle = heroAngles[h];\n float angleDiff = abs(mod(angle - rayAngle + 3.14159, 6.28318) - 3.14159);\n\n // Hero rays: extra long and prominent (fit within 0.535 normalized space)\n float baseHeroLength = 0.45 + hash(float(h) * 31.415 + randomSeed) * 0.08; // 0.45 to 0.53 (max available, longer!)\n\n // Apply UBER elongation: hero rays ALWAYS get extreme elongation (regardless of angle)\n // This creates 3 dramatic streamers that extend far in their respective directions\n float heroLength = baseHeroLength * uberHeroElongation;\n\n // Uber hero rays: keep them narrow but visible for dramatic pointy effect\n // Width scales with elongation to stay sharp but visible\n float baseHeroWidth = 0.15 + hash(float(h) * 27.183 + randomSeed) * 0.15; // 0.15 to 0.3 base width\n float narrowingFactor = mix(1.0, 0.3, (uberHeroElongation - 1.0) / max(uberHeroElongation, 1.0)); // 1.0 → 0.3 (70% narrower at max elongation)\n float heroWidth = baseHeroWidth * narrowingFactor; // Narrow when elongated = pointy!\n\n float distFromEdge = dist - shadowEdge;\n\n // Ghostly ethereal taper - very gradual falloff\n float taper = pow(1.0 - clamp(distFromEdge / max(heroLength, 0.001), 0.0, 1.0), 3.0);\n float rayWidth = heroWidth * taper;\n\n // Soft feathered edges instead of hard cutoff\n float edgeSoftness = 0.15; // Wider feather for smooth edges\n float angularMask = smoothstep(rayWidth + edgeSoftness, rayWidth - edgeSoftness, angleDiff);\n\n // Very gentle radial falloff for ethereal look\n float radialFalloff = pow(taper, 0.8);\n\n // Soft radial range with feathered ends\n float radialMask = smoothstep(-0.1, 0.05, distFromEdge) *\n smoothstep(heroLength + 0.15, heroLength - 0.05, distFromEdge);\n\n float heroIntensity = angularMask * radialFalloff * radialMask * 0.7; // Reduced intensity for ghostly effect\n rayIntensity = max(rayIntensity, heroIntensity);\n }\n\n // 20 supporting rays with rule-of-thirds-aware distribution\n for (float i = 0.0; i < 20.0; i++) {\n // Cluster more rays around hero ray positions (rule of thirds)\n float clusterTarget = mod(i, 3.0); // Which hero ray to cluster near\n float clusterAngle = heroAngles[int(clusterTarget)];\n\n // Base distribution with clustering tendency\n float spreadAngle = (i / 20.0) * 6.28318;\n float clusterPull = (hash(i * 13.579 + randomSeed) - 0.5) * 1.5; // Stronger variation\n float rayAngle = spreadAngle + clusterPull;\n\n float angleDiff = abs(mod(angle - rayAngle + 3.14159, 6.28318) - 3.14159);\n\n // Unique random values per ray\n float random1 = hash(i * 12.9898 + randomSeed);\n float random2 = hash(i * 78.233 + randomSeed);\n float random3 = hash(i * 37.719 + randomSeed);\n float random4 = hash(i * 93.989 + randomSeed);\n\n // Varied lengths following power law distribution (more short, fewer long)\n float lengthVariation = random1 * random1; // Squared for naturalistic distribution\n float baseRayLength = 0.1 + lengthVariation * 0.7; // 0.1 to 0.8\n\n // 20% chance of long streamers (supporting the hero rays)\n float isLong = step(0.80, random2);\n baseRayLength = mix(baseRayLength, 0.7 + random3 * 0.6, isLong); // 0.7 to 1.3\n\n // Apply directional elongation: rays pointing up/down (vertical) get elongated\n float verticalWeight = abs(sin(rayAngle));\n float elongationFactor = mix(1.0, rayElongation, verticalWeight);\n float rayLength = baseRayLength * elongationFactor;\n\n // EQUATORIAL ASYMMETRY (total eclipse only): rays along equator are more prominent\n // Solar minimum: streamers cluster along equatorial plane\n float equatorialWeight = abs(cos(rayAngle)); // 1.0 at horizontal, 0.0 at vertical\n float asymmetryBoost = mix(1.0, 1.0 + equatorialWeight * 0.5, isTotalEclipse);\n rayLength *= asymmetryBoost;\n\n // Varied widths with power law (more thin, fewer thick)\n float baseWidth = 0.03 + (random4 * random4) * 0.2; // 0.03 to 0.23 (naturally varied)\n\n // Taper: wide at base, narrow at tip\n float distFromEdge = dist - shadowEdge;\n\n // Ghostly ethereal taper - very gradual falloff\n float taper = pow(1.0 - clamp(distFromEdge / max(rayLength, 0.001), 0.0, 1.0), 3.5);\n float rayWidth = baseWidth * taper;\n\n // Soft feathered edges for ethereal wisps\n float edgeSoftness = 0.10; // Wider feather for smooth edges\n float angularMask = smoothstep(rayWidth + edgeSoftness, rayWidth - edgeSoftness, angleDiff);\n\n // Very gentle radial falloff for ghostly appearance\n float radialFalloff = pow(taper, 1.0);\n\n // Soft radial range with feathered ends\n float radialMask = smoothstep(-0.08, 0.03, distFromEdge) *\n smoothstep(rayLength + 0.12, rayLength - 0.03, distFromEdge);\n\n float streamerIntensity = angularMask * radialFalloff * radialMask * 0.5; // Reduced for ethereal wisps\n rayIntensity = max(rayIntensity, streamerIntensity);\n }\n\n // Base corona glow - thinner during total eclipse for realism\n float baseGlowWidth = mix(0.04, 0.015, isTotalEclipse); // Thinner during totality\n float baseGlow = smoothstep(shadowEdge - 0.01, shadowEdge, dist) *\n (1.0 - smoothstep(shadowEdge + baseGlowWidth * 0.5, shadowEdge + baseGlowWidth, dist));\n\n // Enhanced gradient: white → cool blue-white → deep blue with distance\n // Distance normalized to corona extent (0 = shadow edge, 1 = far corona)\n float coronaDist = clamp((dist - shadowEdge) / 0.6, 0.0, 1.0);\n\n // ═══════════════════════════════════════════════════════════════════════════\n // TOTAL ECLIPSE ENHANCEMENTS (scaled continuously by isTotalEclipse 0.0-1.0)\n // ═══════════════════════════════════════════════════════════════════════════\n\n // 1. CHROMOSPHERE RED RIM - thin pink/red ring at sun's edge (hydrogen emission)\n float rimStart = shadowEdge;\n float rimEnd = shadowEdge + 0.025;\n float chromosphereRim = smoothstep(rimStart - 0.005, rimStart, dist) *\n (1.0 - smoothstep(rimEnd - 0.01, rimEnd, dist));\n chromosphereRim *= 0.6 * isTotalEclipse; // Scale by eclipse progress\n vec3 chromosphereColor = vec3(1.0, 0.3, 0.4); // Pink-red (H-alpha emission)\n\n // 2. STRONGER BRIGHTNESS FALLOFF - inner corona much brighter\n // Mix between 1.0 (normal) and enhanced falloff based on isTotalEclipse\n float enhancedFalloff = mix(3.0, 0.3, pow(coronaDist, 0.7));\n float brightnessMultiplier = mix(1.0, enhancedFalloff, isTotalEclipse);\n\n // 3. F-CORONA OUTER GLOW - faint diffuse glow from interplanetary dust\n float fCoronaDist = clamp((dist - shadowEdge) / 1.2, 0.0, 1.0);\n float fCorona = (1.0 - fCoronaDist) * 0.08;\n fCorona *= smoothstep(0.3, 0.5, coronaDist);\n fCorona *= isTotalEclipse; // Scale by eclipse progress\n\n // 4. WISPY TENDRILS - add fine detail noise to ray intensity\n float noiseAngle = angle * 8.0 + time * 0.1;\n float noiseRadius = dist * 15.0;\n float wispyDetail = hash(noiseAngle + noiseRadius + randomSeed * 3.0) * 0.15;\n wispyDetail *= rayIntensity * isTotalEclipse; // Scale by eclipse progress\n\n // Combine: base glow + streamers + wispy detail\n float finalIntensity = (baseGlow * 0.6 + rayIntensity + wispyDetail) * intensity;\n finalIntensity *= brightnessMultiplier;\n\n // Multi-stage color gradient for realistic corona\n vec3 innerGlow = vec3(1.0, 1.0, 1.0); // Pure white at base\n vec3 middleGlow = vec3(0.9, 0.95, 1.0); // Cool white\n vec3 outerGlow = vec3(0.6, 0.75, 0.95); // Pale blue\n vec3 farGlow = vec3(0.3, 0.5, 0.8); // Deep blue\n\n // Three-stage color mix\n vec3 coronaColor;\n if (coronaDist < 0.3) {\n // Inner: white → cool white\n coronaColor = mix(innerGlow, middleGlow, coronaDist / 0.3);\n } else if (coronaDist < 0.7) {\n // Middle: cool white → pale blue\n coronaColor = mix(middleGlow, outerGlow, (coronaDist - 0.3) / 0.4);\n } else {\n // Outer: pale blue → deep blue\n coronaColor = mix(outerGlow, farGlow, (coronaDist - 0.7) / 0.3);\n }\n\n vec3 finalColor = coronaColor * finalIntensity;\n\n // Add chromosphere red rim (total eclipse only)\n finalColor += chromosphereColor * chromosphereRim * intensity;\n\n // Add F-corona outer glow (total eclipse only)\n finalColor += vec3(0.9, 0.85, 0.8) * fCorona * intensity; // Slightly warm white\n\n // ═══════════════════════════════════════════════════════════════════════════\n // BLEND LAYERS (Applied globally to entire corona)\n // These allow adjusting the appearance of the corona to prevent black edges\n // ═══════════════════════════════════════════════════════════════════════════\n\n // Layer 1\n if (layer1Enabled > 0.5) {\n vec3 blendColor1 = vec3(min(layer1Strength, 1.0));\n int mode1 = int(layer1Mode + 0.5);\n vec3 blended1 = clamp(applyBlendMode(finalColor, blendColor1, mode1), 0.0, 1.0);\n finalColor = clamp(blended1, 0.0, 1.0);\n }\n\n // Layer 2\n if (layer2Enabled > 0.5) {\n vec3 blendColor2 = vec3(min(layer2Strength, 1.0));\n int mode2 = int(layer2Mode + 0.5);\n vec3 blended2 = clamp(applyBlendMode(finalColor, blendColor2, mode2), 0.0, 1.0);\n finalColor = clamp(blended2, 0.0, 1.0);\n }\n\n // Layer 3\n if (layer3Enabled > 0.5) {\n vec3 blendColor3 = vec3(min(layer3Strength, 1.0));\n int mode3 = int(layer3Mode + 0.5);\n vec3 blended3 = clamp(applyBlendMode(finalColor, blendColor3, mode3), 0.0, 1.0);\n finalColor = clamp(blended3, 0.0, 1.0);\n }\n\n // Layer 4\n if (layer4Enabled > 0.5) {\n vec3 blendColor4 = vec3(min(layer4Strength, 1.0));\n int mode4 = int(layer4Mode + 0.5);\n vec3 blended4 = clamp(applyBlendMode(finalColor, blendColor4, mode4), 0.0, 1.0);\n finalColor = clamp(blended4, 0.0, 1.0);\n }\n\n // Sharp alpha falloff to prevent black bleeding in bloom\n // Higher power = sharper cutoff at edges (less semi-transparent area)\n float alphaFalloff = pow(1.0 - coronaDist, 3.0);\n float alpha = finalIntensity * alphaFalloff * 0.95;\n\n gl_FragColor = vec4(finalColor, alpha);\n }\n `,transparent:!0,blending:2,depthWrite:!1,side:2});this.coronaDisk=new Xn(i,n),this.coronaDisk.position.set(0,0,0),this.coronaDisk.renderOrder=9998,this.scene.add(this.coronaDisk)}createCounterCoronaDisk(){const e=this.coronaDisk.geometry,t=this.randomSeed+5e3,i=new Jn({uniforms:{time:{value:0},glowColor:{value:new dn(.9,.95,1)},intensity:{value:2.4},randomSeed:{value:t},uvRotation:{value:0},rayElongation:{value:1},uberHeroElongation:{value:1},isTotalEclipse:{value:0},layer1Mode:{value:11},layer1Strength:{value:2.155},layer1Enabled:{value:1},layer2Mode:{value:5},layer2Strength:{value:.695},layer2Enabled:{value:1},layer3Mode:{value:0},layer3Strength:{value:1},layer3Enabled:{value:0},layer4Mode:{value:0},layer4Strength:{value:1},layer4Enabled:{value:0}},vertexShader:this.coronaDisk.material.vertexShader,fragmentShader:this.coronaDisk.material.fragmentShader,transparent:!0,blending:2,depthWrite:!1,side:2});this.counterCoronaDisk=new Xn(e,i),this.counterCoronaDisk.position.set(0,0,0),this.counterCoronaDisk.renderOrder=9997,this.scene.add(this.counterCoronaDisk)}setShadowCoverage(e){this.customShadowCoverage=e}setCoronaBlendLayer(e,t){if(e<1||e>4)return void console.error(`❌ Invalid corona layer number: ${e} (must be 1-4)`);const{mode:i=0,strength:n=1,enabled:a=!1}=t;this.coronaDisk?.material?.uniforms&&(this.coronaDisk.material.uniforms[`layer${e}Mode`].value=i,this.coronaDisk.material.uniforms[`layer${e}Strength`].value=n,this.coronaDisk.material.uniforms[`layer${e}Enabled`].value=a?1:0),this.counterCoronaDisk?.material?.uniforms&&(this.counterCoronaDisk.material.uniforms[`layer${e}Mode`].value=i,this.counterCoronaDisk.material.uniforms[`layer${e}Strength`].value=n,this.counterCoronaDisk.material.uniforms[`layer${e}Enabled`].value=a?1:0)}setEclipseType(e){if(e===this.eclipseType)return;const t=this.enabled;this.previousEclipseType=this.eclipseType,this.eclipseType=e,this.enabled=e!==jd,this.manualControl=!1;const i=$d(this.previousEclipseType),n=$d(e);this.startShadowCoverage=i.shadowCoverage,this.targetShadowCoverage=n.shadowCoverage,!t&&this.enabled?(this.transitionDirection="in",this.isTransitioning=!0,this.transitionProgress=0):t&&!this.enabled?(this.transitionDirection="out",this.isTransitioning=!0,this.transitionProgress=0):t&&this.enabled&&(this.isTransitioning=!0,this.transitionProgress=0,this.transitionDirection="switch")}easeInOutCubic(e){return e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2}setManualProgress(e){this.manualControl=!0,this.transitionProgress=Math.max(0,Math.min(1,e)),this.isTransitioning=!0,this.transitionDirection="in"}setManualShadowPosition(e){this.manualControl=!0,this.manualShadowPosition=Math.max(-2,Math.min(2,e)),this.isTransitioning=!0,this.transitionDirection="manual"}update(e,t,i,n=null){const a=e.position,r=t.position,s=t.scale.x;let o=1;if(null!==n&&n>.5){const e=2*(n-.5);o=e*e*e}else if(null!==n&&n<=.5){const e=2*n;o=(1-e)*(1-e)*(1-e)}const l=this.eclipseType===jd?3:1;if(this.time+=i*l,this.isTransitioning&&!this.manualControl){const e=i/this.transitionDuration;this.transitionProgress+=e,this.transitionProgress>=1&&(this.transitionProgress=1,this.isTransitioning=!1)}if(this.enabled||"out"===this.transitionDirection&&this.isTransitioning){const e="out"===this.transitionDirection&&this.isTransitioning?this.previousEclipseType:this.eclipseType,t=$d(e),n=this.sunRadius*s,l=this.easeInOutCubic(this.transitionProgress);let h;h=void 0!==this.customShadowCoverage?this.customShadowCoverage:"switch"===this.transitionDirection&&this.isTransitioning&&void 0!==this.startShadowCoverage&&void 0!==this.targetShadowCoverage?this.startShadowCoverage+(this.targetShadowCoverage-this.startShadowCoverage)*l:t.shadowCoverage;const c=n*h/this.sunRadius;this.shadowDisk.scale.setScalar(c),this.currentShadowPosX=-2,"manual"===this.transitionDirection&&void 0!==this.manualShadowPosition?this.currentShadowPosX=this.manualShadowPosition:this.isTransitioning?"in"===this.transitionDirection?this.currentShadowPosX=2*l-2:"out"===this.transitionDirection?this.currentShadowPosX=0+1*l:"switch"===this.transitionDirection&&(this.currentShadowPosX=0):this.currentShadowPosX=0;const u=this.currentShadowPosX,d=2.5*n,p=u*d*.5,m=-u*u*d*.25;this._directionToCamera.subVectors(a,r).normalize(),this._right.crossVectors(this._directionToCamera,this._up).normalize(),this._upVector.crossVectors(this._right,this._directionToCamera).normalize();const f=0;this._tempOffset.copy(this._directionToCamera).multiplyScalar(f),this.shadowDisk.position.copy(r).add(this._tempOffset),this._tempOffset.copy(this._right).multiplyScalar(p),this.shadowDisk.position.add(this._tempOffset),this._tempOffset.copy(this._upVector).multiplyScalar(m),this.shadowDisk.position.add(this._tempOffset),this.shadowDisk.lookAt(a),this.coronaDisk.parent&&this.coronaDisk.parent!==this.scene||(this.coronaDisk.position.copy(r),this.counterCoronaDisk.position.copy(r),this.coronaDisk.scale.setScalar(s),this.counterCoronaDisk.scale.setScalar(s));const g=Math.abs(this.currentShadowPosX||0),v=2,y=Math.max(0,1-g/v);let b=0;if("switch"===this.transitionDirection&&this.isTransitioning){const e=this.previousEclipseType===qd,t=this.eclipseType===qd;t&&!e?b=l:!t&&e&&(b=1-l)}else e===qd&&(b=1);const M=1+(1+24*Math.pow(y,4)-1)*b,_=1+(1+199*Math.pow(y,5)-1)*b;this.coronaDisk.material.uniforms.rayElongation.value=M,this.counterCoronaDisk.material.uniforms.rayElongation.value=M,this.coronaDisk.material.uniforms.uberHeroElongation.value=_,this.counterCoronaDisk.material.uniforms.uberHeroElongation.value=_;const x=.5,S=.99,w=Math.max(0,Math.min(1,(y-x)/(S-x))),E=w*w*(3-2*w),T=E*b;this.coronaDisk.material.uniforms.isTotalEclipse.value=T,this.counterCoronaDisk.material.uniforms.isTotalEclipse.value=T;const C=b>0&&y>=x,A=1-.947*E*b;this.setCoronaBlendLayer(3,{mode:1,strength:A,enabled:C}),this.coronaDisk.lookAt(a),this.counterCoronaDisk.lookAt(a);let P=0;if(e===jd)P=i/1e3*.075;else if(e===Xd){const e=.075;P=i/1e3*(e-(e-.25*e)*y)}else if(e===qd){const e=.075;P=i/1e3*(e-(e-.05*e)*y)}this.coronaDisk.material.uniforms.uvRotation.value+=P,this.counterCoronaDisk.material.uniforms.uvRotation.value-=P;let D=1.2;if(e===jd)D=3.6;else if(e===Xd){const e=3.6,t=.08*e;this.transitionDirection,D=e-(e-t)*y}else if(e===qd){const e=3.6,t=.65*e;this.transitionDirection,D=e-(e-t)*y}this.coronaDisk.material.uniforms.intensity.value=D*o,this.counterCoronaDisk.material.uniforms.intensity.value=D*o,this.coronaDisk.material.uniforms.time.value=this.time,this.counterCoronaDisk.material.uniforms.time.value=this.time}else{this.shadowDisk.position.set(200,0,0),this.coronaDisk.parent&&this.coronaDisk.parent!==this.scene||(this.coronaDisk.position.copy(r),this.counterCoronaDisk.position.copy(r),this.coronaDisk.scale.setScalar(s),this.counterCoronaDisk.scale.setScalar(s)),this.coronaDisk.material.uniforms.rayElongation.value=1,this.counterCoronaDisk.material.uniforms.rayElongation.value=1,this.coronaDisk.material.uniforms.uberHeroElongation.value=1,this.counterCoronaDisk.material.uniforms.uberHeroElongation.value=1,this.coronaDisk.material.uniforms.isTotalEclipse.value=0,this.counterCoronaDisk.material.uniforms.isTotalEclipse.value=0,this.coronaDisk.material.uniforms.intensity.value=3.06*o,this.counterCoronaDisk.material.uniforms.intensity.value=3.06*o,this.setCoronaBlendLayer(3,{mode:1,strength:0,enabled:!1}),this.coronaDisk.lookAt(a),this.counterCoronaDisk.lookAt(a);const e=i/1e3*.075;this.coronaDisk.material.uniforms.uvRotation.value+=e,this.counterCoronaDisk.material.uniforms.uvRotation.value-=e,this.coronaDisk.material.uniforms.intensity.value=3.6*o,this.counterCoronaDisk.material.uniforms.intensity.value=3.6*o,this.coronaDisk.material.uniforms.time.value=this.time,this.counterCoronaDisk.material.uniforms.time.value=this.time}if(this.eclipseType===qd){let t=0,n=!1;if("manual"===this.transitionDirection){const e=Math.abs(this.currentShadowPosX),i=2;t=Math.max(0,Math.min(1,1-e/i)),t>=.9&&t<=1&&(n=!0)}else if("in"===this.transitionDirection&&this.isTransitioning){const e=.8;this.transitionProgress>=e&&(n=!0,t=.9+(this.transitionProgress-e)/(1-e)*.1)}else if("out"===this.transitionDirection&&this.isTransitioning){const e=.2;this.transitionProgress<=e&&(n=!0,t=1-this.transitionProgress/e*.1)}else this.isTransitioning||(t=1,n=!0);this.baileysBeads.setVisible(n),this.baileysBeads.update(e,r,t,i,s)}else this.baileysBeads.setVisible(!1),this.baileysBeads.update(e,r,0,i,s)}dispose(){this.shadowDisk&&(this.scene.remove(this.shadowDisk),this.shadowDisk.geometry.dispose(),this.shadowDisk.material.dispose(),this.shadowDisk=null),this.coronaDisk&&(this.coronaDisk.parent&&this.coronaDisk.parent.remove(this.coronaDisk),this.coronaDisk.geometry.dispose(),this.coronaDisk.material.dispose(),this.coronaDisk=null),this.counterCoronaDisk&&(this.counterCoronaDisk.parent&&this.counterCoronaDisk.parent.remove(this.counterCoronaDisk),this.counterCoronaDisk.material.dispose(),this.counterCoronaDisk=null),this.baileysBeads&&(this.baileysBeads.dispose(),this.baileysBeads=null),this._directionToCamera=null,this._up=null,this._right=null,this._upVector=null,this._tempOffset=null,this._tempColor=null,this.scene=null,this.sunMesh=null}}class Qd{constructor(e){this.material=e,this.eclipseType="off",this.progress=0,this.targetProgress=0,this.animating=!1,this.bloodMoonColor={r:.85,g:.18,b:.08},this.animationDuration=3e3,this.startTime=0,this.shadowX=-2,this.shadowY=0,this.shadowRadius=.7,this.targetShadowX=-2,this.shadowSpeed=1,this.material.uniforms.eclipseProgress||(this.material.uniforms.eclipseProgress={value:0},this.material.uniforms.eclipseIntensity={value:0},this.material.uniforms.bloodMoonColor={value:[this.bloodMoonColor.r,this.bloodMoonColor.g,this.bloodMoonColor.b]},this.material.uniforms.eclipseShadowPos={value:[this.shadowX,this.shadowY]},this.material.uniforms.eclipseShadowRadius={value:this.shadowRadius})}setEclipseType(e){if(this.eclipseType===e)return;const t="off"===this.eclipseType;switch(this.eclipseType=e,t&&"off"!==e&&(this.shadowX=-2,this.material.uniforms.eclipseShadowPos.value=[this.shadowX,this.shadowY]),e){case"off":this.targetProgress=0,this.targetShadowX=2;break;case"penumbral":this.targetProgress=.3,this.targetShadowX=-1;break;case"partial":this.targetProgress=.65,this.targetShadowX=-.6;break;case"total":this.targetProgress=1,this.targetShadowX=0;break;default:return void console.warn(`Unknown lunar eclipse type: ${e}`)}this.animating=!0,this.startTime=performance.now()}update(e){if(!this.animating)return;const t=performance.now()-this.startTime,i=Math.min(t/this.animationDuration,1),n=this.easeInOutCubic(i);this.progress=this.progress+(this.targetProgress-this.progress)*n,this.shadowX=this.shadowX+(this.targetShadowX-this.shadowX)*n*this.shadowSpeed,this.material.uniforms.eclipseProgress.value=this.progress,this.material.uniforms.eclipseShadowPos.value=[this.shadowX,this.shadowY];let a=0;"total"===this.eclipseType?a=this.progress:"partial"===this.eclipseType?a=.6*this.progress:"penumbral"===this.eclipseType&&(a=.25*this.progress),this.material.uniforms.eclipseIntensity.value=a,i>=1&&(this.animating=!1)}easeInOutCubic(e){return e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2}reset(){this.progress=0,this.targetProgress=0,this.shadowX=-2,this.targetShadowX=-2,this.animating=!1,this.eclipseType="off",this.material.uniforms.eclipseProgress&&(this.material.uniforms.eclipseProgress.value=0,this.material.uniforms.eclipseIntensity.value=0,this.material.uniforms.eclipseShadowPos.value=[this.shadowX,this.shadowY])}dispose(){}}const Jd=["crystal","rough","heart","star"];class ep{constructor(e,t="/assets"){this.renderer=e,this.assetBasePath=t,this.solarEclipse=null,this.lunarEclipse=null,this.crystalSoul=null,this.currentGeometryType=null,this.coreGlowEnabled=!0}initializeForGeometry(e,t={}){const{coreMesh:i,customMaterial:n,sunRadius:a=1}=t;this.currentGeometryType=e,this._cleanupUnneededEffects(e),"sun"===e?this._initSolarEclipse(a,i):"moon"===e&&this._initLunarEclipse(n)}_initSolarEclipse(e,t){!this.solarEclipse&&this.renderer?.scene&&(this.solarEclipse=new Kd(this.renderer.scene,e,t))}_initLunarEclipse(e){!this.lunarEclipse&&e&&(this.lunarEclipse=new Qd(e))}_cleanupUnneededEffects(e){"sun"!==e&&this.solarEclipse&&(this.solarEclipse.dispose(),this.solarEclipse=null),"moon"!==e&&this.lunarEclipse&&(this.lunarEclipse.dispose(),this.lunarEclipse=null),!Jd.includes(e)&&this.crystalSoul&&(this.crystalSoul.dispose(),this.crystalSoul=null)}async createCrystalSoul(e={}){const{coreMesh:t,geometryType:i}=e;if(this.crystalSoul&&(this.crystalSoul.dispose(),this.crystalSoul=null),!t)return null;await Cd._loadInclusionGeometry(this.assetBasePath),this.crystalSoul=new Cd({radius:.35,detail:1,geometryType:i,renderer:this.renderer,assetBasePath:this.assetBasePath}),this.crystalSoul.attachTo(t,this.renderer?.scene);const{shellBaseScale:n,soulScale:a}=this._getCrystalScaleConfig(i);return this.crystalSoul.baseScale=a,this.crystalSoul.mesh.scale.setScalar(a),this.crystalSoul.setVisible(this.coreGlowEnabled),{mesh:this.crystalSoul.mesh,material:this.crystalSoul.material,baseScale:this.crystalSoul.baseScale,shellBaseScale:n}}createCrystalSoulSync(e={}){const{coreMesh:t,geometryType:i}=e;if(this.crystalSoul&&(this.crystalSoul.dispose(),this.crystalSoul=null),!t)return null;this.crystalSoul=new Cd({radius:.35,detail:1,geometryType:i,renderer:this.renderer,assetBasePath:this.assetBasePath}),this.crystalSoul.attachTo(t,this.renderer?.scene);const{shellBaseScale:n,soulScale:a}=this._getCrystalScaleConfig(i);return this.crystalSoul.baseScale=a,this.crystalSoul.mesh.scale.setScalar(a),this.crystalSoul.setVisible(this.coreGlowEnabled),{mesh:this.crystalSoul.mesh,material:this.crystalSoul.material,baseScale:this.crystalSoul.baseScale,shellBaseScale:n}}_getCrystalScaleConfig(e){let t=2,i=1;return"heart"===e?(t=2.4,i=1):"rough"===e?(t=1.6,i=1):"star"===e?(t=2,i=1.4):"crystal"===e&&(t=2,i=1),{shellBaseScale:t,soulScale:i}}setSolarEclipse(e){return!!this.solarEclipse&&(this.solarEclipse.setEclipseType(e),!0)}setLunarEclipse(e){return!!this.lunarEclipse&&(this.lunarEclipse.setEclipseType(e),!0)}stopAllEclipses(){this.solarEclipse&&this.solarEclipse.setEclipseType("off"),this.lunarEclipse&&this.lunarEclipse.setEclipseType("off")}updateCrystalSoul(e,t,i=1){this.crystalSoul&&this.crystalSoul.update(e,t,i)}updateLunarEclipse(e){this.lunarEclipse&&this.lunarEclipse.update(e)}setCrystalSoulEffects(e){this.crystalSoul&&this.crystalSoul.setEffects(e)}setCrystalSoulSize(e){return this.crystalSoul?(this.crystalSoul.setSize(e),this.crystalSoul.baseScale):1}setCrystalSoulVisible(e){this.coreGlowEnabled=e,this.crystalSoul&&this.crystalSoul.setVisible(e)}hasCrystalSoul(){return!!this.crystalSoul}getCrystalSoulBaseScale(){return this.crystalSoul?.baseScale??1}hasSolarEclipse(){return!!this.solarEclipse}hasLunarEclipse(){return!!this.lunarEclipse}getSolarEclipse(){return this.solarEclipse}dispose(){this.solarEclipse&&(this.solarEclipse.dispose(),this.solarEclipse=null),this.lunarEclipse&&(this.lunarEclipse.dispose(),this.lunarEclipse=null),this.crystalSoul&&(this.crystalSoul.dispose(),this.crystalSoul=null),this.renderer=null}}const tp={strength:5,damping:.85,centerOfMass:[0,-.3,0],axes:{pitch:!0,roll:!0,yaw:!1}};class ip{constructor(e={}){this.rotationBehavior=null,this.rightingBehavior=null,this.facingBehavior=null,this.rotationDisabled=e.rotationDisabled||!1,this.wobbleEnabled=!1!==e.wobbleEnabled,this.rightingBehavior=new Fc(tp)}configureForEmotion(e={}){const{geometryType:t,emotionData:i,facingConfig:n}=e;if("moon"===t)return this._disableRotation(),void this._initFacingBehavior(n);this._disposeFacingBehavior(),this.rotationDisabled?this._disableRotation():(i?.["3d"]?.rotation?this._configureRotationFromEmotion(i["3d"].rotation):this._ensureDefaultRotation(),this.rightingBehavior&&this.rightingBehavior.reset())}applyUndertone(e){e&&(e.rotation&&this.rotationBehavior&&this.rotationBehavior.applyUndertoneMultipliers(e.rotation),e.righting&&this.rightingBehavior&&this.rightingBehavior.applyUndertoneMultipliers(e.righting))}update(e,t){this.rotationBehavior&&this.rotationBehavior.update(e,t),this.rightingBehavior&&this.rightingBehavior.update(e,t),this.facingBehavior&&this.facingBehavior.update(e,t)}setWobbleEnabled(e){this.wobbleEnabled=e,this.rotationBehavior&&this.rotationBehavior.setWobbleEnabled(e),!e&&this.rightingBehavior&&this.rightingBehavior.reset()}resetRighting(){this.rightingBehavior&&this.rightingBehavior.reset()}getAngularVelocity(){return this.rotationBehavior?this.rotationBehavior.axes:[0,0,0]}hasRotationBehavior(){return!!this.rotationBehavior}_configureRotationFromEmotion(e){this.rotationBehavior?this.rotationBehavior.updateConfig(e):this.rotationBehavior=new Oc(e),this.rotationBehavior.setWobbleEnabled(this.wobbleEnabled)}_ensureDefaultRotation(){this.rotationBehavior||(this.rotationBehavior=new Oc({axes:[0,.3,0]}),this.rotationBehavior.setWobbleEnabled(this.wobbleEnabled))}_disableRotation(){this.rotationBehavior=null}_initFacingBehavior(e){!this.facingBehavior&&e?.enabled&&(this.facingBehavior=new Uc({strength:e.strength,damping:e.damping,faceAxis:e.faceAxis,targetAxis:e.targetAxis}))}_disposeFacingBehavior(){this.facingBehavior&&(this.facingBehavior.dispose(),this.facingBehavior=null)}dispose(){this.rotationBehavior&&(this.rotationBehavior.destroy?.(),this.rotationBehavior=null),this.rightingBehavior&&(this.rightingBehavior.destroy?.(),this.rightingBehavior=null),this.facingBehavior&&(this.facingBehavior.dispose(),this.facingBehavior=null)}}class np{constructor(){this._phase=null,this._startTime=0,this._duration=0,this._startScale=1,this._targetScale=1,this._currentScale=1}startPhase(e,t){const i=Math.max(.5,Math.min(30,t));switch(this._startScale=this._currentScale,this._startTime=performance.now(),this._duration=1e3*i,this._phase=e,e){case"inhale":this._targetScale=1.3;break;case"exhale":this._targetScale=.85;break;default:this._targetScale=this._startScale}}stop(){this._phase=null,this._currentScale=1,this._startScale=1,this._targetScale=1}isActive(){return null!==this._phase}getPhase(){return this._phase}update(e){if(!this._phase)return this._currentScale;const t=performance.now()-this._startTime,i=Math.min(1,t/this._duration),n=Math.sin(i*Math.PI/2);return this._currentScale=this._startScale+(this._targetScale-this._startScale)*n,i>=1&&(this._currentScale=this._targetScale,this._phase=null),this._currentScale}getScaleMultiplier(){return this._currentScale}getState(){return{phase:this._phase,startScale:this._startScale,targetScale:this._targetScale,currentScale:this._currentScale,duration:this._duration,isActive:null!==this._phase}}dispose(){this._phase=null}}class ap{constructor(e,t={}){this._instanceId=Math.random().toString(36).substr(2,6),this.canvas=e,this.options=t,this._destroyed=!1,this._ready=!1,this._readyPromise=null,this.assetBasePath=t.assetBasePath||"/assets",this.geometryType=t.geometry||"sphere";const i="moon"===this.geometryType;this.renderer=new _h(e,{enablePostProcessing:!1!==t.enablePostProcessing,enableShadows:t.enableShadows||!1,enableControls:!1!==t.enableControls,autoRotate:!i&&!1!==t.autoRotate,autoRotateSpeed:t.autoRotateSpeed,cameraDistance:t.cameraDistance,fov:t.fov,minZoom:t.minZoom,maxZoom:t.maxZoom,assetBasePath:this.assetBasePath});const n=fc[this.geometryType];n?this.geometryConfig=n:(console.warn(`Unknown geometry: ${this.geometryType}, falling back to sphere`),this.geometryConfig=fc.sphere),this.geometry=this.geometryConfig.geometry,this.geometry&&!this.geometry.isGroup&&(this.geometry.userData.geometryType=this.geometryType),this.materialVariant=t.materialVariant||null,this.onMaterialSwap=null;let a=null;const r=Tc(this.emotion),s=Fd(this.geometryType,this.geometryConfig,{glowColor:this.glowColor||[1,1,.95],glowIntensity:this.glowIntensity||1,materialVariant:this.materialVariant,emotionData:r,assetBasePath:this.assetBasePath});if(s&&(a=s.material,this.customMaterial=a,this.customMaterialType=s.type),this.geometryConfig.geometryLoader?this._readyPromise=this._loadAsyncGeometry():(this._ready=!0,this._readyPromise=Promise.resolve()),null===this.geometry&&this.geometryConfig.geometryLoader?this._deferredMeshCreation=!0:(this.coreMesh=this.renderer.createCoreMesh(this.geometry,a),"crystal"===this.customMaterialType&&this.createCrystalInnerCore()),this.calibrationRotation=[0,0,0],this.cameraRoll=0,"moon"===this.geometryType){const e=Math.PI/180;this.calibrationRotation=[Nh*e,Gh*e,Vh*e],this.cameraRoll=0}if("crystal"===this.geometryType||"rough"===this.geometryType||"heart"===this.geometryType||"star"===this.geometryType){const e=Math.PI/180;this.calibrationRotation=[0*e,30*e,0*e]}if(this.animator=new gc,this.gestureBlender=new yc,this.animationManager=new Wd(this.animator,this.gestureBlender),this.effectManager=new ep(this.renderer,this.assetBasePath),this.behaviorController=new ip({rotationDisabled:!1===t.autoRotate,wobbleEnabled:!0}),this.breathingPhaseManager=new np,this.breathingAnimator=new vc,this.breathingEnabled=!1!==t.enableBreathing,this.geometryMorpher=new Bc,this.blinkAnimator=new Dc(this.geometryConfig),this.blinkAnimator.setEmotion(this.emotion),this.blinkingManuallyDisabled=!1,!1===t.enableBlinking&&(this.blinkAnimator.pause(),this.blinkingManuallyDisabled=!0),this.rotationBehavior=null,this.rotationDisabled=!1===t.autoRotate,this.wobbleEnabled=!0,this.rightingBehavior=new Fc({strength:5,damping:.85,centerOfMass:[0,-.3,0],axes:{pitch:!0,roll:!0,yaw:!1}}),this.facingBehavior=null,i&&Hh.enabled){const e=Math.PI/180;this.facingBehavior=new Uc({strength:Hh.strength,lockedFace:Hh.lockedFace,lerpSpeed:Hh.lerpSpeed,calibrationRotation:[Nh*e,Gh*e,Vh*e]},this.renderer.camera)}this.emotion=t.emotion||"neutral",this.undertone=t.undertone||null,this.glowColor=[1,1,1],this.glowColorHex="#FFFFFF",this.glowIntensity=1,this.coreGlowEnabled=!0,this.glowIntensityOverride=null,this.intensityCalibrationOffset=0,this.baseEuler=[0,0,0],this.baseQuaternion=new _t,this.gestureQuaternion=new _t,this.tempEuler=new Pi,this.rotation=[0,0,0],this.baseScale=.16,this.scale=.16,this.position=[0,0,0],this.rhythmEngine=t.rhythmEngine||null,this.rhythm3DAdapter=Lc,this.rhythmEnabled=!1!==t.enableRhythm,this.rhythmEnabled&&this.rhythm3DAdapter.initialize(),this.particlesEnabled=!1!==t.enableParticles,this.particleVisibility=this.particlesEnabled;const o=new xd(50);o.canvasWidth=e.width,o.canvasHeight=e.height;const l=new Sd({worldScale:2,baseRadius:1.5,depthScale:.75,verticalScale:1,coreRadius3D:2}),h=new Ad(150,{renderer:this.renderer.renderer}),c=h.getPoints();c.layers.set(1),this.renderer.scene.add(c),this.particleOrchestrator=new Id(o,l,h),this.particleOrchestrator.setGeometryType(this.geometryType),this.particlesEnabled||h.geometry.setDrawRange(0,0);const u=this.geometry?.parameters?.radius||.5;this.effectManager.initializeForGeometry(this.geometryType,{coreMesh:this.coreMesh,customMaterial:this.customMaterial,sunRadius:u}),this.geometryConfig.defaultGlassMode&&!this.customMaterial&&this.setGlassMaterialEnabled(!0),this.setEmotion(this.emotion)}setEmotion(e,t=null){this.emotion=e,this.undertone=t;const i=Tc(e);if(i&&i.visual){if(i.visual.glowColor){let e=(n=(n=i.visual.glowColor).replace("#",""),[parseInt(n.substring(0,2),16)/255,parseInt(n.substring(2,4),16)/255,parseInt(n.substring(4,6),16)/255]);e=function(e,t){if(!t||"clear"===t||"none"===t)return e;const i={intense:{saturation:2.5,lightness:1.3},confident:{saturation:1.8,lightness:1.15},nervous:{saturation:1.6,lightness:1.1},tired:{saturation:.4,lightness:.65},subdued:{saturation:.25,lightness:.55}}[t];if(!i)return e;const n=function(e,t,i){const n=Math.max(e,t,i),a=Math.min(e,t,i),r=n-a,s=n+a;let o=0,l=0;const h=s/2;if(0!==r)switch(l=h>.5?r/(2-s):r/s,n){case e:o=((t-i)/r+(t<i?6:0))/6;break;case t:o=((i-e)/r+2)/6;break;case i:o=((e-t)/r+4)/6}return[360*o,100*l,100*h]}(e[0],e[1],e[2]);return n[1]=Math.min(100,n[1]*i.saturation),n[2]=Math.min(100,Math.max(0,n[2]*i.lightness)),function(e,t,i){let n,a,r;if(e/=360,i/=100,0==(t/=100))n=a=r=i;else{const s=(e,t,i)=>(i<0&&(i+=1),i>1&&(i-=1),i<1/6?e+6*(t-e)*i:i<.5?t:i<2/3?e+(t-e)*(2/3-i)*6:e),o=i<.5?i*(1+t):i+t-i*t,l=2*i-o;n=s(l,o,e+1/3),a=s(l,o,e),r=s(l,o,e-1/3)}return[n,a,r]}(n[0],n[1],n[2])}(e,t),this.glowColor=e,this.glowColorHex=i.visual.glowColor;const a=this.renderer.materialMode||"glass";this.glowIntensity=vh(i.visual.glowColor,this.intensityCalibrationOffset,a)}if(this.renderer.updateLighting(e,i),this.customMaterial&&"moon"===this.customMaterialType){const e=new dn(this.glowColor[0],this.glowColor[1],this.glowColor[2]);tc(this.customMaterial,e,this.glowIntensity)}else this.customMaterial&&"sun"===this.customMaterialType&&lc(this.coreMesh,this.glowColor,this.glowIntensity,0)}var n;const a="sun"===this.geometryType?rc:null;this.rotationDisabled||"moon"===this.geometryType?this.rotationBehavior=null:i&&i["3d"]&&i["3d"].rotation?this.rotationBehavior?this.rotationBehavior.updateConfig(i["3d"].rotation):(this.rotationBehavior=new Oc(i["3d"].rotation,this.rhythmEngine,a),this.rotationBehavior.setWobbleEnabled(this.wobbleEnabled)):this.rotationBehavior||this.rotationDisabled||(this.rotationBehavior=new Oc({type:"gentle",speed:1,axes:[0,.01,0]},this.rhythmEngine,a),this.rotationBehavior.setWobbleEnabled(this.wobbleEnabled)),this.rightingBehavior&&this.rightingBehavior.reset(),this.baseEuler[0]=0,this.baseEuler[2]=0;const r=Ru(t);if(r&&r["3d"]){const e=r["3d"];e.rotation&&this.rotationBehavior&&this.rotationBehavior.applyUndertoneMultipliers(e.rotation),e.righting&&this.rightingBehavior&&this.rightingBehavior.applyUndertoneMultipliers(e.righting)}this.animator.stopAll();const s=i?.visual?.glowColor||"#00BCD4",o=this.renderer.materialMode||"glass";if(this.baseGlowIntensity=vh(s,this.intensityCalibrationOffset,o),r&&r["3d"]&&r["3d"].glow&&(this.baseGlowIntensity,this.baseGlowIntensity*=r["3d"].glow.intensityMultiplier),this.breathingAnimator.setEmotion(e,r),this.blinkAnimator.setEmotion(e),this.renderer.updateBloom(this.baseGlowIntensity,1,this.geometryType),this.animator.playEmotion(e),this.particlesEnabled&&this.particleOrchestrator&&this.particleOrchestrator.setEmotion(e,t),i&&i.soulAnimation){const e=i.soulAnimation;this.setCrystalSoulEffects({driftEnabled:!0,driftSpeed:e.driftSpeed||.5,shimmerEnabled:!0,shimmerSpeed:e.shimmerSpeed||.5})}}setCoreGlowEnabled(e){this.coreGlowEnabled=e,this.crystalSoul&&this.crystalSoul.setVisible(e)}setGlassMaterialEnabled(e){const t=e?"glass":"glow";this.renderer.setMaterialMode(t)}setGlowIntensity(e){this.glowIntensityOverride=e,null!==e&&(this.glowIntensity=e,this.baseGlowIntensity=e)}sliderToIntensity(e){const t=e/100;return.3*Math.pow(10/.3,t)}setIntensityCalibration(e){this.intensityCalibrationOffset=e,this.setEmotion(this.emotion,this.undertone)}getGlowIntensity(){return this.glowIntensity}playGesture(e){this.animationManager.playGesture(e,{onUpdate:(e,t)=>{e.position&&(this.position=e.position),e.rotation&&(this.tempEuler.set(e.rotation[0],e.rotation[1],e.rotation[2],"XYZ"),this.gestureQuaternion.setFromEuler(this.tempEuler)),void 0!==e.scale&&(this.scale=this.baseScale*e.scale),void 0!==e.glowIntensity&&(this.glowIntensity=this.baseGlowIntensity*e.glowIntensity)},onComplete:()=>{this.position=[0,0,0],this.scale=this.baseScale}})}setSunShadow(e="off"){"sun"===this.geometryType&&this.effectManager.hasSolarEclipse()?this.effectManager.setSolarEclipse(e):console.warn("⚠️ Eclipse only available for sun geometry")}startSolarEclipse(e={}){const t=e.type||"total";"sun"===this.geometryType&&this.effectManager.hasSolarEclipse()?this.effectManager.setSolarEclipse(t):(this.morphToShape("sun"),setTimeout(()=>{this.effectManager.hasSolarEclipse()&&this.effectManager.setSolarEclipse(t)},600))}startLunarEclipse(e={}){const t=e.type||"total";"moon"===this.geometryType&&this.effectManager.hasLunarEclipse()?this.effectManager.setLunarEclipse(t):(this.morphToShape("moon"),setTimeout(()=>{this.effectManager.hasLunarEclipse()&&this.effectManager.setLunarEclipse(t)},600))}stopEclipse(){this.effectManager.stopAllEclipses()}setMoonEclipse(e="off"){"moon"===this.geometryType&&this.effectManager.hasLunarEclipse()?this.effectManager.setLunarEclipse(e):console.warn("⚠️ Lunar eclipse only available for moon geometry")}setBloodMoonBlend(e={}){"moon"===this.geometryType&&this.customMaterial?(void 0!==e.blendMode&&(this.customMaterial.uniforms.blendMode.value=e.blendMode),void 0!==e.blendStrength&&(this.customMaterial.uniforms.blendStrength.value=e.blendStrength),void 0!==e.emissiveStrength&&(this.customMaterial.uniforms.emissiveStrength.value=e.emissiveStrength),void 0!==e.eclipseIntensity&&(this.customMaterial.uniforms.eclipseIntensity.value=e.eclipseIntensity)):console.warn("⚠️ Blood moon blend only available for moon geometry")}setBlendLayer(e,t={}){if("moon"!==this.geometryType&&"sun"!==this.geometryType||!this.customMaterial)return void console.warn("⚠️ Blend layers only available for moon and sun geometry");const i=`layer${e}`;void 0!==t.mode&&this.customMaterial.uniforms[`${i}Mode`]&&(this.customMaterial.uniforms[`${i}Mode`].value=t.mode),void 0!==t.strength&&this.customMaterial.uniforms[`${i}Strength`]&&(this.customMaterial.uniforms[`${i}Strength`].value=t.strength),void 0!==t.enabled&&this.customMaterial.uniforms[`${i}Enabled`]&&(this.customMaterial.uniforms[`${i}Enabled`].value=t.enabled?1:0)}setAllBlendLayers(e){"moon"!==this.geometryType&&"sun"!==this.geometryType||!this.customMaterial?console.warn("⚠️ Blend layers only available for moon and sun geometry"):e.forEach((e,t)=>{this.setBlendLayer(t+1,e)})}setCrystalBlendLayer(e,t,i={}){if("crystal"!==this.geometryType&&"rough"!==this.geometryType||!this.customMaterial||"crystal"!==this.customMaterialType)return;const n=`${e}Blend${t}`;void 0!==i.mode&&this.customMaterial.uniforms[`${n}Mode`]&&(this.customMaterial.uniforms[`${n}Mode`].value=i.mode),void 0!==i.strength&&this.customMaterial.uniforms[`${n}Strength`]&&(this.customMaterial.uniforms[`${n}Strength`].value=i.strength),void 0!==i.enabled&&this.customMaterial.uniforms[`${n}Enabled`]&&(this.customMaterial.uniforms[`${n}Enabled`].value=i.enabled?1:0)}setCrystalUniforms(e={}){if("crystal"!==this.geometryType&&"rough"!==this.geometryType||!this.customMaterial||"crystal"!==this.customMaterialType)return void console.warn("⚠️ Crystal uniforms only available with crystal blend-layers material");const{uniforms:t}=this.customMaterial,i=(e,t,i=0,n=10)=>{e&&"number"==typeof t&&!isNaN(t)&&isFinite(t)&&(e.value=Math.max(i,Math.min(n,t)))};i(t.coreGlowStrength,e.coreGlowStrength,0,2),void 0===e.coreGlowFalloff||isNaN(e.coreGlowFalloff)||(i(t.coreGlowFalloff,e.coreGlowFalloff,.1,3),this.setCrystalCoreSize(e.coreGlowFalloff)),i(t.fresnelStrength,e.fresnelStrength,0,2),i(t.fresnelPower,e.fresnelPower,.5,10),i(t.transmissionStrength,e.transmissionStrength,0,1),i(t.facetStrength,e.facetStrength,0,2),i(t.iridescenceStrength,e.iridescenceStrength,0,1),i(t.chromaticAberration,e.chromaticAberration,0,1),i(t.causticStrength,e.causticStrength,0,1),i(t.emissiveIntensity,e.emissiveIntensity,0,5),i(t.sparkleEnabled,e.sparkleEnabled,0,1),i(t.sparkleSpeed,e.sparkleSpeed,.1,5),i(t.causticEnabled,e.causticEnabled,0,1),i(t.causticSpeed,e.causticSpeed,.1,10),i(t.causticScale,e.causticScale,.5,10),i(t.causticCoverage,e.causticCoverage,0,1),i(t.energyPulseEnabled,e.energyPulseEnabled,0,1),i(t.energyPulseSpeed,e.energyPulseSpeed,.1,5)}createCrystalInnerCore(){if(this.crystalSoul&&(this.crystalSoul.dispose(),this.crystalSoul=null),!this.coreMesh)return;const e=this._targetGeometryType||this.geometryType;this.crystalSoul=new Cd({radius:.35,detail:1,geometryType:e,renderer:this.renderer,assetBasePath:this.assetBasePath}),this.crystalSoul.attachTo(this.coreMesh,this.renderer?.scene);let t=1;"heart"===e?(this.crystalShellBaseScale=2.4,t=1):"rough"===e?(this.crystalShellBaseScale=1.6,t=1):"star"===e?(this.crystalShellBaseScale=2,t=1.4):"crystal"===e&&(this.crystalShellBaseScale=2,t=1),this.crystalSoul.baseScale=t,this.crystalSoul.mesh.scale.setScalar(t),this.crystalSoul.setVisible(this.coreGlowEnabled),this.crystalInnerCore=this.crystalSoul.mesh,this.crystalInnerCoreMaterial=this.crystalSoul.material,this.crystalInnerCoreBaseScale=this.crystalSoul.baseScale}updateCrystalInnerCore(e,t=0){if(!this.crystalSoul)return;const i=this.breathingAnimator&&this.breathingEnabled?this.breathingAnimator.getBreathingScale():1;this.crystalSoul.update(t,e,i),this.crystalInnerCoreBaseScale=this.crystalSoul.baseScale}setCrystalSoulEffects(e={}){this.crystalSoul&&this.crystalSoul.setEffects(e)}setCrystalCoreSize(e){this.crystalSoul&&(this.crystalSoul.setSize(e),this.crystalInnerCoreBaseScale=this.crystalSoul.baseScale)}setCrystalShellSize(e){!this.coreMesh||"crystal"!==this.geometryType&&"rough"!==this.geometryType&&"heart"!==this.geometryType||(this.crystalShellBaseScale=e)}setWobbleEnabled(e){this.wobbleEnabled=e,this.rotationBehavior&&this.rotationBehavior.setWobbleEnabled(e),e||(this.rightingBehavior&&this.rightingBehavior.reset(),this.baseEuler[0]=0,this.baseEuler[2]=0)}setMaterialVariant(e){this.materialVariant=e}setRhythmEnabled(e){this.rhythmEnabled=e,e&&this.rhythm3DAdapter&&!this.rhythm3DAdapter.enabled&&this.rhythm3DAdapter.initialize()}setGrooveEnabled(e){this.rhythm3DAdapter&&this.rhythm3DAdapter.setGrooveEnabled(e)}setBeatSyncStrength(e){this.rhythm3DAdapter&&this.rhythm3DAdapter.setBeatSyncStrength(e)}setGrooveConfig(e){this.rhythm3DAdapter&&this.rhythm3DAdapter.setGrooveConfig(e)}isRhythmPlaying(){return this.rhythm3DAdapter?.isPlaying()||!1}getRhythmBPM(){return this.rhythm3DAdapter?.getBPM()||120}startRhythm(e=120,t="straight"){this.rhythm3DAdapter&&this.rhythm3DAdapter.start(e,t)}stopRhythm(){this.rhythm3DAdapter&&this.rhythm3DAdapter.stop()}setRhythmBPM(e){this.rhythm3DAdapter&&this.rhythm3DAdapter.setBPM(e)}setRhythmPattern(e){this.rhythm3DAdapter&&this.rhythm3DAdapter.setPattern(e)}breathePhase(e,t){this.breathingPhaseManager.startPhase(e,t);const i=this.breathingPhaseManager.getState();console.log(`[Core3D] breathePhase: ${e} for ${t}s (${i.startScale.toFixed(2)} → ${i.targetScale.toFixed(2)})`)}stopBreathingPhase(){this.breathingPhaseManager.stop(),console.log("[Core3D] breathePhase stopped, scale reset to 1.0")}_updateBreathingPhase(e){return this.breathingPhaseManager.update(e)}morphToShape(e,t=800){const i=fc[e];i?this.geometryMorpher.startMorph(this.geometryType,e,t)&&(this.geometryMorpher.getInterruptedTarget(),this.blinkAnimator.pause(),this._targetGeometryConfig=i,this._targetGeometryType=e,i.geometryLoader&&!i.geometry?(this._targetGeometry=null,this._pendingGeometryLoad=i.geometryLoader(this.assetBasePath).then(e=>{this._targetGeometry=e,i.geometry=e,this._pendingGeometryLoad=null})):(this._targetGeometry=i.geometry,this._pendingGeometryLoad=null)):console.warn(`Unknown shape: ${e}`)}isMorphing(){return this.geometryMorpher.isTransitioning}getMorphState(){return this.geometryMorpher.getState()}growIn(e=500){this.geometryMorpher.growIn(this.geometryType,e)}easeInOutCubic(e){return e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2}render(e){if(this._destroyed)return;if(!this._ready)return;this.animator.update(e);const t=this.geometryMorpher.update(e);if(t.shouldSwapGeometry&&this._pendingGeometryLoad&&this.geometryMorpher.pauseAtSwap(),t.waitingForGeometry&&this._targetGeometry&&!this._pendingGeometryLoad&&(this.geometryMorpher.resumeFromSwap(),this.geometryMorpher.hasSwappedGeometry=!1),t.shouldSwapGeometry&&this._targetGeometry){const e=this.geometryType;this.customMaterial&&function(e,t){switch(e){case"moon":!function(e){if(!e||!e.uniforms)return;const t=e.uniforms;t.shadowOffset&&t.shadowOffset.value.set(Wh.full.x,Wh.full.y),t.shadowCoverage&&(t.shadowCoverage.value=.5),t.shadowSoftness&&(t.shadowSoftness.value=.05),t.eclipseProgress&&(t.eclipseProgress.value=0),t.eclipseIntensity&&(t.eclipseIntensity.value=0),t.bloodMoonColor&&(t.bloodMoonColor.value=[.85,.18,.08]),t.emissiveStrength&&(t.emissiveStrength.value=.39),t.eclipseShadowPos&&(t.eclipseShadowPos.value=[-2,0]),t.eclipseShadowRadius&&(t.eclipseShadowRadius.value=1.2),t.shadowDarkness&&(t.shadowDarkness.value=.53),t.eclipseShadowColor&&(t.eclipseShadowColor.value=[1,.58,0]),t.eclipseMidtoneColor&&(t.eclipseMidtoneColor.value=[.71,.43,.03]),t.eclipseHighlightColor&&(t.eclipseHighlightColor.value=[1,.28,.1]),t.eclipseGlowColor&&(t.eclipseGlowColor.value=[.09,.09,.09]),t.eclipseBrightnessModel&&(t.eclipseBrightnessModel.value=0),t.layer1Mode&&(t.layer1Mode.value=9),t.layer1Strength&&(t.layer1Strength.value=.322),t.layer1Enabled&&(t.layer1Enabled.value=1),t.layer2Mode&&(t.layer2Mode.value=0),t.layer2Strength&&(t.layer2Strength.value=2.785),t.layer2Enabled&&(t.layer2Enabled.value=1),t.layer3Mode&&(t.layer3Mode.value=7),t.layer3Strength&&(t.layer3Strength.value=.199),t.layer3Enabled&&(t.layer3Enabled.value=1),t.layer4Mode&&(t.layer4Mode.value=0),t.layer4Strength&&(t.layer4Strength.value=0),t.layer4Enabled&&(t.layer4Enabled.value=0),t.opacity&&(t.opacity.value=1)}(t);break;case"sun":!function(e){if(!e||!e.uniforms)return;const t=e.uniforms;t.eclipseProgress&&(t.eclipseProgress.value=0),t.eclipseShadowPos&&(t.eclipseShadowPos.value=[-2,0]),t.eclipseShadowRadius&&(t.eclipseShadowRadius.value=.882),t.shadowDarkness&&(t.shadowDarkness.value=1),t.shadowOffset&&t.shadowOffset.value.set(200,0),t.shadowCoverage&&(t.shadowCoverage.value=.5),t.shadowSoftness&&(t.shadowSoftness.value=.1),t.layer1Mode&&(t.layer1Mode.value=0),t.layer1Strength&&(t.layer1Strength.value=.23),t.layer1Enabled&&(t.layer1Enabled.value=1),t.layer2Mode&&(t.layer2Mode.value=0),t.layer2Strength&&(t.layer2Strength.value=0),t.layer2Enabled&&(t.layer2Enabled.value=0),t.layer3Mode&&(t.layer3Mode.value=0),t.layer3Strength&&(t.layer3Strength.value=0),t.layer3Enabled&&(t.layer3Enabled.value=0),t.layer4Mode&&(t.layer4Mode.value=0),t.layer4Strength&&(t.layer4Strength.value=0),t.layer4Enabled&&(t.layer4Enabled.value=0),t.emissiveIntensity&&(t.emissiveIntensity.value=4),t.opacity&&(t.opacity.value=1),t.time&&(t.time.value=0)}(t);break;case"crystal":case"diamond":!function(e){if(!e||!e.uniforms)return;const t=e.uniforms,i=Od;t.frostiness&&(t.frostiness.value=i.frostiness),t.fresnelPower&&(t.fresnelPower.value=i.fresnelPower),t.fresnelIntensity&&(t.fresnelIntensity.value=i.fresnelIntensity),t.innerGlowStrength&&(t.innerGlowStrength.value=i.innerGlowStrength),t.surfaceRoughness&&(t.surfaceRoughness.value=i.surfaceRoughness),t.surfaceNoiseScale&&(t.surfaceNoiseScale.value=i.surfaceNoiseScale),t.noiseFrequency&&(t.noiseFrequency.value=i.noiseFrequency),t.causticIntensity&&(t.causticIntensity.value=i.causticIntensity),t.causticScale&&(t.causticScale.value=i.causticScale),t.causticSpeed&&(t.causticSpeed.value=i.causticSpeed),t.textureStrength&&(t.textureStrength.value=i.textureStrength),t.layer1Mode&&(t.layer1Mode.value=i.layer1Mode),t.layer1Strength&&(t.layer1Strength.value=i.layer1Strength),t.layer1Enabled&&(t.layer1Enabled.value=i.layer1Enabled),t.layer2Mode&&(t.layer2Mode.value=i.layer2Mode),t.layer2Strength&&(t.layer2Strength.value=i.layer2Strength),t.layer2Enabled&&(t.layer2Enabled.value=i.layer2Enabled),t.layer3Mode&&(t.layer3Mode.value=i.layer3Mode),t.layer3Strength&&(t.layer3Strength.value=i.layer3Strength),t.layer3Enabled&&(t.layer3Enabled.value=i.layer3Enabled),t.layer4Mode&&(t.layer4Mode.value=i.layer4Mode),t.layer4Strength&&(t.layer4Strength.value=i.layer4Strength),t.layer4Enabled&&(t.layer4Enabled.value=i.layer4Enabled),t.glowIntensity&&(t.glowIntensity.value=i.glowIntensity),t.opacity&&(t.opacity.value=i.opacity),t.time&&(t.time.value=i.time)}(t)}}(e,this.customMaterial),this.geometry=this._targetGeometry,this.geometryType=this._targetGeometryType,this.geometryConfig=this._targetGeometryConfig,this.customMaterial&&(zd(this.customMaterial),this.renderer.disposeMaterial(this.customMaterial),this.customMaterial=null,this.customMaterialType=null);let t=null;const i=Tc(this.emotion),n=Fd(this._targetGeometryType,this._targetGeometryConfig,{glowColor:this.glowColor||[1,1,.95],glowIntensity:this.glowIntensity||1,materialVariant:this.materialVariant,emotionData:i,assetBasePath:this.assetBasePath});if(n&&(t=n.material,this.customMaterial=t,this.customMaterialType=n.type),t)this.renderer.swapGeometry(this.geometry,t);else{this.renderer.swapGeometry(this.geometry);const e=!0===this._targetGeometryConfig.defaultGlassMode;this.setGlassMaterialEnabled(e)}this.onMaterialSwap&&this.onMaterialSwap({geometryType:this._targetGeometryType,material:this.customMaterial,materialType:this.customMaterialType}),this.blinkAnimator.setGeometry(this._targetGeometryConfig),this.rightingBehavior&&this.rightingBehavior.reset(),this.rotation=[0,0,0];const a=this.geometry.parameters?.radius||.5;if(this.effectManager.initializeForGeometry(this._targetGeometryType,{coreMesh:this.renderer.coreMesh,customMaterial:this.customMaterial,sunRadius:a}),"crystal"===this._targetGeometryType||"rough"===this._targetGeometryType||"heart"===this._targetGeometryType||"star"===this._targetGeometryType?"crystal"===this.customMaterialType&&this.createCrystalInnerCore():this.crystalSoul&&(this.crystalSoul.dispose(),this.crystalSoul=null,this.crystalInnerCore=null,this.crystalInnerCoreMaterial=null),"moon"===this._targetGeometryType){this.rotationBehavior=null,this.renderer?.controls&&(this.renderer.controls.autoRotate=!1),this.renderer?.setCameraPreset&&this.renderer.setCameraPreset("front",0,!0);const e=Math.PI/180;this.calibrationRotation[0]=Nh*e,this.calibrationRotation[1]=Gh*e,this.calibrationRotation[2]=Vh*e,!this.facingBehavior&&Hh.enabled&&(this.facingBehavior=new Uc({strength:Hh.strength,lockedFace:Hh.lockedFace,lerpSpeed:Hh.lerpSpeed,calibrationRotation:[Nh*e,Gh*e,Vh*e]},this.renderer.camera))}else{if(this.facingBehavior&&(this.facingBehavior.dispose(),this.facingBehavior=null),this.renderer?.controls&&!1!==this.options.autoRotate&&(this.renderer.controls.autoRotate=!0),"crystal"===this._targetGeometryType||"rough"===this._targetGeometryType||"heart"===this._targetGeometryType){const e=Math.PI/180;this.calibrationRotation[0]=0*e,this.calibrationRotation[1]=30*e,this.calibrationRotation[2]=0*e}else this.calibrationRotation[0]=0,this.calibrationRotation[1]=0,this.calibrationRotation[2]=0;if(this.rotationDisabled)this.rotationBehavior=null;else{const e=Tc(this.emotion);e&&e["3d"]&&e["3d"].rotation&&(this.rotationBehavior?this.rotationBehavior.updateConfig(e["3d"].rotation):(this.rotationBehavior=new Oc(e["3d"].rotation,this.rhythmEngine),this.rotationBehavior.setWobbleEnabled(this.wobbleEnabled)))}}}t.completed&&(this._targetGeometry=null,this._targetGeometryType=null,this._targetGeometryConfig=null,this.blinkingManuallyDisabled||this.blinkAnimator.resume()),this.breathingAnimator.update(e,this.emotion,Ru(this.undertone));const i=this._updateBreathingPhase(e),n=1!==i?i:this.breathingEnabled?this.breathingAnimator.getBreathingScale():1,a=t.scaleMultiplier,r=this.blinkAnimator.update(e);this.rotationBehavior?this.rotationBehavior.update(e,this.baseEuler):"moon"===this.geometryType||this.rotationDisabled||(this.baseEuler[1]+=3e-4*e),this.rightingBehavior&&this.rightingBehavior.update(e,this.baseEuler),this.facingBehavior&&(this.baseEuler[0]=0,this.baseEuler[1]=0,this.baseEuler[2]=0);this.baseEuler[0]=Math.max(-.35,Math.min(.35,this.baseEuler[0])),this.baseEuler[2]=Math.max(-.35,Math.min(.35,this.baseEuler[2])),this.tempEuler.set(this.baseEuler[0],this.baseEuler[1],this.baseEuler[2],"XYZ"),this.baseQuaternion.setFromEuler(this.tempEuler),this.rhythm3DAdapter&&this.rhythm3DAdapter.update(e);const s=this.animationManager.blend(this.baseQuaternion,this.baseScale,this.baseGlowIntensity),o=this.rhythm3DAdapter?.isPlaying()?this.rhythm3DAdapter.getModulation():null,l=this.animationManager.hasActiveAnimations();this.position=o&&!l?[s.position[0]+o.grooveOffset[0],s.position[1]+o.grooveOffset[1],s.position[2]+o.grooveOffset[2]]:o&&l?[s.position[0]*o.positionMultiplier,s.position[1]*o.positionMultiplier,s.position[2]*o.positionMultiplier]:s.position,this.rotation=o&&!l?[s.rotation[0]+o.grooveRotation[0],s.rotation[1]+o.grooveRotation[1],s.rotation[2]+o.grooveRotation[2]]:s.rotation,this.scale=o&&!l?s.scale*o.grooveScale:o&&l?s.scale*o.scaleMultiplier:s.scale,null===this.glowIntensityOverride&&(this.glowIntensity=o&&l?s.glowIntensity*o.glowMultiplier:s.glowIntensity),this.gestureQuaternion=s.gestureQuaternion,this.glowBoost=s.glowBoost||0,r.isBlinking&&r.rotation&&(this.rotation[0]+=r.rotation[0],this.rotation[1]+=r.rotation[1],this.rotation[2]+=r.rotation[2]);const h="crystal"!==this.geometryType&&"rough"!==this.geometryType,c=r.isBlinking&&h?r.scale[1]:1,u=this.crystalShellBaseScale||2,d=this.scale*a*n*c*u;if(this.particleVisibility&&this.particleOrchestrator){const t=this.geometryConfig?.particleRadiusMultiplier||1,i=(this.crystalShellBaseScale||2)*this.scale*n*t;this.particleOrchestrator.update(e,this.emotion,this.undertone,this.animationManager.getActiveAnimations(),this.animationManager.getTime(),{x:this.position[0],y:this.position[1],z:this.position[2]},{width:this.canvas.width,height:this.canvas.height},{euler:this.baseEuler,quaternion:this.baseQuaternion,angularVelocity:this.rotationBehavior?this.rotationBehavior.axes:[0,0,0]},this.baseScale,i)}const p=r.isBlinking&&r.glowBoost?1+r.glowBoost:1,m=this.coreGlowEnabled?this.glowIntensity*p:0,f=this.emotiveEngine?.getVirtualParticle(),g=m*(f?.opacity??1),v=t.isTransitioning?.3:.1;if(this.renderer.updateBloom(g,v,this.geometryType),this.glowBoost>0||this.renderer.glowLayer&&this.renderer.glowLayer.isActive()){const t=this.coreMesh?.position;this.renderer.updateGlowLayer(this.glowBoost,this.glowColor,t,e)}if("sun"===this.customMaterialType&&lc(this.coreMesh,this.glowColor,g,e),"moon"!==this.customMaterialType&&"moon-multiplexer"!==this.customMaterialType||!this.customMaterial||this.customMaterial.uniforms&&this.customMaterial.uniforms.glowIntensity&&(this.customMaterial.uniforms.glowIntensity.value=g),"crystal"===this.customMaterialType&&this.customMaterial){if(this.customMaterial.uniforms){this.customMaterial.uniforms.time.value+=e/1e3,this.customMaterial.uniforms.glowIntensity&&(this.customMaterial.uniforms.glowIntensity.value=g);const t=gh(this.glowColor,.3),i=[t.r,t.g,t.b];if(this.customMaterial.uniforms.emotionColor.value.setRGB(i[0],i[1],i[2]),this.customMaterial.uniforms.blinkIntensity){const e=r.isBlinking?Math.sin(r.progress*Math.PI):0;this.customMaterial.uniforms.blinkIntensity.value=e}}if(this.coreGlowEnabled){const t=gh(this.glowColor,.3),i=[t.r,t.g,t.b];this.updateCrystalInnerCore(i,e)}}this.renderer.render({position:this.position,rotation:this.rotation,scale:d,glowColor:this.glowColor,glowColorHex:this.glowColorHex,glowIntensity:g,hasActiveGesture:this.animationManager.hasActiveAnimations(),calibrationRotation:this.calibrationRotation,solarEclipse:this.effectManager.getSolarEclipse(),deltaTime:e,morphProgress:t.isTransitioning?t.visualProgress:null}),this.effectManager.updateLunarEclipse(e)}async _loadAsyncGeometry(){try{const e=await Nd(this.geometryType,{glowColor:this.glowColor||[1,1,.95],glowIntensity:this.glowIntensity||1,materialVariant:this.materialVariant,emotionData:Tc(this.emotion),assetBasePath:this.assetBasePath});if(this._destroyed)return;if(!e||!e.geometry)return console.warn(`[Core3D:${this._instanceId}] Async geometry load returned null!`),void(this._ready=!0);const t=e.geometry.clone();if(t.userData.geometryType=this.geometryType,this.geometry=t,this._deferredMeshCreation){if(this.coreMesh=this.renderer.createCoreMesh(t,this.customMaterial),this._destroyed)return;if("crystal"===this.customMaterialType&&(await this._createCrystalInnerCoreAsync(),this._destroyed))return;this._deferredMeshCreation=!1}else if(this.coreMesh){const e=this.coreMesh.geometry;if(this.coreMesh.geometry=t,e&&e!==t&&e.dispose(),this._destroyed)return;if("crystal"===this.customMaterialType&&(await this._createCrystalInnerCoreAsync(),this._destroyed))return}if(this._destroyed)return;this._logSceneHierarchy(),this._ready=!0}catch(e){console.warn(`[Core3D:${this._instanceId}] Async geometry load FAILED:`,e),this._destroyed||(this._ready=!0)}}_logSceneHierarchy(){const e=this.renderer?.scene;e&&e.children.forEach((e,t)=>{const i=null===e?"NULL!":void 0===e?"UNDEFINED!":null===e.visible?"visible=NULL!":void 0===e.visible?"visible=UNDEF!":"OK";console.log(` [${t}] ${e?.name||e?.type||"UNKNOWN"} status=${i} uuid=${e?.uuid?.slice(0,8)||"N/A"}`)})}async _createCrystalInnerCoreAsync(){if(this.crystalSoul&&(this.crystalSoul.dispose(),this.crystalSoul=null),!this.coreMesh)return;if(await Cd._loadInclusionGeometry(this.assetBasePath),this._destroyed||!this.coreMesh)return;this.crystalSoul=new Cd({radius:.35,detail:1,geometryType:this.geometryType,renderer:this.renderer,assetBasePath:this.assetBasePath}),this.crystalSoul.attachTo(this.coreMesh,this.renderer?.scene);let e=1;"heart"===this.geometryType?(this.crystalShellBaseScale=2.4,e=1):"rough"===this.geometryType?(this.crystalShellBaseScale=1.6,e=1):"crystal"===this.geometryType&&(e=1),this.crystalSoul.baseScale=e,this.crystalSoul.mesh.scale.setScalar(e),this.crystalSoul.setVisible(this.coreGlowEnabled),this.crystalInnerCore=this.crystalSoul.mesh,this.crystalInnerCoreMaterial=this.crystalSoul.material,this.crystalInnerCoreBaseScale=this.crystalSoul.baseScale}isReady(){return this._ready}async waitUntilReady(){this._ready||this._readyPromise&&await this._readyPromise}destroy(){if(this._instanceId,this._ready,this._destroyed,this.crystalSoul,this.renderer,this._destroyed=!0,this.crystalSoul&&(this.crystalSoul.dispose(),this.crystalSoul=null,this.crystalInnerCore=null,this.crystalInnerCoreMaterial=null),this.particleOrchestrator){const e=this.particleOrchestrator.renderer;if(e){const t=e.getPoints();t&&this.renderer?.scene&&this.renderer.scene.remove(t)}this.particleOrchestrator.destroy(),this.particleOrchestrator=null}this.effectManager&&(this.effectManager.dispose(),this.effectManager=null),this.behaviorController&&(this.behaviorController.dispose(),this.behaviorController=null),this.breathingPhaseManager&&(this.breathingPhaseManager.dispose(),this.breathingPhaseManager=null),this.customMaterial&&(this.renderer.disposeMaterial(this.customMaterial),this.customMaterial=null,this.customMaterialType=null),this.facingBehavior&&(this.facingBehavior.dispose(),this.facingBehavior=null),this.animationManager.stopAll(),this.renderer.destroy(),this.animationManager.dispose(),this.animationManager=null,this.animator.destroy?.(),this.breathingAnimator.destroy?.(),this.gestureBlender.destroy?.(),this.geometryMorpher.destroy?.(),this.blinkAnimator.destroy?.(),this.rotationBehavior&&(this.rotationBehavior.destroy?.(),this.rotationBehavior=null),this.rightingBehavior&&(this.rightingBehavior.destroy?.(),this.rightingBehavior=null),this.tempEuler=null,this.baseQuaternion=null,this.gestureQuaternion=null,this.geometry=null,this.geometryConfig=null,this._targetGeometry=null,this._targetGeometryConfig=null,this._targetGeometryType=null,this.canvas=null,this.options=null,this.coreMesh=null,this.rhythmEngine=null,this.rhythm3DAdapter=null,this.emotiveEngine=null,Vd()}async preloadGeometries(){const e={glowColor:this.glowColor||[1,1,.95],glowIntensity:this.glowIntensity||1,materialVariant:this.materialVariant,emotionData:Tc(this.emotion)};await Gd(e)}}class rp{constructor(){this.listeners=new Map,this.groups=new Map,this.stats={registered:0,removed:0,active:0}}addEventListener(e,t,i,n={},a="default"){const r=this.generateId(),s={id:r,target:e,eventType:t,handler:i,options:n,group:a,active:!0};return this.listeners.set(r,s),this.groups.has(a)||this.groups.set(a,new Set),this.groups.get(a).add(r),e.addEventListener(t,i,n),this.stats.registered++,this.stats.active++,r}removeEventListener(e){const t=this.listeners.get(e);if(!t||!t.active)return!1;t.target.removeEventListener(t.eventType,t.handler,t.options),t.active=!1;const i=this.groups.get(t.group);return i&&(i.delete(e),0===i.size&&this.groups.delete(t.group)),this.listeners.delete(e),this.stats.removed++,this.stats.active--,!0}removeGroup(e){const t=this.groups.get(e);if(!t)return 0;let i=0;for(const e of t)this.removeEventListener(e)&&i++;return i}removeAllForTarget(e){let t=0;for(const[i,n]of this.listeners.entries())n.target===e&&n.active&&this.removeEventListener(i)&&t++;return t}removeAllOfType(e){let t=0;for(const[i,n]of this.listeners.entries())n.eventType===e&&n.active&&this.removeEventListener(i)&&t++;return t}removeAll(){let e=0;for(const[t,i]of this.listeners.entries())i.active&&this.removeEventListener(t)&&e++;return e}createAutoRemove(e,t,i,n={}){const a=this.addEventListener(e,t,i,n);return{id:a,remove:()=>this.removeEventListener(a)}}once(e,t,i,n={}){const a=this.addEventListener(e,t,e=>{i(e),this.removeEventListener(a)},n);return a}debounced(e,t,i,n=250,a={}){let r;return this.addEventListener(e,t,e=>{clearTimeout(r),r=setTimeout(()=>i(e),n)},a)}throttled(e,t,i,n=100,a={}){let r=!1;return this.addEventListener(e,t,e=>{r||(i(e),r=!0,setTimeout(()=>{r=!1},n))},a)}generateId(){return`listener_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}getStats(){return{...this.stats,groups:this.groups.size,listeners:this.listeners.size}}getActiveListeners(){const e=[];for(const[t,i]of this.listeners.entries())i.active&&e.push({id:t,eventType:i.eventType,group:i.group,target:i.target.constructor.name});return e}analyzeLeaks(){const e={totalListeners:this.listeners.size,activeListeners:this.stats.active,inactiveButNotRemoved:0,byTarget:new Map,byType:new Map,potentialLeaks:[]};for(const[t,i]of this.listeners.entries()){const n=i.target.constructor.name;e.byTarget.set(n,(e.byTarget.get(n)||0)+1),e.byType.set(i.eventType,(e.byType.get(i.eventType)||0)+1),i.active||(e.inactiveButNotRemoved++,e.potentialLeaks.push({id:t,eventType:i.eventType,target:n}))}return e.byTarget=Object.fromEntries(e.byTarget),e.byType=Object.fromEntries(e.byType),e}cleanup(){let e=0;for(const[t,i]of this.listeners.entries())i.active||(this.listeners.delete(t),e++);return e}destroy(){const e=this.removeAll();return this.listeners.clear(),this.groups.clear(),this.stats={registered:0,removed:0,active:0},e}}class sp{constructor(){this.errors=[],this.maxErrors=10,this.errorCounts=new Map,this.defaults={emotion:"neutral",gesture:null,audioLevel:0,particleCount:0,glowIntensity:.7,coreSize:1,breathRate:1,color:"#B0B0B0"}}wrap(e,t,i=null){return(...n)=>{try{return e(...n)}catch(e){return this.logError(e,t),null!==i?i:this.getDefault(t)}}}logError(e,t){const i={timestamp:(new Date).toISOString(),context:t,message:e.message,stack:e.stack};this.errors.push(i);const n=this.errorCounts.get(t)||0;this.errorCounts.set(t,n+1),this.errors.length>this.maxErrors&&this.errors.shift()}getDefault(e){const t={"emotion-transition":this.defaults.emotion,"gesture-execution":this.defaults.gesture,"audio-processing":this.defaults.audioLevel,"particle-system":this.defaults.particleCount,rendering:{glowIntensity:this.defaults.glowIntensity,coreSize:this.defaults.coreSize,color:this.defaults.color},"canvas-operations":null,"state-management":this.defaults.emotion};return Object.prototype.hasOwnProperty.call(t,e)?t[e]:null}validateInput(e,t,i){try{switch(t){case"emotion":return["neutral","joy","sadness","anger","fear","surprise","disgust","love","euphoria"].includes(e)?e:i;case"undertone":return null===e||["nervous","confident","tired","intense","subdued"].includes(e)?e:null;case"gesture":return["bounce","pulse","shake","spin","nod","tilt","expand","contract","flash","drift"].includes(e)?e:i;case"number":return"number"!=typeof e||isNaN(e)?i:e;case"string":return"string"==typeof e?e:i;case"boolean":return"boolean"==typeof e?e:i;default:return null!=e?e:i}}catch(e){return this.logError(e,"input-validation"),i}}hasExceededThreshold(e,t=5){return(this.errorCounts.get(e)||0)>=t}getErrorStats(){return{totalErrors:this.errors.length,errorsByContext:Object.fromEntries(this.errorCounts),recentErrors:this.errors.slice(-5)}}clearErrors(){this.errors=[],this.errorCounts.clear()}async attemptRecovery(e,t,i=3){let n=0;for(;n<i;)try{return await t()}catch(t){if(n++,this.logError(t,`recovery-${e}-attempt-${n}`),n>=i)throw new Error(`Recovery failed for ${e} after ${i} attempts`);await new Promise(e=>setTimeout(e,100*Math.pow(2,n)))}}}const op={quartz:{sssStrength:.8,sssAbsorption:[2.8,2.9,3],sssScatterDistance:[.2,.2,.25],sssThicknessBias:.6,sssThicknessScale:1.8,sssCurvatureScale:3,sssAmbient:.12,frostiness:.15,innerGlowStrength:.2,fresnelIntensity:1.5,causticIntensity:1.2,emotionColorBleed:0},emerald:{sssStrength:2,sssAbsorption:[.05,4,.1],sssScatterDistance:[.1,.5,.1],sssThicknessBias:.65,sssThicknessScale:1.8,sssCurvatureScale:3,sssAmbient:.1,frostiness:.2,innerGlowStrength:.15,fresnelIntensity:1.2,causticIntensity:1,emotionColorBleed:.35},ruby:{sssStrength:1.8,sssAbsorption:[4,.03,.08],sssScatterDistance:[.4,.04,.08],sssThicknessBias:.65,sssThicknessScale:1.9,sssCurvatureScale:2.5,sssAmbient:.08,frostiness:.12,innerGlowStrength:.12,fresnelIntensity:1.2,causticIntensity:1.15,emotionColorBleed:.35},sapphire:{sssStrength:2.2,sssAbsorption:[.15,.4,4],sssScatterDistance:[.1,.15,.5],sssThicknessBias:.65,sssThicknessScale:1.8,sssCurvatureScale:3,sssAmbient:.1,frostiness:.18,innerGlowStrength:.15,fresnelIntensity:1.3,causticIntensity:1,emotionColorBleed:.35},amethyst:{sssStrength:2.5,sssAbsorption:[3,.05,4.5],sssScatterDistance:[.4,.05,.5],sssThicknessBias:.7,sssThicknessScale:2,sssCurvatureScale:3,sssAmbient:.08,frostiness:.18,innerGlowStrength:.12,fresnelIntensity:1.4,causticIntensity:1,emotionColorBleed:.35},topaz:{sssStrength:1.5,sssAbsorption:[3.5,2,.1],sssScatterDistance:[.3,.2,.05],sssThicknessBias:.6,sssThicknessScale:1.7,sssCurvatureScale:2.8,sssAmbient:.12,frostiness:.14,innerGlowStrength:.18,fresnelIntensity:1.4,causticIntensity:1.1,emotionColorBleed:.25},citrine:{sssStrength:1.6,sssAbsorption:[3.8,2.5,.05],sssScatterDistance:[.35,.25,.05],sssThicknessBias:.58,sssThicknessScale:1.6,sssCurvatureScale:2.6,sssAmbient:.14,frostiness:.12,innerGlowStrength:.22,fresnelIntensity:1.3,causticIntensity:1.2,emotionColorBleed:.2},diamond:{sssStrength:.5,sssAbsorption:[2.5,2.5,2.5],sssScatterDistance:[.15,.15,.15],sssThicknessBias:.55,sssThicknessScale:1.5,sssCurvatureScale:4,sssAmbient:.15,frostiness:.08,innerGlowStrength:.25,fresnelIntensity:2,causticIntensity:1.5,emotionColorBleed:0}};function lp(e,t){if(!t||!e?.core3D?.customMaterial?.uniforms)return!1;const i=op[t];if(!i)return!1;const n=e.core3D.customMaterial.uniforms;return n.sssStrength&&(n.sssStrength.value=i.sssStrength),n.sssAbsorption&&n.sssAbsorption.value.set(...i.sssAbsorption),n.sssScatterDistance&&n.sssScatterDistance.value.set(...i.sssScatterDistance),n.sssThicknessBias&&(n.sssThicknessBias.value=i.sssThicknessBias),n.sssThicknessScale&&(n.sssThicknessScale.value=i.sssThicknessScale),n.sssCurvatureScale&&(n.sssCurvatureScale.value=i.sssCurvatureScale),n.sssAmbient&&(n.sssAmbient.value=i.sssAmbient),n.frostiness&&(n.frostiness.value=i.frostiness),n.innerGlowStrength&&(n.innerGlowStrength.value=i.innerGlowStrength),n.fresnelIntensity&&(n.fresnelIntensity.value=i.fresnelIntensity),void 0!==i.causticIntensity&&n.causticIntensity&&(n.causticIntensity.value=i.causticIntensity),n.emotionColorBleed&&(n.emotionColorBleed.value=i.emotionColorBleed??0),!0}function hp(){return Object.keys(op)}function cp(e){return op[e]||null}const up=["bouncing up and down","hopping around","rocking back and forth","side to side","light on feet","spring in step","leaning forward","leaning in","leaning closer","leaning toward","reaching out","reaching toward","pointing at","pointing to","waving hello","waving goodbye","nodding head","shaking head","head shake","head nod","head bob","head tilt","deep breath","taking a breath","breathing deeply","settling down","calming down","winding down","getting bigger","getting smaller","puffing up","spinning around","twirling around","at peace","in love","on cloud nine","over the moon","on top of the world","in awe","grossed out","freaked out","low key","low-key","high key","on edge","keyed up","wound up","low energy","no energy","running low","just a bit","just a little","a little bit","kind of","sort of","a bit","a little","a lot","over the top","off the charts","through the roof","split second","one time","few times","many times","again and again","over and over","on repeat","blood moon","full moon","new moon","half moon","solar eclipse","lunar eclipse","total eclipse","ring of fire","diamond ring","killing it","crushing it","nailed it","sussy baka","side eye"],dp=/[,;|\/]+/,pp=new Set(["a","an","the","is","are","am","be","being","been","i","me","my","it","its","to","of","for","with","as","this","that","these","those","just","only","also","too","please","pls","plz"]),mp=new Set(["but","and","or","yet","while","although","not","no","never","very","really","so","quite","rather","slightly","barely","extremely","completely","feeling","feel","feels","become","becoming","morph","morphing"]);function fp(e){return e.toLowerCase().trim().replace(/['']/g,"'").replace(/[""]/g,'"').replace(/\s+/g," ")}function gp(e){return["but","and","or","yet","while","although","with"].includes(e)}function vp(e){return["not","no","never","don't","dont","doesn't","doesnt","isn't","isnt"].includes(e)}const yp={nervous:{candidates:[{category:"emotion",target:"fear",priority:1},{category:"undertone",target:"nervous",priority:2}],rule:"standalone_is_emotion",examples:[{input:"nervous",resolved:{emotion:"fear"}},{input:"happy but nervous",resolved:{emotion:"joy",undertone:"nervous"}}]},anxious:{candidates:[{category:"emotion",target:"fear",priority:1},{category:"undertone",target:"nervous",priority:2}],rule:"standalone_is_emotion"},confident:{candidates:[{category:"emotion",target:"trust",priority:2},{category:"undertone",target:"confident",priority:1}],rule:"prefer_undertone",examples:[{input:"confident",resolved:{undertone:"confident"}},{input:"feeling confident",resolved:{emotion:"trust"}}]},tired:{candidates:[{category:"emotion",target:"sadness",priority:2},{category:"undertone",target:"tired",priority:1}],rule:"prefer_undertone",examples:[{input:"tired",resolved:{undertone:"tired"}},{input:"feeling tired",resolved:{emotion:"sadness",undertone:"tired"}}]},intense:{candidates:[{category:"undertone",target:"intense",priority:1},{category:"modifier",target:"intensity.very",priority:2}],rule:"prefer_undertone"},curious:{candidates:[{category:"emotion",target:"focused",priority:1},{category:"gesture",target:"lean",priority:2}],rule:"standalone_is_emotion",examples:[{input:"curious",resolved:{emotion:"focused"}},{input:"curious, leaning in",resolved:{emotion:"focused",gesture:"lean"}}]},interested:{candidates:[{category:"emotion",target:"focused",priority:1},{category:"gesture",target:"lean",priority:2}],rule:"standalone_is_emotion"},excited:{candidates:[{category:"emotion",target:"joy",priority:1},{category:"gesture",target:"bounce",priority:3}],rule:"standalone_is_emotion"},shaking:{candidates:[{category:"gesture",target:"shake",priority:1},{category:"emotion",target:"fear",priority:2}],rule:"standalone_is_gesture"},nodding:{candidates:[{category:"gesture",target:"nod",priority:1}],rule:"always_gesture"},glowing:{candidates:[{category:"gesture",target:"glow",priority:1},{category:"shape",target:"sun",priority:3}],rule:"standalone_is_gesture"},spinning:{candidates:[{category:"gesture",target:"spin",priority:1}],rule:"always_gesture"},love:{candidates:[{category:"emotion",target:"love",priority:1},{category:"shape",target:"heart",priority:2}],rule:"standalone_is_emotion",examples:[{input:"love",resolved:{emotion:"love"}},{input:"love heart",resolved:{emotion:"love",shape:"heart"}},{input:"become love",resolved:{shape:"heart"}}]},suspicious:{candidates:[{category:"emotion",target:"suspicion",priority:1},{category:"shape",target:"suspicion",priority:2}],rule:"standalone_is_emotion"},bright:{candidates:[{category:"emotion",target:"joy",priority:2},{category:"shape",target:"sun",priority:3},{category:"modifier",target:"intensity.very",priority:4}],rule:"context_dependent"},yes:{candidates:[{category:"gesture",target:"nod",priority:1}],rule:"always_gesture"},no:{candidates:[{category:"gesture",target:"shake",priority:1}],rule:"always_gesture"},agree:{candidates:[{category:"gesture",target:"nod",priority:1},{category:"emotion",target:"trust",priority:2}],rule:"standalone_is_gesture"},disagree:{candidates:[{category:"gesture",target:"shake",priority:1}],rule:"always_gesture"}},bp={emotionContext:["feeling","feel","feels","felt","emotion","emotional","emotionally","mood","moody","state","am","is","are","being","becoming","become","grew","growing"],gestureContext:["do","doing","does","did","perform","performing","action","move","moving","movement","start","starting","begin","beginning","physically","motion"],shapeContext:["morph","morphing","morphed","transform","transforming","transformed","become","becoming","turn into","shape","form","look like","change to","change into"],undertoneContext:["but","yet","while","although","with","and also","mixed with","underneath","underlying","beneath","a bit","slightly","somewhat"],modifierContext:["very","really","so","extremely","slightly","barely","completely","quickly","slowly","briefly"]};function Mp(e,t,i){const n=bp[`${i}Context`];if(!n)return!1;const a=Math.max(0,t-3),r=Math.min(e.length,t+4);for(let i=a;i<r;i++)if(i!==t&&n.includes(e[i]))return!0;return!1}function _p(e,t){switch(t){case"emotion":return null!==e.emotion;case"gesture":return e.gestures&&e.gestures.length>0;case"shape":return null!==e.shape;case"undertone":return null!==e.undertone;default:return!1}}function xp(e,t,i,n){const a=yp[e];if(!a)return null;const{candidates:r,rule:s}=a;if(1===r.length)return r[0];switch(s){case"standalone_is_emotion":if(_p(n,"emotion")){const e=r.find(e=>"emotion"!==e.category);if(e)return e}return Mp(t,i,"emotion"),r.find(e=>"emotion"===e.category)||r[0];case"standalone_is_gesture":if(_p(n,"gesture")){const e=r.find(e=>"gesture"!==e.category);if(e)return e}return Mp(t,i,"gesture"),r.find(e=>"gesture"===e.category)||r[0];case"prefer_undertone":return Mp(t,i,"emotion")?r.find(e=>"emotion"===e.category)||r[0]:r.find(e=>"undertone"===e.category)||r[0];case"always_gesture":return r.find(e=>"gesture"===e.category)||r[0];case"always_emotion":return r.find(e=>"emotion"===e.category)||r[0];case"context_dependent":for(const e of["emotion","gesture","shape","undertone"])if(Mp(t,i,e)){const t=r.find(t=>t.category===e);if(t)return t}return r.sort((e,t)=>e.priority-t.priority)[0];default:return r.sort((e,t)=>e.priority-t.priority)[0]}}function Sp(e){return e in yp}const wp={neutral:["neutral","default","normal","baseline","standard","nothing special","nothing particular","no strong feeling","not much","meh","whatever","indifferent","balanced","even","steady","stable","centered","level","middle ground","in between","ready","waiting","standing by","at attention","present","here","available","attentive","reset","clear","blank","empty","clean slate"],joy:["happy","joy","joyful","joyous","pleased","glad","content","satisfied","gratified","comfortable","good","cheerful","cheery","merry","jovial","jolly","upbeat","sunny","bright","lighthearted","buoyant","delighted","thrilled","overjoyed","elated","jubilant","exultant","gleeful","glowing","beaming","radiant","pumped","stoked","psyched","amped","hyped","vibing","living","slaying","winning","lit","fire","sick","dope","chuffed","pleased as punch","over the moon","made up","tickled","tickled pink","felicitous","beatific","blissful","smiling","grinning","laughing","giggling"],calm:["calm","peaceful","serene","tranquil","relaxed","at ease","comfortable","loose","unwound","decompressed","chilled","still","quiet","hushed","silent","soft","gentle","mild","placid","smooth","composed","collected","centered","grounded","untroubled","unworried","unbothered","unfazed","meditative","zen","mindful","contemplative","reflective","introspective","soothed","eased","mellowed","softened","chill","coasting","floating","drifting","laid back","easy going","low key","sorted","easy peasy"],excited:["excited","exciting","excitable","enthusiastic","eager","keen","avid","passionate","fervent","ardent","zealous","energetic","energized","animated","lively","spirited","vivacious","vibrant","dynamic","bouncy","peppy","perky","sprightly","anticipating","expectant","looking forward","itching","raring","chomping at the bit","fired up","charged","electric","electrified","buzzing","tingling","crackling","sparking","jazzed","juiced","geeked","hype","turnt","going off","well excited","buzzing","restless","fidgety","antsy","jumpy","twitchy","keyed up","wound up"],sadness:["sad","sadness","saddened","unhappy","down","low","blue","glum","bummed","disappointed","let down","discouraged","disheartened","dispirited","deflated","melancholy","melancholic","somber","gloomy","mournful","sorrowful","doleful","woeful","heavy-hearted","downcast","crestfallen","heartbroken","devastated","crushed","shattered","despairing","despondent","desolate","inconsolable","grief","grieving","mourning","bereft","empty","hollow","numb","void","wistful","longing","yearning","pining","nostalgic","bummed out","down in the dumps","in a funk","in the dumps","feeling low","gutted","choked","crying","tearful","weeping","sobbing","sighing","drooping","wilting","slumping"],anger:["angry","anger","angered","mad","annoyed","irritated","bothered","irked","peeved","miffed","vexed","displeased","put out","ticked off","ticked","frustrated","aggravated","exasperated","fed up","sick of","had enough","cross","upset","worked up","furious","enraged","livid","irate","incensed","infuriated","outraged","seething","fuming","boiling","burning","smoldering","raging","ballistic","apoplectic","berserk","seeing red","losing it","pissed","pissed off","salty","pressed","triggered","tilted","heated","steaming","narked","cheesed off","brassed off","shirty","stroppy","mardy","ropeable","filthy","spewing","clenching","tensing","grinding"],fear:["afraid","scared","fear","fearful","uneasy","unsettled","apprehensive","wary","concerned","worried","jittery","shaky","trembling","quivering","tense","tight","clenched","knotted","frightened","alarmed","startled","spooked","freaked","freaked out","creeped out","on edge","rattled","unnerved","terrified","petrified","horrified","panicked","panic","panicking","terror","dread","paranoid","distrustful","looking over shoulder","sketched","sketched out","wigged out","shook","bricking it","having kittens","in a flap","frozen","paralyzed","deer in headlights","heart racing","heart pounding","sweating"],surprise:["surprised","surprise","surprising","oh","huh","hmm","interesting","unexpected","caught off guard","astonished","amazed","astounded","startled","taken aback","struck","shocked","stunned","staggered","floored","dumbfounded","flabbergasted","gobsmacked","blown away","mind blown","speechless","wow","whoa","omg","no way","incredible","unbelievable","amazing","alarmed","dismayed","appalled","bewildered","baffled","perplexed","puzzled","confused","disoriented","thrown","shooketh","gagged","dead","wait what","blimey","crikey","bloody hell","jaw dropped","eyes wide","double take","gasp","gasping"],disgust:["disgusted","disgust","disgusting","distaste","dislike","aversion","put off","turned off","off-putting","repulsed","revolted","repelled","grossed out","creeped out","icked out","sickened","nauseated","nauseous","appalled","horrified","scandalized","offended","outraged","indignant","contempt","contemptuous","disdain","scorn","gagging","retching","cringing","wincing","recoiling","shrinking back","gross","ew","eww","yuck","yucky","ick","nasty","foul","vile","rank","minging","manky","grotty"],love:["love","loving","loved","affection","affectionate","fond","fondness","tender","tenderness","gentle","caring","care","nurturing","supportive","protective","devoted","dedicated","warm","warmth","warm-hearted","kind","kind-hearted","compassionate","sympathetic","adoring","adore","cherish","cherishing","treasure","treasuring","doting","romantic","amorous","passionate","smitten","infatuated","enamored","besotted","head over heels","falling for","connected","bonded","attached","close","intimate","deep","profound","heart eyes","crushing","swooning","melting","hugging","embracing","holding","cuddling","snuggling","nuzzling"],euphoria:["euphoric","euphoria","bliss","blissful","transcendent","otherworldly","sublime","heavenly","divine","ethereal","celestial","ecstatic","ecstasy","rapture","rapturous","exultant","exalted","elevated","peak","pinnacle","height","climax","breakthrough","revelation","epiphany","overwhelming joy","pure joy","absolute joy","complete happiness","total bliss","floating","soaring","flying","weightless","radiating","shining","on cloud nine","in heaven","on top of the world","walking on air","living my best life","ascended"],focused:["focused","focus","focusing","concentrating","concentration","concentrated","attentive","attention","attending","thinking","thought","thoughtful","pondering","considering","contemplating","reflecting","musing","mulling","engaged","absorbed","immersed","engrossed","rapt","riveted","captivated","enthralled","intent","determined","resolute","single-minded","laser focused","zeroed in","working","processing","analyzing","examining","studying","learning","figuring out","locked in","dialed in","in the zone","flow state","deep work","grinding","staring","gazing","peering","squinting","furrowed brow"],suspicion:["suspicious","suspicion","suspect","doubtful","doubt","doubting","skeptical","skepticism","questioning","uncertain","unsure","unconvinced","wary","cautious","guarded","careful","leery","circumspect","vigilant","distrustful","mistrust","mistrustful","disbelieving","incredulous","unbelieving","scrutinizing","examining","assessing","evaluating","judging","sizing up","sus","sussy","suss","side eye","giving side eye","side-eyeing","eyeing","not buying it","narrowed eyes","squinting","raised eyebrow","cocked head","tilted head","looking askance"],resting:["resting","rest","restful","tired","weary","fatigued","exhausted","drained","spent","depleted","worn out","sleepy","drowsy","dozy","groggy","yawning","nodding off","drifting off","sluggish","lethargic","listless","languid","lazy","idle","inactive","recovering","recuperating","recharging","winding down","powering down","shutting down","sleeping","asleep","slumbering","dozing","napping","snoozing","zonked","wiped","beat","dead tired","running on empty","out of gas","crashed","knackered","shattered","cream crackered"],glitch:["glitch","glitchy","glitching","malfunction","malfunctioning","broken","bugged","buggy","error","erroring","corrupted","corruption","scrambled","garbled","distorted","warped","static","noise","interference","pixelated","artifacting","tearing","haywire","fritzing","shorting out","going crazy","spazzing","unstable","erratic","unpredictable","flickering","stuttering","lagging","does not compute","syntax error","crash"]},Ep={nervous:["nervous","nervously","anxious","anxiously","worried","worriedly","uneasy","uneasily","apprehensive","jittery","shaky","trembling","quivering","fidgety","restless","twitchy","tense","tensely","on edge","edgy","keyed up","wound up","uptight","self-conscious","awkward","awkwardly","hesitant","hesitantly","uncertain","uncertainly","sketchy","stressed","stressing","low-key panicking","kinda freaking out"],confident:["confident","confidently","confidence","assured","assuredly","certain","certainly","sure","surely","positive","positively","bold","boldly","brave","bravely","daring","daringly","fearless","fearlessly","strong","strongly","powerful","powerfully","firm","firmly","solid","solidly","authoritative","commanding","assertive","decisive","decisively","resolute","resolutely","poised","self-assured","unflappable","unfazed","owning it","killing it","crushing it","boss","like a boss"],tired:["tired","tiredly","tiredness","exhausted","weary","wearily","fatigued","drained","spent","depleted","sluggish","sluggishly","slow","slowly","lethargic","listless","languid","low energy","no energy","out of energy","running low","running on fumes","droopy","drooping","sagging","slumping","heavy","weighted","dragging","wiped","beat","dead","zonked","burned out","fried","cooked","toast"],intense:["intense","intensely","intensity","heightened","elevated","amplified","magnified","increased","enhanced","forceful","forcefully","powerful","powerfully","fierce","fiercely","strong","strongly","passionate","passionately","fervent","fervently","ardent","ardently","vehement","vehemently","sharp","sharply","acute","acutely","keen","keenly","piercing","piercingly","extreme","extremely","deeply","profoundly","tremendously","immensely","incredibly","super","mega","ultra","hella","mad","crazy"],subdued:["subdued","subduedly","soft","softly","gentle","gently","mild","mildly","light","lightly","restrained","held back","contained","tempered","moderated","toned down","quiet","quietly","hushed","muted","understated","subtle","subtly","modest","modestly","humble","humbly","reserved","demure","unassuming","faint","faintly","dim","dimly","pale","faded","washed out","low key","lowkey","easy","easy going"],clear:["clear","clearly","pure","purely","clean","cleanly","simple","simply","plain","plainly","direct","directly","straightforward","honest","honestly","frank","frankly","transparent","transparently","open","openly","obvious","obviously","evident","evidently","unmodified","unaltered","unchanged","normal","normally","regular","regularly","standard","basic","baseline"]},Tp={bounce:["bounce","bouncing","bouncy","hop","hopping","hoppy","spring","springing","springy","boing","boinging","bouncing up and down","hopping around","spring in step","light on feet"],pulse:["pulse","pulsing","pulsate","pulsating","throb","throbbing","beat","beating","pulsing gently","steady pulse","heartbeat","heart beat"],shake:["shake","shaking","shaky","shudder","shuddering","tremble","trembling","quake","quaking","shiver","shivering","no","nope","nah","disagree","disagreeing","refuse","refusing","deny","denying","shaking head","shake head","head shake","saying no","shaking no"],nod:["nod","nodding","yes","yeah","yep","yup","agree","agreeing","acknowledge","acknowledging","confirm","confirming","accept","accepting","approve","approving","understand","understanding","got it","gotcha","i see","makes sense","understood","nodding head","nod head","head nod","nodding along","nodding yes"],vibrate:["vibrate","vibrating","vibration","buzz","buzzing","hum","humming","quiver","quivering","vibrating slightly","gentle buzz","low hum","subtle vibration"],orbit:["orbit","orbiting","circle","circling","revolve","revolving","rotate","rotating","circling around","going around","rotating slowly","orbital motion"],sway:["sway","swaying","rock","rocking","swing","swinging","oscillate","oscillating","swaying gently","rocking back and forth","gentle sway","side to side"],float:["float","floating","drift","drifting","hover","hovering","glide","gliding","levitate","levitating","weightless","weightlessness","buoyant","airy","floating gently","drifting along","hovering in place","light as air"],lean:["lean","leaning","incline","inclining","tilt","tilting","leaning in","lean in","leaning forward","lean forward","leaning toward","lean toward","leaning closer","lean closer","moving closer","coming closer","drawing near","approaching","interested","intrigued","curious","engaged","attentive","listening closely","paying attention"],reach:["reach","reaching","extend","extending","stretch","stretching","reaching out","reach out","reaching toward","reach toward","extending toward","stretching toward","offer","offering","present","presenting","give","giving","help","helping"],point:["point","pointing","indicate","indicating","gesture","gesturing","direct","directing","pointing at","pointing to","pointing toward","gesturing toward","showing","directing attention"],wave:["wave","waving","greet","greeting","hello","hi","hey","goodbye","bye","farewell","welcome","welcoming","waving hello","waving goodbye","friendly wave","waving hand"],headBob:["headbob","head bob","headbobbing","head bobbing","bobbing","bob","nodding to beat","nodding to music","bobbing along","bobbing to rhythm","vibing","grooving","jamming","bobbing head","bob head","feeling the beat","moving to music"],wiggle:["wiggle","wiggling","wiggly","jiggle","jiggling","jiggly","squirm","squirming","wriggle","wriggling","wiggling around","little wiggle","happy wiggle","excited wiggle"],groove:["groove","grooving","groovy","dance","dancing","boogie","boogying","funk","funky","rhythmic","moving to music","feeling the music","in the groove","getting down","busting a move","doing a little dance"],twitch:["twitch","twitching","twitchy","spasm","spasming","jerk","jerking","jerky","flinch","flinching","quick twitch","nervous twitch","sudden movement"],jitter:["jitter","jittering","jittery","stutter","stuttering","jittering around","slight jitter","nervous jitter"],spin:["spin","spinning","twirl","twirling","whirl","whirling","rotate","rotating","turn","turning","spinning around","quick spin","full rotation","twirling around"],jump:["jump","jumping","jumpy","leap","leaping","spring","springing","bound","bounding","jumping up","leap up","spring up","jumping for joy"],stretch:["stretch","stretching","stretchy","elongate","elongating","extend","extending","lengthen","lengthening","stretching out","big stretch","reaching up","stretching tall"],expand:["expand","expanding","grow","growing","enlarge","enlarging","swell","swelling","inflate","inflating","bloat","bloating","getting bigger","growing larger","puffing up","expanding outward"],contract:["contract","contracting","shrink","shrinking","compress","compressing","deflate","deflating","reduce","reducing","getting smaller","shrinking down","pulling in","contracting inward"],twist:["twist","twisting","twisty","contort","contorting","warp","warping","distort","distorting","twisting around","getting twisted","warping shape"],tilt:["tilt","tilting","tilted","angle","angling","angled","cock","cocking","cocked","tilting head","tilt head","cocking head","curious tilt","angling sideways","head tilt"],hula:["hula","hula-ing","hip sway","swaying hips","circular sway","round motion","hula motion","hula dance"],sparkle:["sparkle","sparkling","sparkly","twinkle","twinkling","twinkly","glitter","glittering","glittery","shine","shining","shiny","celebrate","celebrating","celebration","celebratory","festive","party","partying","victory","triumphant","triumph","winning","success","successful","achievement","accomplished","nailed it","slay","slaying","killing it","yasss","yay","woo","woohoo"],shimmer:["shimmer","shimmering","shimmery","glisten","glistening","gleam","gleaming","lustrous","luminous","soft shimmer","gentle gleam","shimmering light","pearlescent"],glow:["glow","glowing","glowy","radiate","radiating","emanate","emanating","luminous","luminescent","bright","brighten","brightening","soft glow","warm glow","inner glow","glowing warmly","lighting up","lit up"],flash:["flash","flashing","flashy","blink","blinking","strobe","strobing","flare","flaring","quick flash","bright flash","flashing light","strobing light"],flicker:["flicker","flickering","flickery","flutter","fluttering","waver","wavering","guttering","flickering light","unsteady light","wavering glow","candle-like"],burst:["burst","bursting","explode","exploding","explosion","erupt","erupting","eruption","pop","popping","boom","booming","bursting out","burst of energy","explosive","big burst"],settle:["settle","settling","settled","calm","calming","ground","grounding","grounded","center","centering","centered","anchor","anchoring","anchored","root","rooting","rooted","relax","relaxing","unwind","unwinding","decompress","decompressing","settling down","calming down","winding down","cooling down","coming to rest","finding peace","sinking into","melting into"],breathe:["breathe","breathing","breath","inhale","inhaling","exhale","exhaling","sigh","sighing","respire","respiring","deep breath","deep breathing","slow breath","slow breathing","long breath","full breath","breathing deeply","breathing slowly","taking a breath","take a breath","catching breath","breath work","breathwork","inhale exhale","in and out","meditative breathing","calming breath","cleansing breath","relaxing breath","centering breath","mindful breathing"],peek:["peek","peeking","peer","peering","peep","peeping","glance","glancing","peeking out","peek out","looking shyly","shy glance","quick peek","sneaking a look"],fade:["fade","fading","dim","dimming","disappear","disappearing","vanish","vanishing","fading out","fading away","growing dim","becoming transparent","dissolving","melting away"],hold:["hold","holding","pause","pausing","paused","freeze","freezing","frozen","still","stillness","stop","stopping","stopped","holding still","staying still","frozen in place","completely still","motionless","stationary"],rain:["rain","raining","shower","showering","drip","dripping","pour","pouring","fall","falling","raining down","particles falling","gentle rain","shower of particles"]},Cp={circle:["circle","circular","round","rounded","orb","ball","sphere","spherical","ring","disc","disk","whole","complete","unity","unified","endless","infinite","continuous","full circle","perfect round","come full circle"],sphere:["sphere","spherical","globe","globular","ball","3d circle","three dimensional","round ball","floating sphere"],square:["square","squared","boxy","box","rectangle","rectangular","quadrilateral","cube","cubic","block","blocky","stable","solid","grounded","sturdy","rigid","firm","structured","four sided","four corners","box shape"],triangle:["triangle","triangular","tri","pyramid","pyramidal","delta","wedge","arrow","arrowhead","pointed","sharp","dynamic","directional","ascending","three sided","three pointed","pointing up"],heart:["heart","hearted","hearts","love","loving","lovely","valentine","romantic","affection","affectionate","caring","care","tender","warmth","warm-hearted","heartfelt","compassion","compassionate","devotion","devoted","luv","wuv","<3","❤️","💕","💗","full of love","with love","heart shape","heart shaped","from the heart"],suspicion:["suspicion","suspicious","suspect","sly","slyly","sneaky","sneakily","mischievous","mischief","smirk","smirking","smirky","grin","grinning","sly grin","side eye","sideeye","side-eye","skeptical","skepticism","doubtful","doubt","doubting","wary","distrustful","distrust","sus","sussy","sussy baka","hmm","hmmm","hmmmm","shady","fishy","sketchy","not buying it","something fishy","seems off","up to something"],star:["star","starred","starry","stars","stellar","astral","twinkle","twinkling","achievement","achieved","excellence","excellent","gold star","five star","superstar","rockstar","rock star","wonder","wonderful","wondrous","magical","magic","miraculous","amazing","spectacular","reach for stars","seeing stars","star shape","shining star"],sun:["sun","sunny","sunshine","sunlight","solar","sol","daylight","daytime","day","radiant","radiance","radiating","bright","brightness","brilliant","glowing","glow","blazing","blaze","warm","warmth","cheerful","cheery","optimistic","optimism","hopeful","hope","positive","positivity","full of light","ray of sunshine","like the sun","sunny disposition"],moon:["moon","moony","moonlight","moonlit","lunar","crescent","nighttime","night","nocturnal","waxing","waning","gibbous","new moon","full moon","half moon","quarter moon","crescent moon","dreamy","dreamlike","dream","mysterious","mystery","mystical","ethereal","otherworldly","serene","serenity","tranquil","contemplative","reflective","moonlit night","by moonlight","moon shape","under the moon"],lunar:["lunar eclipse","blood moon","blood-moon","red moon","copper moon","rust moon","eclipsing","eclipsed","shadow crossing","earth shadow","ominous","foreboding","portentous","dramatic","intense","transforming","transformation","moon in shadow","moon turning red","eclipse phase","lunar event"],solar:["solar eclipse","total eclipse","corona","diamond ring","totality","umbra","penumbra","ring of fire","dark sun","blocked sun","occluded","awe","awesome","awe-inspiring","rare","momentous","historic","breathtaking","magnificent","sun blocked","sun covered","total darkness","corona visible"],eclipse:["eclipse","eclipsing","eclipsed","celestial event","astronomical event","overshadow","overshadowed","blocked","blocking","obscured","hidden","hiding","concealed","passing","crossing","alignment","in eclipse","going dark","being eclipsed","eclipsed by"]},Ap={intensity:{barely:["barely","hardly","scarcely","faintly","slightly","marginally","just a bit","just a little","just barely","hint of","touch of","trace of"],slightly:["slightly","somewhat","a little","a bit","mildly","lightly","kind of","kinda","sort of","sorta","a tad","a touch","a smidge"],moderately:["moderately","reasonably","fairly","pretty","rather","quite"],normal:["normal","normally","regular","regularly","standard","typical","typically","average","ordinary"],notably:["notably","noticeably","clearly","definitely","certainly","decidedly","genuinely","truly","really"],very:["very","really","so","such","quite","highly","deeply","seriously","majorly","hella","super","extra","mad"],extremely:["extremely","incredibly","immensely","tremendously","enormously","hugely","intensely","fiercely","wildly","insanely","crazy","ridiculously","mega","ultra","hyper"],absolutely:["absolutely","completely","totally","utterly","entirely","wholly","fully","maximum","max","over the top","off the charts","through the roof","to the max"]},duration:{flash:["flash","instant","instantaneous","split second","split-second","momentary","fleeting","brief flash"],quick:["quick","quickly","fast","rapid","swift","swiftly","brief","briefly","short","shortly","snap"],normal:["normal","regular","standard","typical","usual"],slow:["slow","slowly","gradual","gradually","gentle","gently","easy","easily","leisurely","unhurried"],long:["long","prolonged","extended","sustained","lasting","lingering","drawn out","drawn-out"],persistent:["persistent","constant","continuous","ongoing","steady","maintained","held","holding","stay","staying","keep","keeping","remain","remaining"]},transition:{instant:["instant","instantly","immediate","immediately","sudden","suddenly","abrupt","abruptly","snap","cut","jump"],snappy:["snappy","crisp","sharp","sharply","brisk","briskly","punchy"],smooth:["smooth","smoothly","natural","naturally","fluid","fluidly","flowing"],gentle:["gentle","gently","soft","softly","gradual","gradually","easing","gliding","drifting"],dreamy:["dreamy","dreamlike","floaty","ethereal","languid","lazy","flowing","melting"]},repetition:{once:["once","one time","single","just once","only once","one shot"],few:["few","few times","couple","couple times","twice","two times","thrice","three times"],several:["several","several times","multiple","multiple times","repeatedly","again and again"],many:["many","many times","lots","lots of times","over and over","nonstop"],loop:["loop","looping","looped","continuous","continuously","forever","infinitely","endlessly","always","keep going","on repeat"]}},Pp={barely:{min:.1,max:.2,default:.15},slightly:{min:.2,max:.4,default:.3},moderately:{min:.4,max:.5,default:.45},normal:{min:.5,max:.6,default:.55},notably:{min:.6,max:.7,default:.65},very:{min:.7,max:.85,default:.8},extremely:{min:.85,max:.95,default:.9},absolutely:{min:.95,max:1,default:1}},Dp={flash:{min:100,max:500,default:250},quick:{min:500,max:1e3,default:750},normal:{min:1e3,max:2e3,default:1500},slow:{min:2e3,max:4e3,default:3e3},long:{min:4e3,max:8e3,default:6e3},persistent:{min:8e3,max:1/0,default:1e4}};function Rp(e){const t=new Map;for(const[i,n]of Object.entries(e)){for(const e of n){const n=e.toLowerCase().trim();t.set(n,i)}t.set(i.toLowerCase(),i)}return t}class Ip{constructor(){this.emotionLookup=Rp(wp),this.undertoneLookup=Rp(Ep),this.gestureLookup=Rp(Tp),this.shapeLookup=Rp(Cp),this.modifierLookup=function(e){const t=new Map;for(const[i,n]of Object.entries(e))for(const[e,a]of Object.entries(n))for(const n of a){const a=n.toLowerCase().trim();t.set(a,{type:i,level:e})}return t}(Ap)}parse(e){const t={emotion:null,undertone:"clear",gestures:[],shape:null,intensity:Pp.normal.default,duration:Dp.normal.default,transition:"smooth",repetition:"once",unrecognized:[],raw:e};if(!e||"string"!=typeof e)return t;const{tokens:i}=function(e){if(!e||"string"!=typeof e)return{tokens:[],segments:[],phrases:new Map};const t=fp(e),{processed:i,phrases:n}=function(e){const t=new Map;let i=e,n=0;for(const e of up){const a=fp(e);if(i.includes(a)){const e=`__PHRASE_${n}__`;i=i.replace(new RegExp(a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"g"),e),t.set(e,a),n++}}return{processed:i,phrases:t}}(t),a=i.split(dp).map(e=>e.trim()).filter(e=>e.length>0),r=[],s=[];for(const e of a){let t=e;for(const[e,i]of n)t=t.replace(e,i);s.push(t.trim());const i=e.split(/\s+/);for(const e of i){if(n.has(e)){r.push(n.get(e));continue}if(!e)continue;if(pp.has(e)&&!mp.has(e))continue;const t=e.replace(/^[^\w]+|[^\w]+$/g,"");t&&r.push(t)}}return{tokens:r,segments:s,phrases:n}}(e);if(0===i.length)return t;let n=!1;for(let e=0;e<i.length;e++){const a=i[e];if(!gp(a))if(vp(a))n=!0;else if(n)n=!1;else{if(Sp(a)){const n=xp(a,i,e,t);if(n){this._applyResolution(t,n);continue}}this._tryEmotion(a,t)||this._tryGesture(a,t)||this._tryShape(a,t)||this._tryUndertone(a,t)||this._tryModifier(a,t)||t.unrecognized.push(a)}}return t}_applyResolution(e,t){const{category:i,target:n}=t;switch(i){case"emotion":e.emotion||(e.emotion=n);break;case"undertone":"clear"===e.undertone&&(e.undertone=n);break;case"gesture":e.gestures.includes(n)||e.gestures.push(n);break;case"shape":e.shape||(e.shape=n)}}_tryEmotion(e,t){const i=this.emotionLookup.get(e);return!(!i||t.emotion||(t.emotion=i,0))}_tryGesture(e,t){const i=this.gestureLookup.get(e);return!(!i||t.gestures.includes(i)||(t.gestures.push(i),0))}_tryShape(e,t){const i=this.shapeLookup.get(e);return!(!i||t.shape||(t.shape=i,0))}_tryUndertone(e,t){const i=this.undertoneLookup.get(e);return!(!i||"clear"!==t.undertone||(t.undertone=i,0))}_tryModifier(e,t){const i=this.modifierLookup.get(e);if(i){const{type:e,level:n}=i;switch(e){case"intensity":t.intensity=Pp[n]?.default||t.intensity;break;case"duration":t.duration=Dp[n]?.default||t.duration;break;case"transition":t.transition=n;break;case"repetition":t.repetition=n}return!0}return!1}validate(e){const t=[];return e.emotion||0!==e.gestures.length||e.shape||t.push("No actionable intent found (need emotion, gesture, or shape)"),(e.intensity<0||e.intensity>1)&&t.push(`Intensity ${e.intensity} out of range [0, 1]`),e.duration<=0&&t.push(`Duration ${e.duration} must be positive`),{valid:0===t.length,errors:t}}static getAvailableEmotions(){return Object.keys(wp)}static getAvailableUndertones(){return Object.keys(Ep)}static getAvailableGestures(){return Object.keys(Tp)}static getAvailableShapes(){return Object.keys(Cp)}}function Lp(e=32,t=32){const i=[],n=[],a=[];for(let a=0;a<=t;a++){const r=a/t*Math.PI;for(let t=0;t<=e;t++){const a=t/e*Math.PI*2,s=Math.cos(a)*Math.sin(r),o=Math.cos(r),l=Math.sin(a)*Math.sin(r);i.push(s,o,l),n.push(s,o,l)}}for(let i=0;i<t;i++)for(let t=0;t<e;t++){const n=i*(e+1)+t,r=n+e+1,s=n+1,o=r+1;a.push(n,r,s),a.push(s,r,o)}return{vertices:new Float32Array(i),normals:new Float32Array(n),indices:new Uint16Array(a)}}function Bp(e=6){const t=[],i=[],n=[],a=new Map;let r=0;function s(e,n,s,o,l,h){const c=`${e},${n},${s}`;return a.has(c)||(t.push(e,n,s),i.push(o,l,h),a.set(c,r++)),a.get(c)}const o=s(0,1.5,0,0,1,0),l=[];for(let t=0;t<e;t++){const i=t/e*Math.PI*2,n=s(.7*Math.cos(i),0,.7*Math.sin(i),Math.cos(i),0,Math.sin(i));l.push(n)}const h=s(0,-1.5,0,0,-1,0);for(let t=0;t<e;t++){const i=(t+1)%e;n.push(o,l[t],l[i])}for(let t=0;t<e;t++){const i=(t+1)%e;n.push(l[t],h,l[i])}return{vertices:new Float32Array(t),normals:new Float32Array(i),indices:new Uint16Array(n)}}function Op(){const e=[],t=[],i=[],n=[0,1.2,0],a=[0,-.8,0],r=[];for(let e=0;e<8;e++){const t=e/8*Math.PI*2;r.push([.8*Math.cos(t),0,.8*Math.sin(t)])}function s(n,a,r){const s=[a[0]-n[0],a[1]-n[1],a[2]-n[2]],o=[r[0]-n[0],r[1]-n[1],r[2]-n[2]],l=s[1]*o[2]-s[2]*o[1],h=s[2]*o[0]-s[0]*o[2],c=s[0]*o[1]-s[1]*o[0],u=Math.sqrt(l*l+h*h+c*c),d=[l/u,h/u,c/u],p=e.length/3;e.push(...n),t.push(...d),e.push(...a),t.push(...d),e.push(...r),t.push(...d),i.push(p,p+1,p+2)}for(let e=0;e<8;e++){const t=(e+1)%8;s(n,r[e],r[t])}for(let e=0;e<8;e++){const t=(e+1)%8;s(r[e],a,r[t])}return{vertices:new Float32Array(e),normals:new Float32Array(t),indices:new Uint16Array(i)}}const Fp={sphere:Lp(32,32),crystal:Bp(6),diamond:Op()};function Up(){Object.values(Fp).forEach(e=>{e&&e.vertices&&(e.vertices=null,e.normals=null,e.indices=null)})}class zp{constructor(e={}){this.config={canvasId:e.canvasId||"emotive-canvas",coreGeometry:e.coreGeometry||"sphere",targetFPS:e.targetFPS||60,enableParticles:!1!==e.enableParticles,defaultEmotion:e.defaultEmotion||"neutral",...e},this.container=null,this.webglCanvas=null,this.canvas2D=null,this.core3D=null,this.particleSystem=null,this.isRunning=!1,this._destroyed=!1,this.animationFrameId=null,this.lastFrameTime=0,this.gestureTimeouts=[],this.eventManager=new rp,this.eventManager.emit||(this.eventManager._listeners={},this.eventManager.emit=(e,t)=>{const i=this.eventManager._listeners[e];i&&i.forEach(e=>e(t))},this.eventManager.on=(e,t)=>{this.eventManager._listeners[e]||(this.eventManager._listeners[e]=[]),this.eventManager._listeners[e].push(t)},this.eventManager.off=(e,t)=>{const i=this.eventManager._listeners[e];if(i){const e=i.indexOf(t);e>-1&&i.splice(e,1)}}),this.errorBoundary=new sp,this.emotion="neutral",this.undertone=null,this._intentParser=new Ip,this._feelRateLimiter={calls:[],windowMs:1e3,maxCallsPerSecond:10}}init(e){try{if(this.setupCanvasLayers(e),this.core3D=new ap(this.webglCanvas,{geometry:this.config.coreGeometry,emotion:this.config.defaultEmotion,enableParticles:this.config.enableParticles,enablePostProcessing:this.config.enablePostProcessing,enableShadows:this.config.enableShadows,enableControls:this.config.enableControls,autoRotate:this.config.autoRotate,enableBlinking:this.config.enableBlinking,enableBreathing:this.config.enableBreathing,cameraDistance:this.config.cameraDistance,fov:this.config.fov,minZoom:this.config.minZoom,maxZoom:this.config.maxZoom,materialVariant:this.config.materialVariant,assetBasePath:this.config.assetBasePath}),this.ctx2D=this.canvas2D.getContext("2d"),this.config.enableParticles&&!this.core3D?.particleOrchestrator){const e=this.config.maxParticles||300;this.particleSystem=new xd(e,this.errorBoundary),this.particleSystem.canvasWidth=this.canvas2D.width,this.particleSystem.canvasHeight=this.canvas2D.height}return this}catch(e){throw console.error("Failed to initialize 3D engine:",e),e}}setupCanvasLayers(e){if("CANVAS"===e.tagName){const t=e.parentElement;this.container=document.createElement("div"),this.container.style.position="relative",this.container.style.width="100%",this.container.style.height="100%",t.replaceChild(this.container,e)}else this.container=e,this.container.style.position&&"static"!==this.container.style.position||(this.container.style.position="relative");this.canvas2D=document.createElement("canvas"),this.canvas2D.id=`${this.config.canvasId}-particles`,this.canvas2D.width=this.container.offsetWidth||400,this.canvas2D.height=this.container.offsetHeight||400,this.canvas2D.style.position="absolute",this.canvas2D.style.top="0",this.canvas2D.style.left="0",this.canvas2D.style.width="100%",this.canvas2D.style.height="100%",this.canvas2D.style.background="transparent",this.canvas2D.style.zIndex="1",this.canvas2D.style.pointerEvents="none",this.container.appendChild(this.canvas2D),this.webglCanvas=document.createElement("canvas"),this.webglCanvas.id=`${this.config.canvasId}-3d`,this.webglCanvas.width=this.canvas2D.width,this.webglCanvas.height=this.canvas2D.height,this.webglCanvas.style.cssText="\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: transparent;\n z-index: 2;\n ",this.config.enableControls?(this.webglCanvas.style.pointerEvents="auto",this.webglCanvas.style.touchAction="none"):(this.webglCanvas.style.pointerEvents="none",this.webglCanvas.style.touchAction="auto"),this._canvasAppended=!1}async start(){this.isRunning||(this.core3D&&await this.core3D.waitUntilReady(),this.isRunning=!0,this.lastFrameTime=null,this.animationFrameId=requestAnimationFrame(this.animate.bind(this)))}stop(){this.isRunning=!1,this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null)}animate(e){if(!this.isRunning||this._destroyed)return;if(null===this.lastFrameTime)return this.lastFrameTime=e,void(this.animationFrameId=requestAnimationFrame(this.animate.bind(this)));const t=e-this.lastFrameTime,i=Math.min(t,100);if(this.lastFrameTime=e,this.core3D&&!this._destroyed&&(this.core3D.render(i),!this._canvasAppended&&this.webglCanvas&&this.container&&(this.container.appendChild(this.webglCanvas),this._canvasAppended=!0)),this.canvas2D&&this.ctx2D&&(this.ctx2D.clearRect(0,0,this.canvas2D.width,this.canvas2D.height),this.ctx2D.fillStyle="rgba(0,0,0,0)",this.ctx2D.fillRect(0,0,this.canvas2D.width,this.canvas2D.height),this.particleSystem)){const t=this.canvas2D.width/2,n=this.canvas2D.height/2,a=this.core3D?this.core3D.emotion:"neutral",r=Tc(a),s=this.core3D?this.rgbToHex(this.core3D.glowColor):"#FFFFFF",o=r?.visual?.particleBehavior||"ambient",l=r?.visual?.particleRate||15,h=r?.visual?.minParticles||5,c=r?.visual?.maxParticles||30,u=r?.visual?.particleColors||null;this.particleSystem.spawn(o,a,l,t,n,i,null,h,c,1,1,u,this.undertone);let d=null,p=0;if(this.currentGesture){const t=e-this.currentGesture.startTime;p=Math.min(t/this.currentGesture.duration,1),d={...this.currentGesture.config,type:this.currentGesture.name}}this.particleSystem.update(i,t,n,d,p,this.undertone),this.particleSystem.render(this.ctx2D,s,null)}this.animationFrameId=requestAnimationFrame(e=>this.animate(e))}setEmotion(e,t){this.eventManager&&this.eventManager._listeners&&(this.emotion=e,void 0!==t&&("string"==typeof t?this.undertone=t:t&&"object"==typeof t?this.undertone=t.undertone||null:null===t&&(this.undertone=null)),this.core3D&&this.core3D.setEmotion(e,this.undertone),this.particleSystem&&(this.particleSystem.particles=[]),this.eventManager.emit("emotion:change",{emotion:e,undertone:this.undertone}))}updateUndertone(e){this.undertone=e,this.core3D&&this.emotion&&this.core3D.setEmotion(this.emotion,e),this.eventManager.emit("undertone:change",{undertone:e})}setUndertone(e){this.updateUndertone(e)}express(e){if(!this.eventManager||!this.eventManager._listeners)return;this.core3D&&this.core3D.playGesture(e);const t=Pu(e);if(t){const i=t.config||{},n=i.musicalDuration?.musical?500*(i.musicalDuration.beats||2):i.duration||800;this.currentGesture={name:e,gesture:t,config:i,startTime:performance.now(),duration:n};const a=setTimeout(()=>{this.currentGesture&&this.currentGesture.name===e&&(this.currentGesture=null)},n);this.gestureTimeouts.push(a)}this.eventManager.emit("gesture:trigger",{gesture:e})}chain(e){const t=("string"==typeof e?{rise:"breathe > sway+lean+tilt",flow:"sway > lean+tilt > spin > bounce",burst:"jump > nod > shake > flash",drift:"sway+breathe+float+drift",chaos:"shake+shake > spin+flash > bounce+pulse > twist+sparkle",morph:"expand > contract > morph+glow > expand+flash",rhythm:"pulse > pulse+sparkle > pulse+flicker",spiral:"spin > orbital > twist > orbital+sparkle",routine:"nod > bounce > spin+sparkle > sway+pulse > nod+flash",radiance:"sparkle > pulse+flicker > shimmer",twinkle:"sparkle > flash > pulse+sparkle > shimmer+flicker",stream:"wave > nod+pulse > sparkle > flash"}[e]||e:e.join(">")).split(">").map(e=>e.trim().split("+").map(e=>e.trim()).filter(e=>e.length>0));this.executeChainSequence(t)}executeChainSequence(e){if(!e||0===e.length)return;let t=0;const i=()=>{if(!(t>=e.length)&&(e[t].forEach(e=>{this.express(e)}),t++,t<e.length)){const e=setTimeout(i,800);this.gestureTimeouts.push(e)}};i()}morphTo(e,t={}){if(this.core3D){if(void 0!==t.materialVariant&&this.core3D.setMaterialVariant(t.materialVariant),t.onMaterialSwap){const e=this.core3D.onMaterialSwap;this.core3D.onMaterialSwap=i=>{e&&e(i),t.onMaterialSwap(i),this.core3D.onMaterialSwap=e}}const i=t.duration||800;this.core3D.morphToShape(e,i)}this.eventManager.emit("shape:morph",{shape:e})}feel(e){if(!this.eventManager||!this.eventManager._listeners)return{success:!1,error:"Engine destroyed",parsed:null};const t=Date.now(),i=this._feelRateLimiter;if(i.calls=i.calls.filter(e=>t-e<i.windowMs),i.calls.length>=i.maxCallsPerSecond)return console.warn("[feel] Rate limit exceeded. Max 10 calls per second."),{success:!1,error:"Rate limit exceeded",parsed:null};i.calls.push(t);const n=this._intentParser.parse(e),a=this._intentParser.validate(n);if(!a.valid)return console.warn("[feel] Invalid intent:",a.errors),{success:!1,error:a.errors.join("; "),parsed:n};try{if(n.emotion){const e={};n.undertone&&"clear"!==n.undertone&&(e.undertone=n.undertone),this.setEmotion(n.emotion,e)}for(const e of n.gestures)this.express(e);return n.shape&&this.morphTo(n.shape),{success:!0,error:null,parsed:n}}catch(e){return console.error("[feel] Execution error:",e),{success:!1,error:e.message,parsed:n}}}isMorphing(){return!!this.core3D&&this.core3D.isMorphing()}getMorphState(){return this.core3D?this.core3D.getMorphState():null}growIn(e=500){this.core3D&&this.core3D.growIn(e),this.eventManager.emit("animation:growIn",{duration:e})}setCoreGlowEnabled(e){this.core3D&&this.core3D.setCoreGlowEnabled(e),this.eventManager.emit("coreGlow:toggle",{enabled:e})}isCoreGlowEnabled(){return!this.core3D||this.core3D.coreGlowEnabled}enableAutoRotate(){this.core3D&&"moon"!==this.core3D.geometryType&&(this.core3D.renderer?.controls&&(this.core3D.renderer.controls.autoRotate=!0,this.core3D.renderer.controls.autoRotateSpeed=this.core3D.options?.autoRotateSpeed??.5),this.core3D.rotationDisabled=!1,this.setEmotion(this.core3D.emotion,this.undertone))}disableAutoRotate(){this.core3D?.renderer?.controls&&(this.core3D.renderer.controls.autoRotate=!1,this.core3D.renderer.controls.autoRotateSpeed=0),this.core3D&&(this.core3D.rotationDisabled=!0,this.core3D.rotationBehavior=null,this.core3D.baseEuler&&(this.core3D.baseEuler[0]=0,this.core3D.baseEuler[1]=0,this.core3D.baseEuler[2]=0))}setCameraPreset(e,t=1e3){this.core3D?.renderer?.setCameraPreset&&this.core3D.renderer.setCameraPreset(e,t)}get autoRotateEnabled(){return!1===this.core3D?.rotationDisabled}enableParticles(){if(this.core3D?.particleOrchestrator?.renderer&&(this.core3D.particleVisibility=!0,this.core3D.particleOrchestrator.renderer.setVisible(!0),this.core3D.particleOrchestrator.setEmotion(this.core3D.emotion,this.core3D.undertone)),!this.core3D?.particleOrchestrator&&!this.particleSystem&&this.canvas2D){const e=this.config.maxParticles||300;this.particleSystem=new xd(e,this.errorBoundary),this.particleSystem.canvasWidth=this.canvas2D.width,this.particleSystem.canvasHeight=this.canvas2D.height}}disableParticles(){this.core3D?.particleOrchestrator?.renderer&&(this.core3D.particleVisibility=!1,this.core3D.particleOrchestrator.renderer.setVisible(!1),this.core3D.particleOrchestrator.clear()),this.core3D?.particleOrchestrator||this.particleSystem&&(this.particleSystem.destroy(),this.particleSystem=null)}get particlesEnabled(){return this.core3D?.particleOrchestrator?!0===this.core3D.particleVisibility:null!==this.particleSystem}enableBlinking(){this.core3D&&(this.core3D.blinkingManuallyDisabled=!1,this.core3D.blinkAnimator&&this.core3D.blinkAnimator.resume())}disableBlinking(){this.core3D&&(this.core3D.blinkingManuallyDisabled=!0,this.core3D.blinkAnimator&&this.core3D.blinkAnimator.pause())}get blinkingEnabled(){return!(!this.core3D||!this.core3D.blinkAnimator)&&this.core3D.blinkAnimator.enabled}enableBreathing(){this.core3D&&(this.core3D.breathingEnabled=!0)}disableBreathing(){this.core3D&&(this.core3D.breathingEnabled=!1)}get breathingEnabled(){return!this.core3D||!1!==this.core3D.breathingEnabled}breathePhase(e,t){this.core3D&&this.core3D.breathePhase(e,t)}stopBreathingPhase(){this.core3D&&this.core3D.stopBreathingPhase()}enableWobble(){this.core3D&&this.core3D.setWobbleEnabled(!0)}disableWobble(){this.core3D&&this.core3D.setWobbleEnabled(!1)}get wobbleEnabled(){return!this.core3D||!1!==this.core3D.wobbleEnabled}enableRhythmSync(){this.core3D&&this.core3D.setRhythmEnabled(!0)}disableRhythmSync(){this.core3D&&this.core3D.setRhythmEnabled(!1)}get rhythmSyncEnabled(){return!!this.core3D&&this.core3D.rhythmEnabled}enableGroove(){this.core3D&&this.core3D.setGrooveEnabled(!0)}disableGroove(){this.core3D&&this.core3D.setGrooveEnabled(!1)}setBeatSyncStrength(e){this.core3D&&this.core3D.setBeatSyncStrength(e)}setGrooveConfig(e){this.core3D&&this.core3D.setGrooveConfig(e)}isRhythmPlaying(){return this.core3D?.isRhythmPlaying()||!1}getRhythmBPM(){return this.core3D?.getRhythmBPM()||120}startRhythm(e=120,t="straight"){this.core3D&&this.core3D.startRhythm(e,t)}stopRhythm(){this.core3D&&this.core3D.stopRhythm()}setRhythmBPM(e){this.core3D&&this.core3D.setRhythmBPM(e)}setRhythmPattern(e){this.core3D&&this.core3D.setRhythmPattern(e)}async connectAudio(e){if(!e)return;this._audioElement=e,this._audioContext||(this._audioContext=new(window.AudioContext||window.webkitAudioContext)),"suspended"===this._audioContext.state&&await this._audioContext.resume(),this._analyzerNode||(this._analyzerNode=this._audioContext.createAnalyser(),this._analyzerNode.fftSize=256,this._analyzerNode.smoothingTimeConstant=.8),this._audioSourceNode||(this._audioSourceNode=this._audioContext.createMediaElementSource(e),this._audioSourceNode.connect(this._analyzerNode),this._analyzerNode.connect(this._audioContext.destination));const t=()=>{const e=this._detectedBPM||120;this.startRhythm(e,"straight")},i=()=>{this.stopRhythm()},n=()=>{this.stopRhythm()};this._audioHandlers={onPlay:t,onPause:i,onEnded:n},e.addEventListener("play",t),e.addEventListener("pause",i),e.addEventListener("ended",n),e.paused||t(),this._startBPMDetection()}disconnectAudio(){this.stopRhythm(),this._audioElement&&this._audioHandlers&&(this._audioElement.removeEventListener("play",this._audioHandlers.onPlay),this._audioElement.removeEventListener("pause",this._audioHandlers.onPause),this._audioElement.removeEventListener("ended",this._audioHandlers.onEnded)),this._stopBPMDetection(),this._audioElement=null,this._audioHandlers=null}_startBPMDetection(){if(this._bpmDetectionInterval)return;const e=this._analyzerNode?.frequencyBinCount||128,t=new Uint8Array(e);let i=0;const n=[];this._bpmDetectionInterval=setInterval(()=>{if(!this._analyzerNode||!this._audioElement||this._audioElement.paused)return;this._analyzerNode.getByteFrequencyData(t);let e=0;for(let i=0;i<8;i++)e+=t[i];e/=8;const a=performance.now();if(e>180&&a-i>200){if(i>0){const e=a-i;if(n.push(e),n.length>8&&n.shift(),n.length>=4){const e=n.reduce((e,t)=>e+t,0)/n.length,t=Math.round(6e4/e);t>=60&&t<=180&&(this._detectedBPM=t,this.isRhythmPlaying()&&this.setRhythmBPM(t))}}i=a}},50)}_stopBPMDetection(){this._bpmDetectionInterval&&(clearInterval(this._bpmDetectionInterval),this._bpmDetectionInterval=null)}rgbToHex(e){return`#${[Math.round(255*e[0]),Math.round(255*e[1]),Math.round(255*e[2])].map(e=>{const t=e.toString(16);return 1===t.length?`0${t}`:t}).join("")}`}setPosition(e,t,i=0){if(!this.container)return;this.position={x:e,y:t,z:i};const n=window.innerWidth<768;this.container.style.transform=n?`translate(calc(-50% + ${e}px), calc(-50% + ${t}px))`:`translate(${e}px, calc(-50% + ${t}px))`}getPosition(){return this.position||{x:0,y:0,z:0}}animateToPosition(e,t,i=0,n=1e3,a="easeOutCubic"){if(!this.container)return;const r=this.getPosition(),s=performance.now(),o=a=>{const l=a-s,h=Math.min(l/n,1),c=(u=h,1-Math.pow(1-u,3));var u;const d=r.x+(e-r.x)*c,p=r.y+(t-r.y)*c,m=r.z+(i-r.z)*c;this.setPosition(d,p,m),h<1&&requestAnimationFrame(o)};requestAnimationFrame(o)}setContainment(e,t=1){if(this._containmentBounds=e,this._containmentScale=t,this.particleSystem&&1!==t){const e=this.config.particleSpawnRadius||150;this.particleSystem.setSpawnRadius(e*t)}return this}attachToElement(e,t={}){const i="string"==typeof e?document.querySelector(e):e;if(!i)return console.error(`[EmotiveMascot3D] Element not found: ${e}`),this;this._attachedElement=i,this._attachOptions={offsetX:t.offsetX||0,offsetY:t.offsetY||0,animate:!1!==t.animate,duration:t.duration||1e3,scale:t.scale||1,containParticles:!1!==t.containParticles},this._hasAttachedBefore=this._hasAttachedBefore||!1;const n=i.getBoundingClientRect();return this._attachOptions.containParticles?this.setContainment({width:n.width,height:n.height},this._attachOptions.scale):1!==this._attachOptions.scale&&this.setContainment(null,this._attachOptions.scale),this._updateAttachedPosition(),this._setupElementTracking(),this}_updateAttachedPosition(){if(!this._attachedElement||!this.container)return;const e=this._attachedElement.getBoundingClientRect(),t=window.innerWidth<768,i=e.left+e.width/2,n=e.top+e.height/2;let a,r;if(t)a=window.innerWidth/2,r=.18*window.innerHeight;else{const e=750;a=Math.max(20,(window.innerWidth/2-500)/2-375)+e/2,r=window.innerHeight/2}const s=i-a+this._attachOptions.offsetX,o=n-r+this._attachOptions.offsetY,l=!this._hasAttachedBefore;this._hasAttachedBefore=!0,l&&this._attachOptions.animate?this.animateToPosition(s,o,0,this._attachOptions.duration):this.setPosition(s,o,0)}_setupElementTracking(){this._elementTrackingHandlers||(this._elementTrackingHandlers={scroll:()=>this._updateAttachedPosition(),resize:()=>this._updateAttachedPosition()},window.addEventListener("scroll",this._elementTrackingHandlers.scroll,{passive:!0}),window.addEventListener("resize",this._elementTrackingHandlers.resize))}isAttachedToElement(){return!!this._attachedElement}detachFromElement(){return this._attachedElement=null,this._hasAttachedBefore=!1,this._elementTrackingHandlers&&(window.removeEventListener("scroll",this._elementTrackingHandlers.scroll),window.removeEventListener("resize",this._elementTrackingHandlers.resize),this._elementTrackingHandlers=null),this.setContainment(null,1),this.setEmotion("neutral"),this}setSSSPreset(e){this._currentSSSPreset=e,this.core3D&&!this._materialSwapCallbackSet&&(this._materialSwapCallbackSet=!0,this.core3D.onMaterialSwap=e=>{this._currentSSSPreset&&setTimeout(()=>{lp(this,this._currentSSSPreset)},50)});const t=lp(this,e);return t&&this.eventManager.emit("sss:presetChanged",{preset:e}),t}setGeometry(e,t={}){this.morphTo(e,t)}startSolarEclipse(e={}){this.core3D&&"function"==typeof this.core3D.startSolarEclipse?this.core3D.startSolarEclipse(e):(this.morphTo("sun"),this.eventManager.emit("eclipse:solar:start",{type:e.type||"total"}))}startLunarEclipse(e={}){this.core3D&&"function"==typeof this.core3D.startLunarEclipse?this.core3D.startLunarEclipse(e):(this.morphTo("moon"),this.eventManager.emit("eclipse:lunar:start",{type:e.type||"total"}))}stopEclipse(){this.core3D&&"function"==typeof this.core3D.stopEclipse&&this.core3D.stopEclipse(),this.eventManager&&this.eventManager.emit("eclipse:stop")}destroy(){this._destroyed=!0,this.stop(),this.disconnectAudio(),this._audioContext&&(this._audioContext.close(),this._audioContext=null),this._analyzerNode=null,this._audioSourceNode=null,this._elementTrackingHandlers&&(window.removeEventListener("scroll",this._elementTrackingHandlers.scroll),window.removeEventListener("resize",this._elementTrackingHandlers.resize),this._elementTrackingHandlers=null),this._attachedElement=null,this.gestureTimeouts.forEach(e=>clearTimeout(e)),this.gestureTimeouts=[],this.eventManager&&this.eventManager._listeners&&(Object.keys(this.eventManager._listeners).forEach(e=>{this.eventManager._listeners[e]=[]}),this.eventManager._listeners=null),this.core3D&&this.core3D.destroy(),this.particleSystem&&this.particleSystem.destroy(),this.webglCanvas&&this.webglCanvas.parentNode&&this.webglCanvas.parentNode.removeChild(this.webglCanvas),this.canvas2D&&this.canvas2D.parentNode&&this.canvas2D.parentNode.removeChild(this.canvas2D),this.container=null,this.webglCanvas=null,this.canvas2D=null,this.ctx2D=null,this.config=null,this.errorBoundary=null,this.currentGesture=null}}var kp=Object.freeze({__proto__:null,HDRLoader:class extends Br{constructor(e){super(e),this.type=Y}parse(e){const t=function(e,t){switch(e){case 1:throw new Error("THREE.HDRLoader: Read Error: "+(t||""));case 2:throw new Error("THREE.HDRLoader: Write Error: "+(t||""));case 3:throw new Error("THREE.HDRLoader: Bad File Format: "+(t||""));default:throw new Error("THREE.HDRLoader: Memory Error: "+(t||""))}},i=function(e,t,i){t=t||1024;let n=e.pos,a=-1,r=0,s="",o=String.fromCharCode.apply(null,new Uint16Array(e.subarray(n,n+128)));for(;0>(a=o.indexOf("\n"))&&r<t&&n<e.byteLength;)s+=o,r+=o.length,n+=128,o+=String.fromCharCode.apply(null,new Uint16Array(e.subarray(n,n+128)));return-1<a&&(e.pos+=r+a+1,s+o.slice(0,a))},n=function(e,t,i,n){const a=e[t+3],r=Math.pow(2,a-128)/255;i[n+0]=e[t+0]*r,i[n+1]=e[t+1]*r,i[n+2]=e[t+2]*r,i[n+3]=1},a=function(e,t,i,n){const a=e[t+3],r=Math.pow(2,a-128)/255;i[n+0]=bn.toHalfFloat(Math.min(e[t+0]*r,65504)),i[n+1]=bn.toHalfFloat(Math.min(e[t+1]*r,65504)),i[n+2]=bn.toHalfFloat(Math.min(e[t+2]*r,65504)),i[n+3]=bn.toHalfFloat(1)},r=new Uint8Array(e);r.pos=0;const s=function(e){const n=/^\s*GAMMA\s*=\s*(\d+(\.\d+)?)\s*$/,a=/^\s*EXPOSURE\s*=\s*(\d+(\.\d+)?)\s*$/,r=/^\s*FORMAT=(\S+)\s*$/,s=/^\s*\-Y\s+(\d+)\s+\+X\s+(\d+)\s*$/,o={valid:0,string:"",comments:"",programtype:"RGBE",format:"",gamma:1,exposure:1,width:0,height:0};let l,h;for((e.pos>=e.byteLength||!(l=i(e)))&&t(1,"no header found"),(h=l.match(/^#\?(\S+)/))||t(3,"bad initial token"),o.valid|=1,o.programtype=h[1],o.string+=l+"\n";l=i(e),!1!==l;)if(o.string+=l+"\n","#"!==l.charAt(0)){if((h=l.match(n))&&(o.gamma=parseFloat(h[1])),(h=l.match(a))&&(o.exposure=parseFloat(h[1])),(h=l.match(r))&&(o.valid|=2,o.format=h[1]),(h=l.match(s))&&(o.valid|=4,o.height=parseInt(h[1],10),o.width=parseInt(h[2],10)),2&o.valid&&4&o.valid)break}else o.comments+=l+"\n";return 2&o.valid||t(3,"missing format specifier"),4&o.valid||t(3,"missing image size specifier"),o}(r),o=s.width,l=s.height,h=function(e,i,n){const a=i;if(a<8||a>32767||2!==e[0]||2!==e[1]||128&e[2])return new Uint8Array(e);a!==(e[2]<<8|e[3])&&t(3,"wrong scanline width");const r=new Uint8Array(4*i*n);r.length||t(4,"unable to allocate buffer space");let s=0,o=0;const l=4*a,h=new Uint8Array(4),c=new Uint8Array(l);let u=n;for(;u>0&&o<e.byteLength;){o+4>e.byteLength&&t(1),h[0]=e[o++],h[1]=e[o++],h[2]=e[o++],h[3]=e[o++],2==h[0]&&2==h[1]&&(h[2]<<8|h[3])==a||t(3,"bad rgbe scanline format");let i,n=0;for(;n<l&&o<e.byteLength;){i=e[o++];const a=i>128;if(a&&(i-=128),(0===i||n+i>l)&&t(3,"bad scanline data"),a){const t=e[o++];for(let e=0;e<i;e++)c[n++]=t}else c.set(e.subarray(o,o+i),n),n+=i,o+=i}const d=a;for(let e=0;e<d;e++){let t=0;r[s]=c[e+t],t+=a,r[s+1]=c[e+t],t+=a,r[s+2]=c[e+t],t+=a,r[s+3]=c[e+t],s+=4}u--}return r}(r.subarray(r.pos),o,l);let c,u,d;switch(this.type){case q:d=h.length/4;const e=new Float32Array(4*d);for(let t=0;t<d;t++)n(h,4*t,e,4*t);c=e,u=q;break;case Y:d=h.length/4;const t=new Uint16Array(4*d);for(let e=0;e<d;e++)a(h,4*e,t,4*e);c=t,u=Y;break;default:throw new Error("THREE.HDRLoader: Unsupported type: "+this.type)}return{width:o,height:l,data:c,header:s.string,gamma:s.gamma,exposure:s.exposure,type:u}}setDataType(e){return this.type=e,this}load(e,t,i,n){return super.load(e,function(e,i){switch(e.type){case q:case Y:e.colorSpace=ke,e.minFilter=N,e.magFilter=N,e.generateMipmaps=!1,e.flipY=!0}t&&t(e,i)},i,n)}}});export{Fp as CORE_GEOMETRIES,ap as Core3DManager,Cd as CrystalSoul,zp as EmotiveMascot3D,Hd as GeometryCache,Wh as MOON_PHASES,Ic as Rhythm3DAdapter,op as SSSPresets,ec as animateMoonPhase,lp as applySSSPreset,Fh as blendModeNames,Bp as createCrystal,Op as createDiamond,qh as createMoon,Qh as createMoonCrescentMaterial,Zh as createMoonFallbackMaterial,$h as createMoonMaterial,Lp as createSphere,oc as createSunGeometry,sc as createSunMaterial,zp as default,Up as disposeCoreGeometries,Yh as disposeMoon,hc as disposeSun,zh as getBlendModeIndex,Uh as getBlendModeName,jh as getMoonPhaseNames,Xh as getPhaseFromProgress,cp as getSSSPreset,hp as getSSSPresetNames,Lc as rhythm3DAdapter,Jh as setMoonPhase,ic as updateCrescentShadow,tc as updateMoonGlow,lc as updateSunMaterial};
2
2
  //# sourceMappingURL=emotive-mascot-3d.js.map