@needle-tools/engine 5.1.0-experimental.0 → 5.1.0-experimental.2

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,4 +1,4 @@
1
- import{Vector2 as K,Vector3 as b,Vector4 as ye,Quaternion as N,Box3 as Nt,ShadowMaterial as Cb,Euler as ht,PlaneGeometry as Sn,WebGLRenderer as br,PerspectiveCamera as de,OrthographicCamera as Rd,Scene as Mi,Mesh as H,Texture as Se,Uniform as Xi,Color as oe,ShaderMaterial as Hn,MeshStandardMaterial as yt,Box3Helper as sC,GridHelper as Pb,Object3D as M,Material as we,Matrix3 as Ob,Matrix4 as J,Layers as ws,PropertyBinding as La,AnimationClip as Ri,KeyframeTrack as rC,FileLoader as kb,BufferGeometry as Qi,TextureLoader as _r,MeshBasicMaterial as Ce,DoubleSide as Ei,Group as Oo,CylinderGeometry as Mb,SphereGeometry as Ed,BoxGeometry as Da,SpriteMaterial as aC,Sprite as lC,Shape as cC,ExtrudeGeometry as hC,Ray as ko,CubeUVReflectionMapping as Mo,LinearSRGBColorSpace as Ro,ShaderChunk as Kt,Sphere as Td,DataTexture as Lm,RGBAFormat as Ad,EquirectangularReflectionMapping as Eo,SRGBColorSpace as To,Timer as dC,NeutralToneMapping as ja,AgXToneMapping as Id,ACESFilmicToneMapping as Ld,NoToneMapping as Dd,PCFSoftShadowMap as uC,BasicNodeLibrary as pC,WebGLRenderTarget as Gn,DepthTexture as Rb,NearestFilter as jd,AxesHelper as Ti,MathUtils as Ao,Fog as Eb,DirectionalLight as Dm,PointLight as jm,EdgesGeometry as mC,LineSegments as Bm,LineBasicMaterial as Bd,Line as Ba,BufferAttribute as tt,Raycaster as Fd,ArrayCamera as gC,Plane as vr,SkinnedMesh as xs,InterleavedBufferAttribute as Tb,Skeleton as fC,Bone as yC,WebGLCubeRenderTarget as bC,CubeCamera as _C,LoopRepeat as vC,LoopOnce as Fm,AnimationMixer as Um,CompressedTexture as wC,FrontSide as Ss,Camera as xC,Frustum as Ab,AudioListener as SC,PositionalAudio as CC,AudioLoader as zm,VectorKeyframeTrack as PC,QuaternionKeyframeTrack as OC,Audio as kC,BackSide as Ud,PMREMGenerator as MC,EquirectangularRefractionMapping as Ib,CubeTexture as Lb,CompressedCubeTexture as RC,EventDispatcher as Nm,MeshDepthMaterial as EC,CustomBlending as TC,MaxEquation as AC,AlwaysStencilFunc as IC,GreaterEqualStencilFunc as LC,NotEqualStencilFunc as DC,GreaterStencilFunc as jC,LessEqualStencilFunc as BC,EqualStencilFunc as FC,LessStencilFunc as UC,NeverStencilFunc as Db,InvertStencilOp as zC,DecrementWrapStencilOp as NC,IncrementWrapStencilOp as WC,DecrementStencilOp as VC,IncrementStencilOp as $C,ReplaceStencilOp as HC,ZeroStencilOp as GC,KeepStencilOp as qC,AmbientLight as XC,HemisphereLight as QC,Loader as YC,GLSL3 as ZC,AlwaysDepth as KC,GreaterEqualDepth as JC,GreaterDepth as eP,LessEqualDepth as tP,LessDepth as iP,NotEqualDepth as nP,EqualDepth as oP,RawShaderMaterial as jb,BatchedMesh as Bb,LinearFilter as zd,UnsignedByteType as sP,MeshPhysicalMaterial as Fb,RingGeometry as rP,Line3 as aP,AdditiveBlending as Ub,BoxHelper as lP,SpotLight as cP,DirectionalLightHelper as hP,CameraHelper as dP,LOD as uP,Triangle as pP,NormalBlending as mP,ReinhardToneMapping as Wm,LinearToneMapping as Vm,HalfFloatType as $m,Source as gP,VideoTexture as fP,CatmullRomCurve3 as yP,MirroredRepeatWrapping as zb,ShaderLib as Nd,UniformsUtils as Nb,MeshNormalMaterial as bP,AudioContext as _P}from"./three.min.js";import{createLoaders as Hm,LODsManager as wr,NEEDLE_progressive as He,getRaycastMesh as Wb,setKTX2TranscoderLocation as vP,setDracoDecoderLocation as wP,addDracoAndKTX2Loaders as xP,configureLoader as SP}from"./gltf-progressive-3BwW4ETO.min.js";import{GroundedSkybox as Fa,Font as CP,TextGeometry as PP,FontLoader as OP,GLTFLoader as Io,EXRLoader as Gm,HDRLoader as Vb,Stats as kP,nodeFrame as $b,TransformControlsGizmo as Hb,OrbitControls as MP,PositionalAudioHelper as RP,HorizontalBlurShader as EP,VerticalBlurShader as TP,GLTFExporter as Gb,strToU8 as qb,zipSync as AP,XRControllerModelFactory as IP,XRHandMeshModel as LP,Line2 as DP,LineGeometry as jP,LineMaterial as BP,TransformControls as FP,InteractiveGroup as UP,HTMLMesh as zP,VertexNormalsHelper as NP,OBJLoader as qm,FBXLoader as Xb,mergeVertices as WP}from"./three-examples.min.js";import{_md5 as Qb,md5 as VP,v5 as Yb,ByteBuffer as $P,fetchProfile as HP,MotionController as GP,SIZE_PREFIX_LENGTH as Zb,Builder as Xm,createNoise4D as qP,Matrix4 as Qm,BatchedParticleRenderer as XP,ParticleSystem as QP,RenderMode as Lo,ConstantColor as YP,Vector4 as ZP,ConstantValue as KP,TrailParticle as Kb,WorkerBase as JP,MeshBVH as eO}from"./vendor-BgzAK9of.min.js";import{__webpack_exports__default as Oe,__webpack_exports__Text as Jb,__webpack_exports__update as tO,__webpack_exports__Block as e_,SimpleStateBehavior as iO,__webpack_exports__Inline as Ym,__webpack_exports__FontLibrary as t_,ThreeMeshUI as i_}from"./three-mesh-ui-n3JU4M2W.min.js";import{EffectAttribute as nO}from"./postprocessing-BZfyAdCY.min.js";const n_=typeof window!==void 0?window.location.search.includes("debugcontext"):!1;var ue=(o=>(o.ContextRegistered="ContextRegistered",o.ContextCreationStart="ContextCreationStart",o.ContextCreated="ContextCreated",o.ContextFirstFrameRendered="ContextFirstFrameRendered",o.ContextDestroying="ContextDestroying",o.ContextDestroyed="ContextDestroyed",o.MissingCamera="MissingCamera",o.ContextClearing="ContextClearing",o.ContextCleared="ContextCleared",o))(ue||{});class pe{static get Current(){return globalThis["NeedleEngine.Context.Current"]}static set Current(e){globalThis["NeedleEngine.Context.Current"]=e}static get All(){return this.Registered}static Registered=[];static register(e){this.Registered.indexOf(e)===-1&&(n_&&console.warn("Registering context"),this.Registered.push(e),this.dispatchCallback("ContextRegistered",e))}static unregister(e){const t=this.Registered.indexOf(e);t!==-1&&(n_&&console.warn("Unregistering context"),this.Registered.splice(t,1))}static _callbacks={};static registerCallback(e,t){this._callbacks[e]||(this._callbacks[e]=[]),this._callbacks[e].push(t)}static unregisterCallback(e,t){if(!this._callbacks[e])return;const i=this._callbacks[e].indexOf(t);i!==-1&&this._callbacks[e].splice(i,1)}static dispatchCallback(e,t,i){if(!this._callbacks[e])return!0;const n={event:e,context:t};if(i)for(const r in i)n[r]=i[r];const s=new Array;return this._callbacks[e].forEach(r=>{const a=r(n);a instanceof Promise&&s.push(a)}),Promise.all(s)}static addContextCreatedCallback(e){this.registerCallback("ContextCreated",e)}static addContextDestroyedCallback(e){this.registerCallback("ContextDestroyed",e)}}const Zm=new Map;function Ai(o=globalThis.location?.hostname){if(Zm.has(o))return Zm.get(o);const e=/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})|localhost/.test(o);return Zm.set(o,e),e===!0}function o_(){return window.location.hostname.includes("glitch.me")}const s_=()=>o=>o;function oO(o){return s_()(o)}function sO(){return!!w("debug")}class Ii{_factory;_cache=[];_maxSize;_index=0;constructor(e,t){this._factory=e,this._maxSize=t}get(){const e=this._index%this._maxSize;return this._index++,this._cache.length<=e&&(this._cache[e]=this._factory()),this._cache[e]}}let xr=!1;const Km=new Array;typeof window<"u"&&setTimeout(()=>{if(xr){const o={},e=new URL(window.location.href),t=new URL(e);t.searchParams.append("console","");const i=t.toString().replace(/=$|=(?=&)/g,"");for(const s of Km){const r=new URL(e);r.searchParams.append(s,""),o[s]=r.toString().replace(/=$|=(?=&)/g,"")}console.log(`\u{1F335} ?help: Debug Options for Needle Engine.
1
+ import{Vector2 as K,Vector3 as b,Vector4 as ye,Quaternion as N,Box3 as Nt,ShadowMaterial as Cb,Euler as ht,PlaneGeometry as Sn,WebGLRenderer as br,PerspectiveCamera as de,OrthographicCamera as Rd,Scene as Mi,Mesh as H,Texture as Se,Uniform as Xi,Color as oe,ShaderMaterial as Hn,MeshStandardMaterial as yt,Box3Helper as sC,GridHelper as Pb,Object3D as M,Material as we,Matrix3 as Ob,Matrix4 as J,Layers as ws,PropertyBinding as La,AnimationClip as Ri,KeyframeTrack as rC,FileLoader as kb,BufferGeometry as Qi,TextureLoader as _r,MeshBasicMaterial as Ce,DoubleSide as Ei,Group as Oo,CylinderGeometry as Mb,SphereGeometry as Ed,BoxGeometry as Da,SpriteMaterial as aC,Sprite as lC,Shape as cC,ExtrudeGeometry as hC,Ray as ko,CubeUVReflectionMapping as Mo,LinearSRGBColorSpace as Ro,ShaderChunk as Kt,Sphere as Td,DataTexture as Lm,RGBAFormat as Ad,EquirectangularReflectionMapping as Eo,SRGBColorSpace as To,Timer as dC,NeutralToneMapping as ja,AgXToneMapping as Id,ACESFilmicToneMapping as Ld,NoToneMapping as Dd,PCFSoftShadowMap as uC,BasicNodeLibrary as pC,WebGLRenderTarget as Gn,DepthTexture as Rb,NearestFilter as jd,AxesHelper as Ti,MathUtils as Ao,Fog as Eb,DirectionalLight as Dm,PointLight as jm,EdgesGeometry as mC,LineSegments as Bm,LineBasicMaterial as Bd,Line as Ba,BufferAttribute as tt,Raycaster as Fd,ArrayCamera as gC,Plane as vr,SkinnedMesh as xs,InterleavedBufferAttribute as Tb,Skeleton as fC,Bone as yC,WebGLCubeRenderTarget as bC,CubeCamera as _C,LoopRepeat as vC,LoopOnce as Fm,AnimationMixer as Um,CompressedTexture as wC,FrontSide as Ss,Camera as xC,Frustum as Ab,AudioListener as SC,PositionalAudio as CC,AudioLoader as zm,VectorKeyframeTrack as PC,QuaternionKeyframeTrack as OC,Audio as kC,BackSide as Ud,PMREMGenerator as MC,EquirectangularRefractionMapping as Ib,CubeTexture as Lb,CompressedCubeTexture as RC,EventDispatcher as Nm,MeshDepthMaterial as EC,CustomBlending as TC,MaxEquation as AC,AlwaysStencilFunc as IC,GreaterEqualStencilFunc as LC,NotEqualStencilFunc as DC,GreaterStencilFunc as jC,LessEqualStencilFunc as BC,EqualStencilFunc as FC,LessStencilFunc as UC,NeverStencilFunc as Db,InvertStencilOp as zC,DecrementWrapStencilOp as NC,IncrementWrapStencilOp as WC,DecrementStencilOp as VC,IncrementStencilOp as $C,ReplaceStencilOp as HC,ZeroStencilOp as GC,KeepStencilOp as qC,AmbientLight as XC,HemisphereLight as QC,Loader as YC,GLSL3 as ZC,AlwaysDepth as KC,GreaterEqualDepth as JC,GreaterDepth as eP,LessEqualDepth as tP,LessDepth as iP,NotEqualDepth as nP,EqualDepth as oP,RawShaderMaterial as jb,BatchedMesh as Bb,LinearFilter as zd,UnsignedByteType as sP,MeshPhysicalMaterial as Fb,RingGeometry as rP,Line3 as aP,AdditiveBlending as Ub,BoxHelper as lP,SpotLight as cP,DirectionalLightHelper as hP,CameraHelper as dP,LOD as uP,Triangle as pP,NormalBlending as mP,ReinhardToneMapping as Wm,LinearToneMapping as Vm,HalfFloatType as $m,Source as gP,VideoTexture as fP,CatmullRomCurve3 as yP,MirroredRepeatWrapping as zb,ShaderLib as Nd,UniformsUtils as Nb,MeshNormalMaterial as bP,AudioContext as _P}from"./three.min.js";import{createLoaders as Hm,LODsManager as wr,NEEDLE_progressive as He,getRaycastMesh as Wb,setKTX2TranscoderLocation as vP,setDracoDecoderLocation as wP,addDracoAndKTX2Loaders as xP,configureLoader as SP}from"./gltf-progressive-3BwW4ETO.min.js";import{GroundedSkybox as Fa,Font as CP,TextGeometry as PP,FontLoader as OP,GLTFLoader as Io,EXRLoader as Gm,HDRLoader as Vb,Stats as kP,nodeFrame as $b,TransformControlsGizmo as Hb,OrbitControls as MP,PositionalAudioHelper as RP,HorizontalBlurShader as EP,VerticalBlurShader as TP,GLTFExporter as Gb,strToU8 as qb,zipSync as AP,XRControllerModelFactory as IP,XRHandMeshModel as LP,Line2 as DP,LineGeometry as jP,LineMaterial as BP,TransformControls as FP,InteractiveGroup as UP,HTMLMesh as zP,VertexNormalsHelper as NP,OBJLoader as qm,FBXLoader as Xb,mergeVertices as WP}from"./three-examples.min.js";import{_md5 as Qb,md5 as VP,v5 as Yb,ByteBuffer as $P,fetchProfile as HP,MotionController as GP,SIZE_PREFIX_LENGTH as Zb,Builder as Xm,createNoise4D as qP,Matrix4 as Qm,BatchedParticleRenderer as XP,ParticleSystem as QP,RenderMode as Lo,ConstantColor as YP,Vector4 as ZP,ConstantValue as KP,TrailParticle as Kb,WorkerBase as JP,MeshBVH as eO}from"./vendor-Bf43L3CE.min.js";import{__webpack_exports__default as Oe,__webpack_exports__Text as Jb,__webpack_exports__update as tO,__webpack_exports__Block as e_,SimpleStateBehavior as iO,__webpack_exports__Inline as Ym,__webpack_exports__FontLibrary as t_,ThreeMeshUI as i_}from"./three-mesh-ui-n3JU4M2W.min.js";import{EffectAttribute as nO}from"./postprocessing-BZfyAdCY.min.js";const n_=typeof window!==void 0?window.location.search.includes("debugcontext"):!1;var ue=(o=>(o.ContextRegistered="ContextRegistered",o.ContextCreationStart="ContextCreationStart",o.ContextCreated="ContextCreated",o.ContextFirstFrameRendered="ContextFirstFrameRendered",o.ContextDestroying="ContextDestroying",o.ContextDestroyed="ContextDestroyed",o.MissingCamera="MissingCamera",o.ContextClearing="ContextClearing",o.ContextCleared="ContextCleared",o))(ue||{});class pe{static get Current(){return globalThis["NeedleEngine.Context.Current"]}static set Current(e){globalThis["NeedleEngine.Context.Current"]=e}static get All(){return this.Registered}static Registered=[];static register(e){this.Registered.indexOf(e)===-1&&(n_&&console.warn("Registering context"),this.Registered.push(e),this.dispatchCallback("ContextRegistered",e))}static unregister(e){const t=this.Registered.indexOf(e);t!==-1&&(n_&&console.warn("Unregistering context"),this.Registered.splice(t,1))}static _callbacks={};static registerCallback(e,t){this._callbacks[e]||(this._callbacks[e]=[]),this._callbacks[e].push(t)}static unregisterCallback(e,t){if(!this._callbacks[e])return;const i=this._callbacks[e].indexOf(t);i!==-1&&this._callbacks[e].splice(i,1)}static dispatchCallback(e,t,i){if(!this._callbacks[e])return!0;const n={event:e,context:t};if(i)for(const r in i)n[r]=i[r];const s=new Array;return this._callbacks[e].forEach(r=>{const a=r(n);a instanceof Promise&&s.push(a)}),Promise.all(s)}static addContextCreatedCallback(e){this.registerCallback("ContextCreated",e)}static addContextDestroyedCallback(e){this.registerCallback("ContextDestroyed",e)}}const Zm=new Map;function Ai(o=globalThis.location?.hostname){if(Zm.has(o))return Zm.get(o);const e=/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})|localhost/.test(o);return Zm.set(o,e),e===!0}function o_(){return window.location.hostname.includes("glitch.me")}const s_=()=>o=>o;function oO(o){return s_()(o)}function sO(){return!!w("debug")}class Ii{_factory;_cache=[];_maxSize;_index=0;constructor(e,t){this._factory=e,this._maxSize=t}get(){const e=this._index%this._maxSize;return this._index++,this._cache.length<=e&&(this._cache[e]=this._factory()),this._cache[e]}}let xr=!1;const Km=new Array;typeof window<"u"&&setTimeout(()=>{if(xr){const o={},e=new URL(window.location.href),t=new URL(e);t.searchParams.append("console","");const i=t.toString().replace(/=$|=(?=&)/g,"");for(const s of Km){const r=new URL(e);r.searchParams.append(s,""),o[s]=r.toString().replace(/=$|=(?=&)/g,"")}console.log(`\u{1F335} ?help: Debug Options for Needle Engine.
2
2
  Append any of these parameters to the URL to enable specific debug options.
3
3
  Example: ${i} will show an onscreen console window.`);const n=xr===!0?"":` (containing "${xr}")`;console.group("Available URL parameters:"+n);for(const s of Object.keys(o).sort())typeof xr=="string"&&!s.toLowerCase().includes(xr.toLowerCase())||(console.groupCollapsed(s),console.log("Reload with this flag enabled:"),console.log(o[s]),console.groupEnd());console.groupEnd()}},100);function pc(){return new URLSearchParams(globalThis.location?.search)}function w(o){xr&&!Km.includes(o)&&Km.push(o);const e=pc();if(e.has(o)){const t=e.get(o);if(t){const i=Number(t);return isNaN(i)?t:i}else return!0}return!1}xr=w("help");function rO(o,e){const t=pc();t.has(o)?t.set(o,e):t.append(o,e),document.location.search=t.toString()}function mc(o,e,t=!0){const i=pc();i.has(o)?e===null?i.delete(o):i.set(o,e):e!==null&&i.append(o,e),t?r_(o,i):eg(o,i)}function Jm(o,e,t){o.has(e)?o.set(e,t.toString()):o.append(e,t.toString())}function r_(o,e,t){window.history.pushState(t,o,"?"+e.toString())}function eg(o,e,t){window.history.replaceState(t,o,"?"+e.toString())}function aO(o){for(var e="",t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",i=t.length,n=0;n<o;n++)e+=t.charAt(Math.floor(Math.random()*i));return e}function lO(o,e){return Math.floor(Math.random()*(e-o+1))+o}const a_=["smol","tiny","giant","interesting","smart","bright","dull","extreme","beautiful","pretty","dark","epic","salty","silly","funny","lame","lazy","loud","lucky","mad","mean","mighty","mysterious","nasty","odd","old","powerful","quiet","rapid","scary","shiny","shy","silly","smooth","sour","spicy","stupid","sweet","tasty","terrible","ugly","unusual","vast","wet","wild","witty","wrong","zany","zealous","zippy","zombie","zorro"],l_=["cat","dog","mouse","pig","cow","horse","sheep","chicken","duck","goat","panda","tiger","lion","elephant","monkey","bird","fish","snake","frog","turtle","hamster","penguin","kangaroo","whale","dolphin","crocodile","snail","ant","bee","beetle","butterfly","dragon","eagle","fish","giraffe","lizard","panda","penguin","rabbit","snake","spider","tiger","zebra"];function c_(){const o=a_[Math.floor(Math.random()*a_.length)],e=l_[Math.floor(Math.random()*l_.length)];return o+"_"+e}function h_(o){return o=o.replace(/[^a-z0-9áéíóúñü \.,_-]/gim,""),o.trim()}function Ua(o,e,t=!0,i=!1){if(e==null)return null;if(e.userData&&e.userData.guid===o||e.guid==o)return e;if(i&&e.userData?.components){for(const n of e.userData.components)if(n.guid===o)return n}if(t){if(e.scenes)for(const n in e.scenes){const s=e.scenes[n],r=Ua(o,s,t,i);if(r)return r}if(e.children)for(const n in e.children){const s=e.children[n],r=Ua(o,s,t,i);if(r)return r}}}function gc(o,e){if(o!=null&&typeof o=="object"){let t;Array.isArray(o)?t=[]:(t=Object.create(o),Object.assign(t,o));for(const i of Object.keys(o)){const n=o[i];e&&!e(o,i,n)?t[i]=n:n?.clone!==void 0&&typeof n.clone=="function"?t[i]=n.clone():t[i]=gc(n,e)}return t}return o}function Do(o){return new Promise((e,t)=>{setTimeout(e,o)})}function fc(o,e){if(o<=0)return Promise.resolve();if(e||(e=pe.Current),!e)return Promise.reject("No context");const t=e.time.frameCount+o;return new Promise((i,n)=>{if(!e)return n("No context");const s=()=>{e.time.frameCount>=t&&(e.pre_update_callbacks.splice(e.pre_update_callbacks.indexOf(s),1),i())};e.pre_update_callbacks.push(s)})}const Wd=w("debugresolveurl"),d_="rel:";function cO(o,e){return jo(o,e)}function jo(o,e){if(e===void 0)return Wd&&console.warn("getPath: uri is undefined, returning uri",e),e;if(e.startsWith("./"))return e;if(e.startsWith("http"))return Wd&&console.warn("getPath: uri is absolute, returning uri",e),e;if(o===void 0)return Wd&&console.warn("getPath: source is undefined, returning uri",e),e;e.startsWith(d_)&&(e=e.substring(4));const t=o.lastIndexOf("/");if(t>=0){const i=o.substring(0,t+1);for(;i.endsWith("/")&&e.startsWith("/");)e=e.substring(1);const n=i+e;return Wd&&console.log("source:",o,`changed uri
4
4
  from`,e,`
@@ -140,7 +140,7 @@ void main(){
140
140
  #__vconsole .vc-mask {
141
141
  overflow: hidden;
142
142
  }
143
- `,kr?.prepend(i),o===!0&&p_()<=0&&W_(),console.log("\u{1F335} Debug console has loaded")}},e.onerror=()=>{console.warn("\u{1F335} Debug console failed to load."+(window.crossOriginIsolated?"This page is using cross-origin isolation, so external scripts can't be loaded.":"")),xc=!1,pi=null},e.src="https://cdn.jsdelivr.net/npm/vconsole@3.15.1/dist/vconsole.min.js",document.body.appendChild(e)}function pk(){if(!globalThis.VConsole)return;const o=new VConsole.VConsolePlugin("needle-console","\u{1F335} Inspect glTF"),e=()=>document.querySelector("#__vc_plug_"+o._id+" iframe");return o.on("renderTab",function(t){const i=globalThis["needle:codegen_files"];if(!i||i.length===0)return;let n=globalThis["needle:codegen_files"][0];const s=n.indexOf("?");s>-1&&(n=n.substring(0,s));const r=location.protocol+"//"+location.host+location.pathname+"/"+n,a=encodeURIComponent(r);o.fullUrl="https://viewer.needle.tools?inspect&file="+a;var l='<iframe src="" style="width: 100%; height: 99%; border: none;"></iframe>';t(l)}),o.on("show",function(){const t=e();t&&t.src!==o.fullUrl&&(t.src=o.fullUrl)}),o.on("hide",function(){const t=e();t&&(t.src="")}),o.on("addTopBar",function(t){var i=new Array;i.push({name:"Open in new window \u2197",onClick:function(n){window.open(o.fullUrl,"_blank"),pi?.hide()}}),i.push({name:"Reload",onClick:function(n){const s=e();s&&(s.src=o.fullUrl)}}),i.push({name:"Fullscreen",onClick:function(n){const s=e();s.requestFullscreen?s.requestFullscreen():s.webkitRequestFullscreen instanceof Function&&s.webkitRequestFullscreen()}}),t(i)}),o}const Cg="padding: 10px; font-family: monospace;",$_="margin-bottom: 10px;",Mr="margin-bottom: 10px; margin-top: 15px;",mk="width: 100%; border-collapse: collapse; border: 1px solid rgba(0,0,0,0.1); table-layout: fixed;",H_="border: 1px solid rgba(0,0,0,0.1); padding: 5px;",gk=H_,fk=H_+" word-break: break-all;";function Xn(o,e=!1){e&&o.sort((i,n)=>(n.value?1:0)-(i.value?1:0));let t=`<table style='${mk}'>`;t+="<tbody>";for(const i of o){const n=typeof i.value=="boolean"?i.value?"\u2705":"\u274C":i.value;t+=`<tr><td style='${gk}'>${i.label}</td><td style='${fk}'>${n}</td></tr>`}return t+="</tbody></table>",t}function G_(){try{if(document.createElement("canvas").getContext("webgl2"))return"\u2705"}catch{}return"\u274C"}function yk(){if(!globalThis.VConsole)return;const o=new VConsole.VConsolePlugin("device-utilities","\u{1F4F1} Device Info");return o.on("renderTab",function(e){let t=`<div style='${Cg}'>`;const i=kk();t+=`<h3 style='${$_}'>Device: ${i}</h3>`,t+=Xn([{label:"\u{1F4BB} Desktop",value:I.isDesktop()},{label:"\u{1F4F1} Mobile Device",value:I.isMobileDevice()},{label:"\u{1F34E} iOS",value:I.isiOS()},{label:"\u{1F4F1} iPad",value:I.isiPad()},{label:"\u{1F916} Android",value:I.isAndroidDevice()},{label:"\u{1F98A} Mozilla XR",value:I.isMozillaXR()},{label:"\u{1F335} Needle App Clip",value:I.isNeedleAppClip()},{label:"\u{1F34F} macOS",value:I.isMacOS()},{label:"\u{1F453} VisionOS",value:I.isVisionOS()},{label:"\u{1F9ED} Safari",value:I.isSafari()},{label:"\u{1F576}\uFE0F Meta Quest",value:I.isQuest()},{label:"\u{1F517} QuickLook AR Support",value:I.supportsQuickLookAR()}],!0);const n=[],s=I.getiOSVersion();s&&n.push({label:"\u{1F34E} iOS Version",value:s});const r=I.getChromeVersion();r&&n.push({label:"\u{1F310} Chrome Version",value:r});const a=I.getSafariVersion();a&&n.push({label:"\u{1F9ED} Safari Version",value:a}),n.length>0&&(t+=Xn(n,!1)),t+="</div>",t+=`<div style='${Cg} margin-top: 20px;'>`,t+=`<h3 style='${$_}'>User Agent Info</h3>`;const l=[{label:"User Agent",value:navigator.userAgent},{label:"Platform",value:navigator.platform},{label:"App Version",value:navigator.appVersion},{label:"User Agent Data",value:navigator.userAgentData?`Platform: ${navigator.userAgentData.platform}, Mobile: ${navigator.userAgentData.mobile}`:"Not supported"},{label:"WebXR",value:"xr"in navigator?"\u2705":"\u274C"},{label:"WebGPU",value:"gpu"in navigator?"\u2705":"\u274C"},{label:"WebGL 2",value:G_()}];t+=Xn(l,!1),t+="</div>",e(t)}),o}function bk(){if(!globalThis.VConsole)return;const o=new VConsole.VConsolePlugin("graphics-info","\u{1F3A8} Graphics Info");return o.on("renderTab",async function(e){let t=`<div style='${Cg}'>`;const i=_k();i.length>0&&(t+=`<h3 style='${Mr}'>General GPU Info</h3>`,t+=Xn(i,!1));const n=wk();n.length>0&&(t+=`<h3 style='${Mr}'>WebGL</h3>`,t+=Xn(n,!1));const s=xk();s.length>0&&(t+=`<h3 style='${Mr}'>WebGL 2 Features</h3>`,t+=Xn(s,!1));const r=Sk();r.length>0&&(t+=`<h3 style='${Mr}'>WebGL Limits</h3>`,t+=Xn(r,!1));const a=Ck();a.length>0&&(t+=`<h3 style='${Mr}'>Texture Formats</h3>`,t+=Xn(a,!1));const l=await Pk();if(l.length>0&&(t+=`<h3 style='${Mr}'>WebGPU</h3>`,t+=Xn(l,!1)),I.isSafari()){const c=Ok();c.length>0&&(t+=`<h3 style='${Mr}'>Safari GPU Info</h3>`,t+=Xn(c,!1))}t+="</div>",e(t)}),o}function _k(){const o=[],e=window.devicePixelRatio;o.push({label:"Device Pixel Ratio",value:e.toString()}),o.push({label:"Width (px)",value:(window.innerWidth*e).toString()}),o.push({label:"Height (px)",value:(window.innerHeight*e).toString()});const t=I.isMobileDevice()?150:96,i=screen.width/t,n=screen.height/t,s=i*2.54,r=n*2.54;o.push({label:"Estimated Width (cm)",value:s.toFixed(1)}),o.push({label:"Estimated Height (cm)",value:r.toFixed(1)});const a=q_();if(a){o.push({label:"GPU",value:a.renderer}),o.push({label:"Driver",value:a.vendor}),o.push({label:"ANGLE",value:a.angle||"Not detected"});const l=vk(a.renderer);l&&(l.manufacturer&&o.push({label:"Manufacturer",value:l.manufacturer}),l.cardVersion&&o.push({label:"Card Version",value:l.cardVersion}),l.brand&&o.push({label:"Brand",value:l.brand}),o.push({label:"Integrated",value:l.integrated?"Yes":"No"}),l.layer&&o.push({label:"WebGL Layer",value:l.layer}))}return o}function vk(o){if(!o)return null;const e=(l,c)=>{const h=c.match(l);return h&&h[0]},t=e(/(ANGLE)/g,o)||void 0,i=e(/((NVIDIA|AMD|Intel)[^\d]*[^\s]+)/,o)||o,n=i.split(" ");n.shift();const s=e(/(NVIDIA|AMD|Intel)/g,i)||void 0,r=n.length>0?n.pop():void 0,a=n.length>0?n.join(" "):void 0;return{manufacturer:s,cardVersion:r,brand:a,integrated:s==="Intel",layer:t,card:i}}function wk(){const o=[],e=q_();return e&&(o.push({label:"\u{1F4CA} WebGL Version",value:e.version}),o.push({label:"\u{1F3AE} WebGL 2 Available",value:G_()})),o}function xk(){const o=[];try{const e=document.createElement("canvas").getContext("webgl2");if(!e)return o;o.push({label:"Float Color Buffer",value:e.getExtension("EXT_color_buffer_float")?"\u2705":"\u274C"}),o.push({label:"Anisotropic Filtering",value:e.getExtension("EXT_texture_filter_anisotropic")?"\u2705":"\u274C"}),o.push({label:"Float Texture Linear",value:e.getExtension("OES_texture_float_linear")?"\u2705":"\u274C"}),o.push({label:"S3TC Compression",value:e.getExtension("WEBGL_compressed_texture_s3tc")?"\u2705":"\u274C"}),o.push({label:"ETC Compression",value:e.getExtension("WEBGL_compressed_texture_etc")?"\u2705":"\u274C"}),o.push({label:"PVRTC Compression",value:e.getExtension("WEBGL_compressed_texture_pvrtc")?"\u2705":"\u274C"}),o.push({label:"ASTC Compression",value:e.getExtension("WEBGL_compressed_texture_astc")?"\u2705":"\u274C"})}catch{}return o}function Sk(){const o=[];try{const e=document.createElement("canvas"),t=e.getContext("webgl2")||e.getContext("webgl");if(!t)return o;const i=t instanceof WebGL2RenderingContext;o.push({label:"\u{1F4CF} Max Texture Size",value:t.getParameter(t.MAX_TEXTURE_SIZE).toString()}),o.push({label:"\u{1F3A8} Max Renderbuffer Size",value:t.getParameter(t.MAX_RENDERBUFFER_SIZE).toString()}),o.push({label:"\u{1F517} Max Vertex Attribs",value:t.getParameter(t.MAX_VERTEX_ATTRIBS).toString()}),o.push({label:"\u{1F3AF} Max Texture Units",value:t.getParameter(t.MAX_TEXTURE_IMAGE_UNITS).toString()}),i&&(o.push({label:"\u26A1 Max Samples",value:t.getParameter(t.MAX_SAMPLES).toString()}),o.push({label:"\u{1F504} Max Uniform Buffer Bindings",value:t.getParameter(t.MAX_UNIFORM_BUFFER_BINDINGS).toString()}),o.push({label:"\u{1F4D0} Max 3D Texture Size",value:t.getParameter(t.MAX_3D_TEXTURE_SIZE).toString()}))}catch{}return o}function Ck(){const o=[];try{document.createElement("canvas").getContext("webgl")&&(o.push({label:"WebGL 1 RGBA",value:"\u2705"}),o.push({label:"WebGL 1 RGB",value:"\u2705"}));const e=document.createElement("canvas").getContext("webgl2");e&&(o.push({label:"WebGL 2 RGBA32F",value:e.getExtension("EXT_color_buffer_float")?"\u2705":"\u274C"}),o.push({label:"WebGL 2 RGB32F",value:e.getExtension("EXT_color_buffer_float")?"\u2705":"\u274C"}),o.push({label:"WebGL 2 R11F_G11F_B10F",value:"\u2705"}),o.push({label:"WebGL 2 RGB565",value:"\u2705"}),o.push({label:"WebGL 2 RGB5_A1",value:"\u2705"}),o.push({label:"WebGL 2 RGBA4444",value:"\u2705"}))}catch{}return o}async function Pk(){const o=[];if(!("gpu"in navigator))return o.push({label:"\u{1F680} WebGPU Support",value:"\u274C Not supported"}),o;o.push({label:"\u{1F680} WebGPU Support",value:"\u2705 Supported"});try{const e=await navigator.gpu.requestAdapter();if(!e)return o.push({label:"\u{1F3AF} Adapter",value:"No adapter available"}),o;o.push({label:"\u{1F3AF} Adapter",value:e.name||"Unknown Adapter"});const t=await e.requestDevice();o.push({label:"\u{1F527} Device",value:t.label||"WebGPU Device"}),o.push({label:"\u{1F4CF} Max Texture 2D",value:t.limits.maxTextureDimension2D.toString()}),o.push({label:"\u{1F4D0} Max Texture 3D",value:t.limits.maxTextureDimension3D.toString()}),o.push({label:"\u{1F4CA} Max Texture Array Layers",value:t.limits.maxTextureArrayLayers.toString()}),o.push({label:"\u{1F4BE} Max Buffer Size",value:`${(t.limits.maxBufferSize/1024/1024).toFixed(1)}MB`}),o.push({label:"\u{1F517} Max Bind Groups",value:t.limits.maxBindGroups.toString()})}catch(e){o.push({label:"\u274C Error",value:e.message})}return o}function q_(){try{const o=document.createElement("canvas"),e=o.getContext("webgl2")||o.getContext("webgl");if(!e)return null;const t=e.getExtension("WEBGL_debug_renderer_info"),i=t?e.getParameter(t.UNMASKED_RENDERER_WEBGL):e.getParameter(e.RENDERER),n=t?e.getParameter(t.UNMASKED_VENDOR_WEBGL):e.getParameter(e.VENDOR),s=e.getParameter(e.VERSION);let r;if(i&&i.includes("ANGLE")){const a=i.match(/ANGLE \(([^)]+)\)/);a&&(r=a[1])}return{renderer:i,vendor:n,version:s,angle:r}}catch{return null}}function Ok(){const o=[];try{const e=document.createElement("canvas").getContext("webgl");if(e){const t=e.getExtension("WEBGL_debug_renderer_info");if(t){const i=e.getParameter(t.UNMASKED_RENDERER_WEBGL);i&&i.includes("Apple")&&o.push({label:"\u{1F34E} Apple GPU",value:i})}}}catch{}try{const e=document.createElement("canvas").getContext("webgl");e&&(e.getSupportedExtensions()||[]).includes("WEBGL_compressed_texture_pvrtc")&&o.push({label:"\u{1F5DC}\uFE0F PVRTC Support",value:"\u2705"})}catch{}return o}function kk(){return I.isQuest()?"Meta Quest":I.isVisionOS()?"Vision Pro":I.isiOS()?I.isiPad()?"iPad":"iPhone/iPod":I.isAndroidDevice()?"Android Device":I.isMozillaXR()?"Mozilla XR Browser":I.isNeedleAppClip()?"Needle App Clip":I.isMacOS()?"Mac":I.isDesktop()?"Desktop PC":"Unknown Device"}function Mk(){return document.querySelector("#__vconsole .vc-switch")||null}function Rk(){return document.querySelector("#__vconsole")||null}const Kd=w("debugtypes");class Ek{_types=new Map;_reverseTypes=new Map;_lazyLoaders=new Map;constructor(){Kd&&console.warn("TypeStore: Created",this)}add(e,t){Kd&&console.warn("ADD TYPE",e);const i=this._types.get(e);i?Kd&&i!==t&&console.warn("Type name exists multiple times in your project and may lead to runtime errors:",e):(this._types.set(e,t),this._reverseTypes.set(t,e))}addLazy(e,t){this._types.has(e)||this._lazyLoaders.set(e,t)}get(e){return this._types.get(e)||null}async getAsync(e){const t=this._types.get(e);if(t)return t;const i=this._lazyLoaders.get(e);if(i){Kd&&console.warn("LAZY LOAD TYPE",e);const n=await i();return this.add(e,n),this._lazyLoaders.delete(e),n}return null}getKey(e){return this._reverseTypes.get(e)||null}}const Tk=Symbol("BuiltInType"),C=new Ek,Pg=function(o){C.get(o.name)||C.add(o.name,o)};class Ak{context;mixers=[];constructor(e){this.context=e}onDestroy(){this.mixers.forEach(e=>e.stopAllAction()),this.mixers.length=0}registerAnimationMixer(e){if(!e){console.warn("AnimationsRegistry.registerAnimationMixer called with null or undefined mixer");return}this.mixers.includes(e)||this.mixers.push(e)}unregisterAnimationMixer(e){if(!e){console.warn("AnimationsRegistry.unregisterAnimationMixer called with null or undefined mixer");return}const t=this.mixers.indexOf(e);t!==-1&&this.mixers.splice(t,1)}}class Qn{static testIfRootCanAnimate(e,t){const i=e.getRoot();return i&&(i.userData.static||i.matrixAutoUpdate===!1||i.matrixWorldAutoUpdate===!1)?((t===!0||t===void 0&&A())&&console.warn(`AnimationUtils: The root object (${i.name||i.type}) of this AnimationAction has matrixAutoUpdate or matrixWorldAutoUpdate set to false. This may prevent the animation from working correctly. If the object is marked as static, try to change it to dynamic.`,{static:i.userData.static,name:i.userData.name,tag:i.userData.tag,matrixAutoUpdate:i.matrixAutoUpdate,matrixWorldAutoUpdate:i.matrixWorldAutoUpdate}),!1):!0}static tryGetActionsFromMixer(e){return e._actions||null}static tryGetAnimationClipsFromObjectHierarchy(e,t){if(t||(t=new Array),e)e.animations&&t.push(...e.animations);else return t;if(e.children)for(const i of e.children)this.tryGetAnimationClipsFromObjectHierarchy(i,t);return t}static autoplayAnimations(e){if(!e||!e.animations)return console.debug("No animations found in file"),null;const t="scene"in e?e.scene:e,i=new Array;for(let s=0;s<e.animations.length;s++){const r=e.animations[s];if(!r.tracks||r.tracks.length<=0){console.warn("Animation has no tracks");continue}for(const a in r.tracks){const l=r.tracks[a],c=La.parseTrackName(l.name);let h=La.findNode(t,c.nodeName);if(!h){const p=l.__objectName??l.name.substring(0,l.name.indexOf("."));if(h=t.getObjectByProperty("uuid",p)??null,!h)continue}let d=n(h)||n(t);if(!d){const p=C.get("Animation");if(d=t.addComponent(p),!d){console.error("Failed creating Animation component: No 'Animation' component found in TypeStore");break}}i.push(d),d.addClip&&d.addClip(r)}}return i;function n(s){if(!s)return null;const r=s.userData?.components;if(r&&r.length>0)for(let a=0;a<r.length;a++){const l=r[a];if(l.isAnimationComponent===!0)return l}return n(s.parent)}}static emptyClip(){return new Ri("empty",0,[])}static createScaleClip(e){const t=e?.duration??.3;let i={x:1,y:1,z:1};e?.scale!==void 0&&(typeof e.scale=="number"?i={x:e.scale,y:e.scale,z:e.scale}:i=e.scale);const n=e?.type??"linear",s=e?.scaleFactor??1.2,r=new Array,a=new Array;switch(n){case"linear":r.push(0,t),a.push(i.x,i.y,i.z,i.x*s,i.y*s,i.z*s);break;case"spring":r.push(0,t*.3,t*.5,t*.7,t*.9,t),a.push(i.x,i.y,i.z,i.x*s,i.y*s,i.z*s,i.x*.9,i.y*.9,i.z*.9,i.x*1.05,i.y*1.05,i.z*1.05,i.x*.98,i.y*.98,i.z*.98,i.x,i.y,i.z);break}const l=new rC(".scale",r,a);return new Ri("scale",r[r.length-1],[l])}}const qe=function(o){return u(o)},u=function(o){if(o===void 0&&(o=null),!Array.isArray(o))o=X_(o);else for(let e=0;e<o.length;e++){const t=o[e];o[e]=X_(t)}return function(e,t){if(!e){const n=typeof t=="string"?t:t.name;console.warn(`@serializable without a target at '${n}'.`);return}typeof t!="string"&&(t=t.name),Object.getOwnPropertyDescriptor(e,"$serializedTypes")||(e.$serializedTypes={});const i=e.$serializedTypes=e.$serializedTypes||{};i[t]=o}};function X_(o){switch(o?.prototype?.constructor?.name){case"Number":case"String":case"Boolean":return null}return o}const Q_=w("debugcomponentevents");class Jd{static eventListeners=new Map;static addComponentLifecylceEventListener(e,t){this.eventListeners.has(e)&&this.eventListeners.set(e,[]);let i=this.eventListeners.get(e);i||(i=[]),i.push(t),this.eventListeners.set(e,i),Q_&&console.log("Added event listener for "+e,this.eventListeners)}static removeComponentLifecylceEventListener(e,t){const i=this.eventListeners.get(e);if(!i)return;const n=i.indexOf(t);n<0||i.splice(n,1)}static dispatchComponentLifecycleEvent(e,t){const i=this.eventListeners.get(e);if(Q_&&console.log("Dispatching event "+e,i),!!i)for(const n of i)n(t)}}const Y_=w("debugdefines");Ps('if(!globalThis["NEEDLE_ENGINE_VERSION"]) globalThis["NEEDLE_ENGINE_VERSION"] = "0.0.0";'),Ps('if(!globalThis["NEEDLE_ENGINE_GENERATOR"]) globalThis["NEEDLE_ENGINE_GENERATOR"] = "unknown";'),Ps('if(!globalThis["NEEDLE_PROJECT_BUILD_TIME"]) globalThis["NEEDLE_PROJECT_BUILD_TIME"] = "unknown";'),Ps('if(!globalThis["NEEDLE_PUBLIC_KEY"]) globalThis["NEEDLE_PUBLIC_KEY"] = "unknown";'),Ps('globalThis["__NEEDLE_ENGINE_VERSION__"] = "5.1.0-experimental.0";'),Ps('globalThis["__NEEDLE_ENGINE_GENERATOR__"] = "undefined";'),Ps('globalThis["__NEEDLE_PROJECT_BUILD_TIME__"] = "Mon Mar 30 2026 12:54:09 GMT+0700 (Indochina Time)";'),Ps('globalThis["__NEEDLE_PUBLIC_KEY__"] = "npk_ad8e492e31253a2800d563522e42a7311d0d7b766ac4ec1f64d3b425f06eacbd";');const mi="5.1.0-experimental.0",$a="undefined",Sc="Mon Mar 30 2026 12:54:09 GMT+0700 (Indochina Time)";Y_&&console.log(`Engine version: ${mi} (generator: ${$a})
143
+ `,kr?.prepend(i),o===!0&&p_()<=0&&W_(),console.log("\u{1F335} Debug console has loaded")}},e.onerror=()=>{console.warn("\u{1F335} Debug console failed to load."+(window.crossOriginIsolated?"This page is using cross-origin isolation, so external scripts can't be loaded.":"")),xc=!1,pi=null},e.src="https://cdn.jsdelivr.net/npm/vconsole@3.15.1/dist/vconsole.min.js",document.body.appendChild(e)}function pk(){if(!globalThis.VConsole)return;const o=new VConsole.VConsolePlugin("needle-console","\u{1F335} Inspect glTF"),e=()=>document.querySelector("#__vc_plug_"+o._id+" iframe");return o.on("renderTab",function(t){const i=globalThis["needle:codegen_files"];if(!i||i.length===0)return;let n=globalThis["needle:codegen_files"][0];const s=n.indexOf("?");s>-1&&(n=n.substring(0,s));const r=location.protocol+"//"+location.host+location.pathname+"/"+n,a=encodeURIComponent(r);o.fullUrl="https://viewer.needle.tools?inspect&file="+a;var l='<iframe src="" style="width: 100%; height: 99%; border: none;"></iframe>';t(l)}),o.on("show",function(){const t=e();t&&t.src!==o.fullUrl&&(t.src=o.fullUrl)}),o.on("hide",function(){const t=e();t&&(t.src="")}),o.on("addTopBar",function(t){var i=new Array;i.push({name:"Open in new window \u2197",onClick:function(n){window.open(o.fullUrl,"_blank"),pi?.hide()}}),i.push({name:"Reload",onClick:function(n){const s=e();s&&(s.src=o.fullUrl)}}),i.push({name:"Fullscreen",onClick:function(n){const s=e();s.requestFullscreen?s.requestFullscreen():s.webkitRequestFullscreen instanceof Function&&s.webkitRequestFullscreen()}}),t(i)}),o}const Cg="padding: 10px; font-family: monospace;",$_="margin-bottom: 10px;",Mr="margin-bottom: 10px; margin-top: 15px;",mk="width: 100%; border-collapse: collapse; border: 1px solid rgba(0,0,0,0.1); table-layout: fixed;",H_="border: 1px solid rgba(0,0,0,0.1); padding: 5px;",gk=H_,fk=H_+" word-break: break-all;";function Xn(o,e=!1){e&&o.sort((i,n)=>(n.value?1:0)-(i.value?1:0));let t=`<table style='${mk}'>`;t+="<tbody>";for(const i of o){const n=typeof i.value=="boolean"?i.value?"\u2705":"\u274C":i.value;t+=`<tr><td style='${gk}'>${i.label}</td><td style='${fk}'>${n}</td></tr>`}return t+="</tbody></table>",t}function G_(){try{if(document.createElement("canvas").getContext("webgl2"))return"\u2705"}catch{}return"\u274C"}function yk(){if(!globalThis.VConsole)return;const o=new VConsole.VConsolePlugin("device-utilities","\u{1F4F1} Device Info");return o.on("renderTab",function(e){let t=`<div style='${Cg}'>`;const i=kk();t+=`<h3 style='${$_}'>Device: ${i}</h3>`,t+=Xn([{label:"\u{1F4BB} Desktop",value:I.isDesktop()},{label:"\u{1F4F1} Mobile Device",value:I.isMobileDevice()},{label:"\u{1F34E} iOS",value:I.isiOS()},{label:"\u{1F4F1} iPad",value:I.isiPad()},{label:"\u{1F916} Android",value:I.isAndroidDevice()},{label:"\u{1F98A} Mozilla XR",value:I.isMozillaXR()},{label:"\u{1F335} Needle App Clip",value:I.isNeedleAppClip()},{label:"\u{1F34F} macOS",value:I.isMacOS()},{label:"\u{1F453} VisionOS",value:I.isVisionOS()},{label:"\u{1F9ED} Safari",value:I.isSafari()},{label:"\u{1F576}\uFE0F Meta Quest",value:I.isQuest()},{label:"\u{1F517} QuickLook AR Support",value:I.supportsQuickLookAR()}],!0);const n=[],s=I.getiOSVersion();s&&n.push({label:"\u{1F34E} iOS Version",value:s});const r=I.getChromeVersion();r&&n.push({label:"\u{1F310} Chrome Version",value:r});const a=I.getSafariVersion();a&&n.push({label:"\u{1F9ED} Safari Version",value:a}),n.length>0&&(t+=Xn(n,!1)),t+="</div>",t+=`<div style='${Cg} margin-top: 20px;'>`,t+=`<h3 style='${$_}'>User Agent Info</h3>`;const l=[{label:"User Agent",value:navigator.userAgent},{label:"Platform",value:navigator.platform},{label:"App Version",value:navigator.appVersion},{label:"User Agent Data",value:navigator.userAgentData?`Platform: ${navigator.userAgentData.platform}, Mobile: ${navigator.userAgentData.mobile}`:"Not supported"},{label:"WebXR",value:"xr"in navigator?"\u2705":"\u274C"},{label:"WebGPU",value:"gpu"in navigator?"\u2705":"\u274C"},{label:"WebGL 2",value:G_()}];t+=Xn(l,!1),t+="</div>",e(t)}),o}function bk(){if(!globalThis.VConsole)return;const o=new VConsole.VConsolePlugin("graphics-info","\u{1F3A8} Graphics Info");return o.on("renderTab",async function(e){let t=`<div style='${Cg}'>`;const i=_k();i.length>0&&(t+=`<h3 style='${Mr}'>General GPU Info</h3>`,t+=Xn(i,!1));const n=wk();n.length>0&&(t+=`<h3 style='${Mr}'>WebGL</h3>`,t+=Xn(n,!1));const s=xk();s.length>0&&(t+=`<h3 style='${Mr}'>WebGL 2 Features</h3>`,t+=Xn(s,!1));const r=Sk();r.length>0&&(t+=`<h3 style='${Mr}'>WebGL Limits</h3>`,t+=Xn(r,!1));const a=Ck();a.length>0&&(t+=`<h3 style='${Mr}'>Texture Formats</h3>`,t+=Xn(a,!1));const l=await Pk();if(l.length>0&&(t+=`<h3 style='${Mr}'>WebGPU</h3>`,t+=Xn(l,!1)),I.isSafari()){const c=Ok();c.length>0&&(t+=`<h3 style='${Mr}'>Safari GPU Info</h3>`,t+=Xn(c,!1))}t+="</div>",e(t)}),o}function _k(){const o=[],e=window.devicePixelRatio;o.push({label:"Device Pixel Ratio",value:e.toString()}),o.push({label:"Width (px)",value:(window.innerWidth*e).toString()}),o.push({label:"Height (px)",value:(window.innerHeight*e).toString()});const t=I.isMobileDevice()?150:96,i=screen.width/t,n=screen.height/t,s=i*2.54,r=n*2.54;o.push({label:"Estimated Width (cm)",value:s.toFixed(1)}),o.push({label:"Estimated Height (cm)",value:r.toFixed(1)});const a=q_();if(a){o.push({label:"GPU",value:a.renderer}),o.push({label:"Driver",value:a.vendor}),o.push({label:"ANGLE",value:a.angle||"Not detected"});const l=vk(a.renderer);l&&(l.manufacturer&&o.push({label:"Manufacturer",value:l.manufacturer}),l.cardVersion&&o.push({label:"Card Version",value:l.cardVersion}),l.brand&&o.push({label:"Brand",value:l.brand}),o.push({label:"Integrated",value:l.integrated?"Yes":"No"}),l.layer&&o.push({label:"WebGL Layer",value:l.layer}))}return o}function vk(o){if(!o)return null;const e=(l,c)=>{const h=c.match(l);return h&&h[0]},t=e(/(ANGLE)/g,o)||void 0,i=e(/((NVIDIA|AMD|Intel)[^\d]*[^\s]+)/,o)||o,n=i.split(" ");n.shift();const s=e(/(NVIDIA|AMD|Intel)/g,i)||void 0,r=n.length>0?n.pop():void 0,a=n.length>0?n.join(" "):void 0;return{manufacturer:s,cardVersion:r,brand:a,integrated:s==="Intel",layer:t,card:i}}function wk(){const o=[],e=q_();return e&&(o.push({label:"\u{1F4CA} WebGL Version",value:e.version}),o.push({label:"\u{1F3AE} WebGL 2 Available",value:G_()})),o}function xk(){const o=[];try{const e=document.createElement("canvas").getContext("webgl2");if(!e)return o;o.push({label:"Float Color Buffer",value:e.getExtension("EXT_color_buffer_float")?"\u2705":"\u274C"}),o.push({label:"Anisotropic Filtering",value:e.getExtension("EXT_texture_filter_anisotropic")?"\u2705":"\u274C"}),o.push({label:"Float Texture Linear",value:e.getExtension("OES_texture_float_linear")?"\u2705":"\u274C"}),o.push({label:"S3TC Compression",value:e.getExtension("WEBGL_compressed_texture_s3tc")?"\u2705":"\u274C"}),o.push({label:"ETC Compression",value:e.getExtension("WEBGL_compressed_texture_etc")?"\u2705":"\u274C"}),o.push({label:"PVRTC Compression",value:e.getExtension("WEBGL_compressed_texture_pvrtc")?"\u2705":"\u274C"}),o.push({label:"ASTC Compression",value:e.getExtension("WEBGL_compressed_texture_astc")?"\u2705":"\u274C"})}catch{}return o}function Sk(){const o=[];try{const e=document.createElement("canvas"),t=e.getContext("webgl2")||e.getContext("webgl");if(!t)return o;const i=t instanceof WebGL2RenderingContext;o.push({label:"\u{1F4CF} Max Texture Size",value:t.getParameter(t.MAX_TEXTURE_SIZE).toString()}),o.push({label:"\u{1F3A8} Max Renderbuffer Size",value:t.getParameter(t.MAX_RENDERBUFFER_SIZE).toString()}),o.push({label:"\u{1F517} Max Vertex Attribs",value:t.getParameter(t.MAX_VERTEX_ATTRIBS).toString()}),o.push({label:"\u{1F3AF} Max Texture Units",value:t.getParameter(t.MAX_TEXTURE_IMAGE_UNITS).toString()}),i&&(o.push({label:"\u26A1 Max Samples",value:t.getParameter(t.MAX_SAMPLES).toString()}),o.push({label:"\u{1F504} Max Uniform Buffer Bindings",value:t.getParameter(t.MAX_UNIFORM_BUFFER_BINDINGS).toString()}),o.push({label:"\u{1F4D0} Max 3D Texture Size",value:t.getParameter(t.MAX_3D_TEXTURE_SIZE).toString()}))}catch{}return o}function Ck(){const o=[];try{document.createElement("canvas").getContext("webgl")&&(o.push({label:"WebGL 1 RGBA",value:"\u2705"}),o.push({label:"WebGL 1 RGB",value:"\u2705"}));const e=document.createElement("canvas").getContext("webgl2");e&&(o.push({label:"WebGL 2 RGBA32F",value:e.getExtension("EXT_color_buffer_float")?"\u2705":"\u274C"}),o.push({label:"WebGL 2 RGB32F",value:e.getExtension("EXT_color_buffer_float")?"\u2705":"\u274C"}),o.push({label:"WebGL 2 R11F_G11F_B10F",value:"\u2705"}),o.push({label:"WebGL 2 RGB565",value:"\u2705"}),o.push({label:"WebGL 2 RGB5_A1",value:"\u2705"}),o.push({label:"WebGL 2 RGBA4444",value:"\u2705"}))}catch{}return o}async function Pk(){const o=[];if(!("gpu"in navigator))return o.push({label:"\u{1F680} WebGPU Support",value:"\u274C Not supported"}),o;o.push({label:"\u{1F680} WebGPU Support",value:"\u2705 Supported"});try{const e=await navigator.gpu.requestAdapter();if(!e)return o.push({label:"\u{1F3AF} Adapter",value:"No adapter available"}),o;o.push({label:"\u{1F3AF} Adapter",value:e.name||"Unknown Adapter"});const t=await e.requestDevice();o.push({label:"\u{1F527} Device",value:t.label||"WebGPU Device"}),o.push({label:"\u{1F4CF} Max Texture 2D",value:t.limits.maxTextureDimension2D.toString()}),o.push({label:"\u{1F4D0} Max Texture 3D",value:t.limits.maxTextureDimension3D.toString()}),o.push({label:"\u{1F4CA} Max Texture Array Layers",value:t.limits.maxTextureArrayLayers.toString()}),o.push({label:"\u{1F4BE} Max Buffer Size",value:`${(t.limits.maxBufferSize/1024/1024).toFixed(1)}MB`}),o.push({label:"\u{1F517} Max Bind Groups",value:t.limits.maxBindGroups.toString()})}catch(e){o.push({label:"\u274C Error",value:e.message})}return o}function q_(){try{const o=document.createElement("canvas"),e=o.getContext("webgl2")||o.getContext("webgl");if(!e)return null;const t=e.getExtension("WEBGL_debug_renderer_info"),i=t?e.getParameter(t.UNMASKED_RENDERER_WEBGL):e.getParameter(e.RENDERER),n=t?e.getParameter(t.UNMASKED_VENDOR_WEBGL):e.getParameter(e.VENDOR),s=e.getParameter(e.VERSION);let r;if(i&&i.includes("ANGLE")){const a=i.match(/ANGLE \(([^)]+)\)/);a&&(r=a[1])}return{renderer:i,vendor:n,version:s,angle:r}}catch{return null}}function Ok(){const o=[];try{const e=document.createElement("canvas").getContext("webgl");if(e){const t=e.getExtension("WEBGL_debug_renderer_info");if(t){const i=e.getParameter(t.UNMASKED_RENDERER_WEBGL);i&&i.includes("Apple")&&o.push({label:"\u{1F34E} Apple GPU",value:i})}}}catch{}try{const e=document.createElement("canvas").getContext("webgl");e&&(e.getSupportedExtensions()||[]).includes("WEBGL_compressed_texture_pvrtc")&&o.push({label:"\u{1F5DC}\uFE0F PVRTC Support",value:"\u2705"})}catch{}return o}function kk(){return I.isQuest()?"Meta Quest":I.isVisionOS()?"Vision Pro":I.isiOS()?I.isiPad()?"iPad":"iPhone/iPod":I.isAndroidDevice()?"Android Device":I.isMozillaXR()?"Mozilla XR Browser":I.isNeedleAppClip()?"Needle App Clip":I.isMacOS()?"Mac":I.isDesktop()?"Desktop PC":"Unknown Device"}function Mk(){return document.querySelector("#__vconsole .vc-switch")||null}function Rk(){return document.querySelector("#__vconsole")||null}const Kd=w("debugtypes");class Ek{_types=new Map;_reverseTypes=new Map;_lazyLoaders=new Map;constructor(){Kd&&console.warn("TypeStore: Created",this)}add(e,t){Kd&&console.warn("ADD TYPE",e);const i=this._types.get(e);i?Kd&&i!==t&&console.warn("Type name exists multiple times in your project and may lead to runtime errors:",e):(this._types.set(e,t),this._reverseTypes.set(t,e))}addLazy(e,t){this._types.has(e)||this._lazyLoaders.set(e,t)}get(e){return this._types.get(e)||null}async getAsync(e){const t=this._types.get(e);if(t)return t;const i=this._lazyLoaders.get(e);if(i){Kd&&console.warn("LAZY LOAD TYPE",e);const n=await i();return this.add(e,n),this._lazyLoaders.delete(e),n}return null}getKey(e){return this._reverseTypes.get(e)||null}}const Tk=Symbol("BuiltInType"),C=new Ek,Pg=function(o){C.get(o.name)||C.add(o.name,o)};class Ak{context;mixers=[];constructor(e){this.context=e}onDestroy(){this.mixers.forEach(e=>e.stopAllAction()),this.mixers.length=0}registerAnimationMixer(e){if(!e){console.warn("AnimationsRegistry.registerAnimationMixer called with null or undefined mixer");return}this.mixers.includes(e)||this.mixers.push(e)}unregisterAnimationMixer(e){if(!e){console.warn("AnimationsRegistry.unregisterAnimationMixer called with null or undefined mixer");return}const t=this.mixers.indexOf(e);t!==-1&&this.mixers.splice(t,1)}}class Qn{static testIfRootCanAnimate(e,t){const i=e.getRoot();return i&&(i.userData.static||i.matrixAutoUpdate===!1||i.matrixWorldAutoUpdate===!1)?((t===!0||t===void 0&&A())&&console.warn(`AnimationUtils: The root object (${i.name||i.type}) of this AnimationAction has matrixAutoUpdate or matrixWorldAutoUpdate set to false. This may prevent the animation from working correctly. If the object is marked as static, try to change it to dynamic.`,{static:i.userData.static,name:i.userData.name,tag:i.userData.tag,matrixAutoUpdate:i.matrixAutoUpdate,matrixWorldAutoUpdate:i.matrixWorldAutoUpdate}),!1):!0}static tryGetActionsFromMixer(e){return e._actions||null}static tryGetAnimationClipsFromObjectHierarchy(e,t){if(t||(t=new Array),e)e.animations&&t.push(...e.animations);else return t;if(e.children)for(const i of e.children)this.tryGetAnimationClipsFromObjectHierarchy(i,t);return t}static autoplayAnimations(e){if(!e||!e.animations)return console.debug("No animations found in file"),null;const t="scene"in e?e.scene:e,i=new Array;for(let s=0;s<e.animations.length;s++){const r=e.animations[s];if(!r.tracks||r.tracks.length<=0){console.warn("Animation has no tracks");continue}for(const a in r.tracks){const l=r.tracks[a],c=La.parseTrackName(l.name);let h=La.findNode(t,c.nodeName);if(!h){const p=l.__objectName??l.name.substring(0,l.name.indexOf("."));if(h=t.getObjectByProperty("uuid",p)??null,!h)continue}let d=n(h)||n(t);if(!d){const p=C.get("Animation");if(d=t.addComponent(p),!d){console.error("Failed creating Animation component: No 'Animation' component found in TypeStore");break}}i.push(d),d.addClip&&d.addClip(r)}}return i;function n(s){if(!s)return null;const r=s.userData?.components;if(r&&r.length>0)for(let a=0;a<r.length;a++){const l=r[a];if(l.isAnimationComponent===!0)return l}return n(s.parent)}}static emptyClip(){return new Ri("empty",0,[])}static createScaleClip(e){const t=e?.duration??.3;let i={x:1,y:1,z:1};e?.scale!==void 0&&(typeof e.scale=="number"?i={x:e.scale,y:e.scale,z:e.scale}:i=e.scale);const n=e?.type??"linear",s=e?.scaleFactor??1.2,r=new Array,a=new Array;switch(n){case"linear":r.push(0,t),a.push(i.x,i.y,i.z,i.x*s,i.y*s,i.z*s);break;case"spring":r.push(0,t*.3,t*.5,t*.7,t*.9,t),a.push(i.x,i.y,i.z,i.x*s,i.y*s,i.z*s,i.x*.9,i.y*.9,i.z*.9,i.x*1.05,i.y*1.05,i.z*1.05,i.x*.98,i.y*.98,i.z*.98,i.x,i.y,i.z);break}const l=new rC(".scale",r,a);return new Ri("scale",r[r.length-1],[l])}}const qe=function(o){return u(o)},u=function(o){if(o===void 0&&(o=null),!Array.isArray(o))o=X_(o);else for(let e=0;e<o.length;e++){const t=o[e];o[e]=X_(t)}return function(e,t){if(!e){const n=typeof t=="string"?t:t.name;console.warn(`@serializable without a target at '${n}'.`);return}typeof t!="string"&&(t=t.name),Object.getOwnPropertyDescriptor(e,"$serializedTypes")||(e.$serializedTypes={});const i=e.$serializedTypes=e.$serializedTypes||{};i[t]=o}};function X_(o){switch(o?.prototype?.constructor?.name){case"Number":case"String":case"Boolean":return null}return o}const Q_=w("debugcomponentevents");class Jd{static eventListeners=new Map;static addComponentLifecylceEventListener(e,t){this.eventListeners.has(e)&&this.eventListeners.set(e,[]);let i=this.eventListeners.get(e);i||(i=[]),i.push(t),this.eventListeners.set(e,i),Q_&&console.log("Added event listener for "+e,this.eventListeners)}static removeComponentLifecylceEventListener(e,t){const i=this.eventListeners.get(e);if(!i)return;const n=i.indexOf(t);n<0||i.splice(n,1)}static dispatchComponentLifecycleEvent(e,t){const i=this.eventListeners.get(e);if(Q_&&console.log("Dispatching event "+e,i),!!i)for(const n of i)n(t)}}const Y_=w("debugdefines");Ps('if(!globalThis["NEEDLE_ENGINE_VERSION"]) globalThis["NEEDLE_ENGINE_VERSION"] = "0.0.0";'),Ps('if(!globalThis["NEEDLE_ENGINE_GENERATOR"]) globalThis["NEEDLE_ENGINE_GENERATOR"] = "unknown";'),Ps('if(!globalThis["NEEDLE_PROJECT_BUILD_TIME"]) globalThis["NEEDLE_PROJECT_BUILD_TIME"] = "unknown";'),Ps('if(!globalThis["NEEDLE_PUBLIC_KEY"]) globalThis["NEEDLE_PUBLIC_KEY"] = "unknown";'),Ps('globalThis["__NEEDLE_ENGINE_VERSION__"] = "5.1.0-experimental.2";'),Ps('globalThis["__NEEDLE_ENGINE_GENERATOR__"] = "undefined";'),Ps('globalThis["__NEEDLE_PROJECT_BUILD_TIME__"] = "Mon Mar 30 2026 13:22:23 GMT+0700 (Indochina Time)";'),Ps('globalThis["__NEEDLE_PUBLIC_KEY__"] = "npk_ad8e492e31253a2800d563522e42a7311d0d7b766ac4ec1f64d3b425f06eacbd";');const mi="5.1.0-experimental.2",$a="undefined",Sc="Mon Mar 30 2026 13:22:23 GMT+0700 (Indochina Time)";Y_&&console.log(`Engine version: ${mi} (generator: ${$a})
144
144
  Project built at ${Sc}`);const Rr="npk_ad8e492e31253a2800d563522e42a7311d0d7b766ac4ec1f64d3b425f06eacbd",Yn="needle_isActiveInHierarchy",Er="builtin_components",Cc="needle_editor_guid";function Ps(o){try{(0,eval)(o)}catch(e){Y_&&console.error(e)}}const Og={experimentalSmartHierarchyUpdate:!1},Di=Symbol("shadowDomOwner"),Ik=w("debugpatch");function eu(o,e,t,i){const n=Ik===e;if(!t&&!i)return;const s=e+"___needle";Dk(o,e,t,i);const r=Object.getOwnPropertyDescriptor(o,e),a=o[e];n&&console.log("Patch",o.constructor.name,e,r,a),r?(n&&console.log("Apply patch with existing descriptor",o.constructor.name,e,r),typeof r.value=="function"&&(o[e]=K_(r.value,o,e))):(n&&console.log("Create patch with new property",o.constructor.name,e,r),Object.defineProperty(o,e,{set:function(l){if(typeof l=="function")this[s]=K_(l,o,e);else{const c=this[s];J_(o,e,this,c,l),this[s]=l,ev(o,e,this,c,l)}},get:function(){const l=this[s];return typeof l=="function"&&l[s]?l[s]:l}}))}function Lk(o,e,t){const i=Mg(o,e);if(i)for(let n=i.length-1;n>=0;n--){const s=i[n];s.prefix===t&&(s.prefix=null),s.postfix===t&&(s.postfix=null),!s.prefix&&!s.postfix&&i.splice(n,1)}}const Z_=Symbol("Needle:Patches:WrappedFunction");function K_(o,e,t){if(o[Z_])return o;const i=function(...n){J_(e,t,this,...n);const s=o.apply(this,n);return ev(e,t,this,s,...n),s};return i[Z_]=!0,i}const tu="Needle:Patches";function kg(){return globalThis[tu]||(globalThis[tu]=new WeakMap),globalThis[tu]}function Mg(o,e){const t=kg().get(o);return t?t.get(e):null}function Dk(o,e,t,i){let n=kg().get(o);n||(n=new Map,kg().set(o,n));let s=n.get(e);s||(s=[],n.set(e,s)),s.push({prefix:t,postfix:i})}function J_(o,e,t,...i){if(!t)return;const n=Mg(o,e);if(n)for(const s of n)s.prefix?.call(t,...i)}function ev(o,e,t,i,...n){if(!t)return;const s=Mg(o,e);if(s)for(const r of s)r.postfix?.call(t,i,...n)}function jk(o,e){if(typeof window!==void 0&&window.SPECTOR){console.log(window.SPECTOR);const t=new URLSearchParams(window.location.search);if(t.has("spector")){let i=function(){if(n>o.time.frame)return window.requestAnimationFrame(()=>i());const r=s.captureCanvas(e);r&&r instanceof Promise?r.then(()=>s.displayUI()):s.displayUI()};const n=Number.parseInt(t.get("spector")||"0")||0;console.log("Scheduled Spector capture at frame #"+n);const s=new window.SPECTOR.Spector;s.spyCanvases=!0,i();return}else A()&&console.debug("Spector available: Add '?spector=<frame>' to the URL to enable it and capture a frame.")}}function tv(o){const e=o;return!!(e.parser&&e.parser.json)}var iu=(o=>(o[o.None=0]="None",o[o.DontExport=1]="DontExport",o))(iu||{});const iv=Symbol("component-name");function Rg(o){return o&&o.isComponent}const Bk=Symbol("object"),Eg=new Ii(()=>new b,20);class nv{_point;_normal;_tangentVelocity;distance;impulse;friction;get point(){return Eg.get().set(this._point.x,this._point.y,this._point.z)}get normal(){return Eg.get().set(this._normal.x,this._normal.y,this._normal.z)}get tangentVelocity(){return Eg.get().set(this._tangentVelocity.x,this._tangentVelocity.y,this._tangentVelocity.z)}constructor(e,t,i,n,s,r){this._point=e,this.distance=t,this._normal=i,this.impulse=n,this.friction=s,this._tangentVelocity=r}}class ov{contacts;constructor(e,t,i){this.me=e,this._collider=t,this._gameObject=t.gameObject,this.contacts=i}me;_collider;get collider(){return this._collider}_gameObject;get gameObject(){return this._gameObject}get rigidBody(){return this.collider?.attachedRigidbody}}class sv{object;collider;constructor(e,t){this.object=e,this.collider=t}}class Rm{constructor(e){this.context=e,this.root.style.cssText=`
145
145
  position: absolute;
146
146
  width: 1px; height: 1px;
@@ -271,8 +271,8 @@ TEX `+i.texture_lod;if(Kg=="density"&&(g+=`
271
271
  `+(f/n.lastScreenCoverage).toFixed(0)+` dens
272
272
  `+(n.lastScreenCoverage*100).toFixed(1)+`% cov
273
273
  `+(n.lastCentrality*100).toFixed(1)+`% centr
274
- `+(pu.min.x.toFixed(2)+"-"+pu.max.x.toFixed(2)+"x"+pu.min.y.toFixed(2)+"-"+pu.max.y.toFixed(2))+" scr"),n.lastScreenCoverage>.1){const y=e,_=y.worldForward,v=y.worldPosition,P=F(_).multiplyScalar(c*.7).add(l),k=P.distanceTo(v),O=h[Math.min(h.length-1,Math.max(0,s))]+"88",j=this.context.domHeight>0?screen.height/this.context.domHeight:1,L=e.isPerspectiveCamera?Math.tan(e.fov*Math.PI/180/2):1;B.DrawLabel(P,g,k*.012*j*L,void 0,16777215,O)}}}}}const Jg={};function ef(o,e){Jg[o]=e}function Vv(o){const e=o.getBufferIdentifier(),t=Jg[e];return t(o)}function $v(o){return typeof o.guid=="function"?o.guid():null}function Ec(o){const e=[],t={MODULE:void 0,MAYBEMODULE:null,ready(){return t.MODULE?Promise.resolve(t.MODULE):new Promise(i=>{e.push(i)})},async load(){if(t.MODULE)return t.MODULE;const i=await o();t.MODULE=i,t.MAYBEMODULE=i;for(const n of e)n(i);return e.length=0,i}};return t}const T={MaterialX:Ec(()=>import("./materialx-9KHBidZa.min.js")),RAPIER_PHYSICS:Ec(()=>import("./rapier-DJ-luMxr.min.js")),POSTPROCESSING:Ec(()=>import("./postprocessing-BZfyAdCY.min.js").then(o=>o.index)),POSTPROCESSING_AO:Ec(()=>import("./postprocessing-BZfyAdCY.min.js").then(o=>o.N8AO)),PEERJS:Ec(()=>import("./vendor-BgzAK9of.min.js").then(o=>o.bundler))};let tf;function wM(){return tf}function xM(o){tf=o}async function Hv(o,e){const t=(await T.PEERJS.load()).default;return e||(e={}),e={...tf,...e},o?new t(o,e):new t(e)}async function Gv(){const o=await T.PEERJS.load();return o.default===void 0?o:o.default}class qv{get isHost(){return this._host!==void 0}_host;_client;_clientData;constructor(){this.onEnable()}onEnable(){this.trySetupHost("HOST-5980e65c-8438-453e-8b35-f13c736dcd81")}async trySetupHost(e){const t=await Gv(),i=new t(e);i.on("error",n=>{console.error(n),this._host=void 0,this.trySetupClient(e)}),i.on("open",n=>{this._host=new CM(i)})}async trySetupClient(e){const t=await Gv();this._client=new t,this._client.on("error",i=>{console.error("Client error",i)}),this._client.on("open",i=>{console.log("client connected",i),this._clientData=this._client.connect(e,{metadata:{id:i}}),this._clientData.on("open",()=>{console.log("Connected to host")}),this._clientData.on("data",n=>{console.log("<<",n)})})}}class SM{_peer;constructor(e){this._peer=e}}class CM extends SM{get isHost(){return!0}_connections=[];constructor(e){super(e),console.log("I AM THE HOST"),this._peer?.on("connection",this.onConnection.bind(this)),this._peer.on("close",()=>{this.broadcast("BYE")}),setInterval(()=>{this.broadcast("HELLO")},2e3)}onConnection(e){console.log("host connection",e),e.on("open",()=>{this._connections.push(e),this.broadcastConnection(e)})}broadcastConnection(e){const t=this._connections.map(i=>i.metadata?.id).filter(i=>i!==void 0);this.broadcast({type:"connection-list",connections:t})}broadcast(e){if(e!=null){console.log(">>",e);for(const t in this._peer.connections){const i=this._peer.connections[t];if(i)if(Array.isArray(i))for(const n of i)n&&n.send(e);else console.warn(i)}}}}const Xv="https://urls.needle.tools/default-networking-backend/index";let Zi="wss://networking-2.needle.tools/socket";const yi=!!w("debugnet"),Tc=!!(yi||w("debugowner")),gu=w("debugnetbin");var Qv=(o=>(o.ConnectionInfo="connection-start-info",o))(Qv||{}),ie=(o=>(o.Join="join-room",o.Leave="leave-room",o.JoinedRoom="joined-room",o.LeftRoom="left-room",o.UserJoinedRoom="user-joined-room",o.UserLeftRoom="user-left-room",o.RoomStateSent="room-state-sent",o))(ie||{});class PM{room;viewId;allowEditing;inRoom}class OM{room}class kM{userId}var Yv=(o=>(o.RequestHasOwner="request-has-owner",o.ResponseHasOwner="response-has-owner",o.RequestIsOwner="request-is-owner",o.ResponseIsOwner="response-is-owner",o.RequestOwnership="request-ownership",o.GainedOwnership="gained-ownership",o.RemoveOwnership="remove-ownership",o.LostOwnership="lost-ownership",o.GainedOwnershipBroadcast="gained-ownership-broadcast",o.LostOwnershipBroadcast="lost-ownership-broadcast",o))(Yv||{});class nf{guid;connection;get hasOwnership(){return this._hasOwnership}get isOwned(){return this._isOwned}get isConnected(){return this.connection.isConnected}_hasOwnership=!1;_isOwned=void 0;_gainSubscription;_lostSubscription;_hasOwnerResponse;constructor(e,t){this.connection=e,this.guid=t,this._gainSubscription=this.onGainedOwnership.bind(this),this._lostSubscription=this.onLostOwnership.bind(this),e.beginListen("lost-ownership",this._lostSubscription),e.beginListen("gained-ownership-broadcast",this._gainSubscription),this._hasOwnerResponse=this.onHasOwnerResponse.bind(this),e.beginListen("response-has-owner",this._hasOwnerResponse)}_isWaitingForOwnershipResponseCallback=null;updateIsOwned(){this.connection.send("request-has-owner",{guid:this.guid})}onHasOwnerResponse(e){e.guid===this.guid&&(this._isOwned=e.value)}requestOwnershipIfNotOwned(){return this._isWaitingForOwnershipResponseCallback!==null?this:(this._isWaitingForOwnershipResponseCallback=this.waitForHasOwnershipRequestResponse.bind(this),this.connection.beginListen("response-has-owner",this._isWaitingForOwnershipResponseCallback),this.connection.send("request-has-owner",{guid:this.guid}),this)}waitForHasOwnershipRequestResponse(e){e.guid===this.guid&&(this._isWaitingForOwnershipResponseCallback&&(this.connection.stopListen("response-has-owner",this._isWaitingForOwnershipResponseCallback),this._isWaitingForOwnershipResponseCallback=null),this._isOwned=e.value,e.value||(Tc&&console.log("request ownership",this.guid),this.requestOwnership()))}requestOwnershipAsync(){return new Promise((e,t)=>{this.requestOwnership();let i=0;const n=()=>{if(i++>10)return t("Timeout");setTimeout(()=>{this.hasOwnership?e(this):n()},100)};n()})}requestOwnership(){return Tc&&console.log("Request ownership",this.guid),this.connection.send("request-ownership",{guid:this.guid}),this}freeOwnership(){return this.connection.send("remove-ownership",{guid:this.guid}),this._isWaitingForOwnershipResponseCallback&&(this.connection.stopListen("response-has-owner",this._isWaitingForOwnershipResponseCallback),this._isWaitingForOwnershipResponseCallback=null),this}destroy(){this.connection.stopListen("gained-ownership",this._gainSubscription),this.connection.stopListen("lost-ownership",this._lostSubscription),this.connection.stopListen("response-has-owner",this._hasOwnerResponse),this._isWaitingForOwnershipResponseCallback&&(this.connection.stopListen("response-has-owner",this._isWaitingForOwnershipResponseCallback),this._isWaitingForOwnershipResponseCallback=null)}onGainedOwnership(e){e.guid===this.guid&&(this._isOwned=!0,this.connection.connectionId===e.owner?(Tc&&console.log("GAINED OWNERSHIP",this.guid),this._hasOwnership=!0):this._hasOwnership=!1)}onLostOwnership(e){e===this.guid&&(Tc&&console.log("LOST OWNERSHIP",this.guid),this._hasOwnership=!1,this._isOwned=!1)}}class Zv{context;_peer=null;constructor(e){this.context=e}get peer(){return this._peer||(this._peer=new qv),this._peer}tryGetState(e){return e==="invalid"?null:this._state[e]}get connectionId(){return this._connectionId}get isDebugEnabled(){return yi}get isConnected(){return this.connected}get currentRoomName(){return this._currentRoomName}get allowEditing(){return this._currentRoomAllowEditing}get currentRoomViewId(){return this._currentRoomViewId}getViewOnlyUrl(){if(this.currentRoomViewId===null)return null;const e=new URL(window.location.href);return e.searchParams.set("view",this.currentRoomViewId),e.href}get isInRoom(){return this._isInRoom}get currentLatency(){return this._currentDelay}get currentServerUrl(){return this._ws?.url??null}sendPing(){this.send("ping",{time:this.context.time.time})}userIsInRoom(e){return this._currentInRoom.indexOf(e)!==-1}_usersInRoomCopy=[];usersInRoom(e=null){e||(e=this._usersInRoomCopy),e.length=0;for(const t of this._currentInRoom)e.push(t);return e}joinRoom(e,t=!1){return e?e.length>1024?(console.error('Room name too long, can not join: "'+e+'". Max length is 1024 characters.'),!1):(this.isInRoom&&this.currentRoomName!==e&&console.warn("Needle Engine is already connected to a networking room. Connecting to multiple rooms is not supported"),this.connect(),yi&&console.log("join: "+e),this.send("join-room",{room:e,viewOnly:t},Mn.OnConnection),!0):(console.error('Missing room name, can not join: "'+e+'"'),!1)}leaveRoom(e=null){return e||(e=this.currentRoomName),e?(this.send("leave-room",{room:e}),!0):(console.error('Missing room name, can not join: "'+e+'"'),!1)}send(e,t=null,i=Mn.Queued){if(t===null&&(t={}),i===Mn.Queued){this._defaultMessagesBuffer.push({key:e,value:t});return}return this.sendWithWebsocket(e,t,i)}sendDeleteRemoteState(e){this.send("delete-state",{guid:e,dontSave:!0}),delete this._state[e]}sendDeleteRemoteStateAll(){this.send("delete-all-state"),this._state={}}sendBinary(e){gu&&console.log("<< send binary",this.context.time.frame,e.length/1024+" KB"),this._ws?.send(e)}_defaultMessagesBuffer=[];_defaultMessagesBufferArray=[];sendBufferedMessagesNow(){if(!this._ws)return;this._defaultMessagesBufferArray.length=0;const e=Object.keys(this._defaultMessagesBuffer).length;for(const i in this._defaultMessagesBuffer){const n=this._defaultMessagesBuffer[i];if(e<=1){this.sendWithWebsocket(n.key,n.value,Mn.Immediate);break}const s=this.toMessage(n.key,n.value);this._defaultMessagesBufferArray.push(s)}if(this._defaultMessagesBuffer.length=0,this._defaultMessagesBufferArray.length>0&&yi&&console.log("SEND BUFFERED",this._defaultMessagesBufferArray.length),this._defaultMessagesBufferArray.length<=0)return;const t=JSON.stringify(this._defaultMessagesBufferArray);this._ws?.send(t)}beginListen(e,t){return this._listeners[e]||(this._listeners[e]=[]),this._listeners[e].push(t),t}stopListening(e,t){return this.stopListen(e,t)}stopListen(e,t){if(!t||!this._listeners[e])return;const i=this._listeners[e].indexOf(t);i>=0&&this._listeners[e].splice(i,1)}beginListenBinary(e,t){return this._listenersBinary[e]||(this._listenersBinary[e]=[]),this._listenersBinary[e].push(t),t}stopListenBinary(e,t){if(!this._listenersBinary[e])return;const i=this._listenersBinary[e].indexOf(t);i>=0&&this._listenersBinary[e].splice(i,1)}netWebSocketUrlProvider;registerProvider(e){this.netWebSocketUrlProvider=e}async connect(e){if(this.connected&&e&&e!==Zi)return Promise.reject("Can not connect to different server url. Please disconnect first.");if(this.connected)return Promise.resolve(!0);e&&console.debug("Connecting to user provided url "+e);const t=e||this.netWebSocketUrlProvider?.getWebsocketUrl();return t?Zi=t:o_()&&(Zi="wss://"+window.location.host+"/socket"),this.connectWebsocket()}disconnect(){this._ws?.close(),this._ws=void 0,Zi=void 0,this._currentRoomAllowEditing=!0,this._currentRoomName=null,this._currentRoomViewId=null,this._isInRoom=!1,this._currentInRoom.length=0,this._state={},this._currentDelay=-1}_listeners={};_listenersBinary={};connected=!1;channelId;_connectionId=null;_ws;_waitingForSocket={};_isInRoom=!1;_currentRoomName=null;_currentRoomViewId=null;_currentRoomAllowEditing=!0;_currentInRoom=[];_state={};_currentDelay=-1;_connectingToWebsocketPromise=null;connectWebsocket(){return this._connectingToWebsocketPromise?this._connectingToWebsocketPromise:this._connectingToWebsocketPromise=new Promise(async(e,t)=>{let i=!1;const n=c=>{i||(i=!0,e(c))};if(Zi===void 0&&(console.log("Fetch default backend url: "+Xv),Zi=await(await fetch(Xv)).text()),Zi===void 0){n(!1);return}console.debug(`Connecting to networking backend on
275
- `+Zi);const s=await import("./vendor-BgzAK9of.min.js").then(c=>c.index),r=s.default?.WebsocketBuilder??s.WebsocketBuilder,a=s.default?.ExponentialBackoff??s.ExponentialBackoff,l=new r(Zi).withMaxRetries(10).withBackoff(new a(2e3,4)).onOpen(()=>{this._connectingToWebsocketPromise=null,this._ws=l,this.connected=!0,A()||yi?console.log(`Connected to networking backend
274
+ `+(pu.min.x.toFixed(2)+"-"+pu.max.x.toFixed(2)+"x"+pu.min.y.toFixed(2)+"-"+pu.max.y.toFixed(2))+" scr"),n.lastScreenCoverage>.1){const y=e,_=y.worldForward,v=y.worldPosition,P=F(_).multiplyScalar(c*.7).add(l),k=P.distanceTo(v),O=h[Math.min(h.length-1,Math.max(0,s))]+"88",j=this.context.domHeight>0?screen.height/this.context.domHeight:1,L=e.isPerspectiveCamera?Math.tan(e.fov*Math.PI/180/2):1;B.DrawLabel(P,g,k*.012*j*L,void 0,16777215,O)}}}}}const Jg={};function ef(o,e){Jg[o]=e}function Vv(o){const e=o.getBufferIdentifier(),t=Jg[e];return t(o)}function $v(o){return typeof o.guid=="function"?o.guid():null}function Ec(o){const e=[],t={MODULE:void 0,MAYBEMODULE:null,ready(){return t.MODULE?Promise.resolve(t.MODULE):new Promise(i=>{e.push(i)})},async load(){if(t.MODULE)return t.MODULE;const i=await o();t.MODULE=i,t.MAYBEMODULE=i;for(const n of e)n(i);return e.length=0,i}};return t}const T={MaterialX:Ec(()=>import("./materialx-9KHBidZa.min.js")),RAPIER_PHYSICS:Ec(()=>import("./rapier-DJ-luMxr.min.js")),POSTPROCESSING:Ec(()=>import("./postprocessing-BZfyAdCY.min.js").then(o=>o.index)),POSTPROCESSING_AO:Ec(()=>import("./postprocessing-BZfyAdCY.min.js").then(o=>o.N8AO)),PEERJS:Ec(()=>import("./vendor-Bf43L3CE.min.js").then(o=>o.bundler))};let tf;function wM(){return tf}function xM(o){tf=o}async function Hv(o,e){const t=(await T.PEERJS.load()).default;return e||(e={}),e={...tf,...e},o?new t(o,e):new t(e)}async function Gv(){const o=await T.PEERJS.load();return o.default===void 0?o:o.default}class qv{get isHost(){return this._host!==void 0}_host;_client;_clientData;constructor(){this.onEnable()}onEnable(){this.trySetupHost("HOST-5980e65c-8438-453e-8b35-f13c736dcd81")}async trySetupHost(e){const t=await Gv(),i=new t(e);i.on("error",n=>{console.error(n),this._host=void 0,this.trySetupClient(e)}),i.on("open",n=>{this._host=new CM(i)})}async trySetupClient(e){const t=await Gv();this._client=new t,this._client.on("error",i=>{console.error("Client error",i)}),this._client.on("open",i=>{console.log("client connected",i),this._clientData=this._client.connect(e,{metadata:{id:i}}),this._clientData.on("open",()=>{console.log("Connected to host")}),this._clientData.on("data",n=>{console.log("<<",n)})})}}class SM{_peer;constructor(e){this._peer=e}}class CM extends SM{get isHost(){return!0}_connections=[];constructor(e){super(e),console.log("I AM THE HOST"),this._peer?.on("connection",this.onConnection.bind(this)),this._peer.on("close",()=>{this.broadcast("BYE")}),setInterval(()=>{this.broadcast("HELLO")},2e3)}onConnection(e){console.log("host connection",e),e.on("open",()=>{this._connections.push(e),this.broadcastConnection(e)})}broadcastConnection(e){const t=this._connections.map(i=>i.metadata?.id).filter(i=>i!==void 0);this.broadcast({type:"connection-list",connections:t})}broadcast(e){if(e!=null){console.log(">>",e);for(const t in this._peer.connections){const i=this._peer.connections[t];if(i)if(Array.isArray(i))for(const n of i)n&&n.send(e);else console.warn(i)}}}}const Xv="https://urls.needle.tools/default-networking-backend/index";let Zi="wss://networking-2.needle.tools/socket";const yi=!!w("debugnet"),Tc=!!(yi||w("debugowner")),gu=w("debugnetbin");var Qv=(o=>(o.ConnectionInfo="connection-start-info",o))(Qv||{}),ie=(o=>(o.Join="join-room",o.Leave="leave-room",o.JoinedRoom="joined-room",o.LeftRoom="left-room",o.UserJoinedRoom="user-joined-room",o.UserLeftRoom="user-left-room",o.RoomStateSent="room-state-sent",o))(ie||{});class PM{room;viewId;allowEditing;inRoom}class OM{room}class kM{userId}var Yv=(o=>(o.RequestHasOwner="request-has-owner",o.ResponseHasOwner="response-has-owner",o.RequestIsOwner="request-is-owner",o.ResponseIsOwner="response-is-owner",o.RequestOwnership="request-ownership",o.GainedOwnership="gained-ownership",o.RemoveOwnership="remove-ownership",o.LostOwnership="lost-ownership",o.GainedOwnershipBroadcast="gained-ownership-broadcast",o.LostOwnershipBroadcast="lost-ownership-broadcast",o))(Yv||{});class nf{guid;connection;get hasOwnership(){return this._hasOwnership}get isOwned(){return this._isOwned}get isConnected(){return this.connection.isConnected}_hasOwnership=!1;_isOwned=void 0;_gainSubscription;_lostSubscription;_hasOwnerResponse;constructor(e,t){this.connection=e,this.guid=t,this._gainSubscription=this.onGainedOwnership.bind(this),this._lostSubscription=this.onLostOwnership.bind(this),e.beginListen("lost-ownership",this._lostSubscription),e.beginListen("gained-ownership-broadcast",this._gainSubscription),this._hasOwnerResponse=this.onHasOwnerResponse.bind(this),e.beginListen("response-has-owner",this._hasOwnerResponse)}_isWaitingForOwnershipResponseCallback=null;updateIsOwned(){this.connection.send("request-has-owner",{guid:this.guid})}onHasOwnerResponse(e){e.guid===this.guid&&(this._isOwned=e.value)}requestOwnershipIfNotOwned(){return this._isWaitingForOwnershipResponseCallback!==null?this:(this._isWaitingForOwnershipResponseCallback=this.waitForHasOwnershipRequestResponse.bind(this),this.connection.beginListen("response-has-owner",this._isWaitingForOwnershipResponseCallback),this.connection.send("request-has-owner",{guid:this.guid}),this)}waitForHasOwnershipRequestResponse(e){e.guid===this.guid&&(this._isWaitingForOwnershipResponseCallback&&(this.connection.stopListen("response-has-owner",this._isWaitingForOwnershipResponseCallback),this._isWaitingForOwnershipResponseCallback=null),this._isOwned=e.value,e.value||(Tc&&console.log("request ownership",this.guid),this.requestOwnership()))}requestOwnershipAsync(){return new Promise((e,t)=>{this.requestOwnership();let i=0;const n=()=>{if(i++>10)return t("Timeout");setTimeout(()=>{this.hasOwnership?e(this):n()},100)};n()})}requestOwnership(){return Tc&&console.log("Request ownership",this.guid),this.connection.send("request-ownership",{guid:this.guid}),this}freeOwnership(){return this.connection.send("remove-ownership",{guid:this.guid}),this._isWaitingForOwnershipResponseCallback&&(this.connection.stopListen("response-has-owner",this._isWaitingForOwnershipResponseCallback),this._isWaitingForOwnershipResponseCallback=null),this}destroy(){this.connection.stopListen("gained-ownership",this._gainSubscription),this.connection.stopListen("lost-ownership",this._lostSubscription),this.connection.stopListen("response-has-owner",this._hasOwnerResponse),this._isWaitingForOwnershipResponseCallback&&(this.connection.stopListen("response-has-owner",this._isWaitingForOwnershipResponseCallback),this._isWaitingForOwnershipResponseCallback=null)}onGainedOwnership(e){e.guid===this.guid&&(this._isOwned=!0,this.connection.connectionId===e.owner?(Tc&&console.log("GAINED OWNERSHIP",this.guid),this._hasOwnership=!0):this._hasOwnership=!1)}onLostOwnership(e){e===this.guid&&(Tc&&console.log("LOST OWNERSHIP",this.guid),this._hasOwnership=!1,this._isOwned=!1)}}class Zv{context;_peer=null;constructor(e){this.context=e}get peer(){return this._peer||(this._peer=new qv),this._peer}tryGetState(e){return e==="invalid"?null:this._state[e]}get connectionId(){return this._connectionId}get isDebugEnabled(){return yi}get isConnected(){return this.connected}get currentRoomName(){return this._currentRoomName}get allowEditing(){return this._currentRoomAllowEditing}get currentRoomViewId(){return this._currentRoomViewId}getViewOnlyUrl(){if(this.currentRoomViewId===null)return null;const e=new URL(window.location.href);return e.searchParams.set("view",this.currentRoomViewId),e.href}get isInRoom(){return this._isInRoom}get currentLatency(){return this._currentDelay}get currentServerUrl(){return this._ws?.url??null}sendPing(){this.send("ping",{time:this.context.time.time})}userIsInRoom(e){return this._currentInRoom.indexOf(e)!==-1}_usersInRoomCopy=[];usersInRoom(e=null){e||(e=this._usersInRoomCopy),e.length=0;for(const t of this._currentInRoom)e.push(t);return e}joinRoom(e,t=!1){return e?e.length>1024?(console.error('Room name too long, can not join: "'+e+'". Max length is 1024 characters.'),!1):(this.isInRoom&&this.currentRoomName!==e&&console.warn("Needle Engine is already connected to a networking room. Connecting to multiple rooms is not supported"),this.connect(),yi&&console.log("join: "+e),this.send("join-room",{room:e,viewOnly:t},Mn.OnConnection),!0):(console.error('Missing room name, can not join: "'+e+'"'),!1)}leaveRoom(e=null){return e||(e=this.currentRoomName),e?(this.send("leave-room",{room:e}),!0):(console.error('Missing room name, can not join: "'+e+'"'),!1)}send(e,t=null,i=Mn.Queued){if(t===null&&(t={}),i===Mn.Queued){this._defaultMessagesBuffer.push({key:e,value:t});return}return this.sendWithWebsocket(e,t,i)}sendDeleteRemoteState(e){this.send("delete-state",{guid:e,dontSave:!0}),delete this._state[e]}sendDeleteRemoteStateAll(){this.send("delete-all-state"),this._state={}}sendBinary(e){gu&&console.log("<< send binary",this.context.time.frame,e.length/1024+" KB"),this._ws?.send(e)}_defaultMessagesBuffer=[];_defaultMessagesBufferArray=[];sendBufferedMessagesNow(){if(!this._ws)return;this._defaultMessagesBufferArray.length=0;const e=Object.keys(this._defaultMessagesBuffer).length;for(const i in this._defaultMessagesBuffer){const n=this._defaultMessagesBuffer[i];if(e<=1){this.sendWithWebsocket(n.key,n.value,Mn.Immediate);break}const s=this.toMessage(n.key,n.value);this._defaultMessagesBufferArray.push(s)}if(this._defaultMessagesBuffer.length=0,this._defaultMessagesBufferArray.length>0&&yi&&console.log("SEND BUFFERED",this._defaultMessagesBufferArray.length),this._defaultMessagesBufferArray.length<=0)return;const t=JSON.stringify(this._defaultMessagesBufferArray);this._ws?.send(t)}beginListen(e,t){return this._listeners[e]||(this._listeners[e]=[]),this._listeners[e].push(t),t}stopListening(e,t){return this.stopListen(e,t)}stopListen(e,t){if(!t||!this._listeners[e])return;const i=this._listeners[e].indexOf(t);i>=0&&this._listeners[e].splice(i,1)}beginListenBinary(e,t){return this._listenersBinary[e]||(this._listenersBinary[e]=[]),this._listenersBinary[e].push(t),t}stopListenBinary(e,t){if(!this._listenersBinary[e])return;const i=this._listenersBinary[e].indexOf(t);i>=0&&this._listenersBinary[e].splice(i,1)}netWebSocketUrlProvider;registerProvider(e){this.netWebSocketUrlProvider=e}async connect(e){if(this.connected&&e&&e!==Zi)return Promise.reject("Can not connect to different server url. Please disconnect first.");if(this.connected)return Promise.resolve(!0);e&&console.debug("Connecting to user provided url "+e);const t=e||this.netWebSocketUrlProvider?.getWebsocketUrl();return t?Zi=t:o_()&&(Zi="wss://"+window.location.host+"/socket"),this.connectWebsocket()}disconnect(){this._ws?.close(),this._ws=void 0,Zi=void 0,this._currentRoomAllowEditing=!0,this._currentRoomName=null,this._currentRoomViewId=null,this._isInRoom=!1,this._currentInRoom.length=0,this._state={},this._currentDelay=-1}_listeners={};_listenersBinary={};connected=!1;channelId;_connectionId=null;_ws;_waitingForSocket={};_isInRoom=!1;_currentRoomName=null;_currentRoomViewId=null;_currentRoomAllowEditing=!0;_currentInRoom=[];_state={};_currentDelay=-1;_connectingToWebsocketPromise=null;connectWebsocket(){return this._connectingToWebsocketPromise?this._connectingToWebsocketPromise:this._connectingToWebsocketPromise=new Promise(async(e,t)=>{let i=!1;const n=c=>{i||(i=!0,e(c))};if(Zi===void 0&&(console.log("Fetch default backend url: "+Xv),Zi=await(await fetch(Xv)).text()),Zi===void 0){n(!1);return}console.debug(`Connecting to networking backend on
275
+ `+Zi);const s=await import("./vendor-Bf43L3CE.min.js").then(c=>c.index),r=s.default?.WebsocketBuilder??s.WebsocketBuilder,a=s.default?.ExponentialBackoff??s.ExponentialBackoff,l=new r(Zi).withMaxRetries(10).withBackoff(new a(2e3,4)).onOpen(()=>{this._connectingToWebsocketPromise=null,this._ws=l,this.connected=!0,A()||yi?console.log(`Connected to networking backend
276
276
  `+Zi):console.debug("Connected to networking backend",Zi),n(!0),this.onSendQueued(Mn.OnConnection)}).onClose(c=>{this._connectingToWebsocketPromise=null,this.connected=!1,this._isInRoom=!1,n(!1);let h="Websocket connection closed...";Zi?.includes("/socket")||(h+=' Do you perhaps mean to connect to "/socket"?'),console.error(h)}).onError(c=>{console.error("Websocket connection failed..."),n(!1),gi.sendEvent(this.context,"networking",{event:"connection_error"})}).onRetry(()=>{console.log("Retry connecting to networking websocket")}).build();l.addEventListener(s.WebsocketEvent.message,(c,h)=>{this.onMessage(c,h)})})}onMessage(e,t){const i=t.data;try{if(typeof i!="string"){i.size&&this.handleIncomingBinaryMessage(i);return}const n=JSON.parse(i);if(Array.isArray(n))for(const s of n)this.handleIncomingStringMessage(s);else this.handleIncomingStringMessage(n);return}catch(n){yi&&i==="pong"?console.log("<<",i):A()&&console.error("Failed to parse message",n)}}async handleIncomingBinaryMessage(e){gu&&console.log("<< bin",this.context.time.frame);const t=await e.arrayBuffer();var i=new Uint8Array(t);const n=new $P(i),s=n.getBufferIdentifier(),r=this._listenersBinary[s],a=Vv(n),l=$v(a);if(l&&typeof l=="string"&&(this._state[l]=a),!r)return;const c=a??n;for(const h of r)h(c)}handleIncomingStringMessage(e){if(yi&&console.log("<<",e.key??e),e.key)switch(e.key){case"connection-start-info":if(e.data){const r=e.data;r&&(console.assert(r.id!==void 0&&r.id!==null&&r.id.length>0,"server did not send connection id",r.id),console.debug("Your id is: "+r.id,this.context.alias??""),this._connectionId=r.id,gi.sendEvent(this.context,"networking",{event:"connected"}))}else console.warn("Expected connection id in "+e.key);break;case"joined-room":if(yi&&console.log(e),e){this._isInRoom=!0;const r=e;this._currentRoomName=r.room,this._currentRoomViewId=r.viewId,this._currentRoomAllowEditing=r.allowEditing??!0,this._currentInRoom.length=0,this._currentInRoom.push(...r.inRoom),(gu||A())&&console.debug("Joined Needle Engine Room: "+r.room);const a=new URL(window.location.href);a.searchParams.has("room")&&a.searchParams.delete("room"),a.searchParams.set("view",this._currentRoomViewId),console.debug(`Room view id: ${this._currentRoomViewId}
277
277
  ${a.href}`)}this.onSendQueued(Mn.OnRoomJoin),gi.sendEvent(this.context,"networking",{event:"joined_room",room:this._currentRoomName});break;case"left-room":const n=e;n.room===this.currentRoomName&&(this._isInRoom=!1,this._currentRoomName=null,this._currentRoomAllowEditing=!0,this._currentInRoom.length=0,(gu||A())&&console.debug("Left Needle Engine Room: "+n.room)),gi.sendEvent(this.context,"networking",{event:"left_room",room:n.room});break;case"user-joined-room":if(e.data){const r=e.data;this._currentInRoom.push(r.userId),yi&&console.log(r.userId+" joined","now in room:",this._currentInRoom)}break;case"user-left-room":if(e.data){const r=e.data,a=this._currentInRoom.indexOf(r.userId);a>=0&&(yi&&console.log(r.userId+" left","now in room:",this._currentInRoom),this._currentInRoom.splice(a,1)),r.userId===this.connectionId&&console.log("you left the room")}break;case"all-room-state-deleted":yi&&console.log("RECEIVED all-room-state-deleted"),this._state={};break;case"ping":case"pong":const s=e.data?.time;s&&(this._currentDelay=this.context.time.time-s),yi&&console.log(`Current latency: ${(this._currentDelay*1e3).toFixed()} ms`,"Clients in room: "+this._currentInRoom?.length);break}const t=e.data;t&&(this._state[t.guid]=t);let i=this._listeners[e.key];if(i){i=[...i];for(const n of i)try{n(e.data)}catch(s){console.error('Error invoking callback for "'+e.key+'"',s)}}}toMessage(e,t){return{key:e,data:t}}sendWithWebsocket(e,t,i=Mn.OnRoomJoin){if(!this._ws){const s=this._waitingForSocket[i]||[];s.push(()=>this.sendWithWebsocket(e,t,i)),this._waitingForSocket[i]=s;return}const n=JSON.stringify(this.toMessage(e,t));yi&&console.log(">>",e),this._ws.send(n)}onSendQueued(e){const t=this._waitingForSocket[e];if(t){for(const i of t)i();t.length=0}}}const MM=w("debugplayerview");var Uo=(o=>(o.Browser="browser",o.Headset="headset",o.Handheld="handheld",o))(Uo||{});class Kv{userId;context;viewDevice="browser";get currentObject(){return this._object}set currentObject(e){this._object=e}get isConnected(){return this.context.connection.userIsInRoom(this.userId)}removed=!1;_object;constructor(e,t){this.userId=e,this.context=t}}class Jv{context;playerViews=new Map;constructor(e){this.context=e}setPlayerView(e,t,i){let n=this.playerViews.get(e);n||(n=new Kv(e,this.context),this.playerViews.set(e,n)),n.viewDevice=i,n.currentObject=t,n.removed=!1}getPlayerView(e){if(!!e){if(!this.context.connection.userIsInRoom(e)){this.playerViews.delete(e);return}return this.playerViews.get(e)}}removePlayerView(e,t){const i=this.playerViews.get(e);i?.viewDevice===t&&(MM&&console.log("REMOVE",e),i.removed=!0,this.playerViews.delete(e))}}const Ac=new Uint8Array(4);Ac[0]=255,Ac[1]=255,Ac[2]=255,Ac[3]=255;const RM=new Lm(Ac,1,1,Ad);function of(o,e=1){const t="alpha"in o,i=e*e,n=new Uint8Array(4*i),s=Math.floor(o.r*255),r=Math.floor(o.g*255),a=Math.floor(o.b*255);for(let c=0;c<i;c++){const h=c*4;n[h+0]=s,n[h+1]=r,n[h+2]=a,t?n[h+3]=Math.floor(o.alpha*255):n[h+3]=255}const l=new Lm(n,e,e);return l.needsUpdate=!0,l}function EM(o,e,t,i=1,n=3){const s=i*n,r=[o,e,t],a=r.length,l=new Uint8Array(4*a*s),c=new oe;for(let d=0;d<n;d++){const p=Math.floor(d/n*a),m=D.clamp(p+1,0,a-1),f=r[p],g=r[m],y=d/n*a%1;c.lerpColors(f,g,y);const _=Math.floor(c.r*255),v=Math.floor(c.g*255),P=Math.floor(c.b*255);for(let k=0;k<i;k++){const O=(d*i+k)*4;l[O+0]=_,l[O+1]=v,l[O+2]=P,l[O+3]=255}}const h=new Lm(l,i,n);return h.needsUpdate=!0,h}function fu(o,e){const t=o.elements;e||(e=[]),e.length=0;for(let i=0;i<16;i+=4){const n=t[i],s=t[i+1],r=t[i+2],a=t[i+3],l=new ye(n,s,r,a);e.push(l)}return e}const sf=[],ew=[];function TM(o,e){if(sf.length===0)for(let t=0;t<27;t++)sf.push(0);e||(e=sf);for(let t=0;t<27;t++)ew[t]=e[t];e=ew,o.unity_SHAr={value:new ye(e[9],e[3],e[6],e[0])},o.unity_SHBr={value:new ye(e[12],e[15],e[18],e[21])},o.unity_SHAg={value:new ye(e[10],e[4],e[7],e[1])},o.unity_SHBg={value:new ye(e[13],e[16],e[19],e[22])},o.unity_SHAb={value:new ye(e[11],e[5],e[8],e[2])},o.unity_SHBb={value:new ye(e[14],e[17],e[20],e[23])},o.unity_SHC={value:new ye(e[24],e[25],e[26],1)}}class AM{vertexShader;fragmentShader;technique;constructor(e,t,i){this.vertexShader=e,this.fragmentShader=t,this.technique=i}}async function IM(o,e){if(!o)return console.error("Can not find technique: no shader data"),null;const t=o.programs[e],i=t.vertexShader,n=t.fragmentShader;if(i!==void 0&&n!==void 0){const s=o.shaders[i],r=o.shaders[n];if(s.uri&&r.uri||s.code&&r.code){if(!s.code&&s.uri&&await tw(s),!r.code&&r.uri&&await tw(r),!s.code||!r.code)return null;const a=o.techniques[e];return new AM(s.code,r.code,a)}}return console.error("Shader technique not found",e),null}async function tw(o){const e=o.uri;if(e)if(e.endsWith(".glsl")){const t=await new kb().loadAsync(e);o.code=t.toString()}else o.code=LM(o.uri)}function LM(o){return decodeURIComponent(Array.prototype.map.call(atob(o),function(e){return"%"+("00"+e.charCodeAt(0).toString(16)).slice(-2)}).join(""))}const Rn=w("debugenvlight");var Ka=(o=>(o[o.Skybox=0]="Skybox",o[o.Trilight=1]="Trilight",o[o.Flat=3]="Flat",o[o.Custom=4]="Custom",o))(Ka||{}),yu=(o=>(o[o.Skybox=0]="Skybox",o[o.Custom=1]="Custom",o))(yu||{});class iw{context;constructor(e){this.context=e,this.context.pre_update_callbacks.push(this.preUpdate.bind(this))}_currentLightSettingsId;_sceneLightSettings;get currentLightSettingsId(){return this._currentLightSettingsId}preUpdate(){const e=this.context.time;this._timevec4.x=e.time,this._timevec4.y=Math.sin(e.time),this._timevec4.z=Math.cos(e.time),this._timevec4.w=e.deltaTime}_timevec4=new ye;get timeVec4(){return this._timevec4}get environmentIntensity(){if(!this._sceneLightSettings||!this._currentLightSettingsId)return 1;const e=this._sceneLightSettings.get(this._currentLightSettingsId);return e?e.ambientIntensity:1}get sceneLightSettings(){return this._sceneLightSettings?.values()}enable(e){e instanceof ne&&(e=e.url);const t=this._sceneLightSettings?.get(e);return t?(Rn&&console.log("Enable scene light settings",e,t),e!==this._currentLightSettingsId&&this._currentLightSettingsId&&this.disable(this._currentLightSettingsId),this._currentLightSettingsId=e,t.enabled=!0,!0):(Rn&&console.warn("No light settings found for",e),!1)}disable(e){if(e instanceof ne&&(e=e.url),e==null)return!1;const t=this._sceneLightSettings?.get(e);return t?(Rn&&console.log("Disable scene light settings",e,t),t.enabled=!1,!0):!1}enableCurrent(){return this._currentLightSettingsId?(this.enable(this._currentLightSettingsId),this._currentLightSettingsId??null):null}disableCurrent(){if(this._currentLightSettingsId){const e=this._currentLightSettingsId;return this.disable(this._currentLightSettingsId),e}return null}internalRegisterSceneLightSettings(e){const t=e.sourceId;if(!t){console.error("Missing source id for scene light settings, can not register:",e);return}Rn&&console.log("Register "+e?.sourceId+" lighting",e),this._sceneLightSettings||(this._sceneLightSettings=new Map),this._sceneLightSettings.set(t,e)}internalUnregisterSceneLightSettings(e){const t=e.sourceId;if(!t){console.error("Missing source id for scene light settings, can not unregister:",e);return}Rn&&console.log("Unregister "+e?.sourceId+" lighting",e),this._sceneLightSettings&&this._sceneLightSettings.delete(t)}internalRegisterReflection(e,t){Rn&&console.log("Register reflection",e,t);const i=new nw(this.context,t,1);this._lighting[e]=i}internalGetReflection(e){return this._lighting[e]}__currentReflectionId=null;internalEnableReflection(e){this.__currentReflectionId=e;const t=this._sceneLightSettings?.get(e);switch(Rn&&console.log("Enable reflection",e,t?Ka[t.ambientMode]:"Unknown ambient mode",t),t?.ambientMode){case 0:case 4:const i=this.internalGetReflection(e);if(i&&i.Source){Rn&&console.log("Setting environment reflection",i);const n=this.context.scene,s=i.Source;return s.mapping!==Mo&&(s.mapping=Eo),n.environment=s,n.environmentIntensity=this.environmentIntensity||1,s}else Rn&&console.warn("Could not find reflection for source",e);break}if(t?.environmentReflectionSource===1)switch(t?.ambientMode){case 1:if(t.ambientTrilight){const i=t.ambientTrilight,n=EM(i[0],i[1],i[2],64,64);return n.colorSpace=To,n.mapping=Eo,this.context.scene.environment=n,n}else console.error("Missing ambient trilight",t.sourceId);case 3:if(t.ambientLight){const i=of(t.ambientLight,64);return i.colorSpace=To,i.mapping=Eo,this.context.scene.environment=i,i}else console.error("Missing ambientlight",t.sourceId)}return null}internalDisableReflection(e){if(e&&e!==this.__currentReflectionId){Rn&&console.log("Not disabling reflection for",e,"because it is not the current light settings id",this.__currentReflectionId);return}Rn&&console.log("Disable reflection",e);const t=this.context.scene;t.environment=null}_lighting={}}class nw{get Source(){return this._source}_source;constructor(e,t,i=1){this._source=t,t.mapping!==Mo&&(t.mapping=Eo)}}const ow=w("timescale");let rf=1;typeof ow=="number"&&(rf=ow);class sw{get time(){return this._time}set time(e){this._time=e}_time=0;get deltaTime(){return this._deltaTime}set deltaTime(e){this._deltaTime=e}_deltaTime=0;get deltaTimeUnscaled(){return this._deltaTimeUnscaled}_deltaTimeUnscaled=0;timeScale=1;get frame(){return this._frame}set frame(e){this._frame=e}_frame=0;get frameCount(){return this.frame}get realtimeSinceStartup(){return this.clock.getElapsed()}get fps(){return 1/this.deltaTime}get smoothedFps(){return this._smoothedFps}get smoothedDeltaTime(){return 1/this._smoothedFps}clock=new dC;_smoothedFps=0;_smoothedDeltaTime=0;_fpsSamples=[];_fpsSampleIndex=0;constructor(){typeof rf=="number"&&(this.timeScale=rf)}update(){this.clock.update(),this.deltaTime=this.clock.getDelta(),this.deltaTime=Math.min(.1,this.deltaTime),this._deltaTimeUnscaled=this.deltaTime,this.deltaTime<=0&&(this.deltaTime=1e-12),this.deltaTime*=this.timeScale,this.frame+=1,this.time+=this.deltaTime,this._fpsSamples.length<60?this._fpsSamples.push(this.deltaTime):this._fpsSamples[this._fpsSampleIndex++%60]=this.deltaTime;let e=0;for(let t=0;t<this._fpsSamples.length;t++)e+=this._fpsSamples[t];this._smoothedDeltaTime=e/this._fpsSamples.length,this._smoothedFps=1/this._smoothedDeltaTime}}let rw=!1;function aw(o){rw||(rw=!0,DM(),jM())}function DM(){const o=`
278
278
  float startCompression = 0.8;
@@ -876,7 +876,7 @@ Pinch: ${this.getGesture("pinch")?.value.toFixed(3)}`),i+=`
876
876
  Layout: `;for(const n of Object.keys(this._layout.components||{})){const s=this.getStick(n),r=this._layout.components[n]?.gamepadIndices,a=r?Object.entries(r).map(l=>l[0][0].toUpperCase()+l[0].slice(1)+"="+l[1]).join(","):"";i+=`
877
877
  ${n}: ${this._layout.components[n]?.type} [${a}] (${s.x.toPrecision(2)},${s.y.toPrecision(2)})`}}B.DrawLabel(e,i,.006)}onUpdateFrame(e){if(this._handJointPoses.clear(),this._hand_wristDotUp=void 0,!this.xr.referenceSpace||!this.inputSource.gamepad?.connected){this._isTracking=!1;return}const t=e.getPose(this.inputSource.targetRaySpace,this.xr.referenceSpace);this._isTracking=t!=null;let i=null,n=null,s=null,r=null;if(t){const h=t.transform;this._rayMatrix.fromArray(h.matrix).premultiply(ol),this._rayMatrix.decompose(this._rayPosition,this._rayQuaternion,F(1,1,1)),s=F(h.position),r=di(h.orientation),this._rayPositionRaw.copy(s),this._rayRotationRaw.copy(r)}if(this.inputSource.gripSpace){const h=e.getPose(this.inputSource.gripSpace,this.xr.referenceSpace);if(h){const d=h.transform;if(i=F(d.position),n=di(d.orientation),this._gripMatrix.fromArray(d.matrix).premultiply(ol),this._gripMatrix.decompose(this._gripPosition,this._gripQuaternion,F(1,1,1)),"linearVelocity"in h&&h.linearVelocity){const p=h.linearVelocity;this._linearVelocity.set(p.x,p.y,p.z)}}}this.xr.context.mainCamera?.parent&&(this._object.parent!==this.xr.context.mainCamera?.parent&&this.xr.context.mainCamera.parent.add(this._object),this._gripSpaceObject!==void 0&&this._gripSpaceObject?.parent!==this.xr.context.mainCamera?.parent&&this.xr.context.mainCamera.parent.add(this._gripSpaceObject),this._raySpaceObject!==void 0&&this._raySpaceObject?.parent!==this.xr.context.mainCamera?.parent&&this.xr.context.mainCamera.parent.add(this._raySpaceObject));const a=this.hand;if(a){let h=!1;const d=a.get("wrist"),p=d&&this.getHandJointPose(d,e);if(p){h=!0;const g=p.transform.position,y=p.transform.orientation;this._object.position.set(g.x,g.y,g.z),this._object.quaternion.set(y.x,y.y,y.z,y.w).multiply(Ki)}h||(this._object.position.copy(this._rayPosition),this._object.quaternion.copy(this._rayQuaternion).multiply(Ki));const m=a.get("middle-finger-metacarpal"),f=m&&this.getHandJointPose(m,e);f&&(this._gripMatrix.fromArray(f.transform.matrix).premultiply(ol),this._gripMatrix.decompose(this._gripPosition,this._gripQuaternion,F(1,1,1)),i=F().copy(f.transform.position),n=di().copy(f.transform.orientation),n.multiply(rR),i.add(F(aR).applyQuaternion(n)))}else this.inputSource.gripSpace&&this.targetRayMode==="transient-pointer"&&i&&n?(this._object.position.copy(i),this._object.quaternion.copy(n).multiply(Ki)):s&&r&&(this._object.position.copy(s),this._object.quaternion.copy(r).multiply(Ki));zo&&(s&&r&&(this._raySpaceObject?.position.copy(s),this._raySpaceObject?.quaternion.copy(r).multiply(Ki)),i&&n&&(this._gripSpaceObject?.position.copy(i),this._gripSpaceObject?.quaternion.copy(n).multiply(Ki)));const l=this.xr.context.mainCamera?.parent,c=l?_e(l):void 0;i&&n&&(this._gripWorldPosition.copy(i),l&&this._gripWorldPosition.applyMatrix4(l.matrixWorld),this._gripWorldQuaternion.copy(n),this._gripWorldQuaternion.multiply(Ki),c&&this._gripWorldQuaternion.premultiply(c)),this.updateRayWorldPosition(),this.updateRayWorldQuaternion()}onDisconnected(){this._connected=!1,zo&&console.warn("Controller disconnected",this.index);for(const e of this._object.children)this.xr.context.scene.attach(e);this._object?.removeFromParent(),this._debugAxesHelper?.removeFromParent(),this._debugGripAxesHelper?.removeFromParent(),this._debugRayAxesHelper?.removeFromParent(),this._gripSpaceObject?.removeFromParent(),this._raySpaceObject?.removeFromParent(),this.unsubscribeEvents(),this._hitTestSource&&(this._hitTestSource.cancel(),this._hitTestSource=void 0)}getButton(e){if(!this._layout)return;switch(e){case"primary-button":if(this.isLeft)e="x-button";else if(this.isRight)e="a-button";else return;break;case"primary":return this.hand?this.getGesture("pinch"):this.toNeedleGamepadButton(0,e);case"xr-standard-trigger":if(this.inputSource.gamepad)return this.toNeedleGamepadButton(0,e);break;case"xr-standard-squeeze":if(this.inputSource.gamepad)return this.toNeedleGamepadButton(1,e);break;case"xr-standard-thumbstick":if(this.inputSource.gamepad)return this.toNeedleGamepadButton(3,e);break}if(this._buttonMap.has(e))return this.toNeedleGamepadButton(this._buttonMap.get(e),e);const t=this._layout?.components[e];if(t?.gamepadIndices)switch(t.type){case"button":case"squeeze":if(this.inputSource.gamepad){const i=t.gamepadIndices.button;return this._buttonMap.set(e,i),this.toNeedleGamepadButton(i,e)}break;default:console.warn("Unsupported component type",t.type);break}this._buttonMap.set(e,void 0)}getGesture(e){const t=this.states[e];if(!t)return null;this.states[e]=t;const i=this._needleGamepadButtons[e]||new _w(void 0,e);return i.pressed=t.pressed,i.value=t.value,i.isDown=t.isDown,i.isUp=t.isUp,this._needleGamepadButtons[e]=i,i}getPointerId(e){if((e==="primary"||e==="pinch")&&(e=0),typeof e!="number"){const t=this._buttonMap.get(e);if(t===void 0)return;e=t}return this.index*10+e}_needleGamepadButtons={};toNeedleGamepadButton(e,t){if(!this.inputSource.gamepad?.buttons)return;const i=this.inputSource.gamepad?.buttons[e],n=this.states[e],s=this._needleGamepadButtons[e]||new _w(e,t);return i&&(s.pressed=i.pressed,s.value=i.value,s.touched=i.touched),n&&(s.isDown=n.isDown,s.isUp=n.isUp),this._needleGamepadButtons[e]=s,s}getStick(e){if(!this._layout)return{x:0,y:0,z:0};if(this.isHand)return{x:0,y:0,z:0};e==="primary"&&this._layout.components["xr-standard-thumbstick"]&&(e="xr-standard-thumbstick");const t=this._layout?.components[e];if(t?.gamepadIndices)switch(t.type){case"thumbstick":case"touchpad":if(this.inputSource.gamepad){const i=t.gamepadIndices.xAxis,n=t.gamepadIndices.yAxis;let s=this.inputSource.gamepad.axes[i]||0,r=this.inputSource.gamepad.axes[n]||0;s*=-1,r*=-1;const a=t.gamepadIndices.button,l=this.inputSource.gamepad?.buttons[a]?.value||0;return{x:s,y:r,z:l}}}return{x:0,y:0,z:0}}_buttonMap=new Map;_motioncontroller;_layout;getMotionController;initialize(){if(this._hasSelectEvent=this.profiles.includes("generic-hand-select")||this.profiles.some(e=>e.startsWith("generic-trigger")),this._isMetaQuestTouchController=this.profiles.includes("meta-quest-touch-plus")||this.profiles.includes("oculus-touch-v3"),this._isMxInk=this.profiles.includes("logitech-mx-ink"),!this._layout){if(this.inputSource.targetRayMode==="transient-pointer")return;const e=HP(this.inputSource,oR,sR);this.getMotionController=e.then(t=>{if(!this.connected)return null;this._motioncontroller=new GP(this.inputSource,t.profile,t.assetPath||"");const i=t.profile.layouts[this.inputSource.handedness];if(this._layout=i,this._layout){if(!this._layout.gamepad?.length){this._layout.gamepad=[];for(const n in this._layout.components){const s=this._layout.components[n];this._layout.gamepad[s.gamepadIndices.button]=n}}this.profiles.length>=1&&this.profiles[0]==="htc-vive-focus-plus"&&this.inputSource.gamepad&&this.inputSource.gamepad.axes.length===4&&!this._layout.components["xr-standard-thumbstick"]&&(this._layout.components["xr-standard-thumbstick"]={type:"thumbstick",gamepadIndices:{xAxis:2,yAxis:3}})}return this._motioncontroller}).catch(t=>(this.inputSource&&console.warn("Couldn't initialize motion controller profile for ",this.inputSource,t),null))}}emitPointerDownEvent=!0;emitPointerUpEvent=!0;emitPointerMoveEvent=!0;pointerMoveDistanceThreshold=.03;pointerMoveAngleThreshold=.05;subscribeEvents(){this.xr.session.addEventListener("selectstart",this.onSelectStart),this.xr.session.addEventListener("selectend",this.onSelectEnd),this.xr.session.addEventListener("squeezestart",this.onSequeezeStart),this.xr.session.addEventListener("squeezeend",this.onSequeezeEnd)}unsubscribeEvents(){this.xr.session.removeEventListener("selectstart",this.onSelectStart),this.xr.session.removeEventListener("selectend",this.onSelectEnd),this.xr.session.removeEventListener("squeezestart",this.onSequeezeStart),this.xr.session.removeEventListener("squeezeend",this.onSequeezeEnd)}_selectButtonIndex=void 0;_squeezeButtonIndex=void 0;onSelectStart=e=>{if(!this.emitPointerDownEvent||this.inputSource!==e.inputSource)return;this.onUpdateFrame(e.frame),this._hasSelectEvent=!0;const t=this._layout?.selectComponentId,i=this._layout?.components[t]?.gamepadIndices?.button;i!==void 0&&(this._selectButtonIndex=i),!Su&&(zo&&B.DrawDirection(this.rayWorldPosition,F(0,.01,1).applyQuaternion(this.rayWorldQuaternion),16711680,10),this.emitPointerEvent(Ae.PointerDown,this._selectButtonIndex||0,"xr-standard-trigger",!0,e))};onSelectEnd=e=>{this.emitPointerUpEvent&&(Su||this.inputSource===e.inputSource&&this.emitPointerEvent(Ae.PointerUp,this._selectButtonIndex||0,"xr-standard-trigger",!0,e))};onSequeezeStart=e=>{this.emitPointerDownEvent&&this.inputSource===e.inputSource&&(this._squeezeButtonIndex=this._layout?.components["xr-standard-squeeze"]?.gamepadIndices?.button,this._squeezeButtonIndex!==void 0&&(zo&&B.DrawDirection(this.rayWorldPosition,F(0,.01,1).applyQuaternion(this.rayWorldQuaternion),255,10),this.emitPointerEvent(Ae.PointerDown,this._squeezeButtonIndex||0,"xr-standard-squeeze",!0,e)))};onSequeezeEnd=e=>{this.emitPointerUpEvent&&this.inputSource===e.inputSource&&this._squeezeButtonIndex!==void 0&&this.emitPointerEvent(Ae.PointerUp,this._squeezeButtonIndex||0,"xr-standard-squeeze",!0,e)};states={};updateInputEvents(){if(this.gamepad?.buttons){for(let e=0;e<this.gamepad.buttons.length;e++){const t=this.gamepad.buttons[e],i=this.states[e]||new bw;let n=null;this._isMxInk&&(e===4||e===5)?(t.value>0&&!i.pressed?(n="pointerdown",i.isDown=!0,i.isUp=!1):t.value===0&&i.pressed?(n="pointerup",i.isDown=!1,i.isUp=!0):i.pressed&&(n="pointermove",i.isDown=!1,i.isUp=!1),i.pressed=t.value>0,i.value=t.value):(t.pressed&&!i.pressed?(n="pointerdown",i.isDown=!0,i.isUp=!1):!t.pressed&&i.pressed?(n="pointerup",i.isDown=!1,i.isUp=!0):(i.isDown=!1,i.isUp=!1),i.pressed=t.pressed,i.value=t.value),this.states[e]=i;const s=e!==this._selectButtonIndex&&e!==this._squeezeButtonIndex;if(n!=null&&s){let r=this._layout?.gamepad[e];this._isMxInk&&e===4&&(r="stylus-touch"),this._isMxInk&&e===5&&(r="stylus-tip"),(zo||Su)&&console.log("Emitting pointer event",n,e,r,t.value,this.gamepad,this._layout),this.emitPointerEvent(n,e,r??"none",!1,null,t.value)}}if(this._isMetaQuestTouchController){const e=this.gamepad.buttons.length-1,t=this.states[e];if(t&&t.isDown){const i=this.context.menu;i.spatialMenuIsVisible?i.setSpatialMenuVisible(!1):this.context.menu.setSpatialMenuVisible(!0)}}}if(this.hand){const e=this.handObject;if(e){const t=e.joints["index-finger-tip"],i=e.joints["thumb-tip"];if(t&&i){const n=t.position.distanceTo(i.position);this._pinchPosition.lerpVectors(t.position,i.position,.5);const s=this.xr.context.mainCamera?.parent;if(s&&this._pinchPosition.applyMatrix4(s.matrixWorld),n!==0){const r=this.states.pinch||new bw,a=(.02+.01)*1.5;r.value=1-(n-.02)/a;const l=n<.02-.01,c=n>.02+.01;l&&!r.pressed?(Su&&console.log("pinch start",n),r.isDown=!0,r.isUp=!1,r.pressed=!0):c&&r.pressed?(r.isDown=!1,r.isUp=!0,r.pressed=!1):(r.isDown=!1,r.isUp=!1),this.states.pinch=r}}}}}_didMoveLastFrame=!1;_lastPointerMovePosition=new b;_lastPointerMoveQuaternion=new N;onUpdateMove(){if(!this.emitPointerMoveEvent)return;let e=!1;if(this._lastPointerMovePosition.distanceTo(this.gripWorldPosition)>this.pointerMoveDistanceThreshold*this.xr.rigScale&&(e=!0),e||this._lastPointerMoveQuaternion.angleTo(this.gripWorldQuaternion)>this.pointerMoveAngleThreshold&&(e=!0),e){this._didMoveLastFrame=!0,this._lastPointerMovePosition.copy(this.gripWorldPosition),this._lastPointerMoveQuaternion.copy(this.gripWorldQuaternion),zo&&B.DrawLabel(this.rayWorldPosition.add(this.object.worldForward.multiplyScalar(.1)),"move",.01);let t=this.xr.context.input.getFirstPressedButtonForPointer(this.index);t===void 0&&(t=0);const i=this.gamepad?.buttons[t]?.value;this.emitPointerEvent("pointermove",t,"none",!1,null,i)}else this._didMoveLastFrame=!1}pointerInit;emitPointerEvent(e,t,i,n,s=null,r){if(!this.emitEvents){zo&&e!==Ae.PointerMove&&console.warn("Pointer events are disabled for this controller",this.index,e,t);return}if(this.xr.mode==="immersive-vr"||this.xr.isPassThrough){this.pointerInit.origin=this,this.pointerInit.pointerId=this.getPointerId(t),this.pointerInit.pointerType=this.hand?"hand":"controller",this.pointerInit.button=t,this.pointerInit.buttonName=i,this.pointerInit.isPrimary=n,this.pointerInit.mode=this.inputSource.targetRayMode,this.pointerInit.ray=this.ray,this.pointerInit.device=this.object,this.pointerInit.pressure=r,this.pointerInit.clientX=this._rayPosition.x/this.xr.rigScale,this.pointerInit.clientY=this._rayPosition.y/this.xr.rigScale,this.pointerInit.clientZ=this._rayPosition.z/this.xr.rigScale;const a=z.Current;z.Current=this.xr.context,zo&&e!=="pointermove"&&console.warn("Pointer event",e,t,i,{...this.pointerInit}),this.xr.context.input.createInputEvent(new Fo(e,s,this.pointerInit)),z.Current=a}}}class bw{isDown=!1;isUp=!1;pressed=!1;value=0}class _w{index;name;touched=!1;pressed=!1;value=0;isDown=!1;isUp=!1;constructor(e,t){this.index=e,this.name=t}}const jc=w("debugwebxr");class gf{controllerStates=[];userId;context;userStateEvtName;constructor(e,t){this.userId=e,this.context=t,this.userStateEvtName="xr-sync-user-state-"+e,this.context.connection.beginListen(this.userStateEvtName,this.onReceivedControllerState)}dispose(){this.context.connection.stopListen(this.userStateEvtName,this.onReceivedControllerState)}onReceivedControllerState=e=>{jc&&console.log(`XRSync: Received change for ${this.userId}: ${e.type} ${e.handedness}; tracked=${e.isTracking}`);let t=!1;for(let i=0;i<this.controllerStates.length;i++)if(this.controllerStates[i].index===e.index){this.controllerStates[i]=e,t=!0;break}t||this.controllerStates.push(e)};update(e){if(this.context.connection.isConnected!=!1){for(let t=this.controllerStates.length-1;t>=0;t--){const i=this.controllerStates[t];let n=!1;for(let s=0;s<e.controllers.length;s++)e.controllers[s].index===i.index&&(n=!0);n||(jc&&console.log(`XRSync: ${i.type} ${i.handedness} removed`,i.index),this.controllerStates.splice(t,1),this.sendControllerRemoved(i))}for(const t of e.controllers)this.updateControllerStates(t)}}onExitXR(e){for(const t of this.controllerStates)this.sendControllerRemoved(t);this.controllerStates.length=0}sendControllerRemoved(e){e.isTracking=!1,e.guid="",this.context.connection.send(this.userStateEvtName,e),this.context.connection.sendDeleteRemoteState(e.guid)}updateControllerStates(e){const t=this.controllerStates.find(i=>i.index===e.index);if(t){let i=!1;i||=t.isTracking!=e.isTracking,i&&(t.isTracking=e.isTracking,this.context.connection.send(this.userStateEvtName,t))}else{const i={guid:this.userId+"-"+e.index,isTracking:e.isTracking,handedness:e.side,index:e.index,type:e.hand?"hand":"controller"};this.controllerStates.push(i),this.context.connection.send(this.userStateEvtName,i),jc&&console.log(`XRSync: ${i.type} ${i.handedness} added`,i.index)}}}class vw{hasState(e){return e?this._states.has(e):!1}isTracking(e,t){if(!e)return;const i=this._states.get(e);return i?i.controllerStates.find(n=>n.handedness===t)?.isTracking||!1:void 0}getDeviceType(e,t){if(!e)return;const i=this._states.get(e);return i?i.controllerStates.find(n=>n.handedness===t)?.type||"unknown":void 0}context;constructor(e){this.context=e,this.context.connection.beginListen(ie.JoinedRoom,this.onJoinedRoom),this.context.connection.beginListen(ie.LeftRoom,this.onLeftRoom),this.context.connection.beginListen(ie.UserJoinedRoom,this.onOtherUserJoinedRoom),this.context.connection.beginListen(ie.UserLeftRoom,this.onOtherUserLeftRoom)}destroy(){this.context.connection.stopListen(ie.JoinedRoom,this.onJoinedRoom),this.context.connection.stopListen(ie.LeftRoom,this.onLeftRoom),this.context.connection.stopListen(ie.UserJoinedRoom,this.onOtherUserJoinedRoom),this.context.connection.stopListen(ie.UserLeftRoom,this.onOtherUserLeftRoom)}onJoinedRoom=()=>{if(this.context.connection.connectionId){this._states.has(this.context.connection.connectionId)||(jc&&console.log("XRSync: Local user joined room",this.context.connection.connectionId),this._states.set(this.context.connection.connectionId,new gf(this.context.connection.connectionId,this.context)));for(const e of this.context.connection.usersInRoom())this._states.has(e)||this._states.set(e,new gf(e,this.context))}};onLeftRoom=()=>{this.context.connection.connectionId&&(this._states.has(this.context.connection.connectionId)||(this._states.get(this.context.connection.connectionId)?.dispose(),this._states.delete(this.context.connection.connectionId)))};onOtherUserJoinedRoom=e=>{const t=e.userId;this._states.has(t)||(jc&&console.log("XRSync: Remote user joined room",t),this._states.set(t,new gf(t,this.context)))};onOtherUserLeftRoom=e=>{const t=e.userId;this._states.has(t)||(this._states.get(t)?.dispose(),this._states.delete(t))};_states=new Map;onUpdate(e){this.context.connection.isConnected&&this.context.connection.connectionId&&this._states.get(this.context.connection.connectionId)?.update(e)}onExitXR(e){this.context.connection.isConnected&&this.context.connection.connectionId&&this._states.get(this.context.connection.connectionId)?.onExitXR(e)}}class ww{_fadeToColorQuad;_fadeToColorMaterial;constructor(){this._fadeToColorMaterial=new Ce({color:0,transparent:!0,depthTest:!1,fog:!1,side:Ei}),this._fadeToColorQuad=new H(new Sn(10,10),this._fadeToColorMaterial)}dispose(){this._fadeToColorQuad.geometry.dispose(),this._fadeToColorMaterial.dispose()}update(e,t){const i=this._fadeToColorQuad,n=this._fadeToColorMaterial;i.parent!==e&&n.opacity>0?e.add(i):n.opacity===0&&i.removeFromParent(),i.layers.set(2),i.material=this._fadeToColorMaterial,i.position.z=-1,i.renderOrder=1/0;const s=this._requestedFadeValue;n.opacity=D.lerp(n.opacity,s,t/.03),Math.abs(n.opacity-s)<=.01&&this._transitionResolve&&(this._transitionResolve(),this._transitionResolve=null,this._transitionPromise=null,this._requestedFadeValue=0)}remove(){this._fadeToColorQuad.removeFromParent()}fadeTransition(){if(this._transitionPromise)return this._transitionPromise;this._requestedFadeValue=1;const e=new Promise(t=>{this._transitionResolve=t});return this._transitionPromise=e,e}_requestedFadeValue=0;_transitionPromise=null;_transitionResolve=null}class oc{static _active=null;static get active(){return this._active}static _requestInFlight=!1;static async start(e,t){if(this._active)return console.error("Cannot start a new XR session while one is already active"),null;if(this._requestInFlight)return console.error("Cannot start a new XR session while a request is already in flight"),null;if("xr"in navigator&&navigator.xr){if(!t)return console.error("XRSessionInit must be provided"),null;this._requestInFlight=!0;const i=await navigator.xr.requestSession(e,t).catch(n=>{console.error("Failed to start temporary XR session:",n)});return i?(i.addEventListener("end",()=>{this._active=null}),this._requestInFlight?(this._requestInFlight=!1,this._active=new oc(e,t,i),this._active):(i.end(),null)):(this._requestInFlight=!1,null)}return null}static async handoff(){return this._active?this._active.handoff():null}static async stop(){this._requestInFlight=!1,this._active&&(await this._active.end(),await Do(100)),this._active=null}_session;_mode;_init;get isAR(){return this._mode==="immersive-ar"}get isVR(){return this._mode==="immersive-vr"}_renderer;_camera;_scene;constructor(e,t,i){this._mode=e,this._init=t,this._session=i,this._session.addEventListener("end",this.onEnd),this._renderer=new br({alpha:!0,antialias:!0}),this._renderer.outputColorSpace="srgb",this._renderer.setPixelRatio(Math.min(2,window.devicePixelRatio)),this._renderer.setSize(window.innerWidth,window.innerHeight,!0),I.isNeedleAppClip()&&window.requestAnimationFrame(()=>{const n=Math.min(2,window.devicePixelRatio),s=Math.floor(window.innerWidth*n),r=Math.floor(window.innerHeight*n);this._renderer.domElement.width=s,this._renderer.domElement.height=r}),this._renderer.setAnimationLoop(this.onFrame),this._renderer.xr.setSession(i),this._renderer.xr.enabled=!0,this._camera=new de,this._scene=new Mi,this._scene.fog=new Eb(4473924,10,250),this._scene.add(this._camera),this.setupScene()}end(){return this._session?this._session.end():Promise.resolve()}async handoff(){if(!this._session)throw new Error("Cannot handoff a session that has already ended");const e={session:this._session,mode:this._mode,init:this._init};return await this.onBeforeHandoff(),this.onEnd(),this._session=null,e}onEnd=()=>{this._session?.removeEventListener("end",this.onEnd),this._renderer.setAnimationLoop(null),this._renderer.dispose(),this._scene.clear()};_lastTime=0;_frames=0;onFrame=(e,t)=>{const i=e-this._lastTime;this.update(e,i),this._camera.parent!==this._scene&&this._scene.add(this._camera),this._renderer.render(this._scene,this._camera),this._lastTime=e,this._frames++};_roomFlyObjects=[];_logoObject=null;get _logoDistance(){return this.isAR?.3:5}get _logoScale(){return this.isAR?.04:1}update(e,t){const i=e*4e-4;for(let r=0;r<this._roomFlyObjects.length;r++){const a=this._roomFlyObjects[r];a.position.y+=Math.sin(i+r*.5)*.005,a.rotateY(.002)}const n=this._logoObject,s=this._renderer.xr.getCamera();if(n){const r=new b;s.getWorldDirection(r);const a=s.position.clone().addScaledVector(r,this._logoDistance),l=this.isAR?.005:1e-5;n.position.lerp(a,this._frames<=2?1:t*l),n.lookAt(this._camera.position)}}async onBeforeHandoff(){await Do(1e3),this._scene.clear()}setupScene(){this._scene.background=new oe(0);let e=tl;if(Jn()){const h=document.querySelector("needle-engine");if(h){const d=h.getAttribute("logo-src");d?.length&&(e=d,A()&&console.debug("[XR] Using custom loading logo from license:",e))}}const t=this._logoObject=new H(new Sn(1,1,1,1),new Ce({transparent:!0,side:2}));t.scale.multiplyScalar(this._logoScale*window.devicePixelRatio),t.renderOrder=1e3,t.material.opacity=0,this._scene.add(t);const i=document.createElement("canvas"),n=i.getContext("2d"),s=new Image,r=h=>{if(!n)return;t.material.opacity=1;const d=1024;i.width=d,i.height=d,n.imageSmoothingQuality="high";const p=d*.19,m=s.width/s.height;{const P=i.height-p*1.5,k=P*m,O=(i.width-k)/2;n.drawImage(s,O,0,k,P)}const f=d*.12,g="Loading...";n.shadowBlur=0,n.fillStyle=this.isAR?"white":"rgba(255,255,255,0.4)",n.font=`${f}px Arial`,n.shadowBlur=d*.02,n.shadowColor="rgba(0,0,0,0.5)",n.shadowOffsetX=0,n.shadowOffsetY=0;const y=n.measureText(g);n.fillText(g,i.width/2-y.width/2,i.height-p/4),n.font=`${f}px Arial`,n.fillText(g,i.width/2-y.width/2,i.height-p/4);const _=new _r().load(i.toDataURL());_.generateMipmaps=!0,_.colorSpace="srgb",_.anisotropy=4;const v=i.width/i.height;t.scale.x=this._logoScale*v*window.devicePixelRatio,t.scale.y=this._logoScale*window.devicePixelRatio,t.material.map=_,t.material.needsUpdate=!0};s.onload=()=>r(),s.onerror=h=>{console.error("Failed to load temporary XR logo:",e,h),s.src=tl},s.crossOrigin="anonymous",s.src=e;const a=new Dm(16777215,1);a.position.set(0,20,0),a.castShadow=!1,this._scene.add(a);const l=new Dm(16777215,1);l.position.set(0,-1,0),l.castShadow=!1,this._scene.add(l);const c=new jm(16777215,1,100,1);if(c.position.set(0,2,0),c.castShadow=!1,c.distance=200,this._scene.add(c),this.isAR===!1)for(let h=0;h<100;h++){const d=new yt({color:2236962,metalness:1,roughness:.8}),p=Qa.Sphere,m=Ms.createPrimitive(p,{material:d});m.position.x=D.random(-50,50),m.position.y=D.random(-2,50),m.position.z=D.random(-50,50),m.rotation.x=D.random(0,Math.PI*2),m.rotation.y=D.random(0,Math.PI*2),m.rotation.z=D.random(0,Math.PI*2),m.scale.multiplyScalar(.5+Math.random()*10);const f=m.position.distanceTo(this._camera.position)-m.scale.x;f<10&&(m.position.z+=5,m.position.multiplyScalar(1+1/f)),this._roomFlyObjects.push(m),this._scene.add(m)}}}var Bc;(o=>{const e=[];function t(){e?.length||A()&&console.warn("No USDZ exporters found \u2013 cannot export USDZ for QuickLook.");for(const s of e)s.exportAndOpen();return!0}o.exportAndOpen=t;function i(s){e.push(s)}o.registerExporter=i;function n(s){if(!e)return;const r=e.indexOf(s);r>=0&&e.splice(r,1)}o.unregisterExporter=n})(Bc||(Bc={}));const Ze=w("debugwebxr"),xw=w("stats");let ff=0;function lR(o){let e=null;const t=o;return t.getAROverlayContainer?e=t.getAROverlayContainer():e=o,e}cR();async function cR(){let o="immersive-vr";try{if(I.isNeedleAppClip()?o="immersive-ar":await navigator.xr?.isSessionSupported("immersive-vr")||(o="immersive-ar"),!await navigator.xr?.isSessionSupported("immersive-ar")&&o==="immersive-ar")return}catch(e){console.debug("[NeedleXRSession:granted] Error while checking XR support:",e);return}if(w("debugasap")){let e=globalThis["needle:XRSession"];if(e instanceof Promise){delete globalThis["needle:XRSession"],pe.addContextCreatedCallback(async t=>{if(!e)return;Va(!0);const i=await e;if(i){const n=Z.getDefaultSessionInit(o);Z.setSession(o,i,n,t.context)}else console.error("[NeedleXRSession:granted] ASAP session was rejected");e=void 0});return}}if("xr"in navigator){if(/WebXRViewer\//i.test(navigator.userAgent)){console.warn("WebXRViewer does not support addEventListener");return}navigator.xr?.addEventListener("sessiongranted",async()=>{const e=sessionStorage.getItem("needle_xr_session_mode"),t=sessionStorage.getItem("needle_xr_session_init")??null,i=t?JSON.parse(t):null;let n=null;if(Sw()&&(await oc.start(e||o,i||Z.getDefaultSessionInit(o)).catch(s=>console.warn("[NeedleXRSession:granted] TemporaryXRContext start failed:",s)),await uR(),n=await oc.handoff()),n)Z.setSession(n.mode,n.session,n.init,z.Current);else if(e&&t){console.log("[NeedleXRSession:granted] Restore last session");const s=JSON.parse(t);Z.start(e,s).catch(r=>console.warn(r))}else Z.start(o).catch(s=>console.warn("[NeedleXRSession:granted] failed:",s))},{once:!0})}}function hR(o,e){sessionStorage.setItem("needle_xr_session_mode",o),sessionStorage.setItem("needle_xr_session_init",JSON.stringify(e))}function dR(){sessionStorage.removeItem("needle_xr_session_mode"),sessionStorage.removeItem("needle_xr_session_init")}const yf=new Set;pe.registerCallback(ue.ContextCreationStart,async o=>{yf.add(o.context)}),pe.registerCallback(ue.ContextCreated,async o=>{yf.delete(o.context);const e=o.context?.domElement.getAttribute("autostart")||null;pR(e)});function Sw(){return yf.size>0}function uR(){return new Promise(o=>{const e=Date.now(),t=setInterval(()=>{(!Sw()||Date.now()-e>6e4)&&(clearInterval(t),o())},100)})}I.isDesktop()&&A()&&window.addEventListener("keydown",o=>{(o.key==="x"||o.key==="Escape")&&Z.active&&Z.stop()});function pR(o){o&&o?.toLowerCase()==="ar"&&Vn.registerWaitForInteraction(()=>{Z.start("ar")})}const Cu=Symbol("initial-fov"),bf=Symbol("initial-near");class Z{static _sync=null;static getXRSync(e){return this._sync||(this._sync=new vw(e)),this._sync}static get currentSessionRequest(){return this._currentSessionRequestMode}static _currentSessionRequestMode=null;static get active(){return this._activeSession}static get activeMode(){return this._activeSession?.mode??null}static get xrSystem(){return"xr"in navigator?navigator.xr:void 0}static isXRSupported(){return Promise.all([this.isVRSupported(),this.isARSupported()]).then(e=>e.some(t=>t)).catch(()=>!1)}static isVRSupported(){return this.isSessionSupported("immersive-vr")}static isARSupported(){return this.isSessionSupported("immersive-ar")}static isSessionSupported(e){return this.xrSystem?.isSessionSupported(e).catch(t=>(Ze&&console.error(t),!1))??Promise.resolve(!1)}static _currentSessionRequest;static _activeSession;static onSessionRequestStart(e){this._sessionRequestStartListeners.push(e)}static offSessionRequestStart(e){const t=this._sessionRequestStartListeners.indexOf(e);t>=0&&this._sessionRequestStartListeners.splice(t,1)}static _sessionRequestStartListeners=[];static onSessionRequestEnd(e){this._sessionRequestEndListeners.push(e)}static offSessionRequestEnd(e){const t=this._sessionRequestEndListeners.indexOf(e);t>=0&&this._sessionRequestEndListeners.splice(t,1)}static _sessionRequestEndListeners=[];static onXRSessionStart(e){this._xrStartListeners.push(e)}static offXRSessionStart(e){const t=this._xrStartListeners.indexOf(e);t>=0&&this._xrStartListeners.splice(t,1)}static _xrStartListeners=[];static onXRSessionEnd(e){this._xrEndListeners.push(e)}static offXRSessionEnd(e){const t=this._xrEndListeners.indexOf(e);t>=0&&this._xrEndListeners.splice(t,1)}static _xrEndListeners=[];static onControllerAdded(e){this._controllerAddedListeners.push(e)}static offControllerAdded(e){const t=this._controllerAddedListeners.indexOf(e);t>=0&&this._controllerAddedListeners.splice(t,1)}static _controllerAddedListeners=[];static onControllerRemoved(e){this._controllerRemovedListeners.push(e)}static offControllerRemoved(e){const t=this._controllerRemovedListeners.indexOf(e);t>=0&&this._controllerRemovedListeners.splice(t,1)}static _controllerRemovedListeners=[];static offerSession(e,t,i){return"xr"in navigator&&navigator.xr&&"offerSession"in navigator.xr?(typeof navigator.xr.offerSession=="function"&&(console.log("WebXR offerSession is available - requesting mode: "+e),t=="default"&&(t=this.getDefaultSessionInit(e)),navigator.xr.offerSession(e,{...t}).then(n=>Z.setSession(e,n,t,i)).catch(n=>{console.log("XRSession offer rejected (perhaps because another call to offerSession was made or a call to requestSession was made)")})),!0):!1}static getDefaultSessionInit(e){switch(e){case"immersive-ar":const t=["anchors","local-floor","layers","dom-overlay","hit-test","unbounded"];return I.isVisionOS()||t.push("hand-tracking"),{optionalFeatures:t};case"immersive-vr":const i=["local-floor","bounded-floor","high-fixed-foveation-level","layers"];return I.isVisionOS()||i.push("hand-tracking"),{optionalFeatures:i};default:return console.warn("No default session init for mode",e),{}}}static async start(e,t,i){if(t||(t={}),I.isiOS()){const r=await this.isARSupported().catch(()=>!1);if(I.isVisionOS()&&!r&&(e==="ar"||e==="immersive-ar")&&(e="quicklook"),e==="quicklook")return gi.sendEvent(z.Current,"xr",{action:"quicklook_export",source:"NeedleXRSession.start"}),Bc.exportAndOpen(),null;if(!r&&(e==="immersive-ar"||e==="ar")){this.invokeSessionRequestStart("immersive-ar",t);const a=new URL("https://appclip.apple.com/id?p=tools.needle.launch-app.Clip");a.searchParams.set("url",location.href);const l=a.toString();gi.sendEvent(z.Current,"xr",{action:"app_clip_launch",source:"NeedleXRSession.start",url:l});const c=window.top||window;try{console.debug("iOS device detected - opening Needle App Clip for AR experience",{mode:e,init:t,url:a}),c.location.href=l}catch(h){console.warn("Error navigating to AppClip "+l+`
878
878
  `,h),window!==window.top?window.open(l,"_blank"):window.location.href=l}return setTimeout(()=>{this.invokeSessionRequestEnd("immersive-ar",t||{},null)},3e3),null}}if(e==="quicklook")return console.warn("QuickLook mode is only supported on iOS devices"),null;if(e=="ar"&&(e="immersive-ar"),A()&&w("debugxrpreroom"))return console.warn("Debug: Starting temporary XR session"),await oc.start(e,t||Z.getDefaultSessionInit(e)),null;if(this._currentSessionRequest)return console.warn("A XRSession is already being requested"),(Ze||A())&&be("A XRSession is already being requested"),this._currentSessionRequest.then(()=>this._activeSession);if(this._activeSession)return console.error("A XRSession is already running"),this._activeSession;if(i||(i=z.Current),i||(i=pe.All[0]),!i)throw new Error("No Needle Engine Context found");switch(e){case"immersive-ar":{if(await this.xrSystem?.isSessionSupported("immersive-ar")!==!0)return console.error(e+" is not supported by this browser."),null;const r=this.getDefaultSessionInit(e),a=lR(i.domElement);a&&!I.isQuest()&&(r.domOverlay={root:a},r.optionalFeatures.push("dom-overlay")),t={...r,...t}}break;case"immersive-vr":{if(await this.xrSystem?.isSessionSupported("immersive-vr")!==!0)return console.error(e+" is not supported by this browser."),null;t={...this.getDefaultSessionInit(e),...t}}break;default:console.warn("No default session init for mode",e);break}t.optionalFeatures??=[],t.requiredFeatures??=[],await oc.stop();const n=e=="immersive-ar"?i.scripts_immersive_ar:i.scripts_immersive_vr;Ze?console.log(`%cRequesting ${e} session`,"font-weight:bold;",t,n):console.log(`%cRequesting ${e} session`,"font-weight:bold;");for(const r of n)r.onBeforeXR&&r.activeAndEnabled&&!r.destroyed&&r.onBeforeXR(e,t);this.invokeSessionRequestStart(e,t),Ze&&ke("Requesting "+e+" session ("+Date.now()+")"),gi.sendEvent(z.Current,"xr",{action:"session_request",mode:e,features:(t.requiredFeatures??[]).concat(t.optionalFeatures??[]).join(","),source:"NeedleXRSession.start"}),this._currentSessionRequest=navigator?.xr?.requestSession(e,t),this._currentSessionRequestMode=e;const s=await this._currentSessionRequest?.catch(r=>{console.error(r,"Code: "+r?.code),r?.code===9&&be("Couldn't start XR session. Make sure you allow the required permissions."),console.log("If the specified XR configuration is not supported (e.g. entering AR doesnt work) - make sure you access the website on a secure connection (HTTPS) and your device has the required permissions (e.g. camera access)"),location.protocol==="http:"&&be("XR requires a secure connection (HTTPS)")});return this._currentSessionRequest=void 0,this._currentSessionRequestMode=null,this.invokeSessionRequestEnd(e,t,s),s?this.setSession(e,s,t,i):(console.warn("XR Session request was rejected"),null)}static invokeSessionRequestStart(e,t){for(const i of this._sessionRequestStartListeners)i({mode:e,init:t})}static invokeSessionRequestEnd(e,t,i){for(const n of this._sessionRequestEndListeners)n({mode:e,init:t,newSession:i||null})}static setSession(e,t,i,n){if(this._activeSession)return console.error("A XRSession is already running"),this._activeSession;const s=e=="immersive-ar"?n.scripts_immersive_ar:n.scripts_immersive_vr;return this._activeSession=new Z(e,t,n,{scripts:s,controller_added:this._controllerAddedListeners,controller_removed:this._controllerRemovedListeners,init:i}),t.addEventListener("end",this.onEnd),Ze?console.log(`%cStarted ${e} session`,"font-weight:bold;",s):console.log(`%cStarted ${e} session`,"font-weight:bold;"),this._activeSession}static $_stop_request=Symbol();static stop(){const e=this._activeSession;e&&(e[this.$_stop_request]===void 0?(Ze&&console.log("[NeedleXRSession] Stopping XR Session... (new)"),e[this.$_stop_request]=setTimeout(()=>{e.end()})):Ze&&console.warn("[NeedleXRSession] XR Session stop already requested"))}static onEnd=()=>{Ze&&console.log("XR Session ended"),this._activeSession=null};context;get sync(){return Z._sync}get running(){return!this._ended&&this.session!=null}session;mode;get interactionMode(){return this.session.interactionMode}get visibilityState(){return this.session.visibilityState}get isVisibleBlurred(){return this.session.visibilityState==="visible-blurred"}get isSystemKeyboardSupported(){return this.session.isSystemKeyboardSupported}get environmentBlendMode(){return this.session.environmentBlendMode}get frame(){return this.context.xrFrame}controllers=[];get leftController(){return this.controllers.find(e=>e.side==="left")}get rightController(){return this.controllers.find(e=>e.side==="right")}getController(e){return typeof e=="number"?this.controllers[e]||null:this.controllers.find(t=>t.side===e)||null}get isPassThrough(){return!!(this.environmentBlendMode!=="opaque"&&this.interactionMode==="world-space"||this.mode==="immersive-ar"&&this.environmentBlendMode!=="opaque"&&this.controllers.some(e=>e.inputSource.targetRayMode==="tracked-pointer")||A()&&I.isDesktop()&&this.mode==="immersive-ar")}get isAR(){return this.mode==="immersive-ar"}get isVR(){return this.mode==="immersive-vr"}get isScreenBasedAR(){return this.isAR&&!this.isPassThrough}get posePosition(){return this._transformPosition}get poseOrientation(){return this._transformOrientation}get referenceSpace(){return this.context.renderer.xr.getReferenceSpace()}get viewerPose(){return this._viewerPose}get isTrackingImages(){if(this.frame&&"getImageTrackingResults"in this.frame&&typeof this.frame.getImageTrackingResults=="function")try{const e=this.frame.getImageTrackingResults();for(const t of e)if(t.trackingState==="tracked")return!0}catch{return!1}return!1}get rig(){const e=this._rigs[0]??null;return e?.gameObject&&Fr(e.gameObject)||e?.isActive===!1?(this.updateActiveXRRig(),this._rigs[0]??null):e}_rigScale=1;_lastRigScaleUpdate=-1;get rigScale(){return this._rigs[0]?(this._lastRigScaleUpdate!==this.context.time.frame&&(this._lastRigScaleUpdate=this.context.time.frame,this._rigScale=this._rigs[0].gameObject.worldScale.x),this._rigScale):1}addRig(e){this._rigs.indexOf(e)>=0||(e.priority===void 0&&(e.priority=0),this._rigs.push(e),this.updateActiveXRRig())}removeRig(e){const t=this._rigs.indexOf(e);t!==-1&&(this._rigs.splice(t,1),this.updateActiveXRRig())}setRigActive(e){const t=this._rigs.indexOf(e),i=this._rigs[0];this._rigs.splice(t,1),this._rigs.unshift(e),e.priority=i?.priority??0,this.updateActiveXRRig()}getUserOffsetInRig(){const e=this.context.mainCamera?.position;if(!e||!this.rig)return F(0,0,0);const t=F(e);return t.x*=-1,t.z*=-1,t.applyQuaternion(di(this.rig.gameObject.quaternion)),t}updateActiveXRRig(){const e=this._rigs[0]??null;this._defaultRig.gameObject.parent!==this.context.scene&&this.context.scene.add(this._defaultRig.gameObject),this._defaultRig.gameObject.visible=!0,this._rigs.includes(this._defaultRig)||this._rigs.push(this._defaultRig);let t=this._rigs[0];t&&t.priority===void 0&&(t.priority=0);for(let i=1;i<this._rigs.length;i++){const n=this._rigs[i];if(n.isActive){if(Fr(n.gameObject)){this._rigs.splice(i,1),i--;continue}(!t||t.isActive===!1||n.priority!==void 0&&n.priority>t.priority)&&(t=n)}}if(e!==t){const i=this._rigs.indexOf(t);i>=0&&this._rigs.splice(i,1),this._rigs.unshift(t)}Ze&&(e===t?console.log("Updated Active XR Rig:",t,"prev:",e):console.log("Updated Active XRRig:",t," (the same as before)"))}_rigs=[];_viewerHitTestSource=null;getHitTest(e){if(e)return this.getControllerHitTest(e);if(!this._viewerHitTestSource)return null;const t=this._viewerHitTestSource,i=this.frame.getHitTestResults(t);if(i.length>0){const n=i[0];return this.convertHitTestResult(n)}return null}getControllerHitTest(e){const t=e.getHitTestSource();if(!t)return null;const i=this.frame.getHitTestResultsForTransientInput(t);for(const n of i)if(n.inputSource===e.inputSource)for(const s of n.results)return this.convertHitTestResult(s);return null}convertHitTestResult(e){const t=this.context.renderer.xr.getReferenceSpace(),i=t&&e.getPose(t);if(i){const n=F(i.transform.position),s=di(i.transform.orientation),r=this.context.mainCamera;if(r?.parent!==this._cameraRenderParent&&n.applyMatrix4(ol),r?.parent){n.applyMatrix4(r.parent.matrixWorld),s.multiply(Ki);const a=_e(r.parent);a.premultiply(Ki),s.premultiply(a)}return{hit:e,position:n,quaternion:s}}return null}convertSpace(e){const t=F(e.position);t.applyMatrix4(ol);const i=di(e.orientation);return i.premultiply(Ki),{position:t,quaternion:i}}_defaultRig;_xr_scripts;_xr_update_scripts=[];_inactive_scripts=[];_controllerAdded;_controllerRemoved;_originalCameraWorldPosition;_originalCameraWorldRotation;_originalCameraWorldScale;_originalCameraParent;_mainCamera=null;constructor(e,t,i,n){hR(e,n.init),this.session=t,this.mode=e,this.context=i,(Ze||w("console"))&&Va(!0),this._xr_scripts=[...n.scripts],this._xr_update_scripts=this._xr_scripts.filter(s=>typeof s.onUpdateXR=="function"),this._controllerAdded=n.controller_added,this._controllerRemoved=n.controller_removed,Bo(this.onBefore,xe.LateUpdate),this.context.pre_render_callbacks.push(this.onBeforeRender),this.context.post_render_callbacks.push(this.onAfterRender),(n.init.optionalFeatures?.includes("hit-test")||n.init.requiredFeatures?.includes("hit-test"))&&t.requestReferenceSpace("viewer").then(s=>t.requestHitTestSource?.call(t,{space:s})?.then(r=>this._viewerHitTestSource=r).catch(r=>console.error(r))).catch(s=>console.error(s)),this.context.mainCamera&&(this._originalCameraWorldPosition=ee(this.context.mainCamera,new b),this._originalCameraWorldRotation=_e(this.context.mainCamera,new N),this._originalCameraWorldScale=Ge(this.context.mainCamera,new b),this._originalCameraParent=this.context.mainCamera.parent,this.context.mainCamera instanceof de&&(this.context.mainCamera[Cu]=this.context.mainCamera.fov)),this._defaultRig=new nR,this.context.scene.add(this._defaultRig.gameObject),this.addRig(this._defaultRig);for(let s=0;s<t.inputSources.length;s++){const r=t.inputSources[s];if(!r.handedness){console.warn("Input source in xr session has no handedness - ignoring",s);continue}this.onInputSourceAdded(r)}this.session.addEventListener("end",this.onEnd),this.session.addEventListener("inputsourceschange",s=>{for(const r of s.removed)this.disconnectInputSource(r);for(const r of s.added)this.onInputSourceAdded(r)}),this.context.xr=this,this.context.renderer.xr.setSession(this.session).then(this.onRendererSessionSet),"controllerAutoUpdate"in this.context.renderer.xr?(console.debug("Disabling three.js controllerAutoUpdate"),this.context.renderer.xr.controllerAutoUpdate=!1):Ze&&console.warn("controllerAutoUpdate is not available in three.js - cannot disable it"),I.isNeedleAppClip()&&window.requestAnimationFrame(()=>{const s=this.context.renderer.domElement,r=window.devicePixelRatio||1,a=s.width,l=s.height,c=Math.floor(window.innerWidth*r),h=Math.floor(window.innerHeight*r);(Math.abs(a-c)>2||Math.abs(l-h)>2)&&(s.width=c,s.height=h,console.debug("Applied DPR scaling for Needle AppClip XR session",r,s.width,s.height))})}onRendererSessionSet=()=>{this.running&&(this.context.renderer.xr.enabled=!0,this.context.renderer.xr.updateCamera(this.context.mainCamera),this.context.mainCameraComponent?.applyClearFlags())};onInputSourceAdded=e=>{if(e.targetRayMode==="screen")return;let t=0;for(let n=0;n<this.session.inputSources.length;n++)if(this.session.inputSources[n]===e){t=n;break}if(this.controllers.find(n=>n.inputSource===e)){console.debug("Controller already exists for input source",t);return}else if(this._newControllers.find(n=>n.inputSource===e)){console.debug("Controller already registered for input source",t);return}const i=new mf(this,e,t);this._newControllers.push(i)};disconnectInputSource(e){const t=(s,r)=>{if(s.inputSource===e){Ze&&console.log("Disconnecting controller",s.index);const a=r.indexOf(s);a>=0&&r.splice(a,1),this.invokeControllerEvent(s,this._controllerRemoved,"removed");const l={xr:this,controller:s,change:"removed"};for(const c of this._xr_scripts)c.onXRControllerRemoved&&c.onXRControllerRemoved(l);s.onDisconnected()}},i=[...this.controllers];for(let s=i.length-1;s>=0;s--){const r=i[s];t(r,this.controllers)}const n=[...this._newControllers];for(let s=n.length-1;s>=0;s--){const r=n[s];t(r,this._newControllers)}}end(){this._ended||this.session.end().catch(e=>console.warn(e))}_ended=!1;_newControllers=[];onEnd=e=>{if(this._ended)return;this._ended=!0,console.debug("XR Session ended"),gi.sendEvent(z.Current,"xr",{action:"session_end",mode:this.mode,source:"NeedleXRSession.onEnd"}),dR(),this.onAfterRender(),this.revertCustomForward(),this._didStart=!1,this._previousCameraParent=null,this.requestedCameraNearPlane=null,Os(this.onBefore,xe.LateUpdate);const t=this.context.pre_render_callbacks.indexOf(this.onBeforeRender);t>=0&&this.context.pre_render_callbacks.splice(t,1);const i=this.context.post_render_callbacks.indexOf(this.onAfterRender);i>=0&&this.context.post_render_callbacks.splice(i,1),this.context.xr=null,this.context.renderer.xr.enabled=!1,this.context.pre_update_oneshot_callbacks.push(()=>{this.context.mainCameraComponent?.applyClearFlags(),this.context.mainCameraComponent?.applyClippingPlane()}),hw({session:this});for(const s of Z._xrEndListeners)s({xr:this});const n=[...this.controllers];for(let s=0;s<n.length;s++)this.disconnectInputSource(n[s].inputSource);this.controllers.length=0,this._newControllers.length=0;for(const s of this._xr_scripts)s?.onLeaveXR?.({xr:this});this.sync?.onExitXR(this),this.context.mainCamera&&(this._originalCameraParent?.add(this.context.mainCamera),this._originalCameraWorldPosition&&bt(this.context.mainCamera,this._originalCameraWorldPosition),this._originalCameraWorldRotation&&Pn(this.context.mainCamera,this._originalCameraWorldRotation),this._originalCameraWorldScale&&Wa(this.context.mainCamera,this._originalCameraWorldScale),this.context.mainCamera instanceof de&&(this.context.mainCamera[Cu]&&(this.context.mainCamera.fov=this.context.mainCamera[Cu],this.context.mainCamera[Cu]=0),this.context.mainCamera[bf]&&(this.context.mainCamera.near=this.context.mainCamera[bf],this.context.mainCamera[bf]=0))),this.context.requestSizeUpdate(),this._defaultRig.gameObject.removeFromParent(),Va(!1)};_didStart=!1;onBefore=e=>{const t=e.xrFrame;if(!t)return;this.context.xr=this,this.context.mainCameraComponent&&this.context.mainCameraComponent!==this._mainCamera&&(this._mainCamera=this.context.mainCameraComponent),this.rig?.isActive==!1&&(Ze&&console.warn("Latest rig is not active - trying to activate a different rig",this.rig),this.updateActiveXRRig()),this.rig&&this._mainCamera?.gameObject&&this._mainCamera?.gameObject?.parent!==this.rig.gameObject&&this.rig.gameObject.add(this._mainCamera?.gameObject),this.internalUpdateState(),this.applyCustomForward();const i={xr:this};if(this._didStart){if(this.context.new_scripts_xr.length>0){const n=[...this.context.new_scripts_xr];for(let s=0;s<n.length;s++){const r=this.context.new_scripts_xr[s];if(!r||r.destroyed||r.supportsXR?.(this.mode)==!1){this.context.new_scripts_xr.splice(s,1);continue}if(!r.activeAndEnabled){this.context.new_scripts_xr.splice(s,1),this.markInactive(r);continue}if(this.addScript(r)){this.invokeCallback_EnterXR(r);for(const a of this.controllers)this.invokeCallback_ControllerAdded(r,a)}}}}else{if(this._didStart=!0,this.mode==="immersive-vr"){const s=ui(this.context.scene.children);if(s){const r=s.getSize(F());if(r.length()>0){const a=this._defaultRig.gameObject;a.position.set(s.min.x+r.x*.5,s.min.y,s.max.z+r.z*.5+1.5);const l=s.getCenter(F());l.y=a.position.y,a.lookAt(l)}}}cw({session:this}),Ir();for(const s of Z._xrStartListeners)s(i);const n=[...this._xr_scripts];Ze&&console.log("NeedleXRSession start, handle scripts:",n);for(const s of n){if(s.destroyed){this._script_to_remove.push(s);continue}if(!s.activeAndEnabled){this.markInactive(s);continue}this.invokeCallback_EnterXR(s);for(const r of this.controllers)this.invokeCallback_ControllerAdded(s,r)}}this.syncCameraCullingMask();for(const n of this.controllers)n.onUpdate(t);if(this._newControllers.length>0){const n=[...this._newControllers];this._newControllers.length=0;for(const s of n){if(!s.connected){console.warn("New controller is not connected",s);continue}this.controllers.push(s);for(const r of this._xr_scripts){if(r.destroyed){this._script_to_remove.push(r);continue}r.activeAndEnabled!==!1&&this.invokeCallback_ControllerAdded(r,s)}}this.controllers.sort((s,r)=>s.index-r.index)}Ze&&this.context.time.frame%30===0&&this.controllers.length<=0&&this.session.inputSources.length>0&&(Va(!0),console.error("XRControllers are not added but inputSources are present"));for(const n of this._xr_update_scripts){if(n.destroyed===!0){this._script_to_remove.push(n);continue}if(n.activeAndEnabled===!1){this.markInactive(n);continue}n.onUpdateXR&&n.onUpdateXR(i)}if(this.handleInactiveScripts(),this._script_to_remove.length>0){const n=[...new Set(this._script_to_remove)];this._script_to_remove.length=0;for(const s of n)!s.destroyed&&this.running&&s.onLeaveXR?.(i),this.removeScript(s)}this.sync?.onUpdate(this),this.onRenderDebug()};onRenderDebug(){if(Ze)for(const e of this.controllers)e.onRenderDebug();if((Ze||xw)&&this.rig&&(ff++,ff>=20)){const e=this.rig.gameObject.worldPosition,t=this.rig.gameObject.worldForward;e.add(t.multiplyScalar(1.5));const i=this.rig.gameObject.worldUp;e.add(i.multiplyScalar(2.5));let n="";if(n+=`${this.context.time.smoothedFps.toFixed(0)} FPS`,n+=`, calls: ${this.context.renderer.info.render.calls}, tris: ${this.context.renderer.info.render.triangles.toLocaleString()}`,Ze||xw)for(const s of this.controllers)n+=`
879
- ${s.hand?"hand":"ctrl"} ${s.inputSource.handedness}[${s.index}] con:${s.connected} tr:${s.isTracking} hts:${s.hasHitTestSource?"yes":"no"}`;ff=0,B.DrawLabel(e,n,void 0,1/60*20)}}onBeforeRender=()=>{this.context.mainCamera&&(this.updateFade(this.context.mainCamera),this.requestedCameraNearPlane!==null&&this.context.mainCamera instanceof de&&(this.context.mainCamera.near=this.requestedCameraNearPlane,this.requestedCameraNearPlane=null))};onAfterRender=()=>{if(this.onUpdateFade_PostRender(),I.isDesktop()||!this._renderOnceOnDevice){const e=this.context.renderer;if(e.xr.isPresenting&&this.context.mainCamera){this._renderOnceOnDevice=!0;const t=e.xr.enabled,i=e.getRenderTarget(),n=this.context.scene.background;e.xr.enabled=!1,e.setRenderTarget(null),this.isPassThrough&&(this.context.scene.background=null),this.context.composer?this.context.composer.render(this.context.time.deltaTime):e.render(this.context.scene,this.context.mainCamera),e.xr.enabled=t,e.setRenderTarget(i),this.context.scene.background=n}}};addScript(e){return this._xr_scripts.includes(e)?!1:(Ze&&console.log("Register new XRScript",e),this._xr_scripts.push(e),typeof e.onUpdateXR=="function"&&this._xr_update_scripts.push(e),!0)}markInactive(e){if(!(this._inactive_scripts.indexOf(e)>=0)){this.removeScript(e,!1),this._inactive_scripts.push(e);for(const t of this.controllers)this.invokeCallback_ControllerRemoved(e,t);this.invokeCallback_LeaveXR(e)}}handleInactiveScripts(){if(this._inactive_scripts.length>0)for(let e=this._inactive_scripts.length-1;e>=0;e--){const t=this._inactive_scripts[e];if(t.activeAndEnabled){this._inactive_scripts.splice(e,1),this.addScript(t),this.invokeCallback_EnterXR(t);for(const i of this.controllers)this.invokeCallback_ControllerAdded(t,i)}}}_script_to_remove=[];removeScript(e,t=!0){Ze&&console.log("Remove XRScript",e);const i=this._xr_scripts.indexOf(e);i>=0&&this._xr_scripts.splice(i,1);const n=this._xr_update_scripts.indexOf(e);if(n>=0&&this._xr_update_scripts.splice(n,1),t){const s=this._inactive_scripts.indexOf(e);s>=0&&this._inactive_scripts.splice(s,1)}}invokeCallback_EnterXR(e){e.onEnterXR&&e.onEnterXR({xr:this})}invokeCallback_ControllerAdded(e,t){e.onXRControllerAdded&&e.onXRControllerAdded({xr:this,controller:t,change:"added"})}invokeCallback_ControllerRemoved(e,t){e.onXRControllerRemoved&&e.onXRControllerRemoved({xr:this,controller:t,change:"removed"})}invokeCallback_LeaveXR(e){e.onLeaveXR&&!e.destroyed&&e.onLeaveXR({xr:this})}syncCameraCullingMask(){const e=this.context.xrCamera,t=this.context.mainCameraComponent?.cullingMask;if(e&&t!==void 0){for(const i of e.cameras)i.layers.mask=t;e.layers.mask=t}else if(e){for(const i of e.cameras)i.layers.enableAll();e.layers.enableAll()}}invokeControllerEvent(e,t,i){for(let n=t.length-1;n>=0;n--){const s=t[n];if(s)try{s({xr:this,controller:e,change:i})}catch(r){console.error(r)}}}_camera;_cameraRenderParent=new M().rotateY(Math.PI);_previousCameraParent;_customforward=!0;originalCameraNearPlane;requestedCameraNearPlane=null;applyCustomForward(){if(this.context.mainCamera&&this._customforward){this._camera=this.context.mainCamera,this._camera.parent!==this._cameraRenderParent&&(this._previousCameraParent=this._camera.parent,this._previousCameraParent?.add(this._cameraRenderParent)),this._cameraRenderParent.name="XR Camera Render Parent",this._cameraRenderParent.add(this._camera);{let e=.02;const t=.001;if(this.rig){const i=Ge(this.rig.gameObject);e*=i.x}this._camera instanceof de&&Math.abs(this._camera.near-e)>t&&(this.isAR?this.originalCameraNearPlane=this._camera.near:this._camera.near=e,Ze&&console.debug(`Setting camera near plane to ${e} (was ${this.originalCameraNearPlane}) to account for XR rendering scale`))}}}revertCustomForward(){this._camera&&this._previousCameraParent&&this._previousCameraParent.add(this._camera),this._previousCameraParent=null,this._camera instanceof de&&this.originalCameraNearPlane!=null&&(this._camera.near=this.originalCameraNearPlane,this.originalCameraNearPlane=void 0)}_viewerPose;_transformOrientation=new N;_transformPosition=new b;internalUpdateState(){const e=this.context.renderer.xr.getReferenceSpace();if(!e){this._viewerPose=void 0;return}if(this._viewerPose=this.frame.getViewerPose(e),this._viewerPose){const t=this._viewerPose.transform;this._transformPosition.set(t.position.x,t.position.y,t.position.z),this._transformOrientation.set(t.orientation.x,t.orientation.y,t.orientation.z,t.orientation.w)}}_transition;get transition(){return this._transition||(this._transition=new ww),this._transition}fadeTransition(){return this._transition||(this._transition=new ww),this._transition.fadeTransition()}updateFade(e){this._transition&&e instanceof de&&this._transition.update(e,this.context.time.deltaTime)}onUpdateFade_PostRender(){this._transition?.remove()}}const _f=w("debugwebxr");class Cw{static tryFindAvatarObjects(e,t,i){if(i.head&&i.leftHand&&i.rightHand)return;const n=e.name.toLocaleLowerCase();!i.head&&n.includes("head")&&(_f&&console.log("FOUND AVATAR HEAD",e.name),i.head=new ne("",t,e)),n.includes("hand")&&(!i.leftHand&&n.includes("left")&&(_f&&console.log("FOUND AVATAR LEFT HAND",e.name),i.leftHand=new ne("",t,e)),!i.rightHand&&n.includes("right")&&(_f&&console.log("FOUND AVATAR RIGHT HAND",e.name),i.rightHand=new ne("",t,e)));for(let s=0;s<e.children.length;s++){if(i.head&&i.leftHand&&i.rightHand)return;const r=e.children[s];this.tryFindAvatarObjects(r,t,i)}}}class se extends oe{alpha=1;get isRGBAColor(){return!0}set a(e){this.alpha=e}get a(){return this.alpha}constructor(e,t,i,n){super(),typeof e=="number"&&typeof t=="number"&&typeof i=="number"?(this.set(e,t,i),this.alpha=typeof n=="number"?n:1):e!==void 0&&(this.set(e),this.alpha=1)}clone(){const e=super.clone();return e.alpha=this.alpha,e}copy(e){return this.r=e.r,this.g=e.g,this.b=e.b,"alpha"in e&&typeof e.alpha=="number"?this.alpha=e.alpha:typeof e.a=="number"&&(this.alpha=e.a),this}lerp(e,t){const i=e;return i.alpha!=null&&(this.alpha=D.lerp(this.alpha,i.alpha,t)),super.lerp(e,t)}lerpColors(e,t,i){const n=e,s=t;return n.alpha!=null&&s.alpha!=null&&(this.alpha=D.lerp(n.alpha,s.alpha,i)),super.lerpColors(e,t,i)}multiply(e){const t=e;return t.alpha!=null&&(this.alpha=this.alpha*t.alpha),super.multiply(e)}fromArray(e,t=0){return this.alpha=e[t+3],super.fromArray(e,t)}static fromColorRepresentation(e){if(typeof e=="string"){if(e.trim()==="transparent")return new se(0,0,0,0);if(e.startsWith("#")&&e.length===9){const t=parseInt(e.slice(1,9),16),i=t>>24&255,n=t>>16&255,s=t>>8&255,r=t>>0&255;return new se(i/255,n/255,s/255,r/255)}else if(e.startsWith("#")){const t=parseInt(e.slice(1),16),i=t>>16&255,n=t>>8&255,s=t>>0&255;return new se(i/255,n/255,s/255,1)}else if(e.startsWith("rgba")){const t=e.slice(5,-1).split(",").map(Number);return new se(t[0]/255,t[1]/255,t[2]/255,t[3])}else if(e.startsWith("rgb")){const t=e.slice(4,-1).split(",").map(Number);return new se(t[0]/255,t[1]/255,t[2]/255,1)}}else if(Array.isArray(e)){if(e.length===4)return new se(e[0],e[1],e[2],e[3]);if(e.length===3)return new se(e[0],e[1],e[2],1);console.error("Invalid color array length. Expected 3 or 4, got "+e.length)}return new se(e)}}const Wt=new b,Pw=new b,Ow=new N,mR=w("debuggizmos"),En=8947848,vf=32;class B{constructor(){}static enabled=!0;static isGizmo(e){return e[xf]!==void 0}static setVisible(e){for(const t of Ji.timedObjectsBuffer)t.visible=e}static DrawLabel(e,t,i=.05,n=0,s,r,a){if(!B.enabled)return null;s||(s=En);const l=Z.active?.rigScale??1,c=Ji.getTextLabel(n,t,i*l,s,r);return a instanceof M&&a.add(c),c.position.x=e.x,c.position.y=e.y,c.position.z=e.z,c}static DrawRay(e,t,i=En,n=0,s=!0){if(!B.enabled)return;const r=Ji.getLine(n),a=r.geometry.getAttribute("position");a.setXYZ(0,e.x,e.y,e.z),Wt.set(t.x,t.y,t.z).multiplyScalar(999999999),a.setXYZ(1,e.x+Wt.x,e.y+Wt.y,e.z+Wt.z),a.needsUpdate=!0,r.material.depthTest=s,r.material.depthWrite=!1,r.material.fog=!1,Tn(r.material,i)}static DrawDirection(e,t,i=En,n=0,s=!0,r=1){if(!B.enabled)return;const a=Ji.getLine(n),l=a.geometry.getAttribute("position");l.setXYZ(0,e.x,e.y,e.z),t.w!==void 0?(Wt.set(0,0,-r),Ow.set(t.x,t.y,t.z,t.w),Wt.applyQuaternion(Ow)):(Wt.set(t.x,t.y,t.z),Wt.multiplyScalar(r)),l.setXYZ(1,e.x+Wt.x,e.y+Wt.y,e.z+Wt.z),l.needsUpdate=!0,a.material.depthTest=s,a.material.depthWrite=!1,Tn(a.material,i)}static DrawLine(e,t,i=En,n=0,s=!0){if(!B.enabled)return;const r=Ji.getLine(n),a=r.geometry.getAttribute("position");a.setXYZ(0,e.x,e.y,e.z),a.setXYZ(1,t.x,t.y,t.z),a.needsUpdate=!0,r.material.depthTest=s,r.material.depthWrite=!1,r.material.fog=!1,Tn(r.material,i)}static DrawCircle(e,t,i,n=En,s=0,r=!0){if(!B.enabled)return;const a=Ji.getCircle(s);a.position.set(e.x,e.y,e.z),a.scale.set(i,i,i),a.quaternion.setFromUnitVectors(this._up,Wt.set(t.x,t.y,t.z).normalize()),a.material.depthTest=r,a.material.depthWrite=!1,a.material.fog=!1,Tn(a.material,n)}static DrawWireSphere(e,t,i=En,n=0,s=!0){if(!B.enabled)return;const r=Ji.getSphere(t,n,!0);Cr(r,e.x,e.y,e.z),r.material.depthTest=s,r.material.depthWrite=!1,r.material.fog=!1,Tn(r.material,i)}static DrawSphere(e,t,i=En,n=0,s=!0){if(!B.enabled)return;const r=Ji.getSphere(t,n,!1);Cr(r,e.x,e.y,e.z),r.material.depthTest=s,r.material.depthWrite=!1,Tn(r.material,i)}static DrawWireBox(e,t,i=En,n=0,s=!0,r=void 0){if(!B.enabled)return;const a=Ji.getBox(n);a.position.set(e.x,e.y,e.z),a.scale.set(t.x,t.y,t.z),r?a.quaternion.copy(r):a.quaternion.identity(),a.material.depthTest=s,a.material.wireframe=!0,a.material.depthWrite=!1,a.material.fog=!1,Tn(a.material,i)}static DrawWireBox3(e,t=En,i=0,n=!0){if(!B.enabled)return;const s=Ji.getBox(i);s.position.copy(e.getCenter(Wt)),s.scale.copy(e.getSize(Wt)),s.material.depthTest=n,s.material.wireframe=!0,s.material.depthWrite=!1,s.material.fog=!1,Tn(s.material,t)}static _up=new b(0,1,0);static DrawArrow(e,t,i=En,n=0,s=!0,r=!1){if(!B.enabled)return;const a=Ji.getArrowHead(n);a.position.set(t.x,t.y,t.z),a.quaternion.setFromUnitVectors(this._up.set(0,1,0),Wt.set(t.x,t.y,t.z).sub(Pw.set(e.x,e.y,e.z)).normalize());const l=Wt.set(t.x,t.y,t.z).sub(Pw.set(e.x,e.y,e.z)).length()*.1;a.scale.set(l,l,l),a.material.depthTest=s,a.material.wireframe=r,Tn(a.material,i),this.DrawLine(e,t,i,n,s)}static DrawWireMesh(e){const t=Ji.getMesh(e.duration??0);"mesh"in e?(t.geometry=e.mesh.geometry,t.matrixWorld.copy(e.mesh.matrixWorld)):(t.geometry=e.geometry,t.matrixWorld.copy(e.matrix)),t.matrixAutoUpdate=!1,t.matrixWorldAutoUpdate=!1,t.material.depthTest=e.depthTest??!0,t.material.wireframe=!0,Tn(t.material,e.color??En)}}const gR=new Da(1,1,1);function wf(o=null){const e=new oe(o??14540253),t=new mC(gR);return new Bm(t,new Bd({color:e}))}function Tn(o,e){if(Array.isArray(o)){for(const i of o)Tn(i,e);return}const t=e instanceof se?e.a:1;o.color.set(e),o.opacity=t,o.transparent=t<1}const xf=Symbol("GizmoCache");class Ji{static familyName="needle-gizmos";static ensureFont(){let e=Oe.FontLibrary.getFontFamily(this.familyName);e||(e=Oe.FontLibrary.addFontFamily(this.familyName),e.addVariant("normal","normal","https://cdn.needle.tools/static/fonts/msdf/arial/arial-msdf.json","https://cdn.needle.tools/static/fonts/msdf/arial/arial.png")?.addEventListener("ready",()=>{Oe.update()}))}static getTextLabel(e,t,i,n,s){this.ensureFont();let r=this.textLabelCache.pop(),a=1;s&&typeof s=="string"&&s?.length>=8&&s.startsWith("#")?(a=parseInt(s.substring(7),16)/255,s=s.substring(0,7),mR&&console.log(s,a)):typeof s=="object"&&s.a!==void 0&&(a=s.a);const l={boxSizing:"border-box",fontFamily:this.familyName,width:"auto",fontSize:i,color:n,lineHeight:1,backgroundColor:s??void 0,backgroundOpacity:a,textContent:t,borderRadius:.5*i,padding:.8*i,whiteSpace:"pre",offset:.05*i};if(r)r.set(l);else{r=new Jb(l);const c=this,h=r;h.setText=function(d){this.set({textContent:d}),c.tmuiNeedsUpdate=!0}}return this.tmuiNeedsUpdate=!0,this.registerTimedObject(z.Current,r,e,this.textLabelCache),r}static getBox(e){let t=this.boxesCache.pop();if(!t){const i=new Da(1,1,1);t=new H(i)}return this.registerTimedObject(z.Current,t,e,this.boxesCache),t}static getLine(e){let t=this.linesCache.pop();if(!t){t=new Ba;let i=t.geometry.getAttribute("position");i||(i=new tt(new Float32Array(6),3),t.geometry.setAttribute("position",i))}return t.frustumCulled=!1,this.registerTimedObject(z.Current,t,e,this.linesCache),t}static getCircle(e){let t=this.circlesCache.pop();if(!t){t=new Ba;let i=t.geometry.getAttribute("position");if(!i){i=new tt(new Float32Array(vf*3),3),t.geometry.setAttribute("position",i);const n=F(0,1,0),s=F(0,0,1),r=F(s);r.cross(n).normalize();const a=F(r),l=Math.PI*2/(vf-1);for(let c=0;c<vf+1;c++){const h=l*c;n.copy(a).multiplyScalar(Math.cos(h)*1),r.copy(s).multiplyScalar(Math.sin(h)*1);const d=n.add(r);i.setXYZ(c,d.x,d.y,d.z)}}}return t.frustumCulled=!1,this.registerTimedObject(z.Current,t,e,this.circlesCache),t}static getSphere(e,t,i){let n=this.spheresCache.pop();return n||(n=new H(new Ed(1,8,8))),n.scale.set(e,e,e),n.material.wireframe=i,this.registerTimedObject(z.Current,n,t,this.spheresCache),n}static getArrowHead(e){let t=this.arrowHeadsCache.pop();return t||(t=new H(new Mb(0,.5,1,8))),this.registerTimedObject(z.Current,t,e,this.arrowHeadsCache),t}static getMesh(e){let t=this.mesh.pop();return t||(t=new H,t.material=new Ce),this.registerTimedObject(z.Current,t,e,this.mesh),t}static linesCache=[];static circlesCache=[];static spheresCache=[];static boxesCache=[];static arrowHeadsCache=[];static mesh=[];static textLabelCache=[];static registerTimedObject(e,t,i,n){if(!e){console.error("No Needle Engine context available. Did you call a Gizmos function in global scope?");return}const s=this.contextBeforeRenderCallbacks.get(e),r=this.contextPostRenderCallbacks.get(e);if(s){if(e.pre_render_callbacks[e.pre_render_callbacks.length-1]!==s){const a=e.pre_render_callbacks.indexOf(s);a>=0&&e.pre_render_callbacks.splice(a,1),e.pre_render_callbacks.push(s)}}else{const a=()=>{this.onBeforeRender(e,this.timedObjectsBuffer)};this.contextBeforeRenderCallbacks.set(e,a),e.pre_render_callbacks.push(a)}if(r){if(e.post_render_callbacks[e.post_render_callbacks.length-1]!==r){const a=e.post_render_callbacks.indexOf(r);a>=0&&e.post_render_callbacks.splice(a,1),e.post_render_callbacks.push(r)}}else{const a=()=>{this.onPostRender(e,this.timedObjectsBuffer,this.timesBuffer)};this.contextPostRenderCallbacks.set(e,a),e.post_render_callbacks.push(a)}t.traverse(a=>{a.layers.disableAll(),a.layers.enable(2)}),t.renderOrder=999999,t[xf]=n,t.castShadow=!1,t.receiveShadow=!1,t.isGizmo=!0,this.timedObjectsBuffer.push(t),this.timesBuffer.push(z.Current.time.realtimeSinceStartup+i),e.scene.add(t)}static timedObjectsBuffer=new Array;static timesBuffer=new Array;static contextPostRenderCallbacks=new Map;static contextBeforeRenderCallbacks=new Map;static tmuiNeedsUpdate=!1;static onBeforeRender(e,t){this.tmuiNeedsUpdate&&(this.tmuiNeedsUpdate=!1,Oe.update());for(let i=0;i<t.length;i++){const n=t[i];if(e.mainCamera&&n instanceof Oe.MeshUIBaseElement){if(Fr(n))continue;const s=e.isInVR,r=!1,a=!s;yc(n,e.mainCamera,r,a)}}}static onPostRender(e,t,i){const n=e.time.realtimeSinceStartup;for(let s=t.length-1;s>=0;s--){const r=t[s];n>=i[s]-1e-6&&(t.splice(s,1),i.splice(s,1),r.removeFromParent(),Fr(r)!=!0&&r[xf].push(r))}}}const Jt=w("debugphysics"),fR=w("debugworker"),kw=new ws;class Rs{static AllLayers=4294967295;ray;cam;screenPoint;raycaster;results;targets;recursive=!0;minDistance;maxDistance;lineThreshold;layerMask;ignore;testObject;useAcceleratedRaycast;allowSlowRaycastFallback=!0;screenPointFromOffset(e,t){this.screenPoint===void 0&&(this.screenPoint=new K),this.screenPoint.x=e/window.innerWidth*2-1,this.screenPoint.y=-(t/window.innerHeight)*2+1}setLayer(e){kw.set(e),this.layerMask=kw}setMask(e){this.layerMask||(this.layerMask=new ws);const t=this.layerMask;t?t.mask=e:this.layerMask=e}}class Sf{distance;point;object;constructor(e,t,i){this.object=e,this.distance=t,this.point=i}}class sc{static _raycasting=0;static get raycasting(){return this._raycasting>0}raycastPhysicsFast(e,t=void 0,i=1/0,n=!0){return this.context.physics.engine?.raycast(e,t,{maxDistance:i,solid:n})??null}raycastPhysicsFastAndGetNormal(e,t=void 0,i=1/0,n=!0){return this.context.physics.engine?.raycastAndGetNormal(e,t,{maxDistance:i,solid:n})??null}sphereOverlapPhysics(e,t){return this.context.physics.engine?.sphereOverlap(e,t)??null}context;engine;constructor(e){this.context=e}raycaster=new Fd;defaultRaycastOptions=new Rs;targetBuffer=new Array(1);defaultThresholds={Mesh:{},Line:{threshold:-1},LOD:{},Points:{threshold:0},Sprite:{}};sphereResults=new Array;sphereMask=new ws;sphere=new Td;sphereOverlap(e,t,i=!0,n=!1,s=null){if(this.sphereResults.length=0,!this.context.scene)return this.sphereResults;const r=this.sphereMask;r.enableAll(),r.disable(2);for(const a of this.context.scene.children)this.intersectSphere(a,e,t,r,this.sphereResults,i,n,s);return this.sphereResults.sort((a,l)=>a.distance-l.distance)}raycastFromRay(e,t=null){const i=t??this.defaultRaycastOptions;i.ray=e;const n=this.raycast(i);return i===this.defaultRaycastOptions&&(i.ray=void 0),n}raycast(e=null){Jt&&performance.mark("raycast.start"),e||(e=this.defaultRaycastOptions);const t=e.screenPoint??this.context.input.mousePositionRC,i=e.raycaster??this.raycaster;if(i.near=e.minDistance??0,i.far=e.maxDistance??1/0,i.params=this.defaultThresholds,e.lineThreshold===void 0&&(e.lineThreshold=-1),i.params.Line={threshold:e.lineThreshold},e.ray)i.ray.copy(e.ray);else{const a=e.cam??this.context.mainCamera;if(!a)return Jt&&console.error("Can not perform raycast - no main camera found"),this.defaultRaycastOptions.results&&(this.defaultRaycastOptions.results.length=0),this.defaultRaycastOptions.results??[];const l=this.context.xrCamera;this.context.isInXR&&l instanceof gC&&l.cameras.length>0?i.setFromCamera(t,l.cameras[0]):i.setFromCamera(t,a)}let n=e.targets;n||(n=this.targetBuffer,n.length=1,n[0]=this.context.scene);let s=e.results;this.defaultRaycastOptions.results&&(this.defaultRaycastOptions.results.length=0),s||(this.defaultRaycastOptions.results||(this.defaultRaycastOptions.results=new Array),s=this.defaultRaycastOptions.results),e.layerMask!==void 0?e.layerMask instanceof ws?i.layers.mask=e.layerMask.mask:i.layers.mask=e.layerMask:(i.layers.enableAll(),i.layers.disable(2)),Jt&&console.time("raycast"),s.length=0,sc._raycasting++,this.intersect(this.raycaster,n,s,e),s.sort((a,l)=>a.distance-l.distance);const r=e.ignore;return r!==void 0&&r.length>0&&(s=s.filter(a=>!r.includes(a.object))),sc._raycasting--,Jt&&(console.timeEnd("raycast"),console.warn("#"+this.context.time.frame+", hits:",s?.length?[...s]:"nothing"),performance.mark("raycast.end"),performance.measure("raycast","raycast.start","raycast.end")),s}intersect(e,t,i,n){for(const s of t){if(!s||s.visible===!1||B.isGizmo(s)||n.lineThreshold!==void 0&&n.lineThreshold<0&&s instanceof Ba)continue;let r=!0;const a=s,l=a.geometry;if(s.raycastAllowed===!1&&(r=!1),r&&n.testObject){const c=n.testObject?.(s);if(c===!1)continue;c==="continue in children"&&(r=!1)}else r&&(l&&Mw(l)||(r=!1));if(r){const c=i.length,h=s.raycastPreference||"lod";let d=h!=="bounds";if(n.precise===!1&&(d=!1),l&&(d||=l.getAttribute("position")?.array?.length<64),a instanceof Fa&&(d=!1),h==="lod"){const p=Wb(s);p&&(a.geometry=p)}if(!d&&bR(a,e,i)||(n.useAcceleratedRaycast!==!1?Ou.runMeshBVHRaycast(e,a,i,this.context,n):e.intersectObject(a,!1,i)),a.geometry=l,Jt&&i.length!=c){const p=i[i.length-1];B.DrawWireSphere(p.point,.1,7798784,1,!1),B.DrawWireMesh({mesh:s,depthTest:!1,duration:.2,color:7798784})}}n.recursive!==!1&&this.intersect(e,s.children,i,n)}return i}tempBoundingBox=new Nt;intersectSphere(e,t,i,n,s,r,a,l){let c=e&&e.isMesh&&e.layers.test(n)&&!B.isGizmo(e);c&&=e.visible,c&&=!(e instanceof Ba),c&&=!(e instanceof Fa);const h=e,d=h.geometry;if(c&&l){const p=l(e);if(p===!1)return;p==="continue in children"&&(c=!1)}if(d&&Mw(d)||(c=!1),c){if(a){const p=this.sphere;p.center.copy(t),p.radius=i;const m=s.length;if(Ou.runMeshBVHRaycast(this.sphere,h,s,this.context,{}),m!=s.length&&!r)return}else if(d.boundingBox||d.computeBoundingBox(),d.boundingBox){h.matrixWorldNeedsUpdate&&h.updateWorldMatrix(!1,!1);const p=this.tempBoundingBox.copy(d.boundingBox).applyMatrix4(h.matrixWorld),m=this.sphere;if(m.center.copy(t),m.radius=i,m.intersectsBox(p)){const f=ee(e),g=f.distanceTo(m.center),y=new Sf(e,g,f);if(s.push(y),!r)return}}}if(e.children)for(const p of e.children){const m=s.length;if(this.intersectSphere(p,t,i,n,s,r,a,l),m!=s.length&&!r)return}}}function Mw(o){return!(o.index&&o.index.array.length<3)}const Lr=new Td,Pu=new vr,yR=new Ob;function bR(o,e,t){const i=o._computeIntersections;if(!i)return!1;let n=o["_computeIntersections:Needle"];return n||(n=o["_computeIntersections:Needle"]=function(s,r,a){const l=this,c=l.geometry.boundingSphere;if(c){if(l instanceof Fa){Pu.setFromNormalAndCoplanarPoint(F(0,1,0),F(0,-l.position.y,0)),Pu.applyMatrix4(l.matrixWorld,yR);const d=s.ray.intersectPlane(Pu,F());if(d){Lr.copy(c),Lr.applyMatrix4(l.matrixWorld);const p=F(d).sub(s.ray.origin).length(),m=Lr.radius*.5;p<m&&r.push({distance:p,point:d,object:l,normal:Pu.normal.clone()})}return}Lr.copy(c),Lr.applyMatrix4(l.matrixWorld);const h=s.ray.intersectSphere(Lr,F());if(h){const d=F(h).sub(s.ray.origin),p=d.length();if(p>Lr.radius){const m=d.clone().normalize();r.push({distance:p,point:h,object:l,normal:m})}}}}),o._computeIntersections=n,e.intersectObject(o,!1,t),o._computeIntersections=i,!0}var Ou;(o=>{let e=0;function t(v,P,k,O,j){if(!P.geometry||!P.geometry.hasAttribute("position"))return!1;const L=P.geometry;if(P?.isSkinnedMesh){const V=P,W=V.bvhNeedsUpdate;if(!V.staticGenerator)l(),r&&(V.staticGenerator=new r(P),V.staticGenerator.applyWorldTransforms=!1,V.staticGeometry=V.staticGenerator.generate(),L.boundsTree=a?.call(V.staticGeometry),V.staticGeometryLastUpdate=performance.now()+Math.random()*200,V.bvhNeedsUpdate=!0);else if(L.boundsTree&&(V.autoUpdateMeshBvhInterval!==void 0&&V.autoUpdateMeshBvhInterval>=0||W===!0)){const G=performance.now(),X=G-V.staticGeometryLastUpdate,E=V.autoUpdateMeshBvhInterval??100;(W||X>E)&&(Jt&&console.warn(`Physics: updating skinned mesh bvh for ${P.name} after ${X.toFixed(2)}ms`),V.bvhNeedsUpdate=!1,V.staticGeometryLastUpdate=G,V.staticGenerator?.generate(V.staticGeometry),L.boundsTree.refit())}}else if(!L.boundsTree){h||_();let V=!0;if((O.xr||L[f]===!1||L.getAttribute("position")?.isInterleavedBufferAttribute||L.index&&L.index?.isInterleavedBufferAttribute||e>10)&&(V=!1),V&&p){if(L[m]===void 0){let W=null;if(y.length>0){const G=y.shift();G&&!G.running&&(W=G)}if(!W&&g.length<3)try{fR&&console.warn("[GenerateMeshBVHWorker] Creating worker with import.meta.url:",import.meta.url),W=new p,g.push(W)}catch(G){G instanceof DOMException&&G.name==="SecurityError"?(console.warn("Failed to create MeshBVH worker, falling back to main thread generation. This can happen when running from file://, if the browser does not support workers or if the browser is blocking workers for other reasons."),console.debug(G),e+=10):(console.error("Failed to create MeshBVH worker. Please see below for more details:"),console.log(G)),e++}if(W!=null&&!W.running){const G=P.name;Jt&&console.log("<<<< worker start",G,W),L[m]="queued",performance.mark("bvh.create.start");const X=L.clone();try{W.generate(X).then(E=>{L[m]="done",L.boundsTree=E}).catch(E=>{L[m]="failed - "+E?.message,L[f]=!1,Jt&&console.error("Failed to generate mesh bvh on worker",E)}).finally(()=>{Jt&&console.log(">>>>> worker done",G,{hasBoundsTre:L.boundsTree!=null}),y.push(W),X.dispose(),performance.mark("bvh.create.end"),performance.measure("bvh.create (worker)","bvh.create.start","bvh.create.end")})}catch(E){console.error("Failed to generate mesh bvh on worker",E)}}else Jt&&console.warn("No worker available")}}else(!d||!V)&&(l(),s&&(performance.mark("bvh.create.start"),L.boundsTree=new s(L),performance.mark("bvh.create.end"),performance.measure("bvh.create","bvh.create.start","bvh.create.end")))}if(v instanceof Fd){const V=v,W=P.raycast;if(L.boundsTree)l(),n&&(P.acceleratedRaycast||(P.acceleratedRaycast=n.bind(P),Jt&&console.debug(`Physics: bind acceleratedRaycast fn to "${P.name}"`)),P.raycast=P.acceleratedRaycast);else if(Jt&&console.warn("No bounds tree found for mesh",P.name,{workerTask:L[m],hasAcceleratedRaycast:n!=null}),j.allowSlowRaycastFallback===!1&&(L.getAttribute("position")?.array?.length??0)>2e3)return Jt&&console.warn("Skipping raycast because no bounds tree is available and allowSlowRaycastFallback is false"),!1;const G=V.firstHitOnly;return V.firstHitOnly=!1,V.intersectObject(P,!1,k),V.firstHitOnly=G,P.raycast=W,!0}else if(v instanceof Td){const V=L.boundsTree;if(V){const W=v;if(c.copy(P.matrixWorld).invert(),W.applyMatrix4(c),V.intersectsSphere(W)){const G=ee(P),X=G.distanceTo(W.center),E=new Sf(P,X,G);k.push(E)}}return!0}return!1}o.runMeshBVHRaycast=t;let i=!1,n=null,s=null,r=null,a=null;function l(){i||(i=!0,import("./vendor-BgzAK9of.min.js").then(v=>v.index$1).then(v=>{n=v.acceleratedRaycast,s=v.MeshBVH,r=v.StaticGeometryGenerator,a=v.computeBoundsTree}).catch(v=>{(Jt||A())&&console.error("Failed to load BVH library...",v.message)}))}const c=new J;let h=!1,d=!1,p=null;const m=Symbol("Needle:MeshBVH-Worker"),f=Symbol("Needle:MeshBVH-CanUseWorker"),g=[],y=[];function _(){h=!0,d=!0,Promise.resolve().then(()=>LD).then(v=>{p=v.GenerateMeshBVHWorker}).catch(v=>{Jt||A()?console.warn("Failed to setup mesh bvh worker"):console.debug("Failed to setup mesh bvh worker",v)}).finally(()=>{d=!1})}})(Ou||(Ou={}));const Rw=Symbol("gltf-loader-internal-usage-tracker"),_R=w("debugusers");class rc{get name(){return"NEEDLE_internal_usage_tracker"}static isLoading(e){return rc._loadingProcesses>0}static _loadingProcesses=0;parser;_getDependency;_loadingId;_loadedObjects=new Set;constructor(e){this.parser=e,this._getDependency=this.parser.getDependency,this._loadingId=Date.now().toString()}beforeRoot(){rc._loadingProcesses++;const e=this,t=this._getDependency;return this.parser.getDependency=function(i,n){const s=t.call(this,i,n);return s.then(r=>(r&&(e._loadedObjects.add(r),r[Rw]=e._loadingId),r)),s},null}afterRoot(e){rc._loadingProcesses--,this.parser.getDependency=this._getDependency;for(const t of this._loadedObjects)delete t[Rw],t instanceof M&&(t.parent||t instanceof H&&setTimeout(()=>{_R&&console.warn("> GLTF LOADER: Mesh not used in scene!",t),t.material=null,t.geometry=null},1e3));return null}}class Ew{constructor(){window.addEventListener("unhandledrejection",e=>{if(e.defaultPrevented)return;const t=e?.reason?.path;if(t){const i=t[0];i&&i.tagName==="IMG"&&(console.warn(`Could not load image:
879
+ ${s.hand?"hand":"ctrl"} ${s.inputSource.handedness}[${s.index}] con:${s.connected} tr:${s.isTracking} hts:${s.hasHitTestSource?"yes":"no"}`;ff=0,B.DrawLabel(e,n,void 0,1/60*20)}}onBeforeRender=()=>{this.context.mainCamera&&(this.updateFade(this.context.mainCamera),this.requestedCameraNearPlane!==null&&this.context.mainCamera instanceof de&&(this.context.mainCamera.near=this.requestedCameraNearPlane,this.requestedCameraNearPlane=null))};onAfterRender=()=>{if(this.onUpdateFade_PostRender(),I.isDesktop()||!this._renderOnceOnDevice){const e=this.context.renderer;if(e.xr.isPresenting&&this.context.mainCamera){this._renderOnceOnDevice=!0;const t=e.xr.enabled,i=e.getRenderTarget(),n=this.context.scene.background;e.xr.enabled=!1,e.setRenderTarget(null),this.isPassThrough&&(this.context.scene.background=null),this.context.composer?this.context.composer.render(this.context.time.deltaTime):e.render(this.context.scene,this.context.mainCamera),e.xr.enabled=t,e.setRenderTarget(i),this.context.scene.background=n}}};addScript(e){return this._xr_scripts.includes(e)?!1:(Ze&&console.log("Register new XRScript",e),this._xr_scripts.push(e),typeof e.onUpdateXR=="function"&&this._xr_update_scripts.push(e),!0)}markInactive(e){if(!(this._inactive_scripts.indexOf(e)>=0)){this.removeScript(e,!1),this._inactive_scripts.push(e);for(const t of this.controllers)this.invokeCallback_ControllerRemoved(e,t);this.invokeCallback_LeaveXR(e)}}handleInactiveScripts(){if(this._inactive_scripts.length>0)for(let e=this._inactive_scripts.length-1;e>=0;e--){const t=this._inactive_scripts[e];if(t.activeAndEnabled){this._inactive_scripts.splice(e,1),this.addScript(t),this.invokeCallback_EnterXR(t);for(const i of this.controllers)this.invokeCallback_ControllerAdded(t,i)}}}_script_to_remove=[];removeScript(e,t=!0){Ze&&console.log("Remove XRScript",e);const i=this._xr_scripts.indexOf(e);i>=0&&this._xr_scripts.splice(i,1);const n=this._xr_update_scripts.indexOf(e);if(n>=0&&this._xr_update_scripts.splice(n,1),t){const s=this._inactive_scripts.indexOf(e);s>=0&&this._inactive_scripts.splice(s,1)}}invokeCallback_EnterXR(e){e.onEnterXR&&e.onEnterXR({xr:this})}invokeCallback_ControllerAdded(e,t){e.onXRControllerAdded&&e.onXRControllerAdded({xr:this,controller:t,change:"added"})}invokeCallback_ControllerRemoved(e,t){e.onXRControllerRemoved&&e.onXRControllerRemoved({xr:this,controller:t,change:"removed"})}invokeCallback_LeaveXR(e){e.onLeaveXR&&!e.destroyed&&e.onLeaveXR({xr:this})}syncCameraCullingMask(){const e=this.context.xrCamera,t=this.context.mainCameraComponent?.cullingMask;if(e&&t!==void 0){for(const i of e.cameras)i.layers.mask=t;e.layers.mask=t}else if(e){for(const i of e.cameras)i.layers.enableAll();e.layers.enableAll()}}invokeControllerEvent(e,t,i){for(let n=t.length-1;n>=0;n--){const s=t[n];if(s)try{s({xr:this,controller:e,change:i})}catch(r){console.error(r)}}}_camera;_cameraRenderParent=new M().rotateY(Math.PI);_previousCameraParent;_customforward=!0;originalCameraNearPlane;requestedCameraNearPlane=null;applyCustomForward(){if(this.context.mainCamera&&this._customforward){this._camera=this.context.mainCamera,this._camera.parent!==this._cameraRenderParent&&(this._previousCameraParent=this._camera.parent,this._previousCameraParent?.add(this._cameraRenderParent)),this._cameraRenderParent.name="XR Camera Render Parent",this._cameraRenderParent.add(this._camera);{let e=.02;const t=.001;if(this.rig){const i=Ge(this.rig.gameObject);e*=i.x}this._camera instanceof de&&Math.abs(this._camera.near-e)>t&&(this.isAR?this.originalCameraNearPlane=this._camera.near:this._camera.near=e,Ze&&console.debug(`Setting camera near plane to ${e} (was ${this.originalCameraNearPlane}) to account for XR rendering scale`))}}}revertCustomForward(){this._camera&&this._previousCameraParent&&this._previousCameraParent.add(this._camera),this._previousCameraParent=null,this._camera instanceof de&&this.originalCameraNearPlane!=null&&(this._camera.near=this.originalCameraNearPlane,this.originalCameraNearPlane=void 0)}_viewerPose;_transformOrientation=new N;_transformPosition=new b;internalUpdateState(){const e=this.context.renderer.xr.getReferenceSpace();if(!e){this._viewerPose=void 0;return}if(this._viewerPose=this.frame.getViewerPose(e),this._viewerPose){const t=this._viewerPose.transform;this._transformPosition.set(t.position.x,t.position.y,t.position.z),this._transformOrientation.set(t.orientation.x,t.orientation.y,t.orientation.z,t.orientation.w)}}_transition;get transition(){return this._transition||(this._transition=new ww),this._transition}fadeTransition(){return this._transition||(this._transition=new ww),this._transition.fadeTransition()}updateFade(e){this._transition&&e instanceof de&&this._transition.update(e,this.context.time.deltaTime)}onUpdateFade_PostRender(){this._transition?.remove()}}const _f=w("debugwebxr");class Cw{static tryFindAvatarObjects(e,t,i){if(i.head&&i.leftHand&&i.rightHand)return;const n=e.name.toLocaleLowerCase();!i.head&&n.includes("head")&&(_f&&console.log("FOUND AVATAR HEAD",e.name),i.head=new ne("",t,e)),n.includes("hand")&&(!i.leftHand&&n.includes("left")&&(_f&&console.log("FOUND AVATAR LEFT HAND",e.name),i.leftHand=new ne("",t,e)),!i.rightHand&&n.includes("right")&&(_f&&console.log("FOUND AVATAR RIGHT HAND",e.name),i.rightHand=new ne("",t,e)));for(let s=0;s<e.children.length;s++){if(i.head&&i.leftHand&&i.rightHand)return;const r=e.children[s];this.tryFindAvatarObjects(r,t,i)}}}class se extends oe{alpha=1;get isRGBAColor(){return!0}set a(e){this.alpha=e}get a(){return this.alpha}constructor(e,t,i,n){super(),typeof e=="number"&&typeof t=="number"&&typeof i=="number"?(this.set(e,t,i),this.alpha=typeof n=="number"?n:1):e!==void 0&&(this.set(e),this.alpha=1)}clone(){const e=super.clone();return e.alpha=this.alpha,e}copy(e){return this.r=e.r,this.g=e.g,this.b=e.b,"alpha"in e&&typeof e.alpha=="number"?this.alpha=e.alpha:typeof e.a=="number"&&(this.alpha=e.a),this}lerp(e,t){const i=e;return i.alpha!=null&&(this.alpha=D.lerp(this.alpha,i.alpha,t)),super.lerp(e,t)}lerpColors(e,t,i){const n=e,s=t;return n.alpha!=null&&s.alpha!=null&&(this.alpha=D.lerp(n.alpha,s.alpha,i)),super.lerpColors(e,t,i)}multiply(e){const t=e;return t.alpha!=null&&(this.alpha=this.alpha*t.alpha),super.multiply(e)}fromArray(e,t=0){return this.alpha=e[t+3],super.fromArray(e,t)}static fromColorRepresentation(e){if(typeof e=="string"){if(e.trim()==="transparent")return new se(0,0,0,0);if(e.startsWith("#")&&e.length===9){const t=parseInt(e.slice(1,9),16),i=t>>24&255,n=t>>16&255,s=t>>8&255,r=t>>0&255;return new se(i/255,n/255,s/255,r/255)}else if(e.startsWith("#")){const t=parseInt(e.slice(1),16),i=t>>16&255,n=t>>8&255,s=t>>0&255;return new se(i/255,n/255,s/255,1)}else if(e.startsWith("rgba")){const t=e.slice(5,-1).split(",").map(Number);return new se(t[0]/255,t[1]/255,t[2]/255,t[3])}else if(e.startsWith("rgb")){const t=e.slice(4,-1).split(",").map(Number);return new se(t[0]/255,t[1]/255,t[2]/255,1)}}else if(Array.isArray(e)){if(e.length===4)return new se(e[0],e[1],e[2],e[3]);if(e.length===3)return new se(e[0],e[1],e[2],1);console.error("Invalid color array length. Expected 3 or 4, got "+e.length)}return new se(e)}}const Wt=new b,Pw=new b,Ow=new N,mR=w("debuggizmos"),En=8947848,vf=32;class B{constructor(){}static enabled=!0;static isGizmo(e){return e[xf]!==void 0}static setVisible(e){for(const t of Ji.timedObjectsBuffer)t.visible=e}static DrawLabel(e,t,i=.05,n=0,s,r,a){if(!B.enabled)return null;s||(s=En);const l=Z.active?.rigScale??1,c=Ji.getTextLabel(n,t,i*l,s,r);return a instanceof M&&a.add(c),c.position.x=e.x,c.position.y=e.y,c.position.z=e.z,c}static DrawRay(e,t,i=En,n=0,s=!0){if(!B.enabled)return;const r=Ji.getLine(n),a=r.geometry.getAttribute("position");a.setXYZ(0,e.x,e.y,e.z),Wt.set(t.x,t.y,t.z).multiplyScalar(999999999),a.setXYZ(1,e.x+Wt.x,e.y+Wt.y,e.z+Wt.z),a.needsUpdate=!0,r.material.depthTest=s,r.material.depthWrite=!1,r.material.fog=!1,Tn(r.material,i)}static DrawDirection(e,t,i=En,n=0,s=!0,r=1){if(!B.enabled)return;const a=Ji.getLine(n),l=a.geometry.getAttribute("position");l.setXYZ(0,e.x,e.y,e.z),t.w!==void 0?(Wt.set(0,0,-r),Ow.set(t.x,t.y,t.z,t.w),Wt.applyQuaternion(Ow)):(Wt.set(t.x,t.y,t.z),Wt.multiplyScalar(r)),l.setXYZ(1,e.x+Wt.x,e.y+Wt.y,e.z+Wt.z),l.needsUpdate=!0,a.material.depthTest=s,a.material.depthWrite=!1,Tn(a.material,i)}static DrawLine(e,t,i=En,n=0,s=!0){if(!B.enabled)return;const r=Ji.getLine(n),a=r.geometry.getAttribute("position");a.setXYZ(0,e.x,e.y,e.z),a.setXYZ(1,t.x,t.y,t.z),a.needsUpdate=!0,r.material.depthTest=s,r.material.depthWrite=!1,r.material.fog=!1,Tn(r.material,i)}static DrawCircle(e,t,i,n=En,s=0,r=!0){if(!B.enabled)return;const a=Ji.getCircle(s);a.position.set(e.x,e.y,e.z),a.scale.set(i,i,i),a.quaternion.setFromUnitVectors(this._up,Wt.set(t.x,t.y,t.z).normalize()),a.material.depthTest=r,a.material.depthWrite=!1,a.material.fog=!1,Tn(a.material,n)}static DrawWireSphere(e,t,i=En,n=0,s=!0){if(!B.enabled)return;const r=Ji.getSphere(t,n,!0);Cr(r,e.x,e.y,e.z),r.material.depthTest=s,r.material.depthWrite=!1,r.material.fog=!1,Tn(r.material,i)}static DrawSphere(e,t,i=En,n=0,s=!0){if(!B.enabled)return;const r=Ji.getSphere(t,n,!1);Cr(r,e.x,e.y,e.z),r.material.depthTest=s,r.material.depthWrite=!1,Tn(r.material,i)}static DrawWireBox(e,t,i=En,n=0,s=!0,r=void 0){if(!B.enabled)return;const a=Ji.getBox(n);a.position.set(e.x,e.y,e.z),a.scale.set(t.x,t.y,t.z),r?a.quaternion.copy(r):a.quaternion.identity(),a.material.depthTest=s,a.material.wireframe=!0,a.material.depthWrite=!1,a.material.fog=!1,Tn(a.material,i)}static DrawWireBox3(e,t=En,i=0,n=!0){if(!B.enabled)return;const s=Ji.getBox(i);s.position.copy(e.getCenter(Wt)),s.scale.copy(e.getSize(Wt)),s.material.depthTest=n,s.material.wireframe=!0,s.material.depthWrite=!1,s.material.fog=!1,Tn(s.material,t)}static _up=new b(0,1,0);static DrawArrow(e,t,i=En,n=0,s=!0,r=!1){if(!B.enabled)return;const a=Ji.getArrowHead(n);a.position.set(t.x,t.y,t.z),a.quaternion.setFromUnitVectors(this._up.set(0,1,0),Wt.set(t.x,t.y,t.z).sub(Pw.set(e.x,e.y,e.z)).normalize());const l=Wt.set(t.x,t.y,t.z).sub(Pw.set(e.x,e.y,e.z)).length()*.1;a.scale.set(l,l,l),a.material.depthTest=s,a.material.wireframe=r,Tn(a.material,i),this.DrawLine(e,t,i,n,s)}static DrawWireMesh(e){const t=Ji.getMesh(e.duration??0);"mesh"in e?(t.geometry=e.mesh.geometry,t.matrixWorld.copy(e.mesh.matrixWorld)):(t.geometry=e.geometry,t.matrixWorld.copy(e.matrix)),t.matrixAutoUpdate=!1,t.matrixWorldAutoUpdate=!1,t.material.depthTest=e.depthTest??!0,t.material.wireframe=!0,Tn(t.material,e.color??En)}}const gR=new Da(1,1,1);function wf(o=null){const e=new oe(o??14540253),t=new mC(gR);return new Bm(t,new Bd({color:e}))}function Tn(o,e){if(Array.isArray(o)){for(const i of o)Tn(i,e);return}const t=e instanceof se?e.a:1;o.color.set(e),o.opacity=t,o.transparent=t<1}const xf=Symbol("GizmoCache");class Ji{static familyName="needle-gizmos";static ensureFont(){let e=Oe.FontLibrary.getFontFamily(this.familyName);e||(e=Oe.FontLibrary.addFontFamily(this.familyName),e.addVariant("normal","normal","https://cdn.needle.tools/static/fonts/msdf/arial/arial-msdf.json","https://cdn.needle.tools/static/fonts/msdf/arial/arial.png")?.addEventListener("ready",()=>{Oe.update()}))}static getTextLabel(e,t,i,n,s){this.ensureFont();let r=this.textLabelCache.pop(),a=1;s&&typeof s=="string"&&s?.length>=8&&s.startsWith("#")?(a=parseInt(s.substring(7),16)/255,s=s.substring(0,7),mR&&console.log(s,a)):typeof s=="object"&&s.a!==void 0&&(a=s.a);const l={boxSizing:"border-box",fontFamily:this.familyName,width:"auto",fontSize:i,color:n,lineHeight:1,backgroundColor:s??void 0,backgroundOpacity:a,textContent:t,borderRadius:.5*i,padding:.8*i,whiteSpace:"pre",offset:.05*i};if(r)r.set(l);else{r=new Jb(l);const c=this,h=r;h.setText=function(d){this.set({textContent:d}),c.tmuiNeedsUpdate=!0}}return this.tmuiNeedsUpdate=!0,this.registerTimedObject(z.Current,r,e,this.textLabelCache),r}static getBox(e){let t=this.boxesCache.pop();if(!t){const i=new Da(1,1,1);t=new H(i)}return this.registerTimedObject(z.Current,t,e,this.boxesCache),t}static getLine(e){let t=this.linesCache.pop();if(!t){t=new Ba;let i=t.geometry.getAttribute("position");i||(i=new tt(new Float32Array(6),3),t.geometry.setAttribute("position",i))}return t.frustumCulled=!1,this.registerTimedObject(z.Current,t,e,this.linesCache),t}static getCircle(e){let t=this.circlesCache.pop();if(!t){t=new Ba;let i=t.geometry.getAttribute("position");if(!i){i=new tt(new Float32Array(vf*3),3),t.geometry.setAttribute("position",i);const n=F(0,1,0),s=F(0,0,1),r=F(s);r.cross(n).normalize();const a=F(r),l=Math.PI*2/(vf-1);for(let c=0;c<vf+1;c++){const h=l*c;n.copy(a).multiplyScalar(Math.cos(h)*1),r.copy(s).multiplyScalar(Math.sin(h)*1);const d=n.add(r);i.setXYZ(c,d.x,d.y,d.z)}}}return t.frustumCulled=!1,this.registerTimedObject(z.Current,t,e,this.circlesCache),t}static getSphere(e,t,i){let n=this.spheresCache.pop();return n||(n=new H(new Ed(1,8,8))),n.scale.set(e,e,e),n.material.wireframe=i,this.registerTimedObject(z.Current,n,t,this.spheresCache),n}static getArrowHead(e){let t=this.arrowHeadsCache.pop();return t||(t=new H(new Mb(0,.5,1,8))),this.registerTimedObject(z.Current,t,e,this.arrowHeadsCache),t}static getMesh(e){let t=this.mesh.pop();return t||(t=new H,t.material=new Ce),this.registerTimedObject(z.Current,t,e,this.mesh),t}static linesCache=[];static circlesCache=[];static spheresCache=[];static boxesCache=[];static arrowHeadsCache=[];static mesh=[];static textLabelCache=[];static registerTimedObject(e,t,i,n){if(!e){console.error("No Needle Engine context available. Did you call a Gizmos function in global scope?");return}const s=this.contextBeforeRenderCallbacks.get(e),r=this.contextPostRenderCallbacks.get(e);if(s){if(e.pre_render_callbacks[e.pre_render_callbacks.length-1]!==s){const a=e.pre_render_callbacks.indexOf(s);a>=0&&e.pre_render_callbacks.splice(a,1),e.pre_render_callbacks.push(s)}}else{const a=()=>{this.onBeforeRender(e,this.timedObjectsBuffer)};this.contextBeforeRenderCallbacks.set(e,a),e.pre_render_callbacks.push(a)}if(r){if(e.post_render_callbacks[e.post_render_callbacks.length-1]!==r){const a=e.post_render_callbacks.indexOf(r);a>=0&&e.post_render_callbacks.splice(a,1),e.post_render_callbacks.push(r)}}else{const a=()=>{this.onPostRender(e,this.timedObjectsBuffer,this.timesBuffer)};this.contextPostRenderCallbacks.set(e,a),e.post_render_callbacks.push(a)}t.traverse(a=>{a.layers.disableAll(),a.layers.enable(2)}),t.renderOrder=999999,t[xf]=n,t.castShadow=!1,t.receiveShadow=!1,t.isGizmo=!0,this.timedObjectsBuffer.push(t),this.timesBuffer.push(z.Current.time.realtimeSinceStartup+i),e.scene.add(t)}static timedObjectsBuffer=new Array;static timesBuffer=new Array;static contextPostRenderCallbacks=new Map;static contextBeforeRenderCallbacks=new Map;static tmuiNeedsUpdate=!1;static onBeforeRender(e,t){this.tmuiNeedsUpdate&&(this.tmuiNeedsUpdate=!1,Oe.update());for(let i=0;i<t.length;i++){const n=t[i];if(e.mainCamera&&n instanceof Oe.MeshUIBaseElement){if(Fr(n))continue;const s=e.isInVR,r=!1,a=!s;yc(n,e.mainCamera,r,a)}}}static onPostRender(e,t,i){const n=e.time.realtimeSinceStartup;for(let s=t.length-1;s>=0;s--){const r=t[s];n>=i[s]-1e-6&&(t.splice(s,1),i.splice(s,1),r.removeFromParent(),Fr(r)!=!0&&r[xf].push(r))}}}const Jt=w("debugphysics"),fR=w("debugworker"),kw=new ws;class Rs{static AllLayers=4294967295;ray;cam;screenPoint;raycaster;results;targets;recursive=!0;minDistance;maxDistance;lineThreshold;layerMask;ignore;testObject;useAcceleratedRaycast;allowSlowRaycastFallback=!0;screenPointFromOffset(e,t){this.screenPoint===void 0&&(this.screenPoint=new K),this.screenPoint.x=e/window.innerWidth*2-1,this.screenPoint.y=-(t/window.innerHeight)*2+1}setLayer(e){kw.set(e),this.layerMask=kw}setMask(e){this.layerMask||(this.layerMask=new ws);const t=this.layerMask;t?t.mask=e:this.layerMask=e}}class Sf{distance;point;object;constructor(e,t,i){this.object=e,this.distance=t,this.point=i}}class sc{static _raycasting=0;static get raycasting(){return this._raycasting>0}raycastPhysicsFast(e,t=void 0,i=1/0,n=!0){return this.context.physics.engine?.raycast(e,t,{maxDistance:i,solid:n})??null}raycastPhysicsFastAndGetNormal(e,t=void 0,i=1/0,n=!0){return this.context.physics.engine?.raycastAndGetNormal(e,t,{maxDistance:i,solid:n})??null}sphereOverlapPhysics(e,t){return this.context.physics.engine?.sphereOverlap(e,t)??null}context;engine;constructor(e){this.context=e}raycaster=new Fd;defaultRaycastOptions=new Rs;targetBuffer=new Array(1);defaultThresholds={Mesh:{},Line:{threshold:-1},LOD:{},Points:{threshold:0},Sprite:{}};sphereResults=new Array;sphereMask=new ws;sphere=new Td;sphereOverlap(e,t,i=!0,n=!1,s=null){if(this.sphereResults.length=0,!this.context.scene)return this.sphereResults;const r=this.sphereMask;r.enableAll(),r.disable(2);for(const a of this.context.scene.children)this.intersectSphere(a,e,t,r,this.sphereResults,i,n,s);return this.sphereResults.sort((a,l)=>a.distance-l.distance)}raycastFromRay(e,t=null){const i=t??this.defaultRaycastOptions;i.ray=e;const n=this.raycast(i);return i===this.defaultRaycastOptions&&(i.ray=void 0),n}raycast(e=null){Jt&&performance.mark("raycast.start"),e||(e=this.defaultRaycastOptions);const t=e.screenPoint??this.context.input.mousePositionRC,i=e.raycaster??this.raycaster;if(i.near=e.minDistance??0,i.far=e.maxDistance??1/0,i.params=this.defaultThresholds,e.lineThreshold===void 0&&(e.lineThreshold=-1),i.params.Line={threshold:e.lineThreshold},e.ray)i.ray.copy(e.ray);else{const a=e.cam??this.context.mainCamera;if(!a)return Jt&&console.error("Can not perform raycast - no main camera found"),this.defaultRaycastOptions.results&&(this.defaultRaycastOptions.results.length=0),this.defaultRaycastOptions.results??[];const l=this.context.xrCamera;this.context.isInXR&&l instanceof gC&&l.cameras.length>0?i.setFromCamera(t,l.cameras[0]):i.setFromCamera(t,a)}let n=e.targets;n||(n=this.targetBuffer,n.length=1,n[0]=this.context.scene);let s=e.results;this.defaultRaycastOptions.results&&(this.defaultRaycastOptions.results.length=0),s||(this.defaultRaycastOptions.results||(this.defaultRaycastOptions.results=new Array),s=this.defaultRaycastOptions.results),e.layerMask!==void 0?e.layerMask instanceof ws?i.layers.mask=e.layerMask.mask:i.layers.mask=e.layerMask:(i.layers.enableAll(),i.layers.disable(2)),Jt&&console.time("raycast"),s.length=0,sc._raycasting++,this.intersect(this.raycaster,n,s,e),s.sort((a,l)=>a.distance-l.distance);const r=e.ignore;return r!==void 0&&r.length>0&&(s=s.filter(a=>!r.includes(a.object))),sc._raycasting--,Jt&&(console.timeEnd("raycast"),console.warn("#"+this.context.time.frame+", hits:",s?.length?[...s]:"nothing"),performance.mark("raycast.end"),performance.measure("raycast","raycast.start","raycast.end")),s}intersect(e,t,i,n){for(const s of t){if(!s||s.visible===!1||B.isGizmo(s)||n.lineThreshold!==void 0&&n.lineThreshold<0&&s instanceof Ba)continue;let r=!0;const a=s,l=a.geometry;if(s.raycastAllowed===!1&&(r=!1),r&&n.testObject){const c=n.testObject?.(s);if(c===!1)continue;c==="continue in children"&&(r=!1)}else r&&(l&&Mw(l)||(r=!1));if(r){const c=i.length,h=s.raycastPreference||"lod";let d=h!=="bounds";if(n.precise===!1&&(d=!1),l&&(d||=l.getAttribute("position")?.array?.length<64),a instanceof Fa&&(d=!1),h==="lod"){const p=Wb(s);p&&(a.geometry=p)}if(!d&&bR(a,e,i)||(n.useAcceleratedRaycast!==!1?Ou.runMeshBVHRaycast(e,a,i,this.context,n):e.intersectObject(a,!1,i)),a.geometry=l,Jt&&i.length!=c){const p=i[i.length-1];B.DrawWireSphere(p.point,.1,7798784,1,!1),B.DrawWireMesh({mesh:s,depthTest:!1,duration:.2,color:7798784})}}n.recursive!==!1&&this.intersect(e,s.children,i,n)}return i}tempBoundingBox=new Nt;intersectSphere(e,t,i,n,s,r,a,l){let c=e&&e.isMesh&&e.layers.test(n)&&!B.isGizmo(e);c&&=e.visible,c&&=!(e instanceof Ba),c&&=!(e instanceof Fa);const h=e,d=h.geometry;if(c&&l){const p=l(e);if(p===!1)return;p==="continue in children"&&(c=!1)}if(d&&Mw(d)||(c=!1),c){if(a){const p=this.sphere;p.center.copy(t),p.radius=i;const m=s.length;if(Ou.runMeshBVHRaycast(this.sphere,h,s,this.context,{}),m!=s.length&&!r)return}else if(d.boundingBox||d.computeBoundingBox(),d.boundingBox){h.matrixWorldNeedsUpdate&&h.updateWorldMatrix(!1,!1);const p=this.tempBoundingBox.copy(d.boundingBox).applyMatrix4(h.matrixWorld),m=this.sphere;if(m.center.copy(t),m.radius=i,m.intersectsBox(p)){const f=ee(e),g=f.distanceTo(m.center),y=new Sf(e,g,f);if(s.push(y),!r)return}}}if(e.children)for(const p of e.children){const m=s.length;if(this.intersectSphere(p,t,i,n,s,r,a,l),m!=s.length&&!r)return}}}function Mw(o){return!(o.index&&o.index.array.length<3)}const Lr=new Td,Pu=new vr,yR=new Ob;function bR(o,e,t){const i=o._computeIntersections;if(!i)return!1;let n=o["_computeIntersections:Needle"];return n||(n=o["_computeIntersections:Needle"]=function(s,r,a){const l=this,c=l.geometry.boundingSphere;if(c){if(l instanceof Fa){Pu.setFromNormalAndCoplanarPoint(F(0,1,0),F(0,-l.position.y,0)),Pu.applyMatrix4(l.matrixWorld,yR);const d=s.ray.intersectPlane(Pu,F());if(d){Lr.copy(c),Lr.applyMatrix4(l.matrixWorld);const p=F(d).sub(s.ray.origin).length(),m=Lr.radius*.5;p<m&&r.push({distance:p,point:d,object:l,normal:Pu.normal.clone()})}return}Lr.copy(c),Lr.applyMatrix4(l.matrixWorld);const h=s.ray.intersectSphere(Lr,F());if(h){const d=F(h).sub(s.ray.origin),p=d.length();if(p>Lr.radius){const m=d.clone().normalize();r.push({distance:p,point:h,object:l,normal:m})}}}}),o._computeIntersections=n,e.intersectObject(o,!1,t),o._computeIntersections=i,!0}var Ou;(o=>{let e=0;function t(v,P,k,O,j){if(!P.geometry||!P.geometry.hasAttribute("position"))return!1;const L=P.geometry;if(P?.isSkinnedMesh){const V=P,W=V.bvhNeedsUpdate;if(!V.staticGenerator)l(),r&&(V.staticGenerator=new r(P),V.staticGenerator.applyWorldTransforms=!1,V.staticGeometry=V.staticGenerator.generate(),L.boundsTree=a?.call(V.staticGeometry),V.staticGeometryLastUpdate=performance.now()+Math.random()*200,V.bvhNeedsUpdate=!0);else if(L.boundsTree&&(V.autoUpdateMeshBvhInterval!==void 0&&V.autoUpdateMeshBvhInterval>=0||W===!0)){const G=performance.now(),X=G-V.staticGeometryLastUpdate,E=V.autoUpdateMeshBvhInterval??100;(W||X>E)&&(Jt&&console.warn(`Physics: updating skinned mesh bvh for ${P.name} after ${X.toFixed(2)}ms`),V.bvhNeedsUpdate=!1,V.staticGeometryLastUpdate=G,V.staticGenerator?.generate(V.staticGeometry),L.boundsTree.refit())}}else if(!L.boundsTree){h||_();let V=!0;if((O.xr||L[f]===!1||L.getAttribute("position")?.isInterleavedBufferAttribute||L.index&&L.index?.isInterleavedBufferAttribute||e>10)&&(V=!1),V&&p){if(L[m]===void 0){let W=null;if(y.length>0){const G=y.shift();G&&!G.running&&(W=G)}if(!W&&g.length<3)try{fR&&console.warn("[GenerateMeshBVHWorker] Creating worker with import.meta.url:",import.meta.url),W=new p,g.push(W)}catch(G){G instanceof DOMException&&G.name==="SecurityError"?(console.warn("Failed to create MeshBVH worker, falling back to main thread generation. This can happen when running from file://, if the browser does not support workers or if the browser is blocking workers for other reasons."),console.debug(G),e+=10):(console.error("Failed to create MeshBVH worker. Please see below for more details:"),console.log(G)),e++}if(W!=null&&!W.running){const G=P.name;Jt&&console.log("<<<< worker start",G,W),L[m]="queued",performance.mark("bvh.create.start");const X=L.clone();try{W.generate(X).then(E=>{L[m]="done",L.boundsTree=E}).catch(E=>{L[m]="failed - "+E?.message,L[f]=!1,Jt&&console.error("Failed to generate mesh bvh on worker",E)}).finally(()=>{Jt&&console.log(">>>>> worker done",G,{hasBoundsTre:L.boundsTree!=null}),y.push(W),X.dispose(),performance.mark("bvh.create.end"),performance.measure("bvh.create (worker)","bvh.create.start","bvh.create.end")})}catch(E){console.error("Failed to generate mesh bvh on worker",E)}}else Jt&&console.warn("No worker available")}}else(!d||!V)&&(l(),s&&(performance.mark("bvh.create.start"),L.boundsTree=new s(L),performance.mark("bvh.create.end"),performance.measure("bvh.create","bvh.create.start","bvh.create.end")))}if(v instanceof Fd){const V=v,W=P.raycast;if(L.boundsTree)l(),n&&(P.acceleratedRaycast||(P.acceleratedRaycast=n.bind(P),Jt&&console.debug(`Physics: bind acceleratedRaycast fn to "${P.name}"`)),P.raycast=P.acceleratedRaycast);else if(Jt&&console.warn("No bounds tree found for mesh",P.name,{workerTask:L[m],hasAcceleratedRaycast:n!=null}),j.allowSlowRaycastFallback===!1&&(L.getAttribute("position")?.array?.length??0)>2e3)return Jt&&console.warn("Skipping raycast because no bounds tree is available and allowSlowRaycastFallback is false"),!1;const G=V.firstHitOnly;return V.firstHitOnly=!1,V.intersectObject(P,!1,k),V.firstHitOnly=G,P.raycast=W,!0}else if(v instanceof Td){const V=L.boundsTree;if(V){const W=v;if(c.copy(P.matrixWorld).invert(),W.applyMatrix4(c),V.intersectsSphere(W)){const G=ee(P),X=G.distanceTo(W.center),E=new Sf(P,X,G);k.push(E)}}return!0}return!1}o.runMeshBVHRaycast=t;let i=!1,n=null,s=null,r=null,a=null;function l(){i||(i=!0,import("./vendor-Bf43L3CE.min.js").then(v=>v.index$1).then(v=>{n=v.acceleratedRaycast,s=v.MeshBVH,r=v.StaticGeometryGenerator,a=v.computeBoundsTree}).catch(v=>{(Jt||A())&&console.error("Failed to load BVH library...",v.message)}))}const c=new J;let h=!1,d=!1,p=null;const m=Symbol("Needle:MeshBVH-Worker"),f=Symbol("Needle:MeshBVH-CanUseWorker"),g=[],y=[];function _(){h=!0,d=!0,Promise.resolve().then(()=>LD).then(v=>{p=v.GenerateMeshBVHWorker}).catch(v=>{Jt||A()?console.warn("Failed to setup mesh bvh worker"):console.debug("Failed to setup mesh bvh worker",v)}).finally(()=>{d=!1})}})(Ou||(Ou={}));const Rw=Symbol("gltf-loader-internal-usage-tracker"),_R=w("debugusers");class rc{get name(){return"NEEDLE_internal_usage_tracker"}static isLoading(e){return rc._loadingProcesses>0}static _loadingProcesses=0;parser;_getDependency;_loadingId;_loadedObjects=new Set;constructor(e){this.parser=e,this._getDependency=this.parser.getDependency,this._loadingId=Date.now().toString()}beforeRoot(){rc._loadingProcesses++;const e=this,t=this._getDependency;return this.parser.getDependency=function(i,n){const s=t.call(this,i,n);return s.then(r=>(r&&(e._loadedObjects.add(r),r[Rw]=e._loadingId),r)),s},null}afterRoot(e){rc._loadingProcesses--,this.parser.getDependency=this._getDependency;for(const t of this._loadedObjects)delete t[Rw],t instanceof M&&(t.parent||t instanceof H&&setTimeout(()=>{_R&&console.warn("> GLTF LOADER: Mesh not used in scene!",t),t.material=null,t.geometry=null},1e3));return null}}class Ew{constructor(){window.addEventListener("unhandledrejection",e=>{if(e.defaultPrevented)return;const t=e?.reason?.path;if(t){const i=t[0];i&&i.tagName==="IMG"&&(console.warn(`Could not load image:
880
880
  `+i.src),e.preventDefault())}})}}const ku=w("trackresources");function Tw(){return ku==="dispose"}let Dr=!0;ku===0&&(Dr=!1);function vR(o){Dr=o}function Aw(){return Dr}const Iw=Symbol("disposable");function Lw(o,e){o&&(o[Iw]=e,jr&&console.warn("Set disposable",e,o))}const Dw=Symbol("disposed");function wR(o){return o[Dw]===!0}function Me(o){if(o){if(o[Iw]===!1){jr&&console.warn("Object is marked as not disposable",o);return}if(typeof o=="object"&&(o[Dw]=!0),o instanceof Mi)Me(o.environment),Me(o.background),Me(o.customDepthMaterial),Me(o.customDistanceMaterial);else if(o instanceof xs)Me(o.geometry),Me(o.material),Me(o.skeleton),Me(o.bindMatrix),Me(o.bindMatrixInverse),Me(o.customDepthMaterial),Me(o.customDistanceMaterial),o.visible=!1;else if(o instanceof H)Me(o.geometry),Me(o.material),Me(o.customDepthMaterial),Me(o.customDistanceMaterial),o.visible=!1;else if(o instanceof M)o.visible=!1;else if(o instanceof Qi){sl(o);for(const e of Object.keys(o.attributes)){const t=o.attributes[e];Me(t)}}else if(o instanceof tt||o instanceof Tb)jr&&console.warn("BufferAttribute dispose not supported",o.count);else if(o instanceof Array)for(const e of o)e instanceof we&&Me(e);else if(o instanceof we){sl(o);for(const t of Object.keys(o)){const i=o[t];i instanceof Se&&Me(i)}const e=o.uniforms;if(e)for(const t of Object.keys(e)){const i=e[t];i instanceof Se?Me(i):i instanceof Xi&&Me(i.value)}}else o instanceof Se?(sl(o),sl(o.source),o.source?.data instanceof ImageBitmap&&sl(o.source.data)):o instanceof fC?(sl(o.boneTexture),o.boneTexture=null):o instanceof yC||!(o instanceof M)&&jr&&console.warn("Unknown object type",o)}}function sl(o){o&&((jr||Tw()||ku)&&console.warn("\u{1F9E8} FREE",o),o instanceof ImageBitmap||"dispose"in o&&typeof o.dispose=="function"&&o.dispose())}function xR(o){}const SR=new Set;function Cf(o,e,t=null,i){if(i||(i=SR,i.clear()),!o)return i;const n=o[Fc];if(n)for(const s of n)i.has(s)||t?.call(null,s)!==!1&&(i.add(s),e&&Cf(s,!0,t,i));return i}function CR(o){return o[Uc]}const jr=w("debugresourceusers")||w("debugmemory"),Fc=Symbol("needle-resource-users"),Uc=Symbol("needle-resource-users-count");function ei(o,e){eu(o,e,function(t,i){Dr&&!sc.raycasting&&(Mu(Fc,this,t,!1),Mu(Fc,this,i,!0))})}Dr&&(ei(H.prototype,"material"),ei(H.prototype,"geometry"),ei(we.prototype,"map"),ei(we.prototype,"bumpMap"),ei(we.prototype,"alphaMap"),ei(we.prototype,"normalMap"),ei(we.prototype,"displacementMap"),ei(we.prototype,"roughnessMap"),ei(we.prototype,"metalnessMap"),ei(we.prototype,"emissiveMap"),ei(we.prototype,"specularMap"),ei(we.prototype,"envMap"),ei(we.prototype,"lightMap"),ei(we.prototype,"aoMap"),ei(we.prototype,"gradientMap"));function PR(o){if(Dr===!1)return;const e=o[Fc];if(e)for(const t of e)Mu(Fc,t,o,!1)}Dr&&eu(we.prototype,"dispose",function(){PR(this)});let Pf=0;function Mu(o,e,t,i){if(Pf>0)return;if(Array.isArray(t)){for(const s of t)Mu(o,e,s,i);return}if(!t)return;let n=t[o];if(n||(n=new Set),i){if(e&&!n.has(e)){n.add(e);let s=t[Uc]||0;s+=1,t[Uc]=s,jr&&console.warn(`\u{1F7E2} Added user of "${t.type}"`,e,t,s,"users:",n)}}else if(e&&n.has(e)){n.delete(e);let s=t[Uc]||0;s>0&&(s-=1,t[Uc]=s),jr&&console.warn(`\u{1F534} Removed user of "${t.type}"`,e,t,s,"users:",n),s<=0&&(rc.isLoading(t)||(ku&&console.warn(`\u{1F534} Removed all user of "${t.type}"`,t),Tw()&&Me(t)))}t[o]=n}try{eu(br.prototype,"render",function(){Pf++},function(){Pf--})}catch(o){console.warn("Could not wrap WebGLRenderer.render",o)}const zc=Symbol("NEEDLE_NEED_UPDATE_INSTANCE"),jw=Symbol("isUsingInstancing"),Bw=Symbol("instancingRenderer"),Nc=Symbol("instancingAutoUpdateBounds");class yn{static isUsingInstancing(e){return e[jw]===!0}static getRenderer(e){return e[Bw]||null}setAutoUpdateBounds(e,t){const i=yn.getRenderer(e);i&&(i[Nc]=t)}static markDirty(e,t=!0){if(e&&(this.isUsingInstancing(e)&&(e[zc]=!0,e.matrixWorldNeedsUpdate=!0),t))for(const i of e.children)yn.markDirty(i,!0)}}const Fw=new Map;function Uw(o,e){if(!o)return;if(!e){console.warn("No prototype found",o,o.prototype,o.constructor);return}const t=Fw.get(e);t&&t.apply(o)}function Of(o){const e=OR(o.prototype);Fw.set(o,e)}function OR(o){return new kR(o)}class kR{$symbol;extensions;descriptors;constructor(e){this.$symbol=Symbol("prototype-extension"),this.extensions=Object.keys(e),this.descriptors=new Array;for(let t=0;t<this.extensions.length;t++){const i=this.extensions[t],n=Object.getOwnPropertyDescriptor(e,i);n&&this.descriptors.push(n)}}apply(e){if(!e[this.$symbol]){e[this.$symbol]=!0;for(let t=0;t<this.extensions.length;t++){const i=this.extensions[t],n=this.descriptors[t];n&&Object.defineProperty(e,i,n)}}}}function Ru(o){o&&o.isObject3D===!0&&Uw(o,M)}let zw=!1;function MR(){if(zw)return;if(zw=!0,Og.experimentalSmartHierarchyUpdate){const i=M.prototype.add;M.prototype.add=function(...r){return Lf(),i.apply(this,r)};const n=M.prototype.attach;M.prototype.attach=function(...r){return Lf(),n.apply(this,r)};const s=M.prototype.remove;M.prototype.remove=function(...r){return Lf(),s.apply(this,r)}}M.prototype.SetActive=function(i){this.visible=i},M.prototype.setActive=function(i){this.visible=i},M.prototype.destroy=function(){ji(this)},M.prototype.addComponent=function(i,n){return An(this,i,n)},M.prototype.addNewComponent=function(i,n){return An(this,i,n)},M.prototype.removeComponent=function(i){return Ff(this,i)},M.prototype.getOrAddComponent=function(i,n){return Hc(this,i,n)},M.prototype.getComponent=function(i){return Wr(this,i)},M.prototype.getComponents=function(i,n){return Gc(this,i,n)},M.prototype.getComponentInChildren=function(i,n=!1){return qc(this,i,n)},M.prototype.getComponentsInChildren=function(i,n){return ll(this,i,n)},M.prototype.getComponentInParent=function(i,n=!1){return Xc(this,i,n)},M.prototype.getComponentsInParent=function(i,n){return Fu(this,i,n)},Object.getOwnPropertyDescriptor(M.prototype,"activeSelf")||Object.defineProperty(M.prototype,"activeSelf",{get:function(){return rl(this)},set:function(i){Wc(this,i)}}),Object.getOwnPropertyDescriptor(M.prototype,"raycastAllowed")||Object.defineProperty(M.prototype,"raycastAllowed",{get:function(){return this.userData&&this.userData.raycastAllowed!==!1},set:function(i){const n=this;n.userData||(n.userData={}),n.userData.raycastAllowed=i}}),Object.getOwnPropertyDescriptor(M.prototype,"worldPosition")||Object.defineProperty(M.prototype,"worldPosition",{get:function(){return this instanceof Hb?ee(this.object):ee(this)},set:function(i){bt(this,i)}}),Object.getOwnPropertyDescriptor(M.prototype,"worldQuaternion")||Object.defineProperty(M.prototype,"worldQuaternion",{get:function(){return this instanceof Hb?_e(this.object):_e(this)},set:function(i){Pn(this,i)}}),Object.getOwnPropertyDescriptor(M.prototype,"worldRotation")||Object.defineProperty(M.prototype,"worldRotation",{get:function(){return Qd(this)},set:function(i){I_(this,i)}}),Object.getOwnPropertyDescriptor(M.prototype,"worldScale")||Object.defineProperty(M.prototype,"worldScale",{get:function(){return Ge(this)},set:function(i){Wa(this,i)}});const o=new J,e=new b(0,0,0),t=new b(0,1,0);Object.getOwnPropertyDescriptor(M.prototype,"worldForward")||Object.defineProperty(M.prototype,"worldForward",{get:function(){return F().set(0,0,1).applyQuaternion(_e(this))},set:function(i){const n=di().setFromRotationMatrix(o.lookAt(e.set(0,0,0),i,t.set(0,1,0)));this.worldQuaternion=n}}),Object.getOwnPropertyDescriptor(M.prototype,"worldRight")||Object.defineProperty(M.prototype,"worldRight",{get:function(){return F().set(1,0,0).applyQuaternion(_e(this))}}),Object.getOwnPropertyDescriptor(M.prototype,"worldUp")||Object.defineProperty(M.prototype,"worldUp",{get:function(){return F().set(0,1,0).applyQuaternion(_e(this))}}),Object.getOwnPropertyDescriptor(M.prototype,"contains")||Object.defineProperty(M.prototype,"contains",{value:function(i){if(!i)return!1;if(this===i)return!0;for(const n of this.children)if(n.contains(i))return!0;return!1}}),Of(M)}const Eu=w("debuggetcomponent"),Br=w("debuginstantiate");class $n{idProvider;parent;keepWorldPosition;position;rotation;scale;visible;context;components;clone(){const e=new $n;return e.idProvider=this.idProvider,e.parent=this.parent,e.keepWorldPosition=this.keepWorldPosition,e.position=Array.isArray(this.position)?[...this.position]:this.position?.clone(),e.rotation=Array.isArray(this.rotation)?[...this.rotation]:this.rotation?.clone(),e.scale=Array.isArray(this.scale)?[...this.scale]:this.scale?.clone(),e.visible=this.visible,e.context=this.context,e.components=this.components,e}cloneAssign(e){this.idProvider=e.idProvider,this.parent=e.parent,this.keepWorldPosition=e.keepWorldPosition,this.position=Array.isArray(e.position)?[...e.position]:e.position?.clone(),this.rotation=Array.isArray(e.rotation)?[...e.rotation]:e.rotation?.clone(),this.scale=Array.isArray(e.scale)?[...e.scale]:e.scale?.clone(),this.visible=e.visible,this.context=e.context,this.components=e.components}}function rl(o){return o.visible}function Wc(o,e){return typeof e=="number"&&(e=e>.5),o.visible=e,o.visible}function Nw(o){return o[Yn]||Tu(o)}function Ww(o,e){o[jw]=e}function Tu(o){return yn.isUsingInstancing(o)}function kf(o,e){return Ua(o,e,!0,!0)}const Vw=Symbol("isDestroyed");function Fr(o){return o[Vw]}function $w(o,e){o[Vw]=e}const Mf=Symbol("isDontDestroy");function al(o,e=!0){o[Mf]=e}const Au=[],Iu=[];function ji(o,e=!0,t=!1){Au.length=0,Iu.length=0,Rf(o,e,!0);for(const i of Au)i.gameObject=null,i.context=null;for(const i of Iu)$w(i,!0),t&&Me(i);Iu.length=0,Au.length=0}function Rf(o,e=!0,t=!0){if(o==null)return;const i=o;if(i.isComponent){if(i[Mf])return;Au.push(i);const r=i.gameObject;i.__internalDisable(),i.__internalDestroy(),i.gameObject=r;return}if(o[Mf])return;const n=o;Eu&&console.log(n),Iu.push(n);const s=n.userData?.components;if(s!=null&&Array.isArray(s)){let r=s.length;for(let a=0;a<s.length;a++){const l=s[a];Rf(l,e,!1),s.length<r&&(r=s.length,a--)}}if(e&&n.children)for(const r of n.children)Rf(r,e,!1);t&&n.removeFromParent()}function Ur(o,e,t=!0){return Hw(o,e,t)}function*Lu(o,e,t=!1,i=999,n=0){if(o?.userData.components&&!(n>i)){for(const s of o.userData.components)e&&s?.isComponent===!0&&s instanceof e?yield s:yield s;if(t===!0)for(const s of o.children)yield*Lu(s,e,!0,i,n+1)}}function Hw(o,e,t,i=0){if(o){if(o.isObject3D,i>1e3){console.warn("Failed to iterate components: too many levels");return}if(o.userData?.components)for(let n=0;n<o.userData.components.length;n++){const s=o.userData.components[n];if(s?.isComponent===!0){const r=e(s);if(r!==void 0)return r}}if(t&&o.children){const n=i+1;for(let s=0;s<o.children.length;s++){const r=o.children[s];if(!r)continue;const a=Hw(r,e,t,n);if(a!==void 0)return a}}}}function zr(o,e){if("isAssetReference"in o)return o.instantiate(e??void 0);let t=null;e!=null&&(e.x!==void 0?(t=new $n,t.position=e):t=e);let i=z.Current;t?.context&&(i=t.context),Eu&&i.alias&&console.log("context",i.alias),t&&!t.idProvider&&(t.idProvider=new Ut(Date.now()));const n=[],s={},r={},a=Gw(i,o,t,n,s,r);a&&(TR(a,s),ER(r,s)),Eu&&(Yd(o,!0),Yd(a,!0));const l={};if(t?.components!==!1){for(const c in n){const h=n[c],d=h.guid;t&&t.idProvider&&(h.guid=t.idProvider.generateUUID(),l[d]=h.guid,Eu&&console.log(h.name,h.guid)),xu(h,i),h.__internalNewInstanceCreated&&h.__internalNewInstanceCreated()}for(const c in n){const h=n[c];h.resolveGuids&&h.resolveGuids(l),h.enabled!==!1&&(h.enabled=!0)}Du(i)}return a}function Gw(o,e,t,i,n,s){if(!e||e[Di])return null;const r=e.userData;e.userData={};const a=e.children;e.children=[];const l=e.clone(!1);if(Ru(l),e.userData=r,e.children=a,n[e.uuid]={original:e,clone:l},Br&&console.log("ADD",e,l),e.type==="SkinnedMesh"&&(s[e.uuid]={original:e,clone:l}),t?.visible!==void 0&&(l.visible=t.visible),t?.idProvider){l.uuid=t.idProvider.generateUUID();const h=l;h&&(h.guid=l.uuid)}e.animations&&e.animations.length>0&&(l.animations=[...e.animations]);const c=e.parent;if(c&&c.add(l),t?.position)if(Array.isArray(t.position)){const h=new b;h.fromArray(t.position),l.worldPosition=h}else l.worldPosition=t.position;else l.position.copy(e.position);if(t?.rotation){if(t.rotation instanceof N)l.worldQuaternion=t.rotation;else if(t.rotation instanceof ht)l.worldQuaternion=di().setFromEuler(t.rotation);else if(Array.isArray(t.rotation)){const h=new ht;h.fromArray(t.rotation),l.worldQuaternion=di().setFromEuler(h)}}else l.quaternion.copy(e.quaternion);if(t?.scale)if(Array.isArray(t.scale)){const h=new b;h.fromArray(t.scale),t.scale=h}else l.scale.copy(t.scale);else l.scale.copy(e.scale);if(t?.parent&&t.parent!=="scene"){let h=null;if(typeof t.parent=="string"?h=Ua(t.parent,o.scene,!0):h=t.parent,h){const d=t.keepWorldPosition===!0?h.attach:h.add;d?d.call(h,l):console.error("Invalid parent object",h,"received when instantiating:",e)}else console.warn("could not find parent:",t.parent)}for(const[h,d]of Object.entries(e.userData))h!=="components"&&(l.userData[h]=d);if(e.userData?.components){const h=e.userData.components,d=[];l.userData.components=d;for(let p=0;p<h.length;p++){const m=h[p],f=new m.constructor;RR(m,f),m[Cc]!==void 0&&(f[Cc]=m[Cc]),d.push(f),f.gameObject=l,i.push(f),n[m.guid]={original:m,clone:f},Jd.dispatchComponentLifecycleEvent("component-added",f)}}t&&(t.position=void 0,t.rotation=void 0,t.scale=void 0,t.parent=void 0,t.visible=void 0);for(const h in e.children){const d=e.children[h],p=Gw(o,d,t,i,n,s);p&&(n[p.uuid]={original:d,clone:p},l.add(p))}return l}function RR(o,e,t){Xa(e,o,void 0,{})}function ER(o,e){for(const t in o){const i=o[t],n=i.original,s=n.skeleton,r=i.clone;if(!s){console.warn("Skinned mesh has no skeleton?",i);continue}const a=s.bones,l=r.skeleton.clone();r.skeleton=l,r.bindMatrix.clone().copy(n.bindMatrix),r.bindMatrixInverse.copy(n.bindMatrixInverse);const c=[];l.bones=c;for(let h=0;h<a.length;h++){const d=a[h],p=e[d.uuid].clone;c.push(p)}}for(const t in o){const i=o[t].clone;i.skeleton.update(),i.bind(i.skeleton,i.bindMatrix),i.updateMatrixWorld(!0)}}function TR(o,e){for(const t in e){const i=e[t].clone;if(i?.isObject3D&&i?.userData?.components)for(let n=0;n<i.userData.components.length;n++){const s=i.userData.components[n],r=Object.entries(s);for(const[a,l]of r)if(Array.isArray(l)){const c=[];s[a]=c;for(let h=0;h<l.length;h++){const d=l[h];if(typeof d!="object"){c.push(d);continue}const p=qw(s,a,d,e);p!==void 0?(Br&&console.log("Found new instance for",a,d,"->",p),c.push(p)):(Br&&console.warn("Could not find new instance for",a,d),c.push(d))}}else if(typeof l=="object"){const c=qw(s,a,l,e);c!==void 0?s[a]=c:Br&&console.warn("Could not find new instance for",a,l)}}}}function qw(o,e,t,i){if(t!=null)if(t.isComponent===!0){const n=t.gameObject;if(n){const s=n.uuid,r=i[s]?.clone;if(!r){Br&&console.log("reference did not change",e,o,t);return}const a=n.userData.components.indexOf(t);if(a>=0&&r.isObject3D)return Br&&console.log(e,s),r.userData.components[a];console.warn("could not find component",e,t)}}else if(t.isObject3D===!0){if(e==="gameObject")return;const n=t;if(n){const s=n.uuid,r=i[s]?.clone;if(r)return Br&&console.log(e,"old",t,"new",r),r}}else{if(t.isVector4||t.isVector3||t.isVector2||t.isQuaternion||t.isEuler||t.isColor===!0)return t.clone();if(t.isEventList===!0)return t.__internalOnInstantiate(i)}}function Vc(o,e){try{e||o()}catch(t){return console.error(t),!1}return!0}const Ef=w("debugnewscripts"),AR=w("debughierarchy"),Ie=[];function IR(){return Ie.length>0}function Du(o){if(Ef&&console.log("Register new components",o.new_scripts.length,[...o.new_scripts],o.alias?"element: "+o.alias:o.hash,o),o.new_scripts_pre_setup_callbacks.length>0){for(const e of o.new_scripts_pre_setup_callbacks)e&&e();o.new_scripts_pre_setup_callbacks.length=0}if(!(o.new_scripts.length<=0)){Ie.length=0,o.new_scripts.length>0&&Ie.push(...o.new_scripts),o.new_scripts.length=0;for(let e=0;e<Ie.length;e++)try{const t=Ie[e];if(t.isComponent!==!0){(A()||Ef)&&console.error(`Registered script is not a Needle Engine component.
881
881
  The script will be ignored. Please make sure your component extends "Behaviour" imported from "@needle-tools/engine"
882
882
  `,t),Ie.splice(e,1),e--;continue}if(t.destroyed)continue;if(!t.gameObject){console.warn(`Component can not be initialized: no GameObject assigned.
@@ -997,7 +997,7 @@ Consider registering a custom loader via the 'onCreateCustomModelLoader' callbac
997
997
  Content-Type: "${t.headers.get("content-type")}"
998
998
  "Text: "${s}"
999
999
  Binary:`,i)}else je&&console.debug("Could not determine file type from binary data");return"unknown"}const yy=w("debugstencil");function RT(o,e){return(o&1<<e.layer)!=0}const ET=Symbol("stencils");class gr{get name(){return"NEEDLE_render_objects"}static stencils={};static applyStencil(e){if(!e)return;const t=e.sourceId;if(yy&&console.log(t,gr.stencils),!t)return;const i=gr.stencils[t];if(i)for(let n=i.length-1;n>=0;n--){const s=i[n];if(RT(s.layer,e)){yy&&console.log(s),setTimeout(()=>{Ai()&&Tu(e.gameObject)&&(be("Stencil not supported on instanced objects"),console.warn("Stencil not supported on instanced objects",e))},500);for(let r=0;r<e.sharedMaterials.length;r++){let a=e.sharedMaterials[r];a&&(a=a.clone(),a[ET]=!0,a.stencilWrite=!0,a.stencilWriteMask=255,a.stencilFuncMask=255,a.stencilRef=s.value,a.stencilFunc=s.compareFunc,a.stencilZPass=s.passOp,a.stencilFail=s.failOp,a.stencilZFail=s.zFailOp,e.sharedMaterials[r]=a)}e.gameObject.renderOrder=s.event*1e3+s.index*50;break}}}parser;source;constructor(e,t){this.parser=e,this.source=t}afterRoot(e){const t=this.parser.json.extensions;if(t){const i=t[AT];if(i){yy&&console.log(i);const n=i.stencil;if(n&&Array.isArray(n))for(const s of n){const r={...s};r.compareFunc=TT(r.compareFunc),r.passOp=by(r.passOp),r.failOp=by(r.failOp),r.zFailOp=by(r.zFailOp),gr.stencils[this.source]||(gr.stencils[this.source]=[]),gr.stencils[this.source].push(r)}}}return null}}function by(o){switch(o){case 0:return qC;case 1:return GC;case 2:return HC;case 3:return $C;case 4:return VC;case 6:return WC;case 7:return NC;case 5:return zC}return 0}function TT(o){switch(o){case 1:return Db;case 2:return UC;case 3:return FC;case 4:return BC;case 5:return jC;case 6:return DC;case 7:return LC;case 8:return IC}return Db}const AT="NEEDLE_render_objects";class IT{objectToBlock=new WeakMap;meshToOwners=new WeakMap;meshToOriginalCallbacks=new WeakMap;getBlock(e){return this.objectToBlock.get(e)}setBlock(e,t){this.objectToBlock.set(e,t)}deleteBlock(e){this.objectToBlock.delete(e)}isHooked(e,t){return this.meshToOwners.get(e)?.has(t)??!1}addHook(e,t){let i=this.meshToOwners.get(e);i||(i=new Set,this.meshToOwners.set(e,i)),i.add(t)}removeHook(e,t){const i=this.meshToOwners.get(e);i&&(i.delete(t),i.size===0&&this.meshToOwners.delete(e))}getOriginalCallbacks(e){return this.meshToOriginalCallbacks.get(e)}setOriginalCallbacks(e,t){this.meshToOriginalCallbacks.set(e,t)}}const Qo=new IT;class fs{_overrides=[];_defines={};_object=null;get object(){return this._object}constructor(e=null){this._object=e}static get(e){let t=Qo.getBlock(e);return t||(t=new fs(e),Qo.setBlock(e,t),jT(e,t)),t}static hasOverrides(e){const t=Qo.getBlock(e);return t?t.hasOverrides():!1}dispose(){this._object&&Qo.deleteBlock(this._object),this._overrides=[],this._object=null}setOverride(e,t,i){const n=this._overrides.find(s=>s.name===e);n?(n.value=t,n.textureTransform=i):this._overrides.push({name:e,value:t,textureTransform:i})}getOverride(e){return this._overrides.find(t=>t.name===e)}removeOveride(e){const t=this._overrides.findIndex(i=>i.name===e);t>=0&&this._overrides.splice(t,1)}clearAllOverrides(){this._overrides=[]}get overrides(){return this._overrides}hasOverrides(){return this._overrides.length>0}setDefine(e,t){this._defines[e]=t}clearDefine(e){this._defines[e]=void 0}getDefines(){return this._defines}getCacheKey(){const e=[],t=Object.keys(this._defines).sort();for(const i of t){const n=this._defines[i];n!==void 0&&e.push(`d:${i}=${n}`)}for(const i of this._overrides){if(i.value===null)continue;let n="";if(i.value instanceof Se){if(n=i.value.uuid||"texture",i.textureTransform){const s=i.textureTransform;s.offset&&(n+=`;to:${s.offset.x},${s.offset.y}`),s.repeat&&(n+=`;tr:${s.repeat.x},${s.repeat.y}`)}}else if(Array.isArray(i.value))n=i.value.join(",");else if(i.value&&typeof i.value=="object"&&"r"in i.value){const s=i.value;n=`${s.r},${s.g},${s.b},${s.a!==void 0?s.a:""}`}else if(i.value&&typeof i.value=="object"&&"x"in i.value){const s=i.value;n=`${s.x},${s.y}${s.z!==void 0?`,${s.z}`:""}${s.w!==void 0?`,${s.w}`:""}`}else n=String(i.value);e.push(`${i.name}=${n}`)}return e.join(";")}}const dp=Symbol("originalValues"),up=Symbol("savedTextureTransforms");function $x(o){let e=Qo.getBlock(o);if(e)return{block:e,owner:o};if(o.parent&&o.parent.type==="Group"&&(e=Qo.getBlock(o.parent),e))return{block:e,owner:o.parent}}const _l=Symbol("beforeRenderingFlag"),_y=new WeakMap,vy=new WeakMap,LT=function(o,e,t,i){const n=Qo.getBlock(o);if(n&&n.hasOverrides()){const s=n.getOverride("transmission")?.value,r=n.getOverride("transparent")?.value;s!==void 0&&typeof s=="number"&&"transmission"in t&&s!==t.transmission&&(vy.set(this,t.transmission),t.transmission=s),r!==void 0&&typeof r=="boolean"&&r!==t.transparent&&(_y.set(this,t.transparent),t.transparent=r)}},DT=function(o,e,t,i){const n=_y.get(o);n!==void 0&&(_y.delete(o),t.transparent=n);const s=vy.get(o);s!==void 0&&(vy.delete(o),t.transmission=s)},Hx=function(o,e,t,i,n,s){const r=this.material;if(!r)return;if(Array.isArray(r)){if(!r.includes(n))return}else if(r!==n)return;this[_l]===void 0&&(this[_l]=new WeakSet),this[_l].add(n);const a=$x(this);if(!a)return;const{block:l,owner:c}=a,h=l.overrides,d=n,p=l.getDefines(),m=Object.keys(p);if(m.length>0){d.defines||(d.defines={});for(const y of m){const _=p[y];_!==void 0&&(d.defines[y]=_)}}if(h.length===0&&m.length===0)return;let f=m.length>0;d[dp]||(d[dp]=[]);const g=d[dp];for(const y of h){if(y.value===null)continue;const _=d[y.name],v=g.find(P=>P.name===y.name);if(v?v.value=_:g.push({name:y.name,value:_}),!f&&!!_!=!!y.value&&(f=!0),d[y.name]=y.value,y.textureTransform&&y.value instanceof Se){const P=y.value;d[up]||(d[up]=[]),d[up].push({name:y.name,offsetX:P.offset.x,offsetY:P.offset.y,repeatX:P.repeat.x,repeatY:P.repeat.y});const k=y.textureTransform;k.offset&&P.offset.copy(k.offset),k.repeat&&P.repeat.copy(k.repeat)}}f&&(d.needsUpdate=!0),d._forceRefresh=!0},Gx=function(o,e,t,i,n,s){if(this[_l]===void 0||!this[_l].has(n))return;this[_l].delete(n);const r=$x(this);if(!r)return;const{block:a,owner:l}=r,c=a.overrides,h=n,d=h[dp],p=a.getDefines(),m=Object.keys(p);let f=!1;if(m.length>0&&h.defines){for(const y of m)delete h.defines[y];f=!0}if(c.length===0){f&&(h.needsUpdate=!0,h._forceRefresh=!0);return}if(!d)return;const g=h[up];if(g&&g.length>0){for(const y of g){const _=c.find(v=>v.name===y.name);_?.value instanceof Se&&(_.value.offset.set(y.offsetX,y.offsetY),_.value.repeat.set(y.repeatX,y.repeatY))}g.length=0}for(const y of c){const _=d.find(v=>v.name===y.name);_&&(!f&&!!y.value!=!!_.value&&(f=!0),h[y.name]=_.value)}f&&(h.needsUpdate=!0),h._forceRefresh=!0};function jT(o,e){o.type==="Group"?o.children.forEach(t=>{(t.type==="Mesh"||t.type==="SkinnedMesh")&&qx(t,o,e)}):(o.type==="Mesh"||o.type==="SkinnedMesh")&&qx(o,o,e)}function qx(o,e,t){if(!Qo.isHooked(o,e)){if(Qo.addHook(o,e),o["needle:materialPropertyBlock"]=t,!o.onBeforeRender)o.onBeforeRender=Hx;else{const i=o.onBeforeRender;o.onBeforeRender=function(n,s,r,a,l,c){i.call(this,n,s,r,a,l,c),Hx.call(this,n,s,r,a,l,c)}}if(!o.onAfterRender)o.onAfterRender=Gx;else{const i=o.onAfterRender;o.onAfterRender=function(n,s,r,a,l,c){Gx.call(this,n,s,r,a,l,c),i.call(this,n,s,r,a,l,c)}}o.onBeforeRenderListPush=LT,o.onAfterRenderListPush=DT}}var BT=Object.defineProperty,FT=Object.getOwnPropertyDescriptor,pp=(o,e,t,i)=>{for(var n=i>1?void 0:i?FT(e,t):e,s=o.length-1,r;s>=0;s--)(r=o[s])&&(n=(i?r(e,t,n):r(n))||n);return i&&n&&BT(e,t,n),n};const vl=w("debugreflectionprobe"),Xx=w("noreflectionprobe");let ea=null;const UT=Symbol("reflectionProbeKey"),yh=class Wn extends R{static _probes=new Map;static testBox=new Nt;static isUsingReflectionProbe(e){return!!e[UT]}static onEnabled=new ae;static onDisabled=new ae;static get(e,t,i,n){if(!e||e.isObject3D!==!0||Xx)return null;const s=Wn._probes.get(t);if(s){for(const r of s)if(r.__didAwake||r.__internalAwake(),r.activeAndEnabled){if(n){if(r.gameObject===n)return r}else if(r.isInBox(e))return vl&&console.log("Found reflection probe",e.name,r.name),r}}return vl&&console.debug("Did not find reflection probe",e.name,i,e),null}_texture;_textureUrlInFlight;set texture(e){if(this._texture!==e){if(typeof e=="string"){vl&&console.debug(`[ReflectionProbe] Loading reflection probe texture from URL: ${e}`),this._textureUrlInFlight=e;const t=jo(this.sourceId,e);ey(t,this.context.renderer).then(i=>{this._textureUrlInFlight===e&&i&&(this._textureUrlInFlight=void 0,vl&&console.debug(`[ReflectionProbe] Successfully loaded reflection probe texture: ${e}`),this.texture=i)});return}this.__didAwake&&(this._textureUrlInFlight=void 0),this._texture=e,vl&&console.debug("[ReflectionProbe] Set reflection probe texture "+(e?.name||"(removed)")),e&&(e instanceof Lb||e.mapping===Mo||e.mapping!==Eo&&(e.mapping=Eo),e.colorSpace=Ro,e.needsUpdate=!0)}}get texture(){return this._texture}intensity=1;center=new b;size=new b(1,1,1);__lightmapIntensityScale=!0;isInBox(e){return ea??=new Nt,ea.setFromCenterAndSize(this.gameObject.worldPosition.add(this.center),this.size),ui([e],void 0,void 0,Wn.testBox),Wn.testBox.isEmpty()?ea.containsPoint(e.worldPosition):ea?.intersectsBox(Wn.testBox)}constructor(){super(),Wn._probes.has(this.context)||Wn._probes.set(this.context,[]),Wn._probes.get(this.context)?.push(this)}awake(){this._texture&&(this._texture.mapping!==Mo&&(this._texture.mapping=Eo),this._texture.colorSpace=Ro,this._texture.needsUpdate=!0)}update(){vl&&(ea??=new Nt,ea.setFromCenterAndSize(this.gameObject.worldPosition.add(this.center),this.size),B.DrawWireBox3(ea,5592320))}onEnable(){Wn.onEnabled?.invoke(this)}onDisable(){Wn.onDisabled?.invoke(this)}start(){this._texture||console.warn(`[ReflectionProbe] Missing texture. Please assign a custom cubemap texture. To use reflection probes assign them to your renderer's "anchor" property.`)}onDestroy(){const e=Wn._probes.get(this.context);if(e){const t=e.indexOf(this);t>=0&&e.splice(t,1)}}apply(e){if(Xx||!this.enabled||!this.texture)return;const t=fs.get(e);t.setOverride("envMap",this.texture),t.setOverride("envMapRotation",this.gameObject.rotation);let i=this.intensity;this.__lightmapIntensityScale&&t.getOverride("lightMap")&&(i/=Math.PI),t.setOverride("envMapIntensity",i)}unapply(e){const t=fs.get(e);t&&t.getOverride("envMap")?.value===this.texture&&t.removeOveride("envMap")}};pp([u([Se,String])],yh.prototype,"texture",1),pp([u()],yh.prototype,"intensity",2),pp([u(b)],yh.prototype,"center",2),pp([u(b)],yh.prototype,"size",2);let Yo=yh;const wy=w("debugexr");class zT{get name(){return"EXT_texture_exr"}parser;constructor(e){this.parser=e,wy&&console.log(e)}loadTexture(e){const t=this.name,i=this.parser,n=i.json.textures[e];if(wy&&console.log("EXT_texture_exr.loadTexture",e,n),!n.extensions||!n.extensions[t])return null;const s=n.extensions[t],r=new Gm(i.options.manager);return wy&&console.log("EXT_texture_exr.loadTexture",s),i.loadTextureImage(e,s.source,r)}}typeof window<"u"&&window.addEventListener("unhandledrejection",o=>{});const ho=_t,mp="$___Export_Components",NT="NEEDLE_components";class WT{[Er]}class VT{node;nodeIndex;nodeDef;constructor(e,t,i){this.node=e,this.nodeIndex=t,this.nodeDef=i}}class Qx{get name(){return NT}exportContext;objectToNodeMap={};context;writer;registerExport(e){e.register(t=>{if("serializeUserData"in t){const i=t.serializeUserData.bind(t);this.writer=t,t.serializeUserData=(n,s)=>{try{this.serializeUserData(n,s)&&(t.extensionsUsed[this.name]=!0),i(n,s)}finally{this.afterSerializeUserData(n,s)}}}return this})}beforeParse(){this.exportContext={},this.objectToNodeMap={}}serializeUserData(e,t){const i=e.userData?.components;return!i||i.length<=0?!1:(delete e.userData.components,e[mp]=i,!0)}afterSerializeUserData(e,t){if(e.type==="Scene"&&ho&&console.log("DONE",JSON.stringify(t)),e[mp]===void 0)return;const i=e[mp];delete e[mp],i!==null&&(e.userData.components=i)}writeNode(e,t){const i=this.writer.json.nodes.length;ho&&console.log(e.name,i,e.uuid);const n=new VT(e,i,t);this.exportContext[i]=n,this.objectToNodeMap[e.uuid]=i}afterParse(e){ho&&console.log("AFTER",e);for(const t in this.exportContext){const i=this.exportContext[t],n=i.node,s=i.nodeDef,r=i.nodeIndex,a=n.userData?.components;if(!a||a.length<=0)continue;const l=new WT;s.extensions=s.extensions||{},s.extensions[this.name]=l,this.context.object=n,this.context.nodeId=r,this.context.objectToNode=this.objectToNodeMap;const c=[];for(const h of a){this.context.target=h;const d=On().writeBuiltinComponentData(h,this.context);d!==null&&c.push(d)}c.length>0&&(l[Er]=c,ho&&console.log("DID WRITE",n,"nodeIndex",r,c))}}parser;nodeToObjectMap={};gltf=null;beforeRoot(){return ho&&console.log("BEGIN LOAD"),this.nodeToObjectMap={},null}async afterRoot(e){this.gltf=e;const t=e.parser,i=t?.extensions;if(!i)return;const n=i[this.name];ho&&console.log("After root",e,this.parser,i);const s=[];if(n===!0){const r=t.json.nodes;if(r){for(let a=0;a<r.length;a++){const l=await t.getDependency("node",a);this.nodeToObjectMap[a]=l}for(let a=0;a<r.length;a++){const l=r[a],c=a,h=l.extensions;if(!h)continue;const d=h[this.name];if(!d)continue;ho&&console.log("NODE",l);const p=this.nodeToObjectMap[c];if(!p){console.error("Could not find object for node index: "+c,l,t);continue}Ru(p),s.push(this.createComponents(e,l,p,d))}}}await Promise.all(s);for(const r of t.associations.keys()){const a=t.associations.get(r);if(a?.materials!=null){const l="/materials/"+a.materials;eM(r,l)}}}async createComponents(e,t,i,n){if(!n)return;const s=n[Er];if(s){const r=new Array;ho&&console.log(i.name,s);for(const a in s){const l=s[a];if(ho&&console.log("Serialized data",JSON.parse(JSON.stringify(l))),(l?.name==="MeshRenderer"||l?.name==="SkinnedMeshRenderer")&&!l.sharedMaterials){let c=!1;if("mesh"in t){const h=t.mesh;if(typeof h=="number"&&e.parser){const d=e.parser.json.meshes?.[h];d?.primitives&&(l.sharedMaterials=d.primitives.map(p=>"/materials/"+(p.material??0)),c=!0)}}!c&&(ho||A())&&console.warn(`[NEEDLE_components] Component '${l.name}' on object '${i.name}' is not added to a mesh or failed to retrieve materials from glTF.`)}l&&this.parser&&r.push(Ng(this.parser,l).catch(c=>console.error(`Error while resolving references (see console for details)
1000
- `,c,i,l))),i.userData=i.userData||{},i.userData[Er]=i.userData[Er]||[],i.userData[Er].push(l)}await Promise.all(r).catch(a=>{console.error("Error while loading components",a)})}}}const Yx="NEEDLE_gameobject_data";class $T{get name(){return Yx}parser;constructor(e){this.parser=e}afterRoot(e){const t=[];for(let i=0;i<this.parser.json.nodes?.length;i++){const n=this.parser.json.nodes[i];if(n&&n.extensions){const s=n.extensions[Yx];if(s){const r=this.findAndApplyExtensionData(i,s);t.push(r)}}}return Promise.all(t).then(()=>null)}async findAndApplyExtensionData(e,t){const i=await this.parser.getDependency("node",e);i&&this.applyExtensionData(i,t)}applyExtensionData(e,t){t.layers===void 0&&(t.layers=0),e.userData.layer=t.layers,e.layers.disableAll(),e.layers.set(t.layers),e.userData.tag=t.tag??"none",e.hideFlags=0,e.userData.static=t.static??!1,e.visible=t.activeSelf??!0,e.guid=t.guid}}const Zx="NEEDLE_lighting_settings",wl=w("debugenvlight");class HT{get name(){return Zx}parser;sourceId;context;constructor(e,t,i){this.parser=e,this.sourceId=t,this.context=i}afterRoot(e){const t=this.parser.json.extensions;if(t){const i=t[Zx];if(i){wl&&console.log('Loaded "'+this.name+'", src: "'+this.sourceId+'"',i);let n;if(e.scene.children.length===1){const s=e.scene.children[0];n=S.addComponent(s,gp,{},{callAwake:!1})}else{const s=new M;s.name="LightSettings "+this.sourceId,e.scene.add(s),n=S.addComponent(s,gp,{},{callAwake:!1})}n.sourceId=this.sourceId,n.ambientIntensity=i.ambientIntensity,n.ambientLight=new oe().fromArray(i.ambientLight),Array.isArray(i.ambientTrilight)&&(n.ambientTrilight=i.ambientTrilight.map(s=>new oe().fromArray(s))),n.ambientMode=i.ambientMode,n.environmentReflectionSource=i.environmentReflectionSource}}return null}}pe.registerCallback(ue.ContextCreated,o=>{const e=o.context,t=S.findObjectOfType(gp,e);t?.sourceId&&(t.enabled=!0)});class gp extends R{ambientMode=Ka.Skybox;ambientLight;ambientTrilight;ambientIntensity=1;environmentReflectionSource=yu.Skybox;_hasReflection=!1;_ambientLightObj;_hemisphereLightObj;awake(){if(this.sourceId){const t=this.environmentReflectionSource===yu.Skybox?to.Skybox:to.Reflection,i=this.context.lightmaps.tryGet(this.sourceId,t,0);this._hasReflection=i!=null,i&&this.context.sceneLighting.internalRegisterReflection(this.sourceId,i)}this.enabled=!1,this.context.sceneLighting.internalRegisterSceneLightSettings(this),wl&&window.addEventListener("keydown",t=>{this.destroyed||t.key==="l"&&(this.enabled=!this.enabled)});const e=this.gameObject.userData?.components;if(e){const t=e.indexOf(this);e.splice(t,1),e.push(this)}}onDestroy(){this.context.sceneLighting.internalUnregisterSceneLightSettings(this)}calculateIntensityFactor(e){const t=Math.max(e.r,e.g,e.b);return 2.2*D.lerp(0,1.33,t)}onEnable(){if(wl&&console.warn("\u{1F4A1}\u{1F7E1} >>> Enable lighting",this.sourceId,this.enabled,this),this.ambientMode==Ka.Flat){if(this.ambientLight&&!this._ambientLightObj){const e=this.calculateIntensityFactor(this.ambientLight);this._ambientLightObj=new XC(this.ambientLight,this.ambientIntensity*e),wl&&console.log("Created ambient light",this.sourceId,this._ambientLightObj,this.ambientIntensity,e)}this._ambientLightObj&&this.gameObject.add(this._ambientLightObj)}else if(this.ambientMode===Ka.Trilight){if(this.ambientTrilight){const e=this.ambientTrilight[0],t=this.ambientTrilight[this.ambientTrilight.length-1],i=this.calculateIntensityFactor(t);this._hemisphereLightObj=new QC(t,e,this.ambientIntensity*i),this.gameObject.add(this._hemisphereLightObj),wl&&console.log("Created hemisphere ambient light",this.sourceId,this._hemisphereLightObj,this.ambientIntensity,i)}}else this._ambientLightObj&&this._ambientLightObj.removeFromParent(),this._hemisphereLightObj&&this._hemisphereLightObj.removeFromParent();this.sourceId&&(this.context.domElement.getAttribute("environment-image")||this.context.sceneLighting.internalEnableReflection(this.sourceId))}onDisable(){wl&&console.warn("\u{1F4A1}\u26AB <<< Disable lighting:",this.sourceId,this),this._ambientLightObj&&this._ambientLightObj.removeFromParent(),this._hemisphereLightObj&&this._hemisphereLightObj.removeFromParent(),this.sourceId&&this.context.sceneLighting.internalDisableReflection(this.sourceId)}}var fp;(o=>{async function e(t,i){if(!t)throw new Error("URL or XML string is required to load a MaterialX material");const n=await T.MaterialX.load(),s=t.trimStart().startsWith("<"),r=s?t:await fetch(t).then(c=>c.text()).catch(console.error);if(!r)return console.warn("Failed to load MaterialX file from url",t),null;let a;if(i?.url||!s){const c=(i?.url||t).split("/");c.pop(),a=c.join("/")}const l=new _r;return n.Experimental_API.createMaterialXMaterial(r,i?.materialNameOrIndex??0,{getTexture:async c=>(!c.startsWith("http")&&!c.startsWith("data:")&&!c.startsWith("blob:")&&!c.startsWith("file:")&&a&&(c=a+"/"+c),l.loadAsync(c).catch(h=>{console.warn(`Failed to load texture for MaterialX material ${c}`,h)}))},{cacheKey:t})}o.loadFromUrl=e})(fp||(fp={}));class GT extends YC{loadAsync(e,t){return new Promise((i,n)=>{this.load(e,i,t,n)})}load(e,t,i,n){i?.({type:"progress",loaded:0,total:0}),fp.loadFromUrl(e,{}).then(s=>{s?t(this.onLoaded(s)):n?.(new Error("Failed to load MaterialX material from url: "+e))})}onLoaded(e){return Ms.createPrimitive("ShaderBall",{material:e})}}class qT{constructor(e,t,i,n){this.context=e,this.loader=t,this.url=i,this.parser=n}get name(){return"materialx-loading-helper"}mtlxLoader;async beforeRoot(){if(this.parser.json.extensions?.NEEDLE_materials_mtlx){const e=await T.MaterialX.load();try{this.mtlxLoader=new e.MaterialXLoader(this.parser,{cacheKey:`${this.url}:materialx`,parameters:{precision:this.context.renderer?.capabilities.precision}},{getFrame:()=>this.context.time.frame,getTime:()=>this.context.time.time})}catch(t){console.error(t)}}}loadMaterial(e){return this.mtlxLoader?this.mtlxLoader.loadMaterial(e):null}}var Kx=(o=>(o[o.INT=5124]="INT",o[o.FLOAT=5126]="FLOAT",o[o.FLOAT_VEC2=35664]="FLOAT_VEC2",o[o.FLOAT_VEC3=35665]="FLOAT_VEC3",o[o.FLOAT_VEC4=35666]="FLOAT_VEC4",o[o.INT_VEC2=35667]="INT_VEC2",o[o.INT_VEC3=35668]="INT_VEC3",o[o.INT_VEC4=35669]="INT_VEC4",o[o.BOOL=35670]="BOOL",o[o.BOOL_VEC2=35671]="BOOL_VEC2",o[o.BOOL_VEC3=35672]="BOOL_VEC3",o[o.BOOL_VEC4=35673]="BOOL_VEC4",o[o.FLOAT_MAT2=35674]="FLOAT_MAT2",o[o.FLOAT_MAT3=35675]="FLOAT_MAT3",o[o.FLOAT_MAT4=35676]="FLOAT_MAT4",o[o.SAMPLER_2D=35678]="SAMPLER_2D",o[o.SAMPLER_3D=35680]="SAMPLER_3D",o[o.SAMPLER_CUBE=35681]="SAMPLER_CUBE",o[o.UNKNOWN=0]="UNKNOWN",o))(Kx||{});const uo=w("debugcustomshader"),xl="NEEDLE_techniques_webgl";class XT{objectToWorldMatrix=new J;worldToObjectMatrix=new J;objectToWorld=new Array;worldToObject=new Array;updateFrom(e){this.objectToWorldMatrix.copy(e.matrixWorld),fu(this.objectToWorldMatrix,this.objectToWorld),this.worldToObjectMatrix.copy(e.matrixWorld).invert(),fu(this.worldToObjectMatrix,this.worldToObject)}}class Te extends jb{identifier;onBeforeRenderSceneCallback=this.onBeforeRenderScene.bind(this);clone(){const e=super.clone();return Jx(e),e}constructor(e,...t){super(...t),this.identifier=e,uo&&console.log(this),this.type="NEEDLE_CUSTOM_SHADER",this.uniforms[this._objToWorldName]||(this.uniforms[this._objToWorldName]={value:[]}),this.uniforms[this._worldToObjectName]||(this.uniforms[this._worldToObjectName]={value:[]}),this.uniforms[this._viewProjectionName]||(this.uniforms[this._viewProjectionName]={value:[]}),this.uniforms[this._sphericalHarmonicsName],(this.depthTextureUniform||this.opaqueTextureUniform)&&z.Current.pre_render_callbacks.push(this.onBeforeRenderSceneCallback)}dispose(){super.dispose();const e=z.Current.pre_render_callbacks.indexOf(this.onBeforeRenderSceneCallback);e>=0&&z.Current.pre_render_callbacks.splice(e,1)}_sphericalHarmonicsName="unity_SpecCube0";_objToWorldName="hlslcc_mtx4x4unity_ObjectToWorld";_worldToObjectName="hlslcc_mtx4x4unity_WorldToObject";static viewProjection=new J;static _viewProjectionValues=[];_viewProjectionName="hlslcc_mtx4x4unity_MatrixVP";static viewMatrix=new J;static _viewMatrixValues=[];_viewMatrixName="hlslcc_mtx4x4unity_MatrixV";static _worldSpaceCameraPosName="_WorldSpaceCameraPos";static _worldSpaceCameraPos=new b;static _mainLightColor=new ye;static _mainLightPosition=new b;static _lightData=new ye;_rendererData=new XT;get depthTextureUniform(){if(this.uniforms)return this.uniforms._CameraDepthTexture}get opaqueTextureUniform(){if(this.uniforms)return this.uniforms._CameraOpaqueTexture}onBeforeRenderScene(){this.opaqueTextureUniform&&z.Current.setRequireColor(!0),this.depthTextureUniform&&z.Current.setRequireDepth(!0)}onBeforeRender(e,t,i,n,s,r){n.attributes.tangent||n.computeTangents(),this.onUpdateUniforms(i,s)}onUpdateUniforms(e,t){const i=z.Current;if(e&&(Te.viewProjection&&this.uniforms[this._viewProjectionName]&&(Te.viewProjection.copy(e.projectionMatrix).multiply(e.matrixWorldInverse),fu(Te.viewProjection,Te._viewProjectionValues)),Te.viewMatrix&&this.uniforms[this._viewMatrixName]&&(Te.viewMatrix.copy(e.matrixWorldInverse),fu(Te.viewMatrix,Te._viewMatrixValues)),this.uniforms[Te._worldSpaceCameraPosName]&&Te._worldSpaceCameraPos.setFromMatrixPosition(e.matrixWorld)),this.uniforms._TimeParameters&&(this.uniforms._TimeParameters.value=i.sceneLighting.timeVec4),this.uniforms._Time){const a=this.uniforms._Time.value;a.x=i.sceneLighting.timeVec4.x/20,a.y=i.sceneLighting.timeVec4.x,a.z=i.sceneLighting.timeVec4.x*2,a.w=i.sceneLighting.timeVec4.x*3}if(this.uniforms._SinTime){const a=this.uniforms._SinTime.value;a.x=Math.sin(i.sceneLighting.timeVec4.x/8),a.y=Math.sin(i.sceneLighting.timeVec4.x/4),a.z=Math.sin(i.sceneLighting.timeVec4.x/2),a.w=Math.sin(i.sceneLighting.timeVec4.x)}if(this.uniforms._CosTime){const a=this.uniforms._CosTime.value;a.x=Math.cos(i.sceneLighting.timeVec4.x/8),a.y=Math.cos(i.sceneLighting.timeVec4.x/4),a.z=Math.cos(i.sceneLighting.timeVec4.x/2),a.w=Math.cos(i.sceneLighting.timeVec4.x)}if(this.uniforms.unity_DeltaTime){const a=this.uniforms.unity_DeltaTime.value;a.x=i.time.deltaTime,a.y=1/i.time.deltaTime,a.z=i.time.smoothedDeltaTime,a.w=1/i.time.smoothedDeltaTime}const n=i.mainLight;if(n){const a=ee(n.gameObject,Te._mainLightPosition);this.uniforms._MainLightPosition={value:a.normalize()},Te._mainLightColor.set(n.color.r,n.color.g,n.color.b,0),this.uniforms._MainLightColor={value:Te._mainLightColor};const l=n.intensity;Te._lightData.z=l,this.uniforms.unity_LightData={value:Te._lightData}}if(e&&(Te.viewProjection&&this.uniforms[this._viewProjectionName]&&(this.uniforms[this._viewProjectionName].value=Te._viewProjectionValues),Te.viewMatrix&&this.uniforms[this._viewMatrixName]&&(this.uniforms[this._viewMatrixName].value=Te._viewMatrixValues),this.uniforms[Te._worldSpaceCameraPosName]&&(this.uniforms[Te._worldSpaceCameraPosName]={value:Te._worldSpaceCameraPos}),i.mainCameraComponent)){if(this.uniforms._ProjectionParams){const a=this.uniforms._ProjectionParams.value;a.x=1,a.y=i.mainCameraComponent.nearClipPlane,a.z=i.mainCameraComponent.farClipPlane,a.w=1/a.z,this.uniforms._ProjectionParams.value=a}if(this.uniforms._ZBufferParams){const a=this.uniforms._ZBufferParams.value,l=i.mainCameraComponent;a.x=1-l.farClipPlane/l.nearClipPlane,a.y=l.farClipPlane/l.nearClipPlane,a.z=a.x/l.farClipPlane,a.w=a.y/l.farClipPlane,this.uniforms._ZBufferParams.value=a}if(this.uniforms._ScreenParams){const a=this.uniforms._ScreenParams.value;a.x=i.domWidth,a.y=i.domHeight,a.z=1+1/a.x,a.w=1+1/a.y,this.uniforms._ScreenParams.value=a}if(this.uniforms._ScaledScreenParams){const a=this.uniforms._ScaledScreenParams.value;a.x=i.domWidth,a.y=i.domHeight,a.z=1+1/a.x,a.w=1+1/a.y,this.uniforms._ScaledScreenParams.value=a}}const s=this.depthTextureUniform;s&&(s.value=i.depthTexture);const r=this.opaqueTextureUniform;if(r&&(r.value=i.opaqueColorTexture),t){const a=this._rendererData;a.updateFrom(t),this.uniforms[this._worldToObjectName].value=a.worldToObject,this.uniforms[this._objToWorldName].value=a.objectToWorld}this.uniformsNeedUpdate=!0}}class QT{get name(){return xl}parser;identifier;constructor(e,t){this.parser=e,this.identifier=t}loadMaterial(e){const t=this.parser.json.materials[e];if(!t)return uo&&console.log(e,this.parser.json.materials),null;if(!t.extensions||!t.extensions[xl])return uo&&console.log(`Material ${e} does not use NEEDLE_techniques_webgl`),null;uo&&console.log(`Material ${e} uses NEEDLE_techniques_webgl`,t);const i=t.extensions[xl].technique;if(i<0)return console.debug(`Material ${e} does not have a valid technique index`),null;const n=this.parser.json.extensions[xl];if(!n)return uo?console.error("Missing shader data",this.parser.json.extensions):console.debug("Missing custom shader data in parser.json.extensions"),null;uo&&console.log(n);const s=n.techniques[i];return s?new Promise(async(r,a)=>{const l=await IM(n,s.program),c=l?.fragmentShader,h=l?.vertexShader;if(!c||!h)return a();uo&&console.log("loadMaterial",t,l);const d={},p=s.uniforms;(h.includes("_Time")||c.includes("_Time"))&&(d._Time={value:new ye(0,0,0,0)}),(h.includes("_SinTime")||c.includes("_SinTime"))&&(d._SinTime={value:new ye(0,0,0,0)}),(h.includes("_CosTime")||c.includes("_CosTime"))&&(d._CosTime={value:new ye(0,0,0,0)}),(h.includes("unity_DeltaTime")||c.includes("unity_DeltaTime"))&&(d.unity_DeltaTime={value:new ye(0,0,0,0)});for(const g in p){const y=g;switch(y){case"_TimeParameters":const _=new ye;d[y]={value:_};break;case"hlslcc_mtx4x4unity_MatrixV":case"hlslcc_mtx4x4unity_MatrixVP":d[y]={value:[]};break;case"_MainLightPosition":case"_MainLightColor":case"_WorldSpaceCameraPos":d[y]={value:[0,0,0,1]};break;case"unity_OrthoParams":break;case"unity_SpecCube0":d[y]={value:null};break;default:case"_ScreenParams":case"_ZBufferParams":case"_ProjectionParams":d[y]={value:[0,0,0,0]};break;case"_CameraOpaqueTexture":case"_CameraDepthTexture":d[y]={value:null};break}}let m=!1;if(t.extensions&&t.extensions[xl]){const g=t.extensions[xl];if(g.technique===i){uo&&console.log(t.name,"Material Properties",g);for(const y in g.values){const _=g.values[y];if(typeof _=="string"){if(_.startsWith("/textures/")){const v=_.substring(10),P=Number.parseInt(v);if(P>=0){const k=await this.parser.getDependency("texture",P);k instanceof Se&&(k.colorSpace=Ro,k.needsUpdate=!0),d[y]={value:k};continue}}if(y==="alphaMode"){_==="BLEND"&&(m=!0);continue}}if(Array.isArray(_)&&_.length===4){d[y]={value:new ye(_[0],_[1],_[2],_[3])};continue}d[y]={value:_}}}}const f=new Te(this.identifier,{name:t.name??"",uniforms:d,vertexShader:h,fragmentShader:c,lights:!1});switch(f.glslVersion=ZC,f.vertexShader=f.vertexShader.replace("#version 300 es",""),f.fragmentShader=f.fragmentShader.replace("#version 300 es",""),d._Cull?.value){case 0:f.side=Ei;break;case 1:f.side=Ud;break;case 2:f.side=Ss;break;default:f.side=Ss;break}switch(d._ZTest?.value){case 3:f.depthTest=!0,f.depthFunc=oP;break;case 6:f.depthTest=!0,f.depthFunc=nP;break;case 2:f.depthTest=!0,f.depthFunc=iP;break;case 4:f.depthTest=!0,f.depthFunc=tP;break;case 5:f.depthTest=!0,f.depthFunc=eP;break;case 7:f.depthTest=!0,f.depthFunc=JC;break;case 8:f.depthTest=!1,f.depthFunc=KC;break}f.transparent=m,m&&(f.depthWrite=!1),TM(d),f.onUpdateUniforms();for(const g in p){const y=g,_=p[g].type;d[y]?.value===void 0&&(_===Kx.SAMPLER_2D?(d[y]={value:RM},console.warn("Missing/unassigned texture, fallback to white: "+y)):y==="unity_OrthoParams"||console.warn("TODO: EXPECTED UNIFORM / fallback NOT SET: "+y,p[g]))}uo&&console.log(f.uuid,d),Jx(f),r(f)}):null}}function Jx(o){if(o.uniforms){uo&&console.log("Uniforms:",o.uniforms);for(const t in o.uniforms)switch(e(t,t),t){case"_Color":e("color",t);break;case"_map":e("map",t);break}}function e(t,i){Object.getOwnPropertyDescriptor(o,t)||Object.defineProperty(o,t,{get:()=>o.uniforms[i].value,set:n=>{o.uniforms[i].value=n,o.needsUpdate=!0}})}}const YT=w("debugextensions");let yp;const ZT=import("./vendor-BgzAK9of.min.js").then(o=>o.index$2).then(async o=>(yp=o.GLTFAnimationPointerExtension,yp)).catch(o=>{console.warn("Failed to import GLTFLoaderAnimationPointer. Please use @needle-tools/three-animationpointer for full KHR_animation support",o)}),ta=new Array;function KT(o){ta.includes(o)||ta.push(o)}function JT(o){const e=ta.indexOf(o);e>=0&&ta.splice(e,1)}function xy(o){if(o instanceof Io){const e=new Qx;return o.register(t=>(e.parser=t,e)),e}return null}class eA{resolvePath(e){return e.includes("/extensions/builtin_components/")?e.replace("/extensions/builtin_components/","/userData/components/"):e.includes("extensions/builtin_components/")?e.replace("extensions/builtin_components/","/userData/components/"):e}}async function bp(o,e,t,i){const n=t.indexOf("?");n>=0&&(t=t.substring(0,n)),i||(i=t),(i.startsWith("blob:")||i.startsWith("data:"))&&console.debug("[GLTFLoader] Suspicious sourceId detected"),o.register(s=>new $T(s)),o.register(s=>new iM(s)),o.register(s=>new bM(s,e.lightmaps,i)),o.register(s=>new HT(s,i,e)),o.register(s=>new QT(s,i)),o.register(s=>new gr(s,i)),o.register(s=>new He(s)),o.register(s=>new zT(s)),o.register(s=>new Em(s)),o.register(s=>new qT(e,o,t,s)),Aw()&&o.register(s=>new rc(s)),await ZT.catch(s=>{}),o.register(s=>{if(yp){const r=new yp(s);return r.setAnimationPointerResolver.bind(r)(new eA),r}else return(YT||A())&&console.error("Missing KHR_animation_pointer extension..."),{name:"KHR_animation_pointer_NOT_AVAILABLE"}});for(const s of ta)s.onImport&&s.onImport(o,t,e)}function Sy(o,e){for(const t of ta)t.onExport&&t.onExport(o,e)}function e1(o,e,t){for(const i of ta)i.onLoaded&&i.onLoaded(o,e,t)}const Ht=w("debuginstancing");class Ma{static instance=new Ma;static getStartInstanceCount=e=>4;objs=[];setup(e,t,i,n,s,r=0){e.applySettings(t);const a=this.tryCreateOrAddInstance(t,i,s);if(a){n===null&&(n=[]),n.push(a);const l=a.object.material;Array.isArray(l)?l.forEach(d=>He.assignTextureLOD(d,0)):He.assignTextureLOD(l,0);const c=a.object,h=c.geometry;He.assignMeshLOD(c,0).then(d=>{d&&h!=d&&a.setGeometry(d)})}else if(r<=0&&t.type!=="Mesh"){const l=r+1;for(const c of t.children)n=this.setup(e,c,i,n,s,l)}return r===0&&s.useMatrixWorldAutoUpdate&&n&&n.length>=0&&this.autoUpdateInstanceMatrix(t),n}tryCreateOrAddInstance(e,t,i){if(e.type==="Mesh"){const n=i.foundMeshes;if(i.foundMeshes+=1,!i.rend.enableInstancing)return null;if(i.rend.enableInstancing!==!0){if(n>=i.rend.enableInstancing.length)return Ht&&console.error("Something is wrong with instance setup",e,i.rend.enableInstancing,n),null;if(!i.rend.enableInstancing[n])return null}const s=e,r=s.material;for(const h of this.objs)if(!!h.canAdd(s.geometry,r))return h.addInstance(s);let a=Ma.getStartInstanceCount(e);(!a||a<0)&&(a=4);let l=e.name;l?.length||(l=c_());const c=new tA(l,s.geometry,r,a,t);return this.objs.push(c),c.addInstance(s)}return null}autoUpdateInstanceMatrix(e){const t=e.matrixWorld.multiplyMatrices.bind(e.matrixWorld),i=e.matrixWorld.clone(),n=(s,r)=>{const a=t(s,r);return(e[zc]||i.equals(a)===!1)&&(i.copy(a),e[zc]=!0),a};e.matrixWorld.multiplyMatrices=n}}class Aa{static all=[];get name(){return this.object.name}get isActive(){return this.__instanceIndex>=0}get vertexCount(){return this.object.geometry.attributes.position.count}get maxVertexCount(){return Math.max(this.meshInformation.vertexCount,this.vertexCount)}get reservedVertexCount(){return this.__reservedVertexRange}get indexCount(){return this.object.geometry.index?this.object.geometry.index.count:0}get maxIndexCount(){return Math.max(this.meshInformation.indexCount,this.indexCount)}get reservedIndexCount(){return this.__reservedIndexRange}object;renderer;__instanceIndex=-1;__reservedVertexRange=0;__reservedIndexRange=0;__geometryIndex=-1;meshInformation;constructor(e,t){this.__instanceIndex=-1,this.object=e,this.renderer=t,e[Bw]=t,this.meshInformation=ia(e.geometry),Aa.all.push(this)}updateMeshInformation(){const e=ia(this.object.geometry),t=this.meshInformation.vertexCount,i=this.meshInformation.indexCount;return Object.assign(this.meshInformation,e),t!==this.meshInformation.vertexCount||i!==this.meshInformation.indexCount}updateInstanceMatrix(e=!1,t=!0){this.__instanceIndex<0||(t&&this.object.updateWorldMatrix(!0,e),this.renderer.updateInstance(this.object.matrixWorld,this.__instanceIndex))}setMatrix(e){this.__instanceIndex<0||this.renderer.updateInstance(e,this.__instanceIndex)}setGeometry(e){if(this.__geometryIndex<0)return!1;const t=this;if(this.vertexCount>this.__reservedVertexRange)return i(`Instancing: Can not update geometry (${this.name}), reserved vertex range is too small: ${this.__reservedVertexRange.toLocaleString()} < ${this.vertexCount.toLocaleString()} vertices for ${this.name}`);if(this.indexCount>this.__reservedIndexRange)return i(`Instancing: Can not update geometry (${this.name}), reserved index range is too small: ${this.__reservedIndexRange.toLocaleString()} < ${this.indexCount.toLocaleString()} indices for ${this.name}`);return this.renderer.updateGeometry(e,this.__geometryIndex);function i(n){return t.updateMeshInformation()&&(t.renderer.remove(t,!0),t.renderer.add(t))?!0:((A()||Ht)&&console.error(n),!1)}}add(){this.__instanceIndex>=0||(this.renderer.add(this),S.markAsInstancedRendered(this.object,!0))}remove(e){if(!(this.__instanceIndex<0)&&(this.renderer.remove(this,e),S.markAsInstancedRendered(this.object,!1),e)){const t=Aa.all.indexOf(this);t>=0&&Aa.all.splice(t,1)}}}class tA{get batchedMesh(){return this._batchedMesh}get visible(){return this._batchedMesh.visible}set visible(e){this._batchedMesh.visible=e}get castShadow(){return this._batchedMesh.castShadow}set castShadow(e){this._batchedMesh.castShadow=e}set receiveShadow(e){this._batchedMesh.receiveShadow=e}allowResize=!0;name="";geometry;material;get count(){return this._currentInstanceCount}updateBounds(e=!0,t=!0){if(this._needUpdateBounds=!1,e&&this._batchedMesh.computeBoundingBox(),t&&this._batchedMesh.computeBoundingSphere(),Ht&&this._batchedMesh.boundingSphere){const i=this._batchedMesh.boundingSphere;B.DrawWireSphere(i.center,i.radius,65280)}}_context;_batchedMesh;_handles=[];_geometryIds=new WeakMap;_maxInstanceCount;_currentInstanceCount=0;_currentVertexCount=0;_currentIndexCount=0;_maxVertexCount;_maxIndexCount;static nullMatrix=new J;canAdd(e,t){return this._maxVertexCount>1e7||t!==this.material||!this.validateGeometry(e)?!1:!!(!this.mustGrow(e)||this.allowResize)}_needUpdateBounds=!1;_debugMaterial=null;getBatchedMeshName(){return this.name?`${this.name} (BatchedMesh)`:"BatchedMesh"}constructor(e,t,i,n,s){this.name=e,this.geometry=t,this.material=i,this._context=s,this._maxInstanceCount=Math.max(2,n),Ht&&(this._debugMaterial=t1());const r=this.tryEstimateVertexCountSize(this._maxInstanceCount,[t],n);this._maxVertexCount=r.vertexCount,this._maxIndexCount=r.indexCount,this._batchedMesh=new Bb(this._maxInstanceCount,this._maxVertexCount,this._maxIndexCount,this._debugMaterial??this.material),this._batchedMesh.name=this.getBatchedMeshName(),this._batchedMesh[Nc]=!0,this._batchedMesh.visible=!0,this._context.scene.add(this._batchedMesh),i instanceof jb&&(i.defines.USE_INSTANCING=!0,i.needsUpdate=!0),s.pre_render_callbacks.push(this.onBeforeRender),s.post_render_callbacks.push(this.onAfterRender),Ht&&console.log(`Instanced renderer (${this.name}) created with ${this._maxInstanceCount} instances, ${this._maxVertexCount} max vertices and ${this._maxIndexCount} max indices for "${e}"`)}dispose(){Ht&&console.warn("Dispose instanced renderer",this.name),this._context.scene.remove(this._batchedMesh),this._batchedMesh.dispose(),this._batchedMesh=null,this._handles=[]}addInstance(e){const t=new Aa(e,this);e.castShadow===!0&&this._batchedMesh.castShadow===!1&&(this._batchedMesh.castShadow=!0),e.receiveShadow===!0&&this._batchedMesh.receiveShadow===!1&&(this._batchedMesh.receiveShadow=!0);try{this.add(t)}catch(i){if(console.error(`Failed adding mesh to instancing (object name: "${e.name}", instances: ${this._currentInstanceCount.toLocaleString()}/${this._maxInstanceCount.toLocaleString()}, vertices: ${this._currentVertexCount.toLocaleString()}/${this._maxVertexCount.toLocaleString()}, indices: ${this._currentIndexCount.toLocaleString()}/${this._maxIndexCount.toLocaleString()})
1000
+ `,c,i,l))),i.userData=i.userData||{},i.userData[Er]=i.userData[Er]||[],i.userData[Er].push(l)}await Promise.all(r).catch(a=>{console.error("Error while loading components",a)})}}}const Yx="NEEDLE_gameobject_data";class $T{get name(){return Yx}parser;constructor(e){this.parser=e}afterRoot(e){const t=[];for(let i=0;i<this.parser.json.nodes?.length;i++){const n=this.parser.json.nodes[i];if(n&&n.extensions){const s=n.extensions[Yx];if(s){const r=this.findAndApplyExtensionData(i,s);t.push(r)}}}return Promise.all(t).then(()=>null)}async findAndApplyExtensionData(e,t){const i=await this.parser.getDependency("node",e);i&&this.applyExtensionData(i,t)}applyExtensionData(e,t){t.layers===void 0&&(t.layers=0),e.userData.layer=t.layers,e.layers.disableAll(),e.layers.set(t.layers),e.userData.tag=t.tag??"none",e.hideFlags=0,e.userData.static=t.static??!1,e.visible=t.activeSelf??!0,e.guid=t.guid}}const Zx="NEEDLE_lighting_settings",wl=w("debugenvlight");class HT{get name(){return Zx}parser;sourceId;context;constructor(e,t,i){this.parser=e,this.sourceId=t,this.context=i}afterRoot(e){const t=this.parser.json.extensions;if(t){const i=t[Zx];if(i){wl&&console.log('Loaded "'+this.name+'", src: "'+this.sourceId+'"',i);let n;if(e.scene.children.length===1){const s=e.scene.children[0];n=S.addComponent(s,gp,{},{callAwake:!1})}else{const s=new M;s.name="LightSettings "+this.sourceId,e.scene.add(s),n=S.addComponent(s,gp,{},{callAwake:!1})}n.sourceId=this.sourceId,n.ambientIntensity=i.ambientIntensity,n.ambientLight=new oe().fromArray(i.ambientLight),Array.isArray(i.ambientTrilight)&&(n.ambientTrilight=i.ambientTrilight.map(s=>new oe().fromArray(s))),n.ambientMode=i.ambientMode,n.environmentReflectionSource=i.environmentReflectionSource}}return null}}pe.registerCallback(ue.ContextCreated,o=>{const e=o.context,t=S.findObjectOfType(gp,e);t?.sourceId&&(t.enabled=!0)});class gp extends R{ambientMode=Ka.Skybox;ambientLight;ambientTrilight;ambientIntensity=1;environmentReflectionSource=yu.Skybox;_hasReflection=!1;_ambientLightObj;_hemisphereLightObj;awake(){if(this.sourceId){const t=this.environmentReflectionSource===yu.Skybox?to.Skybox:to.Reflection,i=this.context.lightmaps.tryGet(this.sourceId,t,0);this._hasReflection=i!=null,i&&this.context.sceneLighting.internalRegisterReflection(this.sourceId,i)}this.enabled=!1,this.context.sceneLighting.internalRegisterSceneLightSettings(this),wl&&window.addEventListener("keydown",t=>{this.destroyed||t.key==="l"&&(this.enabled=!this.enabled)});const e=this.gameObject.userData?.components;if(e){const t=e.indexOf(this);e.splice(t,1),e.push(this)}}onDestroy(){this.context.sceneLighting.internalUnregisterSceneLightSettings(this)}calculateIntensityFactor(e){const t=Math.max(e.r,e.g,e.b);return 2.2*D.lerp(0,1.33,t)}onEnable(){if(wl&&console.warn("\u{1F4A1}\u{1F7E1} >>> Enable lighting",this.sourceId,this.enabled,this),this.ambientMode==Ka.Flat){if(this.ambientLight&&!this._ambientLightObj){const e=this.calculateIntensityFactor(this.ambientLight);this._ambientLightObj=new XC(this.ambientLight,this.ambientIntensity*e),wl&&console.log("Created ambient light",this.sourceId,this._ambientLightObj,this.ambientIntensity,e)}this._ambientLightObj&&this.gameObject.add(this._ambientLightObj)}else if(this.ambientMode===Ka.Trilight){if(this.ambientTrilight){const e=this.ambientTrilight[0],t=this.ambientTrilight[this.ambientTrilight.length-1],i=this.calculateIntensityFactor(t);this._hemisphereLightObj=new QC(t,e,this.ambientIntensity*i),this.gameObject.add(this._hemisphereLightObj),wl&&console.log("Created hemisphere ambient light",this.sourceId,this._hemisphereLightObj,this.ambientIntensity,i)}}else this._ambientLightObj&&this._ambientLightObj.removeFromParent(),this._hemisphereLightObj&&this._hemisphereLightObj.removeFromParent();this.sourceId&&(this.context.domElement.getAttribute("environment-image")||this.context.sceneLighting.internalEnableReflection(this.sourceId))}onDisable(){wl&&console.warn("\u{1F4A1}\u26AB <<< Disable lighting:",this.sourceId,this),this._ambientLightObj&&this._ambientLightObj.removeFromParent(),this._hemisphereLightObj&&this._hemisphereLightObj.removeFromParent(),this.sourceId&&this.context.sceneLighting.internalDisableReflection(this.sourceId)}}var fp;(o=>{async function e(t,i){if(!t)throw new Error("URL or XML string is required to load a MaterialX material");const n=await T.MaterialX.load(),s=t.trimStart().startsWith("<"),r=s?t:await fetch(t).then(c=>c.text()).catch(console.error);if(!r)return console.warn("Failed to load MaterialX file from url",t),null;let a;if(i?.url||!s){const c=(i?.url||t).split("/");c.pop(),a=c.join("/")}const l=new _r;return n.Experimental_API.createMaterialXMaterial(r,i?.materialNameOrIndex??0,{getTexture:async c=>(!c.startsWith("http")&&!c.startsWith("data:")&&!c.startsWith("blob:")&&!c.startsWith("file:")&&a&&(c=a+"/"+c),l.loadAsync(c).catch(h=>{console.warn(`Failed to load texture for MaterialX material ${c}`,h)}))},{cacheKey:t})}o.loadFromUrl=e})(fp||(fp={}));class GT extends YC{loadAsync(e,t){return new Promise((i,n)=>{this.load(e,i,t,n)})}load(e,t,i,n){i?.({type:"progress",loaded:0,total:0}),fp.loadFromUrl(e,{}).then(s=>{s?t(this.onLoaded(s)):n?.(new Error("Failed to load MaterialX material from url: "+e))})}onLoaded(e){return Ms.createPrimitive("ShaderBall",{material:e})}}class qT{constructor(e,t,i,n){this.context=e,this.loader=t,this.url=i,this.parser=n}get name(){return"materialx-loading-helper"}mtlxLoader;async beforeRoot(){if(this.parser.json.extensions?.NEEDLE_materials_mtlx){const e=await T.MaterialX.load();try{this.mtlxLoader=new e.MaterialXLoader(this.parser,{cacheKey:`${this.url}:materialx`,parameters:{precision:this.context.renderer?.capabilities.precision}},{getFrame:()=>this.context.time.frame,getTime:()=>this.context.time.time})}catch(t){console.error(t)}}}loadMaterial(e){return this.mtlxLoader?this.mtlxLoader.loadMaterial(e):null}}var Kx=(o=>(o[o.INT=5124]="INT",o[o.FLOAT=5126]="FLOAT",o[o.FLOAT_VEC2=35664]="FLOAT_VEC2",o[o.FLOAT_VEC3=35665]="FLOAT_VEC3",o[o.FLOAT_VEC4=35666]="FLOAT_VEC4",o[o.INT_VEC2=35667]="INT_VEC2",o[o.INT_VEC3=35668]="INT_VEC3",o[o.INT_VEC4=35669]="INT_VEC4",o[o.BOOL=35670]="BOOL",o[o.BOOL_VEC2=35671]="BOOL_VEC2",o[o.BOOL_VEC3=35672]="BOOL_VEC3",o[o.BOOL_VEC4=35673]="BOOL_VEC4",o[o.FLOAT_MAT2=35674]="FLOAT_MAT2",o[o.FLOAT_MAT3=35675]="FLOAT_MAT3",o[o.FLOAT_MAT4=35676]="FLOAT_MAT4",o[o.SAMPLER_2D=35678]="SAMPLER_2D",o[o.SAMPLER_3D=35680]="SAMPLER_3D",o[o.SAMPLER_CUBE=35681]="SAMPLER_CUBE",o[o.UNKNOWN=0]="UNKNOWN",o))(Kx||{});const uo=w("debugcustomshader"),xl="NEEDLE_techniques_webgl";class XT{objectToWorldMatrix=new J;worldToObjectMatrix=new J;objectToWorld=new Array;worldToObject=new Array;updateFrom(e){this.objectToWorldMatrix.copy(e.matrixWorld),fu(this.objectToWorldMatrix,this.objectToWorld),this.worldToObjectMatrix.copy(e.matrixWorld).invert(),fu(this.worldToObjectMatrix,this.worldToObject)}}class Te extends jb{identifier;onBeforeRenderSceneCallback=this.onBeforeRenderScene.bind(this);clone(){const e=super.clone();return Jx(e),e}constructor(e,...t){super(...t),this.identifier=e,uo&&console.log(this),this.type="NEEDLE_CUSTOM_SHADER",this.uniforms[this._objToWorldName]||(this.uniforms[this._objToWorldName]={value:[]}),this.uniforms[this._worldToObjectName]||(this.uniforms[this._worldToObjectName]={value:[]}),this.uniforms[this._viewProjectionName]||(this.uniforms[this._viewProjectionName]={value:[]}),this.uniforms[this._sphericalHarmonicsName],(this.depthTextureUniform||this.opaqueTextureUniform)&&z.Current.pre_render_callbacks.push(this.onBeforeRenderSceneCallback)}dispose(){super.dispose();const e=z.Current.pre_render_callbacks.indexOf(this.onBeforeRenderSceneCallback);e>=0&&z.Current.pre_render_callbacks.splice(e,1)}_sphericalHarmonicsName="unity_SpecCube0";_objToWorldName="hlslcc_mtx4x4unity_ObjectToWorld";_worldToObjectName="hlslcc_mtx4x4unity_WorldToObject";static viewProjection=new J;static _viewProjectionValues=[];_viewProjectionName="hlslcc_mtx4x4unity_MatrixVP";static viewMatrix=new J;static _viewMatrixValues=[];_viewMatrixName="hlslcc_mtx4x4unity_MatrixV";static _worldSpaceCameraPosName="_WorldSpaceCameraPos";static _worldSpaceCameraPos=new b;static _mainLightColor=new ye;static _mainLightPosition=new b;static _lightData=new ye;_rendererData=new XT;get depthTextureUniform(){if(this.uniforms)return this.uniforms._CameraDepthTexture}get opaqueTextureUniform(){if(this.uniforms)return this.uniforms._CameraOpaqueTexture}onBeforeRenderScene(){this.opaqueTextureUniform&&z.Current.setRequireColor(!0),this.depthTextureUniform&&z.Current.setRequireDepth(!0)}onBeforeRender(e,t,i,n,s,r){n.attributes.tangent||n.computeTangents(),this.onUpdateUniforms(i,s)}onUpdateUniforms(e,t){const i=z.Current;if(e&&(Te.viewProjection&&this.uniforms[this._viewProjectionName]&&(Te.viewProjection.copy(e.projectionMatrix).multiply(e.matrixWorldInverse),fu(Te.viewProjection,Te._viewProjectionValues)),Te.viewMatrix&&this.uniforms[this._viewMatrixName]&&(Te.viewMatrix.copy(e.matrixWorldInverse),fu(Te.viewMatrix,Te._viewMatrixValues)),this.uniforms[Te._worldSpaceCameraPosName]&&Te._worldSpaceCameraPos.setFromMatrixPosition(e.matrixWorld)),this.uniforms._TimeParameters&&(this.uniforms._TimeParameters.value=i.sceneLighting.timeVec4),this.uniforms._Time){const a=this.uniforms._Time.value;a.x=i.sceneLighting.timeVec4.x/20,a.y=i.sceneLighting.timeVec4.x,a.z=i.sceneLighting.timeVec4.x*2,a.w=i.sceneLighting.timeVec4.x*3}if(this.uniforms._SinTime){const a=this.uniforms._SinTime.value;a.x=Math.sin(i.sceneLighting.timeVec4.x/8),a.y=Math.sin(i.sceneLighting.timeVec4.x/4),a.z=Math.sin(i.sceneLighting.timeVec4.x/2),a.w=Math.sin(i.sceneLighting.timeVec4.x)}if(this.uniforms._CosTime){const a=this.uniforms._CosTime.value;a.x=Math.cos(i.sceneLighting.timeVec4.x/8),a.y=Math.cos(i.sceneLighting.timeVec4.x/4),a.z=Math.cos(i.sceneLighting.timeVec4.x/2),a.w=Math.cos(i.sceneLighting.timeVec4.x)}if(this.uniforms.unity_DeltaTime){const a=this.uniforms.unity_DeltaTime.value;a.x=i.time.deltaTime,a.y=1/i.time.deltaTime,a.z=i.time.smoothedDeltaTime,a.w=1/i.time.smoothedDeltaTime}const n=i.mainLight;if(n){const a=ee(n.gameObject,Te._mainLightPosition);this.uniforms._MainLightPosition={value:a.normalize()},Te._mainLightColor.set(n.color.r,n.color.g,n.color.b,0),this.uniforms._MainLightColor={value:Te._mainLightColor};const l=n.intensity;Te._lightData.z=l,this.uniforms.unity_LightData={value:Te._lightData}}if(e&&(Te.viewProjection&&this.uniforms[this._viewProjectionName]&&(this.uniforms[this._viewProjectionName].value=Te._viewProjectionValues),Te.viewMatrix&&this.uniforms[this._viewMatrixName]&&(this.uniforms[this._viewMatrixName].value=Te._viewMatrixValues),this.uniforms[Te._worldSpaceCameraPosName]&&(this.uniforms[Te._worldSpaceCameraPosName]={value:Te._worldSpaceCameraPos}),i.mainCameraComponent)){if(this.uniforms._ProjectionParams){const a=this.uniforms._ProjectionParams.value;a.x=1,a.y=i.mainCameraComponent.nearClipPlane,a.z=i.mainCameraComponent.farClipPlane,a.w=1/a.z,this.uniforms._ProjectionParams.value=a}if(this.uniforms._ZBufferParams){const a=this.uniforms._ZBufferParams.value,l=i.mainCameraComponent;a.x=1-l.farClipPlane/l.nearClipPlane,a.y=l.farClipPlane/l.nearClipPlane,a.z=a.x/l.farClipPlane,a.w=a.y/l.farClipPlane,this.uniforms._ZBufferParams.value=a}if(this.uniforms._ScreenParams){const a=this.uniforms._ScreenParams.value;a.x=i.domWidth,a.y=i.domHeight,a.z=1+1/a.x,a.w=1+1/a.y,this.uniforms._ScreenParams.value=a}if(this.uniforms._ScaledScreenParams){const a=this.uniforms._ScaledScreenParams.value;a.x=i.domWidth,a.y=i.domHeight,a.z=1+1/a.x,a.w=1+1/a.y,this.uniforms._ScaledScreenParams.value=a}}const s=this.depthTextureUniform;s&&(s.value=i.depthTexture);const r=this.opaqueTextureUniform;if(r&&(r.value=i.opaqueColorTexture),t){const a=this._rendererData;a.updateFrom(t),this.uniforms[this._worldToObjectName].value=a.worldToObject,this.uniforms[this._objToWorldName].value=a.objectToWorld}this.uniformsNeedUpdate=!0}}class QT{get name(){return xl}parser;identifier;constructor(e,t){this.parser=e,this.identifier=t}loadMaterial(e){const t=this.parser.json.materials[e];if(!t)return uo&&console.log(e,this.parser.json.materials),null;if(!t.extensions||!t.extensions[xl])return uo&&console.log(`Material ${e} does not use NEEDLE_techniques_webgl`),null;uo&&console.log(`Material ${e} uses NEEDLE_techniques_webgl`,t);const i=t.extensions[xl].technique;if(i<0)return console.debug(`Material ${e} does not have a valid technique index`),null;const n=this.parser.json.extensions[xl];if(!n)return uo?console.error("Missing shader data",this.parser.json.extensions):console.debug("Missing custom shader data in parser.json.extensions"),null;uo&&console.log(n);const s=n.techniques[i];return s?new Promise(async(r,a)=>{const l=await IM(n,s.program),c=l?.fragmentShader,h=l?.vertexShader;if(!c||!h)return a();uo&&console.log("loadMaterial",t,l);const d={},p=s.uniforms;(h.includes("_Time")||c.includes("_Time"))&&(d._Time={value:new ye(0,0,0,0)}),(h.includes("_SinTime")||c.includes("_SinTime"))&&(d._SinTime={value:new ye(0,0,0,0)}),(h.includes("_CosTime")||c.includes("_CosTime"))&&(d._CosTime={value:new ye(0,0,0,0)}),(h.includes("unity_DeltaTime")||c.includes("unity_DeltaTime"))&&(d.unity_DeltaTime={value:new ye(0,0,0,0)});for(const g in p){const y=g;switch(y){case"_TimeParameters":const _=new ye;d[y]={value:_};break;case"hlslcc_mtx4x4unity_MatrixV":case"hlslcc_mtx4x4unity_MatrixVP":d[y]={value:[]};break;case"_MainLightPosition":case"_MainLightColor":case"_WorldSpaceCameraPos":d[y]={value:[0,0,0,1]};break;case"unity_OrthoParams":break;case"unity_SpecCube0":d[y]={value:null};break;default:case"_ScreenParams":case"_ZBufferParams":case"_ProjectionParams":d[y]={value:[0,0,0,0]};break;case"_CameraOpaqueTexture":case"_CameraDepthTexture":d[y]={value:null};break}}let m=!1;if(t.extensions&&t.extensions[xl]){const g=t.extensions[xl];if(g.technique===i){uo&&console.log(t.name,"Material Properties",g);for(const y in g.values){const _=g.values[y];if(typeof _=="string"){if(_.startsWith("/textures/")){const v=_.substring(10),P=Number.parseInt(v);if(P>=0){const k=await this.parser.getDependency("texture",P);k instanceof Se&&(k.colorSpace=Ro,k.needsUpdate=!0),d[y]={value:k};continue}}if(y==="alphaMode"){_==="BLEND"&&(m=!0);continue}}if(Array.isArray(_)&&_.length===4){d[y]={value:new ye(_[0],_[1],_[2],_[3])};continue}d[y]={value:_}}}}const f=new Te(this.identifier,{name:t.name??"",uniforms:d,vertexShader:h,fragmentShader:c,lights:!1});switch(f.glslVersion=ZC,f.vertexShader=f.vertexShader.replace("#version 300 es",""),f.fragmentShader=f.fragmentShader.replace("#version 300 es",""),d._Cull?.value){case 0:f.side=Ei;break;case 1:f.side=Ud;break;case 2:f.side=Ss;break;default:f.side=Ss;break}switch(d._ZTest?.value){case 3:f.depthTest=!0,f.depthFunc=oP;break;case 6:f.depthTest=!0,f.depthFunc=nP;break;case 2:f.depthTest=!0,f.depthFunc=iP;break;case 4:f.depthTest=!0,f.depthFunc=tP;break;case 5:f.depthTest=!0,f.depthFunc=eP;break;case 7:f.depthTest=!0,f.depthFunc=JC;break;case 8:f.depthTest=!1,f.depthFunc=KC;break}f.transparent=m,m&&(f.depthWrite=!1),TM(d),f.onUpdateUniforms();for(const g in p){const y=g,_=p[g].type;d[y]?.value===void 0&&(_===Kx.SAMPLER_2D?(d[y]={value:RM},console.warn("Missing/unassigned texture, fallback to white: "+y)):y==="unity_OrthoParams"||console.warn("TODO: EXPECTED UNIFORM / fallback NOT SET: "+y,p[g]))}uo&&console.log(f.uuid,d),Jx(f),r(f)}):null}}function Jx(o){if(o.uniforms){uo&&console.log("Uniforms:",o.uniforms);for(const t in o.uniforms)switch(e(t,t),t){case"_Color":e("color",t);break;case"_map":e("map",t);break}}function e(t,i){Object.getOwnPropertyDescriptor(o,t)||Object.defineProperty(o,t,{get:()=>o.uniforms[i].value,set:n=>{o.uniforms[i].value=n,o.needsUpdate=!0}})}}const YT=w("debugextensions");let yp;const ZT=import("./vendor-Bf43L3CE.min.js").then(o=>o.index$2).then(async o=>(yp=o.GLTFAnimationPointerExtension,yp)).catch(o=>{console.warn("Failed to import GLTFLoaderAnimationPointer. Please use @needle-tools/three-animationpointer for full KHR_animation support",o)}),ta=new Array;function KT(o){ta.includes(o)||ta.push(o)}function JT(o){const e=ta.indexOf(o);e>=0&&ta.splice(e,1)}function xy(o){if(o instanceof Io){const e=new Qx;return o.register(t=>(e.parser=t,e)),e}return null}class eA{resolvePath(e){return e.includes("/extensions/builtin_components/")?e.replace("/extensions/builtin_components/","/userData/components/"):e.includes("extensions/builtin_components/")?e.replace("extensions/builtin_components/","/userData/components/"):e}}async function bp(o,e,t,i){const n=t.indexOf("?");n>=0&&(t=t.substring(0,n)),i||(i=t),(i.startsWith("blob:")||i.startsWith("data:"))&&console.debug("[GLTFLoader] Suspicious sourceId detected"),o.register(s=>new $T(s)),o.register(s=>new iM(s)),o.register(s=>new bM(s,e.lightmaps,i)),o.register(s=>new HT(s,i,e)),o.register(s=>new QT(s,i)),o.register(s=>new gr(s,i)),o.register(s=>new He(s)),o.register(s=>new zT(s)),o.register(s=>new Em(s)),o.register(s=>new qT(e,o,t,s)),Aw()&&o.register(s=>new rc(s)),await ZT.catch(s=>{}),o.register(s=>{if(yp){const r=new yp(s);return r.setAnimationPointerResolver.bind(r)(new eA),r}else return(YT||A())&&console.error("Missing KHR_animation_pointer extension..."),{name:"KHR_animation_pointer_NOT_AVAILABLE"}});for(const s of ta)s.onImport&&s.onImport(o,t,e)}function Sy(o,e){for(const t of ta)t.onExport&&t.onExport(o,e)}function e1(o,e,t){for(const i of ta)i.onLoaded&&i.onLoaded(o,e,t)}const Ht=w("debuginstancing");class Ma{static instance=new Ma;static getStartInstanceCount=e=>4;objs=[];setup(e,t,i,n,s,r=0){e.applySettings(t);const a=this.tryCreateOrAddInstance(t,i,s);if(a){n===null&&(n=[]),n.push(a);const l=a.object.material;Array.isArray(l)?l.forEach(d=>He.assignTextureLOD(d,0)):He.assignTextureLOD(l,0);const c=a.object,h=c.geometry;He.assignMeshLOD(c,0).then(d=>{d&&h!=d&&a.setGeometry(d)})}else if(r<=0&&t.type!=="Mesh"){const l=r+1;for(const c of t.children)n=this.setup(e,c,i,n,s,l)}return r===0&&s.useMatrixWorldAutoUpdate&&n&&n.length>=0&&this.autoUpdateInstanceMatrix(t),n}tryCreateOrAddInstance(e,t,i){if(e.type==="Mesh"){const n=i.foundMeshes;if(i.foundMeshes+=1,!i.rend.enableInstancing)return null;if(i.rend.enableInstancing!==!0){if(n>=i.rend.enableInstancing.length)return Ht&&console.error("Something is wrong with instance setup",e,i.rend.enableInstancing,n),null;if(!i.rend.enableInstancing[n])return null}const s=e,r=s.material;for(const h of this.objs)if(!!h.canAdd(s.geometry,r))return h.addInstance(s);let a=Ma.getStartInstanceCount(e);(!a||a<0)&&(a=4);let l=e.name;l?.length||(l=c_());const c=new tA(l,s.geometry,r,a,t);return this.objs.push(c),c.addInstance(s)}return null}autoUpdateInstanceMatrix(e){const t=e.matrixWorld.multiplyMatrices.bind(e.matrixWorld),i=e.matrixWorld.clone(),n=(s,r)=>{const a=t(s,r);return(e[zc]||i.equals(a)===!1)&&(i.copy(a),e[zc]=!0),a};e.matrixWorld.multiplyMatrices=n}}class Aa{static all=[];get name(){return this.object.name}get isActive(){return this.__instanceIndex>=0}get vertexCount(){return this.object.geometry.attributes.position.count}get maxVertexCount(){return Math.max(this.meshInformation.vertexCount,this.vertexCount)}get reservedVertexCount(){return this.__reservedVertexRange}get indexCount(){return this.object.geometry.index?this.object.geometry.index.count:0}get maxIndexCount(){return Math.max(this.meshInformation.indexCount,this.indexCount)}get reservedIndexCount(){return this.__reservedIndexRange}object;renderer;__instanceIndex=-1;__reservedVertexRange=0;__reservedIndexRange=0;__geometryIndex=-1;meshInformation;constructor(e,t){this.__instanceIndex=-1,this.object=e,this.renderer=t,e[Bw]=t,this.meshInformation=ia(e.geometry),Aa.all.push(this)}updateMeshInformation(){const e=ia(this.object.geometry),t=this.meshInformation.vertexCount,i=this.meshInformation.indexCount;return Object.assign(this.meshInformation,e),t!==this.meshInformation.vertexCount||i!==this.meshInformation.indexCount}updateInstanceMatrix(e=!1,t=!0){this.__instanceIndex<0||(t&&this.object.updateWorldMatrix(!0,e),this.renderer.updateInstance(this.object.matrixWorld,this.__instanceIndex))}setMatrix(e){this.__instanceIndex<0||this.renderer.updateInstance(e,this.__instanceIndex)}setGeometry(e){if(this.__geometryIndex<0)return!1;const t=this;if(this.vertexCount>this.__reservedVertexRange)return i(`Instancing: Can not update geometry (${this.name}), reserved vertex range is too small: ${this.__reservedVertexRange.toLocaleString()} < ${this.vertexCount.toLocaleString()} vertices for ${this.name}`);if(this.indexCount>this.__reservedIndexRange)return i(`Instancing: Can not update geometry (${this.name}), reserved index range is too small: ${this.__reservedIndexRange.toLocaleString()} < ${this.indexCount.toLocaleString()} indices for ${this.name}`);return this.renderer.updateGeometry(e,this.__geometryIndex);function i(n){return t.updateMeshInformation()&&(t.renderer.remove(t,!0),t.renderer.add(t))?!0:((A()||Ht)&&console.error(n),!1)}}add(){this.__instanceIndex>=0||(this.renderer.add(this),S.markAsInstancedRendered(this.object,!0))}remove(e){if(!(this.__instanceIndex<0)&&(this.renderer.remove(this,e),S.markAsInstancedRendered(this.object,!1),e)){const t=Aa.all.indexOf(this);t>=0&&Aa.all.splice(t,1)}}}class tA{get batchedMesh(){return this._batchedMesh}get visible(){return this._batchedMesh.visible}set visible(e){this._batchedMesh.visible=e}get castShadow(){return this._batchedMesh.castShadow}set castShadow(e){this._batchedMesh.castShadow=e}set receiveShadow(e){this._batchedMesh.receiveShadow=e}allowResize=!0;name="";geometry;material;get count(){return this._currentInstanceCount}updateBounds(e=!0,t=!0){if(this._needUpdateBounds=!1,e&&this._batchedMesh.computeBoundingBox(),t&&this._batchedMesh.computeBoundingSphere(),Ht&&this._batchedMesh.boundingSphere){const i=this._batchedMesh.boundingSphere;B.DrawWireSphere(i.center,i.radius,65280)}}_context;_batchedMesh;_handles=[];_geometryIds=new WeakMap;_maxInstanceCount;_currentInstanceCount=0;_currentVertexCount=0;_currentIndexCount=0;_maxVertexCount;_maxIndexCount;static nullMatrix=new J;canAdd(e,t){return this._maxVertexCount>1e7||t!==this.material||!this.validateGeometry(e)?!1:!!(!this.mustGrow(e)||this.allowResize)}_needUpdateBounds=!1;_debugMaterial=null;getBatchedMeshName(){return this.name?`${this.name} (BatchedMesh)`:"BatchedMesh"}constructor(e,t,i,n,s){this.name=e,this.geometry=t,this.material=i,this._context=s,this._maxInstanceCount=Math.max(2,n),Ht&&(this._debugMaterial=t1());const r=this.tryEstimateVertexCountSize(this._maxInstanceCount,[t],n);this._maxVertexCount=r.vertexCount,this._maxIndexCount=r.indexCount,this._batchedMesh=new Bb(this._maxInstanceCount,this._maxVertexCount,this._maxIndexCount,this._debugMaterial??this.material),this._batchedMesh.name=this.getBatchedMeshName(),this._batchedMesh[Nc]=!0,this._batchedMesh.visible=!0,this._context.scene.add(this._batchedMesh),i instanceof jb&&(i.defines.USE_INSTANCING=!0,i.needsUpdate=!0),s.pre_render_callbacks.push(this.onBeforeRender),s.post_render_callbacks.push(this.onAfterRender),Ht&&console.log(`Instanced renderer (${this.name}) created with ${this._maxInstanceCount} instances, ${this._maxVertexCount} max vertices and ${this._maxIndexCount} max indices for "${e}"`)}dispose(){Ht&&console.warn("Dispose instanced renderer",this.name),this._context.scene.remove(this._batchedMesh),this._batchedMesh.dispose(),this._batchedMesh=null,this._handles=[]}addInstance(e){const t=new Aa(e,this);e.castShadow===!0&&this._batchedMesh.castShadow===!1&&(this._batchedMesh.castShadow=!0),e.receiveShadow===!0&&this._batchedMesh.receiveShadow===!1&&(this._batchedMesh.receiveShadow=!0);try{this.add(t)}catch(i){if(console.error(`Failed adding mesh to instancing (object name: "${e.name}", instances: ${this._currentInstanceCount.toLocaleString()}/${this._maxInstanceCount.toLocaleString()}, vertices: ${this._currentVertexCount.toLocaleString()}/${this._maxVertexCount.toLocaleString()}, indices: ${this._currentIndexCount.toLocaleString()}/${this._maxIndexCount.toLocaleString()})
1001
1001
  `,i),A()){wc("Failed instancing mesh. See the browser console for details.");debugger}return null}return t}add(e){const t=e.object.geometry;if(!t||!t.attributes)return console.error("Cannot add object to instancing without geometry",e.name),!1;if(this._currentInstanceCount+1>this._maxInstanceCount||this.mustGrow(t))if(this.allowResize)this.grow(t);else return console.error("Cannot add instance, max count reached",this.name,this.count,this._maxInstanceCount),!1;return e.object.updateWorldMatrix(!0,!0),this.addGeometry(e),this._handles[e.__instanceIndex]=e,this._currentInstanceCount+=1,this.markNeedsUpdate(),this._currentInstanceCount>0&&(this._batchedMesh.visible=!0),!0}remove(e,t){e&&(e.__instanceIndex<0||this._handles[e.__instanceIndex]!=e||this._currentInstanceCount<=0||(this.removeGeometry(e,t),this._handles[e.__instanceIndex]=null,e.__instanceIndex=-1,this._currentInstanceCount>0&&(this._currentInstanceCount-=1),this._currentInstanceCount<=0&&(this._batchedMesh.visible=!1),this.markNeedsUpdate()))}updateInstance(e,t){this._batchedMesh.setMatrixAt(t,e),this.markNeedsUpdate()}updateGeometry(e,t){return this.validateGeometry(e)?(this.mustGrow()&&this.grow(e),Ht&&console.debug("[Instancing] UPDATE GEOMETRY at "+t,this._batchedMesh._geometryCount,e.name,ia(e),e.attributes.position.count,e.index?e.index.count:0),this._batchedMesh.setGeometryAt(t,e),this._geometryIds.set(e,t),this.markNeedsUpdate(),!0):!1}onBeforeRender=()=>{this._batchedMesh.layers.enableAll(),this._needUpdateBounds&&this._batchedMesh[Nc]===!0&&(Ht==="verbose"&&console.log("Update instancing bounds",this.name,this._batchedMesh.matrixWorldNeedsUpdate),this.updateBounds())};onAfterRender=()=>{this._batchedMesh.layers.disableAll()};validateGeometry(e){const t=this.geometry;for(const i in t.attributes)if(i!=="batchId"&&!e.hasAttribute(i))return A()&&console.warn(`BatchedMesh: Added geometry missing "${i}". All geometries must have consistent attributes.`),!1;return!0}markNeedsUpdate(){Ht==="verbose"&&console.warn("Marking instanced mesh dirty",this.name),this._needUpdateBounds=!0}mustGrow(e){if(this.count>=this._maxInstanceCount)return!0;if(!e||!e.attributes||this._geometryIds.has(e))return!1;const t=ia(e),i=t.vertexCount,n=t.indexCount;return this._currentVertexCount+i>this._maxVertexCount||this._currentIndexCount+n>this._maxIndexCount}_growId=0;grow(e){const t=++this._growId,i=this.count>=this._maxInstanceCount?Math.ceil(this._maxInstanceCount*2):this._maxInstanceCount,n=this.tryEstimateVertexCountSize(i,[e]),s=1.25,r=Math.max(this._maxVertexCount,Math.ceil(n.vertexCount*s)),a=Math.max(this._maxIndexCount,Math.ceil(n.indexCount*s));if(Ht){const h=ia(e);console.warn(`[Instancing] Growing Buffer
1002
1002
  Mesh: "${this.name}${e.name?.length?"/"+e.name:""}" (${h.vertexCount.toLocaleString()} vertices, ${h.indexCount.toLocaleString()} indices)
1003
1003
  Max count ${this._maxInstanceCount.toLocaleString()} \u2192 ${i.toLocaleString()}