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.

144 lines (131 loc) 1.27 MB
import{Vector2 as K,Vector3 as b,Vector4 as ye,Quaternion as N,PlaneGeometry as vn,WebGLRenderer as yr,PerspectiveCamera as de,OrthographicCamera as Pd,Scene as Hi,Mesh as H,Texture as Se,Uniform$1 as Gi,Color as oe,ShaderMaterial as Vn,Box3 as Ft,ShadowMaterial as fb,Euler as at,MeshStandardMaterial as gt,Box3Helper as GS,GridHelper as yb,Object3D as M,Material as we,Matrix3 as bb,Matrix4 as J,Layers as _s,Ray as Co,MathUtils as Po,AxesHelper as Pi,MeshBasicMaterial as Ce,DoubleSide as Oi,BufferGeometry as wn,Group as Oo,CylinderGeometry as _b,SphereGeometry as Od,BoxGeometry as Ia,SpriteMaterial as qS,Sprite as XS,Shape as QS,ExtrudeGeometry as YS,Fog as vb,DirectionalLight as Om,PointLight as km,TextureLoader as br,EdgesGeometry as ZS,LineSegments as wb,LineBasicMaterial as Mm,Line as La,BufferAttribute as ft,Raycaster as kd,Sphere as Md,ArrayCamera as KS,Plane as _r,SkinnedMesh as vs,InterleavedBufferAttribute as xb,Skeleton as JS,Bone as eC,WebGLCubeRenderTarget as tC,CubeCamera as iC,AnimationClip as ki,FileLoader as Em,PropertyBinding as Da,KeyframeTrack as nC,LinearSRGBColorSpace as ko,ShaderChunk as Zt,DataTexture as Rm,RGBAFormat as Ed,EquirectangularReflectionMapping as Mo,SRGBColorSpace as Eo,Clock as oC,NeutralToneMapping as ja,AgXToneMapping as Rd,ACESFilmicToneMapping as Td,NoToneMapping as Ad,PCFSoftShadowMap$1 as sC,BasicNodeLibrary as rC,WebGLRenderTarget as $n,DepthTexture as Sb,NearestFilter as Id,LoopRepeat as aC,LoopOnce as Tm,AnimationMixer as Am,CompressedTexture as lC,FrontSide as ws,Camera as cC,Frustum as Cb,AudioListener as hC,PositionalAudio as dC,AudioLoader as Im,EventDispatcher as Lm,BackSide as Ld,MeshDepthMaterial as uC,CustomBlending as pC,MaxEquation as mC,AlwaysStencilFunc as gC,GreaterEqualStencilFunc as fC,NotEqualStencilFunc as yC,GreaterStencilFunc as bC,LessEqualStencilFunc as _C,EqualStencilFunc as vC,LessStencilFunc as wC,NeverStencilFunc as Pb,InvertStencilOp as xC,DecrementWrapStencilOp as SC,IncrementWrapStencilOp as CC,DecrementStencilOp as PC,IncrementStencilOp as OC,ReplaceStencilOp as kC,ZeroStencilOp as MC,KeepStencilOp as EC,CubeUVReflectionMapping as Ob,CubeTexture as kb,AmbientLight as RC,HemisphereLight as TC,Loader as AC,RawShaderMaterial as Mb,GLSL3 as IC,AlwaysDepth as LC,GreaterEqualDepth as DC,GreaterDepth as jC,LessEqualDepth as BC,LessDepth as FC,NotEqualDepth as UC,EqualDepth as zC,BatchedMesh as Eb,LinearFilter as Dd,UnsignedByteType as NC,MeshPhysicalMaterial as Rb,RingGeometry as WC,Line3 as VC,AdditiveBlending as Tb,BoxHelper as $C,SpotLight as HC,DirectionalLightHelper as GC,CameraHelper as qC,LOD as XC,Triangle as QC,NormalBlending as YC,ReinhardToneMapping as Dm,LinearToneMapping as jm,HalfFloatType as Bm,VideoTexture as ZC,CompressedCubeTexture as KC,EquirectangularRefractionMapping as JC,CatmullRomCurve3 as eP,VectorKeyframeTrack as tP,QuaternionKeyframeTrack as iP,Audio as nP,ShaderLib as jd,UniformsUtils as Ab,MirroredRepeatWrapping as Ib,MeshNormalMaterial as oP,AudioContext as sP,PMREMGenerator$1 as rP}from"./three.min.js";import{createLoaders as Fm,getRaycastMesh as Lb,LODsManager as vr,NEEDLE_progressive as Ve,addDracoAndKTX2Loaders as aP,configureLoader as lP,setKTX2TranscoderLocation as cP,setDracoDecoderLocation as hP}from"./gltf-progressive-BmXoz_HR.min.js";import{GroundedSkybox as Ba,Font as dP,TextGeometry as uP,FontLoader as pP,GLTFLoader as Ro,TransformControlsGizmo as Db,EXRLoader as Um,RGBELoader as jb,Stats as mP,nodeFrame as Bb,OrbitControls as gP,PositionalAudioHelper as fP,HorizontalBlurShader as yP,VerticalBlurShader as bP,GLTFExporter as Fb,strToU8 as Ub,zipSync as _P,XRControllerModelFactory as vP,XRHandMeshModel as wP,Line2 as xP,LineGeometry as SP,LineMaterial as CP,TransformControls as PP,InteractiveGroup as OP,HTMLMesh as kP,VertexNormalsHelper as MP,OBJLoader as zm,FBXLoader as zb,mergeVertices as EP}from"./three-examples.min.js";import{fetchProfile as RP,MotionController as TP,$70d766613f57b014$export$2e2bcd8739ae039 as Nb,ByteBuffer as AP,v5 as Wb,md5 as Vb,SIZE_PREFIX_LENGTH as $b,Builder as Nm,createNoise4D as IP,Matrix4 as Wm,BatchedParticleRenderer as LP,ParticleSystem as DP,RenderMode as To,ConstantColor as jP,Vector4 as BP,ConstantValue as FP,TrailParticle as Hb,WorkerBase as UP,MeshBVH as zP}from"./vendor-DZ45lcA8.min.js";import{__webpack_exports__default as Pe,__webpack_exports__Text as Gb,__webpack_exports__Block as qb,__webpack_exports__update as NP,SimpleStateBehavior as WP,__webpack_exports__Inline as Vm,__webpack_exports__FontLibrary as Xb,ThreeMeshUI as Qb}from"./three-mesh-ui-n3JU4M2W.min.js";import{EffectAttribute as VP}from"./postprocessing-CaEfRjRY.min.js";const $m=new Map;function Mi(o=globalThis.location?.hostname){if($m.has(o))return $m.get(o);const e=/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})|localhost/.test(o);return $m.set(o,e),e===!0}function Yb(){return window.location.hostname.includes("glitch.me")}const Zb=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&&(Zb&&console.warn("Registering context"),this.Registered.push(e),this.dispatchCallback("ContextRegistered",e))}static unregister(e){const t=this.Registered.indexOf(e);t!==-1&&(Zb&&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 Kb=()=>o=>o;function $P(o){return Kb()(o)}function HP(){return!!w("debug")}class Ei{_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 wr=!1;const Hm=new Array;typeof window<"u"&&setTimeout(()=>{if(wr){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 Hm){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=wr===!0?"":` (containing "${wr}")`;console.group("Available URL parameters:"+n);for(const s of Object.keys(o).sort())typeof wr=="string"&&!s.toLowerCase().includes(wr.toLowerCase())||(console.groupCollapsed(s),console.log("Reload with this flag enabled:"),console.log(o[s]),console.groupEnd());console.groupEnd()}},100);function dc(){return new URLSearchParams(globalThis.location?.search)}function w(o){wr&&!Hm.includes(o)&&Hm.push(o);const e=dc();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}wr=w("help");function GP(o,e){const t=dc();t.has(o)?t.set(o,e):t.append(o,e),document.location.search=t.toString()}function uc(o,e,t=!0){const i=dc();i.has(o)?e===null?i.delete(o):i.set(o,e):e!==null&&i.append(o,e),t?Jb(o,i):qm(o,i)}function Gm(o,e,t){o.has(e)?o.set(e,t.toString()):o.append(e,t.toString())}function Jb(o,e,t){window.history.pushState(t,o,"?"+e.toString())}function qm(o,e,t){window.history.replaceState(t,o,"?"+e.toString())}function qP(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 XP(o,e){return Math.floor(Math.random()*(e-o+1))+o}const e_=["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"],t_=["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 i_(){const o=e_[Math.floor(Math.random()*e_.length)],e=t_[Math.floor(Math.random()*t_.length)];return o+"_"+e}function n_(o){return o=o.replace(/[^a-z0-9áéíóúñü \.,_-]/gim,""),o.trim()}function Fa(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=Fa(o,s,t,i);if(r)return r}if(e.children)for(const n in e.children){const s=e.children[n],r=Fa(o,s,t,i);if(r)return r}}}function pc(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]=pc(n,e)}return t}return o}function Ao(o){return new Promise((e,t)=>{setTimeout(e,o)})}function mc(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 Bd=w("debugresolveurl"),o_="rel:";function QP(o,e){return Io(o,e)}function Io(o,e){if(e===void 0)return Bd&&console.warn("getPath: uri is undefined, returning uri",e),e;if(e.startsWith("./"))return e;if(e.startsWith("http"))return Bd&&console.warn("getPath: uri is absolute, returning uri",e),e;if(o===void 0)return Bd&&console.warn("getPath: source is undefined, returning uri",e),e;e.startsWith(o_)&&(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 Bd&&console.log("source:",o,`changed uri from`,e,` to `,n,` basePath: `+i),n}return e}function s_(o){if(o)return o=o.trim(),o=o.split("?")[0]?.split("#")[0],o}class YP{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 ps{_watches=[];constructor(e,t){if(Array.isArray(t))for(const i of t)this._watches.push(new ps(e,i));else this._watches.push(new YP(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 Ua=Symbol("needle:watches");function Fd(o,e){if(!o[Ua])if(o instanceof K)o[Ua]=new ps(o,["x","y"]);else if(o instanceof b)o[Ua]=new ps(o,["x","y","z"]);else if(o instanceof ye||o instanceof N)o[Ua]=new ps(o,["x","y","z","w"]);else return!1;return o[Ua].subscribeWrite(e),!0}function Xm(o,e){if(!o)return;const t=o[Ua];t&&t.unsubscribeWrite(e)}var I;(o=>{let e;function t(){if(e!==void 0)return e;const te=window.navigator.userAgent,We=/Windows|MacOS|Mac OS/.test(te),ci=/Windows NT/.test(te)&&/Edg/.test(te)&&!/Win64/.test(te);return e=We&&!ci&&!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 R;function $(){if(R!==void 0)return R;const te=navigator.userAgent.match(/iPhone OS (\d+_\d+)/);if(te&&(R=te[1].replace("_",".")),!R){const We=navigator.userAgent.match(/(?:\(Macintosh;|iPhone;|iPad;).*Version\/(\d+\.\d+)/);We&&(R=We[1])}return R||(R=null),R}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 me(){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=me})(I||(I={}));function ZP(){return I.isDesktop()}function KP(){return I.isMobileDevice()}function JP(){return I.isiPad()}function eO(){return I.isiPad()}function tO(){return I.isAndroidDevice()}function iO(){return I.isMozillaXR()}function nO(){return I.isMacOS()}function oO(){return I.isiOS()}function sO(){return I.isSafari()}function rO(){return I.isQuest()}async function aO(){return I.microphonePermissionsGranted()}const xs=new WeakMap;function Qm(o,e,t){if(!xs.get(o)){const n=new MutationObserver(s=>{lO(o,s)});xs.set(o,{observer:n,attributeChangedListeners:new Map}),n.observe(o,{attributes:!0})}const i=xs.get(o).attributeChangedListeners;return i.has(e)||i.set(e,[]),i.get(e).push(t),()=>{Ym(o,e,t)}}function Ym(o,e,t){if(!xs.get(o))return;const i=xs.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),xs.get(o)?.observer.disconnect(),xs.delete(o)))}function lO(o,e){const t=xs.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 Zm{reason;constructor(e){this.reason=e}}async function Km(o){const e=await Promise.allSettled(o).catch(n=>[new Zm(n.message)]);let t=!1;const i=e.map(n=>"value"in n?n.value:(t=!0,new Zm(n.reason)));return{anyFailed:t,results:i}}const cO=w("debugdebug");let Jm=!1;(w("noerrors")||w("nooverlaymessages"))&&(Jm=!0);const eg="needle_engine_global_error_container";var Ri=(o=>(o[o.Log=0]="Log",o[o.Warn=1]="Warn",o[o.Error=2]="Error",o))(Ri||{});function r_(){return c_}const tg=new Array;function hO(o){tg.push(o)}let ig=!1;function dO(...o){if(!ig){ig=!0;try{for(let e=0;e<tg.length;e++)tg[e](...o)}catch(e){console.error(e)}ig=!1}}const a_=console.error,uO=function(...o){a_.apply(console,o),gO(o),xr(2,o,{}),mO(...o)};function l_(o){Jm=!o,o?console.error=uO:console.error=a_}function pO(o){return l_(o)}let c_=0;function mO(...o){c_+=1,dO(...o)}function gO(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 h_=new Set;function xr(o,e,t={},i,n){if(Jm)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(h_.has(a))return;h_.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||fO(o,r,e,t)}}const za=new Map,d_=.2;function fO(o,e,t,i={}){if(t==null)return;const n=_O(e);if(n.childElementCount>=20){const c=n.lastElementChild;p_(c)}t.length>400&&(t=t.substring(0,400)+"...");const s=i.key??t;if(za.has(s)){za.get(s)?.update(t,i);return}const r=vO(o,t);n.prepend(r);const a=()=>{za.delete(s),p_(r)};let l=setTimeout(a,Math.max(d_,i.duration??10)*1e3);za.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(d_,h.duration)*1e3))},removeFunction:a})}function yO(){cO&&console.log("Clearing messages");for(const o of za.values())o?.removeFunction.call(o);za.clear()}const bO=` @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 _O(o){globalThis[eg]||(globalThis[eg]=new Map);const e=globalThis[eg];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=bO,t.appendChild(n),t}}const u_=Symbol("logtype"),Ud=new Map;function p_(o){o.remove();const e=o[u_],t=Ud.get(e)??[];t.push(o),Ud.set(e,t)}function vO(o,e){if(Ud.has(o)){const i=Ud.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[u_]=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}class wO{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 xO){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 xO=["x","y","z","w"],D=new wO;class m_{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 zd{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 m_(this.alpha(this.minCutOff)),this.dx=new m_(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 ng{x;y;z;constructor(e,t=1,i=0,n=1){this.x=new zd(e,t,i,n),this.y=new zd(e,t,i,n),this.z=new zd(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 Nd="needle:cameraController";function g_(o){return o[Nd]}function og(o,e,t){t?o[Nd]=e:o[Nd]===e&&(o[Nd]=null)}const sg="needle:autofit";function f_(o){return o[sg]===void 0?!0:o[sg]!==!1}function Wd(o,e){o[sg]=e}let xn;const SO={x:0,y:0,width:0,height:0},CO=w("debugfocusrect");function PO(o,e,t,i,n){o instanceof Element&&(CO&&o instanceof HTMLElement&&(o.style.outline="2px dashed rgba(255, 150, 0, .8)"),o=o.getBoundingClientRect()),xn=n.domElement.getBoundingClientRect();const s=SO;s.x=o.x,s.y=o.y,s.width=o.width,s.height=o.height,s.x-=xn.x,s.y-=xn.y;const r=xn.width,a=xn.height,l=i.view,c=e.zoom;let h=l?.offsetX||0,d=l?.offsetY||0,p=xn.width,m=xn.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=xn.width*.5,_=xn.height*.5,v=f-y,P=g-_;h-=v/c,d-=P/c,e.offsetX!==void 0&&(h+=e.offsetX*(xn.width*.5)),e.offsetY!==void 0&&(d-=e.offsetY*(xn.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 OO(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 rg=new N,y_=new N().setFromAxisAngle(new b(0,1,0),Math.PI);function kO(o,e){o.lookAt(e),o.quaternion.multiply(y_)}function gc(o,e,t=!0,i=!1){if(o===e)return;rg.copy(o.quaternion);const n=ee(e),s=ee(o);if(i){if(Sn(o,_e(e)),t){const r=s.y,a=s.sub(x_(o));a.y=r,o.lookAt(a),o.quaternion.multiply(y_)}Number.isNaN(o.quaternion.x)&&o.quaternion.copy(rg);return}t&&(n.y=s.y),o.lookAt(n),Number.isNaN(o.quaternion.x)&&o.quaternion.copy(rg)}function MO(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 EO=new Ei(()=>new b,100);function F(o,e,t){const i=EO.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 RO=new Ei(()=>new oe,30);function b_(o){const e=RO.get();return o?e.copy(o):e.set(0,0,0),e}const TO=new Ei(()=>new N,100);function hi(o,e,t,i){const n=TO.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 ag=new Ei(()=>new b,100),__=Symbol("lastMatrixWorldUpdateKey");function ee(o,e=null,t=!0){const i=e??ag.get();return o?o.parent?(t&&o.updateWorldMatrix(!0,!1),o.matrixWorldNeedsUpdate&&o[__]!==Date.now()&&(o[__]=Date.now(),o.updateMatrixWorld()),i.setFromMatrixPosition(o.matrixWorld),i):i.copy(o.position):i.set(0,0,0)}function yt(o,e){if(!o)return o;const t=ag.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 Sr(o,e,t,i){const n=ag.get();return n.set(e,t,i),yt(o,n),o}const Vd=new Ei(()=>new N,100),Cr=new N,lg=new N;function _e(o,e=null){if(!o)return Vd.get().identity();const t=e??Vd.get();return o.parent?(o.getWorldQuaternion(t),t):t.copy(o.quaternion)}function Sn(o,e){if(!o)return;e!==Cr&&Cr.copy(e);const t=Cr;o?.parent?.getWorldQuaternion(lg),lg.invert();const i=lg.multiply(t);o.quaternion.set(i.x,i.y,i.z,i.w)}function cg(o,e,t,i,n){Cr.set(e,t,i,n),Sn(o,Cr)}const AO=new Ei(()=>new b,100),IO=new b;function $e(o,e=null){return e||(e=AO.get()),o?o.parent?(o.getWorldScale(e),e):e.copy(o.scale):e.set(0,0,0)}function Na(o,e){if(!o)return;if(!o.parent){o.scale.copy(e);return}const t=IO;o.parent.getWorldScale(t),o.scale.copy(e),o.scale.divide(t)}const LO=new b,v_=new N;function DO(o){return _e(o,v_),LO.set(0,0,1).applyQuaternion(v_)}const jO=new Ei(()=>new b,100),w_=new N;function x_(o,e){return e||(e=jO.get().set(0,0,1)),_e(o,w_),e.applyQuaternion(w_)}const S_=new at,C_=new at,BO=new b;function hg(o){const e=Vd.get();return o.getWorldQuaternion(e),C_.setFromQuaternion(e),C_}function dg(o,e){const t=Vd.get();Sn(o,t.setFromEuler(e))}function $d(o){const e=hg(o),t=BO;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 P_(o,e){fc(o,e.x,e.y,e.z,!0)}function fc(o,e,t,i,n=!0){n&&(e=D.toRadians(e),t=D.toRadians(t),i=D.toRadians(i)),S_.set(e,t,i),Cr.setFromEuler(S_),Sn(o,Cr)}function Hd(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 FO(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 O_(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 wm extends Vn{static vertex=` varying vec2 vUv; void main(){ vUv = uv; gl_Position = vec4(position.xy, 0., 1.0); }`;constructor(){super({vertexShader:wm.vertex,uniforms:{map:new Gi(null),flipY:new Gi(!0),writeDepth:new Gi(!1),depthTexture:new Gi(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 pr{static planeGeometry=new vn(2,2,1,1);static renderer=new yr({antialias:!1,alpha:!0});static perspectiveCam=new de;static orthographicCam=new Pd;static scene=new Hi;static blitMaterial=new wm;static mesh=new H(pr.planeGeometry,pr.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=wm.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 Gi(!0),s.uniforms.depthTexture.value=a):(s.uniforms.writeDepth=new Gi(!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.pixelRatio!==window.devicePixelRatio&&n.xr.isPresenting===!1&&n.setPixelRatio(window.devicePixelRatio),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=k_(e));const i=e.image;if(zO(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 k_(o){return pr.copyTexture(o)}function UO(o,e=!1){return pr.textureToCanvas(o,e)}function zO(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 NO(o){const e=o.type;return e==="Mesh"||e==="SkinnedMesh"}function ug(o,e){e?o["needle:rendercustomshadow"]=!0:o["needle:rendercustomshadow"]=!1}function M_(o){return!!(o&&(o["needle:rendercustomshadow"]===!0||o["needle:rendercustomshadow"]==null))}function di(o,e=void 0,t=void 0,i=void 0){const n=i||new Ft;n.makeEmpty();const s=[];function r(l){let c=!0;if(l.visible&&f_(l)!==!1&&!(l.type==="TransformControlsGizmo"||l.type==="TransformControlsPlane")){if(l instanceof GS&&(c=!1),l instanceof yb&&(c=!1),l instanceof Ba&&(c=!1),l.isGizmo===!0&&(c=!1),l.material instanceof fb&&(c=!1),NO(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 E_(o,e,t){const i=di([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&&Na(o,$e(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),yt(o,ee(o).add(m))}return{boundsBefore:i,scale:l}}function R_(o,e){const t=di([o]),i=new b;t.getCenter(i),i.y=t.min.y;const n=e.clone().sub(i),s=ee(o);return yt(o,s.add(n)),{offset:n,bounds:t}}function pg(o,e,t,i){if(Array.isArray(e)){let r=!0;for(let a=0;a<e.length;a++)pg(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 gt;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 Gd=!1;hO((...o)=>{A()&&pe.Current?.isInXR&&(Wa(!0),T_("error",...o))});function Wa(o){if(o){if(Gd)return;Gd=!0,VO()}else{if(!Gd)return;Gd=!1,$O()}}const yc={log:void 0,warn:void 0,error:void 0};class WO{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 ng(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),gc(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 Pe.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}),Pe.update()}ensureFont(){let e=Pe.FontLibrary.getFontFamily(this.familyName);e||(e=Pe.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",()=>{Pe.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 Pe.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&&Pe.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 Pe.Block(t),this.root}}let Pr=null;function VO(){Pr||(Pr=new WO),Pr.onEnable();for(const o in yc){yc[o]=console[o];let e=!1;console[o]=function(){if(yc[o]?.apply(console,arguments),!e)try{e=!0,T_(o,...arguments)}finally{e=!1}}}}function $O(){Pr?.onDisable();for(const o in yc)console[o]=yc[o]}const bc=new Map;function T_(o,...e){try{switch(bc.clear(),o){case"log":Pr?.addLog("log",t());break;case"warn":Pr?.addLog("warn",t());break;case"error":Pr?.addLog("error",t());break}}catch(s){console.error("Error in spatial console",s)}finally{bc.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 bb)return`[${s.elements.join(", ")}]`;if(s instanceof J)return`[${s.elements.join(", ")}]`;if(s instanceof _s)return s.mask.toString();if(typeof s=="object"){if(bc.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(bc.has(p)){c+="";continue}bc.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}}const HO=w("nodevlogs");function Oe(o,e){xr(e?.type??Ri.Log,o,e)}function be(o,e){Oe(o,{...e,type:Ri.Warn})}function _c(o,e){Oe(o,{...e,type:Ri.Error})}let mg,gg;function A(){if(HO)return!1;if(mg!==void 0)return mg;if(gg!==void 0)return gg;let o=Mi();return o||(o=window.location.hostname.endsWith(".local-credentialless.webcontainer.io")),gg=o,o}function GO(o){mg=o}let ui,Or=null,Hn=null,vc=!1,A_=null;const I_="terminal",qO=w("console");qO&&fg();const XO=Symbol("consoleParent");function fg(){if(ui){ui.showSwitch();return}JO()}function L_(){ui&&(ui.hide(),ui.hideSwitch())}function QO(){A_||(A_=setInterval(YO,500))}let D_=0;function YO(){const o=r_(),e=o!==D_;D_=o,e&&ZO()}function ZO(){fg(),Hn&&(Hn.setAttribute("error","true"),Hn.innerText="\u{1F92C}")}function KO(){Hn&&(Hn.removeAttribute("error"),Hn.innerText=I_)}function JO(o=!1){if(ui!==void 0||vc)return;vc=!0;const e=document.createElement("script");e.onload=()=>{if(!globalThis.VConsole){console.warn("\u{1F335} Debug console failed to load."),vc=!1,ui=null;return}vc=!1,QO(),ui=new VConsole({pluginOrder:["default","needle-console"]});const t=globalThis["needle:codegen_files"];if(t&&t.length>0&&ui.addPlugin(ek()),ui.addPlugin(ok()),ui.addPlugin(sk()),Or=fk(),Or&&(Or[XO]=Or.parentElement,Or.style.position="absolute",Or.style.zIndex=Number.MAX_SAFE_INTEGER.toString()),ui.setSwitchPosition(20,30),Hn=gk(),Hn){Hn.innerText=I_,Hn.addEventListener("click",KO);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; } `,Or?.prepend(i),o===!0&&r_()<=0&&L_(),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.":"")),vc=!1,ui=null},e.src="https://cdn.jsdelivr.net/npm/vconsole@3.15.1/dist/vconsole.min.js",document.body.appendChild(e)}function ek(){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"),ui?.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 yg="padding: 10px; font-family: monospace;",j_="margin-bottom: 10px;",kr="margin-bottom: 10px; margin-top: 15px;",tk="width: 100%; border-collapse: collapse; border: 1px solid rgba(0,0,0,0.1); table-layout: fixed;",B_="border: 1px solid rgba(0,0,0,0.1); padding: 5px;",ik=B_,nk=B_+" word-break: break-all;";function Gn(o,e=!1){e&&o.sort((i,n)=>(n.value?1:0)-(i.value?1:0));let t=`<table style='${tk}'>`;t+="<tbody>";for(const i of o){const n=typeof i.value=="boolean"?i.value?"\u2705":"\u274C":i.value;t+=`<tr><td style='${ik}'>${i.label}</td><td style='${nk}'>${n}</td></tr>`}return t+="</tbody></table>",t}function F_(){try{if(document.createElement("canvas").getContext("webgl2"))return"\u2705"}catch{}return"\u274C"}function ok(){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='${yg}'>`;const i=mk();t+=`<h3 style='${j_}'>Device: ${i}</h3>`,t+=Gn([{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+=Gn(n,!1)),t+="</div>",t+=`<div style='${yg} margin-top: 20px;'>`,t+=`<h3 style='${j_}'>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:F_()}];t+=Gn(l,!1),t+="</div>",e(t)}),o}function sk(){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='${yg}'>`;const i=rk();i.length>0&