UNPKG

@needle-tools/engine

Version:

Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in.

143 lines (131 loc) 1.28 MB
import{Vector2 as K,Vector3 as b,Vector4 as ye,Quaternion as N,Box3 as Nt,ShadowMaterial as Sb,Euler as ct,PlaneGeometry as Sn,WebGLRenderer as br,PerspectiveCamera as de,OrthographicCamera as Rd,Scene as Mi,Mesh as H,Texture as Se,Uniform$1 as Xi,Color as oe,ShaderMaterial as Hn,MeshStandardMaterial as yt,Box3Helper as nC,GridHelper as Cb,Object3D as M,Material as we,Matrix3 as Pb,Matrix4 as J,Layers as ws,PropertyBinding as La,AnimationClip as Ri,KeyframeTrack as oC,FileLoader as Ob,BufferGeometry as Qi,TextureLoader as _r,MeshBasicMaterial as Ce,DoubleSide as Ei,Group as Oo,CylinderGeometry as kb,SphereGeometry as Ed,BoxGeometry as Da,SpriteMaterial as sC,Sprite as rC,Shape as aC,ExtrudeGeometry as lC,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,Clock as cC,NeutralToneMapping as ja,AgXToneMapping as Id,ACESFilmicToneMapping as Ld,NoToneMapping as Dd,PCFSoftShadowMap$1 as hC,BasicNodeLibrary as dC,WebGLRenderTarget as Gn,DepthTexture as Mb,NearestFilter as jd,AxesHelper as Ti,MathUtils as Ao,Fog as Rb,DirectionalLight as Dm,PointLight as jm,EdgesGeometry as uC,LineSegments as Bm,LineBasicMaterial as Bd,Line as Ba,BufferAttribute as tt,Raycaster as Fd,ArrayCamera as pC,Plane as vr,SkinnedMesh as xs,InterleavedBufferAttribute as Eb,Skeleton as mC,Bone as gC,WebGLCubeRenderTarget as fC,CubeCamera as yC,LoopRepeat as bC,LoopOnce as Fm,AnimationMixer as Um,CompressedTexture as _C,FrontSide as Ss,Camera as vC,Frustum as Tb,AudioListener as wC,PositionalAudio as xC,AudioLoader as zm,VectorKeyframeTrack as SC,QuaternionKeyframeTrack as CC,Audio as PC,BackSide as Ud,PMREMGenerator$1 as OC,EquirectangularRefractionMapping as Ab,CubeTexture as Ib,CompressedCubeTexture as kC,EventDispatcher as Nm,MeshDepthMaterial as MC,CustomBlending as RC,MaxEquation as EC,AlwaysStencilFunc as TC,GreaterEqualStencilFunc as AC,NotEqualStencilFunc as IC,GreaterStencilFunc as LC,LessEqualStencilFunc as DC,EqualStencilFunc as jC,LessStencilFunc as BC,NeverStencilFunc as Lb,InvertStencilOp as FC,DecrementWrapStencilOp as UC,IncrementWrapStencilOp as zC,DecrementStencilOp as NC,IncrementStencilOp as WC,ReplaceStencilOp as VC,ZeroStencilOp as $C,KeepStencilOp as HC,AmbientLight as GC,HemisphereLight as qC,Loader as XC,GLSL3 as QC,AlwaysDepth as YC,GreaterEqualDepth as ZC,GreaterDepth as KC,LessEqualDepth as JC,LessDepth as eP,NotEqualDepth as tP,EqualDepth as iP,RawShaderMaterial as Db,BatchedMesh as jb,LinearFilter as zd,UnsignedByteType as nP,MeshPhysicalMaterial as Bb,RingGeometry as oP,Line3 as sP,AdditiveBlending as Fb,BoxHelper as rP,SpotLight as aP,DirectionalLightHelper as lP,CameraHelper as cP,LOD as hP,Triangle as dP,NormalBlending as uP,ReinhardToneMapping as Wm,LinearToneMapping as Vm,HalfFloatType as $m,Source as pP,VideoTexture as mP,CatmullRomCurve3 as gP,MirroredRepeatWrapping as Ub,ShaderLib as Nd,UniformsUtils as zb,MeshNormalMaterial as fP,AudioContext as yP}from"./three.min.js";import{createLoaders as Hm,LODsManager as wr,NEEDLE_progressive as He,getRaycastMesh as Nb,setKTX2TranscoderLocation as bP,setDracoDecoderLocation as _P,addDracoAndKTX2Loaders as vP,configureLoader as wP}from"./gltf-progressive-BryRjllq.min.js";import{GroundedSkybox as Fa,Font as xP,TextGeometry as SP,FontLoader as CP,GLTFLoader as Io,EXRLoader as Gm,RGBELoader as Wb,Stats as PP,nodeFrame as Vb,TransformControlsGizmo as $b,OrbitControls as OP,PositionalAudioHelper as kP,HorizontalBlurShader as MP,VerticalBlurShader as RP,GLTFExporter as Hb,strToU8 as Gb,zipSync as EP,XRControllerModelFactory as TP,XRHandMeshModel as AP,Line2 as IP,LineGeometry as LP,LineMaterial as DP,TransformControls as jP,InteractiveGroup as BP,HTMLMesh as FP,VertexNormalsHelper as UP,OBJLoader as qm,FBXLoader as qb,mergeVertices as zP}from"./three-examples.min.js";import{_md5 as Xb,md5 as NP,v5 as Qb,ByteBuffer as WP,fetchProfile as VP,MotionController as $P,SIZE_PREFIX_LENGTH as Yb,Builder as Xm,createNoise4D as HP,Matrix4 as Qm,BatchedParticleRenderer as GP,ParticleSystem as qP,RenderMode as Lo,ConstantColor as XP,Vector4 as QP,ConstantValue as YP,TrailParticle as Zb,WorkerBase as ZP,MeshBVH as KP}from"./vendor-DPbfJJ4d.min.js";import{__webpack_exports__default as Oe,__webpack_exports__Text as Kb,__webpack_exports__update as JP,__webpack_exports__Block as Jb,SimpleStateBehavior as eO,__webpack_exports__Inline as Ym,__webpack_exports__FontLibrary as e_,ThreeMeshUI as t_}from"./three-mesh-ui-n3JU4M2W.min.js";import{EffectAttribute as tO}from"./postprocessing-B_9sKVU7.min.js";const i_=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&&(i_&&console.warn("Registering context"),this.Registered.push(e),this.dispatchCallback("ContextRegistered",e))}static unregister(e){const t=this.Registered.indexOf(e);t!==-1&&(i_&&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 n_(){return window.location.hostname.includes("glitch.me")}const o_=()=>o=>o;function iO(o){return o_()(o)}function nO(){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. Append any of these parameters to the URL to enable specific debug options. 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 oO(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?s_(o,i):eg(o,i)}function Jm(o,e,t){o.has(e)?o.set(e,t.toString()):o.append(e,t.toString())}function s_(o,e,t){window.history.pushState(t,o,"?"+e.toString())}function eg(o,e,t){window.history.replaceState(t,o,"?"+e.toString())}function sO(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 rO(o,e){return Math.floor(Math.random()*(e-o+1))+o}const r_=["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"],a_=["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 l_(){const o=r_[Math.floor(Math.random()*r_.length)],e=a_[Math.floor(Math.random()*a_.length)];return o+"_"+e}function c_(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"),h_="rel:";function aO(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(h_)&&(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 from`,e,` to `,n,` basePath: `+i),n}return e}function d_(o){if(o)return o=o.trim(),o=o.split("?")[0]?.split("#")[0],o}class lO{subscribeWrite(e){this.writeCallbacks.push(e)}unsubscribeWrite(e){const t=this.writeCallbacks.indexOf(e);t!==-1&&this.writeCallbacks.splice(t,1)}writeCallbacks=[];constructor(e,t){this._object=e,this._prop=t,this._wrapperProp=Symbol("$"+t),this.apply()}_applied=!1;_object;_prop;_wrapperProp;apply(){if(this._applied||!this._object)return;const e=this._object,t=this._prop;if(e[t]===void 0)return;this._applied=!0,e[this._wrapperProp]!==void 0&&console.warn("Watcher is being applied to an object that already has a wrapper property. This is not (yet) supported");const i=e[t];e[this._wrapperProp]=i,Object.defineProperty(e,t,{get:()=>e[this._wrapperProp],set:n=>{e[this._wrapperProp]=n;for(const s of this.writeCallbacks)s(n,this._prop)}})}revoke(){if(!this._applied||!this._object)return;this._applied=!1;const e=this._object,t=this._prop;Reflect.deleteProperty(e,t);const i=e[this._wrapperProp];e[t]=i,Reflect.deleteProperty(e,this._wrapperProp)}dispose(){this.revoke(),this.writeCallbacks.length=0,this._object=null}}class gs{_watches=[];constructor(e,t){if(Array.isArray(t))for(const i of t)this._watches.push(new gs(e,i));else this._watches.push(new lO(e,t))}subscribeWrite(e){for(const t of this._watches)t.subscribeWrite(e)}unsubscribeWrite(e){for(const t of this._watches)t.unsubscribeWrite(e)}apply(){for(const e of this._watches)e.apply()}revoke(){for(const e of this._watches)e.revoke()}dispose(){for(const e of this._watches)e.dispose();this._watches.length=0}}const za=Symbol("needle:watches");function Vd(o,e){if(!o[za])if(o instanceof K)o[za]=new gs(o,["x","y"]);else if(o instanceof b)o[za]=new gs(o,["x","y","z"]);else if(o instanceof ye||o instanceof N)o[za]=new gs(o,["x","y","z","w"]);else return!1;return o[za].subscribeWrite(e),!0}function tg(o,e){if(!o)return;const t=o[za];t&&t.unsubscribeWrite(e)}var I;(o=>{let e;function t(){if(e!==void 0)return e;const te=window.navigator.userAgent,$e=/Windows|MacOS|Mac OS/.test(te),hi=/Windows NT/.test(te)&&/Edg/.test(te)&&!/Win64/.test(te);return e=$e&&!hi&&!k()}o.isDesktop=t;let i;function n(){return i!==void 0?i:typeof window.orientation<"u"||navigator.userAgent.indexOf("IEMobile")!==-1?i=!0:i=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent)}o.isMobileDevice=n;function s(){return a()}o.isIPad=s;let r;function a(){if(r!==void 0)return r;const te=navigator.userAgent.toLowerCase();return r=/iPad/.test(navigator.userAgent)||te.includes("macintosh")&&"ontouchend"in document}o.isiPad=a;let l;function c(){return l!==void 0?l:l=/Android/.test(navigator.userAgent)}o.isAndroidDevice=c;let h;function d(){return h!==void 0?h:h=/WebXRViewer\//i.test(navigator.userAgent)}o.isMozillaXR=d;let p;function m(){return p!==void 0?p:p=/NeedleAppClip\//i.test(navigator.userAgent)}o.isNeedleAppClip=m;let f;function g(){if(f!==void 0)return f;if(k()||a())return f=!1;const te=navigator.userAgent.toLowerCase();return navigator.userAgentData?f=navigator.userAgentData.platform==="macOS":f=te.includes("mac os x")||te.includes("macintosh")}o.isMacOS=g;let y;function _(){return y!==void 0?y:y=a()&&"xr"in navigator&&G()}o.isVisionOS=_;let v;const P=["iPad Simulator","iPhone Simulator","iPod Simulator","iPad","iPhone","iPod"];function k(){return v!==void 0?v:v=P.includes(navigator.platform)||navigator.userAgent.includes("Mac")&&"ontouchend"in document}o.isiOS=k;let O;function j(){return O!==void 0||(O=/^((?!chrome|android).)*safari/i.test(navigator.userAgent)),O}o.isSafari=j;let L;function V(){return L!==void 0?L:L=navigator.userAgent.includes("OculusBrowser")}o.isQuest=V;let W;function G(){return W!==void 0||(W=document.createElement("a").relList.supports("ar")),W}o.supportsQuickLookAR=G;async function X(){try{return(await navigator.permissions.query({name:"microphone"})).state!=="denied"}catch(te){return console.error("Error querying `microphone` permissions.",te),!1}}o.microphonePermissionsGranted=X;let E;function $(){if(E!==void 0)return E;const te=navigator.userAgent.match(/iPhone OS (\d+_\d+)/);if(te&&(E=te[1].replace("_",".")),!E){const $e=navigator.userAgent.match(/(?:\(Macintosh;|iPhone;|iPad;).*Version\/(\d+\.\d+)/);$e&&(E=$e[1])}return E||(E=null),E}o.getiOSVersion=$;let q;function he(){if(q!==void 0)return q;const te=navigator.userAgent.match(/(?:CriOS|Chrome)\/(\d+\.\d+\.\d+\.\d+)/);return te?q=te[1].replace("_","."):q=null,q}o.getChromeVersion=he;let re;function ge(){if(re!==void 0)return re;const te=navigator.userAgent.match(/Version\/(\d+\.\d+)/);return te&&j()?re=te[1]:re=null,re}o.getSafariVersion=ge})(I||(I={}));function cO(){return I.isDesktop()}function hO(){return I.isMobileDevice()}function dO(){return I.isiPad()}function uO(){return I.isiPad()}function pO(){return I.isAndroidDevice()}function mO(){return I.isMozillaXR()}function gO(){return I.isMacOS()}function fO(){return I.isiOS()}function yO(){return I.isSafari()}function bO(){return I.isQuest()}async function _O(){return I.microphonePermissionsGranted()}const Cs=new WeakMap;function ig(o,e,t){if(!Cs.get(o)){const n=new MutationObserver(s=>{vO(o,s)});Cs.set(o,{observer:n,attributeChangedListeners:new Map}),n.observe(o,{attributes:!0})}const i=Cs.get(o).attributeChangedListeners;return i.has(e)||i.set(e,[]),i.get(e).push(t),()=>{ng(o,e,t)}}function ng(o,e,t){if(!Cs.get(o))return;const i=Cs.get(o).attributeChangedListeners;if(!i.has(e))return;const n=i.get(e),s=n.indexOf(t);s!==-1&&(n.splice(s,1),n.length<=0&&(i.delete(e),Cs.get(o)?.observer.disconnect(),Cs.delete(o)))}function vO(o,e){const t=Cs.get(o).attributeChangedListeners;for(const i of e)if(i.type==="attributes"){const n=i.attributeName,s=o.getAttribute(n);if(t.has(n))for(const r of t.get(n))r(s)}}class og{reason;constructor(e){this.reason=e}}async function sg(o){const e=await Promise.allSettled(o).catch(n=>[new og(n.message)]);let t=!1;const i=e.map(n=>"value"in n?n.value:(t=!0,new og(n.reason)));return{anyFailed:t,results:i}}const wO=w("debugdebug");let rg=!1;(w("noerrors")||w("nooverlaymessages"))&&(rg=!0);const ag="needle_engine_global_error_container";var Li=(o=>(o[o.Log=0]="Log",o[o.Warn=1]="Warn",o[o.Error=2]="Error",o))(Li||{});function u_(){return g_}const lg=new Array;function xO(o){lg.push(o)}let cg=!1;function SO(...o){if(!cg){cg=!0;try{for(let e=0;e<lg.length;e++)lg[e](...o)}catch(e){console.error(e)}cg=!1}}const p_=console.error,CO=function(...o){p_.apply(console,o),kO(o),Sr(2,o,{}),OO(...o)};function m_(o){rg=!o,o?console.error=CO:console.error=p_}function PO(o){return m_(o)}let g_=0;function OO(...o){g_+=1,SO(...o)}function kO(o){if(Array.isArray(o))for(let e=0;e<o.length;e++){const t=o[e];typeof t=="string"&&t.startsWith("THREE.PropertyBinding: Trying to update node for track:")&&(o[e]="Some animated objects couldn't be found: see console for details")}}const f_=new Set;function Sr(o,e,t={},i,n){if(rg)return;if(t.once===!0){let a="";if(Array.isArray(e))for(let l=0;l<e.length;l++){let c=e[l];c instanceof Error&&(c=c.message),typeof c!="object"&&(l>0&&(a+=" "),a+=c)}else typeof e=="string"&&(a=e);if(f_.has(a))return;f_.add(a)}const s=pe.Current;let r=s?.domElement??document.querySelector("needle-engine");if(s?.isInAR&&(r=s.arOverlayElement),!!r){if(Array.isArray(e)){let a="";for(let l=0;l<e.length;l++){let c=e[l];c instanceof Error&&(c=c.message),typeof c!="object"&&(l>0&&(a+=" "),a+=c)}e=a}!e||e.length<=0||MO(o,r,e,t)}}const Na=new Map,y_=.2;function MO(o,e,t,i={}){if(t==null)return;const n=TO(e);if(n.childElementCount>=20){const c=n.lastElementChild;__(c)}t.length>400&&(t=t.substring(0,400)+"...");const s=i.key??t;if(Na.has(s)){Na.get(s)?.update(t,i);return}const r=AO(o,t);n.prepend(r);const a=()=>{Na.delete(s),__(r)};let l=setTimeout(a,Math.max(y_,i.duration??10)*1e3);Na.set(s,{update:(c,h)=>{c.length>400&&(c=c.substring(0,400)+"..."),r.innerHTML=c,h.duration&&(clearTimeout(l),l=setTimeout(a,Math.max(y_,h.duration)*1e3))},removeFunction:a})}function RO(){wO&&console.log("Clearing messages");for(const o of Na.values())o?.removeFunction.call(o);Na.clear()}const EO=` @import url('https://fonts.googleapis.com/css2?family=Roboto+Flex:opsz,wght@8..144,100..1000&display=swap'); div[data-needle_engine_debug_overlay] { font-family: 'Roboto Flex', sans-serif; font-weight: 400; font-size: 16px; } div[data-needle_engine_debug_overlay] strong { font-weight: 700; } div[data-needle_engine_debug_overlay] a { color: white; text-decoration: none; border-bottom: 1px solid rgba(255, 255, 255, 0.3); } div[data-needle_engine_debug_overlay] a:hover { text-decoration: none; border: none; } div[data-needle_engine_debug_overlay] .log strong { color: rgba(200,200,200,.9); } div[data-needle_engine_debug_overlay] .warn strong { color: rgba(255,255,230, 1); } div[data-needle_engine_debug_overlay] .error strong { color: rgba(255,100,120, 1); } `;function TO(o){globalThis[ag]||(globalThis[ag]=new Map);const e=globalThis[ag];if(e.has(o))return e.get(o);{const t=document.createElement("div");e.set(o,t),t.setAttribute("data-needle_engine_debug_overlay",""),t.classList.add("debug-container"),t.style.cssText=` position: absolute; top: 0; right: 5px; padding-top: env(safe-area-inset-top, 0px); max-width: 70%; max-height: calc(100% - 105px); z-index: 100000; pointer-events: scroll; display: flex; align-items: end; flex-direction: column; color: white; overflow: auto; word-break: break-word; `,I.isNeedleAppClip()&&(t.style.left="5px",t.style.right="unset");const i=document.querySelector('meta[name="viewport"]');i&&!i.getAttribute("content")?.includes("viewport-fit=")&&i.setAttribute("content",i.getAttribute("content")+",viewport-fit=cover"),o.shadowRoot?o.shadowRoot.appendChild(t):o.appendChild(t);const n=document.createElement("style");return n.innerHTML=EO,t.appendChild(n),t}}const b_=Symbol("logtype"),$d=new Map;function __(o){o.remove();const e=o[b_],t=$d.get(e)??[];t.push(o),$d.set(e,t)}function AO(o,e){if($d.has(o)){const i=$d.get(o);if(i.length>0){const n=i.pop();return n.innerHTML=e,n}}const t=document.createElement("div");switch(t.setAttribute("data-id","__needle_engine_debug_overlay"),t.style.marginRight="5px",t.style.padding=".5em",t.style.backgroundColor="rgba(0,0,0,.9)",t.style.marginTop="5px",t.style.marginBottom="3px",t.style.borderRadius="8px",t.style.pointerEvents="all",t.style.userSelect="text",t.style.maxWidth="250px",t.style.whiteSpace="pre-wrap",t.style["backdrop-filter"]="blur(10px)",t.style["-webkit-backdrop-filter"]="blur(10px)",t.style.backgroundColor="rgba(20,20,20,.8)",t.style.boxShadow="inset 0 0 80px rgba(0,0,0,.2), 0 0 5px rgba(0,0,0,.2)",t.style.border="1px solid rgba(160,160,160,.2)",t[b_]=o,o){case 0:t.classList.add("log"),t.style.color="rgba(200,200,200,.7)",t.style.backgroundColor="rgba(40,40,40,.7)";break;case 1:t.classList.add("warn"),t.style.color="rgb(255, 255, 150)",t.style.backgroundColor="rgba(50,50,20,.8)";break;case 2:t.classList.add("error"),t.style.color="rgb(255, 50, 50",t.style.backgroundColor="rgba(50,20,20,.8)";break}return t.title="Open the browser console (F12) for more information",t.innerHTML=e,t}const IO=w("nodevlogs");let hg,dg;function A(){if(IO)return!1;if(hg!==void 0)return hg;if(dg!==void 0)return dg;let o=Ai();return o||(o=window.location.hostname.endsWith(".local-credentialless.webcontainer.io")),dg=o,o}function LO(o){hg=o}class DO{random(e,t){return Array.isArray(e)?e.length<=0?null:e[Math.floor(Math.random()*e.length)]:e!==void 0&&t!==void 0?Math.random()*(t-e)+e:Math.random()}randomVector3(e,t=0,i=1){e.x=this.random(t,i),e.y=this.random(t,i),e.z=this.random(t,i)}clamp(e,t,i){return e<t?t:e>i?i:e}clamp01(e){return this.clamp(e,0,1)}lerp(e,t,i){return i=i<0?0:i,i=i>1?1:i,e+(t-e)*i}inverseLerp(e,t,i){return(i-e)/(t-e)}remap(e,t,i,n,s){return n+(s-n)*(e-t)/(i-t)}moveTowards(e,t,i){return e+=i,(i<0&&e<t||i>0&&e>t)&&(e=t),e}Rad2Deg=180/Math.PI;Deg2Rad=Math.PI/180;Epsilon=1e-5;toDegrees(e){return e*180/Math.PI}toRadians(e){return e*Math.PI/180}tan(e){return Math.tan(e)}gammaToLinear(e){return Math.pow(e,2.2)}linearToGamma(e){return Math.pow(e,1/2.2)}approximately(e,t,i=Number.EPSILON){for(const n of jO){const s=e[n],r=t[n];if(s===void 0||r===void 0)break;if(Math.abs(s-r)>i)return!1}return!0}easeInOutCubic(e){return e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2}}const jO=["x","y","z","w"],D=new DO;class v_{y;s;alpha=0;constructor(e){this.setAlpha(e),this.y=null,this.s=null}setAlpha(e){if(e<=0||e>1)throw new Error;this.alpha=e}filter(e,t){t&&this.setAlpha(t);let i;return this.y?i=this.alpha*e+(1-this.alpha)*this.s:i=e,this.y=e,this.s=i,i}lastValue(){return this.y}reset(e){this.y=e,this.s=e}}class Hd{freq;minCutOff;beta;dCutOff;x;dx;lasttime;constructor(e,t=1,i=0,n=1){if(e<=0||t<=0||n<=0)throw new Error;this.freq=e,this.minCutOff=t,this.beta=i,this.dCutOff=n,this.x=new v_(this.alpha(this.minCutOff)),this.dx=new v_(this.alpha(this.dCutOff)),this.lasttime=null}alpha(e){const t=1/this.freq;return 1/(1+1/(2*Math.PI*e)/t)}filter(e,t=null){this.lasttime&&t&&(this.freq=1/(t-this.lasttime)),this.lasttime=t;const i=this.x.lastValue(),n=i?(e-i)*this.freq:0,s=this.dx.filter(n,this.alpha(this.dCutOff)),r=this.minCutOff+this.beta*Math.abs(s);return this.x.filter(e,this.alpha(r))}reset(e){e!=null&&this.x.reset(e),this.x.alpha=this.alpha(this.minCutOff),this.dx.alpha=this.alpha(this.dCutOff),this.lasttime=null}}class ug{x;y;z;constructor(e,t=1,i=0,n=1){this.x=new Hd(e,t,i,n),this.y=new Hd(e,t,i,n),this.z=new Hd(e,t,i,n)}filter(e,t,i=null){t.x=this.x.filter(e.x,i),t.y=this.y.filter(e.y,i),t.z=this.z.filter(e.z,i)}reset(e){this.x.reset(e?.x),this.y.reset(e?.y),this.z.reset(e?.z)}}const Gd="needle:cameraController";function w_(o){return o[Gd]}function pg(o,e,t){t?o[Gd]=e:o[Gd]===e&&(o[Gd]=null)}const mg="needle:autofit";function x_(o){return o[mg]===void 0?!0:o[mg]!==!1}function qd(o,e){o[mg]=e}let Cn;const BO={x:0,y:0,width:0,height:0},FO=w("debugfocusrect");function UO(o,e,t,i,n){o instanceof Element&&(FO&&o instanceof HTMLElement&&(o.style.outline="2px dashed rgba(255, 150, 0, .8)"),o=o.getBoundingClientRect()),Cn=n.domElement.getBoundingClientRect();const s=BO;s.x=o.x,s.y=o.y,s.width=o.width,s.height=o.height,s.x-=Cn.x,s.y-=Cn.y;const r=Cn.width,a=Cn.height,l=i.view,c=e.zoom;let h=l?.offsetX||0,d=l?.offsetY||0,p=Cn.width,m=Cn.height;p/=c,m/=c,h=p*(c-1)*.5,d=m*(c-1)*.5;const f=s.x+s.width*.5,g=s.y+s.height*.5,y=Cn.width*.5,_=Cn.height*.5,v=f-y,P=g-_;h-=v/c,d-=P/c,e.offsetX!==void 0&&(h+=e.offsetX*(Cn.width*.5)),e.offsetY!==void 0&&(d-=e.offsetY*(Cn.height*.5));const k=l?.offsetX||h,O=l?.offsetY||d;h=D.lerp(k,h,t),d=D.lerp(O,d,t);const j=l?.width||r,L=l?.height||a;p=D.lerp(j,p,t),m=D.lerp(L,m,t),i.setViewOffset(r,a,h,d,p,m),i.updateProjectionMatrix(),e.damping>0&&(e.damping*=1-t,e.damping<.01&&(e.damping=0),e.damping=Math.max(0,e.damping))}function S_(o,e,t){const i=o.length(),n=e.length(),s=D.lerp(i,n,t);return o.lerp(e,t).normalize().multiplyScalar(s)}const gg=new N,C_=new N().setFromAxisAngle(new b(0,1,0),Math.PI);function zO(o,e){o.lookAt(e),o.quaternion.multiply(C_)}function yc(o,e,t=!0,i=!1){if(o===e)return;gg.copy(o.quaternion);const n=ee(e),s=ee(o);if(i){if(Pn(o,_e(e)),t){const r=s.y,a=s.sub(R_(o));a.y=r,o.lookAt(a),o.quaternion.multiply(C_)}Number.isNaN(o.quaternion.x)&&o.quaternion.copy(gg);return}t&&(n.y=s.y),o.lookAt(n),Number.isNaN(o.quaternion.x)&&o.quaternion.copy(gg)}function NO(o,e,t,i=1){if(t){const n=F(0,0,0),s=e.x/window.innerWidth*2-1,r=-(e.y/window.innerHeight)*2+1;n.set(s,r,0),n.unproject(t);const a=t.worldPosition,l=o.worldPosition.distanceTo(a),c=n.sub(a);c.multiplyScalar(i*3.6*l);const h=t.worldPosition.add(c);return o.lookAt(h),h}return null}const WO=new Ii(()=>new b,100);function F(o,e,t){const i=WO.get();return i.set(0,0,0),o instanceof b?i.copy(o):Array.isArray(o)?i.set(o[0],o[1],o[2]):o instanceof DOMPointReadOnly?i.set(o.x,o.y,o.z):typeof o=="number"?(i.x=o,i.y=e!==void 0?e:i.x,i.z=t!==void 0?t:i.x):typeof o=="object"&&(i.x=o.x,i.y=o.y,i.z=o.z),i}const VO=new Ii(()=>new oe,30);function P_(o){const e=VO.get();return o?e.copy(o):e.set(0,0,0),e}const $O=new Ii(()=>new N,100);function di(o,e,t,i){const n=$O.get();return n.identity(),o instanceof N?n.copy(o):o instanceof DOMPointReadOnly?n.set(o.x,o.y,o.z,o.w):typeof o=="number"&&e!==void 0&&t!==void 0&&i!==void 0?n.set(o,e,t,i):typeof o=="object"&&"x"in o&&"y"in o&&"z"in o&&"w"in o&&n.set(o.x,o.y,o.z,o.w),n}const fg=new Ii(()=>new b,100),O_=Symbol("lastMatrixWorldUpdateKey");function ee(o,e=null,t=!0){const i=e??fg.get();return o?o.parent?(t&&o.updateWorldMatrix(!0,!1),o.matrixWorldNeedsUpdate&&o[O_]!==Date.now()&&(o[O_]=Date.now(),o.updateMatrixWorld()),i.setFromMatrixPosition(o.matrixWorld),i):i.copy(o.position):i.set(0,0,0)}function bt(o,e){if(!o)return o;const t=fg.get();return e!==t&&t.copy(e),o.parent!==null&&o.parent.worldToLocal(t),o.position.set(t.x,t.y,t.z),o}function Cr(o,e,t,i){const n=fg.get();return n.set(e,t,i),bt(o,n),o}const Xd=new Ii(()=>new N,100),Pr=new N,yg=new N;function _e(o,e=null){if(!o)return Xd.get().identity();const t=e??Xd.get();return o.parent?(o.getWorldQuaternion(t),t):t.copy(o.quaternion)}function Pn(o,e){if(!o)return;e!==Pr&&Pr.copy(e);const t=Pr;o?.parent?.getWorldQuaternion(yg),yg.invert();const i=yg.multiply(t);o.quaternion.set(i.x,i.y,i.z,i.w)}function bg(o,e,t,i,n){Pr.set(e,t,i,n),Pn(o,Pr)}const HO=new Ii(()=>new b,100),GO=new b;function Ge(o,e=null){return e||(e=HO.get()),o?o.parent?(o.getWorldScale(e),e):e.copy(o.scale):e.set(0,0,0)}function Wa(o,e){if(!o)return;if(!o.parent){o.scale.copy(e);return}const t=GO;o.parent.getWorldScale(t),o.scale.copy(e),o.scale.divide(t)}const qO=new b,k_=new N;function XO(o){return _e(o,k_),qO.set(0,0,1).applyQuaternion(k_)}const QO=new Ii(()=>new b,100),M_=new N;function R_(o,e){return e||(e=QO.get().set(0,0,1)),_e(o,M_),e.applyQuaternion(M_)}const E_=new ct,T_=new ct,YO=new b;function _g(o){const e=Xd.get();return o.getWorldQuaternion(e),T_.setFromQuaternion(e),T_}function vg(o,e){const t=Xd.get();Pn(o,t.setFromEuler(e))}function Qd(o){const e=_g(o),t=YO;return t.set(e.x,e.y,e.z),t.x=D.toDegrees(t.x),t.y=D.toDegrees(t.y),t.z=D.toDegrees(t.z),t}function A_(o,e){bc(o,e.x,e.y,e.z,!0)}function bc(o,e,t,i,n=!0){n&&(e=D.toRadians(e),t=D.toRadians(t),i=D.toRadians(i)),E_.set(e,t,i),Pr.setFromEuler(E_),Pn(o,Pr)}function Yd(o,e=!0){o&&(e?function t(i){console.groupCollapsed((i.name?i.name:"(no name : "+i.type+")")+" %o",i),i.children.forEach(t),console.groupEnd()}(o):o.traverse(function(t){for(var i="|___",n=t;n.parent!==null;)i=" "+i,n=n.parent;console.log(i+t.name+" <"+t.type+">")}))}function ZO(o){let e=o?.name||"";if(!o)return e;let t=o.parent;for(;t;)e=t.name+"/"+e,t=t.parent;return e}function I_(o){if(o){const e=o;return e.blendMode!==void 0&&e.clampWhenFinished!==void 0&&e.enabled!==void 0&&e.fadeIn!==void 0&&e.getClip!==void 0}return!1}class Mm extends Hn{static vertex=` varying vec2 vUv; void main(){ vUv = uv; gl_Position = vec4(position.xy, 0., 1.0); }`;constructor(){super({vertexShader:Mm.vertex,uniforms:{map:new Xi(null),flipY:new Xi(!0),writeDepth:new Xi(!1),depthTexture:new Xi(null)},fragmentShader:` uniform sampler2D map; uniform bool flipY; uniform bool writeDepth; uniform sampler2D depthTexture; varying vec2 vUv; void main(){ vec2 uv = vUv; if (flipY) uv.y = 1.0 - uv.y; gl_FragColor = texture2D(map, uv); if (writeDepth) { float depth = texture2D(depthTexture, uv).r; gl_FragDepth = depth; // float linearDepth = (depth - 0.99) * 100.0; // Enhance near 1.0 values // gl_FragColor = vec4(linearDepth, linearDepth, linearDepth, 1.0); } }`})}reset(){this.uniforms.map.value=null,this.uniforms.flipY.value=!0,this.uniforms.writeDepth.value=!1,this.uniforms.depthTexture.value=null,this.needsUpdate=!0,this.uniformsNeedUpdate=!0}}class mr{static planeGeometry=new Sn(2,2,1,1);static renderer=new br({antialias:!1,alpha:!0});static perspectiveCam=new de;static orthographicCam=new Rd;static scene=new Mi;static blitMaterial=new Mm;static mesh=new H(mr.planeGeometry,mr.blitMaterial);static copyTexture(e,t){t||(t=this.blitMaterial),this.blitMaterial.reset();const i=t||this.blitMaterial;i.uniforms.map.value=e,i.needsUpdate=!0,i.uniformsNeedUpdate=!0;const n=i.vertexShader;i.vertexShader=Mm.vertex;const s=this.mesh;s.material=i,s.frustumCulled=!1,this.scene.children.length=0,this.scene.add(s),this.renderer.setSize(e.image.width,e.image.height),this.renderer.clear(),this.renderer.render(this.scene,this.perspectiveCam);const r=new Se(this.renderer.domElement);return r.name="Copy",r.needsUpdate=!0,i.vertexShader=n,r}static blit(e,t,i){const{renderer:n=this.renderer,blitMaterial:s=this.blitMaterial,flipY:r=!1,depthTexture:a=null,depthTest:l=!0,depthWrite:c=!0}=i||{};this.blitMaterial.reset(),s.uniforms.map&&(s.uniforms.map.value=e),s.uniforms.flipY&&(s.uniforms.flipY.value=r),a?(s.uniforms.writeDepth=new Xi(!0),s.uniforms.depthTexture.value=a):(s.uniforms.writeDepth=new Xi(!1),s.uniforms.depthTexture.value=null),s.needsUpdate=!0,s.uniformsNeedUpdate=!0;const h=this.mesh;h.material=s,h.frustumCulled=!1,this.scene.children.length=0,this.scene.add(h);const d=n.getRenderTarget(),p=n.getContext();l?p.enable(p.DEPTH_TEST):p.disable(p.DEPTH_TEST),n.state.buffers.depth.setMask(c),n.setClearColor(new oe(0,0,0),0),n.setRenderTarget(t),n.clear(),n.render(this.scene,this.perspectiveCam),n.setRenderTarget(d),p.enable(p.DEPTH_TEST),n.state.buffers.depth.setMask(!0)}static textureToCanvas(e,t=!1){if(!e)return null;(t===!0||e.isCompressedTexture===!0)&&(e=L_(e));const i=e.image;if(JO(i)){const n=document.createElement("canvas");n.width=i.width,n.height=i.height;const s=n.getContext("2d");return s?(s.drawImage(i,0,0,i.width,i.height,0,0,n.width,n.height),n):(console.error("Failed getting canvas 2d context"),null)}return null}}function L_(o){return mr.copyTexture(o)}function KO(o,e=!1){return mr.textureToCanvas(o,e)}function JO(o){return typeof HTMLImageElement<"u"&&o instanceof HTMLImageElement||typeof HTMLCanvasElement<"u"&&o instanceof HTMLCanvasElement||typeof OffscreenCanvas<"u"&&o instanceof OffscreenCanvas||typeof ImageBitmap<"u"&&o instanceof ImageBitmap}function ek(o){const e=o.type;return e==="Mesh"||e==="SkinnedMesh"}function wg(o,e){e?o["needle:rendercustomshadow"]=!0:o["needle:rendercustomshadow"]=!1}function D_(o){return!!(o&&(o["needle:rendercustomshadow"]===!0||o["needle:rendercustomshadow"]==null))}function ui(o,e=void 0,t=void 0,i=void 0){const n=i||new Nt;n.makeEmpty();const s=[];function r(l){let c=!0;if(l.visible&&x_(l)!==!1&&!(l.type==="TransformControlsGizmo"||l.type==="TransformControlsPlane")){if(l instanceof nC&&(c=!1),l instanceof Cb&&(c=!1),l instanceof Fa&&(c=!1),l.isGizmo===!0&&(c=!1),l.material instanceof Sb&&(c=!1),ek(l)||(c=!1),t&&l.layers.test(t)===!1&&(c=!1),c&&(e&&Array.isArray(e)&&e?.includes(l)||typeof e=="function"&&e(l)===!0))return;if(l.isUI!==!0){if(c){const h=l.children;l.children=s;const d=l.position,p=l.scale;if(Number.isNaN(d.x)||Number.isNaN(d.y)||Number.isNaN(d.z)){console.warn(`Object "${l.name}" has NaN values in position or scale.... will ignore it`,d,p);return}l.geometry===null&&(l.geometry=void 0),n.expandByObject(l,!0),l.children=h}for(const h of l.children)r(h)}}}let a=!1;Array.isArray(o)||(o=[o]);for(const l of o)l&&(a=!0,l.updateMatrixWorld(),r(l));return a||console.warn("No objects to fit camera to..."),n}function j_(o,e,t){const i=ui([o],t?.ignore),n=new b;i.getSize(n);const s=new b;i.getCenter(s);const r=new b;e.getSize(r);const a=new b;e.getCenter(a);const l=new b;l.set(r.x/n.x,r.y/n.y,r.z/n.z);const c=Math.min(l.x,l.y,l.z),h=t?.scale!==!1;if(h&&Wa(o,Ge(o).multiplyScalar(c)),t?.position!==!1){const d=new b;i.getCenter(d),d.y=i.min.y;const p=new b;e.getCenter(p),p.y=e.min.y;const m=p.clone().sub(d);h&&m.multiplyScalar(c),bt(o,ee(o).add(m))}return{boundsBefore:i,scale:l}}function B_(o,e){const t=ui([o]),i=new b;t.getCenter(i),i.y=t.min.y;const n=e.clone().sub(i),s=ee(o);return bt(o,s.add(n)),{offset:n,bounds:t}}function xg(o,e,t,i){if(Array.isArray(e)){let r=!0;for(let a=0;a<e.length;a++)xg(o,e[a],a,e)||(r=!1);return r}if(e.type==="MeshStandardMaterial"||e.type==="MeshBasicMaterial")return!1;if(e["material:fbx"]!=null)return!0;const n=new yt;n["material:fbx"]=e;const s=e;return s&&(s.map?n.color.set(1,1,1):n.color.copyLinearToSRGB(s.color),n.emissive.copyLinearToSRGB(s.emissive),n.emissiveIntensity=s.emissiveIntensity,n.opacity=s.opacity,n.displacementScale=s.displacementScale,n.transparent=s.transparent,n.bumpMap=s.bumpMap,n.aoMap=s.aoMap,n.map=s.map,n.displacementMap=s.displacementMap,n.emissiveMap=s.emissiveMap,n.normalMap=s.normalMap,n.envMap=s.envMap,n.alphaMap=s.alphaMap,n.metalness=s.reflectivity,n.vertexColors=s.vertexColors,s.shininess&&(n.roughness=1-Math.sqrt(s.shininess)/10),n.needsUpdate=!0),t===void 0?o.material=n:i[t]=n,!0}let Zd=!1;xO((...o)=>{A()&&pe.Current?.isInXR&&(Va(!0),F_("error",...o))});function Va(o){if(o){if(Zd)return;Zd=!0,ik()}else{if(!Zd)return;Zd=!1,nk()}}const _c={log:void 0,warn:void 0,error:void 0};class tk{familyName="needle-xr";root=null;context=null;defaultFontSize=.06;constructor(){this.ensureFont()}onEnable(){this.context=pe.Current||pe.All[0],this.context.pre_render_callbacks.push(this.onBeforeRender)}onDisable(){this.context?.pre_render_callbacks.splice(this.context?.pre_render_callbacks.indexOf(this.onBeforeRender),1),this.root?.removeFromParent()}targetObject=new M;userForwardViewPoint=new b;oneEuroFilter=new ug(90,.8);_lastElementRemoveTime=0;onBeforeRender=()=>{const e=this.context?.mainCamera;if(this.context&&e instanceof de){const t=this.getRoot();Number.isNaN(t.position.x)&&t.position.set(0,0,0),Number.isNaN(t.quaternion.x)&&t.quaternion.set(0,0,0,1),this.context.scene.add(this.targetObject);const i=this.context.xr?.rigScale??1,n=3.5*i,s=e.worldForward;s.y=0,s.normalize().multiplyScalar(n),this.userForwardViewPoint.copy(e.worldPosition).sub(s),this.targetObject.position.distanceTo(this.userForwardViewPoint)>2*i&&(this.targetObject.position.copy(this.userForwardViewPoint),yc(this.targetObject,e,!0,!0),this.targetObject.rotateY(Math.PI)),this.oneEuroFilter.filter(this.targetObject.position,t.position,this.context.time.time);const r=this.context.time.deltaTime;if(t.quaternion.slerp(this.targetObject.quaternion,r*5),t.scale.setScalar(i),this.targetObject.removeFromParent(),this.context.scene.add(t),this.context.time.time-this._lastElementRemoveTime>.1){this._lastElementRemoveTime=this.context.time.time;const a=Date.now();for(let l=0;l<this._activeTexts.length;l++){const c=this._activeTexts[l];if(c instanceof Oe.Text&&a-c._activatedTime>2e4){c.removeFromParent(),this._textBuffer.push(c),this._activeTexts.splice(l,1);break}}}}};addLog(e,t){const i=this.getRoot(),n=this.getText();let s=16777215,r=0;switch(e){case"log":s=16777215,r=0;break;case"warn":s=16772761,r=4465152;break;case"error":s=16755370,r=7798784;break}t.length>1e3&&(t=t.substring(0,1e3)+"...");const a=new Date().toISOString().split("T")[1].split(".")[0];n.textContent="["+a+"] "+t,n.visible=!0,n._activatedTime=Date.now(),i.add(n),this._activeTexts.push(n),this.context&&this.context.scene.add(i),n.set({backgroundColor:s,color:r}),Oe.update()}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()}))}textOptions={fontSize:this.defaultFontSize,fontFamily:this.familyName,padding:.03,margin:.005,color:0,backgroundColor:16777215,backgroundOpacity:.4,borderRadius:.03,offset:.025};_textBuffer=[];_activeTexts=[];getText(){const e=this.getRoot();if(this._textBuffer.length>0){const i=this._textBuffer.pop();return i.visible=!0,setTimeout(()=>this.disableDepthTestRecursive(i),100),i}if(e.children.length>20&&this._activeTexts.length>0)return this._activeTexts.shift();const t=new Oe.Text(this.textOptions);return setTimeout(()=>this.disableDepthTestRecursive(t),500),setTimeout(()=>this.disableDepthTestRecursive(t),1500),t}disableDepthTestRecursive(e,t=0){for(let n=0;n<e.children.length;n++){const s=e.children[n];s instanceof M&&this.disableDepthTestRecursive(s,t+1)}e.renderOrder=10*t,e.layers.set(2);const i=e.material;i&&(i.depthWrite=!1,i.depthTest=!1,i.transparent=!0),t===0&&Oe.update()}getRoot(){if(this.root)return this.root;const e=this.defaultFontSize,t={boxSizing:"border-box",fontFamily:this.familyName,width:"2.6",fontSize:e,color:0,lineHeight:1,backgroundColor:16777215,backgroundOpacity:0,whiteSpace:"pre-wrap",flexDirection:"column-reverse"};return this.root=new Oe.Block(t),this.root}}let Or=null;function ik(){Or||(Or=new tk),Or.onEnable();for(const o in _c){_c[o]=console[o];let e=!1;console[o]=function(){if(_c[o]?.apply(console,arguments),!e)try{e=!0,F_(o,...arguments)}finally{e=!1}}}}function nk(){Or?.onDisable();for(const o in _c)console[o]=_c[o]}const vc=new Map;function F_(o,...e){try{switch(vc.clear(),o){case"log":Or?.addLog("log",t());break;case"warn":Or?.addLog("warn",t());break;case"error":Or?.addLog("error",t());break}}catch(s){console.error("Error in spatial console",s)}finally{vc.clear()}function t(){let s="";for(let r=0;r<e.length;r++){const a=e[r];s+=i(a),r<e.length-1&&(s+=", ")}return s}function i(s,r=0){if(typeof s=="string")return'"'+s+'"';if(typeof s=="number"){if(s%1!==0){const a=s.toFixed(5),l=a.indexOf(".");let c=a.length-1;for(;c>l&&a[c]==="0";)c--;return a.substring(0,c+1)}return s.toString()}else if(Array.isArray(s)){let a="[";for(let l=0;l<s.length;l++){const c=s[l];a+=i(c,r+1),l<s.length-1&&(a+=", ")}return a+="]",a}else{if(s===null)return"null";if(s===void 0)return"undefined";if(typeof s=="function")return s.name+"()"}if(s instanceof K)return`(${i(s.x)}, ${i(s.y)})`;if(s instanceof b)return`(${i(s.x)}, ${i(s.y)}, ${i(s.z)})`;if(s instanceof ye)return`(${i(s.x)}, ${i(s.y)}, ${i(s.z)}, ${i(s.w)})`;if(s instanceof N)return`(${i(s.x)}, ${i(s.y)}, ${i(s.z)}, ${i(s.w)})`;if(s instanceof we||s instanceof Se)return s.name;if(s instanceof Pb)return`[${s.elements.join(", ")}]`;if(s instanceof J)return`[${s.elements.join(", ")}]`;if(s instanceof ws)return s.mask.toString();if(typeof s=="object"){if(vc.has(s))return"*";let a=`{ `;a+=n(r);const l=Object.keys(s);let c="";for(let h=0;h<l.length;h++){const d=l[h],p=s[d];if(vc.has(p)){c+="";continue}vc.set(p,!0),c+=d+":"+i(p,r+1),h<l.length-1&&(c+=", "),c.length>=60&&(c+=` `,c+=n(r),a+=c,c="")}return a+=c,a+=` }`,a}return s}function n(s){let r="";for(let a=0;a<s;a++)r+=" ";return r}}function ke(o,e){Sr(e?.type??Li.Log,o,e)}function be(o,e){ke(o,{...e,type:Li.Warn})}function wc(o,e){ke(o,{...e,type:Li.Error})}let pi,kr=null,qn=null,xc=!1,U_=null;const z_="terminal",ok=w("console");ok&&Sg();const sk=Symbol("consoleParent");function Sg(){if(pi){pi.showSwitch();return}hk()}function N_(){pi&&(pi.hide(),pi.hideSwitch())}function rk(){U_||(U_=setInterval(ak,500))}let W_=0;function ak(){const o=u_(),e=o!==W_;W_=o,e&&lk()}function lk(){Sg(),qn&&(qn.setAttribute("error","true"),qn.innerText="\u{1F92C}")}function ck(){qn&&(qn.removeAttribute("error"),qn.innerText=z_)}function hk(o=!1){if(pi!==void 0||xc)return;xc=!0;const e=document.createElement("script");e.onload=()=>{if(!globalThis.VConsole){console.warn("\u{1F335} Debug console failed to load."),xc=!1,pi=null;return}xc=!1,rk(),pi=new VConsole({pluginOrder:["default","needle-console"]});const t=globalThis["needle:codegen_files"];if(t&&t.length>0&&pi.addPlugin(dk()),pi.addPlugin(gk()),pi.addPlugin(fk()),kr=kk(),kr&&(kr[sk]=kr.parentElement,kr.style.position="absolute",kr.style.zIndex=Number.MAX_SAFE_INTEGER.toString()),pi.setSwitchPosition(20,30),qn=Ok(),qn){qn.innerText=z_,qn.addEventListener("click",ck);const i=document.createElement("style"),n=40;i.innerHTML=` #__vconsole .vc-switch { border: 1px solid rgba(255, 255, 255, .1); border-radius: 50%; width: ${n}px; height: ${n}px; padding: 0; line-height: ${n}px; font-size: ${n*.4}px; text-align: center; background: #ffffff5c; backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); user-select: none; pointer-events: auto; transition: transform .2s ease-in-out; box-shadow: 0px 7px 0.5rem 0px rgb(0 0 0 / 6%), inset 0px 0px 1.3rem rgba(0,0,0,.05); font-family: 'Material Symbols Outlined'; color: black; font-size: 2.3em; font-weight: 100; } #__vconsole .vc-switch:hover { cursor: pointer; transform: scale(1.1); transition: transform .1s ease-in-out, background .1s linear; background: rgba(245, 245, 245, .8); outline: rgba(0, 0, 0, .05) 1px solid; } #__vconsole .vc-switch[error] { background: rgba(255,0,0,.2); animation: vconsole-notify 1s ease-in-out; line-height: 35px; } @keyframes vconsole-notify { from { transform: scale(1, 1); } 10% { transform: scale(1.3, 1.3); } 70% { transform: scale(1.4, 1.4); } to { transform: scale(1, 1); } } #__vconsole .vc-panel { font-family: monospace; font-size: 11px; } #__vconsole .vc-plugin-box.vc-actived { height: 100%; } #__vconsole .vc-mask { overflow: hidden; } `,kr?.prepend(i),o===!0&&u_()<=0&&N_(),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 dk(){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;",V_="margin-bottom: 10px;",Mr="margin-bottom: 10px; margin-top: 15px;",uk="width: 100%; border-collapse: collapse; border: 1px solid rgba(0,0,0,0.1); table-layout: fixed;",$_="border: 1px solid rgba(0,0,0,0.1); padding: 5px;",pk=$_,mk=$_+" 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='${uk}'>`;t+="<tbody>";for(const i of o){const n=typeof i.value=="boolean"?i.value?"\u2705":"\u274C":i.value;t+=`<tr><td style='${pk}'>${i.label}</td><td style='${mk}'>${n}</td></tr>`}return t+="</tbody></table>",t}function H_(){try{if(document.createElement("canvas").getContext("webgl2"))return"\u2705"}catch{}return"\u274C"}function gk(){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=Pk();t+=`<h3 style='${V_}'>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='${V_}'>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:H_()}];t+=Xn(l,!1),t+="</div>",e(t)}),o}function fk(){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=yk();i.length>0&&(t+=`<h3 style='${Mr}'>General GPU Info</h3>`,t+=Xn(i,!1));const n=_k();n.length>0&&(t+=`<h3 style='${Mr}'>WebGL</h3>`,t+=Xn(n,!