@needle-tools/engine 4.11.0-next.cc37c71 → 4.11.1-next.0bef517

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@ All notable changes to this package will be documented in this file.
4
4
  The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5
5
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [4.11.1] - 2025-10-16
8
+ - Fix: WebXR / VR issue where trying to access missing geometry during raycasting caused errors
9
+ - Change: ScrollFollow now only applies when scroll has changed. It also immediately jumps to the target position on the first update instead of interpolating (avoiding interpolation through long timeline animations).
10
+ - Change: SplineWalker now has an option to disable LookAt. It also received a `pullStrength` property which controls how tightly the object moves along the spline.
11
+ - Improved: OrbitControls and ViewBox interaction
12
+
7
13
  ## [4.11.0] - 2025-10-15
8
14
  - **NEW**: SeeThrough component. With this component you can easily fade-out objects between the camera and a reference point in the scene. See the [See-Through sample](<https://see-through-walls-z23hmxbz1kjfjn.needle.run/>) to see it in action
9
15
  - **NEW**: [Droplistener sample](<https://engine.needle.tools/samples/droplistener/>)
@@ -141,7 +141,7 @@ void main(){
141
141
  #__vconsole .vc-mask {
142
142
  overflow: hidden;
143
143
  }
144
- `,br?.prepend(i),o===!0&&zb()<=0&&u_(),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.":"")),rc=!1,Hi=null},e.src="https://cdn.jsdelivr.net/npm/vconsole@3.15.1/dist/vconsole.min.js",document.body.appendChild(e)}function LO(){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"),Hi?.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}function jO(){return document.querySelector("#__vconsole .vc-switch")||null}function DO(){return document.querySelector("#__vconsole")||null}const m_=v("debugdefines");gs('if(!globalThis["NEEDLE_ENGINE_VERSION"]) globalThis["NEEDLE_ENGINE_VERSION"] = "0.0.0";'),gs('if(!globalThis["NEEDLE_ENGINE_GENERATOR"]) globalThis["NEEDLE_ENGINE_GENERATOR"] = "unknown";'),gs('if(!globalThis["NEEDLE_PROJECT_BUILD_TIME"]) globalThis["NEEDLE_PROJECT_BUILD_TIME"] = "unknown";'),gs('if(!globalThis["NEEDLE_PUBLIC_KEY"]) globalThis["NEEDLE_PUBLIC_KEY"] = "unknown";'),gs('globalThis["__NEEDLE_ENGINE_VERSION__"] = "4.11.0";'),gs('globalThis["__NEEDLE_ENGINE_GENERATOR__"] = "undefined";'),gs('globalThis["__NEEDLE_PROJECT_BUILD_TIME__"] = "Thu Oct 16 2025 12:36:35 GMT+0000 (Coordinated Universal Time)";'),gs('globalThis["__NEEDLE_PUBLIC_KEY__"] = "'+NEEDLE_PUBLIC_KEY+'";');const bn="4.11.0",Dd="undefined",og="Thu Oct 16 2025 12:36:35 GMT+0000 (Coordinated Universal Time)";m_&&console.log(`Engine version: ${bn} (generator: ${Dd})
144
+ `,br?.prepend(i),o===!0&&zb()<=0&&u_(),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.":"")),rc=!1,Hi=null},e.src="https://cdn.jsdelivr.net/npm/vconsole@3.15.1/dist/vconsole.min.js",document.body.appendChild(e)}function LO(){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"),Hi?.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}function jO(){return document.querySelector("#__vconsole .vc-switch")||null}function DO(){return document.querySelector("#__vconsole")||null}const m_=v("debugdefines");gs('if(!globalThis["NEEDLE_ENGINE_VERSION"]) globalThis["NEEDLE_ENGINE_VERSION"] = "0.0.0";'),gs('if(!globalThis["NEEDLE_ENGINE_GENERATOR"]) globalThis["NEEDLE_ENGINE_GENERATOR"] = "unknown";'),gs('if(!globalThis["NEEDLE_PROJECT_BUILD_TIME"]) globalThis["NEEDLE_PROJECT_BUILD_TIME"] = "unknown";'),gs('if(!globalThis["NEEDLE_PUBLIC_KEY"]) globalThis["NEEDLE_PUBLIC_KEY"] = "unknown";'),gs('globalThis["__NEEDLE_ENGINE_VERSION__"] = "4.11.1";'),gs('globalThis["__NEEDLE_ENGINE_GENERATOR__"] = "undefined";'),gs('globalThis["__NEEDLE_PROJECT_BUILD_TIME__"] = "Thu Oct 16 2025 15:45:14 GMT+0000 (Coordinated Universal Time)";'),gs('globalThis["__NEEDLE_PUBLIC_KEY__"] = "'+NEEDLE_PUBLIC_KEY+'";');const bn="4.11.1",Dd="undefined",og="Thu Oct 16 2025 15:45:14 GMT+0000 (Coordinated Universal Time)";m_&&console.log(`Engine version: ${bn} (generator: ${Dd})
145
145
  Project built at ${og}`);const Ea=NEEDLE_PUBLIC_KEY,Po="needle_isActiveInHierarchy",_r="builtin_components",ac="needle_editor_guid";function gs(o){try{(0,eval)(o)}catch(e){m_&&console.error(e)}}let g_,f_=null;function _n(){return g_}function sg(o){if(o==null){console.warn("Oh no: someone tried registering a non-existend gltf-loader. When you see this log it might mean that needle-engine is being imported multiple times. Please check your project setup.");return}f_!==o&&(f_=o,g_=new o)}const ki=Symbol("shadowDomOwner"),BO=v("debugpatch");function Bd(o,e,t,i){const n=BO===e;if(!t&&!i)return;const s=e+"___needle";UO(o,e,t,i);const r=Object.getOwnPropertyDescriptor(o,e),a=o[e];n&&console.log("Patch",o.constructor.name,e,r,a),r?(n&&console.log("Apply patch with existing descriptor",o.constructor.name,e,r),typeof r.value=="function"&&(o[e]=b_(r.value,o,e))):(n&&console.log("Create patch with new property",o.constructor.name,e,r),Object.defineProperty(o,e,{set:function(l){if(typeof l=="function")this[s]=b_(l,o,e);else{const c=this[s];__(o,e,this,c,l),this[s]=l,v_(o,e,this,c,l)}},get:function(){const l=this[s];return typeof l=="function"&&l[s]?l[s]:l}}))}function FO(o,e,t){const i=ag(o,e);if(i)for(let n=i.length-1;n>=0;n--){const s=i[n];s.prefix===t&&(s.prefix=null),s.postfix===t&&(s.postfix=null),!s.prefix&&!s.postfix&&i.splice(n,1)}}const y_=Symbol("Needle:Patches:WrappedFunction");function b_(o,e,t){if(o[y_])return o;const i=function(...n){__(e,t,this,...n);const s=o.apply(this,n);return v_(e,t,this,s,...n),s};return i[y_]=!0,i}const Fd="Needle:Patches";function rg(){return globalThis[Fd]||(globalThis[Fd]=new WeakMap),globalThis[Fd]}function ag(o,e){const t=rg().get(o);return t?t.get(e):null}function UO(o,e,t,i){let n=rg().get(o);n||(n=new Map,rg().set(o,n));let s=n.get(e);s||(s=[],n.set(e,s)),s.push({prefix:t,postfix:i})}function __(o,e,t,...i){if(!t)return;const n=ag(o,e);if(n)for(const s of n)s.prefix?.call(t,...i)}function v_(o,e,t,i,...n){if(!t)return;const s=ag(o,e);if(s)for(const r of s)r.postfix?.call(t,i,...n)}const Aa=[];function Ud(o){Aa.indexOf(o)===-1&&Aa.push(o)}function zO(o){const e=Aa.indexOf(o);e!==-1&&Aa.splice(e,1)}const Ia=[];function lg(o){Ia.indexOf(o)===-1&&Ia.push(o)}function NO(o){const e=Ia.indexOf(o);e!==-1&&Ia.splice(e,1)}function w_(o){globalThis.dispatchEvent(new CustomEvent("needle-xrsession-start",{detail:o}));for(let e=0;e<Aa.length;e++)Aa[e](o)}function x_(o){globalThis.dispatchEvent(new CustomEvent("needle-xrsession-end",{detail:o}));for(let e=0;e<Ia.length;e++)Ia[e](o)}const st=v("debuginput");var zd=(o=>(o.Mouse="mouse",o.Touch="touch",o.Controller="controller",o.Hand="hand",o))(zd||{}),Ae=(o=>(o.PointerDown="pointerdown",o.PointerUp="pointerup",o.PointerMove="pointermove",o.KeyDown="keydown",o.KeyUp="keyup",o.KeyPressed="keypress",o))(Ae||{});class Oo extends PointerEvent{clientZ;deviceIndex;origin;source;mode;get isSpatial(){return this.mode!="screen"}get ray(){return this._ray||(this._ray=new yo(this.space.worldPosition.clone(),this.space.worldForward.clone())),this._ray}set ray(e){this._ray=e}get hasRay(){return this._ray!==void 0}_ray;space;isClick=!1;isDoubleClick=!1;get used(){return this._used}_used=!1;use(){this._used=!0}get pointerId(){return this._pointerid}_pointerid;get pointerType(){return this._pointerType}_pointerType;get type(){return this._type}_type;metadata={};intersections=new Array;constructor(e,t,i){super(e,i),this.clientZ=i.clientZ,this._pointerid=i.pointerId,this._pointerType=i.pointerType,this._type=e,this.deviceIndex=i.deviceIndex,this.origin=i.origin,this.source=t,this.mode=i.mode,this._ray=i.ray,this.space=i.device}_immediatePropagationStopped=!1;get immediatePropagationStopped(){return this._immediatePropagationStopped}_propagationStopped=!1;get propagationStopped(){return this._immediatePropagationStopped||this._propagationStopped}stopImmediatePropagation(){this._immediatePropagationStopped=!0,super.stopImmediatePropagation(),this.source?.stopImmediatePropagation()}stopPropagation(){this._propagationStopped=!0,super.stopPropagation(),this.source?.stopPropagation(),st&&console.warn("Stop propagation...",this.pointerId,this.pointerType)}}class lc extends KeyboardEvent{source;constructor(e,t,i){super(e,i),this.source=t}stopImmediatePropagation(){super.stopImmediatePropagation(),this.source?.stopImmediatePropagation()}}class VO{key;keyType;source;constructor(e){this.key=e.key,this.keyType=e.type,this.source=e}}var oi=(o=>(o[o.Early=-100]="Early",o[o.Default=0]="Default",o[o.Late=100]="Late",o))(oi||{});class S_{_eventListeners={};addEventListener(e,t,i){if(this._eventListeners[e]||(this._eventListeners[e]=[]),!t||typeof t!="function"){console.error("Invalid call to addEventListener: callback is required and must be a function!");return}i?i={...i}:i={};let n=0;i?.queue!=null&&(n=i.queue);const s=this._eventListeners[e],r=s.find(a=>a.priority===n);r?r.listeners.push({callback:t,options:i}):(s.push({priority:n,listeners:[{callback:t,options:i}]}),s.sort((a,l)=>a.priority-l.priority))}removeEventListener(e,t,i){if(!this._eventListeners[e]||!t)return;const n=this._eventListeners[e];if(i?.queue!=null){const s=n.find(a=>a.priority===i.queue);if(!s)return;const r=s.listeners.findIndex(a=>a.callback===t);r>=0&&s.listeners.splice(r,1)}else for(const s of n){const r=s.listeners.findIndex(a=>a.callback===t);r>=0&&s.listeners.splice(r,1)}}dispatchEvent(e){let t=!1;if(e instanceof lc){const i=this._eventListeners[e.type];if(i)for(const n of i)for(let s=0;s<n.listeners.length;s++){const r=n.listeners[s];if(r.options?.signal?.aborted){n.listeners.splice(s,1),s--;continue}r.options.once&&(n.listeners.splice(s,1),s--),r.callback(e)}}if(e instanceof Oo){const i=this._eventListeners[e.type];if(i)for(const n of i){if(t)break;for(let s=0;s<n.listeners.length;s++){const r=n.listeners[s];if(r.options?.signal?.aborted){n.listeners.splice(s,1),s--;continue}if(e.immediatePropagationStopped){t=!0,st&&console.log("immediatePropagationStopped",e.type);break}else e.propagationStopped&&(t=!0,st&&console.log("propagationStopped",e.type));r.options.once&&(n.listeners.splice(s,1),s--),r.callback(e)}}}}_doubleClickTimeThreshold=.2;_longPressTimeThreshold=1;get mousePosition(){return this._pointerPositions[0]}get mousePositionRC(){return this._pointerPositionsRC[0]}get mouseDown(){return this._pointerDown[0]}get mouseUp(){return this._pointerUp[0]}get mouseClick(){return this._pointerClick[0]}get mouseDoubleClick(){return this._pointerDoubleClick[0]}get mousePressed(){return this._pointerPressed[0]}get mouseWheelChanged(){return this.getMouseWheelChanged(0)}get click(){return this._pointerClick[0]}get doubleClick(){return this._pointerDoubleClick[0]}getGamepad(e=0){return typeof navigator<"u"&&"getGamepads"in navigator&&navigator.getGamepads()[e]||null}_setCursorTypes=[];setCursorPointer(){this.setCursor("pointer")}setCursorNormal(){this.unsetCursor("pointer")}setCursor(e){this._setCursorTypes.push(e),this._setCursorTypes.length>10&&this._setCursorTypes.shift(),this.updateCursor()}unsetCursor(e){for(let t=this._setCursorTypes.length-1;t>=0;t--)if(this._setCursorTypes[t]===e){this._setCursorTypes.splice(t,1),this.updateCursor();break}}updateCursor(){this._setCursorTypes?.length==0?this.context.domElement.style.cursor="default":this.context.domElement.style.cursor=this._setCursorTypes[this._setCursorTypes.length-1]}getIsPointerIdInUse(e){for(const t of this._pointerEventsPressed)if(t.pointerId===e&&t.used)return!0;return!1}getPointerPressedCount(){let e=0;for(let t=0;t<this._pointerPressed.length;t++)this._pointerPressed[t]&&e++;return e}getPointerPosition(e){return e>=this._pointerPositions.length?null:this._pointerPositions[e]}getPointerPositionLastFrame(e){return e>=this._pointerPositionsLastFrame.length?null:this._pointerPositionsLastFrame[e]}getPointerPositionDelta(e){return e>=this._pointerPositionsDelta.length?null:this._pointerPositionsDelta[e]}getPointerPositionRC(e){return e>=this._pointerPositionsRC.length?null:this._pointerPositionsRC[e]}getPointerDown(e){return e>=this._pointerDown.length?!1:this._pointerDown[e]}getPointerUp(e){return e>=this._pointerUp.length?!1:this._pointerUp[e]}getPointerPressed(e){return e>=this._pointerPressed.length?!1:this._pointerPressed[e]}getPointerClicked(e){return e>=this._pointerClick.length?!1:this._pointerClick[e]}getPointerDoubleClicked(e){return e>=this._pointerDoubleClick.length?!1:this._pointerDoubleClick[e]}getPointerDownTime(e){return e>=this._pointerDownTime.length?-1:this._pointerDownTime[e]}getPointerUpTime(e){return e>=this._pointerUpTime.length?-1:this._pointerUpTime[e]}getPointerLongPress(e){return e>=this._pointerDownTime.length?!1:this.getPointerPressed(e)&&this.context.time.time-this._pointerDownTime[e]>this._longPressTimeThreshold}getIsMouse(e){return e<0||e>=this._pointerTypes.length?!1:this._pointerTypes[e]==="mouse"}getIsTouch(e){return e<0||e>=this._pointerTypes.length?!1:this._pointerTypes[e]==="touch"}getTouchesPressedCount(){let e=0;for(let t=0;t<this._pointerPressed.length;t++)this._pointerPressed[t]&&this.getIsTouch(t)&&e++;return e}getMouseWheelChanged(e=0){return e>=this._mouseWheelChanged.length?!1:this._mouseWheelChanged[e]}getMouseWheelDeltaY(e=0){return e>=this._mouseWheelDeltaY.length?0:this._mouseWheelDeltaY[e]}getPointerEvent(e){if(!(e>=this._pointerEvent.length))return this._pointerEvent[e]??void 0}*foreachPointerId(e){for(let t=0;t<this._pointerTypes.length;t++)if(this._pointerIsActive(t)){if(e!==void 0){const i=this._pointerTypes[t];if(Array.isArray(e)){let n=!1;for(const s of e)if(i===s){n=!0;break}if(!n)continue}else if(e!==i)continue}yield t}}*foreachTouchId(){for(let e=0;e<this._pointerTypes.length;e++)this._pointerTypes[e]==="touch"&&this._pointerIsActive[e]&&(yield e)}_pointerIsActive(e){return e<0?!1:this._pointerPressed[e]||this._pointerDown[e]||this._pointerUp[e]}context;_pointerDown=[!1];_pointerUp=[!1];_pointerClick=[!1];_pointerDoubleClick=[!1];_pointerPressed=[!1];_pointerPositions=[new J];_pointerPositionsLastFrame=[new J];_pointerPositionsDelta=[new J];_pointerPositionsRC=[new J];_pointerPositionDown=[new b];_pointerDownTime=[];_pointerUpTime=[];_pointerUpTimestamp=[];_pointerIds=[];_pointerTypes=[""];_mouseWheelChanged=[!1];_mouseWheelDeltaY=[0];_pointerEvent=[];_pointerEventsPressed=[];_pointerSpace=[];_pressedStack=new Map;onDownButton(e,t){let i=this._pressedStack.get(e);i||(i=[],this._pressedStack.set(e,i)),i.push(t)}onReleaseButton(e,t){const i=this._pressedStack.get(e);if(!i)return;const n=i.indexOf(t);n>=0&&i.splice(n,1)}getFirstPressedButtonForPointer(e){const t=this._pressedStack.get(e);if(t)return t[0]}getLatestPressedButtonForPointer(e){const t=this._pressedStack.get(e);if(t)return t[t.length-1]}getKeyDown(e){if(e!==void 0)return this.isKeyDown(e);for(const t in this.keysPressed){const i=this.keysPressed[t];if(i.startFrame===this.context.time.frameCount)return i.key}return null}getKeyPressed(e){if(e!==void 0)return this.isKeyPressed(e);for(const t in this.keysPressed){const i=this.keysPressed[t];if(i.pressed)return i.key}return null}getKeyUp(e){if(e!==void 0)return this.isKeyUp(e);for(const t in this.keysPressed){const i=this.keysPressed[t];return i.pressed===!1&&i.frame===this.context.time.frameCount}return null}isKeyDown(e){if(!this.context.application.isVisible||!this.context.application.hasFocus)return!1;const t=this.getCodeForCommonKeyName(e);if(t!==null){for(const n of t)if(this.isKeyDown(n))return!0;return!1}const i=this.keysPressed[e];return i?i.startFrame===this.context.time.frameCount&&i.pressed:!1}isKeyUp(e){if(!this.context.application.isVisible||!this.context.application.hasFocus)return!1;const t=this.getCodeForCommonKeyName(e);if(t!==null){for(const n of t)if(this.isKeyUp(n))return!0;return!1}const i=this.keysPressed[e];return i?i.frame===this.context.time.frameCount&&i.pressed===!1:!1}isKeyPressed(e){if(!this.context.application.isVisible||!this.context.application.hasFocus)return!1;const t=this.getCodeForCommonKeyName(e);if(t!==null){for(const n of t)if(this.isKeyPressed(n))return!0;return!1}const i=this.keysPressed[e];return i&&i.pressed||!1}getCodeForCommonKeyName(e){if(e.length===1){if(e>="0"&&e<="9")return["Digit"+e];if(e>="a"&&e<="z")return["Key"+e.toUpperCase()];if(e==" ")return["Space"]}switch(e){case"shift":case"Shift":return["ShiftLeft","ShiftRight"];case"control":case"Control":return["ControlLeft","ControlRight"];case"alt":case"Alt":return["AltLeft","AltRight"]}return null}createInputEvent(e){switch(e.type){case"pointerdown":st&&Ee("Create Pointer down"),this.onDownButton(e.deviceIndex,e.button),this.onDown(e);break;case"pointermove":st&&Ee("Create Pointer move"),this.onMove(e);break;case"pointerup":st&&Ee("Create Pointer up"),this.onUp(e),this.onReleaseButton(e.deviceIndex,e.button);break}}convertScreenspaceToRaycastSpace(e){return e.x=(e.x-this.context.domX)/this.context.domWidth*2-1,e.y=-((e.y-this.context.domY)/this.context.domHeight)*2+1,e}constructor(e){this.context=e,this.context.post_render_callbacks.push(this.onEndOfFrame)}_htmlEventSource;bindEvents(){this.unbindEvents(),this._htmlEventSource=this.context.renderer.domElement,window.addEventListener("contextmenu",this.onContextMenu),this._htmlEventSource.addEventListener("pointerdown",this.onPointerDown,{passive:!0}),window.addEventListener("pointermove",this.onPointerMove,{passive:!0,capture:!0}),window.addEventListener("pointerup",this.onPointerUp,{passive:!0}),window.addEventListener("pointercancel",this.onPointerCancel,{passive:!0}),window.addEventListener("touchstart",this.onTouchStart,{passive:!0}),window.addEventListener("touchmove",this.onTouchMove,{passive:!0}),window.addEventListener("touchend",this.onTouchEnd,{passive:!0}),this._htmlEventSource.addEventListener("wheel",this.onMouseWheel,{passive:!0}),window.addEventListener("wheel",this.onWheelWindow,{passive:!0}),window.addEventListener("keydown",this.onKeyDown,!1),window.addEventListener("keypress",this.onKeyPressed,!1),window.addEventListener("keyup",this.onKeyUp,!1),window.addEventListener("blur",this.onLostFocus)}unbindEvents(){for(const e in this._eventListeners)this._eventListeners[e].length=0;window.removeEventListener("contextmenu",this.onContextMenu),this._htmlEventSource?.removeEventListener("pointerdown",this.onPointerDown),window.removeEventListener("pointermove",this.onPointerMove),window.removeEventListener("pointerup",this.onPointerUp),window.removeEventListener("pointercancel",this.onPointerCancel),window.removeEventListener("touchstart",this.onTouchStart),window.removeEventListener("touchmove",this.onTouchMove),window.removeEventListener("touchend",this.onTouchEnd),this._htmlEventSource?.removeEventListener("wheel",this.onMouseWheel,!1),window.removeEventListener("wheel",this.onWheelWindow,!1),window.removeEventListener("keydown",this.onKeyDown,!1),window.removeEventListener("keypress",this.onKeyPressed,!1),window.removeEventListener("keyup",this.onKeyUp,!1),window.removeEventListener("blur",this.onLostFocus)}dispose(){const e=this.context.post_render_callbacks.indexOf(this.onEndOfFrame);e>=0&&this.context.post_render_callbacks.splice(e,1),this.unbindEvents()}onLostFocus=()=>{for(const e in this.keysPressed)this.keysPressed[e].pressed=!1};_receivedPointerMoveEventsThisFrame=new Array;onEndOfFrame=()=>{this._receivedPointerMoveEventsThisFrame.length=0;for(let e=0;e<this._pointerUp.length;e++)this._pointerUp[e]=!1;for(let e=0;e<this._pointerDown.length;e++)this._pointerDown[e]=!1;for(let e=0;e<this._pointerClick.length;e++)this._pointerClick[e]=!1;for(let e=0;e<this._pointerDoubleClick.length;e++)this._pointerDoubleClick[e]=!1;for(const e of this._pointerPositionsDelta)e.set(0,0);for(let e=0;e<this._mouseWheelChanged.length;e++)this._mouseWheelChanged[e]=!1;for(let e=0;e<this._mouseWheelDeltaY.length;e++)this._mouseWheelDeltaY[e]=0};canReceiveInput(e){return e.target===this.context.renderer?.domElement||e.target===this.context.domElement||this.context.isInAR||this.context.isInAR&&e.target===document.body&&q.isMozillaXR()?!0:(st&&console.warn("CanReceiveInput:False for",e.target),!1)}onContextMenu=e=>{this.canReceiveInput(e)!==!1&&e instanceof PointerEvent&&e.pointerType};keysPressed={};onKeyDown=e=>{if(st&&console.log(`key down ${e.code}, ${this.context.application.hasFocus}`,e),!this.context.application.hasFocus)return;const t=this.keysPressed[e.code];if(t&&t.pressed)return;this.keysPressed[e.code]={pressed:!0,frame:this.context.time.frameCount+1,startFrame:this.context.time.frameCount+1,key:e.key,code:e.code};const i=new lc("keydown",e,e);this.onDispatchEvent(i)};onKeyPressed=e=>{if(!this.context.application.hasFocus)return;const t=this.keysPressed[e.code];if(!t)return;t.pressed=!0,t.frame=this.context.time.frameCount+1;const i=new lc("keypress",e,e);this.onDispatchEvent(i)};onKeyUp=e=>{if(!this.context.application.hasFocus)return;const t=this.keysPressed[e.code];if(!t)return;t.pressed=!1,t.frame=this.context.time.frameCount+1;const i=new lc("keyup",e,e);this.onDispatchEvent(i)};onWheelWindow=e=>{document.pointerLockElement&&this.onMouseWheel(e)};onMouseWheel=e=>{if(this.canReceiveInput(e)===!1)return;this._mouseWheelDeltaY.length<=0&&this._mouseWheelDeltaY.push(0),this._mouseWheelChanged.length<=0&&this._mouseWheelChanged.push(!1),this._mouseWheelChanged[0]=!0;const t=this._mouseWheelDeltaY[0];this._mouseWheelDeltaY[0]=t+e.deltaY};onPointerDown=e=>{if(this.context.isInAR||this.canReceiveInput(e)===!1)return;e.target instanceof HTMLElement&&e.target.setPointerCapture(e.pointerId);const t=this.getPointerId(e);st&&Ee(`pointer down #${t}, identifier:${e.pointerId}`);const i=this.getAndUpdateSpatialObjectForScreenPosition(t,e.clientX,e.clientY),n=new Oo("pointerdown",e,{origin:this,mode:"screen",deviceIndex:0,pointerId:t,button:e.button,clientX:e.clientX,clientY:e.clientY,pointerType:e.pointerType,buttonName:this.getButtonName(e),device:i,pressure:e.pressure});this.onDown(n)};onPointerMove=e=>{if(this.context.isInAR||this._receivedPointerMoveEventsThisFrame.includes(e.pointerId))return;this._receivedPointerMoveEventsThisFrame.push(e.pointerId);let t=e.button;e.pointerType==="mouse"&&(t=this.getFirstPressedButtonForPointer(0)??0);const i=this.getPointerId(e,t);t===-1&&(t=i);const n=this.getAndUpdateSpatialObjectForScreenPosition(i,e.clientX,e.clientY),s=new Oo("pointermove",e,{origin:this,mode:"screen",deviceIndex:0,pointerId:i,button:t,clientX:e.clientX,clientY:e.clientY,pointerType:e.pointerType,buttonName:this.getButtonName(e),device:n,pressure:e.pressure});this.onMove(s)};onPointerCancel=e=>{this.context.isInAR||(st&&console.log("Pointer cancel",e),this.onPointerUp(e))};onPointerUp=e=>{if(this.context.isInAR)return;e.target instanceof HTMLElement&&e.target.releasePointerCapture(e.pointerId);const t=this.getPointerId(e),i=new Oo("pointerup",e,{origin:this,mode:"screen",deviceIndex:0,pointerId:t,button:e.button,clientX:e.clientX,clientY:e.clientY,pointerType:e.pointerType,buttonName:this.getButtonName(e),device:this.getAndUpdateSpatialObjectForScreenPosition(t,e.clientX,e.clientY),pressure:e.pressure});this.onUp(i),this._pointerIds[t]=-1,st&&console.log("ID="+t,"PointerId="+e.pointerId,"ALL:",[...this._pointerIds])};getPointerId(e,t){return e.pointerType==="mouse"?0+(t??e.button):this.getPointerIndex(e.pointerId)}getButtonName(e){const t=e.button;if(e.pointerType==="mouse")switch(t){case 0:return"left";case 1:return"middle";case 2:return"right"}return"unknown"}onTouchStart=e=>{if(this.context.isInAR)for(let t=0;t<e.changedTouches.length;t++){const i=e.changedTouches[t],n=this.getPointerIndex(i.identifier),s=this.getAndUpdateSpatialObjectForScreenPosition(n,i.clientX,i.clientY),r=new Oo("pointerdown",e,{origin:this,mode:"screen",deviceIndex:0,pointerId:n,button:0,clientX:i.clientX,clientY:i.clientY,pointerType:"touch",buttonName:"unknown",device:s,pressure:i.force});this.onDown(r)}};onTouchMove=e=>{if(this.context.isInAR)for(let t=0;t<e.changedTouches.length;t++){const i=e.changedTouches[t],n=this.getPointerIndex(i.identifier),s=this.getAndUpdateSpatialObjectForScreenPosition(n,i.clientX,i.clientY),r=new Oo("pointermove",e,{origin:this,mode:"screen",deviceIndex:0,pointerId:n,button:0,clientX:i.clientX,clientY:i.clientY,pointerType:"touch",buttonName:"unknown",device:s,pressure:i.force});this.onMove(r)}};onTouchEnd=e=>{if(this.context.isInAR)for(let t=0;t<e.changedTouches.length;t++){const i=e.changedTouches[t],n=this.getPointerIndex(i.identifier),s=new Oo("pointerup",e,{origin:this,mode:"screen",deviceIndex:0,pointerId:n,button:0,clientX:i.clientX,clientY:i.clientY,pointerType:"touch",buttonName:"unknown",device:this.getAndUpdateSpatialObjectForScreenPosition(n,i.clientX,i.clientY),pressure:i.force});this.onUp(s),this._pointerIds[n]=-1}};tempNearPlaneVector=new b;tempFarPlaneVector=new b;tempLookMatrix=new Z;getAndUpdateSpatialObjectForScreenPosition(e,t,i){let n=this._pointerSpace[e];n||(n=new O,this._pointerSpace[e]=n),this._pointerSpace[e]=n;const s=this.context.mainCamera;if(s){const r=this.tempNearPlaneVector.set(t,i,-1);this.convertScreenspaceToRaycastSpace(r);const a=this.tempFarPlaneVector.set(r.x,r.y,1);r.unproject(s),a.unproject(s);const l=s.worldUp||D(0,1,0).applyQuaternion(be(s));this.tempLookMatrix.lookAt(a,r,l),n.position.set(r.x,r.y,r.z),n.quaternion.setFromRotationMatrix(this.tempLookMatrix)}return n}isInRect(e){if(this.context.isInXR)return!0;const t=this.context.domElement.getBoundingClientRect(),i=e.clientX,n=e.clientY,s=i>=t.x&&i<=t.right&&n>=t.y&&n<=t.bottom;return st&&!s&&console.log("Not in rect",t,i,n),s}onDown(e){const t=e.pointerId;if(this.getPointerPressed(t)&&console.warn(`Received pointerDown for pointerId that is already pressed: ${t}`,st?e:""),st&&console.log(e.pointerType,"DOWN",t),!!this.isInRect(e)){for(this.setPointerState(t,this._pointerPressed,!0),this.setPointerState(t,this._pointerDown,!0),this.setPointerStateT(t,this._pointerEvent,e.source);t>=this._pointerTypes.length;)this._pointerTypes.push(e.pointerType);for(this._pointerTypes[t]=e.pointerType;t>=this._pointerPositionDown.length;)this._pointerPositionDown.push(new b);for(this._pointerPositionDown[t].set(e.clientX,e.clientY,e.clientZ??0);t>=this._pointerPositions.length;)this._pointerPositions.push(new J);this._pointerPositions[t].set(e.clientX,e.clientY),t>=this._pointerDownTime.length&&this._pointerDownTime.push(0),this._pointerDownTime[t]=this.context.time.realtimeSinceStartup,this.updatePointerPosition(e),this._pointerEventsPressed.push(e),this.onDispatchEvent(e)}}onMove(e){const t=e.pointerId,i=this.getPointerPressed(t);i===!1&&!this.isInRect(e)||e.pointerType==="touch"&&!i||(this.updatePointerPosition(e),this.setPointerStateT(t,this._pointerEvent,e.source),this.onDispatchEvent(e))}onUp(e){const t=e.pointerId;if(!this.getPointerPressed(t)){st&&console.log(e.pointerType,"UP",t,"was not down");return}st&&console.log(e.pointerType,"UP",t),this.setPointerState(t,this._pointerPressed,!1),this.setPointerStateT(t,this._pointerEvent,e.source),this.setPointerState(t,this._pointerUp,!0),this.updatePointerPosition(e);for(let a=this._pointerEventsPressed.length-1;a>=0;a--)if(this._pointerEventsPressed[a].pointerId===t){this._pointerEventsPressed.splice(a,1);break}if(!this._pointerPositionDown[t]){st&&fe("Received pointer up event without matching down event for button: "+t),console.warn("Received pointer up event without matching down event for button: "+t);return}const i=this._pointerUpTime[t],n=this._pointerDownTime[t],s=this.context.time.realtimeSinceStartup,r=s-n;if(t>=this._pointerUpTime.length&&this._pointerUpTime.push(-99),this._pointerUpTime[t]=s,r<1){let a=e.clientX-this._pointerPositionDown[t].x,l=e.clientY-this._pointerPositionDown[t].y,c=0;if(e.isSpatial&&e.clientZ!=null&&(c=e.clientZ-this._pointerPositionDown[t].z,a*=200,l*=200,c*=200),Math.abs(a)<5&&Math.abs(l)<5&&Math.abs(c)<5){this.setPointerState(t,this._pointerClick,!0),e.isClick=!0;const h=s-i;st&&console.log("CLICK",t,a,l,c,h),h<this._doubleClickTimeThreshold&&h>0&&(this.setPointerState(t,this._pointerDoubleClick,!0),e.isDoubleClick=!0)}}this.onDispatchEvent(e)}updatePointerPosition(e){const t=e.pointerId;for(;t>=this._pointerPositions.length;)this._pointerPositions.push(new J);for(;t>=this._pointerPositionsLastFrame.length;)this._pointerPositionsLastFrame.push(new J);for(;t>=this._pointerPositionsDelta.length;)this._pointerPositionsDelta.push(new J);const i=this._pointerPositionsLastFrame[t];i.copy(this._pointerPositions[t]);const n=this._pointerPositionsDelta[t];let s=e.clientX-i.x,r=e.clientY-i.y;if(e.source instanceof MouseEvent||e.source instanceof TouchEvent){const h=e.source;s===0&&h.movementX!==0&&(s=h.movementX||0),r===0&&h.movementY!==0&&(r=h.movementY||0)}n.x+=s,n.y+=r,this._pointerPositions[t].x=e.clientX,this._pointerPositions[t].y=e.clientY;const a=e.clientX,l=e.clientY;for(;t>=this._pointerPositionsRC.length;)this._pointerPositionsRC.push(new J);const c=this._pointerPositionsRC[t];c.set(a,l),this.convertScreenspaceToRaycastSpace(c)}getPointerIndex(e){let t=-1;for(let i=0;i<this._pointerIds.length;i++){if(this._pointerIds[i]===e)return i;t===-1&&this._pointerIds[i]===-1&&(t=i)}return t!==-1?(this._pointerIds[t]=e,t):(st&&console.log("PUSH pointerId:",e),this._pointerIds.push(e),this._pointerIds.length-1)}setPointerState(e,t,i){t[e]=i}setPointerStateT(e,t,i){return t[e]=i,i}onDispatchEvent(e){const t=V.Current;try{V.Current=this.context,this.dispatchEvent(e)}finally{V.Current=t}}}const La=new Z().makeRotationY(Math.PI),Gi=new N().setFromAxisAngle(new b(0,1,0),Math.PI),WO=v("debugwebxr");class $O{priority=-1e5;gameObject;isXRRig(){return!0}get isActive(){return this.gameObject.visible}constructor(){if(this.gameObject=new O,this.gameObject.name="Implicit XR Rig",WO){const e=Sg(16733661);e.position.y+=.5,this.gameObject.add(e)}}}const ko=v("debugwebxr"),Nd=v("debugcustomgesture"),HO="https://cdn.jsdelivr.net/npm/@webxr-input-profiles/assets@1.0/dist/profiles",GO="generic-trigger",qO=new N().setFromEuler(new ot(bo.degToRad(0),bo.degToRad(-90),bo.degToRad(-90))),XO=new b(.04,-.04,0);class cg{xr;get context(){return this.xr.context}inputSource;index=0;emitEvents=!0;get connected(){return this._connected}_connected=!0;get isTracking(){return this._isTracking}_isTracking=!1;get gamepad(){return this.__gamepad??=this.inputSource.gamepad}__gamepad;get isHand(){return this.hand!=null}get hand(){return this.__hand??=this.inputSource.hand}__hand;get handObject(){return this.context.renderer.xr.getHand(this.index)}get profiles(){return this.inputSource.profiles}get layout(){return this._layout}get targetRayMode(){return this.inputSource.targetRayMode}get targetRaySpace(){return this.inputSource.targetRaySpace}get gripSpace(){return this.inputSource.gripSpace}get side(){return this.__side??=this.inputSource.handedness}__side=void 0;get isRight(){return this.side==="right"}get isLeft(){return this.side==="left"}get isStylus(){return this._isMxInk}getHitTestSource(){return this._hitTestSource||this._requestHitTestSource(),this._hitTestSource}get hasHitTestSource(){return this._hitTestSource}cancelHitTestSource(){this._hitTestSource&&(this._hitTestSource.cancel(),this._hitTestSource=void 0)}_hitTestSource=void 0;_hasSelectEvent=!1;get hasSelectEvent(){return this._hasSelectEvent}_isMxInk=!1;_isMetaQuestTouchController=!1;getHitTest(){return this.xr.getHitTest(this)}_handJointPoses=new Map;getHandJointPose(e,t){if(t=t||this.xr.frame,!this.hand||!t?.getJointPose||!this.xr.referenceSpace)return null;let i=this._handJointPoses?.get(e);return i||(i=t.getJointPose(e,this.xr.referenceSpace),i&&this._handJointPoses.set(e,i),i)}_gripMatrix=new Z;_gripPosition=new b;_gripQuaternion=new N;_linearVelocity=new b;_rayPositionRaw=new b;_rayRotationRaw=new N;_rayMatrix=new Z;_rayPosition=new b;_rayQuaternion=new N;get gripPosition(){return D(this._gripPosition)}get gripQuaternion(){return ni(this._gripQuaternion)}get gripMatrix(){return this._gripMatrix}get gripLinearVelocity(){return D(this._linearVelocity).applyQuaternion(Gi)}get rayPosition(){return D(this._rayPosition)}get rayQuaternion(){return ni(this._rayQuaternion)}get gripWorldPosition(){return D(this._gripWorldPosition)}_gripWorldPosition=new b;get gripWorldQuaternion(){return ni(this._gripWorldQuaternion)}_gripWorldQuaternion=new N;get rayWorldPosition(){return D(this._rayWorldPosition)}_rayWorldPosition=new b;updateRayWorldPosition(){const e=this.xr.context.mainCamera?.parent;this._rayWorldPosition.copy(this._rayPositionRaw),e&&this._rayWorldPosition.applyMatrix4(e.matrixWorld)}get rayWorldQuaternion(){return ni(this._rayWorldQuaternion)}_rayWorldQuaternion=new N;get pinchPosition(){return D(this._pinchPosition)}_pinchPosition=new b;updateRayWorldQuaternion(){const e=this.xr.context.mainCamera?.parent,t=e?be(e):void 0;this._rayWorldQuaternion.copy(this._rayRotationRaw).multiply(Gi),t&&this._rayWorldQuaternion.premultiply(t)}get ray(){return this._ray.origin.copy(this.rayWorldPosition),this._ray.direction.copy(D(0,0,1).applyQuaternion(this.rayWorldQuaternion)),this._ray}_ray;_hand_wristDotUp=void 0;get handWristDotUp(){if(this._hand_wristDotUp!==void 0)return this._hand_wristDotUp;const e=this.handObject?.joints.wrist;if(e){const t=D(0,1,0).applyQuaternion(e.quaternion),i=D(0,1,0).dot(t);return this._hand_wristDotUp=i}}get isHandUpsideDown(){return this.handWristDotUp!==void 0?this.handWristDotUp<-.7:!1}get isTeleportGesture(){return this.isHandUpsideDown&&this.getGesture("pinch")?.isDown}get object(){return this._object}_object;_gripSpaceObject;_raySpaceObject;model=null;_debugAxesHelper=new xi(.15);_debugGripAxesHelper=new xi(.07);_debugRayAxesHelper=new xi(.07);async getModelUrl(){return this.getMotionController?.then(e=>e?.assetUrl||null)}constructor(e,t,i){this.xr=e,this.inputSource=t,this.index=i,this._object=new O,this._object.name=`NeedleXRController_${i}`,ko&&(this._object.add(this._debugAxesHelper),this._gripSpaceObject=new O,this._raySpaceObject=new O,this._gripSpaceObject.name=`NeedleXRController_${i}_gripSpace`,this._raySpaceObject.name=`NeedleXRController_${i}_raySpace`,this._gripSpaceObject.add(this._debugGripAxesHelper),this._raySpaceObject.add(this._debugRayAxesHelper),this.xr.context.scene.add(this._gripSpaceObject),this.xr.context.scene.add(this._raySpaceObject)),this.xr.context.scene.add(this._object),this._ray=new yo,this.pointerInit={origin:this,pointerType:this.hand?"hand":"controller",deviceIndex:this.index,pointerId:-1,mode:this.inputSource.targetRayMode,ray:this._ray,device:this._object,buttonName:"none"},this.initialize(),this.subscribeEvents()}_hitTestSourcePromise=null;_requestHitTestSource(){return this._hitTestSourcePromise?this._hitTestSourcePromise:this.xr.mode==="immersive-ar"&&this.inputSource.targetRayMode==="tracked-pointer"&&this.xr.session.requestHitTestSourceForTransientInput?this._hitTestSourcePromise=this.xr.session.requestHitTestSourceForTransientInput({profile:this.inputSource.profiles[0],offsetRay:new XRRay})?.then(e=>(this._hitTestSourcePromise=null,this.connected?this._hitTestSource=e:(e.cancel(),null)))??null:null}onPointerHits=e=>{};onUpdate(e){this.onUpdateFrame(e),this.updateInputEvents(),this.onUpdateMove()}onRenderDebug(){B.DrawSphere(this.rayWorldPosition,.003),B.DrawDirection(this.rayWorldPosition,D(0,0,10).applyQuaternion(this.rayWorldQuaternion));const e=(this.inputSource.gripSpace?this.gripWorldPosition:this.object.worldPosition).sub(this.object.worldForward.multiplyScalar(.1)),t=this.inputSource.profiles.join(`
146
146
  `);let i=`Controller[${this.index}] (${this.inputSource.targetRayMode}, ${this.side})
147
147
  C:${this.connected?"x":"-"} T:${this.isTracking?"x":"-"} Hand:${this.inputSource.hand?"x":"-"} Pen: ${this._isMxInk?"x":"-"}`;if(this.inputSource.hand&&(i+=`
@@ -164,7 +164,7 @@ See https://engine.needle.tools/docs/scripting.html#special-lifecycle-hooks for
164
164
  `+qi);const s=await import("./vendor-DWGd3dEf.min.js").then(c=>c.index),r=s.default?.WebsocketBuilder??s.WebsocketBuilder,a=s.default?.ExponentialBackoff??s.ExponentialBackoff,l=new r(qi).withMaxRetries(10).withBackoff(new a(2e3,4)).onOpen(()=>{this._connectingToWebsocketPromise=null,this._ws=l,this.connected=!0,A()||si?console.log(`\u229E Connected to networking backend
165
165
  `+qi):console.debug("\u229E Connected to networking backend",qi),n(!0),this.onSendQueued(vn.OnConnection)}).onClose(c=>{this._connectingToWebsocketPromise=null,this.connected=!1,this._isInRoom=!1,n(!1);let h="Websocket connection closed...";qi?.includes("/socket")||(h+=' Do you perhaps mean to connect to "/socket"?'),console.error(h)}).onError(c=>{console.error("\u22A0 Websocket connection failed..."),n(!1)}).onRetry(()=>{console.log("\u2192 Retry connecting to networking websocket")}).build();l.addEventListener(s.WebsocketEvent.message,(c,h)=>{this.onMessage(c,h)})})}onMessage(e,t){const i=t.data;try{if(typeof i!="string"){i.size&&this.handleIncomingBinaryMessage(i);return}const n=JSON.parse(i);if(Array.isArray(n))for(const s of n)this.handleIncomingStringMessage(s);else this.handleIncomingStringMessage(n);return}catch(n){si&&i==="pong"?console.log("<<",i):A()&&console.error("Failed to parse message",n)}}async handleIncomingBinaryMessage(e){$d&&console.log("<< bin",this.context.time.frame);const t=await e.arrayBuffer();var i=new Uint8Array(t);const n=new oP(i),s=n.getBufferIdentifier(),r=this._listenersBinary[s],a=T_(n),l=E_(a);if(l&&typeof l=="string"&&(this._state[l]=a),!r)return;const c=a??n;for(const h of r)h(c)}handleIncomingStringMessage(e){if(si&&console.log("<<",e.key??e),e.key)switch(e.key){case"connection-start-info":if(e.data){const r=e.data;r&&(console.assert(r.id!==void 0&&r.id!==null&&r.id.length>0,"server did not send connection id",r.id),console.debug("Your id is: "+r.id,this.context.alias??""),this._connectionId=r.id)}else console.warn("Expected connection id in "+e.key);break;case"joined-room":if(si&&console.log(e),e){this._isInRoom=!0;const r=e;this._currentRoomName=r.room,this._currentRoomViewId=r.viewId,this._currentRoomAllowEditing=r.allowEditing??!0,this._currentInRoom.length=0,this._currentInRoom.push(...r.inRoom),($d||A())&&console.debug("Joined Needle Engine Room: "+r.room);const a=new URL(window.location.href);a.searchParams.has("room")&&a.searchParams.delete("room"),a.searchParams.set("view",this._currentRoomViewId),console.debug(`Room view id: ${this._currentRoomViewId}
166
166
  ${a.href}`)}this.onSendQueued(vn.OnRoomJoin);break;case"left-room":const n=e;n.room===this.currentRoomName&&(this._isInRoom=!1,this._currentRoomName=null,this._currentRoomAllowEditing=!0,this._currentInRoom.length=0,($d||A())&&console.debug("Left Needle Engine Room: "+n.room));break;case"user-joined-room":if(e.data){const r=e.data;this._currentInRoom.push(r.userId),si&&console.log(r.userId+" joined","now in room:",this._currentInRoom)}break;case"user-left-room":if(e.data){const r=e.data,a=this._currentInRoom.indexOf(r.userId);a>=0&&(si&&console.log(r.userId+" left","now in room:",this._currentInRoom),this._currentInRoom.splice(a,1)),r.userId===this.connectionId&&console.log("you left the room")}break;case"all-room-state-deleted":si&&console.log("RECEIVED all-room-state-deleted"),this._state={};break;case"ping":case"pong":const s=e.data?.time;s&&(this._currentDelay=this.context.time.time-s),si&&console.log(`Current latency: ${(this._currentDelay*1e3).toFixed()} ms`,"Clients in room: "+this._currentInRoom?.length);break}const t=e.data;t&&(this._state[t.guid]=t);let i=this._listeners[e.key];if(i){i=[...i];for(const n of i)try{n(e.data)}catch(s){console.error('Error invoking callback for "'+e.key+'"',s)}}}toMessage(e,t){return{key:e,data:t}}sendWithWebsocket(e,t,i=vn.OnRoomJoin){if(!this._ws){const s=this._waitingForSocket[i]||[];s.push(()=>this.sendWithWebsocket(e,t,i)),this._waitingForSocket[i]=s;return}const n=JSON.stringify(this.toMessage(e,t));si&&console.log(">>",e),this._ws.send(n)}onSendQueued(e){const t=this._waitingForSocket[e];if(t){for(const i of t)i();t.length=0}}}const hc=v("debugwebxr");class fg{controllerStates=[];userId;context;userStateEvtName;constructor(e,t){this.userId=e,this.context=t,this.userStateEvtName="xr-sync-user-state-"+e,this.context.connection.beginListen(this.userStateEvtName,this.onReceivedControllerState)}dispose(){this.context.connection.stopListen(this.userStateEvtName,this.onReceivedControllerState)}onReceivedControllerState=e=>{hc&&console.log(`XRSync: Received change for ${this.userId}: ${e.type} ${e.handedness}; tracked=${e.isTracking}`);let t=!1;for(let i=0;i<this.controllerStates.length;i++)if(this.controllerStates[i].index===e.index){this.controllerStates[i]=e,t=!0;break}t||this.controllerStates.push(e)};update(e){if(this.context.connection.isConnected!=!1){for(let t=this.controllerStates.length-1;t>=0;t--){const i=this.controllerStates[t];let n=!1;for(let s=0;s<e.controllers.length;s++)e.controllers[s].index===i.index&&(n=!0);n||(hc&&console.log(`XRSync: ${i.type} ${i.handedness} removed`,i.index),this.controllerStates.splice(t,1),this.sendControllerRemoved(i))}for(const t of e.controllers)this.updateControllerStates(t)}}onExitXR(e){for(const t of this.controllerStates)this.sendControllerRemoved(t);this.controllerStates.length=0}sendControllerRemoved(e){e.isTracking=!1,e.guid="",this.context.connection.send(this.userStateEvtName,e),this.context.connection.sendDeleteRemoteState(e.guid)}updateControllerStates(e){const t=this.controllerStates.find(i=>i.index===e.index);if(t){let i=!1;i||=t.isTracking!=e.isTracking,i&&(t.isTracking=e.isTracking,this.context.connection.send(this.userStateEvtName,t))}else{const i={guid:this.userId+"-"+e.index,isTracking:e.isTracking,handedness:e.side,index:e.index,type:e.hand?"hand":"controller"};this.controllerStates.push(i),this.context.connection.send(this.userStateEvtName,i),hc&&console.log(`XRSync: ${i.type} ${i.handedness} added`,i.index)}}}class U_{hasState(e){return e?this._states.has(e):!1}isTracking(e,t){if(!e)return;const i=this._states.get(e);return i?i.controllerStates.find(n=>n.handedness===t)?.isTracking||!1:void 0}getDeviceType(e,t){if(!e)return;const i=this._states.get(e);return i?i.controllerStates.find(n=>n.handedness===t)?.type||"unknown":void 0}context;constructor(e){this.context=e,this.context.connection.beginListen(te.JoinedRoom,this.onJoinedRoom),this.context.connection.beginListen(te.LeftRoom,this.onLeftRoom),this.context.connection.beginListen(te.UserJoinedRoom,this.onOtherUserJoinedRoom),this.context.connection.beginListen(te.UserLeftRoom,this.onOtherUserLeftRoom)}destroy(){this.context.connection.stopListen(te.JoinedRoom,this.onJoinedRoom),this.context.connection.stopListen(te.LeftRoom,this.onLeftRoom),this.context.connection.stopListen(te.UserJoinedRoom,this.onOtherUserJoinedRoom),this.context.connection.stopListen(te.UserLeftRoom,this.onOtherUserLeftRoom)}onJoinedRoom=()=>{if(this.context.connection.connectionId){this._states.has(this.context.connection.connectionId)||(hc&&console.log("XRSync: Local user joined room",this.context.connection.connectionId),this._states.set(this.context.connection.connectionId,new fg(this.context.connection.connectionId,this.context)));for(const e of this.context.connection.usersInRoom())this._states.has(e)||this._states.set(e,new fg(e,this.context))}};onLeftRoom=()=>{this.context.connection.connectionId&&(this._states.has(this.context.connection.connectionId)||(this._states.get(this.context.connection.connectionId)?.dispose(),this._states.delete(this.context.connection.connectionId)))};onOtherUserJoinedRoom=e=>{const t=e.userId;this._states.has(t)||(hc&&console.log("XRSync: Remote user joined room",t),this._states.set(t,new fg(t,this.context)))};onOtherUserLeftRoom=e=>{const t=e.userId;this._states.has(t)||(this._states.get(t)?.dispose(),this._states.delete(t))};_states=new Map;onUpdate(e){this.context.connection.isConnected&&this.context.connection.connectionId&&this._states.get(this.context.connection.connectionId)?.update(e)}onExitXR(e){this.context.connection.isConnected&&this.context.connection.connectionId&&this._states.get(this.context.connection.connectionId)?.onExitXR(e)}}class z_{_fadeToColorQuad;_fadeToColorMaterial;constructor(){this._fadeToColorMaterial=new xe({color:0,transparent:!0,depthTest:!1,fog:!1,side:Si}),this._fadeToColorQuad=new G(new Fn(10,10),this._fadeToColorMaterial)}dispose(){this._fadeToColorQuad.geometry.dispose(),this._fadeToColorMaterial.dispose()}update(e,t){const i=this._fadeToColorQuad,n=this._fadeToColorMaterial;i.parent!==e&&n.opacity>0?e.add(i):n.opacity===0&&i.removeFromParent(),i.layers.set(2),i.material=this._fadeToColorMaterial,i.position.z=-1,i.renderOrder=1/0;const s=this._requestedFadeValue;n.opacity=I.lerp(n.opacity,s,t/.03),Math.abs(n.opacity-s)<=.01&&this._transitionResolve&&(this._transitionResolve(),this._transitionResolve=null,this._transitionPromise=null,this._requestedFadeValue=0)}remove(){this._fadeToColorQuad.removeFromParent()}fadeTransition(){if(this._transitionPromise)return this._transitionPromise;this._requestedFadeValue=1;const e=new Promise(t=>{this._transitionResolve=t});return this._transitionPromise=e,e}_requestedFadeValue=0;_transitionPromise=null;_transitionResolve=null}var wr=(o=>(o[o.Quad=0]="Quad",o[o.Cube=1]="Cube",o[o.Sphere=2]="Sphere",o[o.Cylinder=3]="Cylinder",o[o.RoundedCube=10]="RoundedCube",o))(wr||{});class xr{static createText(e,t){let i=null;const n=t?.font||nk(t?.familyFamily||null);n instanceof FC?i=this.#t(e,n,t):i==null&&(i=new gn);const s=t?.color||16777215,r=new G(i,t?.material??new pt({color:s}));return this.applyDefaultObjectOptions(r,t),n instanceof Promise?n.then(a=>{r.geometry=this.#t(e,a,t),t?.onGeometry&&t.onGeometry(r)}):t?.onGeometry&&t.onGeometry(r),r}static#t(e,t,i){const n=i?.depth||.1;return new UC(e,{font:t,size:1,depth:n,height:n,bevelEnabled:i?.bevel||!1,bevelThickness:.01,bevelOffset:.01,bevelSize:.01})}static createOccluder(e){const t=new xe({colorWrite:!1,depthWrite:!0,side:Si});return this.createPrimitive(e,{material:t})}static createPrimitive(e,t){let i;const n=t?.color||16777215;switch(e){case"Quad":case 0:{const s=new Fn(1,1,1,1),r=t?.material??new pt({color:n});t?.texture&&"map"in r&&(r.map=t.texture),i=new G(s,r),i.name="Quad"}break;case"Cube":case 1:{const s=new Sa(1,1,1),r=t?.material??new pt({color:n});t?.texture&&"map"in r&&(r.map=t.texture),i=new G(s,r),i.name="Cube"}break;case 10:case"RoundedCube":{const s=ik(1,1,1,.1,2),r=t?.material??new pt({color:n});t?.texture&&"map"in r&&(r.map=t.texture),i=new G(s,r),i.name="RoundedCube"}break;case"Sphere":case 2:{const s=new gd(.5,16,16),r=t?.material??new pt({color:n});t?.texture&&"map"in r&&(r.map=t.texture),i=new G(s,r),i.name="Sphere"}break;case"Cylinder":case 3:{const s=new K0(.5,.5,1,32),r=t?.material??new pt({color:n});t?.texture&&"map"in r&&(r.map=t.texture),i=new G(s,r),i.name="Cylinder"}break;case"ShaderBall":i=new _o,i.name="ShaderBall",ok(i,t);break}return this.applyDefaultObjectOptions(i,t),i}static createSprite(e){const t=new _S({color:16777215});e?.texture&&"map"in t&&(t.map=e.texture);const i=new vS(t);return this.applyDefaultObjectOptions(i,e),i}static applyDefaultObjectOptions(e,t){e.receiveShadow=!0,e.castShadow=!0,t?.name&&(e.name=t.name),t?.position&&(Array.isArray(t.position)?e.position.set(t.position[0],t.position[1],t.position[2]):e.position.set(t.position.x||0,t.position.y||0,t.position.z||0)),t?.rotation&&(Array.isArray(t.rotation)?e.rotation.set(t.rotation[0],t.rotation[1],t.rotation[2]):e.rotation.set(t.rotation.x||0,t.rotation.y||0,t.rotation.z||0)),t?.scale&&(typeof t.scale=="number"?e.scale.set(t.scale,t.scale,t.scale):Array.isArray(t.scale)?e.scale.set(t.scale[0],t.scale[1],t.scale[2]):e.scale.set(t.scale.x||1,t.scale.y||1,t.scale.z||1)),t?.receiveShadow!=null&&(e.receiveShadow=t.receiveShadow),t?.castShadow!=null&&(e.castShadow=t.castShadow),t?.parent&&t.parent.add(e)}}function ik(o,e,t,i,n){const s=new wS,r=1e-5,a=i-r;s.absarc(r,r,r,-Math.PI/2,-Math.PI,!0),s.absarc(r,e-a*2,r,Math.PI,Math.PI/2,!0),s.absarc(o-a*2,e-a*2,r,Math.PI/2,0,!0),s.absarc(o-a*2,r,r,0,-Math.PI/2,!0);const l=new xS(s,{bevelEnabled:!0,bevelSegments:n*2,steps:1,bevelSize:a,bevelThickness:i,curveSegments:n,UVGenerator:{generateTopUV:(c,h)=>{const d=[];for(let p=0;p<h.length;p+=3)d.push(new J(h[p]/o,h[p+1]/e));return d},generateSideWallUV:(c,h,d,p,m,f)=>{const g=[];return g.push(new J(h[d]/o,h[d+1]/e)),g.push(new J(h[p]/o,h[p+1]/e)),g.push(new J(h[m]/o,h[m+1]/e)),g.push(new J(h[f]/o,h[f+1]/e)),g}}});return l.scale(1,1,1-i),l.center(),l.index||l.setIndex(Array.from({length:l.attributes.position.count},(c,h)=>h)),l.computeVertexNormals(),l}const Hd=new Map;function nk(o){let e="";switch(o){default:case"OpenSans":e="https://cdn.needle.tools/static/fonts/facetype/Open Sans_Regular_ascii.json";break;case"Helvetiker":e="https://raw.githubusercontent.com/mrdoob/three.js/master/examples/fonts/helvetiker_regular.typeface.json";break}if(Hd.has(e)){const n=Hd.get(e);if(n)return n}const t=new zC,i=new Promise((n,s)=>{t.load(e,r=>{Hd.set(e,r),n(r)},void 0,s)});return Hd.set(e,i),i}let yg=!1,bg=null;function ok(o,e){if(bg===null){const t="https://cdn.needle.tools/static/models/shaderball.glb",i=new So,n=Cm(null);i.setDRACOLoader(n.dracoLoader),i.setKTX2Loader(n.ktx2Loader),yg=!0,bg=i.loadAsync(t).then(s=>{const r=s.scene;return r.position.y-=.5,r}).catch(s=>(console.warn("Failed to load shaderball mesh: "+s.message),V_())).finally(()=>{yg=!1})}if(yg){const t=V_();t.name="ShaderBall-Placeholder";const i=t.children[0];i?.type==="Mesh"&&N_(i,e),o.add(t)}bg.then(t=>{o.children.forEach(s=>{s.name==="ShaderBall-Placeholder"&&o.remove(s)});const i=t.clone(),n=i.children[0];n?.type==="Mesh"&&(n.geometry.attributes.tangent||n.geometry.computeTangents(),N_(n,e)),o.add(i)})}function N_(o,e){if(e?.color||e?.material||e?.texture){const t=e?.material??o.material?.clone()??new pt;e.color&&"color"in t&&t.color instanceof ne&&t.color.set(e.color),e?.texture&&"map"in t&&(t.map=e.texture),o.material=t}}function V_(){return new _o().add(xr.createPrimitive("Sphere",{material:new xe({transparent:!0,opacity:.1})}))}class Nl{static _active=null;static get active(){return this._active}static _requestInFlight=!1;static async start(e,t){if(this._active)return console.error("Cannot start a new XR session while one is already active"),null;if(this._requestInFlight)return console.error("Cannot start a new XR session while a request is already in flight"),null;if("xr"in navigator&&navigator.xr){if(!t)return console.error("XRSessionInit must be provided"),null;this._requestInFlight=!0;const i=await navigator.xr.requestSession(e,t);return i.addEventListener("end",()=>{this._active=null}),this._requestInFlight?(this._requestInFlight=!1,this._active=new Nl(e,t,i),this._active):(i.end(),null)}return null}static async handoff(){return this._active?this._active.handoff():null}static async stop(){this._requestInFlight=!1,this._active&&(await this._active.end(),await Nn(100)),this._active=null}_session;_mode;_init;get isAR(){return this._mode==="immersive-ar"}_renderer;_camera;_scene;constructor(e,t,i){this._mode=e,this._init=t,this._session=i,this._session.addEventListener("end",this.onEnd),this._renderer=new cr({alpha:!0}),this._renderer.setAnimationLoop(this.onFrame),this._renderer.xr.setSession(i),this._renderer.xr.enabled=!0,this._camera=new re,this._scene=new vi,this._scene.fog=new J0(4473924,10,250),this._scene.add(this._camera),this.setupScene()}end(){return this._session?this._session.end():Promise.resolve()}async handoff(){if(!this._session)throw new Error("Cannot handoff a session that has already ended");const e={session:this._session,mode:this._mode,init:this._init};return await this.onBeforeHandoff(),this.onEnd(),this._session=null,e}onEnd=()=>{this._session?.removeEventListener("end",this.onEnd),this._renderer.setAnimationLoop(null),this._renderer.dispose(),this._scene.clear()};_lastTime=0;onFrame=(e,t)=>{const i=e-this._lastTime;this.update(e,i),this._camera.parent!==this._scene&&this._scene.add(this._camera),this._renderer.render(this._scene,this._camera)};async onBeforeHandoff(){await Nn(1e3),this._scene.clear()}_objects=[];setupScene(){this._scene.background=new ne(0),this._scene.add(new hm(5,10,1118481,1118481));const e=new dm(16777215,1);e.position.set(0,20,0),e.castShadow=!1,this._scene.add(e);const t=new dm(16777215,1);t.position.set(0,-1,0),t.castShadow=!1,this._scene.add(t);const i=new um(16777215,1,100,1);i.position.set(0,2,0),i.castShadow=!1,i.distance=200,this._scene.add(i);const n=50;for(let s=0;s<100;s++){const r=new pt({color:2236962,metalness:1,roughness:.8});this.isAR&&(r.emissive=new ne(Math.random(),Math.random(),Math.random()),r.emissiveIntensity=Math.random());const a=I.random(0,1)>.5?wr.Sphere:wr.Cube,l=xr.createPrimitive(a,{material:r});l.position.x=I.random(-n,n),l.position.y=I.random(-2,n),l.position.z=I.random(-n,n),l.rotation.x=I.random(0,Math.PI*2),l.rotation.y=I.random(0,Math.PI*2),l.rotation.z=I.random(0,Math.PI*2),l.scale.multiplyScalar(.5+Math.random()*10);const c=l.position.distanceTo(this._camera.position)-l.scale.x;c<1&&l.position.multiplyScalar(1+1/c),this._objects.push(l),this._scene.add(l)}}update(e,t){const i=e*4e-4;for(let n=0;n<this._objects.length;n++){const s=this._objects[n];s.position.y+=Math.sin(i+n*.5)*.005,s.rotateY(.002)}}}var dc;(o=>{const e=[];function t(){if(!e?.length)return!1;for(const s of e)s.exportAndOpen();return!0}o.exportAndOpen=t;function i(s){e.push(s)}o.registerExporter=i;function n(s){if(!e)return;const r=e.indexOf(s);r>=0&&e.splice(r,1)}o.unregisterExporter=n})(dc||(dc={}));const Ge=v("debugwebxr"),W_=v("stats");let _g=0;function sk(o){let e=null;const t=o;return t.getAROverlayContainer?e=t.getAROverlayContainer():e=o,e}rk();async function rk(){if(v("debugasap")){let o=globalThis["needle:XRSession"];if(o instanceof Promise){delete globalThis["needle:XRSession"],ue.addContextCreatedCallback(async e=>{if(!o)return;fr(!0);const t=await o;if(t){const i=Y.getDefaultSessionInit("immersive-vr");Y.setSession("immersive-vr",t,i,e.context)}else console.error("NeedleXRSession: ASAP session was rejected");o=void 0});return}}if("xr"in navigator){if(/WebXRViewer\//i.test(navigator.userAgent)){console.warn("WebXRViewer does not support addEventListener");return}navigator.xr?.addEventListener("sessiongranted",async()=>{fr(!0),console.log("Received Session Granted..."),await Nn(100);const o=sessionStorage.getItem("needle_xr_session_mode"),e=sessionStorage.getItem("needle_xr_session_init")??null,t=e?JSON.parse(e):null;let i=null;if($_()&&(await Nl.start(o||"immersive-vr",t||Y.getDefaultSessionInit("immersive-vr")),await ck(),i=await Nl.handoff()),i)Y.setSession(i.mode,i.session,i.init,V.Current);else if(o&&e){console.log("Session Granted: Restore last session");const n=JSON.parse(e);Y.start(o,n).catch(s=>console.warn(s))}else Y.start("immersive-vr").catch(n=>console.warn("Session Granted failed:",n))},{once:!0})}}function ak(o,e){sessionStorage.setItem("needle_xr_session_mode",o),sessionStorage.setItem("needle_xr_session_init",JSON.stringify(e))}function lk(){sessionStorage.removeItem("needle_xr_session_mode"),sessionStorage.removeItem("needle_xr_session_init")}const vg=new Set;ue.registerCallback(de.ContextCreationStart,async o=>{vg.add(o.context)}),ue.registerCallback(de.ContextCreated,async o=>{vg.delete(o.context);const e=o.context?.domElement.getAttribute("autostart")||null;hk(e)});function $_(){return vg.size>0}function ck(){return new Promise(o=>{const e=Date.now(),t=setInterval(()=>{(!$_()||Date.now()-e>6e4)&&(clearInterval(t),o())},100)})}q.isDesktop()&&A()&&window.addEventListener("keydown",o=>{(o.key==="x"||o.key==="Escape")&&Y.active&&Y.stop()});function hk(o){if(o)switch(o?.toLowerCase()){case"ar":jn.registerWaitForInteraction(()=>{Y.start("ar")});break}}const Gd=Symbol("initial-fov");class Y{static _sync=null;static getXRSync(e){return this._sync||(this._sync=new U_(e)),this._sync}static get currentSessionRequest(){return this._currentSessionRequestMode}static _currentSessionRequestMode=null;static get active(){return this._activeSession}static get activeMode(){return this._activeSession?.mode??null}static get xrSystem(){return"xr"in navigator?navigator.xr:void 0}static isXRSupported(){return Promise.all([this.isVRSupported(),this.isARSupported()]).then(e=>e.some(t=>t)).catch(()=>!1)}static isVRSupported(){return this.isSessionSupported("immersive-vr")}static isARSupported(){return this.isSessionSupported("immersive-ar")}static isSessionSupported(e){return this.xrSystem?.isSessionSupported(e).catch(t=>(Ge&&console.error(t),!1))??Promise.resolve(!1)}static _currentSessionRequest;static _activeSession;static onSessionRequestStart(e){this._sessionRequestStartListeners.push(e)}static offSessionRequestStart(e){const t=this._sessionRequestStartListeners.indexOf(e);t>=0&&this._sessionRequestStartListeners.splice(t,1)}static _sessionRequestStartListeners=[];static onSessionRequestEnd(e){this._sessionRequestEndListeners.push(e)}static offSessionRequestEnd(e){const t=this._sessionRequestEndListeners.indexOf(e);t>=0&&this._sessionRequestEndListeners.splice(t,1)}static _sessionRequestEndListeners=[];static onXRSessionStart(e){this._xrStartListeners.push(e)}static offXRSessionStart(e){const t=this._xrStartListeners.indexOf(e);t>=0&&this._xrStartListeners.splice(t,1)}static _xrStartListeners=[];static onXRSessionEnd(e){this._xrEndListeners.push(e)}static offXRSessionEnd(e){const t=this._xrEndListeners.indexOf(e);t>=0&&this._xrEndListeners.splice(t,1)}static _xrEndListeners=[];static onControllerAdded(e){this._controllerAddedListeners.push(e)}static offControllerAdded(e){const t=this._controllerAddedListeners.indexOf(e);t>=0&&this._controllerAddedListeners.splice(t,1)}static _controllerAddedListeners=[];static onControllerRemoved(e){this._controllerRemovedListeners.push(e)}static offControllerRemoved(e){const t=this._controllerRemovedListeners.indexOf(e);t>=0&&this._controllerRemovedListeners.splice(t,1)}static _controllerRemovedListeners=[];static offerSession(e,t,i){return"xr"in navigator&&navigator.xr&&"offerSession"in navigator.xr?(typeof navigator.xr.offerSession=="function"&&(console.log("WebXR offerSession is available - requesting mode: "+e),t=="default"&&(t=this.getDefaultSessionInit(e)),navigator.xr.offerSession(e,{...t}).then(n=>Y.setSession(e,n,t,i)).catch(n=>{console.log("XRSession offer rejected (perhaps because another call to offerSession was made or a call to requestSession was made)")})),!0):!1}static getDefaultSessionInit(e){switch(e){case"immersive-ar":const t=["anchors","local-floor","layers","dom-overlay","hit-test","unbounded"];return q.isVisionOS()||t.push("hand-tracking"),{optionalFeatures:t};case"immersive-vr":const i=["local-floor","bounded-floor","high-fixed-foveation-level","layers"];return q.isVisionOS()||i.push("hand-tracking"),{optionalFeatures:i};default:return console.warn("No default session init for mode",e),{}}}static async start(e,t,i){if(q.isiOS()){if(e==="ar")if(await this.isARSupported())e="immersive-ar";else return dc.exportAndOpen(),null}else e=="ar"&&(e="immersive-ar");if(A()&&v("debugxrpreroom"))return console.warn("Debug: Starting temporary XR session"),await Nl.start(e,t||Y.getDefaultSessionInit(e)),null;if(this._currentSessionRequest)return console.warn("A XRSession is already being requested"),(Ge||A())&&fe("A XRSession is already being requested"),this._currentSessionRequest.then(()=>this._activeSession);if(this._activeSession)return console.error("A XRSession is already running"),this._activeSession;if(i||(i=V.Current),i||(i=ue.All[0]),!i)throw new Error("No Needle Engine Context found");switch(t||(t={}),e){case"immersive-ar":{if(await this.xrSystem?.isSessionSupported("immersive-ar")!==!0)return console.error(e+" is not supported by this browser."),null;const r=this.getDefaultSessionInit(e),a=sk(i.domElement);a&&!q.isQuest()&&(r.domOverlay={root:a},r.optionalFeatures.push("dom-overlay")),t={...r,...t}}break;case"immersive-vr":{if(await this.xrSystem?.isSessionSupported("immersive-vr")!==!0)return console.error(e+" is not supported by this browser."),null;t={...this.getDefaultSessionInit(e),...t}}break;default:console.warn("No default session init for mode",e);break}t.optionalFeatures??=[],t.requiredFeatures??=[],await Nl.stop();const n=e=="immersive-ar"?i.scripts_immersive_ar:i.scripts_immersive_vr;Ge?console.log(`%cRequesting ${e} session`,"font-weight:bold;",t,n):console.log(`%cRequesting ${e} session`,"font-weight:bold;");for(const r of n)r.onBeforeXR&&r.onBeforeXR(e,t);for(const r of this._sessionRequestStartListeners)r({mode:e,init:t});Ge&&Ee("Requesting "+e+" session ("+Date.now()+")"),this._currentSessionRequest=navigator?.xr?.requestSession(e,t),this._currentSessionRequestMode=e;const s=await this._currentSessionRequest?.catch(r=>{console.error(r,"Code: "+r.code),r.code===9&&fe("Make sure your device has the required permissions (e.g. camera access)"),console.log("If the specified XR configuration is not supported (e.g. entering AR doesnt work) - make sure you access the website on a secure connection (HTTPS) and your device has the required permissions (e.g. camera access)"),location.protocol==="http:"&&fe("XR requires a secure connection (HTTPS)")});this._currentSessionRequest=void 0,this._currentSessionRequestMode=null;for(const r of this._sessionRequestEndListeners)r({mode:e,init:t,newSession:s||null});return s?this.setSession(e,s,t,i):(console.warn("XR Session request was rejected"),null)}static setSession(e,t,i,n){if(this._activeSession)return console.error("A XRSession is already running"),this._activeSession;const s=e=="immersive-ar"?n.scripts_immersive_ar:n.scripts_immersive_vr;return this._activeSession=new Y(e,t,n,{scripts:s,controller_added:this._controllerAddedListeners,controller_removed:this._controllerRemovedListeners,init:i}),t.addEventListener("end",this.onEnd),Ge?console.log(`%cStarted ${e} session`,"font-weight:bold;",s):console.log(`%cStarted ${e} session`,"font-weight:bold;"),this._activeSession}static $_stop_request=Symbol();static stop(){const e=this._activeSession;e&&(e[this.$_stop_request]===void 0?(Ge&&console.log("[NeedleXRSession] Stopping XR Session... (new)"),e[this.$_stop_request]=setTimeout(()=>{e.end()})):Ge&&console.warn("[NeedleXRSession] XR Session stop already requested"))}static onEnd=()=>{Ge&&console.log("XR Session ended"),this._activeSession=null};context;get sync(){return Y._sync}get running(){return!this._ended&&this.session!=null}session;mode;get interactionMode(){return this.session.interactionMode}get visibilityState(){return this.session.visibilityState}get isVisibleBlurred(){return this.session.visibilityState==="visible-blurred"}get isSystemKeyboardSupported(){return this.session.isSystemKeyboardSupported}get environmentBlendMode(){return this.session.environmentBlendMode}get frame(){return this.context.xrFrame}controllers=[];get leftController(){return this.controllers.find(e=>e.side==="left")}get rightController(){return this.controllers.find(e=>e.side==="right")}getController(e){return typeof e=="number"?this.controllers[e]||null:this.controllers.find(t=>t.side===e)||null}get isPassThrough(){return!!(this.environmentBlendMode!=="opaque"&&this.interactionMode==="world-space"||this.mode==="immersive-ar"&&this.environmentBlendMode!=="opaque"&&this.controllers.some(e=>e.inputSource.targetRayMode==="tracked-pointer")||A()&&q.isDesktop()&&this.mode==="immersive-ar")}get isAR(){return this.mode==="immersive-ar"}get isVR(){return this.mode==="immersive-vr"}get isScreenBasedAR(){return this.isAR&&!this.isPassThrough}get posePosition(){return this._transformPosition}get poseOrientation(){return this._transformOrientation}get referenceSpace(){return this.context.renderer.xr.getReferenceSpace()}get viewerPose(){return this._viewerPose}get isTrackingImages(){if(this.frame&&"getImageTrackingResults"in this.frame&&typeof this.frame.getImageTrackingResults=="function")try{const e=this.frame.getImageTrackingResults();for(const t of e)if(t.trackingState==="tracked")return!0}catch{return!1}return!1}get rig(){const e=this._rigs[0]??null;return e?.gameObject&&Rr(e.gameObject)||e?.isActive===!1?(this.updateActiveXRRig(),this._rigs[0]??null):e}_rigScale=1;_lastRigScaleUpdate=-1;get rigScale(){return this._rigs[0]?(this._lastRigScaleUpdate!==this.context.time.frame&&(this._lastRigScaleUpdate=this.context.time.frame,this._rigScale=this._rigs[0].gameObject.worldScale.x),this._rigScale):1}addRig(e){this._rigs.indexOf(e)>=0||(e.priority===void 0&&(e.priority=0),this._rigs.push(e),this.updateActiveXRRig())}removeRig(e){const t=this._rigs.indexOf(e);t!==-1&&(this._rigs.splice(t,1),this.updateActiveXRRig())}setRigActive(e){const t=this._rigs.indexOf(e),i=this._rigs[0];this._rigs.splice(t,1),this._rigs.unshift(e),e.priority=i?.priority??0,this.updateActiveXRRig()}getUserOffsetInRig(){const e=this.context.mainCamera?.position;if(!e||!this.rig)return D(0,0,0);const t=D(e);return t.x*=-1,t.z*=-1,t.applyQuaternion(ni(this.rig.gameObject.quaternion)),t}updateActiveXRRig(){const e=this._rigs[0]??null;this._defaultRig.gameObject.parent!==this.context.scene&&this.context.scene.add(this._defaultRig.gameObject),this._defaultRig.gameObject.visible=!0,this._rigs.includes(this._defaultRig)||this._rigs.push(this._defaultRig);let t=this._rigs[0];t&&t.priority===void 0&&(t.priority=0);for(let i=1;i<this._rigs.length;i++){const n=this._rigs[i];if(n.isActive){if(Rr(n.gameObject)){this._rigs.splice(i,1),i--;continue}(!t||t.isActive===!1||n.priority!==void 0&&n.priority>t.priority)&&(t=n)}}if(e!==t){const i=this._rigs.indexOf(t);i>=0&&this._rigs.splice(i,1),this._rigs.unshift(t)}Ge&&(e===t?console.log("Updated Active XR Rig:",t,"prev:",e):console.log("Updated Active XRRig:",t," (the same as before)"))}_rigs=[];_viewerHitTestSource=null;getHitTest(e){if(e)return this.getControllerHitTest(e);if(!this._viewerHitTestSource)return null;const t=this._viewerHitTestSource,i=this.frame.getHitTestResults(t);if(i.length>0){const n=i[0];return this.convertHitTestResult(n)}return null}getControllerHitTest(e){const t=e.getHitTestSource();if(!t)return null;const i=this.frame.getHitTestResultsForTransientInput(t);for(const n of i)if(n.inputSource===e.inputSource)for(const s of n.results)return this.convertHitTestResult(s);return null}convertHitTestResult(e){const t=this.context.renderer.xr.getReferenceSpace(),i=t&&e.getPose(t);if(i){const n=D(i.transform.position),s=ni(i.transform.orientation),r=this.context.mainCamera;if(r?.parent!==this._cameraRenderParent&&n.applyMatrix4(La),r?.parent){n.applyMatrix4(r.parent.matrixWorld),s.multiply(Gi);const a=be(r.parent);a.premultiply(Gi),s.premultiply(a)}return{hit:e,position:n,quaternion:s}}return null}convertSpace(e){const t=D(e.position);t.applyMatrix4(La);const i=ni(e.orientation);return i.premultiply(Gi),{position:t,quaternion:i}}_defaultRig;_xr_scripts;_xr_update_scripts=[];_inactive_scripts=[];_controllerAdded;_controllerRemoved;_originalCameraWorldPosition;_originalCameraWorldRotation;_originalCameraWorldScale;_originalCameraParent;_mainCamera=null;constructor(e,t,i,n){ak(e,n.init),this.session=t,this.mode=e,this.context=i,(Ge||v("console"))&&fr(!0),this._xr_scripts=[...n.scripts],this._xr_update_scripts=this._xr_scripts.filter(s=>typeof s.onUpdateXR=="function"),this._controllerAdded=n.controller_added,this._controllerRemoved=n.controller_removed,Mo(this.onBefore,we.LateUpdate),this.context.pre_render_callbacks.push(this.onBeforeRender),this.context.post_render_callbacks.push(this.onAfterRender),(n.init.optionalFeatures?.includes("hit-test")||n.init.requiredFeatures?.includes("hit-test"))&&t.requestReferenceSpace("viewer").then(s=>t.requestHitTestSource?.call(t,{space:s})?.then(r=>this._viewerHitTestSource=r).catch(r=>console.error(r))).catch(s=>console.error(s)),this.context.mainCamera&&(this._originalCameraWorldPosition=K(this.context.mainCamera,new b),this._originalCameraWorldRotation=be(this.context.mainCamera,new N),this._originalCameraWorldScale=He(this.context.mainCamera,new b),this._originalCameraParent=this.context.mainCamera.parent,this.context.mainCamera instanceof re&&(this.context.mainCamera[Gd]=this.context.mainCamera.fov)),this._defaultRig=new $O,this.context.scene.add(this._defaultRig.gameObject),this.addRig(this._defaultRig);for(let s=0;s<t.inputSources.length;s++){const r=t.inputSources[s];if(!r.handedness){console.warn("Input source in xr session has no handedness - ignoring",s);continue}this.onInputSourceAdded(r)}this.session.addEventListener("end",this.onEnd),this.session.addEventListener("inputsourceschange",s=>{for(const r of s.removed)this.disconnectInputSource(r);for(const r of s.added)this.onInputSourceAdded(r)}),this.context.xr=this,this.context.renderer.xr.setSession(this.session).then(this.onRendererSessionSet),"controllerAutoUpdate"in this.context.renderer.xr?(console.debug("Disabling three.js controllerAutoUpdate"),this.context.renderer.xr.controllerAutoUpdate=!1):Ge&&console.warn("controllerAutoUpdate is not available in three.js - cannot disable it")}onRendererSessionSet=()=>{this.running&&(this.context.renderer.xr.enabled=!0,this.context.renderer.xr.updateCamera(this.context.mainCamera),this.context.mainCameraComponent?.applyClearFlags())};onInputSourceAdded=e=>{if(e.targetRayMode==="screen")return;let t=0;for(let n=0;n<this.session.inputSources.length;n++)if(this.session.inputSources[n]===e){t=n;break}if(this.controllers.find(n=>n.inputSource===e)){console.debug("Controller already exists for input source",t);return}else if(this._newControllers.find(n=>n.inputSource===e)){console.debug("Controller already registered for input source",t);return}const i=new cg(this,e,t);this._newControllers.push(i)};disconnectInputSource(e){const t=(s,r)=>{if(s.inputSource===e){Ge&&console.log("Disconnecting controller",s.index);const a=r.indexOf(s);a>=0&&r.splice(a,1),this.invokeControllerEvent(s,this._controllerRemoved,"removed");const l={xr:this,controller:s,change:"removed"};for(const c of this._xr_scripts)c.onXRControllerRemoved&&c.onXRControllerRemoved(l);s.onDisconnected()}},i=[...this.controllers];for(let s=i.length-1;s>=0;s--){const r=i[s];t(r,this.controllers)}const n=[...this._newControllers];for(let s=n.length-1;s>=0;s--){const r=n[s];t(r,this._newControllers)}}end(){this._ended||this.session.end().catch(e=>console.warn(e))}_ended=!1;_newControllers=[];onEnd=e=>{if(this._ended)return;this._ended=!0,console.debug("XR Session ended"),lk(),this.onAfterRender(),this.revertCustomForward(),this._didStart=!1,this._previousCameraParent=null,this.requestedCameraNearPlane=null,fs(this.onBefore,we.LateUpdate);const t=this.context.pre_render_callbacks.indexOf(this.onBeforeRender);t>=0&&this.context.pre_render_callbacks.splice(t,1);const i=this.context.post_render_callbacks.indexOf(this.onAfterRender);i>=0&&this.context.post_render_callbacks.splice(i,1),this.context.xr=null,this.context.renderer.xr.enabled=!1,this.context.pre_update_oneshot_callbacks.push(()=>{this.context.mainCameraComponent?.applyClearFlags(),this.context.mainCameraComponent?.applyClippingPlane()}),x_({session:this});for(const s of Y._xrEndListeners)s({xr:this});const n=[...this.controllers];for(let s=0;s<n.length;s++)this.disconnectInputSource(n[s].inputSource);this.controllers.length=0,this._newControllers.length=0;for(const s of this._xr_scripts)s?.onLeaveXR?.({xr:this});this.sync?.onExitXR(this),this.context.mainCamera&&(this._originalCameraParent?.add(this.context.mainCamera),this._originalCameraWorldPosition&&gt(this.context.mainCamera,this._originalCameraWorldPosition),this._originalCameraWorldRotation&&yn(this.context.mainCamera,this._originalCameraWorldRotation),this._originalCameraWorldScale&&Ta(this.context.mainCamera,this._originalCameraWorldScale),this.context.mainCamera instanceof re&&this.context.mainCamera[Gd]&&(this.context.mainCamera.fov=this.context.mainCamera[Gd],this.context.mainCamera[Gd]=0)),this.context.requestSizeUpdate(),this._defaultRig.gameObject.removeFromParent(),fr(!1)};_didStart=!1;onBefore=e=>{const t=e.xrFrame;if(!t)return;this.context.xr=this,this.context.mainCameraComponent&&this.context.mainCameraComponent!==this._mainCamera&&(this._mainCamera=this.context.mainCameraComponent),this.rig?.isActive==!1&&(Ge&&console.warn("Latest rig is not active - trying to activate a different rig",this.rig),this.updateActiveXRRig()),this.rig&&this._mainCamera?.gameObject&&this._mainCamera?.gameObject?.parent!==this.rig.gameObject&&this.rig.gameObject.add(this._mainCamera?.gameObject),this.internalUpdateState(),this.applyCustomForward();const i={xr:this};if(this._didStart){if(this.context.new_scripts_xr.length>0){const n=[...this.context.new_scripts_xr];for(let s=0;s<n.length;s++){const r=this.context.new_scripts_xr[s];if(!r||r.destroyed||r.supportsXR?.(this.mode)==!1){this.context.new_scripts_xr.splice(s,1);continue}if(!r.activeAndEnabled){this.context.new_scripts_xr.splice(s,1),this.markInactive(r);continue}if(this.addScript(r)){this.invokeCallback_EnterXR(r);for(const a of this.controllers)this.invokeCallback_ControllerAdded(r,a)}}}}else{if(this._didStart=!0,this.mode==="immersive-vr"){const s=Gt(this.context.scene.children);if(s){const r=s.getSize(D());if(r.length()>0){const a=this._defaultRig.gameObject;a.position.set(s.min.x+r.x*.5,s.min.y,s.max.z+r.z*.5+1.5);const l=s.getCenter(D());l.y=a.position.y,a.lookAt(l)}}}w_({session:this}),vr();for(const s of Y._xrStartListeners)s(i);const n=[...this._xr_scripts];Ge&&console.log("NeedleXRSession start, handle scripts:",n);for(const s of n){if(s.destroyed){this._script_to_remove.push(s);continue}if(!s.activeAndEnabled){this.markInactive(s);continue}this.invokeCallback_EnterXR(s);for(const r of this.controllers)this.invokeCallback_ControllerAdded(s,r)}}this.syncCameraCullingMask();for(const n of this.controllers)n.onUpdate(t);if(this._newControllers.length>0){const n=[...this._newControllers];this._newControllers.length=0;for(const s of n){if(!s.connected){console.warn("New controller is not connected",s);continue}this.controllers.push(s);for(const r of this._xr_scripts){if(r.destroyed){this._script_to_remove.push(r);continue}r.activeAndEnabled!==!1&&this.invokeCallback_ControllerAdded(r,s)}}this.controllers.sort((s,r)=>s.index-r.index)}Ge&&this.context.time.frame%30===0&&this.controllers.length<=0&&this.session.inputSources.length>0&&(fr(!0),console.error("XRControllers are not added but inputSources are present"));for(const n of this._xr_update_scripts){if(n.destroyed===!0){this._script_to_remove.push(n);continue}if(n.activeAndEnabled===!1){this.markInactive(n);continue}n.onUpdateXR&&n.onUpdateXR(i)}if(this.handleInactiveScripts(),this._script_to_remove.length>0){const n=[...new Set(this._script_to_remove)];this._script_to_remove.length=0;for(const s of n)!s.destroyed&&this.running&&s.onLeaveXR?.(i),this.removeScript(s)}this.sync?.onUpdate(this),this.onRenderDebug()};onRenderDebug(){if(Ge)for(const e of this.controllers)e.onRenderDebug();if((Ge||W_)&&this.rig&&(_g++,_g>=20)){const e=this.rig.gameObject.worldPosition,t=this.rig.gameObject.worldForward;e.add(t.multiplyScalar(1.5));const i=this.rig.gameObject.worldUp;e.add(i.multiplyScalar(2.5));let n="";if(n+=`${this.context.time.smoothedFps.toFixed(0)} FPS`,n+=`, calls: ${this.context.renderer.info.render.calls}, tris: ${this.context.renderer.info.render.triangles.toLocaleString()}`,Ge||W_)for(const s of this.controllers)n+=`
167
- ${s.hand?"hand":"ctrl"} ${s.inputSource.handedness}[${s.index}] con:${s.connected} tr:${s.isTracking} hts:${s.hasHitTestSource?"yes":"no"}`;_g=0,B.DrawLabel(e,n,void 0,1/60*20)}}onBeforeRender=()=>{this.context.mainCamera&&(this.updateFade(this.context.mainCamera),this.requestedCameraNearPlane!==null&&this.context.mainCamera instanceof re&&(this.context.mainCamera.near=this.requestedCameraNearPlane,this.requestedCameraNearPlane=null))};onAfterRender=()=>{if(this.onUpdateFade_PostRender(),q.isDesktop()||!this._renderOnceOnDevice){const e=this.context.renderer;if(e.xr.isPresenting&&this.context.mainCamera){this._renderOnceOnDevice=!0;const t=e.xr.enabled,i=e.getRenderTarget(),n=this.context.scene.background;e.xr.enabled=!1,e.setRenderTarget(null),this.isPassThrough&&(this.context.scene.background=null),this.context.composer?this.context.composer.render(this.context.time.deltaTime):e.render(this.context.scene,this.context.mainCamera),e.xr.enabled=t,e.setRenderTarget(i),this.context.scene.background=n}}};addScript(e){return this._xr_scripts.includes(e)?!1:(Ge&&console.log("Register new XRScript",e),this._xr_scripts.push(e),typeof e.onUpdateXR=="function"&&this._xr_update_scripts.push(e),!0)}markInactive(e){if(!(this._inactive_scripts.indexOf(e)>=0)){this.removeScript(e,!1),this._inactive_scripts.push(e);for(const t of this.controllers)this.invokeCallback_ControllerRemoved(e,t);this.invokeCallback_LeaveXR(e)}}handleInactiveScripts(){if(this._inactive_scripts.length>0)for(let e=this._inactive_scripts.length-1;e>=0;e--){const t=this._inactive_scripts[e];if(t.activeAndEnabled){this._inactive_scripts.splice(e,1),this.addScript(t),this.invokeCallback_EnterXR(t);for(const i of this.controllers)this.invokeCallback_ControllerAdded(t,i)}}}_script_to_remove=[];removeScript(e,t=!0){Ge&&console.log("Remove XRScript",e);const i=this._xr_scripts.indexOf(e);i>=0&&this._xr_scripts.splice(i,1);const n=this._xr_update_scripts.indexOf(e);if(n>=0&&this._xr_update_scripts.splice(n,1),t){const s=this._inactive_scripts.indexOf(e);s>=0&&this._inactive_scripts.splice(s,1)}}invokeCallback_EnterXR(e){e.onEnterXR&&e.onEnterXR({xr:this})}invokeCallback_ControllerAdded(e,t){e.onXRControllerAdded&&e.onXRControllerAdded({xr:this,controller:t,change:"added"})}invokeCallback_ControllerRemoved(e,t){e.onXRControllerRemoved&&e.onXRControllerRemoved({xr:this,controller:t,change:"removed"})}invokeCallback_LeaveXR(e){e.onLeaveXR&&!e.destroyed&&e.onLeaveXR({xr:this})}syncCameraCullingMask(){const e=this.context.xrCamera,t=this.context.mainCameraComponent?.cullingMask;if(e&&t!==void 0){for(const i of e.cameras)i.layers.mask=t;e.layers.mask=t}else if(e){for(const i of e.cameras)i.layers.enableAll();e.layers.enableAll()}}invokeControllerEvent(e,t,i){for(let n=t.length-1;n>=0;n--){const s=t[n];if(s)try{s({xr:this,controller:e,change:i})}catch(r){console.error(r)}}}_camera;_cameraRenderParent=new O().rotateY(Math.PI);_previousCameraParent;_customforward=!0;originalCameraNearPlane;requestedCameraNearPlane=null;applyCustomForward(){if(this.context.mainCamera&&this._customforward){this._camera=this.context.mainCamera,this._camera.parent!==this._cameraRenderParent&&(this._previousCameraParent=this._camera.parent,this._previousCameraParent?.add(this._cameraRenderParent)),this._cameraRenderParent.name="XR Camera Render Parent",this._cameraRenderParent.add(this._camera);{let e=.02;const t=.001;if(this.rig){const i=He(this.rig.gameObject);e*=i.x}this._camera instanceof re&&Math.abs(this._camera.near-e)>t&&(this.isAR?this.originalCameraNearPlane=this._camera.near:this._camera.near=e,Ge&&console.debug(`Setting camera near plane to ${e} (was ${this.originalCameraNearPlane}) to account for XR rendering scale`))}}}revertCustomForward(){this._camera&&this._previousCameraParent&&this._previousCameraParent.add(this._camera),this._previousCameraParent=null,this._camera instanceof re&&this.originalCameraNearPlane!=null&&(this._camera.near=this.originalCameraNearPlane,this.originalCameraNearPlane=void 0)}_viewerPose;_transformOrientation=new N;_transformPosition=new b;internalUpdateState(){const e=this.context.renderer.xr.getReferenceSpace();if(!e){this._viewerPose=void 0;return}if(this._viewerPose=this.frame.getViewerPose(e),this._viewerPose){const t=this._viewerPose.transform;this._transformPosition.set(t.position.x,t.position.y,t.position.z),this._transformOrientation.set(t.orientation.x,t.orientation.y,t.orientation.z,t.orientation.w)}}_transition;get transition(){return this._transition||(this._transition=new z_),this._transition}fadeTransition(){return this._transition||(this._transition=new z_),this._transition.fadeTransition()}updateFade(e){this._transition&&e instanceof re&&this._transition.update(e,this.context.time.deltaTime)}onUpdateFade_PostRender(){this._transition?.remove()}}const wg=v("debugwebxr");class H_{static tryFindAvatarObjects(e,t,i){if(i.head&&i.leftHand&&i.rightHand)return;const n=e.name.toLocaleLowerCase();!i.head&&n.includes("head")&&(wg&&console.log("FOUND AVATAR HEAD",e.name),i.head=new ie("",t,e)),n.includes("hand")&&(!i.leftHand&&n.includes("left")&&(wg&&console.log("FOUND AVATAR LEFT HAND",e.name),i.leftHand=new ie("",t,e)),!i.rightHand&&n.includes("right")&&(wg&&console.log("FOUND AVATAR RIGHT HAND",e.name),i.rightHand=new ie("",t,e)));for(let s=0;s<e.children.length;s++){if(i.head&&i.leftHand&&i.rightHand)return;const r=e.children[s];this.tryFindAvatarObjects(r,t,i)}}}class oe extends ne{alpha=1;get isRGBAColor(){return!0}set a(e){this.alpha=e}get a(){return this.alpha}constructor(e,t,i,n){super(),typeof e=="number"&&typeof t=="number"&&typeof i=="number"?(this.set(e,t,i),this.alpha=typeof n=="number"?n:1):e!==void 0&&(this.set(e),this.alpha=1)}clone(){const e=super.clone();return e.alpha=this.alpha,e}copy(e){return this.r=e.r,this.g=e.g,this.b=e.b,"alpha"in e&&typeof e.alpha=="number"?this.alpha=e.alpha:typeof e.a=="number"&&(this.alpha=e.a),this}lerp(e,t){const i=e;return i.alpha!=null&&(this.alpha=I.lerp(this.alpha,i.alpha,t)),super.lerp(e,t)}lerpColors(e,t,i){const n=e,s=t;return n.alpha!=null&&s.alpha!=null&&(this.alpha=I.lerp(n.alpha,s.alpha,i)),super.lerpColors(e,t,i)}multiply(e){const t=e;return t.alpha!=null&&(this.alpha=this.alpha*t.alpha),super.multiply(e)}fromArray(e,t=0){return this.alpha=e[t+3],super.fromArray(e,t)}static fromColorRepresentation(e){if(typeof e=="string"){if(e.trim()==="transparent")return new oe(0,0,0,0);if(e.startsWith("#")&&e.length===9){const t=parseInt(e.slice(1,9),16),i=t>>24&255,n=t>>16&255,s=t>>8&255,r=t>>0&255;return new oe(i/255,n/255,s/255,r/255)}else if(e.startsWith("#")){const t=parseInt(e.slice(1),16),i=t>>16&255,n=t>>8&255,s=t>>0&255;return new oe(i/255,n/255,s/255,1)}else if(e.startsWith("rgba")){const t=e.slice(5,-1).split(",").map(Number);return new oe(t[0]/255,t[1]/255,t[2]/255,t[3])}else if(e.startsWith("rgb")){const t=e.slice(4,-1).split(",").map(Number);return new oe(t[0]/255,t[1]/255,t[2]/255,1)}}else if(Array.isArray(e)){if(e.length===4)return new oe(e[0],e[1],e[2],e[3]);if(e.length===3)return new oe(e[0],e[1],e[2],1);console.error("Invalid color array length. Expected 3 or 4, got "+e.length)}return new oe(e)}}const Lt=new b,G_=new b,q_=new N,dk=v("debuggizmos"),wn=8947848,xg=32;class B{constructor(){}static enabled=!0;static isGizmo(e){return e[Cg]!==void 0}static setVisible(e){for(const t of Xi.timedObjectsBuffer)t.visible=e}static DrawLabel(e,t,i=.05,n=0,s,r,a){if(!B.enabled)return null;s||(s=wn);const l=Y.active?.rigScale??1,c=Xi.getTextLabel(n,t,i*l,s,r);return a instanceof O&&a.add(c),c.position.x=e.x,c.position.y=e.y,c.position.z=e.z,c}static DrawRay(e,t,i=wn,n=0,s=!0){if(!B.enabled)return;const r=Xi.getLine(n),a=r.geometry.getAttribute("position");a.setXYZ(0,e.x,e.y,e.z),Lt.set(t.x,t.y,t.z).multiplyScalar(999999999),a.setXYZ(1,e.x+Lt.x,e.y+Lt.y,e.z+Lt.z),a.needsUpdate=!0,r.material.depthTest=s,r.material.depthWrite=!1,r.material.fog=!1,xn(r.material,i)}static DrawDirection(e,t,i=wn,n=0,s=!0,r=1){if(!B.enabled)return;const a=Xi.getLine(n),l=a.geometry.getAttribute("position");l.setXYZ(0,e.x,e.y,e.z),t.w!==void 0?(Lt.set(0,0,-r),q_.set(t.x,t.y,t.z,t.w),Lt.applyQuaternion(q_)):(Lt.set(t.x,t.y,t.z),Lt.multiplyScalar(r)),l.setXYZ(1,e.x+Lt.x,e.y+Lt.y,e.z+Lt.z),l.needsUpdate=!0,a.material.depthTest=s,a.material.depthWrite=!1,xn(a.material,i)}static DrawLine(e,t,i=wn,n=0,s=!0){if(!B.enabled)return;const r=Xi.getLine(n),a=r.geometry.getAttribute("position");a.setXYZ(0,e.x,e.y,e.z),a.setXYZ(1,t.x,t.y,t.z),a.needsUpdate=!0,r.material.depthTest=s,r.material.depthWrite=!1,r.material.fog=!1,xn(r.material,i)}static DrawCircle(e,t,i,n=wn,s=0,r=!0){if(!B.enabled)return;const a=Xi.getCircle(s);a.position.set(e.x,e.y,e.z),a.scale.set(i,i,i),a.quaternion.setFromUnitVectors(this._up,Lt.set(t.x,t.y,t.z).normalize()),a.material.depthTest=r,a.material.depthWrite=!1,a.material.fog=!1,xn(a.material,n)}static DrawWireSphere(e,t,i=wn,n=0,s=!0){if(!B.enabled)return;const r=Xi.getSphere(t,n,!0);mr(r,e.x,e.y,e.z),r.material.depthTest=s,r.material.depthWrite=!1,r.material.fog=!1,xn(r.material,i)}static DrawSphere(e,t,i=wn,n=0,s=!0){if(!B.enabled)return;const r=Xi.getSphere(t,n,!1);mr(r,e.x,e.y,e.z),r.material.depthTest=s,r.material.depthWrite=!1,xn(r.material,i)}static DrawWireBox(e,t,i=wn,n=0,s=!0,r=void 0){if(!B.enabled)return;const a=Xi.getBox(n);a.position.set(e.x,e.y,e.z),a.scale.set(t.x,t.y,t.z),r?a.quaternion.copy(r):a.quaternion.identity(),a.material.depthTest=s,a.material.wireframe=!0,a.material.depthWrite=!1,a.material.fog=!1,xn(a.material,i)}static DrawWireBox3(e,t=wn,i=0,n=!0){if(!B.enabled)return;const s=Xi.getBox(i);s.position.copy(e.getCenter(Lt)),s.scale.copy(e.getSize(Lt)),s.material.depthTest=n,s.material.wireframe=!0,s.material.depthWrite=!1,s.material.fog=!1,xn(s.material,t)}static _up=new b(0,1,0);static DrawArrow(e,t,i=wn,n=0,s=!0,r=!1){if(!B.enabled)return;const a=Xi.getArrowHead(n);a.position.set(t.x,t.y,t.z),a.quaternion.setFromUnitVectors(this._up.set(0,1,0),Lt.set(t.x,t.y,t.z).sub(G_.set(e.x,e.y,e.z)).normalize());const l=Lt.set(t.x,t.y,t.z).sub(G_.set(e.x,e.y,e.z)).length()*.1;a.scale.set(l,l,l),a.material.depthTest=s,a.material.wireframe=r,xn(a.material,i),this.DrawLine(e,t,i,n,s)}static DrawWireMesh(e){const t=Xi.getMesh(e.duration??0);"mesh"in e?(t.geometry=e.mesh.geometry,t.matrixWorld.copy(e.mesh.matrixWorld)):(t.geometry=e.geometry,t.matrixWorld.copy(e.matrix)),t.matrixAutoUpdate=!1,t.matrixWorldAutoUpdate=!1,t.material.depthTest=e.depthTest??!0,t.material.wireframe=!0,xn(t.material,e.color??wn)}}const uk=new Sa(1,1,1);function Sg(o=null){const e=new ne(o??14540253),t=new SS(uk);return new eb(t,new pm({color:e}))}function xn(o,e){if(Array.isArray(o)){for(const i of o)xn(i,e);return}const t=e instanceof oe?e.a:1;o.color.set(e),o.opacity=t,o.transparent=t<1}const Cg=Symbol("GizmoCache");class Xi{static familyName="needle-gizmos";static ensureFont(){let e=Ce.FontLibrary.getFontFamily(this.familyName);e||(e=Ce.FontLibrary.addFontFamily(this.familyName),e.addVariant("normal","normal","https://uploads.needle.tools/include/font-msdf.json","https://uploads.needle.tools/include/font.png")?.addEventListener("ready",()=>{Ce.update()}))}static getTextLabel(e,t,i,n,s){this.ensureFont();let r=this.textLabelCache.pop(),a=1;s&&typeof s=="string"&&s?.length>=8&&s.startsWith("#")?(a=parseInt(s.substring(7),16)/255,s=s.substring(0,7),dk&&console.log(s,a)):typeof s=="object"&&s.a!==void 0&&(a=s.a);const l={boxSizing:"border-box",fontFamily:this.familyName,width:"auto",fontSize:i,color:n,lineHeight:1,backgroundColor:s??void 0,backgroundOpacity:a,textContent:t,borderRadius:.5*i,padding:.8*i,whiteSpace:"pre",offset:.05*i};if(r)r.set(l);else{r=new Cb(l);const c=this,h=r;h.setText=function(d){this.set({textContent:d}),c.tmuiNeedsUpdate=!0}}return this.tmuiNeedsUpdate=!0,this.registerTimedObject(V.Current,r,e,this.textLabelCache),r}static getBox(e){let t=this.boxesCache.pop();if(!t){const i=new Sa(1,1,1);t=new G(i)}return this.registerTimedObject(V.Current,t,e,this.boxesCache),t}static getLine(e){let t=this.linesCache.pop();if(!t){t=new Ca;let i=t.geometry.getAttribute("position");i||(i=new mt(new Float32Array(6),3),t.geometry.setAttribute("position",i))}return t.frustumCulled=!1,this.registerTimedObject(V.Current,t,e,this.linesCache),t}static getCircle(e){let t=this.circlesCache.pop();if(!t){t=new Ca;let i=t.geometry.getAttribute("position");if(!i){i=new mt(new Float32Array(xg*3),3),t.geometry.setAttribute("position",i);const n=D(0,1,0),s=D(0,0,1),r=D(s);r.cross(n).normalize();const a=D(r),l=Math.PI*2/(xg-1);for(let c=0;c<xg+1;c++){const h=l*c;n.copy(a).multiplyScalar(Math.cos(h)*1),r.copy(s).multiplyScalar(Math.sin(h)*1);const d=n.add(r);i.setXYZ(c,d.x,d.y,d.z)}}}return t.frustumCulled=!1,this.registerTimedObject(V.Current,t,e,this.circlesCache),t}static getSphere(e,t,i){let n=this.spheresCache.pop();return n||(n=new G(new gd(1,8,8))),n.scale.set(e,e,e),n.material.wireframe=i,this.registerTimedObject(V.Current,n,t,this.spheresCache),n}static getArrowHead(e){let t=this.arrowHeadsCache.pop();return t||(t=new G(new K0(0,.5,1,8))),this.registerTimedObject(V.Current,t,e,this.arrowHeadsCache),t}static getMesh(e){let t=this.mesh.pop();return t||(t=new G,t.material=new xe),this.registerTimedObject(V.Current,t,e,this.mesh),t}static linesCache=[];static circlesCache=[];static spheresCache=[];static boxesCache=[];static arrowHeadsCache=[];static mesh=[];static textLabelCache=[];static registerTimedObject(e,t,i,n){if(!e){console.error("No Needle Engine context available. Did you call a Gizmos function in global scope?");return}const s=this.contextBeforeRenderCallbacks.get(e),r=this.contextPostRenderCallbacks.get(e);if(s){if(e.pre_render_callbacks[e.pre_render_callbacks.length-1]!==s){const a=e.pre_render_callbacks.indexOf(s);a>=0&&e.pre_render_callbacks.splice(a,1),e.pre_render_callbacks.push(s)}}else{const a=()=>{this.onBeforeRender(e,this.timedObjectsBuffer)};this.contextBeforeRenderCallbacks.set(e,a),e.pre_render_callbacks.push(a)}if(r){if(e.post_render_callbacks[e.post_render_callbacks.length-1]!==r){const a=e.post_render_callbacks.indexOf(r);a>=0&&e.post_render_callbacks.splice(a,1),e.post_render_callbacks.push(r)}}else{const a=()=>{this.onPostRender(e,this.timedObjectsBuffer,this.timesBuffer)};this.contextPostRenderCallbacks.set(e,a),e.post_render_callbacks.push(a)}t.traverse(a=>{a.layers.disableAll(),a.layers.enable(2)}),t.renderOrder=999999,t[Cg]=n,t.castShadow=!1,t.receiveShadow=!1,t.isGizmo=!0,this.timedObjectsBuffer.push(t),this.timesBuffer.push(V.Current.time.realtimeSinceStartup+i),e.scene.add(t)}static timedObjectsBuffer=new Array;static timesBuffer=new Array;static contextPostRenderCallbacks=new Map;static contextBeforeRenderCallbacks=new Map;static tmuiNeedsUpdate=!1;static onBeforeRender(e,t){this.tmuiNeedsUpdate&&(this.tmuiNeedsUpdate=!1,Ce.update());for(let i=0;i<t.length;i++){const n=t[i];if(e.mainCamera&&n instanceof Ce.MeshUIBaseElement){if(Rr(n))continue;const s=e.isInVR,r=!1,a=!s;tc(n,e.mainCamera,r,a)}}}static onPostRender(e,t,i){const n=e.time.realtimeSinceStartup;for(let s=t.length-1;s>=0;s--){const r=t[s];n>=i[s]-1e-6&&(t.splice(s,1),i.splice(s,1),r.removeFromParent(),Rr(r)!=!0&&r[Cg].push(r))}}}const qt=v("debugphysics"),X_=new hs;class ys{static AllLayers=4294967295;ray;cam;screenPoint;raycaster;results;targets;recursive=!0;minDistance;maxDistance;lineThreshold;layerMask;ignore;testObject;useAcceleratedRaycast;allowSlowRaycastFallback=!0;screenPointFromOffset(e,t){this.screenPoint===void 0&&(this.screenPoint=new J),this.screenPoint.x=e/window.innerWidth*2-1,this.screenPoint.y=-(t/window.innerHeight)*2+1}setLayer(e){X_.set(e),this.layerMask=X_}setMask(e){this.layerMask||(this.layerMask=new hs);const t=this.layerMask;t?t.mask=e:this.layerMask=e}}class Pg{distance;point;object;constructor(e,t,i){this.object=e,this.distance=t,this.point=i}}class Vl{static _raycasting=0;static get raycasting(){return this._raycasting>0}raycastPhysicsFast(e,t=void 0,i=1/0,n=!0){return this.context.physics.engine?.raycast(e,t,{maxDistance:i,solid:n})??null}raycastPhysicsFastAndGetNormal(e,t=void 0,i=1/0,n=!0){return this.context.physics.engine?.raycastAndGetNormal(e,t,{maxDistance:i,solid:n})??null}sphereOverlapPhysics(e,t){return this.context.physics.engine?.sphereOverlap(e,t)??null}context;engine;constructor(e){this.context=e}raycaster=new fd;defaultRaycastOptions=new ys;targetBuffer=new Array(1);defaultThresholds={Mesh:{},Line:{threshold:-1},LOD:{},Points:{threshold:0},Sprite:{}};sphereResults=new Array;sphereMask=new hs;sphere=new yd;sphereOverlap(e,t,i=!0,n=!1,s=null){if(this.sphereResults.length=0,!this.context.scene)return this.sphereResults;const r=this.sphereMask;r.enableAll(),r.disable(2);for(const a of this.context.scene.children)this.intersectSphere(a,e,t,r,this.sphereResults,i,n,s);return this.sphereResults.sort((a,l)=>a.distance-l.distance)}raycastFromRay(e,t=null){const i=t??this.defaultRaycastOptions;i.ray=e;const n=this.raycast(i);return i===this.defaultRaycastOptions&&(i.ray=void 0),n}raycast(e=null){qt&&performance.mark("raycast.start"),e||(e=this.defaultRaycastOptions);const t=e.screenPoint??this.context.input.mousePositionRC,i=e.raycaster??this.raycaster;if(i.near=e.minDistance??0,i.far=e.maxDistance??1/0,i.params=this.defaultThresholds,e.lineThreshold===void 0&&(e.lineThreshold=-1),i.params.Line={threshold:e.lineThreshold},e.ray)i.ray.copy(e.ray);else{const a=e.cam??this.context.mainCamera;if(!a)return qt&&console.error("Can not perform raycast - no main camera found"),this.defaultRaycastOptions.results&&(this.defaultRaycastOptions.results.length=0),this.defaultRaycastOptions.results??[];const l=this.context.xrCamera;this.context.isInXR&&l instanceof CS&&l.cameras.length>0?i.setFromCamera(t,l.cameras[0]):i.setFromCamera(t,a)}let n=e.targets;n||(n=this.targetBuffer,n.length=1,n[0]=this.context.scene);let s=e.results;this.defaultRaycastOptions.results&&(this.defaultRaycastOptions.results.length=0),s||(this.defaultRaycastOptions.results||(this.defaultRaycastOptions.results=new Array),s=this.defaultRaycastOptions.results),e.layerMask!==void 0?e.layerMask instanceof hs?i.layers.mask=e.layerMask.mask:i.layers.mask=e.layerMask:(i.layers.enableAll(),i.layers.disable(2)),qt&&console.time("raycast"),s.length=0,Vl._raycasting++,this.intersect(this.raycaster,n,s,e),s.sort((a,l)=>a.distance-l.distance);const r=e.ignore;return r!==void 0&&r.length>0&&(s=s.filter(a=>!r.includes(a.object))),Vl._raycasting--,qt&&(console.timeEnd("raycast"),console.warn("#"+this.context.time.frame+", hits:",s?.length?[...s]:"nothing"),performance.mark("raycast.end"),performance.measure("raycast","raycast.start","raycast.end")),s}intersect(e,t,i,n){for(const s of t){if(!s||s.visible===!1||B.isGizmo(s)||n.lineThreshold!==void 0&&n.lineThreshold<0&&s instanceof Ca)continue;let r=!0;const a=s,l=a.geometry;if(s.raycastAllowed===!1&&(r=!1),r&&n.testObject){const c=n.testObject?.(s);if(c===!1)continue;c==="continue in children"&&(r=!1)}else r&&(l&&Q_(l)||(r=!1));if(r){const c=i.length,h=s.raycastPreference||"lod";let d=h!=="bounds";if(n.precise===!1&&(d=!1),d||=l.getAttribute("position")?.array?.length<64,a instanceof ka&&(d=!1),h==="lod"){const p=db(s);p&&(a.geometry=p)}if(!d&&mk(a,e,i)||(n.useAcceleratedRaycast!==!1?Xd.runMeshBVHRaycast(e,a,i,this.context,n):e.intersectObject(a,!1,i)),a.geometry=l,qt&&i.length!=c){const p=i[i.length-1];B.DrawWireSphere(p.point,.1,7798784,1,!1),B.DrawWireMesh({mesh:s,depthTest:!1,duration:.2,color:7798784})}}n.recursive!==!1&&this.intersect(e,s.children,i,n)}return i}tempBoundingBox=new wi;intersectSphere(e,t,i,n,s,r,a,l){let c=e&&e.isMesh&&e.layers.test(n)&&!B.isGizmo(e);c&&=e.visible,c&&=!(e instanceof Ca),c&&=!(e instanceof ka);const h=e,d=h.geometry;if(c&&l){const p=l(e);if(p===!1)return;p==="continue in children"&&(c=!1)}if(d&&Q_(d)||(c=!1),c){if(a){const p=this.sphere;p.center.copy(t),p.radius=i;const m=s.length;if(Xd.runMeshBVHRaycast(this.sphere,h,s,this.context,{}),m!=s.length&&!r)return}else if(d.boundingBox||d.computeBoundingBox(),d.boundingBox){h.matrixWorldNeedsUpdate&&h.updateWorldMatrix(!1,!1);const p=this.tempBoundingBox.copy(d.boundingBox).applyMatrix4(h.matrixWorld),m=this.sphere;if(m.center.copy(t),m.radius=i,m.intersectsBox(p)){const f=K(e),g=f.distanceTo(m.center),y=new Pg(e,g,f);if(s.push(y),!r)return}}}if(e.children)for(const p of e.children){const m=s.length;if(this.intersectSphere(p,t,i,n,s,r,a,l),m!=s.length&&!r)return}}}function Q_(o){return!(o.index&&o.index.array.length<3)}const Sr=new yd,qd=new hr,pk=new Z0;function mk(o,e,t){const i=o._computeIntersections;if(!i)return!1;let n=o["_computeIntersections:Needle"];return n||(n=o["_computeIntersections:Needle"]=function(s,r,a){const l=this,c=l.geometry.boundingSphere;if(c){if(l instanceof ka){qd.setFromNormalAndCoplanarPoint(D(0,1,0),D(0,-l.position.y,0)),qd.applyMatrix4(l.matrixWorld,pk);const d=s.ray.intersectPlane(qd,D());if(d){Sr.copy(c),Sr.applyMatrix4(l.matrixWorld);const p=D(d).sub(s.ray.origin).length(),m=Sr.radius*.5;p<m&&r.push({distance:p,point:d,object:l,normal:qd.normal.clone()})}return}Sr.copy(c),Sr.applyMatrix4(l.matrixWorld);const h=s.ray.intersectSphere(Sr,D());if(h){const d=D(h).sub(s.ray.origin),p=d.length();if(p>Sr.radius){const m=d.clone().normalize();r.push({distance:p,point:h,object:l,normal:m})}}}}),o._computeIntersections=n,e.intersectObject(o,!1,t),o._computeIntersections=i,!0}var Xd;(o=>{let e=0;function t(w,P,M,k,F){if(!P.geometry||!P.geometry.hasAttribute("position"))return!1;const L=P.geometry;if(P?.isSkinnedMesh){const z=P,j=z.bvhNeedsUpdate;if(!z.staticGenerator)l(),r&&(z.staticGenerator=new r(P),z.staticGenerator.applyWorldTransforms=!1,z.staticGeometry=z.staticGenerator.generate(),L.boundsTree=a?.call(z.staticGeometry),z.staticGeometryLastUpdate=performance.now()+Math.random()*200,z.bvhNeedsUpdate=!0);else if(L.boundsTree&&(z.autoUpdateMeshBvhInterval!==void 0&&z.autoUpdateMeshBvhInterval>=0||j===!0)){const $=performance.now(),ee=$-z.staticGeometryLastUpdate,E=z.autoUpdateMeshBvhInterval??100;(j||ee>E)&&(qt&&console.warn(`Physics: updating skinned mesh bvh for ${P.name} after ${ee.toFixed(2)}ms`),z.bvhNeedsUpdate=!1,z.staticGeometryLastUpdate=$,z.staticGenerator?.generate(z.staticGeometry),L.boundsTree.refit())}}else if(!L.boundsTree){h||_();let z=!0;if((k.xr||L[f]===!1||L.getAttribute("position")?.isInterleavedBufferAttribute||L.index&&L.index?.isInterleavedBufferAttribute||e>10)&&(z=!1),z&&p){if(L[m]===void 0){let j=null;if(y.length>0){const $=y.shift();$&&!$.running&&(j=$)}if(!j&&g.length<3)try{j=new p,g.push(j)}catch($){$ instanceof DOMException&&$.name==="SecurityError"?(console.warn("Failed to create MeshBVH worker, falling back to main thread generation. This can happen when running from file://, if the browser does not support workers or if the browser is blocking workers for other reasons."),console.debug($),e+=10):(console.error("Failed to create MeshBVH worker"),console.debug($)),e++}if(j!=null&&!j.running){const $=P.name;qt&&console.log("<<<< worker start",$,j),L[m]="queued",performance.mark("bvh.create.start");const ee=L.clone();try{j.generate(ee).then(E=>{L[m]="done",L.boundsTree=E}).catch(E=>{L[m]="failed - "+E?.message,L[f]=!1,qt&&console.error("Failed to generate mesh bvh on worker",E)}).finally(()=>{qt&&console.log(">>>>> worker done",$,{hasBoundsTre:L.boundsTree!=null}),y.push(j),ee.dispose(),performance.mark("bvh.create.end"),performance.measure("bvh.create (worker)","bvh.create.start","bvh.create.end")})}catch(E){console.error("Failed to generate mesh bvh on worker",E)}}else qt&&console.warn("No worker available")}}else(!d||!z)&&(l(),s&&(performance.mark("bvh.create.start"),L.boundsTree=new s(L),performance.mark("bvh.create.end"),performance.measure("bvh.create","bvh.create.start","bvh.create.end")))}if(w instanceof fd){const z=w,j=P.raycast;if(L.boundsTree)l(),n&&(P.acceleratedRaycast||(P.acceleratedRaycast=n.bind(P),qt&&console.debug(`Physics: bind acceleratedRaycast fn to "${P.name}"`)),P.raycast=P.acceleratedRaycast);else if(qt&&console.warn("No bounds tree found for mesh",P.name,{workerTask:L[m],hasAcceleratedRaycast:n!=null}),F.allowSlowRaycastFallback===!1&&(L.getAttribute("position")?.array?.length??0)>2e3)return qt&&console.warn("Skipping raycast because no bounds tree is available and allowSlowRaycastFallback is false"),!1;const $=z.firstHitOnly;return z.firstHitOnly=!1,z.intersectObject(P,!1,M),z.firstHitOnly=$,P.raycast=j,!0}else if(w instanceof yd){const z=L.boundsTree;if(z){const j=w;if(c.copy(P.matrixWorld).invert(),j.applyMatrix4(c),z.intersectsSphere(j)){const $=K(P),ee=$.distanceTo(j.center),E=new Pg(P,ee,$);M.push(E)}}return!0}return!1}o.runMeshBVHRaycast=t;let i=!1,n=null,s=null,r=null,a=null;function l(){i||(i=!0,import("./vendor-DWGd3dEf.min.js").then(w=>w.index$1).then(w=>{n=w.acceleratedRaycast,s=w.MeshBVH,r=w.StaticGeometryGenerator,a=w.computeBoundsTree}).catch(w=>{(qt||A())&&console.error("Failed to load BVH library...",w.message)}))}const c=new Z;let h=!1,d=!1,p=null;const m=Symbol("Needle:MeshBVH-Worker"),f=Symbol("Needle:MeshBVH-CanUseWorker"),g=[],y=[];function _(){h=!0,d=!0,Promise.resolve().then(()=>cL).then(w=>{p=w.GenerateMeshBVHWorker}).catch(w=>{qt||A()?console.warn("Failed to setup mesh bvh worker"):console.debug("Failed to setup mesh bvh worker",w)}).finally(()=>{d=!1})}})(Xd||(Xd={}));const Y_=Symbol("gltf-loader-internal-usage-tracker"),gk=v("debugusers");class Wl{get name(){return"NEEDLE_internal_usage_tracker"}static isLoading(e){return Wl._loadingProcesses>0}static _loadingProcesses=0;parser;_getDependency;_loadingId;_loadedObjects=new Set;constructor(e){this.parser=e,this._getDependency=this.parser.getDependency,this._loadingId=Date.now().toString()}beforeRoot(){Wl._loadingProcesses++;const e=this,t=this._getDependency;return this.parser.getDependency=function(i,n){const s=t.call(this,i,n);return s.then(r=>(r&&(e._loadedObjects.add(r),r[Y_]=e._loadingId),r)),s},null}afterRoot(e){Wl._loadingProcesses--,this.parser.getDependency=this._getDependency;for(const t of this._loadedObjects)delete t[Y_],t instanceof O&&(t.parent||t instanceof G&&setTimeout(()=>{gk&&console.warn("> GLTF LOADER: Mesh not used in scene!",t),t.material=null,t.geometry=null},1e3));return null}}class Z_{constructor(){window.addEventListener("unhandledrejection",e=>{if(e.defaultPrevented)return;const t=e?.reason?.path;if(t){const i=t[0];i&&i.tagName==="IMG"&&(console.warn(`Could not load image:
167
+ ${s.hand?"hand":"ctrl"} ${s.inputSource.handedness}[${s.index}] con:${s.connected} tr:${s.isTracking} hts:${s.hasHitTestSource?"yes":"no"}`;_g=0,B.DrawLabel(e,n,void 0,1/60*20)}}onBeforeRender=()=>{this.context.mainCamera&&(this.updateFade(this.context.mainCamera),this.requestedCameraNearPlane!==null&&this.context.mainCamera instanceof re&&(this.context.mainCamera.near=this.requestedCameraNearPlane,this.requestedCameraNearPlane=null))};onAfterRender=()=>{if(this.onUpdateFade_PostRender(),q.isDesktop()||!this._renderOnceOnDevice){const e=this.context.renderer;if(e.xr.isPresenting&&this.context.mainCamera){this._renderOnceOnDevice=!0;const t=e.xr.enabled,i=e.getRenderTarget(),n=this.context.scene.background;e.xr.enabled=!1,e.setRenderTarget(null),this.isPassThrough&&(this.context.scene.background=null),this.context.composer?this.context.composer.render(this.context.time.deltaTime):e.render(this.context.scene,this.context.mainCamera),e.xr.enabled=t,e.setRenderTarget(i),this.context.scene.background=n}}};addScript(e){return this._xr_scripts.includes(e)?!1:(Ge&&console.log("Register new XRScript",e),this._xr_scripts.push(e),typeof e.onUpdateXR=="function"&&this._xr_update_scripts.push(e),!0)}markInactive(e){if(!(this._inactive_scripts.indexOf(e)>=0)){this.removeScript(e,!1),this._inactive_scripts.push(e);for(const t of this.controllers)this.invokeCallback_ControllerRemoved(e,t);this.invokeCallback_LeaveXR(e)}}handleInactiveScripts(){if(this._inactive_scripts.length>0)for(let e=this._inactive_scripts.length-1;e>=0;e--){const t=this._inactive_scripts[e];if(t.activeAndEnabled){this._inactive_scripts.splice(e,1),this.addScript(t),this.invokeCallback_EnterXR(t);for(const i of this.controllers)this.invokeCallback_ControllerAdded(t,i)}}}_script_to_remove=[];removeScript(e,t=!0){Ge&&console.log("Remove XRScript",e);const i=this._xr_scripts.indexOf(e);i>=0&&this._xr_scripts.splice(i,1);const n=this._xr_update_scripts.indexOf(e);if(n>=0&&this._xr_update_scripts.splice(n,1),t){const s=this._inactive_scripts.indexOf(e);s>=0&&this._inactive_scripts.splice(s,1)}}invokeCallback_EnterXR(e){e.onEnterXR&&e.onEnterXR({xr:this})}invokeCallback_ControllerAdded(e,t){e.onXRControllerAdded&&e.onXRControllerAdded({xr:this,controller:t,change:"added"})}invokeCallback_ControllerRemoved(e,t){e.onXRControllerRemoved&&e.onXRControllerRemoved({xr:this,controller:t,change:"removed"})}invokeCallback_LeaveXR(e){e.onLeaveXR&&!e.destroyed&&e.onLeaveXR({xr:this})}syncCameraCullingMask(){const e=this.context.xrCamera,t=this.context.mainCameraComponent?.cullingMask;if(e&&t!==void 0){for(const i of e.cameras)i.layers.mask=t;e.layers.mask=t}else if(e){for(const i of e.cameras)i.layers.enableAll();e.layers.enableAll()}}invokeControllerEvent(e,t,i){for(let n=t.length-1;n>=0;n--){const s=t[n];if(s)try{s({xr:this,controller:e,change:i})}catch(r){console.error(r)}}}_camera;_cameraRenderParent=new O().rotateY(Math.PI);_previousCameraParent;_customforward=!0;originalCameraNearPlane;requestedCameraNearPlane=null;applyCustomForward(){if(this.context.mainCamera&&this._customforward){this._camera=this.context.mainCamera,this._camera.parent!==this._cameraRenderParent&&(this._previousCameraParent=this._camera.parent,this._previousCameraParent?.add(this._cameraRenderParent)),this._cameraRenderParent.name="XR Camera Render Parent",this._cameraRenderParent.add(this._camera);{let e=.02;const t=.001;if(this.rig){const i=He(this.rig.gameObject);e*=i.x}this._camera instanceof re&&Math.abs(this._camera.near-e)>t&&(this.isAR?this.originalCameraNearPlane=this._camera.near:this._camera.near=e,Ge&&console.debug(`Setting camera near plane to ${e} (was ${this.originalCameraNearPlane}) to account for XR rendering scale`))}}}revertCustomForward(){this._camera&&this._previousCameraParent&&this._previousCameraParent.add(this._camera),this._previousCameraParent=null,this._camera instanceof re&&this.originalCameraNearPlane!=null&&(this._camera.near=this.originalCameraNearPlane,this.originalCameraNearPlane=void 0)}_viewerPose;_transformOrientation=new N;_transformPosition=new b;internalUpdateState(){const e=this.context.renderer.xr.getReferenceSpace();if(!e){this._viewerPose=void 0;return}if(this._viewerPose=this.frame.getViewerPose(e),this._viewerPose){const t=this._viewerPose.transform;this._transformPosition.set(t.position.x,t.position.y,t.position.z),this._transformOrientation.set(t.orientation.x,t.orientation.y,t.orientation.z,t.orientation.w)}}_transition;get transition(){return this._transition||(this._transition=new z_),this._transition}fadeTransition(){return this._transition||(this._transition=new z_),this._transition.fadeTransition()}updateFade(e){this._transition&&e instanceof re&&this._transition.update(e,this.context.time.deltaTime)}onUpdateFade_PostRender(){this._transition?.remove()}}const wg=v("debugwebxr");class H_{static tryFindAvatarObjects(e,t,i){if(i.head&&i.leftHand&&i.rightHand)return;const n=e.name.toLocaleLowerCase();!i.head&&n.includes("head")&&(wg&&console.log("FOUND AVATAR HEAD",e.name),i.head=new ie("",t,e)),n.includes("hand")&&(!i.leftHand&&n.includes("left")&&(wg&&console.log("FOUND AVATAR LEFT HAND",e.name),i.leftHand=new ie("",t,e)),!i.rightHand&&n.includes("right")&&(wg&&console.log("FOUND AVATAR RIGHT HAND",e.name),i.rightHand=new ie("",t,e)));for(let s=0;s<e.children.length;s++){if(i.head&&i.leftHand&&i.rightHand)return;const r=e.children[s];this.tryFindAvatarObjects(r,t,i)}}}class oe extends ne{alpha=1;get isRGBAColor(){return!0}set a(e){this.alpha=e}get a(){return this.alpha}constructor(e,t,i,n){super(),typeof e=="number"&&typeof t=="number"&&typeof i=="number"?(this.set(e,t,i),this.alpha=typeof n=="number"?n:1):e!==void 0&&(this.set(e),this.alpha=1)}clone(){const e=super.clone();return e.alpha=this.alpha,e}copy(e){return this.r=e.r,this.g=e.g,this.b=e.b,"alpha"in e&&typeof e.alpha=="number"?this.alpha=e.alpha:typeof e.a=="number"&&(this.alpha=e.a),this}lerp(e,t){const i=e;return i.alpha!=null&&(this.alpha=I.lerp(this.alpha,i.alpha,t)),super.lerp(e,t)}lerpColors(e,t,i){const n=e,s=t;return n.alpha!=null&&s.alpha!=null&&(this.alpha=I.lerp(n.alpha,s.alpha,i)),super.lerpColors(e,t,i)}multiply(e){const t=e;return t.alpha!=null&&(this.alpha=this.alpha*t.alpha),super.multiply(e)}fromArray(e,t=0){return this.alpha=e[t+3],super.fromArray(e,t)}static fromColorRepresentation(e){if(typeof e=="string"){if(e.trim()==="transparent")return new oe(0,0,0,0);if(e.startsWith("#")&&e.length===9){const t=parseInt(e.slice(1,9),16),i=t>>24&255,n=t>>16&255,s=t>>8&255,r=t>>0&255;return new oe(i/255,n/255,s/255,r/255)}else if(e.startsWith("#")){const t=parseInt(e.slice(1),16),i=t>>16&255,n=t>>8&255,s=t>>0&255;return new oe(i/255,n/255,s/255,1)}else if(e.startsWith("rgba")){const t=e.slice(5,-1).split(",").map(Number);return new oe(t[0]/255,t[1]/255,t[2]/255,t[3])}else if(e.startsWith("rgb")){const t=e.slice(4,-1).split(",").map(Number);return new oe(t[0]/255,t[1]/255,t[2]/255,1)}}else if(Array.isArray(e)){if(e.length===4)return new oe(e[0],e[1],e[2],e[3]);if(e.length===3)return new oe(e[0],e[1],e[2],1);console.error("Invalid color array length. Expected 3 or 4, got "+e.length)}return new oe(e)}}const Lt=new b,G_=new b,q_=new N,dk=v("debuggizmos"),wn=8947848,xg=32;class B{constructor(){}static enabled=!0;static isGizmo(e){return e[Cg]!==void 0}static setVisible(e){for(const t of Xi.timedObjectsBuffer)t.visible=e}static DrawLabel(e,t,i=.05,n=0,s,r,a){if(!B.enabled)return null;s||(s=wn);const l=Y.active?.rigScale??1,c=Xi.getTextLabel(n,t,i*l,s,r);return a instanceof O&&a.add(c),c.position.x=e.x,c.position.y=e.y,c.position.z=e.z,c}static DrawRay(e,t,i=wn,n=0,s=!0){if(!B.enabled)return;const r=Xi.getLine(n),a=r.geometry.getAttribute("position");a.setXYZ(0,e.x,e.y,e.z),Lt.set(t.x,t.y,t.z).multiplyScalar(999999999),a.setXYZ(1,e.x+Lt.x,e.y+Lt.y,e.z+Lt.z),a.needsUpdate=!0,r.material.depthTest=s,r.material.depthWrite=!1,r.material.fog=!1,xn(r.material,i)}static DrawDirection(e,t,i=wn,n=0,s=!0,r=1){if(!B.enabled)return;const a=Xi.getLine(n),l=a.geometry.getAttribute("position");l.setXYZ(0,e.x,e.y,e.z),t.w!==void 0?(Lt.set(0,0,-r),q_.set(t.x,t.y,t.z,t.w),Lt.applyQuaternion(q_)):(Lt.set(t.x,t.y,t.z),Lt.multiplyScalar(r)),l.setXYZ(1,e.x+Lt.x,e.y+Lt.y,e.z+Lt.z),l.needsUpdate=!0,a.material.depthTest=s,a.material.depthWrite=!1,xn(a.material,i)}static DrawLine(e,t,i=wn,n=0,s=!0){if(!B.enabled)return;const r=Xi.getLine(n),a=r.geometry.getAttribute("position");a.setXYZ(0,e.x,e.y,e.z),a.setXYZ(1,t.x,t.y,t.z),a.needsUpdate=!0,r.material.depthTest=s,r.material.depthWrite=!1,r.material.fog=!1,xn(r.material,i)}static DrawCircle(e,t,i,n=wn,s=0,r=!0){if(!B.enabled)return;const a=Xi.getCircle(s);a.position.set(e.x,e.y,e.z),a.scale.set(i,i,i),a.quaternion.setFromUnitVectors(this._up,Lt.set(t.x,t.y,t.z).normalize()),a.material.depthTest=r,a.material.depthWrite=!1,a.material.fog=!1,xn(a.material,n)}static DrawWireSphere(e,t,i=wn,n=0,s=!0){if(!B.enabled)return;const r=Xi.getSphere(t,n,!0);mr(r,e.x,e.y,e.z),r.material.depthTest=s,r.material.depthWrite=!1,r.material.fog=!1,xn(r.material,i)}static DrawSphere(e,t,i=wn,n=0,s=!0){if(!B.enabled)return;const r=Xi.getSphere(t,n,!1);mr(r,e.x,e.y,e.z),r.material.depthTest=s,r.material.depthWrite=!1,xn(r.material,i)}static DrawWireBox(e,t,i=wn,n=0,s=!0,r=void 0){if(!B.enabled)return;const a=Xi.getBox(n);a.position.set(e.x,e.y,e.z),a.scale.set(t.x,t.y,t.z),r?a.quaternion.copy(r):a.quaternion.identity(),a.material.depthTest=s,a.material.wireframe=!0,a.material.depthWrite=!1,a.material.fog=!1,xn(a.material,i)}static DrawWireBox3(e,t=wn,i=0,n=!0){if(!B.enabled)return;const s=Xi.getBox(i);s.position.copy(e.getCenter(Lt)),s.scale.copy(e.getSize(Lt)),s.material.depthTest=n,s.material.wireframe=!0,s.material.depthWrite=!1,s.material.fog=!1,xn(s.material,t)}static _up=new b(0,1,0);static DrawArrow(e,t,i=wn,n=0,s=!0,r=!1){if(!B.enabled)return;const a=Xi.getArrowHead(n);a.position.set(t.x,t.y,t.z),a.quaternion.setFromUnitVectors(this._up.set(0,1,0),Lt.set(t.x,t.y,t.z).sub(G_.set(e.x,e.y,e.z)).normalize());const l=Lt.set(t.x,t.y,t.z).sub(G_.set(e.x,e.y,e.z)).length()*.1;a.scale.set(l,l,l),a.material.depthTest=s,a.material.wireframe=r,xn(a.material,i),this.DrawLine(e,t,i,n,s)}static DrawWireMesh(e){const t=Xi.getMesh(e.duration??0);"mesh"in e?(t.geometry=e.mesh.geometry,t.matrixWorld.copy(e.mesh.matrixWorld)):(t.geometry=e.geometry,t.matrixWorld.copy(e.matrix)),t.matrixAutoUpdate=!1,t.matrixWorldAutoUpdate=!1,t.material.depthTest=e.depthTest??!0,t.material.wireframe=!0,xn(t.material,e.color??wn)}}const uk=new Sa(1,1,1);function Sg(o=null){const e=new ne(o??14540253),t=new SS(uk);return new eb(t,new pm({color:e}))}function xn(o,e){if(Array.isArray(o)){for(const i of o)xn(i,e);return}const t=e instanceof oe?e.a:1;o.color.set(e),o.opacity=t,o.transparent=t<1}const Cg=Symbol("GizmoCache");class Xi{static familyName="needle-gizmos";static ensureFont(){let e=Ce.FontLibrary.getFontFamily(this.familyName);e||(e=Ce.FontLibrary.addFontFamily(this.familyName),e.addVariant("normal","normal","https://uploads.needle.tools/include/font-msdf.json","https://uploads.needle.tools/include/font.png")?.addEventListener("ready",()=>{Ce.update()}))}static getTextLabel(e,t,i,n,s){this.ensureFont();let r=this.textLabelCache.pop(),a=1;s&&typeof s=="string"&&s?.length>=8&&s.startsWith("#")?(a=parseInt(s.substring(7),16)/255,s=s.substring(0,7),dk&&console.log(s,a)):typeof s=="object"&&s.a!==void 0&&(a=s.a);const l={boxSizing:"border-box",fontFamily:this.familyName,width:"auto",fontSize:i,color:n,lineHeight:1,backgroundColor:s??void 0,backgroundOpacity:a,textContent:t,borderRadius:.5*i,padding:.8*i,whiteSpace:"pre",offset:.05*i};if(r)r.set(l);else{r=new Cb(l);const c=this,h=r;h.setText=function(d){this.set({textContent:d}),c.tmuiNeedsUpdate=!0}}return this.tmuiNeedsUpdate=!0,this.registerTimedObject(V.Current,r,e,this.textLabelCache),r}static getBox(e){let t=this.boxesCache.pop();if(!t){const i=new Sa(1,1,1);t=new G(i)}return this.registerTimedObject(V.Current,t,e,this.boxesCache),t}static getLine(e){let t=this.linesCache.pop();if(!t){t=new Ca;let i=t.geometry.getAttribute("position");i||(i=new mt(new Float32Array(6),3),t.geometry.setAttribute("position",i))}return t.frustumCulled=!1,this.registerTimedObject(V.Current,t,e,this.linesCache),t}static getCircle(e){let t=this.circlesCache.pop();if(!t){t=new Ca;let i=t.geometry.getAttribute("position");if(!i){i=new mt(new Float32Array(xg*3),3),t.geometry.setAttribute("position",i);const n=D(0,1,0),s=D(0,0,1),r=D(s);r.cross(n).normalize();const a=D(r),l=Math.PI*2/(xg-1);for(let c=0;c<xg+1;c++){const h=l*c;n.copy(a).multiplyScalar(Math.cos(h)*1),r.copy(s).multiplyScalar(Math.sin(h)*1);const d=n.add(r);i.setXYZ(c,d.x,d.y,d.z)}}}return t.frustumCulled=!1,this.registerTimedObject(V.Current,t,e,this.circlesCache),t}static getSphere(e,t,i){let n=this.spheresCache.pop();return n||(n=new G(new gd(1,8,8))),n.scale.set(e,e,e),n.material.wireframe=i,this.registerTimedObject(V.Current,n,t,this.spheresCache),n}static getArrowHead(e){let t=this.arrowHeadsCache.pop();return t||(t=new G(new K0(0,.5,1,8))),this.registerTimedObject(V.Current,t,e,this.arrowHeadsCache),t}static getMesh(e){let t=this.mesh.pop();return t||(t=new G,t.material=new xe),this.registerTimedObject(V.Current,t,e,this.mesh),t}static linesCache=[];static circlesCache=[];static spheresCache=[];static boxesCache=[];static arrowHeadsCache=[];static mesh=[];static textLabelCache=[];static registerTimedObject(e,t,i,n){if(!e){console.error("No Needle Engine context available. Did you call a Gizmos function in global scope?");return}const s=this.contextBeforeRenderCallbacks.get(e),r=this.contextPostRenderCallbacks.get(e);if(s){if(e.pre_render_callbacks[e.pre_render_callbacks.length-1]!==s){const a=e.pre_render_callbacks.indexOf(s);a>=0&&e.pre_render_callbacks.splice(a,1),e.pre_render_callbacks.push(s)}}else{const a=()=>{this.onBeforeRender(e,this.timedObjectsBuffer)};this.contextBeforeRenderCallbacks.set(e,a),e.pre_render_callbacks.push(a)}if(r){if(e.post_render_callbacks[e.post_render_callbacks.length-1]!==r){const a=e.post_render_callbacks.indexOf(r);a>=0&&e.post_render_callbacks.splice(a,1),e.post_render_callbacks.push(r)}}else{const a=()=>{this.onPostRender(e,this.timedObjectsBuffer,this.timesBuffer)};this.contextPostRenderCallbacks.set(e,a),e.post_render_callbacks.push(a)}t.traverse(a=>{a.layers.disableAll(),a.layers.enable(2)}),t.renderOrder=999999,t[Cg]=n,t.castShadow=!1,t.receiveShadow=!1,t.isGizmo=!0,this.timedObjectsBuffer.push(t),this.timesBuffer.push(V.Current.time.realtimeSinceStartup+i),e.scene.add(t)}static timedObjectsBuffer=new Array;static timesBuffer=new Array;static contextPostRenderCallbacks=new Map;static contextBeforeRenderCallbacks=new Map;static tmuiNeedsUpdate=!1;static onBeforeRender(e,t){this.tmuiNeedsUpdate&&(this.tmuiNeedsUpdate=!1,Ce.update());for(let i=0;i<t.length;i++){const n=t[i];if(e.mainCamera&&n instanceof Ce.MeshUIBaseElement){if(Rr(n))continue;const s=e.isInVR,r=!1,a=!s;tc(n,e.mainCamera,r,a)}}}static onPostRender(e,t,i){const n=e.time.realtimeSinceStartup;for(let s=t.length-1;s>=0;s--){const r=t[s];n>=i[s]-1e-6&&(t.splice(s,1),i.splice(s,1),r.removeFromParent(),Rr(r)!=!0&&r[Cg].push(r))}}}const qt=v("debugphysics"),X_=new hs;class ys{static AllLayers=4294967295;ray;cam;screenPoint;raycaster;results;targets;recursive=!0;minDistance;maxDistance;lineThreshold;layerMask;ignore;testObject;useAcceleratedRaycast;allowSlowRaycastFallback=!0;screenPointFromOffset(e,t){this.screenPoint===void 0&&(this.screenPoint=new J),this.screenPoint.x=e/window.innerWidth*2-1,this.screenPoint.y=-(t/window.innerHeight)*2+1}setLayer(e){X_.set(e),this.layerMask=X_}setMask(e){this.layerMask||(this.layerMask=new hs);const t=this.layerMask;t?t.mask=e:this.layerMask=e}}class Pg{distance;point;object;constructor(e,t,i){this.object=e,this.distance=t,this.point=i}}class Vl{static _raycasting=0;static get raycasting(){return this._raycasting>0}raycastPhysicsFast(e,t=void 0,i=1/0,n=!0){return this.context.physics.engine?.raycast(e,t,{maxDistance:i,solid:n})??null}raycastPhysicsFastAndGetNormal(e,t=void 0,i=1/0,n=!0){return this.context.physics.engine?.raycastAndGetNormal(e,t,{maxDistance:i,solid:n})??null}sphereOverlapPhysics(e,t){return this.context.physics.engine?.sphereOverlap(e,t)??null}context;engine;constructor(e){this.context=e}raycaster=new fd;defaultRaycastOptions=new ys;targetBuffer=new Array(1);defaultThresholds={Mesh:{},Line:{threshold:-1},LOD:{},Points:{threshold:0},Sprite:{}};sphereResults=new Array;sphereMask=new hs;sphere=new yd;sphereOverlap(e,t,i=!0,n=!1,s=null){if(this.sphereResults.length=0,!this.context.scene)return this.sphereResults;const r=this.sphereMask;r.enableAll(),r.disable(2);for(const a of this.context.scene.children)this.intersectSphere(a,e,t,r,this.sphereResults,i,n,s);return this.sphereResults.sort((a,l)=>a.distance-l.distance)}raycastFromRay(e,t=null){const i=t??this.defaultRaycastOptions;i.ray=e;const n=this.raycast(i);return i===this.defaultRaycastOptions&&(i.ray=void 0),n}raycast(e=null){qt&&performance.mark("raycast.start"),e||(e=this.defaultRaycastOptions);const t=e.screenPoint??this.context.input.mousePositionRC,i=e.raycaster??this.raycaster;if(i.near=e.minDistance??0,i.far=e.maxDistance??1/0,i.params=this.defaultThresholds,e.lineThreshold===void 0&&(e.lineThreshold=-1),i.params.Line={threshold:e.lineThreshold},e.ray)i.ray.copy(e.ray);else{const a=e.cam??this.context.mainCamera;if(!a)return qt&&console.error("Can not perform raycast - no main camera found"),this.defaultRaycastOptions.results&&(this.defaultRaycastOptions.results.length=0),this.defaultRaycastOptions.results??[];const l=this.context.xrCamera;this.context.isInXR&&l instanceof CS&&l.cameras.length>0?i.setFromCamera(t,l.cameras[0]):i.setFromCamera(t,a)}let n=e.targets;n||(n=this.targetBuffer,n.length=1,n[0]=this.context.scene);let s=e.results;this.defaultRaycastOptions.results&&(this.defaultRaycastOptions.results.length=0),s||(this.defaultRaycastOptions.results||(this.defaultRaycastOptions.results=new Array),s=this.defaultRaycastOptions.results),e.layerMask!==void 0?e.layerMask instanceof hs?i.layers.mask=e.layerMask.mask:i.layers.mask=e.layerMask:(i.layers.enableAll(),i.layers.disable(2)),qt&&console.time("raycast"),s.length=0,Vl._raycasting++,this.intersect(this.raycaster,n,s,e),s.sort((a,l)=>a.distance-l.distance);const r=e.ignore;return r!==void 0&&r.length>0&&(s=s.filter(a=>!r.includes(a.object))),Vl._raycasting--,qt&&(console.timeEnd("raycast"),console.warn("#"+this.context.time.frame+", hits:",s?.length?[...s]:"nothing"),performance.mark("raycast.end"),performance.measure("raycast","raycast.start","raycast.end")),s}intersect(e,t,i,n){for(const s of t){if(!s||s.visible===!1||B.isGizmo(s)||n.lineThreshold!==void 0&&n.lineThreshold<0&&s instanceof Ca)continue;let r=!0;const a=s,l=a.geometry;if(s.raycastAllowed===!1&&(r=!1),r&&n.testObject){const c=n.testObject?.(s);if(c===!1)continue;c==="continue in children"&&(r=!1)}else r&&(l&&Q_(l)||(r=!1));if(r){const c=i.length,h=s.raycastPreference||"lod";let d=h!=="bounds";if(n.precise===!1&&(d=!1),l&&(d||=l.getAttribute("position")?.array?.length<64),a instanceof ka&&(d=!1),h==="lod"){const p=db(s);p&&(a.geometry=p)}if(!d&&mk(a,e,i)||(n.useAcceleratedRaycast!==!1?Xd.runMeshBVHRaycast(e,a,i,this.context,n):e.intersectObject(a,!1,i)),a.geometry=l,qt&&i.length!=c){const p=i[i.length-1];B.DrawWireSphere(p.point,.1,7798784,1,!1),B.DrawWireMesh({mesh:s,depthTest:!1,duration:.2,color:7798784})}}n.recursive!==!1&&this.intersect(e,s.children,i,n)}return i}tempBoundingBox=new wi;intersectSphere(e,t,i,n,s,r,a,l){let c=e&&e.isMesh&&e.layers.test(n)&&!B.isGizmo(e);c&&=e.visible,c&&=!(e instanceof Ca),c&&=!(e instanceof ka);const h=e,d=h.geometry;if(c&&l){const p=l(e);if(p===!1)return;p==="continue in children"&&(c=!1)}if(d&&Q_(d)||(c=!1),c){if(a){const p=this.sphere;p.center.copy(t),p.radius=i;const m=s.length;if(Xd.runMeshBVHRaycast(this.sphere,h,s,this.context,{}),m!=s.length&&!r)return}else if(d.boundingBox||d.computeBoundingBox(),d.boundingBox){h.matrixWorldNeedsUpdate&&h.updateWorldMatrix(!1,!1);const p=this.tempBoundingBox.copy(d.boundingBox).applyMatrix4(h.matrixWorld),m=this.sphere;if(m.center.copy(t),m.radius=i,m.intersectsBox(p)){const f=K(e),g=f.distanceTo(m.center),y=new Pg(e,g,f);if(s.push(y),!r)return}}}if(e.children)for(const p of e.children){const m=s.length;if(this.intersectSphere(p,t,i,n,s,r,a,l),m!=s.length&&!r)return}}}function Q_(o){return!(o.index&&o.index.array.length<3)}const Sr=new yd,qd=new hr,pk=new Z0;function mk(o,e,t){const i=o._computeIntersections;if(!i)return!1;let n=o["_computeIntersections:Needle"];return n||(n=o["_computeIntersections:Needle"]=function(s,r,a){const l=this,c=l.geometry.boundingSphere;if(c){if(l instanceof ka){qd.setFromNormalAndCoplanarPoint(D(0,1,0),D(0,-l.position.y,0)),qd.applyMatrix4(l.matrixWorld,pk);const d=s.ray.intersectPlane(qd,D());if(d){Sr.copy(c),Sr.applyMatrix4(l.matrixWorld);const p=D(d).sub(s.ray.origin).length(),m=Sr.radius*.5;p<m&&r.push({distance:p,point:d,object:l,normal:qd.normal.clone()})}return}Sr.copy(c),Sr.applyMatrix4(l.matrixWorld);const h=s.ray.intersectSphere(Sr,D());if(h){const d=D(h).sub(s.ray.origin),p=d.length();if(p>Sr.radius){const m=d.clone().normalize();r.push({distance:p,point:h,object:l,normal:m})}}}}),o._computeIntersections=n,e.intersectObject(o,!1,t),o._computeIntersections=i,!0}var Xd;(o=>{let e=0;function t(w,P,M,k,F){if(!P.geometry||!P.geometry.hasAttribute("position"))return!1;const L=P.geometry;if(P?.isSkinnedMesh){const z=P,j=z.bvhNeedsUpdate;if(!z.staticGenerator)l(),r&&(z.staticGenerator=new r(P),z.staticGenerator.applyWorldTransforms=!1,z.staticGeometry=z.staticGenerator.generate(),L.boundsTree=a?.call(z.staticGeometry),z.staticGeometryLastUpdate=performance.now()+Math.random()*200,z.bvhNeedsUpdate=!0);else if(L.boundsTree&&(z.autoUpdateMeshBvhInterval!==void 0&&z.autoUpdateMeshBvhInterval>=0||j===!0)){const $=performance.now(),ee=$-z.staticGeometryLastUpdate,E=z.autoUpdateMeshBvhInterval??100;(j||ee>E)&&(qt&&console.warn(`Physics: updating skinned mesh bvh for ${P.name} after ${ee.toFixed(2)}ms`),z.bvhNeedsUpdate=!1,z.staticGeometryLastUpdate=$,z.staticGenerator?.generate(z.staticGeometry),L.boundsTree.refit())}}else if(!L.boundsTree){h||_();let z=!0;if((k.xr||L[f]===!1||L.getAttribute("position")?.isInterleavedBufferAttribute||L.index&&L.index?.isInterleavedBufferAttribute||e>10)&&(z=!1),z&&p){if(L[m]===void 0){let j=null;if(y.length>0){const $=y.shift();$&&!$.running&&(j=$)}if(!j&&g.length<3)try{j=new p,g.push(j)}catch($){$ instanceof DOMException&&$.name==="SecurityError"?(console.warn("Failed to create MeshBVH worker, falling back to main thread generation. This can happen when running from file://, if the browser does not support workers or if the browser is blocking workers for other reasons."),console.debug($),e+=10):(console.error("Failed to create MeshBVH worker"),console.debug($)),e++}if(j!=null&&!j.running){const $=P.name;qt&&console.log("<<<< worker start",$,j),L[m]="queued",performance.mark("bvh.create.start");const ee=L.clone();try{j.generate(ee).then(E=>{L[m]="done",L.boundsTree=E}).catch(E=>{L[m]="failed - "+E?.message,L[f]=!1,qt&&console.error("Failed to generate mesh bvh on worker",E)}).finally(()=>{qt&&console.log(">>>>> worker done",$,{hasBoundsTre:L.boundsTree!=null}),y.push(j),ee.dispose(),performance.mark("bvh.create.end"),performance.measure("bvh.create (worker)","bvh.create.start","bvh.create.end")})}catch(E){console.error("Failed to generate mesh bvh on worker",E)}}else qt&&console.warn("No worker available")}}else(!d||!z)&&(l(),s&&(performance.mark("bvh.create.start"),L.boundsTree=new s(L),performance.mark("bvh.create.end"),performance.measure("bvh.create","bvh.create.start","bvh.create.end")))}if(w instanceof fd){const z=w,j=P.raycast;if(L.boundsTree)l(),n&&(P.acceleratedRaycast||(P.acceleratedRaycast=n.bind(P),qt&&console.debug(`Physics: bind acceleratedRaycast fn to "${P.name}"`)),P.raycast=P.acceleratedRaycast);else if(qt&&console.warn("No bounds tree found for mesh",P.name,{workerTask:L[m],hasAcceleratedRaycast:n!=null}),F.allowSlowRaycastFallback===!1&&(L.getAttribute("position")?.array?.length??0)>2e3)return qt&&console.warn("Skipping raycast because no bounds tree is available and allowSlowRaycastFallback is false"),!1;const $=z.firstHitOnly;return z.firstHitOnly=!1,z.intersectObject(P,!1,M),z.firstHitOnly=$,P.raycast=j,!0}else if(w instanceof yd){const z=L.boundsTree;if(z){const j=w;if(c.copy(P.matrixWorld).invert(),j.applyMatrix4(c),z.intersectsSphere(j)){const $=K(P),ee=$.distanceTo(j.center),E=new Pg(P,ee,$);M.push(E)}}return!0}return!1}o.runMeshBVHRaycast=t;let i=!1,n=null,s=null,r=null,a=null;function l(){i||(i=!0,import("./vendor-DWGd3dEf.min.js").then(w=>w.index$1).then(w=>{n=w.acceleratedRaycast,s=w.MeshBVH,r=w.StaticGeometryGenerator,a=w.computeBoundsTree}).catch(w=>{(qt||A())&&console.error("Failed to load BVH library...",w.message)}))}const c=new Z;let h=!1,d=!1,p=null;const m=Symbol("Needle:MeshBVH-Worker"),f=Symbol("Needle:MeshBVH-CanUseWorker"),g=[],y=[];function _(){h=!0,d=!0,Promise.resolve().then(()=>cL).then(w=>{p=w.GenerateMeshBVHWorker}).catch(w=>{qt||A()?console.warn("Failed to setup mesh bvh worker"):console.debug("Failed to setup mesh bvh worker",w)}).finally(()=>{d=!1})}})(Xd||(Xd={}));const Y_=Symbol("gltf-loader-internal-usage-tracker"),gk=v("debugusers");class Wl{get name(){return"NEEDLE_internal_usage_tracker"}static isLoading(e){return Wl._loadingProcesses>0}static _loadingProcesses=0;parser;_getDependency;_loadingId;_loadedObjects=new Set;constructor(e){this.parser=e,this._getDependency=this.parser.getDependency,this._loadingId=Date.now().toString()}beforeRoot(){Wl._loadingProcesses++;const e=this,t=this._getDependency;return this.parser.getDependency=function(i,n){const s=t.call(this,i,n);return s.then(r=>(r&&(e._loadedObjects.add(r),r[Y_]=e._loadingId),r)),s},null}afterRoot(e){Wl._loadingProcesses--,this.parser.getDependency=this._getDependency;for(const t of this._loadedObjects)delete t[Y_],t instanceof O&&(t.parent||t instanceof G&&setTimeout(()=>{gk&&console.warn("> GLTF LOADER: Mesh not used in scene!",t),t.material=null,t.geometry=null},1e3));return null}}class Z_{constructor(){window.addEventListener("unhandledrejection",e=>{if(e.defaultPrevented)return;const t=e?.reason?.path;if(t){const i=t[0];i&&i.tagName==="IMG"&&(console.warn(`Could not load image:
168
168
  `+i.src),e.preventDefault())}})}}const Qd=v("trackresources");function K_(){return Qd==="dispose"}let Cr=!0;Qd===0&&(Cr=!1);function fk(o){Cr=o}function J_(){return Cr}const ev=Symbol("disposable");function tv(o,e){o&&(o[ev]=e,Pr&&console.warn("Set disposable",e,o))}const iv=Symbol("disposed");function yk(o){return o[iv]===!0}function Pe(o){if(o){if(o[ev]===!1){Pr&&console.warn("Object is marked as not disposable",o);return}if(typeof o=="object"&&(o[iv]=!0),o instanceof vi)Pe(o.environment),Pe(o.background),Pe(o.customDepthMaterial),Pe(o.customDistanceMaterial);else if(o instanceof ds)Pe(o.geometry),Pe(o.material),Pe(o.skeleton),Pe(o.bindMatrix),Pe(o.bindMatrixInverse),Pe(o.customDepthMaterial),Pe(o.customDistanceMaterial),o.visible=!1;else if(o instanceof G)Pe(o.geometry),Pe(o.material),Pe(o.customDepthMaterial),Pe(o.customDistanceMaterial),o.visible=!1;else if(o instanceof O)o.visible=!1;else if(o instanceof gn){Fa(o);for(const e of Object.keys(o.attributes)){const t=o.attributes[e];Pe(t)}}else if(o instanceof mt||o instanceof tb)Pr&&console.warn("BufferAttribute dispose not supported",o.count);else if(o instanceof Array)for(const e of o)e instanceof ve&&Pe(e);else if(o instanceof ve){Fa(o);for(const t of Object.keys(o)){const i=o[t];i instanceof Te&&Pe(i)}const e=o.uniforms;if(e)for(const t of Object.keys(e)){const i=e[t];i instanceof Te?Pe(i):i instanceof Wi&&Pe(i.value)}}else o instanceof Te?(Fa(o),Fa(o.source),o.source?.data instanceof ImageBitmap&&Fa(o.source.data)):o instanceof PS?(Fa(o.boneTexture),o.boneTexture=null):o instanceof OS||!(o instanceof O)&&Pr&&console.warn("Unknown object type",o)}}function Fa(o){o&&((Pr||K_()||Qd)&&console.warn("\u{1F9E8} FREE",o),o instanceof ImageBitmap||"dispose"in o&&typeof o.dispose=="function"&&o.dispose())}function bk(o){}const _k=new Set;function Og(o,e,t=null,i){if(i||(i=_k,i.clear()),!o)return i;const n=o[uc];if(n)for(const s of n)i.has(s)||t?.call(null,s)!==!1&&(i.add(s),e&&Og(s,!0,t,i));return i}function vk(o){return o[pc]}const Pr=v("debugresourceusers")||v("debugmemory"),uc=Symbol("needle-resource-users"),pc=Symbol("needle-resource-users-count");function Xt(o,e){Bd(o,e,function(t,i){Cr&&!Vl.raycasting&&(Yd(uc,this,t,!1),Yd(uc,this,i,!0))})}Cr&&(Xt(G.prototype,"material"),Xt(G.prototype,"geometry"),Xt(ve.prototype,"map"),Xt(ve.prototype,"bumpMap"),Xt(ve.prototype,"alphaMap"),Xt(ve.prototype,"normalMap"),Xt(ve.prototype,"displacementMap"),Xt(ve.prototype,"roughnessMap"),Xt(ve.prototype,"metalnessMap"),Xt(ve.prototype,"emissiveMap"),Xt(ve.prototype,"specularMap"),Xt(ve.prototype,"envMap"),Xt(ve.prototype,"lightMap"),Xt(ve.prototype,"aoMap"),Xt(ve.prototype,"gradientMap"));function wk(o){if(Cr===!1)return;const e=o[uc];if(e)for(const t of e)Yd(uc,t,o,!1)}Cr&&Bd(ve.prototype,"dispose",function(){wk(this)});let kg=0;function Yd(o,e,t,i){if(kg>0)return;if(Array.isArray(t)){for(const s of t)Yd(o,e,s,i);return}if(!t)return;let n=t[o];if(n||(n=new Set),i){if(e&&!n.has(e)){n.add(e);let s=t[pc]||0;s+=1,t[pc]=s,Pr&&console.warn(`\u{1F7E2} Added user of "${t.type}"`,e,t,s,"users:",n)}}else if(e&&n.has(e)){n.delete(e);let s=t[pc]||0;s>0&&(s-=1,t[pc]=s),Pr&&console.warn(`\u{1F534} Removed user of "${t.type}"`,e,t,s,"users:",n),s<=0&&(Wl.isLoading(t)||(Qd&&console.warn(`\u{1F534} Removed all user of "${t.type}"`,t),K_()&&Pe(t)))}t[o]=n}try{Bd(cr.prototype,"render",function(){kg++},function(){kg--})}catch(o){console.warn("Could not wrap WebGLRenderer.render",o)}const nv=v("debugcomponentevents");class Zd{static eventListeners=new Map;static addComponentLifecylceEventListener(e,t){this.eventListeners.has(e)&&this.eventListeners.set(e,[]);let i=this.eventListeners.get(e);i||(i=[]),i.push(t),this.eventListeners.set(e,i),nv&&console.log("Added event listener for "+e,this.eventListeners)}static removeComponentLifecylceEventListener(e,t){const i=this.eventListeners.get(e);if(!i)return;const n=i.indexOf(t);n<0||i.splice(n,1)}static dispatchComponentLifecycleEvent(e,t){const i=this.eventListeners.get(e);if(nv&&console.log("Dispatching event "+e,i),!!i)for(const n of i)n(t)}}const mc=Symbol("NEEDLE_NEED_UPDATE_INSTANCE"),ov=Symbol("isUsingInstancing"),sv=Symbol("instancingRenderer"),gc=Symbol("instancingAutoUpdateBounds");class hn{static isUsingInstancing(e){return e[ov]===!0}static getRenderer(e){return e[sv]||null}setAutoUpdateBounds(e,t){const i=hn.getRenderer(e);i&&(i[gc]=t)}static markDirty(e,t=!0){if(e&&(this.isUsingInstancing(e)&&(e[mc]=!0,e.matrixWorldNeedsUpdate=!0),t))for(const i of e.children)hn.markDirty(i,!0)}}var fc;(o=>{o.experimentalSmartHierarchyUpdate=!1})(fc||(fc={}));function Ua(o,e){try{e||o()}catch(t){return console.error(t),!1}return!0}const Mg=v("debugnewscripts"),xk=v("debughierarchy"),Ie=[];function Sk(){return Ie.length>0}function Kd(o){if(Mg&&console.log("Register new components",o.new_scripts.length,[...o.new_scripts],o.alias?"element: "+o.alias:o.hash,o),o.new_scripts_pre_setup_callbacks.length>0){for(const e of o.new_scripts_pre_setup_callbacks)e&&e();o.new_scripts_pre_setup_callbacks.length=0}if(!(o.new_scripts.length<=0)){Ie.length=0,o.new_scripts.length>0&&Ie.push(...o.new_scripts),o.new_scripts.length=0;for(let e=0;e<Ie.length;e++)try{const t=Ie[e];if(t.isComponent!==!0){(A()||Mg)&&console.error(`Registered script is not a Needle Engine component.
169
169
  The script will be ignored. Please make sure your component extends "Behaviour" imported from "@needle-tools/engine"
170
170
  `,t),Ie.splice(e,1),e--;continue}if(t.destroyed)continue;if(!t.gameObject){console.warn(`Component can not be initialized: no GameObject assigned.
@@ -1427,8 +1427,8 @@ C) Set "joinRandomRoom" to true`),!1):(_0&&console.log("Join "+this.roomName),th
1427
1427
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1428
1428
  * See the License for the specific language governing permissions and
1429
1429
  * limitations under the License.
1430
- */const lI={topLight:{intensity:500,position:[.418,16.199,.3]},room:{position:[-.757,13.219,.717],scale:[31.713,28.305,28.591]},boxes:[{position:[-10.906,2.009,1.846],rotation:-.195,scale:[2.328,7.905,4.651]},{position:[-5.607,-.754,-.758],rotation:.994,scale:[1.97,1.534,3.955]},{position:[6.167,.857,7.803],rotation:.561,scale:[3.927,6.285,3.687]},{position:[-2.017,.018,6.124],rotation:.333,scale:[2.002,4.566,2.064]},{position:[2.291,-.756,-2.621],rotation:-.286,scale:[1.546,1.552,1.496]},{position:[-2.193,-.369,-5.547],rotation:.516,scale:[3.875,3.487,2.986]}],lights:[{intensity:50,position:[-16.116,14.37,8.208],scale:[.1,2.428,2.739]},{intensity:50,position:[-16.109,18.021,-8.207],scale:[.1,2.425,2.751]},{intensity:17,position:[14.904,12.198,-1.832],scale:[.15,4.265,6.331]},{intensity:43,position:[-.462,8.89,14.52],scale:[4.38,5.441,.088]},{intensity:20,position:[3.235,11.486,-12.541],scale:[2.5,2,.1]},{intensity:100,position:[0,20,0],scale:[1,.1,1]}]},cI={topLight:{intensity:400,position:[.5,14,.5]},room:{position:[0,13.2,0],scale:[31.5,28.5,31.5]},boxes:[{position:[-10.906,-1,1.846],rotation:-.195,scale:[2.328,7.905,4.651]},{position:[-5.607,-.754,-.758],rotation:.994,scale:[1.97,1.534,3.955]},{position:[6.167,-.16,7.803],rotation:.561,scale:[3.927,6.285,3.687]},{position:[-2.017,.018,6.124],rotation:.333,scale:[2.002,4.566,2.064]},{position:[2.291,-.756,-2.621],rotation:-.286,scale:[1.546,1.552,1.496]},{position:[-2.193,-.369,-5.547],rotation:.516,scale:[3.875,3.487,2.986]}],lights:[{intensity:80,position:[-14,10,8],scale:[.1,2.5,2.5]},{intensity:80,position:[-14,14,-4],scale:[.1,2.5,2.5]},{intensity:23,position:[14,12,0],scale:[.1,5,5]},{intensity:16,position:[0,9,14],scale:[5,5,.1]},{intensity:80,position:[7,8,-14],scale:[2.5,2.5,.1]},{intensity:80,position:[-7,16,-14],scale:[2.5,2.5,.1]},{intensity:1,position:[0,20,0],scale:[.1,.1,.1]}]};class qp extends vi{constructor(e){super(),this.position.y=-3.5;const t=new Sa;t.deleteAttribute("uv");const i=new pt({metalness:0,side:Sd}),n=new pt({metalness:0}),s=e=="legacy"?lI:cI,r=new um(16777215,s.topLight.intensity,28,2);r.position.set(...s.topLight.position),this.add(r);const a=new G(t,i);a.position.set(...s.room.position),a.scale.set(...s.room.scale),this.add(a);for(const l of s.boxes){const c=new G(t,n);c.position.set(...l.position),c.rotation.set(0,l.rotation,0),c.scale.set(...l.scale),this.add(c)}for(const l of s.lights){const c=new G(t,this.createAreaLightMaterial(l.intensity));c.position.set(...l.position),c.scale.set(...l.scale),this.add(c)}}createAreaLightMaterial(e){const t=new xe;return t.color.setScalar(e),t}}var hI=Object.defineProperty,Xp=(o,e,t,i)=>{for(var n=void 0,s=o.length-1,r;s>=0;s--)(r=o[s])&&(n=r(e,t,n)||n);return n&&hI(e,t,n),n};const zh=class yS extends R{target;invertForward=!1;keepUpDirection=!0;copyTargetRotation=!1;static flipYQuat=new N().setFromAxisAngle(new b(0,1,0),Math.PI);onBeforeRender(){let e=this.target;if(e||(e=this.context.mainCamera,A()&&!this.__did_warn&&(this.__did_warn=!0,console.debug(`[LookAt] No target set on ${this.name}, using main camera as target.`))),!e)return;let t=this.copyTargetRotation;(this.context.isInVR||this.context.isInPassThrough)&&(t=!1),tc(this.gameObject,e,this.keepUpDirection,t),this.invertForward&&this.gameObject.quaternion.multiply(yS.flipYQuat)}createBehaviours(e,t,i){if(t.uuid===this.gameObject.uuid){let n=t;if(this.keepUpDirection){const r=nt.createEmptyParent(t);n=r;const a=this.invertForward?-1:1;r.setMatrix(r.getMatrix().multiply(new Z().makeRotationZ(Math.PI/2*a))),t.setMatrix(t.getMatrix().multiply(new Z().makeRotationZ(-Math.PI/2*a)))}const s=new At("lookat "+this.name,Ft.sceneStartTrigger(),ge.lookAtCameraAction(n,void 0,this.invertForward?pn.back:pn.forward,this.keepUpDirection?pn.up:pn.zero));e.addBehavior(s)}}};Xp([u(O)],zh.prototype,"target"),Xp([u()],zh.prototype,"invertForward"),Xp([u()],zh.prototype,"keepUpDirection"),Xp([u()],zh.prototype,"copyTargetRotation");let O0=zh;var dI=Object.defineProperty,k0=(o,e,t,i)=>{for(var n=void 0,s=o.length-1,r;s>=0;s--)(r=o[s])&&(n=r(e,t,n)||n);return n&&dI(e,t,n),n};class Il extends R{url;mode=0;clickable=!0;async open(){if(!this.url){console.warn("OpenURL: URL is not set, can't open.",this);return}this._validateUrl();let e=this.url;switch(!e.startsWith("mailto:")&&e.includes("@")&&(e="mailto:"+e),A()&&Ee("Open URL: "+e),this.mode){case 0:q.isSafari(),globalThis.open(e,"_blank");break;case 1:q.isSafari()&&q.isiOS()?globalThis.open(e,"_top"):globalThis.open(e,"_self");break;case 2:q.isSafari()?globalThis.open(e,"_top"):globalThis.open(e,"_new");break}}start(){this.gameObject.getComponentInParent(Ti)||this.gameObject.addComponent(Ti)}onPointerEnter(e){!e.used&&this.clickable&&this.context.input.setCursor("pointer")}onPointerExit(){this.clickable&&this.context.input.unsetCursor("pointer")}onPointerClick(e){this.clickable&&!e.used&&this.url?.length&&this.open()}_validateUrl(){this.url&&this.url.startsWith("www.")&&(A()&&console.warn("URL is not valid, adding https:// to the start of the URL",this.url),this.url="https://"+this.url)}}k0([u()],Il.prototype,"url"),k0([u()],Il.prototype,"mode"),k0([u()],Il.prototype,"clickable"),xu(o=>{const e=o.domElement.getAttribute("clickthrough");if(t(e)){const i=o.scene.addComponent(Qp);Dm(o.domElement,"clickthrough",()=>{const n=o.domElement.getAttribute("clickthrough");i.enabled=t(n)})}function t(i){return i!==null&&i!=="0"&&i!=="false"}});class Qp extends R{_previousPointerEvents="all";onEnable(){this.context.input.addEventListener("pointerdown",this.onPointerEvent),this.context.input.addEventListener("pointermove",this.onPointerEvent,{queue:100}),window.addEventListener("touchstart",this.onTouchStart,{passive:!0}),window.addEventListener("touchend",this.onTouchEnd,{passive:!0}),this._previousPointerEvents=this.context.domElement.style.pointerEvents}onDisable(){this.context.input.removeEventListener("pointerdown",this.onPointerEvent),this.context.input.removeEventListener("pointermove",this.onPointerEvent),window.removeEventListener("touchstart",this.onTouchStart),window.removeEventListener("touchend",this.onTouchEnd),this.context.domElement.style.pointerEvents=this._previousPointerEvents}onPointerEnter(){}onPointerEvent=e=>{e.pointerId>0||(e.intersections?.length<=0?this.context.domElement.style.pointerEvents="none":this.context.domElement.style.pointerEvents="all")};_touchDidHitAnything=!1;onTouchStart=e=>{const t=e.touches[0];if(!t)return;const i=t.clientX/window.innerWidth*2-1,n=-(t.clientY/window.innerHeight)*2+1;this.context.physics.raycast({screenPoint:new J(i,n)}).length>0&&(this._touchDidHitAnything=!0)};onTouchEnd=e=>{const t=this._touchDidHitAnything;this._touchDidHitAnything=!1,setTimeout(()=>{t&&(this.context.domElement.style.pointerEvents="all")},100)}}var uI=Object.defineProperty,Yp=(o,e,t,i)=>{for(var n=void 0,s=o.length-1,r;s>=0;s--)(r=o[s])&&(n=r(e,t,n)||n);return n&&uI(e,t,n),n};const pI=v("debugcursor");class ua extends R{damping=0;useFullPage=!0;keepDistance=!0;snapToSurface=!1;_distance=-1;updateDistance(e=!1){!e&&this.keepDistance&&this._distance!==-1||(this._distance=this.gameObject.worldPosition.distanceTo(this.context.mainCamera.worldPosition))}awake(){this._distance=-1}onEnable(){this._distance=-1,window.addEventListener("pointermove",this._onPointerMove)}onDisable(){window.removeEventListener("pointermove",this._onPointerMove)}_ndc_x=0;_ndc_y=0;_onPointerMove=e=>{if(!this.useFullPage)return;const t=e.clientX,i=e.clientY,n=this.context.domX,s=this.context.domY,r=this.context.domWidth,a=this.context.domHeight;this._ndc_x=(t-n)/r*2-1,this._ndc_y=-(i-s)/a*2+1};lateUpdate(){this.updateDistance();const e=this.useFullPage?this._ndc_x:this.context.input.mousePositionRC.x,t=this.useFullPage?this._ndc_y:this.context.input.mousePositionRC.y,i=this.context.mainCamera,n=i.worldPosition,s=D(e,t,1).unproject(i);s.sub(n).normalize();const r=D(s).multiplyScalar(this._distance).add(n);let a=r;if(this.damping>0){const l=this.gameObject.worldPosition;l.lerp(r,this.context.time.deltaTime/this.damping),this.gameObject.worldPosition=l,a=l}else this.gameObject.worldPosition=r;if(this.snapToSurface){M0.origin=a,M0.direction=s.multiplyScalar(-1);const l=this.context.physics.raycastFromRay(M0);if(l?.length){const c=l[0];this.damping>0?this.gameObject.worldPosition=a.lerp(c.point,this.context.time.deltaTime/this.damping):this.gameObject.worldPosition=c.point,pI&&B.DrawLine(c.point,c.normal.add(c.point),65280)}}}}Yp([u()],ua.prototype,"damping"),Yp([u()],ua.prototype,"useFullPage"),Yp([u()],ua.prototype,"keepDistance"),Yp([u()],ua.prototype,"snapToSurface");const M0=new yo;var mI=Object.defineProperty,gI=Object.getOwnPropertyDescriptor,Ll=(o,e,t,i)=>{for(var n=i>1?void 0:i?gI(e,t):e,s=o.length-1,r;s>=0;s--)(r=o[s])&&(n=(i?r(e,t,n):r(n))||n);return i&&n&&mI(e,t,n),n};let uo=class extends R{type="linear";duration=.1;scaleFactor=1.1;hovered=null;idle=null;animation=null;start(){this.idle||(this.idle=_s.emptyClip()),(!this.hovered||!(this.hovered instanceof Ci))&&(this.hovered=_s.createScaleClip({type:"linear",duration:this.duration||.1,scale:this.gameObject.scale,scaleFactor:this.scaleFactor||1.1})),this.animation??=this.gameObject.addComponent(jt),this.animation.playAutomatically=!1,this.playIdle()}onEnable(){this.animation&&(this.animation.enabled=!0),this.playIdle()}onDisable(){this.animation&&(this.animation.enabled=!1),this.playIdle()}onPointerEnter(){this.playHover()}onPointerExit(){this.playIdle()}playIdle(){this.idle&&this.animation?.play(this.idle,{exclusive:!0,fadeDuration:.1,loop:!0})}playHover(){this.hovered&&this.animation?.play(this.hovered,{exclusive:!0,fadeDuration:.1,loop:!1,clampWhenFinished:!0})}};Ll([u()],uo.prototype,"type",2),Ll([u()],uo.prototype,"duration",2),Ll([u()],uo.prototype,"scaleFactor",2),Ll([u(Ci)],uo.prototype,"hovered",2),Ll([u(Ci)],uo.prototype,"idle",2),uo=Ll([Fg],uo);var fI=Object.defineProperty,jl=(o,e,t,i)=>{for(var n=void 0,s=o.length-1,r;s>=0;s--)(r=o[s])&&(n=r(e,t,n)||n);return n&&fI(e,t,n),n};const Nh=v("debugscroll");class Ko extends R{target=null;damping=0;invert=!1;htmlSelector=null;mode="window";changed=new he;get currentValue(){return this._current_value}_current_value=0;_target_value=0;_appliedValue=-1;onEnable(){window.addEventListener("wheel",this.updateCurrentScrollValue,{passive:!0}),this._appliedValue=-1}onDisable(){window.removeEventListener("wheel",this.updateCurrentScrollValue)}lateUpdate(){if(this.updateCurrentScrollValue(),this._target_value>=0&&(this.damping>0?(this._current_value=I.lerp(this._current_value,this._target_value,this.context.time.deltaTime/this.damping),Math.abs(this._current_value-this._target_value)<.001&&(this._current_value=this._target_value)):this._current_value=this._target_value),this._current_value!==this._appliedValue){this._appliedValue=this._current_value;let e=!1;if(this.changed.listenerCount>0){const t={type:"change",value:this._current_value,component:this,preventDefault:()=>{t.defaultPrevented=!0},defaultPrevented:!1};this.changed.invoke(t),e=t.defaultPrevented}if(!e){const t=this.invert?1-this._current_value:this._current_value;Array.isArray(this.target)?this.target.forEach(i=>i&&this.applyScroll(i,t)):this.target&&this.applyScroll(this.target,t),Nh&&this.context.time.frame%30===0&&console.debug(`[ScrollFollow] ${this._current_value.toFixed(5)} \u2014 ${(this._target_value*100).toFixed(0)}%, targets [${Array.isArray(this.target)?this.target.length:1}]`)}}}_lastSelectorValue=null;_lastSelectorElement=null;updateCurrentScrollValue=()=>{switch(this.mode){case"window":if(this.htmlSelector?.length){if(this.htmlSelector!==this._lastSelectorValue&&(this._lastSelectorElement=document.querySelector(this.htmlSelector),this._lastSelectorValue=this.htmlSelector),this._lastSelectorElement){const e=this._lastSelectorElement.getBoundingClientRect();this._target_value=-e.top/(e.height-window.innerHeight);break}}else if(!(window.document.body.scrollHeight<=window.innerHeight)){const e=window.document.body.scrollHeight-window.innerHeight;this._target_value=window.scrollY/(e||1)}break}(isNaN(this._target_value)||!isFinite(this._target_value))&&(this._target_value=-1)};applyScroll(e,t){if(e)if(e instanceof ca)this.handleTimelineTarget(e,t),e.isPlaying&&e.pause(),e.evaluate();else if(e instanceof yt)e.setFloat("scroll",t);else if(e instanceof jt)e.time=t*e.duration;else if(e instanceof Ei){if(!e.duration)return;e.time=t*e.duration}else if(e instanceof an)e.position01=t;else if(e instanceof mi)e.intensity=t;else if(e instanceof O){const i=e;i["needle:scrollbounds"]===void 0&&(i["needle:scrollbounds"]=Gt(e)||null);const n=i["needle:scrollbounds"];n&&(e.position.y=-n.min.y-t*(n.max.y-n.min.y))}else"scroll"in e&&(typeof e.scroll=="number"?e.scroll=t:typeof e.scroll=="function"&&e.scroll(t))}handleTimelineTarget(e,t){const i=e.duration;let n=I1.get(e);if(!n){n=[],I1.set(e,n);let l=0;for(const c of e.foreachMarker("ScrollMarker")){const h=l++;if(c.element===void 0||c.needsUpdate===!0||c.element&&!c.element?.parentNode){c.needsUpdate=!1;try{if(c.element=L1(h),Nh&&console.debug(`ScrollMarker #${h} (${c.time.toFixed(2)}) found`,c.element),!c.element){(Nh||A())&&console.warn(`No HTML element found for ScrollMarker: ${c.name} (index ${h})`);continue}}catch(d){c.element=null,console.error("ScrollMarker selector is not valid: "+c.name+`
1431
- `,d)}}c.element&&n.push(c)}n.length<=0&&document.querySelectorAll("[data-timeline-marker]").forEach(c=>{const h=c.getAttribute("data-timeline-marker"),d=parseFloat(h||"NaN");isNaN(d)?(A()||Nh)&&console.warn('[ScrollFollow] data-timeline-marker attribute is not a valid number. Supported are numbers only (e.g. <div data-timeline-marker="0.5">)'):n.push({time:d,element:c})});for(const c of n)c.element&&(c.timeline=new ViewTimeline({subject:c.element,axis:"block"}))}po.length=0;let s=0;const r=1/60;let a=0;for(let l=0;l<n.length;l++){const c=n[l];if(!c.element)continue;const h=n[l+1],d=h?h.time-r:i;a+=1;const p=c.timeline;if(p){const m=yI(p),f=1-Math.abs(m-.5)*2,g=`marker${l}`;if(m>0&&m<=1){const y=c.time+(d-c.time)*m;po.push({name:g,time:y,weight:f}),s+=f}else l===0&&m<=0?(po.push({name:g,time:0,weight:1}),s+=1):l===n.length-1&&m>=1&&(po.push({name:g,time:i,weight:1}),s+=1)}}if(po.length<=0&&a<=0)e.time=t*i;else if(po.length>0){let l=po[0].time;if(po.length>1)for(const c of po){const h=c.weight/Math.max(1e-5,s),d=Math.abs(c.time-l);l+=d*h}this.damping<=0?e.time=l:e.time=I.lerp(e.time,l,this.context.time.deltaTime/this.damping),Nh&&this.context.time.frame%30===0&&console.log(`[ScrollFollow ] Timeline ${e.name}: ${l.toFixed(3)}`,po.map(c=>`[${c.name} ${(c.weight*100).toFixed(0)}%]`).join(", "))}}}jl([u([R,O])],Ko.prototype,"target"),jl([u()],Ko.prototype,"damping"),jl([u()],Ko.prototype,"invert"),jl([u()],Ko.prototype,"htmlSelector"),jl([u()],Ko.prototype,"mode"),jl([u(he)],Ko.prototype,"changed");const I1=new WeakMap,po=[],R0=new Array;let T0=!0;function L1(o){return T0?(T0=!1,R0.length=0,document.querySelectorAll("[data-timeline-marker]").forEach((e,t)=>{R0[t]=e}),T0=!1,L1(o)):R0[o]||null}function yI(o){if(!o.source)return 0;const e=o.currentTime,t=o.duration;let i=1;return(t.unit==="seconds"||t.unit==="percent")&&(i=t.value),e.unit==="seconds"?e.value/i:e.value/100}var j1=Object.defineProperty,bI=Object.getOwnPropertyDescriptor,_I=(o,e,t)=>e in o?j1(o,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[e]=t,Zp=(o,e,t,i)=>{for(var n=i>1?void 0:i?bI(e,t):e,s=o.length-1,r;s>=0;s--)(r=o[s])&&(n=(i?r(e,t,n):r(n))||n);return i&&n&&j1(e,t,n),n},E0=(o,e,t)=>_I(o,typeof e!="symbol"?e+"":e,t);const er=v("debugviewbox"),vI=new oe(.5,.5,.5,.5);let it=class extends R{referenceFieldOfView=-1;get mode(){return this._mode}set mode(o){o!==this._mode&&(this._mode=o,o==="once"&&(this._applyCount=0),(er||this.debug)&&console.debug("[ViewBox] Set mode:",o))}_mode="continuous";debug=!1;onEnable(){(er||this.debug||A())&&console.debug("[ViewBox] Using camera fov:",this.referenceFieldOfView),it.instances.push(this),this._applyCount=0,this.removeUpdateCallback(),this.context.pre_render_callbacks.push(this.internalUpdate)}onDisable(){(er||this.debug)&&console.debug("[ViewBox] Disabled");const o=it.instances.indexOf(this);o!==-1&&it.instances.splice(o,1),this._projectedBoxElement?.remove(),this.removeUpdateCallback()}removeUpdateCallback(){const o=this.context.pre_render_callbacks.indexOf(this.internalUpdate);o!==-1&&this.context.pre_render_callbacks.splice(o,1)}_applyCount=0;internalUpdate=()=>{if(this.context.isInXR||this.destroyed||!this.activeAndEnabled)return;if(it.instances[it.instances.length-1]!==this){(er||this.debug)&&B.DrawWireBox(this.gameObject.worldPosition,this.gameObject.worldScale,vI);return}(er||this.debug)&&B.DrawWireBox(this.gameObject.worldPosition,this.gameObject.worldScale,14540032,0,!0,this.gameObject.worldQuaternion);const o=this.context.mainCamera;if(!o||!(o instanceof re))return;if((this.referenceFieldOfView===void 0||this.referenceFieldOfView===-1)&&(this.referenceFieldOfView=o.fov,console.debug("[ViewBox] No referenceFieldOfView set, using camera fov:",this.referenceFieldOfView)),this.referenceFieldOfView===void 0||this.referenceFieldOfView<=0){(er||this.debug)&&console.warn("[ViewBox] No valid referenceFieldOfView set, cannot adjust box size:",this.referenceFieldOfView);return}if(this._applyCount>=1&&this.mode==="once")return;this._applyCount++;const e=this.context.domWidth,t=this.context.domHeight;let i=e,n=t,s=1,r=1;const a=this.context.focusRectSize;a&&(i=a.width,n=a.height,s=e/i,r=t/n),it._tempProjectionMatrix.copy(o.projectionMatrix),it._tempProjectionMatrixInverse.copy(o.projectionMatrixInverse);const l=o.view,c=o.zoom,h=o.aspect,d=o.fov;o.view=null,o.zoom=1,o.fov=this.referenceFieldOfView,o.updateProjectionMatrix();const p=this.gameObject.worldPosition,m=this.gameObject.worldScale,f=o.worldPosition,g=f.distanceTo(p),y=Math.max(m.x,m.y,m.z),_=D(f).sub(p);if(g<y){(this.debug||er)&&console.warn("[ViewBox] Moving camera out of bounds",g,"<",y);const ee=D(_);ee.y*=1e-8,ee.normalize();const E=y-g,H=f.add(ee.multiplyScalar(E));o.worldPosition=H.lerp(f,1-this.context.time.deltaTime)}const w=D(p);o.worldToLocal(w),o.lookAt(p),o.updateMatrixWorld();const P=this.referenceFieldOfView*Math.PI/180,M=2*Math.tan(P/2)*g,k=M*o.aspect,F=this.projectBoxIntoCamera(o,1),L=F.maxX-F.minX,z=F.maxY-F.minY,j=this.fit(L*o.aspect,z,k/s,M/r)/(M*.5),$=D(p);$.project(o),this.context.focusRectSettings.offsetX=$.x,this.context.focusRectSettings.offsetY=$.y,this.context.focusRectSettings.zoom=j,this.context.focusRect||this.context.setCameraFocusRect(this.context.domElement),o.view=l,o.zoom=c,o.aspect=h,o.fov=d,o.projectionMatrix.copy(it._tempProjectionMatrix),o.projectionMatrixInverse.copy(it._tempProjectionMatrixInverse)};fit(o,e,t,i){const n=t/o,s=i/e;return Math.min(n,s)}projectBoxIntoCamera(o,e){const t=.5*e,i=[D(-t,-t,-t),D(t,-t,-t),D(-t,t,-t),D(t,t,-t),D(-t,-t,t),D(t,-t,t),D(-t,t,t),D(t,t,t)];let n=Number.POSITIVE_INFINITY,s=Number.NEGATIVE_INFINITY,r=Number.POSITIVE_INFINITY,a=Number.NEGATIVE_INFINITY;for(let l=0;l<i.length;l++){const c=i[l];c.applyMatrix4(this.gameObject.matrixWorld),c.project(o),c.x<n&&(n=c.x),c.x>s&&(s=c.x),c.y<r&&(r=c.y),c.y>a&&(a=c.y)}return er&&(this._projectedBoxElement||(this._projectedBoxElement=document.createElement("div")),this._projectedBoxElement.parentElement!==this.context.domElement&&this.context.domElement.appendChild(this._projectedBoxElement),this._projectedBoxElement.style.position="fixed",this._projectedBoxElement.style.outline="2px dashed rgba(255,0,0,.5)",this._projectedBoxElement.style.left=(n*.5+.5)*this.context.domWidth+"px",this._projectedBoxElement.style.top=(-a*.5+.5)*this.context.domHeight+"px",this._projectedBoxElement.style.width=(s-n)*.5*this.context.domWidth+"px",this._projectedBoxElement.style.height=(a-r)*.5*this.context.domHeight+"px",this._projectedBoxElement.style.pointerEvents="none",this._projectedBoxElement.style.zIndex="1000"),{minX:n,maxX:s,minY:r,maxY:a}}_projectedBoxElement=null};E0(it,"instances",[]),E0(it,"_tempProjectionMatrix",new Z),E0(it,"_tempProjectionMatrixInverse",new Z),Zp([u()],it.prototype,"referenceFieldOfView",2),Zp([u()],it.prototype,"mode",1),Zp([u()],it.prototype,"debug",2),it=Zp([Fg],it);var wI=Object.defineProperty,Dl=(o,e,t,i)=>{for(var n=void 0,s=o.length-1,r;s>=0;s--)(r=o[s])&&(n=r(e,t,n)||n);return n&&wI(e,t,n),n};class Jo extends R{get activeAndEnabled(){return!0}side="none";controller=!0;hands=!1;controlVisibility=!0;useGripSpace=!1;resetTransformAfterXRSession=!0;_startPosition=new b;_startRotation=new N;_startScale=new b;onEnterXR(e){this._startPosition.copy(this.gameObject.position),this._startRotation.copy(this.gameObject.quaternion),this._startScale.copy(this.gameObject.scale)}onUpdateXR(e){if(!this.enabled)return;const t=e.xr.getController(this.side);if(t){if(t.hand&&!this.hands){this.controlVisibility&&(this.gameObject.visible=!1);return}else if(!this.controller){this.controlVisibility&&(this.gameObject.visible=!1);return}this.controlVisibility&&(this.gameObject.visible=!0),this.useGripSpace||t.targetRayMode==="transient-pointer"?(this.gameObject.worldPosition=t.gripWorldPosition,this.gameObject.worldQuaternion=t.gripWorldQuaternion,this.gameObject.worldScale=D(t.xr.rigScale,t.xr.rigScale,t.xr.rigScale).multiply(this._startScale)):(this.gameObject.worldPosition=t.rayWorldPosition,this.gameObject.worldQuaternion=t.rayWorldQuaternion,this.gameObject.worldScale=D(t.xr.rigScale,t.xr.rigScale,t.xr.rigScale).multiply(this._startScale))}}onLeaveXR(e){this.resetTransformAfterXRSession&&(this.gameObject.position.copy(this._startPosition),this.gameObject.quaternion.copy(this._startRotation),this.gameObject.scale.copy(this._startScale))}}Dl([u()],Jo.prototype,"side"),Dl([u()],Jo.prototype,"controller"),Dl([u()],Jo.prototype,"hands"),Dl([u()],Jo.prototype,"controlVisibility"),Dl([u()],Jo.prototype,"useGripSpace"),Dl([u()],Jo.prototype,"resetTransformAfterXRSession");function D1(o,e){const t=o.xr.getFrame();if(!t)return console.warn("No XRFrame available"),!1;const i=t.session.enabledFeatures;if(i&&!i.some(s=>s==="camera-access"))return console.error(`No camera feed available - please request the 'camera-access' feature before starting WebXR or add the ARCameraBackground component to your scene.
1430
+ */const lI={topLight:{intensity:500,position:[.418,16.199,.3]},room:{position:[-.757,13.219,.717],scale:[31.713,28.305,28.591]},boxes:[{position:[-10.906,2.009,1.846],rotation:-.195,scale:[2.328,7.905,4.651]},{position:[-5.607,-.754,-.758],rotation:.994,scale:[1.97,1.534,3.955]},{position:[6.167,.857,7.803],rotation:.561,scale:[3.927,6.285,3.687]},{position:[-2.017,.018,6.124],rotation:.333,scale:[2.002,4.566,2.064]},{position:[2.291,-.756,-2.621],rotation:-.286,scale:[1.546,1.552,1.496]},{position:[-2.193,-.369,-5.547],rotation:.516,scale:[3.875,3.487,2.986]}],lights:[{intensity:50,position:[-16.116,14.37,8.208],scale:[.1,2.428,2.739]},{intensity:50,position:[-16.109,18.021,-8.207],scale:[.1,2.425,2.751]},{intensity:17,position:[14.904,12.198,-1.832],scale:[.15,4.265,6.331]},{intensity:43,position:[-.462,8.89,14.52],scale:[4.38,5.441,.088]},{intensity:20,position:[3.235,11.486,-12.541],scale:[2.5,2,.1]},{intensity:100,position:[0,20,0],scale:[1,.1,1]}]},cI={topLight:{intensity:400,position:[.5,14,.5]},room:{position:[0,13.2,0],scale:[31.5,28.5,31.5]},boxes:[{position:[-10.906,-1,1.846],rotation:-.195,scale:[2.328,7.905,4.651]},{position:[-5.607,-.754,-.758],rotation:.994,scale:[1.97,1.534,3.955]},{position:[6.167,-.16,7.803],rotation:.561,scale:[3.927,6.285,3.687]},{position:[-2.017,.018,6.124],rotation:.333,scale:[2.002,4.566,2.064]},{position:[2.291,-.756,-2.621],rotation:-.286,scale:[1.546,1.552,1.496]},{position:[-2.193,-.369,-5.547],rotation:.516,scale:[3.875,3.487,2.986]}],lights:[{intensity:80,position:[-14,10,8],scale:[.1,2.5,2.5]},{intensity:80,position:[-14,14,-4],scale:[.1,2.5,2.5]},{intensity:23,position:[14,12,0],scale:[.1,5,5]},{intensity:16,position:[0,9,14],scale:[5,5,.1]},{intensity:80,position:[7,8,-14],scale:[2.5,2.5,.1]},{intensity:80,position:[-7,16,-14],scale:[2.5,2.5,.1]},{intensity:1,position:[0,20,0],scale:[.1,.1,.1]}]};class qp extends vi{constructor(e){super(),this.position.y=-3.5;const t=new Sa;t.deleteAttribute("uv");const i=new pt({metalness:0,side:Sd}),n=new pt({metalness:0}),s=e=="legacy"?lI:cI,r=new um(16777215,s.topLight.intensity,28,2);r.position.set(...s.topLight.position),this.add(r);const a=new G(t,i);a.position.set(...s.room.position),a.scale.set(...s.room.scale),this.add(a);for(const l of s.boxes){const c=new G(t,n);c.position.set(...l.position),c.rotation.set(0,l.rotation,0),c.scale.set(...l.scale),this.add(c)}for(const l of s.lights){const c=new G(t,this.createAreaLightMaterial(l.intensity));c.position.set(...l.position),c.scale.set(...l.scale),this.add(c)}}createAreaLightMaterial(e){const t=new xe;return t.color.setScalar(e),t}}var hI=Object.defineProperty,Xp=(o,e,t,i)=>{for(var n=void 0,s=o.length-1,r;s>=0;s--)(r=o[s])&&(n=r(e,t,n)||n);return n&&hI(e,t,n),n};const zh=class yS extends R{target;invertForward=!1;keepUpDirection=!0;copyTargetRotation=!1;static flipYQuat=new N().setFromAxisAngle(new b(0,1,0),Math.PI);onBeforeRender(){let e=this.target;if(e||(e=this.context.mainCamera,A()&&!this.__did_warn&&(this.__did_warn=!0,console.debug(`[LookAt] No target set on ${this.name}, using main camera as target.`))),!e)return;let t=this.copyTargetRotation;(this.context.isInVR||this.context.isInPassThrough)&&(t=!1),tc(this.gameObject,e,this.keepUpDirection,t),this.invertForward&&this.gameObject.quaternion.multiply(yS.flipYQuat)}createBehaviours(e,t,i){if(t.uuid===this.gameObject.uuid){let n=t;if(this.keepUpDirection){const r=nt.createEmptyParent(t);n=r;const a=this.invertForward?-1:1;r.setMatrix(r.getMatrix().multiply(new Z().makeRotationZ(Math.PI/2*a))),t.setMatrix(t.getMatrix().multiply(new Z().makeRotationZ(-Math.PI/2*a)))}const s=new At("lookat "+this.name,Ft.sceneStartTrigger(),ge.lookAtCameraAction(n,void 0,this.invertForward?pn.back:pn.forward,this.keepUpDirection?pn.up:pn.zero));e.addBehavior(s)}}};Xp([u(O)],zh.prototype,"target"),Xp([u()],zh.prototype,"invertForward"),Xp([u()],zh.prototype,"keepUpDirection"),Xp([u()],zh.prototype,"copyTargetRotation");let O0=zh;var dI=Object.defineProperty,k0=(o,e,t,i)=>{for(var n=void 0,s=o.length-1,r;s>=0;s--)(r=o[s])&&(n=r(e,t,n)||n);return n&&dI(e,t,n),n};class Il extends R{url;mode=0;clickable=!0;async open(){if(!this.url){console.warn("OpenURL: URL is not set, can't open.",this);return}this._validateUrl();let e=this.url;switch(!e.startsWith("mailto:")&&e.includes("@")&&(e="mailto:"+e),A()&&Ee("Open URL: "+e),this.mode){case 0:q.isSafari(),globalThis.open(e,"_blank");break;case 1:q.isSafari()&&q.isiOS()?globalThis.open(e,"_top"):globalThis.open(e,"_self");break;case 2:q.isSafari()?globalThis.open(e,"_top"):globalThis.open(e,"_new");break}}start(){this.gameObject.getComponentInParent(Ti)||this.gameObject.addComponent(Ti)}onPointerEnter(e){!e.used&&this.clickable&&this.context.input.setCursor("pointer")}onPointerExit(){this.clickable&&this.context.input.unsetCursor("pointer")}onPointerClick(e){this.clickable&&!e.used&&this.url?.length&&this.open()}_validateUrl(){this.url&&this.url.startsWith("www.")&&(A()&&console.warn("URL is not valid, adding https:// to the start of the URL",this.url),this.url="https://"+this.url)}}k0([u()],Il.prototype,"url"),k0([u()],Il.prototype,"mode"),k0([u()],Il.prototype,"clickable"),xu(o=>{const e=o.domElement.getAttribute("clickthrough");if(t(e)){const i=o.scene.addComponent(Qp);Dm(o.domElement,"clickthrough",()=>{const n=o.domElement.getAttribute("clickthrough");i.enabled=t(n)})}function t(i){return i!==null&&i!=="0"&&i!=="false"}});class Qp extends R{_previousPointerEvents="all";onEnable(){this.context.input.addEventListener("pointerdown",this.onPointerEvent),this.context.input.addEventListener("pointermove",this.onPointerEvent,{queue:100}),window.addEventListener("touchstart",this.onTouchStart,{passive:!0}),window.addEventListener("touchend",this.onTouchEnd,{passive:!0}),this._previousPointerEvents=this.context.domElement.style.pointerEvents}onDisable(){this.context.input.removeEventListener("pointerdown",this.onPointerEvent),this.context.input.removeEventListener("pointermove",this.onPointerEvent),window.removeEventListener("touchstart",this.onTouchStart),window.removeEventListener("touchend",this.onTouchEnd),this.context.domElement.style.pointerEvents=this._previousPointerEvents}onPointerEnter(){}onPointerEvent=e=>{e.pointerId>0||(e.intersections?.length<=0?this.context.domElement.style.pointerEvents="none":this.context.domElement.style.pointerEvents="all")};_touchDidHitAnything=!1;onTouchStart=e=>{const t=e.touches[0];if(!t)return;const i=t.clientX/window.innerWidth*2-1,n=-(t.clientY/window.innerHeight)*2+1;this.context.physics.raycast({screenPoint:new J(i,n)}).length>0&&(this._touchDidHitAnything=!0)};onTouchEnd=e=>{const t=this._touchDidHitAnything;this._touchDidHitAnything=!1,setTimeout(()=>{t&&(this.context.domElement.style.pointerEvents="all")},100)}}var uI=Object.defineProperty,Yp=(o,e,t,i)=>{for(var n=void 0,s=o.length-1,r;s>=0;s--)(r=o[s])&&(n=r(e,t,n)||n);return n&&uI(e,t,n),n};const pI=v("debugcursor");class ua extends R{damping=0;useFullPage=!0;keepDistance=!0;snapToSurface=!1;_distance=-1;updateDistance(e=!1){!e&&this.keepDistance&&this._distance!==-1||(this._distance=this.gameObject.worldPosition.distanceTo(this.context.mainCamera.worldPosition))}awake(){this._distance=-1}onEnable(){this._distance=-1,window.addEventListener("pointermove",this._onPointerMove)}onDisable(){window.removeEventListener("pointermove",this._onPointerMove)}_ndc_x=0;_ndc_y=0;_onPointerMove=e=>{if(!this.useFullPage)return;const t=e.clientX,i=e.clientY,n=this.context.domX,s=this.context.domY,r=this.context.domWidth,a=this.context.domHeight;this._ndc_x=(t-n)/r*2-1,this._ndc_y=-(i-s)/a*2+1};lateUpdate(){this.updateDistance();const e=this.useFullPage?this._ndc_x:this.context.input.mousePositionRC.x,t=this.useFullPage?this._ndc_y:this.context.input.mousePositionRC.y,i=this.context.mainCamera,n=i.worldPosition,s=D(e,t,1).unproject(i);s.sub(n).normalize();const r=D(s).multiplyScalar(this._distance).add(n);let a=r;if(this.damping>0){const l=this.gameObject.worldPosition;l.lerp(r,this.context.time.deltaTime/this.damping),this.gameObject.worldPosition=l,a=l}else this.gameObject.worldPosition=r;if(this.snapToSurface){M0.origin=a,M0.direction=s.multiplyScalar(-1);const l=this.context.physics.raycastFromRay(M0);if(l?.length){const c=l[0];this.damping>0?this.gameObject.worldPosition=a.lerp(c.point,this.context.time.deltaTime/this.damping):this.gameObject.worldPosition=c.point,pI&&B.DrawLine(c.point,c.normal.add(c.point),65280)}}}}Yp([u()],ua.prototype,"damping"),Yp([u()],ua.prototype,"useFullPage"),Yp([u()],ua.prototype,"keepDistance"),Yp([u()],ua.prototype,"snapToSurface");const M0=new yo;var mI=Object.defineProperty,gI=Object.getOwnPropertyDescriptor,Ll=(o,e,t,i)=>{for(var n=i>1?void 0:i?gI(e,t):e,s=o.length-1,r;s>=0;s--)(r=o[s])&&(n=(i?r(e,t,n):r(n))||n);return i&&n&&mI(e,t,n),n};let uo=class extends R{type="linear";duration=.1;scaleFactor=1.1;hovered=null;idle=null;animation=null;start(){this.idle||(this.idle=_s.emptyClip()),(!this.hovered||!(this.hovered instanceof Ci))&&(this.hovered=_s.createScaleClip({type:"linear",duration:this.duration||.1,scale:this.gameObject.scale,scaleFactor:this.scaleFactor||1.1})),this.animation??=this.gameObject.addComponent(jt),this.animation.playAutomatically=!1,this.playIdle()}onEnable(){this.animation&&(this.animation.enabled=!0),this.playIdle()}onDisable(){this.animation&&(this.animation.enabled=!1),this.playIdle()}onPointerEnter(){this.playHover()}onPointerExit(){this.playIdle()}playIdle(){this.idle&&this.animation?.play(this.idle,{exclusive:!0,fadeDuration:.1,loop:!0})}playHover(){this.hovered&&this.animation?.play(this.hovered,{exclusive:!0,fadeDuration:.1,loop:!1,clampWhenFinished:!0})}};Ll([u()],uo.prototype,"type",2),Ll([u()],uo.prototype,"duration",2),Ll([u()],uo.prototype,"scaleFactor",2),Ll([u(Ci)],uo.prototype,"hovered",2),Ll([u(Ci)],uo.prototype,"idle",2),uo=Ll([Fg],uo);var fI=Object.defineProperty,jl=(o,e,t,i)=>{for(var n=void 0,s=o.length-1,r;s>=0;s--)(r=o[s])&&(n=r(e,t,n)||n);return n&&fI(e,t,n),n};const Nh=v("debugscroll");class Ko extends R{target=null;damping=0;invert=!1;htmlSelector=null;mode="window";changed=new he;get currentValue(){return this._current_value}_current_value=0;_target_value=0;_appliedValue=-1;_needsUpdate=!1;_firstUpdate=!1;awake(){this._firstUpdate=!0}onEnable(){window.addEventListener("wheel",this.updateCurrentScrollValue,{passive:!0}),this._appliedValue=-1,this._needsUpdate=!0}onDisable(){window.removeEventListener("wheel",this.updateCurrentScrollValue)}lateUpdate(){if(this.updateCurrentScrollValue(),this._target_value>=0&&(this.damping>0&&!this._firstUpdate?(this._current_value=I.lerp(this._current_value,this._target_value,this.context.time.deltaTime/this.damping),Math.abs(this._current_value-this._target_value)<.001&&(this._current_value=this._target_value)):this._current_value=this._target_value),this._needsUpdate||this._current_value!==this._appliedValue){this._appliedValue=this._current_value,this._needsUpdate=!1;let e=!1;if(this.changed.listenerCount>0){const t={type:"change",value:this._current_value,component:this,preventDefault:()=>{t.defaultPrevented=!0},defaultPrevented:!1};this.changed.invoke(t),e=t.defaultPrevented}if(!e){const t=this.invert?1-this._current_value:this._current_value;Array.isArray(this.target)?this.target.forEach(i=>i&&this.applyScroll(i,t)):this.target&&this.applyScroll(this.target,t),Nh&&this.context.time.frame%30===0&&console.debug(`[ScrollFollow] ${this._current_value.toFixed(5)} \u2014 ${(this._target_value*100).toFixed(0)}%, targets [${Array.isArray(this.target)?this.target.length:1}]`)}this._firstUpdate=!1}}_lastSelectorValue=null;_lastSelectorElement=null;updateCurrentScrollValue=()=>{switch(this.mode){case"window":if(this.htmlSelector?.length){if(this.htmlSelector!==this._lastSelectorValue&&(this._lastSelectorElement=document.querySelector(this.htmlSelector),this._lastSelectorValue=this.htmlSelector),this._lastSelectorElement){const e=this._lastSelectorElement.getBoundingClientRect();this._target_value=-e.top/(e.height-window.innerHeight);break}}else if(!(window.document.body.scrollHeight<=window.innerHeight)){const e=window.document.body.scrollHeight-window.innerHeight;this._target_value=window.scrollY/(e||1)}break}(isNaN(this._target_value)||!isFinite(this._target_value))&&(this._target_value=-1)};applyScroll(e,t){if(e)if(e instanceof ca)this.handleTimelineTarget(e,t),e.isPlaying&&e.pause(),e.evaluate();else if(e instanceof yt)e.setFloat("scroll",t);else if(e instanceof jt)e.time=t*e.duration;else if(e instanceof Ei){if(!e.duration)return;e.time=t*e.duration}else if(e instanceof an)e.position01=t;else if(e instanceof mi)e.intensity=t;else if(e instanceof O){const i=e;i["needle:scrollbounds"]===void 0&&(i["needle:scrollbounds"]=Gt(e)||null);const n=i["needle:scrollbounds"];n&&(e.position.y=-n.min.y-t*(n.max.y-n.min.y))}else"scroll"in e&&(typeof e.scroll=="number"?e.scroll=t:typeof e.scroll=="function"&&e.scroll(t))}handleTimelineTarget(e,t){const i=e.duration;let n=I1.get(e);if(!n){n=[],I1.set(e,n);let l=0;for(const c of e.foreachMarker("ScrollMarker")){const h=l++;if(c.element===void 0||c.needsUpdate===!0||c.element&&!c.element?.parentNode){c.needsUpdate=!1;try{if(c.element=L1(h),Nh&&console.debug(`ScrollMarker #${h} (${c.time.toFixed(2)}) found`,c.element),!c.element){(Nh||A())&&console.warn(`No HTML element found for ScrollMarker: ${c.name} (index ${h})`);continue}}catch(d){c.element=null,console.error("ScrollMarker selector is not valid: "+c.name+`
1431
+ `,d)}}c.element&&n.push(c)}n.length<=0&&document.querySelectorAll("[data-timeline-marker]").forEach(c=>{const h=c.getAttribute("data-timeline-marker"),d=parseFloat(h||"NaN");isNaN(d)?(A()||Nh)&&console.warn('[ScrollFollow] data-timeline-marker attribute is not a valid number. Supported are numbers only (e.g. <div data-timeline-marker="0.5">)'):n.push({time:d,element:c})});for(const c of n)c.element&&(c.timeline=new ViewTimeline({subject:c.element,axis:"block"}))}po.length=0;let s=0;const r=1/60;let a=0;for(let l=0;l<n.length;l++){const c=n[l];if(!c.element)continue;const h=n[l+1],d=h?h.time-r:i;a+=1;const p=c.timeline;if(p){const m=yI(p),f=1-Math.abs(m-.5)*2,g=`marker${l}`;if(m>0&&m<=1){const y=c.time+(d-c.time)*m;po.push({name:g,time:y,weight:f}),s+=f}else l===0&&m<=0?(po.push({name:g,time:0,weight:1}),s+=1):l===n.length-1&&m>=1&&(po.push({name:g,time:i,weight:1}),s+=1)}}if(po.length<=0&&a<=0)e.time=t*i;else if(po.length>0){let l=po[0].time;if(po.length>1)for(const c of po){const h=c.weight/Math.max(1e-5,s),d=Math.abs(c.time-l);l+=d*h}this.damping<=0||this._firstUpdate?e.time=l:e.time=I.lerp(e.time,l,this.context.time.deltaTime/this.damping),Math.abs(e.time-l)>.001&&(this._needsUpdate=!0),Nh&&this.context.time.frame%30===0&&console.log(`[ScrollFollow ] Timeline ${e.name}: ${l.toFixed(3)}`,po.map(c=>`[${c.name} ${(c.weight*100).toFixed(0)}%]`).join(", "))}}}jl([u([R,O])],Ko.prototype,"target"),jl([u()],Ko.prototype,"damping"),jl([u()],Ko.prototype,"invert"),jl([u()],Ko.prototype,"htmlSelector"),jl([u()],Ko.prototype,"mode"),jl([u(he)],Ko.prototype,"changed");const I1=new WeakMap,po=[],R0=new Array;let T0=!0;function L1(o){return T0?(T0=!1,R0.length=0,document.querySelectorAll("[data-timeline-marker]").forEach((e,t)=>{R0[t]=e}),T0=!1,L1(o)):R0[o]||null}function yI(o){if(!o.source)return 0;const e=o.currentTime,t=o.duration;let i=1;return(t.unit==="seconds"||t.unit==="percent")&&(i=t.value),e.unit==="seconds"?e.value/i:e.value/100}var j1=Object.defineProperty,bI=Object.getOwnPropertyDescriptor,_I=(o,e,t)=>e in o?j1(o,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[e]=t,Zp=(o,e,t,i)=>{for(var n=i>1?void 0:i?bI(e,t):e,s=o.length-1,r;s>=0;s--)(r=o[s])&&(n=(i?r(e,t,n):r(n))||n);return i&&n&&j1(e,t,n),n},E0=(o,e,t)=>_I(o,typeof e!="symbol"?e+"":e,t);const er=v("debugviewbox"),vI=new oe(.5,.5,.5,.5);let it=class extends R{referenceFieldOfView=-1;get mode(){return this._mode}set mode(o){o!==this._mode&&(this._mode=o,o==="once"&&(this._applyCount=0),(er||this.debug)&&console.debug("[ViewBox] Set mode:",o))}_mode="continuous";debug=!1;onEnable(){(er||this.debug||A())&&console.debug("[ViewBox] Using camera fov:",this.referenceFieldOfView),it.instances.push(this),this._applyCount=0,this.removeUpdateCallback(),this.context.pre_render_callbacks.push(this.internalUpdate)}onDisable(){(er||this.debug)&&console.debug("[ViewBox] Disabled");const o=it.instances.indexOf(this);o!==-1&&it.instances.splice(o,1),this._projectedBoxElement?.remove(),this.removeUpdateCallback()}removeUpdateCallback(){const o=this.context.pre_render_callbacks.indexOf(this.internalUpdate);o!==-1&&this.context.pre_render_callbacks.splice(o,1)}_applyCount=0;internalUpdate=()=>{if(this.context.isInXR||this.destroyed||!this.activeAndEnabled)return;if(it.instances[it.instances.length-1]!==this){(er||this.debug)&&B.DrawWireBox(this.gameObject.worldPosition,this.gameObject.worldScale,vI);return}(er||this.debug)&&B.DrawWireBox(this.gameObject.worldPosition,this.gameObject.worldScale,14540032,0,!0,this.gameObject.worldQuaternion);const o=this.context.mainCamera;if(!o||!(o instanceof re))return;if((this.referenceFieldOfView===void 0||this.referenceFieldOfView===-1)&&(this.referenceFieldOfView=o.fov,console.debug("[ViewBox] No referenceFieldOfView set, using camera fov:",this.referenceFieldOfView)),this.referenceFieldOfView===void 0||this.referenceFieldOfView<=0){(er||this.debug)&&console.warn("[ViewBox] No valid referenceFieldOfView set, cannot adjust box size:",this.referenceFieldOfView);return}if(this._applyCount>=1&&this.mode==="once")return;this._applyCount++;const e=this.context.domWidth,t=this.context.domHeight;let i=e,n=t,s=1,r=1;const a=this.context.focusRectSize;a&&(i=a.width,n=a.height,s=e/i,r=t/n),it._tempProjectionMatrix.copy(o.projectionMatrix),it._tempProjectionMatrixInverse.copy(o.projectionMatrixInverse);const l=o.view,c=o.zoom,h=o.aspect,d=o.fov;o.view=null,o.zoom=1,o.fov=this.referenceFieldOfView,o.updateProjectionMatrix();const p=this.gameObject.worldPosition,m=this.gameObject.worldScale,f=o.worldPosition,g=f.distanceTo(p),y=Math.max(m.x,m.y,m.z),_=D(f).sub(p);if(g<y){(this.debug||er)&&console.warn("[ViewBox] Moving camera out of bounds",g,"<",y);const ee=D(_);ee.y*=1e-8,ee.normalize();const E=y-g,H=f.add(ee.multiplyScalar(E));o.worldPosition=H.lerp(f,1-this.context.time.deltaTime)}const w=D(p);o.worldToLocal(w),o.lookAt(p),o.updateMatrixWorld();const P=this.referenceFieldOfView*Math.PI/180,M=2*Math.tan(P/2)*g,k=M*o.aspect,F=this.projectBoxIntoCamera(o,1),L=F.maxX-F.minX,z=F.maxY-F.minY,j=this.fit(L*o.aspect,z,k/s,M/r)/(M*.5),$=D(p);$.project(o),this.context.focusRectSettings.offsetX=$.x,this.context.focusRectSettings.offsetY=$.y,this.context.focusRectSettings.zoom=j,this.context.focusRect||this.context.setCameraFocusRect(this.context.domElement),o.view=l,o.zoom=c,o.aspect=h,o.fov=d,o.projectionMatrix.copy(it._tempProjectionMatrix),o.projectionMatrixInverse.copy(it._tempProjectionMatrixInverse)};fit(o,e,t,i){const n=t/o,s=i/e;return Math.min(n,s)}projectBoxIntoCamera(o,e){const t=.5*e,i=[D(-t,-t,-t),D(t,-t,-t),D(-t,t,-t),D(t,t,-t),D(-t,-t,t),D(t,-t,t),D(-t,t,t),D(t,t,t)];let n=Number.POSITIVE_INFINITY,s=Number.NEGATIVE_INFINITY,r=Number.POSITIVE_INFINITY,a=Number.NEGATIVE_INFINITY;for(let l=0;l<i.length;l++){const c=i[l];c.applyMatrix4(this.gameObject.matrixWorld),c.project(o),c.x<n&&(n=c.x),c.x>s&&(s=c.x),c.y<r&&(r=c.y),c.y>a&&(a=c.y)}return er&&(this._projectedBoxElement||(this._projectedBoxElement=document.createElement("div")),this._projectedBoxElement.parentElement!==this.context.domElement&&this.context.domElement.appendChild(this._projectedBoxElement),this._projectedBoxElement.style.position="fixed",this._projectedBoxElement.style.outline="2px dashed rgba(255,0,0,.5)",this._projectedBoxElement.style.left=(n*.5+.5)*this.context.domWidth+"px",this._projectedBoxElement.style.top=(-a*.5+.5)*this.context.domHeight+"px",this._projectedBoxElement.style.width=(s-n)*.5*this.context.domWidth+"px",this._projectedBoxElement.style.height=(a-r)*.5*this.context.domHeight+"px",this._projectedBoxElement.style.pointerEvents="none",this._projectedBoxElement.style.zIndex="1000"),{minX:n,maxX:s,minY:r,maxY:a}}_projectedBoxElement=null};E0(it,"instances",[]),E0(it,"_tempProjectionMatrix",new Z),E0(it,"_tempProjectionMatrixInverse",new Z),Zp([u()],it.prototype,"referenceFieldOfView",2),Zp([u()],it.prototype,"mode",1),Zp([u()],it.prototype,"debug",2),it=Zp([Fg],it);var wI=Object.defineProperty,Dl=(o,e,t,i)=>{for(var n=void 0,s=o.length-1,r;s>=0;s--)(r=o[s])&&(n=r(e,t,n)||n);return n&&wI(e,t,n),n};class Jo extends R{get activeAndEnabled(){return!0}side="none";controller=!0;hands=!1;controlVisibility=!0;useGripSpace=!1;resetTransformAfterXRSession=!0;_startPosition=new b;_startRotation=new N;_startScale=new b;onEnterXR(e){this._startPosition.copy(this.gameObject.position),this._startRotation.copy(this.gameObject.quaternion),this._startScale.copy(this.gameObject.scale)}onUpdateXR(e){if(!this.enabled)return;const t=e.xr.getController(this.side);if(t){if(t.hand&&!this.hands){this.controlVisibility&&(this.gameObject.visible=!1);return}else if(!this.controller){this.controlVisibility&&(this.gameObject.visible=!1);return}this.controlVisibility&&(this.gameObject.visible=!0),this.useGripSpace||t.targetRayMode==="transient-pointer"?(this.gameObject.worldPosition=t.gripWorldPosition,this.gameObject.worldQuaternion=t.gripWorldQuaternion,this.gameObject.worldScale=D(t.xr.rigScale,t.xr.rigScale,t.xr.rigScale).multiply(this._startScale)):(this.gameObject.worldPosition=t.rayWorldPosition,this.gameObject.worldQuaternion=t.rayWorldQuaternion,this.gameObject.worldScale=D(t.xr.rigScale,t.xr.rigScale,t.xr.rigScale).multiply(this._startScale))}}onLeaveXR(e){this.resetTransformAfterXRSession&&(this.gameObject.position.copy(this._startPosition),this.gameObject.quaternion.copy(this._startRotation),this.gameObject.scale.copy(this._startScale))}}Dl([u()],Jo.prototype,"side"),Dl([u()],Jo.prototype,"controller"),Dl([u()],Jo.prototype,"hands"),Dl([u()],Jo.prototype,"controlVisibility"),Dl([u()],Jo.prototype,"useGripSpace"),Dl([u()],Jo.prototype,"resetTransformAfterXRSession");function D1(o,e){const t=o.xr.getFrame();if(!t)return console.warn("No XRFrame available"),!1;const i=t.session.enabledFeatures;if(i&&!i.some(s=>s==="camera-access"))return console.error(`No camera feed available - please request the 'camera-access' feature before starting WebXR or add the ARCameraBackground component to your scene.
1432
1432
 
1433
1433
  Example to request camera-access in global scope:
1434
1434
  NeedleXRSession.onSessionRequestStart(evt => {