xrblocks 0.2.0 → 0.3.0

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.
Files changed (64) hide show
  1. package/README.md +25 -9
  2. package/build/addons/ai/AudioCaptureProcessorCode.d.ts +1 -0
  3. package/build/addons/ai/AudioCaptureProcessorCode.js +27 -0
  4. package/build/addons/ai/GeminiManager.d.ts +7 -3
  5. package/build/addons/ai/GeminiManager.js +48 -23
  6. package/build/addons/objects/SimpleDecalGeometry.js +9 -5
  7. package/build/addons/simulator/instructions/CustomInstruction.js +8 -9
  8. package/build/addons/simulator/instructions/HandsInstructions.js +17 -10
  9. package/build/addons/simulator/instructions/NavigationInstructions.js +10 -9
  10. package/build/addons/simulator/instructions/SimulatorInstructions.js +17 -18
  11. package/build/addons/simulator/instructions/SimulatorInstructionsCard.js +69 -75
  12. package/build/addons/simulator/instructions/SimulatorInstructionsEvents.js +4 -1
  13. package/build/addons/simulator/instructions/UserInstructions.js +18 -15
  14. package/build/addons/simulator/ui/EnterXRButton.js +17 -17
  15. package/build/addons/simulator/ui/GeminiLiveApiKeyInput.js +45 -39
  16. package/build/addons/simulator/ui/HandPosePanel.js +20 -10
  17. package/build/addons/simulator/ui/MicButton.js +23 -18
  18. package/build/addons/simulator/ui/ModeIndicator.js +17 -17
  19. package/build/addons/ui/TextBillboard.js +1 -1
  20. package/build/addons/utils/Palette.js +3 -15
  21. package/build/addons/virtualkeyboard/Keyboard.js +24 -21
  22. package/build/addons/volumes/VolumetricCloud.glsl.js +1 -1
  23. package/build/addons/volumes/VolumetricCloud.js +8 -5
  24. package/build/agent/Tool.d.ts +3 -1
  25. package/build/ai/AI.d.ts +2 -2
  26. package/build/ai/Gemini.d.ts +1 -5
  27. package/build/camera/XRDeviceCamera.d.ts +1 -1
  28. package/build/core/Core.d.ts +3 -1
  29. package/build/core/Options.d.ts +7 -0
  30. package/build/core/components/ScreenshotSynthesizer.d.ts +2 -2
  31. package/build/core/components/XRTransition.d.ts +1 -1
  32. package/build/depth/DepthMesh.d.ts +1 -1
  33. package/build/input/Hands.d.ts +1 -1
  34. package/build/input/Input.d.ts +1 -1
  35. package/build/input/gestures/GestureEvents.d.ts +23 -0
  36. package/build/input/gestures/GestureRecognition.d.ts +43 -0
  37. package/build/input/gestures/GestureRecognitionOptions.d.ts +43 -0
  38. package/build/input/gestures/GestureTypes.d.ts +16 -0
  39. package/build/input/gestures/providers/HeuristicGestureDetectors.d.ts +2 -0
  40. package/build/simulator/Simulator.d.ts +2 -0
  41. package/build/simulator/SimulatorControls.d.ts +1 -1
  42. package/build/simulator/controlModes/SimulatorControlMode.d.ts +1 -1
  43. package/build/simulator/handPoses/HandPoseJoints.d.ts +2 -2
  44. package/build/simulator/userActions/PinchOnButtonAction.d.ts +2 -2
  45. package/build/simulator/userActions/WalkTowardsPanelAction.d.ts +1 -1
  46. package/build/singletons.d.ts +2 -2
  47. package/build/sound/CoreSound.d.ts +1 -1
  48. package/build/stereo/utils.d.ts +1 -1
  49. package/build/ui/components/MaterialSymbolsView.d.ts +1 -1
  50. package/build/ui/components/ScrollingTroikaTextView.d.ts +1 -1
  51. package/build/ui/interaction/ModelViewer.d.ts +6 -2
  52. package/build/utils/ModelLoader.d.ts +1 -1
  53. package/build/utils/SparkRendererHolder.d.ts +5 -0
  54. package/build/utils/Types.d.ts +2 -2
  55. package/build/video/VideoStream.d.ts +1 -1
  56. package/build/world/World.d.ts +1 -1
  57. package/build/world/objects/ObjectDetector.d.ts +1 -1
  58. package/build/world/planes/PlaneDetector.d.ts +1 -1
  59. package/build/xrblocks.d.ts +3 -0
  60. package/build/xrblocks.js +6782 -6020
  61. package/build/xrblocks.js.map +1 -1
  62. package/build/xrblocks.min.js +1 -1
  63. package/build/xrblocks.min.js.map +1 -1
  64. package/package.json +13 -8
@@ -1,2 +1,2 @@
1
- import*as e from"three";import{Pass as t,FullScreenQuad as i}from"three/addons/postprocessing/Pass.js";import{XRControllerModelFactory as s}from"three/addons/webxr/XRControllerModelFactory.js";import{XRHandModelFactory as n}from"three/addons/webxr/XRHandModelFactory.js";import{XREstimatedLight as r}from"three/addons/webxr/XREstimatedLight.js";import{GLTFLoader as o}from"three/addons/loaders/GLTFLoader.js";import{SVGLoader as a}from"three/addons/loaders/SVGLoader.js";import{DRACOLoader as h}from"three/addons/loaders/DRACOLoader.js";import{KTX2Loader as l}from"three/addons/loaders/KTX2Loader.js";import*as c from"three/addons/utils/BufferGeometryUtils.js";class d{constructor(e="You are a helpful assistant."){this.instructions=e}get instruction(){return this.instructions}build(e,t){const i=e.getShortTerm().map((e=>this.formatEntry(e))).join("\n"),s=t.map((e=>`- ${e.name}: ${e.description}`)).join("\n");return`${this.instructions} You have access to the following tools: ${s}\n Current Conversation history: ${i}. You should reply to the user or call a tool as needed.`}formatEntry(e){switch(e.role){case"user":return`User: ${e.content}`;case"ai":return`AI: ${e.content}`;case"tool":return`Tool Output: ${e.content}`}}}class u{constructor(){this.shortTermMemory=[]}addShortTerm(e){this.shortTermMemory.push(e)}getShortTerm(){return[...this.shortTermMemory]}clear(){this.shortTermMemory.length=0}}class p{static{this.dependencies={}}constructor(e,t=[],i="",s){this.isSessionActive=!1,this.ai=e,this.tools=t,this.memory=new u,this.contextBuilder=new d(i),this.lifecycleCallbacks=s}async start(e){return this.memory.addShortTerm({role:"user",content:e}),this.ai.isAvailable()||await this.ai.init({aiOptions:this.ai.options}),this.run()}async run(){for(;;){const e=this.contextBuilder.build(this.memory,this.tools),t=await this.ai.model.query({type:"text",text:e},this.tools);if(this.memory.addShortTerm({role:"ai",content:JSON.stringify(t)}),!t?.toolCall){if(t?.text)return console.log(`Final Response: ${t.text}`),t.text;{const e="The AI did not provide a valid response.";return console.error(e),e}}{console.log(`Executing tool: ${t.toolCall.name}`);const e=this.findTool(t.toolCall.name);if(e){const i=await e.execute(t.toolCall.args);this.memory.addShortTerm({role:"tool",content:JSON.stringify(i)})}else{const e=`Error: Tool "${t.toolCall.name}" not found.`;console.error(e),this.memory.addShortTerm({role:"tool",content:e})}}}}findTool(e){return this.tools.find((t=>t.name===e))}getSessionState(){return{isActive:this.isSessionActive,toolCount:this.tools.length,memorySize:this.memory.getShortTerm?.()?.length||0}}}class g{constructor(e){this.name=e.name,this.description=e.description,this.parameters=e.parameters||{},this.onTriggered=e.onTriggered}async execute(e){try{if(this.onTriggered){return{success:!0,data:await Promise.resolve(this.onTriggered(e)),metadata:{executedAt:Date.now(),toolName:this.name}}}throw new Error("The execute method must be implemented by a subclass or onTriggered must be provided.")}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e),metadata:{executedAt:Date.now(),toolName:this.name}}}}toJSON(){const e={name:this.name};return this.description&&(e.description=this.description),this.parameters&&(e.parameters=this.parameters),e}}class m extends g{constructor(e,t){super({name:"generateSkybox",description:"Generate a 360 equirectangular skybox image for the given prompt.",parameters:{type:"OBJECT",properties:{prompt:{type:"STRING",description:'A description of the skybox to generate, e.g. "a sunny beach with palm trees"'}},required:["prompt"]}}),this.ai=e,this.scene=t}async execute(t){try{const i=await this.ai.generate("Generate a 360 equirectangular skybox image for the prompt of:"+t.prompt,"image","Generate a 360 equirectangular skybox image for the prompt","gemini-2.5-flash-image-preview");return i?(console.log("Applying texture..."),this.scene.background=(new e.TextureLoader).load(i),this.scene.background.mapping=e.EquirectangularReflectionMapping,{success:!0,data:"Skybox generated successfully.",metadata:{prompt:t.prompt,timestamp:Date.now()}}):{success:!1,error:"Failed to generate skybox image",metadata:{prompt:t.prompt,timestamp:Date.now()}}}catch(e){return console.error("error:",e),{success:!1,error:e instanceof Error?e.message:"Unknown error while creating skybox",metadata:{prompt:t.prompt,timestamp:Date.now()}}}}}class f extends p{constructor(e,t,i,s){super(e,[new m(e,i)],"You are a friendly and helpful skybox designer. The response should be short. Your only capability\n is to generate a 360-degree equirectangular skybox image based on\n a user's description. You will generate a default skybox if the user\n does not provide any description. You will use the tool 'generateSkybox'\n with the summarized description as the 'prompt' argument to create the skybox.",s),this.sound=t,this.sessionState={isActive:!1,messageCount:0,toolCallCount:0}}async startLiveSession(e){const t=this.wrapCallbacks(e);e&&this.ai.setLiveCallbacks(t);const i=this.tools.map((e=>e.toJSON())),s={parts:[{text:this.contextBuilder.instruction}]};await this.ai.startLiveSession({tools:i,systemInstruction:s}),this.sessionState.isActive=!0,this.sessionState.startTime=Date.now(),this.isSessionActive=!0,await(this.lifecycleCallbacks?.onSessionStart?.())}async stopLiveSession(){await this.ai.stopLiveSession(),this.sessionState.isActive=!1,this.sessionState.endTime=Date.now(),this.isSessionActive=!1,await(this.lifecycleCallbacks?.onSessionEnd?.())}wrapCallbacks(e){return{onopen:()=>{e?.onopen?.()},onmessage:t=>{this.sessionState.messageCount++,e?.onmessage?.(t)},onerror:t=>{this.sessionState.lastError=t.message,this.lifecycleCallbacks?.onError?.(new Error(t.message)),e?.onerror?.(t)},onclose:t=>{this.sessionState.isActive=!1,this.sessionState.endTime=Date.now(),this.isSessionActive=!1,e?.onclose?.(t)}}}async sendToolResponse(e){if(!this.validateToolResponse(e))return void console.error("Invalid tool response format:",e);const t=Array.isArray(e.functionResponses)?e.functionResponses:[e.functionResponses];this.sessionState.toolCallCount+=t.length,console.log("Sending tool response:",e),this.ai.sendToolResponse(e)}validateToolResponse(e){if(!e.functionResponses)return!1;return(Array.isArray(e.functionResponses)?e.functionResponses:[e.functionResponses]).every((e=>e.id&&e.name&&void 0!==e.response))}static createToolResponse(e,t,i){return{id:e,name:t,response:i.success?{result:i.data}:{error:i.error}}}getLiveSessionState(){return{...this.sessionState}}getSessionDuration(){if(!this.sessionState.startTime)return null;return(this.sessionState.endTime||Date.now())-this.sessionState.startTime}}class v extends g{constructor(){super({name:"get_weather",description:"Gets the current weather for a specific location.",parameters:{type:"OBJECT",properties:{location:{type:"STRING",description:"The city and state, e.g. San Francisco, CA"},unit:{type:"STRING",enum:["celsius","fahrenheit"]}},required:["location"]}})}async execute(e){e.latitude&&e.longitude||(e.latitude=37.7749,e.longitude=-122.4194);const t=`https://api.open-meteo.com/v1/forecast?latitude=${e.latitude}&longitude=${e.longitude}&current=weather_code,temperature_2m&temperature_unit=fahrenheit`;try{const i=await fetch(t),s=await i.json();return i.ok?{success:!0,data:{temperature:s.current.temperature_2m,weathercode:s.current.weather_code},metadata:{latitude:e.latitude,longitude:e.longitude,timestamp:Date.now()}}:{success:!1,error:"Could not retrieve weather for the specified location.",metadata:{latitude:e.latitude,longitude:e.longitude}}}catch(t){return console.error("Error fetching weather:",t),{success:!1,error:t instanceof Error?t.message:"There was an error fetching the weather.",metadata:{latitude:e.latitude,longitude:e.longitude}}}}}class y{constructor(t){this.draggable=!1,this.selectable=!1,this.touchable=!1,this.selected=[],this.hovered=[],this.touched=[],this.activeDragged=[],this.positions=[],this.distances=[],this.uvs=[],this.initialPosition=new e.Vector3,this.parent=t}isHovered(){return this.hovered.includes(!0)}isSelected(){return this.selected.includes(!0)}isDragging(){return this.activeDragged.includes(!0)}update(e,t){const i=e.userData.id;this.initializeVariablesForId(i),t.object!==this.parent&&t.object!==this.parent.mesh||(this.hovered[i]=!0,this.selected[i]=e.userData.selected,t.uv&&this.uvs[i].copy(t.uv),this.positions[i].copy(t.point),this.distances[i]=t.distance,this.selected[i]||(this.activeDragged[i]=!1))}initializeVariablesForId(t){for(;this.selected.length<=t;)this.selected.push(!1),this.hovered.push(!1),this.activeDragged.push(!1),this.positions.push(new e.Vector3),this.distances.push(1),this.uvs.push(new e.Vector2)}reset(){for(const e in this.selected)this.selected[e]=!1,this.hovered[e]=!1}getPrimaryTwoControllerIds(){const e=[];if(this.hovered)for(let t=0;t<this.hovered.length&&e.length<2;++t)this.hovered[t]&&e.push(t);return[e[0]??null,e[1]??null]}}function w(e){return class extends e{constructor(){super(...arguments),this.ux=new y(this),this.isXRScript=!0}init(e){}update(e,t){}initPhysics(e){}physicsStep(){}onXRSessionStarted(e){}onXRSessionEnded(){}onSimulatorStarted(){}onSelectStart(e){}onSelectEnd(e){}onSelect(e){}onSelecting(e){}onKeyDown(e){}onKeyUp(e){}onSqueezeStart(e){}onSqueezeEnd(e){}onSqueezing(e){}onSqueeze(e){}onObjectSelectStart(e){return!1}onObjectSelectEnd(e){return!1}onHoverEnter(e){}onHoverExit(e){}onHovering(e){}onObjectTouchStart(e){}onObjectTouching(e){}onObjectTouchEnd(e){}onObjectGrabStart(e){}onObjectGrabbing(e){}onObjectGrabEnd(e){}dispose(){}}}const x=w(e.Object3D);class S extends x{}const b=w(e.Mesh);class C extends b{constructor(e,t){super(e,t)}}function T(e,t,i){return Math.min(Math.max(e,t),i)}function R(e,t,i){return e+(t-e)*i}function M(...e){console.log("*",...e)}const D=new URLSearchParams(window.location.search);function E(e){return new URLSearchParams(window.location.search).get(e)}function _(e,t=!1){const i=D.get(e)?.toLowerCase();return"true"===i||"1"===i||"false"!==i&&"0"!==i&&t}function P(e,t=0){const i=D.get(e);if(i){const e=parseInt(i,10);if(!isNaN(e))return e}return t}function A(e,t=0){const i=D.get(e);if(i){const e=parseFloat(i);if(!isNaN(e))return e}return t}function O(t){if("string"!=typeof t)throw new Error("colorString must be a string");const i=t.startsWith("#")?t.slice(1):t,s=i.length;let n=1,r=i;if(3!==s&&4!==s||(r=i.split("").map((e=>e+e)).join("")),8===r.length)n=parseInt(r.slice(6,8),16)/255,r=r.slice(0,6);else if(6!==r.length)throw new Error(`Invalid hex color string format: ${t}`);const o=parseInt(r.slice(0,2),16)/255,a=parseInt(r.slice(2,4),16)/255,h=parseInt(r.slice(4,6),16)/255;if(isNaN(o)||isNaN(a)||isNaN(h)||isNaN(n))throw new Error(`Invalid hex values in color string: ${t}`);return new e.Vector4(o,a,h,n)}function I(e){if("string"==typeof e){const t=O(e);return(Math.round(255*t.x)<<16)+(Math.round(255*t.y)<<8)+Math.round(255*t.z)}return"number"==typeof e?e:16777215}function L(e){const t=e.match(/^data:(image\/[a-zA-Z0-9\-+.]+);base64,/);if(t){const i=t[1];return{strippedBase64:e.substring(t[0].length),mimeType:i}}return{strippedBase64:e,mimeType:null}}class V{constructor(){this.apiKey="",this.urlParam="geminiKey",this.keyValid=!1,this.enabled=!1,this.model="gemini-2.0-flash",this.config={},this.live={enabled:!1,model:"gemini-live-2.5-flash-preview",voiceName:"Aoede",screenshotInterval:3e3,audioConfig:{sampleRate:16e3,channelCount:1,echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0}}}}class B{constructor(){this.apiKey="",this.urlParam="openaiKey",this.model="gpt-4.1",this.enabled=!1}}class F{constructor(){this.enabled=!1,this.model="gemini",this.gemini=new V,this.openai=new B,this.globalUrlParams={key:"key"}}}class z{constructor(){}}let k,j,U,N,G,H;class W extends z{constructor(e){super(),this.options=e,this.inited=!1,this.isLiveMode=!1,this.liveCallbacks={}}async init(){await async function(){if(!U)try{const e=await import("@google/genai");if(!e||!e.GoogleGenAI)throw new Error("'@google/genai' module loaded but is not valid.");k=e.createPartFromUri,j=e.createUserContent,U=e.GoogleGenAI,N=e.EndSensitivity,G=e.StartSensitivity,H=e.Modality,console.log("'@google/genai' module loaded successfully.")}catch(e){const t=`The '@google/genai' module is required for Gemini but failed to load. Error: ${e}`;throw console.error(t),new Error(t)}}()}isAvailable(){return!!U&&(this.inited||(this.ai=new U({apiKey:this.options.apiKey}),this.inited=!0),!0)}isLiveAvailable(){return this.isAvailable()&&N&&G&&H}async startLiveSession(e={}){if(!this.isLiveAvailable())throw new Error("Live API not available. Make sure @google/genai module is loaded.");if(this.liveSession)return this.liveSession;const t={responseModalities:[H.AUDIO],speechConfig:{voiceConfig:{prebuiltVoiceConfig:{voiceName:"Aoede"}}},outputAudioTranscription:{},inputAudioTranscription:{}};e.tools&&e.tools.length>0&&(t.tools=[{functionDeclarations:e.tools}]),e.systemInstruction&&("string"==typeof e.systemInstruction?t.systemInstruction=j(e.systemInstruction):t.systemInstruction=e.systemInstruction);const i={onopen:()=>{this.isLiveMode=!0,console.log("🔓 Live session opened."),this.liveCallbacks?.onopen&&this.liveCallbacks.onopen()},onmessage:e=>{this.liveCallbacks?.onmessage&&this.liveCallbacks.onmessage(e)},onerror:e=>{console.error("❌ Live session error:",e),this.liveCallbacks?.onerror&&this.liveCallbacks.onerror(e)},onclose:e=>{this.isLiveMode=!1,this.liveSession=void 0,e.reason?console.warn("🔒 Live session closed:",e):console.warn("🔒 Live session closed without reason."),this.liveCallbacks?.onclose&&this.liveCallbacks.onclose(e)}};try{const e={model:"gemini-2.5-flash-preview-native-audio-dialog",callbacks:i,config:t};return console.log("Connecting with params:",e),this.liveSession=await this.ai.live.connect(e),this.liveSession}catch(e){throw console.error("❌ Failed to start live session:",e),e}}async stopLiveSession(){this.liveSession&&(this.liveSession.close(),this.liveSession=void 0,this.isLiveMode=!1)}setLiveCallbacks(e){this.liveCallbacks=e}sendToolResponse(e){this.liveSession&&(console.debug("Sending tool response to gemini:",e),this.liveSession.sendToolResponse(e))}sendRealtimeInput(e){if(this.liveSession)try{this.liveSession.sendRealtimeInput(e)}catch(e){throw console.error("❌ Error sending realtime input:",e),e}}getLiveSessionStatus(){return{isActive:this.isLiveMode,hasSession:!!this.liveSession,isAvailable:this.isLiveAvailable()}}async query(e,t=[]){if(!this.inited)return console.warn("Gemini not inited."),null;const i=this.options,s=i.config||{};if(!("type"in e)){return{text:(await this.ai.models.generateContent({model:i.model,contents:e.prompt,config:s})).text||null}}const n=this.ai.models,r={model:this.options.model,contents:[],config:this.options.config||{}};let o=null;switch(e.type){case"text":r.contents=e.text,o=await n.generateContent(r);break;case"base64":e.mimeType||(e.mimeType="image/png"),r.contents={inlineData:{mimeType:e.mimeType,data:e.base64}},o=await n.generateContent(r);break;case"uri":r.contents=j([k(e.uri,e.mimeType),e.text]),o=await n.generateContent(r);break;case"multiPart":r.contents=[{role:"user",parts:e.parts}],o=await n.generateContent(r)}if(!o)return{text:null};const a=o.functionCalls?.[0];return a&&a.name?{toolCall:{name:a.name,args:a.args}}:{text:o.text||null}}async generate(e,t="image",i="Generate an image",s="gemini-2.5-flash-image-preview"){if(!this.isAvailable())return;let n;n=Array.isArray(e)?e.map((e=>{if("string"==typeof e){if(e.startsWith("data:image/")){const[t,i]=e.split(",");return{inlineData:{mimeType:t.split(";")[0].split(":")[1],data:i}}}return{text:e}}return e})):e;const r=await this.ai.models.generateContent({model:s,contents:n,config:{systemInstruction:i}});if(r.candidates&&r.candidates.length>0){const e=r.candidates[0];for(const i of e?.content?.parts||[])if("image"===t&&i.inlineData)return"data:image/png;base64,"+i.inlineData.data}}}let q=null;class X extends z{constructor(e){super(),this.options=e}async init(){await async function(){if(!q)try{const e=await import("openai");q=e.default,console.log("'openai' module loaded successfully.")}catch(e){console.warn("'openai' module not found. Using fallback implementations.","Error details:",e)}}(),this.options.apiKey&&q?(this.openai=new q({apiKey:this.options.apiKey,dangerouslyAllowBrowser:!0}),console.log("OpenAI model initialized")):console.error("OpenAI API key is missing or module failed to load.")}isAvailable(){return!!this.openai}async query(e,t){if(!this.isAvailable())throw new Error("OpenAI model is not initialized.");try{const t=(await this.openai.chat.completions.create({messages:[{role:"user",content:e.prompt}],model:this.options.model})).choices[0].message.content;return t?{text:t}:null}catch(e){throw console.error("Error querying OpenAI:",e),e}}async generate(){throw new Error("Wrapper not implemented")}}const K={gemini:W,openai:X};class $ extends S{constructor(){super(...arguments),this.lock=!1}static{this.dependencies={aiOptions:F}}async loadKeysFromFile(){if(this.keysCache)return this.keysCache;try{const e=await fetch("./keys.json");if(e.ok)return this.keysCache=await e.json(),console.log("🔑 Loaded keys.json"),this.keysCache}catch{}return null}async init({aiOptions:e}){if(this.lock=!1,this.options=e,!e.enabled)return void console.log("AI is disabled in options");const t=e.model,i=K[t];if(i){const s=e[t];s&&s.enabled?await this.initializeModel(i,s):console.log(`${t} is disabled in AI options`)}else console.error(`Unsupported AI model: ${t}`)}async initializeModel(e,t){const i=await this.resolveApiKey(t);if(i&&this.isValidApiKey(i)){t.apiKey=i,this.model=new e(t);try{await this.model.init(),console.log(`${this.options.model} initialized`)}catch(e){console.error(`Failed to initialize ${this.options.model}:`,e),this.model=void 0}}else console.error(`No valid API key found for ${this.options.model}`)}async resolveApiKey(e){const t=this.options.model;if(e.apiKey)return e.apiKey;const i=E("key");if(i)return i;const s=E(e.urlParam);if(s)return s;const n=E("geminiKey64");if(n)return window.atob(n);const r=await this.loadKeysFromFile();if(r){const e=t+"ApiKey";let i=null;if("object"==typeof r[t]?i=r[t]?.apiKey:"string"==typeof r[e]?i=r[e]:"string"==typeof r[t]&&(i=r[t]),i)return console.log(`🔑 Using ${t} key from keys.json`),i}return null}isValidApiKey(e){return e&&"string"==typeof e&&e.length>0}isAvailable(){return this.model&&this.model.isAvailable()&&!this.lock}async query(e,t){if(!this.isAvailable())throw new Error("AI is not available. Check if it's enabled and properly initialized.");return await this.model.query(e,t)}async startLiveSession(e={}){if(!this.model)throw new Error("AI model is not initialized.");if(!("isLiveAvailable"in this.model)||!this.model.isLiveAvailable())throw new Error("Live session is not available for the current model.");this.lock=!0;try{return await this.model.startLiveSession(e)}catch(e){throw this.lock=!1,console.error("❌ Failed to start Live session:",e),e}}async stopLiveSession(){if(this.model)try{await("stopLiveSession"in this.model&&this.model.stopLiveSession())}catch(e){console.error("❌ Error stopping Live session:",e)}finally{this.lock=!1}}async setLiveCallbacks(e){this.model&&"setLiveCallbacks"in this.model&&this.model.setLiveCallbacks(e)}sendToolResponse(e){this.model&&"sendToolResponse"in this.model&&this.model.sendToolResponse(e)}sendRealtimeInput(e){return!(!this.model||!("sendRealtimeInput"in this.model))&&this.model.sendRealtimeInput(e)}getLiveSessionStatus(){return this.model&&"getLiveSessionStatus"in this.model?this.model.getLiveSessionStatus():{isActive:!1,hasSession:!1,isAvailable:!1}}isLiveAvailable(){return this.model&&"isLiveAvailable"in this.model&&this.model.isLiveAvailable()}triggerKeyPopup(){}async generate(e,t="image",i="Generate an image",s="gemini-2.5-flash-image-preview"){return this.model.generate(e,t,i,s)}static createSampleKeysStructure(){return{gemini:{apiKey:"YOUR_GEMINI_API_KEY_HERE"},openai:{apiKey:"YOUR_OPENAI_API_KEY_HERE"}}}async hasApiKey(){if(!this.options)return!1;const e=this.options[this.options.model];if(!e)return!1;const t=await this.resolveApiKey(e);return t&&this.isValidApiKey(t)}}const Q=2,Y=25,J=[[1,2],[2,3],[3,4],[5,6],[6,7],[7,8],[8,9],[10,11],[11,12],[12,13],[13,14],[15,16],[16,17],[17,18],[18,19],[20,21],[21,22],[22,23],[23,24]],Z=[[0,1],[1,2],[3,4],[4,5],[5,6],[7,8],[8,9],[9,10],[11,12],[12,13],[13,14],[15,16],[16,17],[17,18]],ee=.002,te=1,ie=2,se=3,ne=4,re=1280,oe=720,ae="https://cdn.jsdelivr.net/gh/xrblocks/assets@34228db7ec7cef66fd65ef3250ef6f4a930fe373/";function he(e){return Object.freeze(e),Object.getOwnPropertyNames(e).forEach((t=>{const i=e[t];i&&"object"==typeof i&&!Object.isFrozen(i)&&he(i)})),e}function le(e,t){if(null==t)return e;const i=e;for(const e in t)if(Object.prototype.hasOwnProperty.call(t,e)){const s=i[e],n=t[e];s&&"object"==typeof s&&n&&"object"==typeof n?le(s,n):i[e]=n}}class ce{constructor(e){this.enabled=!1,this.willCaptureFrequently=!1,le(this,e)}}const de={enabled:!0,videoConstraints:{width:{ideal:1280},height:{ideal:720}}},ue=he(new ce({...de,videoConstraints:{...de.videoConstraints,facingMode:"environment"}})),pe=he(new ce({...de,videoConstraints:{...de.videoConstraints,facingMode:"user"}})),ge=he(new ce({...ue,willCaptureFrequently:!0})),me=he(new ce({...pe,willCaptureFrequently:!0}));function fe(){return!/Mobi|Linux|Android|iPhone/i.test(navigator.userAgent)}const ve={vertexShader:"\nvarying vec3 vNormal;\nvarying vec3 vViewPosition;\nvarying vec2 vUv;\n\nvoid main() {\n vUv = uv;\n vNormal = normal;\n\n // Computes the view position.\n vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);\n vViewPosition = -mvPosition.xyz;\n\n gl_Position = projectionMatrix * mvPosition;\n}\n",fragmentShader:"\n#include <packing>\n\nuniform vec3 uColor;\nuniform sampler2D uDepthTexture;\nuniform sampler2DArray uDepthTextureArray;\nuniform vec3 uLightDirection;\nuniform vec2 uResolution;\nuniform float uRawValueToMeters;\n\nvarying vec3 vNormal;\nvarying vec3 vViewPosition;\nvarying vec2 vUv;\n\nconst highp float kMaxDepthInMeters = 8.0;\nconst float kInvalidDepthThreshold = 0.01;\nuniform float uMinDepth;\nuniform float uMaxDepth;\nuniform float uDebug;\nuniform float uOpacity;\nuniform bool uUsingFloatDepth;\nuniform bool uIsTextureArray;\n\nfloat saturate(in float x) {\n return clamp(x, 0.0, 1.0);\n}\n\nvec3 TurboColormap(in float x) {\n const vec4 kRedVec4 = vec4(0.55305649, 3.00913185, -5.46192616, -11.11819092);\n const vec4 kGreenVec4 = vec4(0.16207513, 0.17712472, 15.24091500, -36.50657960);\n const vec4 kBlueVec4 = vec4(-0.05195877, 5.18000081, -30.94853351, 81.96403246);\n const vec2 kRedVec2 = vec2(27.81927491, -14.87899417);\n const vec2 kGreenVec2 = vec2(25.95549545, -5.02738237);\n const vec2 kBlueVec2 = vec2(-86.53476570, 30.23299484);\n\n // Adjusts color space via 6 degree poly interpolation to avoid pure red.\n vec4 v4 = vec4( 1.0, x, x * x, x * x * x);\n vec2 v2 = v4.zw * v4.z;\n return vec3(\n dot(v4, kRedVec4) + dot(v2, kRedVec2),\n dot(v4, kGreenVec4) + dot(v2, kGreenVec2),\n dot(v4, kBlueVec4) + dot(v2, kBlueVec2)\n );\n}\n\n// Depth is packed into the luminance and alpha components of its texture.\n// The texture is in a normalized format, storing raw values that need to be\n// converted to meters.\nfloat DepthGetMeters(in sampler2D depth_texture, in vec2 depth_uv) {\n if (uUsingFloatDepth) {\n return texture2D(depth_texture, depth_uv).r * uRawValueToMeters;\n }\n vec2 packedDepthAndVisibility = texture2D(depth_texture, depth_uv).rg;\n return dot(packedDepthAndVisibility, vec2(255.0, 256.0 * 255.0)) * uRawValueToMeters;\n}\n\nfloat DepthArrayGetMeters(in sampler2DArray depth_texture, in vec2 depth_uv) {\n return uRawValueToMeters * texture(uDepthTextureArray, vec3 (depth_uv.x, depth_uv.y, 0)).r;\n}\n\nvec3 DepthGetColorVisualization(in float x) {\n return step(kInvalidDepthThreshold, x) * TurboColormap(x);\n}\n\nvoid main() {\n vec3 lightDirection = normalize(uLightDirection);\n\n // Compute UV coordinates relative to resolution\n // vec2 uv = gl_FragCoord.xy / uResolution;\n vec2 uv = vUv;\n\n // Ambient, diffuse, and specular terms\n vec3 ambient = 0.1 * uColor;\n float diff = max(dot(vNormal, lightDirection), 0.0);\n vec3 diffuse = diff * uColor;\n\n vec3 viewDir = normalize(vViewPosition);\n vec3 reflectDir = reflect(-lightDirection, vNormal);\n float spec = pow(max(dot(viewDir, reflectDir), 0.0), 16.0);\n vec3 specular = vec3(0.5) * spec; // Adjust specular color/strength\n\n // Combine Phong lighting\n vec3 finalColor = ambient + diffuse + specular;\n // finalColor = vec3(vNormal);\n\n // Output color\n gl_FragColor = uOpacity * vec4(finalColor, 1.0);\n\n if (uDebug > 0.5) {\n return;\n }\n\n vec2 depth_uv = uv;\n depth_uv.y = 1.0 - depth_uv.y;\n\n float depth = (uIsTextureArray ? DepthArrayGetMeters(uDepthTextureArray, depth_uv) : DepthGetMeters(uDepthTexture, depth_uv)) * 8.0;\n float normalized_depth =\n saturate((depth - uMinDepth) / (uMaxDepth - uMinDepth));\n gl_FragColor = uOpacity * vec4(TurboColormap(normalized_depth), 1.0);\n}\n"};class ye extends C{static{this.dependencies={camera:e.Camera,renderer:e.WebGLRenderer}}static{this.isDepthMesh=!0}constructor(t,i,s,n){const r=t.depthMesh,o=new e.PlaneGeometry(1,1,159,159);let a,h;r.useDepthTexture||r.showDebugTexture?(h={uDepthTexture:{value:null},uDepthTextureArray:{value:null},uIsTextureArray:{value:0},uColor:{value:new e.Color(11184810)},uResolution:{value:new e.Vector2(i,s)},uRawValueToMeters:{value:1},uMinDepth:{value:0},uMaxDepth:{value:8},uOpacity:{value:r.opacity},uDebug:{value:r.showDebugTexture?1:0},uLightDirection:{value:new e.Vector3(1,1,1).normalize()},uUsingFloatDepth:{value:t.useFloat32}},a=new e.ShaderMaterial({uniforms:h,vertexShader:ve.vertexShader,fragmentShader:ve.fragmentShader,side:e.FrontSide,transparent:!0})):(a=new e.ShadowMaterial({opacity:r.shadowOpacity}),a.depthWrite=!1),super(o,a),this.depthOptions=t,this.depthTextures=n,this.ignoreReticleRaycast=!1,this.worldPosition=new e.Vector3,this.worldQuaternion=new e.Quaternion,this.updateVertexNormals=!1,this.minDepth=8,this.maxDepth=0,this.minDepthPrev=8,this.maxDepthPrev=0,this.colliders=[],this.projectionMatrixInverse=new e.Matrix4,this.lastColliderUpdateTime=0,this.colliderId=0,this.visible=r.showDebugTexture||r.renderShadow,this.options=r,this.projectionMatrixInverse=new e.Matrix4,this.lastColliderUpdateTime=performance.now(),this.updateVertexNormals=r.updateVertexNormals,this.colliderUpdateFps=r.colliderUpdateFps,this.depthTextureMaterialUniforms=h,r.renderShadow&&(this.receiveShadow=!0,this.castShadow=!1),r.useDownsampledGeometry&&(this.downsampledGeometry=new e.PlaneGeometry(1,1,39,39),this.downsampledMesh=new e.Mesh(this.downsampledGeometry,a),this.downsampledMesh.visible=!1,this.add(this.downsampledMesh))}init({camera:e,renderer:t}){this.camera=e,this.renderer=t}updateDepth(t){const i=this.renderer.xr?.getCamera?.()?.cameras?.[0]||this.camera;if(!i)return;this.projectionMatrixInverse.copy(i.projectionMatrix).invert(),this.minDepth=8,this.maxDepth=0,this.options.updateFullResolutionGeometry&&this.updateFullResolutionGeometry(t),this.downsampledGeometry&&this.updateGeometry(t,this.downsampledGeometry),this.minDepthPrev=this.minDepth,this.maxDepthPrev=this.maxDepth,this.geometry.attributes.position.needsUpdate=!0;const s=this.depthTextures?.get(0);if(s&&this.depthTextureMaterialUniforms){const t=s instanceof e.ExternalTexture;this.depthTextureMaterialUniforms.uIsTextureArray.value=t?1:0,t?this.depthTextureMaterialUniforms.uDepthTextureArray.value=s:this.depthTextureMaterialUniforms.uDepthTexture.value=s,this.depthTextureMaterialUniforms.uMinDepth.value=this.minDepth,this.depthTextureMaterialUniforms.uMaxDepth.value=this.maxDepth,this.depthTextureMaterialUniforms.uRawValueToMeters.value=this.depthTextures.depthData.length?this.depthTextures.depthData[0].rawValueToMeters:1}this.options.updateVertexNormals&&this.geometry.computeVertexNormals(),this.updateColliderIfNeeded()}updateGPUDepth(e){this.updateDepth(this.convertGPUToGPU(e))}convertGPUToGPU(t){if(!this.depthTarget){this.depthTarget=new e.WebGLRenderTarget(t.width,t.height,{format:e.RedFormat,type:e.FloatType,internalFormat:"R32F",minFilter:e.NearestFilter,magFilter:e.NearestFilter,depthBuffer:!1}),this.depthTexture=new e.ExternalTexture(t.texture);this.renderer.properties.get(this.depthTexture).__webglTexture=t.texture,this.gpuPixels=new Float32Array(t.width*t.height);const i=new e.ShaderMaterial({vertexShader:"\n varying vec2 vUv;\n void main() {\n vUv = uv;\n vUv.y = 1.0-vUv.y;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n ",fragmentShader:"\n precision highp float;\n precision highp sampler2DArray;\n\n uniform sampler2DArray uTexture;\n uniform float uCameraNear;\n varying vec2 vUv;\n\n void main() {\n float z = texture(uTexture, vec3(vUv, 0)).r;\n z = uCameraNear / (1.0 - z);\n z = clamp(z, 0.0, 20.0);\n gl_FragColor = vec4(z, 0, 0, 1.0);\n }\n ",uniforms:{uTexture:{value:this.depthTexture},uCameraNear:{value:t.depthNear}},blending:e.NoBlending,depthTest:!1,depthWrite:!1,side:e.DoubleSide}),s=new e.Mesh(new e.PlaneGeometry(2,2),i);this.depthScene=new e.Scene,this.depthScene.add(s),this.depthCamera=new e.OrthographicCamera(-1,1,1,-1,0,1)}const i=this.renderer.getRenderTarget();return this.renderer.xr.enabled=!1,this.renderer.setRenderTarget(this.depthTarget),this.renderer.render(this.depthScene,this.depthCamera),this.renderer.readRenderTargetPixels(this.depthTarget,0,0,t.width,t.height,this.gpuPixels,0),this.renderer.xr.enabled=!0,this.renderer.setRenderTarget(i),{width:t.width,height:t.height,data:this.gpuPixels.buffer,rawValueToMeters:t.rawValueToMeters}}updateFullResolutionGeometry(e){this.updateGeometry(e,this.geometry)}updateGeometry(t,i){const s=t.width,n=t.height,r=this.depthOptions.useFloat32?new Float32Array(t.data):new Uint16Array(t.data),o=new e.Vector3;for(let e=0;e<i.attributes.position.count;++e){const a=i.attributes.uv.array[2*e],h=i.attributes.uv.array[2*e+1],l=Math.round(T(a*s,0,s-1)),c=r[Math.round(T((1-h)*n,0,n-1))*s+l];let d=t.rawValueToMeters*c;this.depthOptions.useFloat32&&(d=c),d>0&&(d<this.minDepth?this.minDepth=d:d>this.maxDepth&&(this.maxDepth=d)),0==d&&this.options.patchHoles&&(d=this.maxDepthPrev),this.options.patchHolesUpper&&h>.9&&(d=this.minDepthPrev),o.set(2*(a-.5),2*(h-.5),-1),o.applyMatrix4(this.projectionMatrixInverse),o.multiplyScalar(-d/o.z),i.attributes.position.array[3*e+0]=o.x,i.attributes.position.array[3*e+1]=o.y,i.attributes.position.array[3*e+2]=o.z}}updateColliderIfNeeded(){const e=performance.now()-this.lastColliderUpdateTime;if(this.RAPIER&&e>1e3/this.colliderUpdateFps){this.getWorldPosition(this.worldPosition),this.getWorldQuaternion(this.worldQuaternion),this.rigidBody.setTranslation(this.worldPosition,!1),this.rigidBody.setRotation(this.worldQuaternion,!1);const e=this.downsampledGeometry?this.downsampledGeometry:this.geometry,t=e.attributes.position.array,i=e.getIndex().array,s=this.RAPIER.ColliderDesc.trimesh(t,i).setDensity(1);if(this.options.useDualCollider)this.colliderId=(this.colliderId+1)%2,this.blendedWorld.removeCollider(this.colliders[this.colliderId],!1),this.colliders[this.colliderId]=this.blendedWorld.createCollider(s,this.rigidBody);else{const e=this.blendedWorld.createCollider(s,this.rigidBody);this.blendedWorld.removeCollider(this.collider,!1),this.collider=e}this.lastColliderUpdateTime=performance.now()}}initRapierPhysics(e,t){this.getWorldPosition(this.worldPosition),this.getWorldQuaternion(this.worldQuaternion);const i=e.RigidBodyDesc.fixed().setTranslation(this.worldPosition.x,this.worldPosition.y,this.worldPosition.z).setRotation(this.worldQuaternion);this.rigidBody=t.createRigidBody(i);const s=this.geometry.attributes.position.array,n=this.geometry.getIndex().array,r=e.ColliderDesc.trimesh(s,n);this.options.useDualCollider?(this.colliders=[],this.colliders.push(t.createCollider(r,this.rigidBody),t.createCollider(r,this.rigidBody)),this.colliderId=0):this.collider=t.createCollider(r,this.rigidBody),this.RAPIER=e,this.blendedWorld=t,this.lastColliderUpdateTime=performance.now()}getDepth(t,i,s){const n=new e.Vector2(i.x,i.y);t.setFromCamera(n,s);const r=t.intersectObject(this);if(r.length>0){return r[0].distance}return-1}raycast(e,t){const i=[];return this.downsampledMesh?this.downsampledMesh.raycast(e,i):super.raycast(e,i),i.forEach((e=>{e.object=this})),this.updateVertexNormals||i.forEach((e=>{e.normal&&e.face&&e.normal.copy(e.face.normal)})),t.push(...i),!0}getColliderFromHandle(e){if(this.collider?.handle==e)return this.collider;for(const t of this.colliders)if(t?.handle==e)return t}}class we{constructor(){this.enabled=!1,this.updateVertexNormals=!1,this.showDebugTexture=!1,this.useDepthTexture=!1,this.renderShadow=!1,this.shadowOpacity=.25,this.patchHoles=!1,this.patchHolesUpper=!1,this.opacity=1,this.useDualCollider=!1,this.useDownsampledGeometry=!0,this.updateFullResolutionGeometry=!1,this.colliderUpdateFps=5}}class xe{constructor(e){this.debugging=!1,this.enabled=!1,this.depthMesh=new we,this.depthTexture={enabled:!1,constantKernel:!1,applyGaussianBlur:!1,applyKawaseBlur:!1},this.occlusion={enabled:!1},this.useFloat32=!0,le(this,e)}}const Se=he(new xe({enabled:!0,depthMesh:{enabled:!0,updateVertexNormals:!1,showDebugTexture:!1,useDepthTexture:!1,renderShadow:!1,shadowOpacity:.25,patchHoles:!0,useDownsampledGeometry:!0,updateFullResolutionGeometry:!1,colliderUpdateFps:5}})),be=he(new xe({enabled:!0,depthMesh:{enabled:!0,updateVertexNormals:!0,showDebugTexture:!0,useDepthTexture:!0,renderShadow:!1,shadowOpacity:.25,patchHoles:!0,opacity:.1,useDownsampledGeometry:!0,updateFullResolutionGeometry:!0,colliderUpdateFps:5},depthTexture:{enabled:!0,constantKernel:!0,applyGaussianBlur:!0,applyKawaseBlur:!0}})),Ce=he(new xe({enabled:!0,depthMesh:{enabled:!0,updateVertexNormals:!1,showDebugTexture:!1,useDepthTexture:!1,renderShadow:!0,shadowOpacity:.25,patchHoles:!0,patchHolesUpper:!0,useDualCollider:!1,useDownsampledGeometry:!0,updateFullResolutionGeometry:!1,colliderUpdateFps:5}}));class Te{constructor(e){this.options=e,this.uint16Arrays=[],this.uint8Arrays=[],this.dataTextures=[],this.nativeTextures=[],this.depthData=[]}createDataDepthTextures(t,i){if(this.dataTextures[i]&&this.dataTextures[i].dispose(),this.options.useFloat32){const s=new Uint16Array(t.width*t.height),n=e.RedFormat,r=e.HalfFloatType;this.uint16Arrays[i]=s,this.dataTextures[i]=new e.DataTexture(s,t.width,t.height,n,r)}else{const s=new Uint8Array(t.width*t.height*2),n=e.RGFormat,r=e.UnsignedByteType;this.uint8Arrays[i]=s,this.dataTextures[i]=new e.DataTexture(s,t.width,t.height,n,r)}}updateData(t,i){if((this.dataTextures.length<i+1||this.dataTextures[i].image.width!==t.width||this.dataTextures[i].image.height!==t.height)&&this.createDataDepthTextures(t,i),this.options.useFloat32){const s=new Float32Array(t.data),n=new Uint16Array(s.length);for(let t=0;t<n.length;t++)n[t]=e.DataUtils.toHalfFloat(s[t]);this.uint16Arrays[i].set(n)}else this.uint8Arrays[i].set(new Uint8Array(t.data));this.dataTextures[i].needsUpdate=!0,this.depthData[i]=t}updateNativeTexture(t,i,s){this.dataTextures.length<s+1?this.nativeTextures[s]=new e.ExternalTexture(t.texture):this.nativeTextures[s].sourceTexture=t.texture;const n=i.properties.get(this.nativeTextures[s]);n.__webglTexture=t.texture,n.__version=1}get(e){return this.dataTextures.length>0?this.dataTextures[e]:this.nativeTextures[e]}}const Re={vertexShader:"\n uniform float uBlurSize;\n uniform vec2 uTexelSize;\n varying vec2 vTexCoord;\n varying vec4 uv1;\n varying vec4 uv2;\n varying vec4 uv3;\n varying vec4 uv4;\n\n void vertCopy(vec2 uv) {}\n\n void vertUpsample(vec2 uv) {\n vec2 halfPixel = uTexelSize * 0.5;\n vec2 offset = vec2(uBlurSize);\n uv1.xy = uv + vec2(-halfPixel.x * 2.0, 0.0) * offset;\n uv1.zw = uv + vec2(-halfPixel.x, halfPixel.y) * offset;\n uv2.xy = uv + vec2(0.0, halfPixel.y * 2.0) * offset;\n uv2.zw = uv + halfPixel * offset;\n uv3.xy = uv + vec2(halfPixel.x * 2.0, 0.0) * offset;\n uv3.zw = uv + vec2(halfPixel.x, -halfPixel.y) * offset;\n uv4.xy = uv + vec2(0.0, -halfPixel.y * 2.0) * offset;\n uv4.zw = uv - halfPixel * offset;\n }\n\n void vertDownsample(vec2 uv) {\n vec2 halfPixel = uTexelSize * 0.5;\n vec2 offset = vec2(uBlurSize);\n uv1.xy = uv - halfPixel * offset;\n uv1.zw = uv + halfPixel * offset;\n uv2.xy = uv - vec2(halfPixel.x, -halfPixel.y) * offset;\n uv2.zw = uv + vec2(halfPixel.x, -halfPixel.y) * offset;\n }\n\n void main() {\n vTexCoord = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n if (MODE == 0) {\n vertCopy(uv);\n } else if (MODE == 1) {\n vertDownsample(uv);\n } else {\n vertUpsample(uv);\n }\n }\n",fragmentShader:"\n uniform sampler2D tDiffuse;\n varying vec2 vTexCoord;\n varying vec4 uv1;\n varying vec4 uv2;\n varying vec4 uv3;\n varying vec4 uv4;\n\n vec2 getUV0() {\n return vTexCoord;\n }\n\n vec4 fragCopy() {\n return texture2D(tDiffuse, getUV0());\n }\n\n vec4 fragDownsample() {\n vec4 sum = texture2D(tDiffuse, getUV0()) * 4.0;\n sum += texture2D(tDiffuse, uv1.xy);\n sum += texture2D(tDiffuse, uv1.zw);\n sum += texture2D(tDiffuse, uv2.xy);\n sum += texture2D(tDiffuse, uv2.zw);\n return sum * 0.125;\n }\n\n vec4 fragUpsample() {\n vec4 sum = texture2D(tDiffuse, uv1.xy);\n sum += texture2D(tDiffuse, uv1.zw) * 2.0;\n sum += texture2D(tDiffuse, uv2.xy);\n sum += texture2D(tDiffuse, uv2.zw) * 2.0;\n sum += texture2D(tDiffuse, uv3.xy);\n sum += texture2D(tDiffuse, uv3.zw) * 2.0;\n sum += texture2D(tDiffuse, uv4.xy);\n sum += texture2D(tDiffuse, uv4.zw) * 2.0;\n return sum * 0.0833;\n }\n\n void main(void) {\n if (MODE == 0) {\n gl_FragColor = fragCopy();\n } else if (MODE == 1) {\n gl_FragColor = fragDownsample();\n } else {\n gl_FragColor = fragUpsample();\n }\n }\n"},Me={vertexShader:"\nvarying vec2 vTexCoord;\n\nvoid main() {\n vTexCoord = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}\n ",fragmentShader:"\nprecision mediump float;\n\nuniform sampler2D tDiffuse;\nuniform sampler2D tOcclusionMap;\n\nvarying vec2 vTexCoord;\n\nvoid main(void) {\n vec4 diffuse = texture2D(tDiffuse, vTexCoord);\n vec4 occlusion = texture2D(tOcclusionMap, vTexCoord);\n float occlusionValue = occlusion.r / max(0.0001, occlusion.g);\n occlusionValue = clamp(occlusionValue, 0.0, 1.0);\n gl_FragColor = occlusionValue * diffuse;\n\n gl_FragColor = sRGBTransferOETF( gl_FragColor );\n}\n"},De={vertexShader:"\nvarying vec2 vTexCoord;\n\nvoid main() {\n vTexCoord = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}\n ",fragmentShader:"\n#include <packing>\n\nprecision mediump float;\n\nuniform sampler2D uDepthTexture;\nuniform mat4 uUvTransform;\nuniform float uRawValueToMeters;\nuniform float uAlpha;\nuniform float uViewId;\nuniform bool uFloatDepth;\n\nuniform sampler2D tDiffuse;\nuniform sampler2D tDepth;\nuniform float cameraNear;\nuniform float cameraFar;\n\nvarying vec2 vTexCoord;\n\nfloat DepthGetMeters(in sampler2D depth_texture, in vec2 depth_uv) {\n // Depth is packed into the luminance and alpha components of its texture.\n // The texture is in a normalized format, storing raw values that need to be\n // converted to meters.\n vec2 packedDepthAndVisibility = texture2D(depth_texture, depth_uv).rg;\n if (uFloatDepth) {\n return packedDepthAndVisibility.r * uRawValueToMeters;\n }\n return dot(packedDepthAndVisibility, vec2(255.0, 256.0 * 255.0)) * uRawValueToMeters;\n}\n\nfloat readOrthographicDepth( sampler2D depthSampler, vec2 coord ) {\n float fragCoordZ = texture2D( depthSampler, coord ).x;\n // See https://github.com/mrdoob/three.js/issues/23072.\n #ifdef USE_LOGDEPTHBUF\n float viewZ = 1.0 - exp2(fragCoordZ * log(cameraFar + 1.0) / log(2.0));\n #else\n float viewZ = perspectiveDepthToViewZ(fragCoordZ, cameraNear, cameraFar);\n #endif\n return viewZToOrthographicDepth( viewZ, cameraNear, cameraFar );\n}\n\nvoid main(void) {\n vec4 texCoord = vec4(vTexCoord, 0, 1);\n vec2 uv = texCoord.xy;\n uv.y = 1.0 - uv.y;\n\n vec4 diffuse = texture2D( tDiffuse, texCoord.xy );\n highp float real_depth = DepthGetMeters(uDepthTexture, uv);\n highp float virtual_depth =\n (readOrthographicDepth(tDepth, texCoord.xy ) *\n (cameraFar - cameraNear) + cameraNear);\n gl_FragColor = vec4(step(virtual_depth, real_depth), step(0.001, diffuse.a), 0.0, 0.0);\n}\n"};class Ee extends e.MeshBasicMaterial{constructor(e,t){super(),this.uniforms={uDepthTexture:{value:null},uDepthTextureArray:{value:null},uViewId:{value:0},uIsTextureArray:{value:0},uRawValueToMeters:{value:8/65536},cameraFar:{value:e.far},cameraNear:{value:e.near},uFloatDepth:{value:t},uDepthNear:{value:0}},this.onBeforeCompile=e=>{Object.assign(e.uniforms,this.uniforms),this.uniforms=e.uniforms,e.vertexShader=e.vertexShader.replace("#include <common>",["varying vec2 vTexCoord;","varying float vVirtualDepth;","#include <common>"].join("\n")).replace("#include <fog_vertex>",["#include <fog_vertex>","vec4 view_position = modelViewMatrix * vec4( position, 1.0 );","vVirtualDepth = -view_position.z;","gl_Position = gl_Position / gl_Position.w;","vTexCoord = 0.5 + 0.5 * gl_Position.xy;"].join("\n")),e.fragmentShader=e.fragmentShader.replace("uniform vec3 diffuse;",["uniform vec3 diffuse;","uniform sampler2D uDepthTexture;","uniform sampler2DArray uDepthTextureArray;","uniform float uRawValueToMeters;","uniform float cameraNear;","uniform float cameraFar;","uniform bool uFloatDepth;","uniform bool uIsTextureArray;","uniform float uDepthNear;","uniform int uViewId;","varying vec2 vTexCoord;","varying float vVirtualDepth;"].join("\n")).replace("#include <clipping_planes_pars_fragment>",["#include <clipping_planes_pars_fragment>","\n float DepthGetMeters(in sampler2D depth_texture, in vec2 depth_uv) {\n // Depth is packed into the luminance and alpha components of its texture.\n // The texture is in a normalized format, storing raw values that need to be\n // converted to meters.\n vec2 packedDepthAndVisibility = texture2D(depth_texture, depth_uv).rg;\n if (uFloatDepth) {\n return packedDepthAndVisibility.r * uRawValueToMeters;\n }\n return dot(packedDepthAndVisibility, vec2(255.0, 256.0 * 255.0)) * uRawValueToMeters;\n }\n float DepthArrayGetMeters(in sampler2DArray depth_texture, in vec2 depth_uv) {\n float textureValue = texture(depth_texture, vec3(depth_uv.x, depth_uv.y, uViewId)).r;\n return uRawValueToMeters * uDepthNear / (1.0 - textureValue);\n }\n"].join("\n")).replace("#include <dithering_fragment>",["#include <dithering_fragment>","vec4 texCoord = vec4(vTexCoord, 0, 1);","vec2 uv = vec2(texCoord.x, uIsTextureArray?texCoord.y:(1.0 - texCoord.y));","highp float real_depth = uIsTextureArray ? DepthArrayGetMeters(uDepthTextureArray, uv) : DepthGetMeters(uDepthTexture, uv);","gl_FragColor = vec4(step(vVirtualDepth, real_depth), 1.0, 0.0, 1.0);"].join("\n"))}}}var _e;!function(e){e[e.COPY=0]="COPY",e[e.DOWN=1]="DOWN",e[e.UP=2]="UP"}(_e||(_e={}));class Pe extends t{constructor(t,s,n=!0,r=!1,o=3){super(),this.scene=t,this.camera=s,this.renderToScreen=r,this.occludableItemsLayer=o,this.depthTextures=[],this.depthNear=[],this.occlusionMeshMaterial=new Ee(s,n),this.occlusionMapUniforms={uDepthTexture:{value:null},uDepthTextureArray:{value:null},uViewId:{value:0},uIsTextureArray:{value:0},uUvTransform:{value:new e.Matrix4},uRawValueToMeters:{value:8/65536},uAlpha:{value:.75},tDiffuse:{value:null},tDepth:{value:null},uFloatDepth:{value:n},cameraFar:{value:s.far},cameraNear:{value:s.near}},this.occlusionMapQuad=new i(new e.ShaderMaterial({name:"OcclusionMapShader",uniforms:this.occlusionMapUniforms,vertexShader:De.vertexShader,fragmentShader:De.fragmentShader})),this.occlusionMapTexture=new e.WebGLRenderTarget,this.kawaseBlurTargets=[new e.WebGLRenderTarget,new e.WebGLRenderTarget,new e.WebGLRenderTarget],this.kawaseBlurQuads=[this.setupKawaseBlur(_e.DOWN,this.occlusionMapTexture.texture),this.setupKawaseBlur(_e.DOWN,this.kawaseBlurTargets[0].texture),this.setupKawaseBlur(_e.DOWN,this.kawaseBlurTargets[1].texture),this.setupKawaseBlur(_e.UP,this.kawaseBlurTargets[2].texture),this.setupKawaseBlur(_e.UP,this.kawaseBlurTargets[1].texture),this.setupKawaseBlur(_e.UP,this.kawaseBlurTargets[0].texture)],this.occlusionUniforms={tDiffuse:{value:null},tOcclusionMap:{value:this.occlusionMapTexture.texture}},this.occlusionQuad=new i(new e.ShaderMaterial({name:"OcclusionShader",uniforms:this.occlusionUniforms,vertexShader:Me.vertexShader,fragmentShader:Me.fragmentShader})),this.occludableItemsLayer=o}setupKawaseBlur(t,s){const n={uBlurSize:{value:7},uTexelSize:{value:new e.Vector2},tDiffuse:{value:s}},r=new e.ShaderMaterial({name:"Kawase",uniforms:n,vertexShader:Re.vertexShader,fragmentShader:Re.fragmentShader,defines:{MODE:t}});return new i(r)}setDepthTexture(e,t,i,s){this.depthTextures[i]=e,this.occlusionMapUniforms.uRawValueToMeters.value=t,this.occlusionMeshMaterial.uniforms.uRawValueToMeters.value=t,this.depthNear[i]=s,e.needsUpdate=!0}render(t,i,s,n=0){const r=t.getRenderTarget(),o=new e.Vector2;null==s?this.renderOcclusionMapFromScene(t,o,n):this.renderOcclusionMapFromReadBuffer(t,s,o,n),this.blurOcclusionMap(t,o),this.applyOcclusionMapToRenderedImage(t,s,i),t.setRenderTarget(r)}renderOcclusionMapFromScene(t,i,s){const n=this.depthTextures[s],r=n instanceof e.ExternalTexture;this.occlusionMeshMaterial.uniforms.uIsTextureArray.value=r?1:0,this.occlusionMeshMaterial.uniforms.uViewId.value=s,r?(this.occlusionMeshMaterial.uniforms.uDepthTextureArray.value=n,this.occlusionMeshMaterial.uniforms.uDepthNear.value=this.depthNear[s]):this.occlusionMeshMaterial.uniforms.uDepthTexture.value=n,this.scene.overrideMaterial=this.occlusionMeshMaterial,t.getDrawingBufferSize(i),this.occlusionMapTexture.setSize(i.x,i.y);const o=this.occlusionMapTexture;t.setRenderTarget(o);const a=t.xr.getCamera().cameras[s]||this.camera,h=Array.from(Array(32).keys()).filter((e=>a.layers.isEnabled(e)));a.layers.set(this.occludableItemsLayer),t.render(this.scene,a),a.layers.disableAll(),h.forEach((e=>{a.layers.enable(e)})),this.scene.overrideMaterial=null}renderOcclusionMapFromReadBuffer(t,i,s,n){this.occlusionMapUniforms.tDiffuse.value=i.texture,this.occlusionMapUniforms.tDepth.value=i.depthTexture;const r=this.depthTextures[n],o=r instanceof e.ExternalTexture;this.occlusionMeshMaterial.uniforms.uIsTextureArray.value=o?1:0,this.occlusionMeshMaterial.uniforms.uViewId.value=n,o?(this.occlusionMeshMaterial.uniforms.uDepthTextureArray.value=r,this.occlusionMeshMaterial.uniforms.uDepthNear.value=this.depthNear[n]):this.occlusionMeshMaterial.uniforms.uDepthTexture.value=r,t.getDrawingBufferSize(s),this.occlusionMapTexture.setSize(s.x,s.y),t.setRenderTarget(this.occlusionMapTexture),this.occlusionMapQuad.render(t)}blurOcclusionMap(e,t){for(let e=0;e<3;e++)this.kawaseBlurTargets[e].setSize(t.x/2**e,t.y/2**e);for(let e=0;e<3;e++)this.kawaseBlurQuads[e].material.uniforms.uTexelSize.value.set(1/(t.x/2**e),1/(t.y/2**e)),this.kawaseBlurQuads[this.kawaseBlurQuads.length-1-e].material.uniforms.uTexelSize.value.set(1/(t.x/2**(e-1)),1/(t.y/2**(e-1)));e.setRenderTarget(this.kawaseBlurTargets[0]),this.kawaseBlurQuads[0].render(e),e.setRenderTarget(this.kawaseBlurTargets[1]),this.kawaseBlurQuads[1].render(e),e.setRenderTarget(this.kawaseBlurTargets[2]),this.kawaseBlurQuads[2].render(e),e.setRenderTarget(this.kawaseBlurTargets[1]),this.kawaseBlurQuads[3].render(e),e.setRenderTarget(this.kawaseBlurTargets[0]),this.kawaseBlurQuads[4].render(e),e.setRenderTarget(this.occlusionMapTexture),this.kawaseBlurQuads[5].render(e)}applyOcclusionMapToRenderedImage(e,t,i){t&&(this.renderToScreen||i)&&(this.occlusionUniforms.tDiffuse.value=t.texture,e.setRenderTarget(i&&!this.renderToScreen?i:null),this.occlusionQuad.render(e))}dispose(){this.occlusionMeshMaterial.dispose(),this.occlusionMapTexture.dispose();for(let e=0;e<this.kawaseBlurQuads.length;e++)this.kawaseBlurQuads[e].dispose()}updateOcclusionMapUniforms(e,t){const i=t.xr.getCamera().cameras[0]||this.camera;e.tOcclusionMap.value=this.occlusionMapTexture.texture,e.uOcclusionClipFromWorld.value.copy(i.projectionMatrix).multiply(i.matrixWorldInverse)}}const Ae=new e.Vector3;class Oe{constructor(){if(this.projectionMatrixInverse=new e.Matrix4,this.view=[],this.cpuDepthData=[],this.gpuDepthData=[],this.depthArray=[],this.options=new xe,this.width=160,this.height=160,this.rawValueToMeters=.0010000000474974513,this.occludableShaders=new Set,this.depthClientsInitialized=!1,this.depthClients=new Set,Oe.instance)return Oe.instance;Oe.instance=this}init(t,i,s,n,r){this.camera=t,this.options=i,this.renderer=s,this.scene=r,this.options.depthTexture.enabled&&(this.depthTextures=new Te(i),n.register(this.depthTextures)),this.options.depthMesh.enabled&&(this.depthMesh=new ye(i,this.width,this.height,this.depthTextures),n.register(this.depthMesh),this.options.depthMesh.renderShadow&&(this.renderer.shadowMap.enabled=!0,this.renderer.shadowMap.type=e.PCFShadowMap),t.add(this.depthMesh),r.add(t)),this.options.occlusion.enabled&&(this.occlusionPass=new Pe(r,t))}getDepth(e,t){if(!this.depthArray[0])return 0;const i=Math.round(T(e*this.width,0,this.width-1)),s=Math.round(T((1-t)*this.height,0,this.height-1)),n=this.depthArray[0][s*this.width+i];return this.rawValueToMeters*n}getProjectedDepthViewPositionFromWorldPosition(t,i=new e.Vector3){const s=this.renderer.xr?.getCamera?.()?.cameras?.[0]||this.camera;Ae.copy(t).applyMatrix4(s.matrixWorldInverse).applyMatrix4(s.projectionMatrix);const n=.5*(Ae.x+1),r=.5*(Ae.y+1),o=this.getDepth(n,r);return i.set(2*(n-.5),2*(r-.5),-1),i.applyMatrix4(s.projectionMatrixInverse),i.multiplyScalar((i.z-o)/i.z),i}getVertex(t,i){if(!this.depthArray[0])return null;const s=Math.round(T(t*this.width,0,this.width-1)),n=Math.round(T((1-i)*this.height,0,this.height-1)),r=this.depthArray[0][n*this.width+s],o=this.rawValueToMeters*r,a=new e.Vector3(2*(t-.5),2*(i-.5),-1);return a.applyMatrix4(this.projectionMatrixInverse),a.multiplyScalar(-o/a.z),a}updateCPUDepthData(e,t=0){this.cpuDepthData[t]=e,this.rawValueToMeters=e.rawValueToMeters,this.options.useFloat32&&(this.rawValueToMeters=1),null==this.depthArray[t]?(this.depthArray[t]=this.options.useFloat32?new Float32Array(e.data):new Uint16Array(e.data),this.width=e.width,this.height=e.height):this.depthArray[t].set(this.options.useFloat32?new Float32Array(e.data):new Uint16Array(e.data)),this.options.depthTexture.enabled&&this.depthTextures&&this.depthTextures.updateData(e,t),this.options.depthMesh.enabled&&this.depthMesh&&0==t&&this.depthMesh.updateDepth(e)}updateGPUDepthData(e,t=0){this.gpuDepthData[t]=e,this.rawValueToMeters=e.rawValueToMeters,this.options.useFloat32&&(this.rawValueToMeters=1);const i=this.options.depthMesh.enabled&&this.depthMesh?this.depthMesh.convertGPUToGPU(e):null;i&&(null==this.depthArray[t]?(this.depthArray[t]=this.options.useFloat32?new Float32Array(i.data):new Uint16Array(i.data),this.width=i.width,this.height=i.height):this.depthArray[t].set(this.options.useFloat32?new Float32Array(i.data):new Uint16Array(i.data))),this.options.depthTexture.enabled&&this.depthTextures&&this.depthTextures.updateNativeTexture(e,this.renderer,t),this.options.depthMesh.enabled&&this.depthMesh&&0==t&&(i?this.depthMesh.updateDepth(i):this.depthMesh.updateGPUDepth(e))}getTexture(e){if(this.options.depthTexture.enabled)return this.depthTextures?.get(e)}update(e){this.options.enabled&&(this.updateLocalDepth(e),this.options.occlusion.enabled&&this.renderOcclusionPass())}updateLocalDepth(e){if(fe())return;const t=this.renderer.xr?.getCamera?.()?.cameras?.[0];if(t&&this.depthMesh&&this.depthMesh.parent!=t&&(t.add(this.depthMesh),this.scene.add(t)),!e)return;const i=e.session,s=this.renderer.xr.getBinding();if(void 0!==i.depthActive&&this.depthClientsInitialized){const e=this.depthClients.size>0;if(i.depthActive&&!e?i.pauseDepthSensing?.():!i.depthActive&&e&&i.resumeDepthSensing?.(),0==this.depthClients.size)return}if(null==this.xrRefSpace)i.requestReferenceSpace("local").then((e=>{this.xrRefSpace=e})),i.addEventListener("end",(()=>{this.xrRefSpace=void 0}));else{const t=e.getViewerPose(this.xrRefSpace);if(t)for(let n=0;n<t.views.length;++n){const r=t.views[n];if(this.view[n]=r,"gpu-optimized"===i.depthUsage){const e=s.getDepthInformation(r);if(!e)return;this.updateGPUDepthData(e,n)}else{const t=e.getDepthInformation(r);if(!t)return;this.updateCPUDepthData(t,n)}}else console.error("Pose unavailable in the current frame.")}}renderOcclusionPass(){const e=this.getTexture(0);e&&this.occlusionPass.setDepthTexture(e,this.rawValueToMeters,0,this.gpuDepthData[0]?.depthNear);const t=this.getTexture(1);t&&this.occlusionPass.setDepthTexture(t,this.rawValueToMeters,1,this.gpuDepthData[1]?.depthNear);const i=this.renderer.xr.isPresenting;this.renderer.xr.isPresenting=!1,this.occlusionPass.render(this.renderer,void 0,void 0,0),this.renderer.xr.isPresenting=i;for(const e of this.occludableShaders)this.occlusionPass.updateOcclusionMapUniforms(e.uniforms,this.renderer)}debugLog(){const e=this.cpuDepthData[0].data,t=new Uint8Array(e),i=Array.from(t,(e=>String.fromCharCode(e))).join(""),s=btoa(i);console.log(s)}resumeDepth(e){this.depthClientsInitialized=!0,this.depthClients.add(e)}pauseDepth(e){this.depthClientsInitialized=!0,this.depthClients.delete(e)}}const Ie={depth:1,RGB:4/3},Le={scale:1,scaleX:.75,scaleY:.63,translateU:.2,translateV:-.02,k1:-.046,k2:0,k3:0,p1:0,p2:0,xc:0,yc:0};function Ve(e,t){if(t?.simulatorCamera){const i=window.innerWidth/window.innerHeight,s=t.simulatorCamera.width/t.simulatorCamera.height;let{u:n,v:r}=e;if(i>s){const e=s/i;n=n*e+(1-e)/2}else{const e=i/s;r=r*e+(1-e)/2}return{u:n,v:1-r}}if(!Ie||!Ie.depth||!Ie.RGB)return console.error("Invalid aspect ratios provided."),null;let i,s;Ie.depth>Ie.RGB?(s=1,i=Ie.RGB/Ie.depth):(i=1,s=Ie.depth/Ie.RGB);const n=e.u-.5,r=e.v-.5,o=n-Le.xc,a=r-Le.yc,h=o*o+a*a,l=1+Le.k1*h+Le.k2*h*h+Le.k3*h*h*h;return{u:((o*l+(2*Le.p1*o*a+Le.p2*(h+2*o*o))+Le.xc)*i+Le.translateU)*Le.scale*Le.scaleX+.5,v:1-(((a*l+(Le.p1*(h+2*a*a)+2*Le.p2*o*a)+Le.yc)*s+Le.translateV)*Le.scale*Le.scaleY+.5)}}function Be(t,i,s,n,r,o=Oe.instance){if(!(i&&s&&n&&o))return null;const a=Ve(t,r);if(!a)return null;const{u:h,v:l}=a,c=Math.round(T(h*o.width,0,o.width-1)),d=i[Math.round(T((1-l)*o.height,0,o.height-1))*o.width+c],u=o.rawValueToMeters*d,p=new e.Vector3(2*(h-.5),2*(l-.5),-1),g=s.clone().invert();p.applyMatrix4(g),p.multiplyScalar(-u/p.z);return p.clone().applyMatrix4(n)}async function Fe(t,i){if(!t)throw new Error("No image data provided for cropping.");const s=new Image;await new Promise(((e,i)=>{s.onload=e,s.onerror=e=>{console.error("Error loading image for cropping:",e),i(new Error("Failed to load image for cropping."))},s.src=t.startsWith("data:image")?t:`data:image/png;base64,${t}`}));const n=document.createElement("canvas"),r=n.getContext("2d"),o=new e.Box2(new e.Vector2(0,0),new e.Vector2(1,1)),a=i.clone().intersect(o),h=new e.Vector2;if(a.getSize(h),0===h.x||0===h.y)return"data:image/png;base64,";const l=s.width*a.min.x,c=s.height*a.min.y,d=s.width*h.x,u=s.height*h.y;return n.width=d,n.height=u,r.drawImage(s,l,c,d,u,0,0,d,u),n.toDataURL("image/png")}var ze;!function(e){e.IDLE="idle",e.INITIALIZING="initializing",e.STREAMING="streaming",e.ERROR="error",e.NO_DEVICES_FOUND="no_devices_found"}(ze||(ze={}));class ke extends S{constructor({willCaptureFrequently:t=!1}={}){super(),this.loaded=!1,this.state=ze.IDLE,this.stream_=null,this.video_=document.createElement("video"),this.frozenTexture_=null,this.canvas_=null,this.context_=null,this.willCaptureFrequently_=t,this.video_.autoplay=!0,this.video_.muted=!0,this.video_.playsInline=!0,this.texture=new e.VideoTexture(this.video_),this.texture.colorSpace=e.SRGBColorSpace,this.texture.minFilter=e.LinearFilter,this.texture.magFilter=e.LinearFilter}setState_(e,t={}){(this.state!==e||t.force)&&(this.state=e,this.dispatchEvent({type:"statechange",state:this.state,...t}),console.debug(`VideoStream state changed to ${e} with details:`,t))}handleVideoStreamLoadedMetadata(e,t,i=!1){try{if(this.video_.videoWidth>0&&this.video_.videoHeight>0)this.width=this.video_.videoWidth,this.height=this.video_.videoHeight,this.aspectRatio=this.width/this.height,this.loaded=!0,e();else if(i)setTimeout((()=>{this.handleVideoStreamLoadedMetadata(e,t,!1)}),500);else{const e=new Error("Failed to get valid video dimensions.");this.setState_(ze.ERROR,{error:e}),t(e)}}catch(e){e instanceof Error&&(this.setState_(ze.ERROR,{error:e}),t(e))}}getSnapshot({width:t=this.width,height:i=this.height,outputFormat:s="texture",mimeType:n="image/jpeg",quality:r=.9}={}){if(!this.loaded||!t||!i||this.video_.readyState<this.video_.HAVE_CURRENT_DATA)return null;(t>this.width||i>this.height)&&console.warn(`The requested snapshot width (${t}px x ${i}px) is larger than the source video width (${this.width}px x ${this.height}px). The snapshot will be upscaled.`);try{switch(this.canvas_&&this.canvas_.width===t&&this.canvas_.height===i||(this.canvas_=document.createElement("canvas"),this.canvas_.width=t,this.canvas_.height=i,this.context_=this.canvas_.getContext("2d",{willCaptureFrequently:this.willCaptureFrequently_})),this.context_.drawImage(this.video_,0,0,t,i),s){case"imageData":return this.context_.getImageData(0,0,t,i);case"base64":return this.canvas_.toDataURL(n,r);default:{const t=new e.Texture(this.canvas_);return t.needsUpdate=!0,t.colorSpace=e.SRGBColorSpace,this.frozenTexture_=t,this.frozenTexture_}}}catch(e){return console.error("Error capturing snapshot:",e),null}}stop_(){this.stream_&&(this.stream_.getTracks().forEach((e=>e.stop())),this.stream_=null),this.video_.srcObject&&(this.video_.srcObject=null),this.video_.src&&this.video_.src.startsWith("blob:")&&URL.revokeObjectURL(this.video_.src),this.video_.src="",this.loaded=!1,this.setState_(ze.IDLE)}dispose(){this.stop_(),this.texture?.dispose(),this.frozenTexture_?.dispose(),this.canvas_=null,this.context_=null,super.dispose()}}class je extends ke{constructor({videoConstraints:e={facingMode:"environment"},willCaptureFrequently:t=!1}={}){super({willCaptureFrequently:t}),this.isInitializing_=!1,this.availableDevices_=[],this.currentDeviceIndex_=-1,this.videoConstraints_={...e}}async getAvailableVideoDevices(){if(!navigator.mediaDevices?.enumerateDevices)return console.warn("navigator.mediaDevices.enumerateDevices() is not supported."),[];const e=[...await navigator.mediaDevices.enumerateDevices()];if(this.simulatorCamera){const t=await this.simulatorCamera.enumerateDevices();e.push(...t)}return e.filter((e=>"videoinput"===e.kind))}async init(){this.setState_(ze.INITIALIZING);try{this.availableDevices_=await this.getAvailableVideoDevices(),this.availableDevices_.length>0?await this.initStream_():(this.setState_(ze.NO_DEVICES_FOUND),console.warn("No video devices found."))}catch(e){throw this.setState_(ze.ERROR,{error:e}),console.error("Error initializing XRDeviceCamera:",e),e}}async initStream_(){if(!this.isInitializing_){this.isInitializing_=!0,this.setState_(ze.INITIALIZING),this.currentTrackSettings_=void 0,this.currentDeviceIndex_=-1;try{console.debug("Requesting media stream with constraints:",this.videoConstraints_);let e=null;const t=this.videoConstraints_.deviceId,i="string"==typeof t?t:Array.isArray(t)?t[0]:t?.exact;if(!!this.simulatorCamera&&(i&&"simulator"===this.availableDevices_.find((e=>e.deviceId===i))?.groupId||!i&&"environment"===this.videoConstraints_.facingMode)){if(e=this.simulatorCamera.getMedia(this.videoConstraints_),!e)throw new Error("Simulator camera failed to provide a media stream.")}else e=await navigator.mediaDevices.getUserMedia({video:this.videoConstraints_});const s=e?.getVideoTracks()||[];if(!s.length)throw new Error("MediaStream has no video tracks.");const n=s[0];this.currentTrackSettings_=n.getSettings(),console.debug("Active track settings:",this.currentTrackSettings_),this.currentTrackSettings_.deviceId?this.currentDeviceIndex_=this.availableDevices_.findIndex((e=>e.deviceId===this.currentTrackSettings_.deviceId)):console.warn("Stream started without deviceId as it was unavailable"),this.stop_(),this.stream_=e,this.video_.srcObject=e,this.video_.src="",await new Promise(((e,t)=>{this.video_.onloadedmetadata=()=>{this.handleVideoStreamLoadedMetadata(e,t,!0)},this.video_.onerror=()=>{const e=new Error("Error playing camera stream.");this.setState_(ze.ERROR,{error:e}),t(e)},this.video_.play()}));const r={width:this.width,height:this.height,aspectRatio:this.aspectRatio,device:this.getCurrentDevice(),facingMode:this.currentTrackSettings_.facingMode,trackSettings:this.currentTrackSettings_};this.setState_(ze.STREAMING,r)}catch(e){throw this.setState_(ze.ERROR,{error:e}),e}finally{this.isInitializing_=!1}}}async setDeviceId(e){const t=this.availableDevices_.findIndex((t=>t.deviceId===e));if(-1===t)throw new Error(`Device with ID ${e} not found.`);t!==this.currentDeviceIndex_?(delete this.videoConstraints_.facingMode,this.videoConstraints_.deviceId={exact:e},await this.initStream_()):console.log(`Device ${e} is already active.`)}async setFacingMode(e){delete this.videoConstraints_.deviceId,this.videoConstraints_.facingMode=e,this.currentDeviceIndex_=-1,await this.initStream_()}getAvailableDevices(){return this.availableDevices_}getCurrentDevice(){if(-1!==this.currentDeviceIndex_&&this.availableDevices_.length)return this.availableDevices_[this.currentDeviceIndex_]}getCurrentTrackSettings(){return this.currentTrackSettings_}getCurrentDeviceIndex(){return this.currentDeviceIndex_}registerSimulatorCamera(e){this.simulatorCamera=e,this.init()}}class Ue{constructor(){this.instances=new Map}register(e,t){const i=t??e.constructor;if(!(e instanceof i))throw new Error(`Instance of type '${e.constructor.name}' is not an instance of the registration type '${i.name}'.`);this.instances.set(i,e)}get(e){return this.instances.get(e)}getOrCreate(e,t){let i=this.get(e);if(void 0===i){if(i=t(),!(i instanceof e))throw new Error(`Factory for type ${e.name} returned an incompatible instance of type ${i.constructor.name}.`);this.register(i,e)}return i}unregister(e){this.instances.delete(e)}}function Ne(e,t,i){const s=4*t,n=new Uint8Array(s);for(let t=0;t<i/2;t++){const r=t*s,o=(i-1-t)*s;n.set(e.subarray(r,r+s)),e.set(e.subarray(o,o+s),r),e.set(n,o)}}class Ge{constructor(e,t,i){this.resolve=e,this.reject=t,this.overlayOnCamera=i}}class He{constructor(){this.pendingScreenshotRequests=[],this.virtualBuffer=new Uint8Array,this.virtualRealBuffer=new Uint8Array,this.renderTargetWidth=640}async onAfterRender(e,t,i){if(0==this.pendingScreenshotRequests.length)return;if(null==e.getRenderTarget())throw new Error("Expecting render target");this.pendingScreenshotRequests.every((e=>!e.overlayOnCamera))&&this.createVirtualImageDataURL(e,t).then((e=>{this.resolveVirtualOnlyRequests(e)}));const s=this.pendingScreenshotRequests.some((e=>e.overlayOnCamera));if(s&&i)this.createVirtualRealImageDataURL(e,t,i).then((e=>{e&&this.resolveVirtualRealRequests(e)}));else if(s)throw new Error("No device camera provided")}async createVirtualImageDataURL(t,i){const s=t.getRenderTarget(),n=t.xr.isPresenting&&2==t.xr.getCamera().cameras.length?s.width/2:s.width,r=Math.round(s.height*(this.renderTargetWidth/n));this.virtualRenderTarget&&this.virtualRenderTarget.width==this.renderTargetWidth||(this.virtualRenderTarget?.dispose(),this.virtualRenderTarget=new e.WebGLRenderTarget(this.renderTargetWidth,r,{colorSpace:e.SRGBColorSpace}));const o=t.xr.isPresenting;t.xr.isPresenting=!1;const a=this.virtualRenderTarget;t.setRenderTarget(a),t.clearColor(),t.clearDepth(),i(),t.setRenderTarget(s),t.xr.isPresenting=o;const h=a.width*a.height*4;this.virtualBuffer.length!=h&&(this.virtualBuffer=new Uint8Array(h));const l=this.virtualBuffer;await t.readRenderTargetPixelsAsync(a,0,0,a.width,a.height,l),Ne(l,a.width,a.height);const c=this.virtualCanvas||(this.virtualCanvas=document.createElement("canvas"));c.width=a.width,c.height=a.height;const d=c.getContext("2d");if(!d)throw new Error("Failed to get 2D context");const u=new ImageData(new Uint8ClampedArray(l),a.width,a.height);return d.putImageData(u,0,0),c.toDataURL()}resolveVirtualOnlyRequests(e){let t=0;for(let i=0;i<this.pendingScreenshotRequests.length;i++){const s=this.pendingScreenshotRequests[i];s.overlayOnCamera?this.pendingScreenshotRequests[t++]=s:s.resolve(e)}this.pendingScreenshotRequests.length=t}async createVirtualRealImageDataURL(t,i,s){if(!s.loaded)return console.debug("Waiting for device camera to be loaded"),null;const n=t.getRenderTarget(),r=t.xr.isPresenting&&2==t.xr.getCamera().cameras.length?n.width/2:n.width,o=Math.round(n.height*(this.renderTargetWidth/r));this.virtualRealRenderTarget&&this.virtualRealRenderTarget.height==o||(this.virtualRealRenderTarget?.dispose(),this.virtualRealRenderTarget=new e.WebGLRenderTarget(this.renderTargetWidth,o,{colorSpace:e.SRGBColorSpace}));const a=this.virtualRealRenderTarget;t.setRenderTarget(a);const h=t.xr.isPresenting;t.xr.isPresenting=!1;const l=this.getFullScreenQuad();l.material.map=s.texture,l.render(t),i(),t.xr.isPresenting=h,t.setRenderTarget(n),this.virtualRealBuffer.length!=a.width*a.height*4&&(this.virtualRealBuffer=new Uint8Array(a.width*a.height*4));const c=this.virtualRealBuffer;await t.readRenderTargetPixelsAsync(a,0,0,a.width,a.height,c),Ne(c,a.width,a.height);const d=this.virtualRealCanvas||(this.virtualRealCanvas=document.createElement("canvas"));d.width=a.width,d.height=a.height;const u=d.getContext("2d");if(!u)throw new Error("Failed to get 2D context");const p=new ImageData(new Uint8ClampedArray(c),a.width,a.height);return u.putImageData(p,0,0),d.toDataURL()}resolveVirtualRealRequests(e){let t=0;for(let i=0;i<this.pendingScreenshotRequests.length;i++){const s=this.pendingScreenshotRequests[i];s.overlayOnCamera?s.resolve(e):this.pendingScreenshotRequests[t++]=s}this.pendingScreenshotRequests.length=t}getFullScreenQuad(){return this.fullScreenQuad||(this.fullScreenQuad=new i(new e.MeshBasicMaterial({transparent:!0}))),this.fullScreenQuad}async getScreenshot(e=!1){return await new Promise(((t,i)=>{this.pendingScreenshotRequests.push(new Ge(t,i,e))}))}}class We{constructor(e){this.initScriptFunction=e,this.scripts=new Set,this.callSelectStartBound=this.callSelectStart.bind(this),this.callSelectEndBound=this.callSelectEnd.bind(this),this.callSelectBound=this.callSelect.bind(this),this.callSqueezeStartBound=this.callSqueezeStart.bind(this),this.callSqueezeEndBound=this.callSqueezeEnd.bind(this),this.callSqueezeBound=this.callSqueeze.bind(this),this.callKeyDownBound=this.callKeyDown.bind(this),this.callKeyUpBound=this.callKeyUp.bind(this),this.initializingScripts=new Set}async initScript(e){this.scripts.has(e)||this.initializingScripts.has(e)||(this.initializingScripts.add(e),await this.initScriptFunction(e),this.scripts.add(e),this.initializingScripts.delete(e))}uninitScript(e){this.scripts.has(e)&&(e.dispose(),this.scripts.delete(e),this.initializingScripts.delete(e))}async syncScriptsWithScene(e){const t=new Set,i=[];e.traverse((e=>{if(e.isXRScript){const s=e;i.push(this.initScript(s)),t.add(s)}})),await Promise.allSettled(i);for(const e of this.scripts)t.has(e)||this.uninitScript(e)}callSelectStart(e){for(const t of this.scripts)t.onSelectStart(e)}callSelectEnd(e){for(const t of this.scripts)t.onSelectEnd(e)}callSelect(e){for(const t of this.scripts)t.onSelect(e)}callSqueezeStart(e){for(const t of this.scripts)t.onSqueezeStart(e)}callSqueezeEnd(e){for(const t of this.scripts)t.onSqueezeEnd(e)}callSqueeze(e){for(const t of this.scripts)t.onSqueeze(e)}callKeyDown(e){for(const t of this.scripts)t.onKeyDown(e)}callKeyUp(e){for(const t of this.scripts)t.onKeyUp(e)}onXRSessionStarted(e){for(const t of this.scripts)t.onXRSessionStarted(e)}onXRSessionEnded(){for(const e of this.scripts)e.onXRSessionEnded()}onSimulatorStarted(){for(const e of this.scripts)e.onSimulatorStarted()}}class qe{constructor(){this.callbacks=[]}onFrame(){this.callbacks.forEach((e=>{try{e()}catch(e){console.error(e)}})),this.callbacks.length=0}async waitFrame(){return new Promise((e=>{this.callbacks.push(e)}))}}var Xe;!function(e){e.UNSUPPORTED="unsupported",e.READY="ready",e.SESSION_START="sessionstart",e.SESSION_END="sessionend"}(Xe||(Xe={}));class Ke extends e.EventDispatcher{constructor(e,t,i){super(),this.renderer=e,this.sessionInit=t,this.mode=i,this.onSessionEndedBound=this.onSessionEndedInternal.bind(this)}async initialize(){if(!("xr"in navigator))return console.warn("WebXR not supported"),this.xrModeSupported=!1,void this.dispatchEvent({type:Xe.UNSUPPORTED});let e=!1;try{e=await navigator.xr.isSessionSupported(this.mode)||!1}catch(e){return console.error("Error getting isSessionSupported",e),this.xrModeSupported=!1,void this.dispatchEvent({type:Xe.UNSUPPORTED})}e?(this.xrModeSupported=!0,this.sessionOptions={...this.sessionInit,optionalFeatures:["local-floor",...this.sessionInit.optionalFeatures||[]]},this.dispatchEvent({type:Xe.READY,sessionOptions:this.sessionOptions}),void 0!==navigator.xr.offerSession&&navigator.xr.offerSession(this.mode,this.sessionOptions).then(this.onSessionStartedInternal.bind(this)).catch((e=>{console.warn(e)}))):(console.log(`${this.mode} not supported`),this.xrModeSupported=!1,this.dispatchEvent({type:Xe.UNSUPPORTED}))}startSession(){if(void 0===this.xrModeSupported)throw new Error("Initialize not yet complete");if(!this.xrModeSupported)throw new Error("WebXR not supported");if(this.currentSession)throw new Error("Session already started");navigator.xr.requestSession(this.mode,this.sessionOptions).then(this.onSessionStartedInternal.bind(this))}endSession(){if(!this.currentSession)throw new Error("No session to end");this.currentSession.end(),this.currentSession=void 0}isXRSupported(){return this.xrModeSupported}async onSessionStartedInternal(e){e.addEventListener("end",this.onSessionEndedBound),await this.renderer.xr.setSession(e),this.currentSession=e,this.dispatchEvent({type:Xe.SESSION_START,session:e})}onSessionEndedInternal(){this.dispatchEvent({type:Xe.SESSION_END}),this.currentSession?.removeEventListener("end",this.onSessionEndedBound),this.currentSession=void 0}}const $e="XRButton";class Qe{constructor(e,t="ENTER XR",i="END XR",s="XR NOT SUPPORTED",n="START SIMULATOR",r=!1,o=!1,a=()=>{}){this.sessionManager=e,this.startText=t,this.endText=i,this.invalidText=s,this.startSimulatorText=n,this.startSimulator=a,this.domElement=document.createElement("div"),this.simulatorButtonElement=document.createElement("button"),this.xrButtonElement=document.createElement("button"),this.domElement.id="XRButtonWrapper",this.createXRButtonElement(),r&&(fe()||o)&&this.createSimulatorButton(),this.sessionManager.addEventListener(Xe.UNSUPPORTED,this.showXRNotSupported.bind(this)),this.sessionManager.addEventListener(Xe.READY,(()=>this.onSessionReady())),this.sessionManager.addEventListener(Xe.SESSION_START,(()=>this.onSessionStarted())),this.sessionManager.addEventListener(Xe.SESSION_END,this.onSessionEnded.bind(this))}createSimulatorButton(){this.simulatorButtonElement.classList.add($e),this.simulatorButtonElement.innerText=this.startSimulatorText,this.simulatorButtonElement.onclick=()=>{this.domElement.remove(),this.startSimulator()},this.domElement.appendChild(this.simulatorButtonElement)}createXRButtonElement(){this.xrButtonElement.classList.add($e),this.xrButtonElement.disabled=!0,this.xrButtonElement.textContent="...",this.domElement.appendChild(this.xrButtonElement)}onSessionReady(){const e=this.xrButtonElement;e.style.display="",e.innerHTML=this.startText,e.disabled=!1,e.onclick=()=>{this.sessionManager.startSession()}}showXRNotSupported(){this.xrButtonElement.textContent=this.invalidText,this.xrButtonElement.disabled=!0}async onSessionStarted(){this.xrButtonElement.innerHTML=this.endText}onSessionEnded(){this.xrButtonElement.innerHTML=this.startText}}class Ye extends t{render(e,t,i,s,n,r=0){}}class Je{constructor(t,i,s){this.renderer=t,this.scene=i,this.timer=s,this.passes=[],this.renderTargets=[],this.dimensions=new e.Vector2}addPass(e){e.renderToScreen=!1,this.passes.push(e)}setupRenderTargets(t){const i=this.renderer.getRenderTarget();if(null==i)return;const s=this.renderer.xr.isPresenting?4:2;for(let n=0;n<s;n++)(n>=this.renderTargets.length||this.renderTargets[n].width!=t.x||this.renderTargets[n].height!=t.y)&&(this.renderTargets[n]?.depthTexture?.dispose(),this.renderTargets[n]?.dispose(),this.renderTargets[n]=i.clone(),this.renderTargets[n].depthTexture=new e.DepthTexture(t.x,t.y));for(let e=s;e<this.renderTargets.length;e++)this.renderTargets[e].depthTexture?.dispose(),this.renderTargets[e].dispose()}render(){this.renderer.getDrawingBufferSize(this.dimensions),this.setupRenderTargets(this.dimensions),this.renderer.xr.cameraAutoUpdate=!1;this.renderer.getRenderTarget()&&(this.renderer.xr.isPresenting?this.renderXr():this.renderSimulator())}renderXr(){const t=this.renderer.getRenderTarget(),i=this.renderer,s=i.xr.enabled,n=i.xr.isPresenting,r=this.renderTargets,o=new e.Vector4;i.getViewport(o),i.xr.cameraAutoUpdate=!1,i.xr.enabled=!1;const a=this.timer.getDelta();if(2==i.xr.getCamera().cameras.length){for(let e=0;e<2;++e){const t=i.xr.getCamera().cameras[e];i.setViewport(t.viewport),i.setRenderTarget(r[e]),i.clear(),i.xr.isPresenting=!0,i.render(this.scene,t)}i.setRenderTarget(t),i.clear(),i.xr.isPresenting=!1,i.autoClearColor=!1;for(let e=0;e<2;e++){for(let s=0;s<this.passes.length-1;++s){const n=s%2,r=(s+1)%2;t.viewport.set(e*this.dimensions.x/2,0,this.dimensions.x/2,this.dimensions.y),this.passes[s].render(i,this.renderTargets[2*r+e],this.renderTargets[2*n+e],a,!1,e)}if(this.passes.length>0){const s=(this.passes.length-1)%2;t.viewport.set(e*this.dimensions.x/2,0,this.dimensions.x/2,this.dimensions.y),this.passes[this.passes.length-1].render(i,t,this.renderTargets[2*s+e],a,!1,e)}}i.xr.enabled=s,i.xr.isPresenting=n}}renderSimulator(){const t=this.renderer.getRenderTarget(),i=this.renderer,s=i.xr.enabled,n=i.xr.isPresenting,r=new e.Vector4;i.getViewport(r),i.xr.cameraAutoUpdate=!1,i.xr.enabled=!1;const o=this.timer.getDelta();i.setRenderTarget(t),i.clear(),i.xr.isPresenting=!1,i.autoClearColor=!1;for(let e=0;e<this.passes.length-1;++e){const t=e%2,s=(e+1)%2;this.passes[e].render(i,this.renderTargets[s],this.renderTargets[t],o,!1,0)}if(this.passes.length>0){const e=(this.passes.length-1)%2;this.passes[this.passes.length-1].render(i,t,this.renderTargets[e],o,!1,0)}i.xr.enabled=s,i.xr.isPresenting=n}}const Ze=["wrist","thumb-metacarpal","thumb-phalanx-proximal","thumb-phalanx-distal","thumb-tip","index-finger-metacarpal","index-finger-phalanx-proximal","index-finger-phalanx-intermediate","index-finger-phalanx-distal","index-finger-tip","middle-finger-metacarpal","middle-finger-phalanx-proximal","middle-finger-phalanx-intermediate","middle-finger-phalanx-distal","middle-finger-tip","ring-finger-metacarpal","ring-finger-phalanx-proximal","ring-finger-phalanx-intermediate","ring-finger-phalanx-distal","ring-finger-tip","pinky-finger-metacarpal","pinky-finger-phalanx-proximal","pinky-finger-phalanx-intermediate","pinky-finger-phalanx-distal","pinky-finger-tip"];var et;!function(e){e[e.NONE=-1]="NONE",e[e.LEFT=0]="LEFT",e[e.RIGHT=1]="RIGHT"}(et||(et={}));class tt{constructor(e){this.hands=e,this.dominant=et.RIGHT}getJoint(e,t){let i=t;i===et.NONE&&(i=this.dominant);const s=this.hands[i];if(s){if(s.joints&&e in s.joints)return s.joints[e]}else console.log("no hand")}getIndexTip(e=et.NONE){return this.getJoint("index-finger-tip",e)}getThumbTip(e=et.NONE){return this.getJoint("thumb-tip",e)}getMiddleTip(e=et.NONE){return this.getJoint("middle-finger-tip",e)}getRingTip(e=et.NONE){return this.getJoint("ring-finger-tip",e)}getPinkyTip(e=et.NONE){return this.getJoint("pinky-finger-tip",e)}getWrist(e=et.NONE){return this.getJoint("wrist",e)}toString(){let e="";return[et.LEFT,et.RIGHT].forEach((t=>{const i=this.hands[t];i&&i.joints?Ze.forEach((s=>{const n=i.joints[s];n?n.position?e+=`${t} - ${s}: ${n.position.x.toFixed(3)}, ${n.position.y.toFixed(3)}, ${n.position.z.toFixed(3)}\n`:e+=`${t} - ${s}: Position unavailable\n`:e+=`${t} - ${s}: Joint unavailable\n`})):e+=`${t} Hand: Data unavailable\n`})),e}toPositionQuaternionArray(){const e=[],t=[et.LEFT,et.RIGHT],i=Ze.length;t.forEach((t=>{const i=this.hands[t],s=i&&i.joints;Ze.forEach((t=>{const n=s?i.joints[t]:null;if(n&&n.position&&n.quaternion)e.push(n.position.x,n.position.y,n.position.z),e.push(n.quaternion.x,n.quaternion.y,n.quaternion.z,n.quaternion.w);else for(let t=0;t<7;t++)e.push(0)}))}));const s=t.length*i*7;if(e.length!==s)for(console.error(`XRHands.toPositionQuaternionArray: Output array size mismatch. Expected ${s}, got ${e.length}. Padding with zeros.`);e.length<s;)e.push(0);return e}isValid(e){return!(!this.hands||!Array.isArray(this.hands)||2!==this.hands.length)&&(0===e||1===e?!!this.hands[e]:!!this.hands[et.LEFT]&&!!this.hands[et.RIGHT])}}const it={uniforms:{uColor:{value:(new e.Color).setHex(16777215)},uPressed:{value:0}},vertexShader:"\n varying vec2 vTexCoord;\n\n void main() {\n vTexCoord = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n // Makes the position slightly closer to avoid z fighting.\n gl_Position.z -= 0.1;\n }\n",fragmentShader:'\n precision mediump float;\n\n uniform sampler2D uDepthTexture;\n uniform vec3 uColor;\n uniform float uPressed;\n\n varying vec2 vTexCoord;\n\n void main(void) {\n // Distance from center of quad.\n highp float dist = distance(vTexCoord, vec2(0.5f, 0.5f));\n if (dist > 0.45) discard;\n\n // Get the rate of change of dist on x and y.\n highp vec2 dist_grad = vec2(dFdx(dist), dFdy(dist));\n highp float grad_magnitude = length(dist_grad);\n highp float antialias_dist = max(grad_magnitude, 0.001f);\n\n // Outer radius is 0.5, but we want to bring it in a few pixels so we have room\n // for a gradient outward to anti-alias the circle.\n // These "few pixels" are determined by our derivative calculation above.\n highp float outerradius = 0.5f - antialias_dist;\n highp float delta_to_outer = dist - outerradius;\n highp float clamped_outer_delta = clamp(delta_to_outer, 0.0f, antialias_dist);\n highp float outer_alpha = 1.0f - (clamped_outer_delta / antialias_dist);\n\n // #FFFFFF = (1,1,1)\n // #FFFFFF with 0.5 alpha = (((1,1,1) * 0.5), 0.5)\n vec4 inner_base_color = vec4(0.5 * uColor, 0.5);\n vec4 pressed_inner_color = vec4(uColor, 1.0);\n // #505050 = (0.077,0.077,0.077)\n // #505050 with 0.7 alpha = (((0.077,0.077,0.077)*0.7), 0.7)\n const vec4 inner_gradient_color = vec4(0.054, 0.054, 0.054, 1.0);\n const vec4 outer_ring_color = vec4(0.077, 0.077, 0.077, 1.0);\n // 0.5 - stoke_width (0.75dp = 0.04 approx)\n const float gradient_end = 0.46;\n // 73% of gradient_end\n const float gradient_start = 0.33;\n // gradient_end - 130% stoke_width. Additional 30% to account for the down scaling.\n const float pressed_inner_radius = 0.41;\n\n vec4 unpressed_inner_color =\n mix(inner_base_color, inner_gradient_color,\n smoothstep(gradient_start, gradient_end, dist));\n vec4 unpressed_color =\n mix(unpressed_inner_color, outer_ring_color,\n step(gradient_end, dist));\n\n // Builds a smooth gradient to fade between colors.\n highp float smooth_distance = antialias_dist * 4.0;\n float percent_to_inner_rad = max(pressed_inner_radius - dist, 0.0) / pressed_inner_radius;\n highp float pressed_color_t = 1.0 - percent_to_inner_rad;\n pressed_color_t -= (1.0 - smooth_distance);\n pressed_color_t *= (1.0 / smooth_distance);\n pressed_color_t = clamp(pressed_color_t, 0.0, 1.0);\n vec4 pressed_color = mix(pressed_inner_color, outer_ring_color, pressed_color_t);\n\n vec4 final_color = mix(unpressed_color, pressed_color, uPressed);\n gl_FragColor = final_color * outer_alpha;\n // Converts to straight alpha.\n gl_FragColor.rgb = gl_FragColor.rgb / max(gl_FragColor.a, 0.001);\n }\n'};class st extends e.Mesh{constructor(t=.8,i=.001,s=.019,n=!1){const r=new e.CircleGeometry(s,32);r.applyMatrix4((new e.Matrix4).makeTranslation(0,0,i)),super(r,new e.ShaderMaterial({uniforms:e.UniformsUtils.clone(it.uniforms),vertexShader:it.vertexShader,fragmentShader:it.fragmentShader,depthTest:n,transparent:!0})),this.name="Reticle",this.ignoreReticleRaycast=!0,this.direction=new e.Vector3,this.renderOrder=1e3,this.originalNormal=new e.Vector3(0,0,1),this.newRotation=new e.Quaternion,this.objectRotation=new e.Quaternion,this.normalVector=new e.Vector3,this.rotationSmoothing=t,this.offset=i}setRotationFromNormalVector(e){const t=this.originalNormal.angleTo(e);this.originalNormal.cross(e).normalize(),this.newRotation.setFromAxisAngle(this.originalNormal,t),this.originalNormal.set(0,0,1),this.quaternion.slerp(this.newRotation,1-this.rotationSmoothing)}setPoseFromIntersection(e){e&&e.normal&&(this.intersection=e,this.position.copy(e.point),e.object.getWorldQuaternion(this.objectRotation),this.normalVector.copy(e.normal).applyQuaternion(this.objectRotation),this.setRotationFromNormalVector(this.normalVector))}setColor(e){this.material.uniforms.uColor.value.set(e)}getColor(){return this.material.uniforms.uColor.value}setPressed(e){this.material.uniforms.uPressed.value=e?1:0,this.scale.setScalar(e?.7:1)}setPressedAmount(e){this.material.uniforms.uPressed.value=e,this.scale.setScalar(R(1,.7,e))}raycast(){}}class nt extends e.Line{constructor(){super((new e.BufferGeometry).setFromPoints([new e.Vector3(0,0,0),new e.Vector3(0,0,-1)])),this.scale.z=5}raycast(){}}class rt{constructor(e=0,t=0,i=1,s=1){this.value=e,this.minValue=t,this.maxValue=i,this.speed=s}update(e){this.value=T(this.value+e*this.speed,this.minValue,this.maxValue)}}class ot extends S{constructor(){super(...arguments),this.userData={connected:!1,id:2,selected:!1},this.reticle=new st,this.activationTimeSeconds=1.5,this.activationAmount=new rt(0,0,1,1/this.activationTimeSeconds),this.lastReticlePosition=new e.Vector3,this.clock=new e.Clock}static{this.dependencies={camera:e.Camera}}init({camera:e}){this.camera=e}update(){super.update(),this.position.copy(this.camera.position),this.quaternion.copy(this.camera.quaternion),this.updateMatrixWorld();const e=this.clock.getDelta();this.activationAmount.update(e);this.lastReticlePosition.distanceTo(this.reticle.position)/e>.2&&(this.activationAmount.value=0,this.userData.selected&&this.callSelectEnd(),this.userData.selected=!1),1!=this.activationAmount.value||this.userData.selected||this.callSelectStart(),this.updateReticleScale(),this.lastReticlePosition.copy(this.reticle.position)}updateReticleScale(){this.reticle.setPressedAmount(this.activationAmount.value)}callSelectStart(){this.dispatchEvent({type:"selectstart",target:this})}callSelectEnd(){this.dispatchEvent({type:"selectend",target:this})}connect(){this.dispatchEvent({type:"connected",target:this})}disconnect(){this.dispatchEvent({type:"disconnected",target:this})}}class at extends S{static{this.dependencies={camera:e.Camera}}constructor(){super(),this.userData={id:3,connected:!1,selected:!1},this.raycaster=new e.Raycaster,this.forwardVector=new e.Vector3(0,0,-1)}init({camera:e}){this.camera=e}update(){super.update(),this.userData.connected&&this.position.copy(this.camera.position)}updateMousePositionFromEvent(t){this.position.copy(this.camera.position);const i=new e.Vector2;i.x=t.clientX/window.innerWidth*2-1,i.y=-t.clientY/window.innerHeight*2+1,this.raycaster.setFromCamera(i,this.camera);const s=this.raycaster.ray.direction;this.quaternion.setFromUnitVectors(this.forwardVector,s),this.updateMatrixWorld()}callSelectStart(){this.dispatchEvent({type:"selectstart",target:this})}callSelectEnd(){this.dispatchEvent({type:"selectend",target:this})}connect(){this.dispatchEvent({type:"connected",target:this})}disconnect(){this.dispatchEvent({type:"disconnected",target:this})}}class ht extends e.Object3D{}const lt=new e.Matrix4;class ct{constructor(){this.controllers=[],this.controllerGrips=[],this.hands=[],this.raycaster=new e.Raycaster,this.initialized=!1,this.pivotsEnabled=!1,this.gazeController=new ot,this.mouseController=new at,this.controllersEnabled=!0,this.listeners=new Map,this.intersectionsForController=new Map,this.intersections=[],this.activeControllers=new ht}init({scene:e,options:t,renderer:i}){e.add(this.activeControllers),this.options=t,this.scene=e;const r=this.controllers,o=this.controllerGrips;for(let e=0;e<2;++e)r.push(i.xr.getController(e)),r[e].userData.id=e,this.activeControllers.add(this.controllers[e]);r.push(this.gazeController),r.push(this.mouseController),this.activeControllers.add(this.mouseController);for(const e of r)this.intersectionsForController.set(e,[]);if(t.controllers.enabled){if(t.controllers.visualization){const e=new s;for(let t=0;t<2;++t)o.push(i.xr.getControllerGrip(t)),o[t].add(e.createControllerModel(o[t])),this.activeControllers.add(o[t])}if(t.hands.enabled){for(let e=0;e<2;++e)this.hands.push(i.xr.getHand(e)),this.activeControllers.add(this.hands[e]);if(t.hands.visualization){if(t.hands.visualizeJoints){console.log("Visualize hand joints.");const e=new n;for(let t=0;t<2;++t){const i=e.createHandModel(this.hands[t],"boxes");i.ignoreReticleRaycast=!0,this.hands[t].add(i)}}if(t.hands.visualizeMeshes){console.log("Visualize hand meshes.");const e=new n;for(let t=0;t<2;++t){const i=e.createHandModel(this.hands[t],"mesh");i.ignoreReticleRaycast=!0,this.hands[t].add(i)}}}}}if(t.controllers.visualizeRays)for(let e=0;e<2;++e)r[e].add(new nt);this.bindSelectStart(this.defaultOnSelectStart.bind(this)),this.bindSelectEnd(this.defaultOnSelectEnd.bind(this)),this.bindSqueezeStart(this.defaultOnSelectStart.bind(this)),this.bindSqueezeEnd(this.defaultOnSelectEnd.bind(this)),this.bindListener("connected",this.defaultOnConnected.bind(this)),this.bindListener("disconnected",this.defaultOnDisconnected.bind(this))}get(e){return this.controllers[e]}addObject(t){const i=new e.Group;i.add(t);for(let e=0;e<this.controllers.length;++e)this.controllers[e].add(i.clone())}enablePivots(){if(this.pivotsEnabled)return;this.pivotsEnabled=!0;const t=new e.Mesh(new e.IcosahedronGeometry(.01,3));t.name="pivot",t.position.z=-.05,this.addObject(t)}addReticles(){let e=0;for(const t of this.controllers)null==t.reticle&&(t.reticle=new st,t.reticle.name="Reticle "+e,++e),t.reticle.visible=!1,this.scene.add(t.reticle)}defaultOnSelectStart(e){const t=e.target;t.userData.selected=!0,this._setRaycasterFromController(t),this.performRaycastOnScene(t)}defaultOnSelectEnd(e){e.target.userData.selected=!1}defaultOnSqueezeStart(e){e.target.userData.squeezing=!0}defaultOnSqueezeEnd(e){e.target.userData.squeezing=!1}defaultOnConnected(e){const t=e.target;switch(t.userData.connected=!0,t.gamepad=e.data?.gamepad,t.inputSource=e.data,e.data?.handedness){case"left":this.leftController=t;break;case"right":this.rightController=t}}defaultOnDisconnected(e){const t=e.target;switch(t.userData.connected=!1,t.reticle&&(t.reticle.visible=!1),delete t?.gamepad,e.data?.handedness){case"left":this.leftController=void 0;break;case"right":this.rightController=void 0}}bindListener(e,t){for(const i of this.controllers)i.addEventListener(e,t);this.listeners.has(e)||this.listeners.set(e,[]),this.listeners.get(e).push(t)}unbindListener(e,t){if(this.listeners.has(e)){const i=this.listeners.get(e),s=i.indexOf(t);-1!==s&&i.splice(s,1)}for(const i of this.controllers)i.removeEventListener(e,t)}dispatchEvent(e){if(this.listeners.has(e.type))for(const t of this.listeners.get(e.type))t(e)}bindSelectStart(e){this.bindListener("selectstart",e)}bindSelectEnd(e){this.bindListener("selectend",e)}bindSelect(e){this.bindListener("select",e)}bindSqueezeStart(e){this.bindListener("squeezestart",e)}bindSqueezeEnd(e){this.bindListener("squeezeend",e)}bindSqueeze(e){this.bindListener("squeeze",e)}bindKeyDown(e){window.addEventListener("keydown",e)}bindKeyUp(e){window.addEventListener("keyup",e)}unbindKeyDown(e){window.removeEventListener("keydown",e)}unbindKeyUp(e){window.removeEventListener("keyup",e)}intersectObjectByController(e,t){return e.updateMatrixWorld(),this.raycaster.setFromXRController(e),this.raycaster.intersectObject(t,!1)}intersectObjectByEvent(e,t){return this.intersectObjectByController(e.target,t)}intersectObject(e){const t=this.intersectObjectByController(this.controllers[0],e);return t.length>0?t:this.intersectObjectByController(this.controllers[1],e)}update(){if(this.controllersEnabled)for(const e of this.controllers)this.updateController(e)}updateController(e){!1!==e.userData.connected&&(e.updateMatrixWorld(),this._setRaycasterFromController(e),this.performRaycastOnScene(e),this.updateReticleFromIntersections(e))}_setRaycasterFromController(e){e.getWorldPosition(this.raycaster.ray.origin),lt.identity().extractRotation(e.matrixWorld),this.raycaster.ray.direction.set(0,0,-1).applyMatrix4(lt).normalize()}updateReticleFromIntersections(e){if(!e.reticle)return;const t=e.reticle,i=this.intersectionsForController.get(e)?.find((e=>{let t=e.object;for(;t;){if(!0===t.ignoreReticleRaycast)return!1;t=t.parent}return!0}));i?(t.visible=!0,i.object?.isXRScript?i.object.ux.update(e,i):i.object?.parent?.isXRScript&&i.object.parent.ux.update(e,i),t.intersection=i,t.direction.copy(this.raycaster.ray.direction).normalize(),t.setPoseFromIntersection(i),t.setPressed(e.userData.selected)):t.visible=!1}enableGazeController(){this.activeControllers.add(this.gazeController),this.gazeController.connect()}disableGazeController(){this.gazeController.disconnect(),this.activeControllers.remove(this.gazeController)}disableControllers(){this.controllersEnabled=!1;for(const e of this.controllers)e.userData.selected=!1,e.reticle&&(e.reticle.visible=!1,e.reticle.targetObject=void 0)}enableControllers(){this.controllersEnabled=!0}performRaycastOnScene(e){this.intersectionsForController.has(e)||this.intersectionsForController.set(e,[]);const t=this.intersectionsForController.get(e);t.length=0,this.raycaster.intersectObject(this.scene,!0,t)}}class dt{constructor(){if(this.dirLight=new e.DirectionalLight,this.ambientProbe=new e.LightProbe,this.ambientLight=new e.Vector3,this.shadowOpacity=0,this.lightGroup=new e.Group,this.simulatorRunning=!1,dt.instance)return dt.instance;dt.instance=this}init(t,i,s,n){if(this.options=t,this.depth=n,this.options.enabled){if(this.xrLight=new r(i),this.options.castDirectionalLightShadow&&(i.shadowMap.enabled=!0,i.shadowMap.type=e.PCFShadowMap),this.options.castDirectionalLightShadow){const t=this.dirLight;t.castShadow=!0,t.shadow.mapSize.width=2048,t.shadow.mapSize.height=2048,t.shadow.camera.near=.3,t.shadow.camera.far=50;const i=4;t.shadow.camera.left=-4,t.shadow.camera.right=i,t.shadow.camera.top=i,t.shadow.camera.bottom=-4,t.shadow.blurSamples=25,t.shadow.radius=5,t.shadow.bias=0,this.lightGroup.add(t.target),this.options.debugging&&s.add(new e.CameraHelper(t.shadow.camera))}this.options.useAmbientSH&&this.lightGroup.add(this.ambientProbe),this.options.useDirectionalLight&&this.lightGroup.add(this.dirLight),s.add(this.lightGroup),this.xrLight.addEventListener("estimationend",(()=>{s.remove(this.xrLight)}))}}update(){if(this.options.enabled&&(this.dirLight.position.copy(this.xrLight.directionalLight.position).multiplyScalar(20),this.dirLight.target.position.setScalar(0),this.dirLight.color=this.xrLight.directionalLight.color,this.dirLight.intensity=this.xrLight.directionalLight.intensity,this.ambientProbe.sh.copy(this.xrLight.lightProbe.sh),this.ambientProbe.intensity=this.xrLight.lightProbe.intensity,this.ambientLight.copy(this.xrLight.lightProbe.sh.coefficients[0]),this.simulatorRunning&&(this.dirLight.position.set(-10,10,-2),this.dirLight.target.position.set(0,0,-.5),this.dirLight.color.setHex(16777215),this.dirLight.intensity=3.8,this.ambientProbe.sh.fromArray([.22636516392230988,.2994415760040283,.2827182114124298,.03430574759840965,.029604531824588776,-.002050594426691532,.016114741563796997,.004344218410551548,.07621686905622482,.024204734712839127,-.02397896535694599,-.07645703107118607,.15790101885795593,.16706973314285278,.18418270349502563,-.13088643550872803,-.1461198776960373,-.1411236822605133,.04788218438625336,.08909443765878677,.10185115039348602,.020251473411917686,-.002100071171298623,-.06455840915441513,-.12393051385879517,-.05158703774213791,-.00532124936580658]),this.ambientProbe.intensity=1,this.ambientLight.copy(this.ambientProbe.sh.coefficients[0])),this.options.castDirectionalLightShadow&&this.options.useDynamicSoftShadow)){const t=this.ambientLight,i=.21*t.x+.72*t.y+.07*t.z,s=new e.Vector3(this.dirLight.color.r,this.dirLight.color.g,this.dirLight.color.b).multiplyScalar(this.dirLight.intensity),n=i/(.21*s.x+.72*s.y+.07*s.z);this.dirLight.shadow.radius=Math.min(Math.max(1,30*n),10),this.shadowOpacity=Math.max(Math.min(.7*(10-30*n),.7),.3),this.depth?.options?.enabled&&this.depth.options.depthMesh.enabled&&this.depth.depthMesh?.material instanceof e.ShadowMaterial&&(this.depth.depthMesh.material.opacity=this.shadowOpacity)}this.options.debugging&&this.debugLog()}debugLog(){console.log("Lighting.dirLight",this.dirLight),console.log("Lighting.ambientProbe",this.ambientProbe),console.log("Lighting.ambientLight",this.ambientLight)}}class ut{constructor(){this.initialized=!1,this.fps=0}get timestep(){return 1/this.fps}async init({physicsOptions:e}){this.options=e,this.RAPIER=this.options.RAPIER,this.fps=this.options.fps,this.RAPIER.init&&await this.RAPIER.init(),this.blendedWorld=new this.RAPIER.World(this.options.gravity),this.blendedWorld.timestep=this.timestep,this.options.useEventQueue&&(this.eventQueue=new this.RAPIER.EventQueue(!0)),this.initialized=!0}physicsStep(){this.options?.worldStep&&this.blendedWorld&&this.blendedWorld.step(this.eventQueue)}dispose(){this.eventQueue&&this.eventQueue.free(),this.blendedWorld&&this.blendedWorld.free()}}class pt{constructor(e){this.enabled=!1,this.visualization=!1,this.visualizeJoints=!1,this.visualizeMeshes=!1,this.debugging=!1,le(this,e)}enableHands(){return this.enabled=!0,this}enableHandsVisualization(){return this.enabled=!0,this.visualization=!0,this}}class gt{constructor(e){this.debugging=!1,this.enabled=!1,this.useAmbientSH=!1,this.useDirectionalLight=!1,this.castDirectionalLightShadow=!1,this.useDynamicSoftShadow=!1,le(this,e)}}class mt{constructor(){this.fps=45,this.gravity={x:0,y:-9.81,z:0},this.worldStep=!0,this.useEventQueue=!1}}var ft;!function(e){e.USER="User",e.POSE="Navigation",e.CONTROLLER="Hands"}(ft||(ft={}));const vt={[ft.USER]:ft.POSE,[ft.POSE]:ft.CONTROLLER,[ft.CONTROLLER]:ft.USER};class yt{constructor(e){this.initialCameraPosition={x:0,y:1.5,z:0},this.scenePath=ae+"simulator/scenes/XREmulatorsceneV5_livingRoom.glb",this.initialScenePosition={x:-1.6,y:.3,z:0},this.defaultMode=ft.USER,this.defaultHand=et.LEFT,this.modeIndicator={enabled:!0,element:"xrblocks-simulator-mode-indicator"},this.instructions={enabled:!0,element:"xrblocks-simulator-instructions",customInstructions:[]},this.handPosePanel={enabled:!0,element:"xrblocks-simulator-hand-pose-panel"},this.geminilive=!1,this.stereo={enabled:!1},this.renderToRenderTexture=!0,this.blendingMode="normal",le(this,e)}}class wt{constructor(){this.enabled=!1,this.allowInterruptions=!1}}class xt{constructor(){this.enabled=!0,this.lang="en-US",this.continuous=!1,this.commands=[],this.interimResults=!1,this.commandConfidenceThreshold=.7,this.playSimulatorActivationSounds=!0}}class St{constructor(){this.speechSynthesizer=new wt,this.speechRecognizer=new xt}}class bt{constructor(e){this.debugging=!1,this.enabled=!1,this.showDebugVisualizations=!1,this.objectImageMargin=.05,this.backendConfig={activeBackend:"gemini",gemini:{systemInstruction:"Please provide me with the bounding box coordinates for the primary objects in the given image, prioritizing objects that are nearby. For each bounding box, include ymin, xmin, ymax, and xmax. These coordinates should be absolute values ranging from 0 to 1000, corresponding to the image as if it were resized to 1000x1000 pixels. The origin (xmin:0; ymin:0) is the top-left corner of the image, and (xmax:1000; ymax:1000) is the bottom-right corner. List a maximum of 5 objects. Ignore hands and other human body parts, as well as any UI elements attached to them (e.g., a blue circle attached to a finger).",responseSchema:{type:"ARRAY",items:{type:"OBJECT",required:["objectName","ymin","xmin","ymax","xmax"],properties:{objectName:{type:"STRING"},ymin:{type:"NUMBER"},xmin:{type:"NUMBER"},ymax:{type:"NUMBER"},xmax:{type:"NUMBER"}}}}},mediapipe:{}},e&&le(this,e)}enable(){return this.enabled=!0,this}}class Ct{constructor(e){this.debugging=!1,this.enabled=!1,this.showDebugVisualizations=!1,e&&le(this,e)}enable(){return this.enabled=!0,this}}class Tt{constructor(e){this.debugging=!1,this.enabled=!1,this.planes=new Ct,this.objects=new bt,e&&le(this,e)}enablePlaneDetection(){return this.enabled=!0,this.planes.enable(),this}enableObjectDetection(){return this.enabled=!0,this.objects.enable(),this}}class Rt{constructor(){this.enabled=!0,this.enabledMouse=!0,this.debug=!1,this.visualization=!1,this.visualizeRays=!1}}class Mt{constructor(){this.enabled=!0}}class Dt{constructor(){this.enabled=!1,this.transitionTime=.5,this.defaultBackgroundColor=16777215}}class Et{constructor(e){this.antialias=!0,this.logarithmicDepthBuffer=!1,this.debugging=!1,this.stencil=!1,this.webxrRequiredFeatures=[],this.referenceSpaceType="local-floor",this.controllers=new Rt,this.depth=new xe,this.lighting=new gt,this.deviceCamera=new ce,this.hands=new pt,this.reticles=new Mt,this.sound=new St,this.ai=new F,this.simulator=new yt,this.world=new Tt,this.physics=new mt,this.transition=new Dt,this.camera={near:.01,far:500},this.usePostprocessing=!1,this.xrButton={enabled:!0,startText:"Enter XR",endText:"Exit XR",invalidText:"XR Not Supported",startSimulatorText:"Enter Simulator",enableSimulator:!0,showSimulatorButtonOnMobile:!1,autostartSimulatorOnDesktop:!0,autostartSimulator:!1},le(this,e)}enableUI(){return this.antialias=!0,this.reticles.enabled=!0,this}enableReticles(){return this.reticles.enabled=!0,this}enableDepth(){return this.depth=new xe(Se),this}enablePlaneDetection(){return this.world.enablePlaneDetection(),this}enableObjectDetection(){return this.world.enableObjectDetection(),this}enableCamera(e="environment"){return this.deviceCamera=new ce("environment"===e?ue:pe),this}enableHands(){return this.hands.enabled=!0,this}enableHandRays(){return this.controllers.visualizeRays=!0,this}enableGeminiLive(){return this.simulator.geminilive=!0,this}enableAI(){return this.ai.enabled=!0,this.ai.gemini.enabled=!0,this.ai.gemini.live.enabled=!0,this}enableXRTransitions(){return this.transition.enabled=!0,this}}class _t{constructor(e="simulator",t="simulator",i="videoinput",s="Simulator Camera"){this.deviceId=e,this.groupId=t,this.kind=i,this.label=s}}var Pt;!function(e){e[e.EXACT=0]="EXACT",e[e.IDEAL=1]="IDEAL",e[e.ACCEPTABLE=2]="ACCEPTABLE",e[e.UNACCEPTABLE=3]="UNACCEPTABLE"}(Pt||(Pt={}));class At{constructor(t){this.renderer=t,this.cameraCreated=!1,this.fps=30,this.matchRenderingCamera=!0,this.width=512,this.height=512,this.camera=new e.PerspectiveCamera}init(){this.createSimulatorCamera()}createSimulatorCamera(){if(this.cameraCreated)return;this.canvas=document.createElement("canvas"),this.canvas.width=this.width,this.canvas.height=this.height,this.context=this.canvas.getContext("2d"),this.mediaStream=this.canvas.captureStream(this.fps);const e=this.mediaStream.getVideoTracks()[0],t=this.mediaStream.getVideoTracks()[0].getSettings().deviceId;this.cameraInfo=new _t(t),e.stop(),this.cameraCreated=!0}async enumerateDevices(){return this.cameraInfo?[this.cameraInfo]:[]}onBeforeSimulatorSceneRender(e,t){if(this.cameraCreated&&!this.matchRenderingCamera){this.camera.position.copy(e.position),this.camera.quaternion.copy(e.quaternion),t(this.camera);const i=this.renderer.domElement.width,s=this.renderer.domElement.height,n=this.width/this.height,r=Math.min(i,s*n),o=Math.min(s,i/n),a=(i-r)/2,h=(s-o)/2;this.context.drawImage(this.renderer.domElement,a,h,r,o,0,0,this.width,this.height)}}onSimulatorSceneRendered(){if(this.cameraCreated&&this.matchRenderingCamera){const e=this.renderer.domElement.width,t=this.renderer.domElement.height,i=this.width/this.height,s=Math.min(e,t*i),n=Math.min(t,e/i),r=(e-s)/2,o=(t-n)/2;this.context.drawImage(this.renderer.domElement,r,o,s,n,0,0,this.width,this.height)}}restartVideoTrack(){if(!this.cameraCreated)return;this.mediaStream=this.canvas.captureStream(this.fps);const e=this.mediaStream.getVideoTracks()[0].getSettings().deviceId;this.cameraInfo.deviceId=e||""}getMedia(e={}){if(this.cameraCreated){if(!e?.deviceId||function(e,t){const i=(e,t)=>"string"==typeof e?t===e:e.includes(t);return null==e?Pt.ACCEPTABLE:"string"==typeof e||Array.isArray(e)?i(e,t)?Pt.EXACT:Pt.UNACCEPTABLE:"object"==typeof e?void 0!==e.exact?i(e.exact,t)?Pt.EXACT:Pt.UNACCEPTABLE:void 0!==e.ideal&&i(e.ideal,t)?Pt.IDEAL:Pt.ACCEPTABLE:Pt.UNACCEPTABLE}(e?.deviceId,this.cameraInfo.deviceId)!=Pt.UNACCEPTABLE){return"ended"==this.mediaStream.getVideoTracks()[0].readyState&&this.restartVideoTrack(),this.mediaStream}return null}}}const Ot=.063;var It,Lt;!function(e){e.DEFAULT="default",e.STEREO_LEFT="left",e.STEREO_RIGHT="right"}(It||(It={}));class Vt{constructor(){this.localControllerPositions=[new e.Vector3(-.3,-.1,-.3),new e.Vector3(.3,-.1,-.3)],this.localControllerOrientations=[new e.Quaternion,new e.Quaternion],this.currentControllerIndex=0}}!function(e){e.W_CODE="KeyW",e.A_CODE="KeyA",e.S_CODE="KeyS",e.D_CODE="KeyD",e.UP="ArrowUp",e.DOWN="ArrowDown",e.LEFT="ArrowLeft",e.RIGHT="ArrowRight",e.Q_CODE="KeyQ",e.E_CODE="KeyE",e.PAGE_UP="PageUp",e.PAGE_DOWN="PageDown",e.SPACE_CODE="Space",e.ENTER_CODE="Enter",e.T_CODE="KeyT",e.LEFT_SHIFT_CODE="ShiftLeft",e.RIGHT_SHIFT_CODE="ShiftRight",e.LEFT_CTRL_CODE="ControlLeft",e.RIGHT_CTRL_CODE="ControlRight",e.LEFT_ALT_CODE="AltLeft",e.RIGHT_ALT_CODE="AltRight",e.CAPS_LOCK_CODE="CapsLock",e.ESCAPE_CODE="Escape",e.TAB_CODE="Tab",e.B_CODE="KeyB",e.C_CODE="KeyC",e.F_CODE="KeyF",e.G_CODE="KeyG",e.H_CODE="KeyH",e.I_CODE="KeyI",e.J_CODE="KeyJ",e.K_CODE="KeyK",e.L_CODE="KeyL",e.M_CODE="KeyM",e.N_CODE="KeyN",e.O_CODE="KeyO",e.P_CODE="KeyP",e.R_CODE="KeyR",e.U_CODE="KeyU",e.V_CODE="KeyV",e.X_CODE="KeyX",e.Y_CODE="KeyY",e.Z_CODE="KeyZ",e.DIGIT_0="Digit0",e.DIGIT_1="Digit1",e.DIGIT_2="Digit2",e.DIGIT_3="Digit3",e.DIGIT_4="Digit4",e.DIGIT_5="Digit5",e.DIGIT_6="Digit6",e.DIGIT_7="Digit7",e.DIGIT_8="Digit8",e.DIGIT_9="Digit9",e.BACKQUOTE="Backquote"}(Lt||(Lt={}));const{A_CODE:Bt,D_CODE:Ft,E_CODE:zt,Q_CODE:kt,S_CODE:jt,W_CODE:Ut}=Lt,Nt=new e.Vector3,Gt=new e.Euler;class Ht{constructor(e,t,i,s,n){this.simulatorControllerState=e,this.downKeys=t,this.hands=i,this.setStereoRenderMode=s,this.toggleUserInterface=n}init({camera:e,input:t,timer:i}){this.camera=e,this.input=t,this.timer=i}onPointerDown(e){}onPointerUp(e){}onPointerMove(e){}onKeyDown(e){e.code==Lt.DIGIT_1?this.setStereoRenderMode(It.STEREO_LEFT):e.code==Lt.DIGIT_2?this.setStereoRenderMode(It.STEREO_RIGHT):e.code==Lt.BACKQUOTE&&this.toggleUserInterface()}onModeActivated(){}onModeDeactivated(){}update(){this.updateCameraPosition(),this.updateControllerPositions()}updateCameraPosition(){const e=this.timer.getDelta(),t=this.camera.quaternion,i=this.camera.position,s=this.downKeys;Nt.set(Number(s.has(Ft))-Number(s.has(Bt)),Number(s.has(kt))-Number(s.has(zt)),Number(s.has(jt))-Number(s.has(Ut))).multiplyScalar(e).applyQuaternion(t),i.add(Nt)}updateControllerPositions(){this.camera.updateMatrixWorld();for(let e=0;e<2;e++){const t=this.input.controllers[e];t.position.copy(this.simulatorControllerState.localControllerPositions[e]).applyMatrix4(this.camera.matrixWorld),t.quaternion.copy(this.simulatorControllerState.localControllerOrientations[e]).premultiply(this.camera.quaternion),t.updateMatrix();const i=0==e?this.hands.leftController:this.hands.rightController;i.position.copy(t.position),i.quaternion.copy(t.quaternion)}}rotateOnPointerMove(e,t,i=.002){Gt.setFromQuaternion(t,"YXZ"),Gt.y+=e.movementX*i,Gt.x+=e.movementY*i;const s=Math.PI/2;Gt.x=Math.max(.01-s,Math.min(s-.01,Gt.x)),t.setFromEuler(Gt)}enableSimulatorHands(){this.hands.showHands(),this.input.dispatchEvent({type:"connected",target:this.input.controllers[0],data:{handedness:"left"}}),this.input.dispatchEvent({type:"connected",target:this.input.controllers[1],data:{handedness:"right"}})}disableSimulatorHands(){this.hands.hideHands(),this.input.dispatchEvent({type:"disconnected",target:this.input.controllers[0],data:{handedness:"left"}}),this.input.dispatchEvent({type:"disconnected",target:this.input.controllers[1],data:{handedness:"right"}})}}const Wt=new e.Vector3,{A_CODE:qt,D_CODE:Xt,E_CODE:Kt,Q_CODE:$t,S_CODE:Qt,SPACE_CODE:Yt,T_CODE:Jt,W_CODE:Zt}=Lt;class ei extends Ht{onPointerMove(e){if(e.buttons){const t=this.simulatorControllerState.localControllerOrientations[this.simulatorControllerState.currentControllerIndex];this.rotateOnPointerMove(e,t,-.002)}}update(){this.updateControllerPositions()}onModeActivated(){this.enableSimulatorHands()}updateControllerPositions(){const e=this.timer.getDelta(),t=this.downKeys;Wt.set(Number(t.has(Xt))-Number(t.has(qt)),Number(t.has($t))-Number(t.has(Kt)),Number(t.has(Qt))-Number(t.has(Zt))).multiplyScalar(e),this.simulatorControllerState.localControllerPositions[this.simulatorControllerState.currentControllerIndex].add(Wt),super.updateControllerPositions()}toggleControllerIndex(){this.hands.toggleHandedness()}onKeyDown(e){if(super.onKeyDown(e),e.code==Jt)this.toggleControllerIndex();else if(e.code==Yt){const e=this.input.controllers[this.simulatorControllerState.currentControllerIndex].userData?.selected,t=!e;0==this.simulatorControllerState.currentControllerIndex?this.hands.setLeftHandPinching(t):this.hands.setRightHandPinching(t)}}}class ti extends Ht{onModeActivated(){this.enableSimulatorHands()}onPointerMove(e){e.buttons&&this.rotateOnPointerMove(e,this.camera.quaternion)}}class ii extends Ht{onModeActivated(){this.disableSimulatorHands(),this.input.mouseController.connect()}onModeDeactivated(){this.input.mouseController.disconnect()}onPointerDown(e){1&e.buttons&&this.input.mouseController.callSelectStart()}onPointerUp(){this.input.mouseController.userData.selected&&this.input.mouseController.callSelectEnd()}onPointerMove(e){this.input.mouseController.updateMousePositionFromEvent(e),2&e.buttons&&this.rotateOnPointerMove(e,this.camera.quaternion)}}class si extends Event{static{this.type="setSimulatorMode"}constructor(e){super(si.type,{bubbles:!0,composed:!0}),this.simulatorMode=e}}function ni(e){e.preventDefault()}class ri{constructor(e,t,i,s){this.simulatorControllerState=e,this.hands=t,this.userInterface=s,this.pointerDown=!1,this.downKeys=new Set,this.simulatorMode=ft.USER,this._onPointerDown=this.onPointerDown.bind(this),this._onPointerUp=this.onPointerUp.bind(this),this._onKeyDown=this.onKeyDown.bind(this),this._onKeyUp=this.onKeyUp.bind(this),this._onPointerMove=this.onPointerMove.bind(this);const n=()=>{this.userInterface.toggleInterfaceVisible()};this.simulatorModes={[ft.USER]:new ii(this.simulatorControllerState,this.downKeys,t,i,n),[ft.POSE]:new ti(this.simulatorControllerState,this.downKeys,t,i,n),[ft.CONTROLLER]:new ei(this.simulatorControllerState,this.downKeys,t,i,n)},this.simulatorModeControls=this.simulatorModes[this.simulatorMode]}init({camera:e,input:t,timer:i,renderer:s,simulatorOptions:n}){for(const s in this.simulatorModes)this.simulatorModes[s].init({camera:e,input:t,timer:i});this.renderer=s,this.setSimulatorMode(n.defaultMode),this.simulatorControllerState.currentControllerIndex=n.defaultHand===et.LEFT?0:1,this.connect()}connect(){const e=this.renderer.domElement;document.addEventListener("keyup",this._onKeyUp),document.addEventListener("keydown",this._onKeyDown),e.addEventListener("pointermove",this._onPointerMove),e.addEventListener("pointerdown",this._onPointerDown),e.addEventListener("pointerup",this._onPointerUp),e.addEventListener("contextmenu",ni)}update(){this.simulatorModeControls.update()}onPointerMove(e){this.simulatorModeControls.onPointerMove(e)}onPointerDown(e){this.simulatorModeControls.onPointerDown(e),this.pointerDown=!0}onPointerUp(e){this.simulatorModeControls.onPointerUp(e),this.pointerDown=!1}onKeyDown(e){this.downKeys.add(e.code),e.code==Lt.LEFT_SHIFT_CODE&&this.setSimulatorMode(vt[this.simulatorMode]),this.simulatorModeControls.onKeyDown(e)}onKeyUp(e){this.downKeys.delete(e.code)}setSimulatorMode(e){this.simulatorMode=e,this.simulatorModeControls.onModeDeactivated(),this.simulatorModeControls=this.simulatorModes[this.simulatorMode],this.simulatorModeControls.onModeActivated(),this.modeIndicatorElement&&(this.modeIndicatorElement.simulatorMode=e)}setModeIndicatorElement(e){e.simulatorMode=this.simulatorMode,e.addEventListener("setSimulatorMode",(e=>{e instanceof si&&this.setSimulatorMode(e.simulatorMode)})),this.modeIndicatorElement=e}}class oi extends e.MeshBasicMaterial{onBeforeCompile(e){e.vertexShader=e.vertexShader.replace("#include <clipping_planes_pars_vertex>",["#include <clipping_planes_pars_vertex>","varying vec4 vViewCoordinates;"].join("\n")).replace("#include <project_vertex>",["#include <project_vertex>","vViewCoordinates = mvPosition;"].join("\n")),e.fragmentShader=e.fragmentShader.replace("#include <clipping_planes_pars_fragment>",["#include <clipping_planes_pars_fragment>","varying vec4 vViewCoordinates;"].join("\n")).replace("#include <dithering_fragment>",["#include <dithering_fragment>","gl_FragColor = vec4(-vViewCoordinates.z, 0.0, 0.0, 1.0);"].join("\n"))}}class ai{constructor(e){this.simulatorScene=e,this.depthWidth=160,this.depthHeight=160,this.depthBufferSlice=new Float32Array}init(e,t,i){this.renderer=e,this.camera=t,this.depth=i,this.createRenderTarget(),this.depthMaterial=new oi}createRenderTarget(){this.depthRenderTarget=new e.WebGLRenderTarget(this.depthWidth,this.depthHeight,{format:e.RedFormat,type:e.FloatType}),this.depthBuffer=new Float32Array(this.depthWidth*this.depthHeight)}update(){this.renderDepthScene(),this.updateDepth()}renderDepthScene(){const e=this.renderer.getRenderTarget();this.renderer.setRenderTarget(this.depthRenderTarget),this.simulatorScene.overrideMaterial=this.depthMaterial,this.renderer.render(this.simulatorScene,this.camera),this.simulatorScene.overrideMaterial=null,this.renderer.setRenderTarget(e)}updateDepth(){const e=this.renderer.getContext();e.bindBuffer(e.PIXEL_PACK_BUFFER,null),this.renderer.readRenderTargetPixels(this.depthRenderTarget,0,0,this.depthWidth,this.depthHeight,this.depthBuffer),this.depthBufferSlice.length!=this.depthWidth&&(this.depthBufferSlice=new Float32Array(this.depthWidth));for(let e=0;e<this.depthHeight/2;++e){const t=this.depthHeight-1-e,i=e*this.depthWidth,s=t*this.depthWidth;this.depthBufferSlice.set(this.depthBuffer.subarray(i,i+this.depthWidth)),this.depthBuffer.copyWithin(i,s,s+this.depthWidth),this.depthBuffer.set(this.depthBufferSlice,s)}const t={width:this.depthWidth,height:this.depthHeight,data:this.depthBuffer.buffer,rawValueToMeters:1};this.depth.updateCPUDepthData(t,0)}}class hi extends Event{static{this.type="SimulatorHandPoseChangeRequestEvent"}constructor(e){super(hi.type,{bubbles:!0,composed:!0}),this.pose=e}}var li;!function(e){e.RELAXED="relaxed",e.PINCHING="pinching",e.FIST="fist",e.THUMBS_UP="thumbs_up",e.POINTING="pointing",e.ROCK="rock",e.THUMBS_DOWN="thumbs_down",e.VICTORY="victory"}(li||(li={}));const ci=Object.freeze({[li.RELAXED]:[{t:[-.05,-.08,-.1],r:[.5373,0,0,.8434]},{t:[-.0281,-.0594,-.1165],r:[.3943,-.2036,-.3103,.8407]},{t:[.0026,-.0299,-.1518],r:[.3476,-.1049,-.5285,.7674]},{t:[.0169,-.0181,-.1728],r:[.3521,.0515,-.635,.6857]},{t:[.0268,-.0018,-.1966],r:[.3521,.0515,-.635,.6857]},{t:[-.0369,-.0541,-.1121],r:[.5882,-.1036,.0205,.8018]},{t:[-.024,.0143,-.1465],r:[.3269,-.0887,-3e-4,.9409]},{t:[-.0172,.0394,-.1765],r:[-.0114,-.0813,-.0286,.9962]},{t:[-.0138,.0388,-.1986],r:[-.1994,-.0379,-.0372,.9785]},{t:[-.0125,.0287,-.2199],r:[-.1994,-.0379,-.0372,.9785]},{t:[-.0499,-.0528,-.1125],r:[.5569,-.0203,.0319,.8297]},{t:[-.0496,.0131,-.1445],r:[.3908,-.0273,.1089,.9136]},{t:[-.0513,.0438,-.1738],r:[.0747,-.0923,.0634,.9909]},{t:[-.0462,.0488,-.2036],r:[-.1936,-.1156,.0299,.9738]},{t:[-.0404,.0387,-.2253],r:[-.1936,-.1156,.0299,.9738]},{t:[-.0612,-.0561,-.1138],r:[.5095,.0572,.0274,.8581]},{t:[-.0698,.0022,-.1468],r:[.4396,-.0068,.1748,.881]},{t:[-.0751,.0329,-.1719],r:[.071,-.0911,.1344,.9842]},{t:[-.0703,.0383,-.2029],r:[-.1764,-.1244,.0831,.9729]},{t:[-.0641,.0302,-.2227],r:[-.1764,-.1244,.0831,.9729]},{t:[-.0708,-.0616,-.1145],r:[.4571,.1437,.0457,.8765]},{t:[-.0889,-.0132,-.148],r:[.3971,.0569,.2436,.883]},{t:[-.098,.0096,-.1727],r:[.1604,-.0085,.243,.9566]},{t:[-.0997,.0171,-.194],r:[-.0034,-.0735,.1859,.9798]},{t:[-.0979,.0165,-.2131],r:[-.0034,-.0735,.1859,.9798]}],[li.PINCHING]:[{t:[-.05,-.08,-.1],r:[.5373,0,0,.8434],s:[1,1,1]},{t:[-.0281,-.0594,-.1165],r:[.3072,-.0483,-.257,.915],s:[1,1,1]},{t:[-.0083,-.0299,-.1581],r:[.1832,.0632,-.4718,.8602],s:[1,1,1]},{t:[-.0069,-.0195,-.1841],r:[.2232,.1362,-.6112,.747],s:[1,1,.9999]},{t:[-.0063,-.0051,-.2109],r:[.2232,.1362,-.6112,.747],s:[1,1,.9999]},{t:[-.0369,-.0541,-.112],r:[.5858,-.1038,.0205,.8035],s:[1,1,1]},{t:[-.024,.0142,-.1465],r:[.1342,-.1392,-.0707,.9786],s:[1.0001,1,.9999]},{t:[-.0122,.0248,-.1828],r:[-.2614,-.0983,-.1184,.9529],s:[1.0001,.9999,.9999]},{t:[-.0095,.0131,-.2017],r:[-.3454,-.0506,-.1338,.9275],s:[1,.9999,1]},{t:[-.0098,-.0028,-.219],r:[-.3454,-.0506,-.1338,.9275],s:[1,.9999,1]},{t:[-.0498,-.0529,-.1126],r:[.5552,-.0196,.0307,.8309],s:[1.0001,1,1]},{t:[-.0496,.0131,-.1444],r:[.3957,-.0669,.0916,.9113],s:[1,.9999,1]},{t:[-.0477,.0443,-.173],r:[.0284,-.1256,.0276,.9913],s:[1,1,.9999]},{t:[-.0403,.0463,-.2027],r:[-.1956,-.1387,-.007,.9708],s:[1.0001,1,1]},{t:[-.0339,.036,-.224],r:[-.1956,-.1387,-.007,.9708],s:[1.0001,1,1]},{t:[-.0612,-.0561,-.1137],r:[.5088,.0591,.0245,.8585],s:[1,1.0001,1]},{t:[-.0697,.0021,-.1467],r:[.464,-.0595,.1601,.8692],s:[1,1,1]},{t:[-.0713,.0348,-.1698],r:[.0595,-.1373,.0948,.9842],s:[1.0001,1.0001,1]},{t:[-.0633,.0395,-.2003],r:[-.1735,-.159,.0354,.9713],s:[1,1,.9999]},{t:[-.0561,.0313,-.2197],r:[-.1735,-.159,.0354,.9713],s:[1,1,.9999]},{t:[-.0707,-.0617,-.1146],r:[.4573,.1467,.0408,.8762],s:[1,1,1]},{t:[-.0889,-.0132,-.148],r:[.4065,.0051,.2314,.8838],s:[1,.9999,1.0001]},{t:[-.0946,.0109,-.1723],r:[.1595,-.0578,.2175,.9612],s:[1,.9999,1]},{t:[-.094,.019,-.1934],r:[-.0122,-.1189,.1509,.9813],s:[1.0001,1,1]},{t:[-.0904,.0182,-.2123],r:[-.0122,-.1189,.1509,.9813],s:[1.0001,1,1]}],[li.FIST]:[{t:[-.0933,-.0266,-.1338],r:[.1346,-.1437,.0038,.9804]},{t:[-.0648,-.0265,-.1529],r:[.0354,-.3351,-.1786,.9244]},{t:[-.0318,-.0293,-.1932],r:[.0407,-.2202,-.5685,.7916]},{t:[-.0212,-.0345,-.2179],r:[.0132,-.12,-.576,.8084]},{t:[-.0161,-.039,-.2469],r:[.0132,-.12,-.576,.8084]},{t:[-.0731,-.0197,-.1569],r:[.0999,-.2377,.0822,.9627]},{t:[-.0399,-.0023,-.2221],r:[-.4356,-.1075,-.0127,.8936]},{t:[-.0325,-.0319,-.246],r:[.9331,.066,.0832,-.3436]},{t:[-.035,-.0462,-.2296],r:[.9874,.021,.128,-.0903]},{t:[-.0408,-.0496,-.2076],r:[.9874,.021,.128,-.0903]},{t:[-.0853,-.0187,-.1614],r:[.115,-.1594,.0889,.9765]},{t:[-.0646,-7e-4,-.2271],r:[-.4919,-.1197,.0382,.8616]},{t:[-.0544,-.0353,-.2477],r:[.9309,.1571,.0605,-.324]},{t:[-.0548,-.0542,-.2244],r:[.9835,.1315,.1097,.0583]},{t:[-.0607,-.051,-.2013],r:[.9835,.1315,.1097,.0583]},{t:[-.0972,-.0213,-.1628],r:[.0881,-.0966,.0847,.9878]},{t:[-.0856,-.0088,-.2263],r:[-.4818,-.1075,.1033,.8635]},{t:[-.0742,-.0406,-.246],r:[.9378,.1774,.0089,-.2983]},{t:[-.0715,-.0585,-.2205],r:[.9769,.1847,.0804,.0714]},{t:[-.0757,-.0552,-.1994],r:[.9769,.1847,.0804,.0714]},{t:[-.1078,-.0253,-.162],r:[.0535,-.0126,.0933,.9941]},{t:[-.1069,-.0188,-.2215],r:[-.4433,-.1294,.1523,.8738]},{t:[-.0939,-.0444,-.2398],r:[.9002,.2018,-.0275,-.385]},{t:[-.0891,-.0599,-.2248],r:[.9644,.2553,.0425,-.0538]},{t:[-.0914,-.0623,-.2063],r:[.9644,.2553,.0425,-.0538]}],[li.THUMBS_UP]:[{t:[-.011,-.0299,-.0701],r:[.1224,-.1562,.6052,.771]},{t:[.0025,-.0017,-.0854],r:[.3796,-.3776,.3843,.7521]},{t:[.0162,.041,-.1065],r:[.6152,-.1749,.0935,.763]},{t:[.0204,.0676,-.1116],r:[.5992,-.1247,.1335,.7795]},{t:[.0225,.096,-.1202],r:[.5992,-.1247,.1335,.7795]},{t:[-.0042,-.008,-.0928],r:[.1427,-.2467,.6763,.6793]},{t:[.0063,.0312,-.155],r:[-.4551,-.5645,.3425,.5974]},{t:[.0447,.0257,-.1538],r:[.7509,.6277,.1981,-.053]},{t:[.0396,.0184,-.1338],r:[.7246,.5124,.4244,.1797]},{t:[.0207,.0148,-.1212],r:[.7246,.5124,.4244,.1797]},{t:[-.0078,-.0192,-.0982],r:[.109,-.1737,.6698,.7137]},{t:[-6e-4,.0083,-.163],r:[-.4929,-.5301,.4215,.5462]},{t:[.0407,.0046,-.1614],r:[.705,.703,.0897,-.0263]},{t:[.0382,-5e-4,-.132],r:[.6279,.5816,.4074,.3186]},{t:[.0165,-.0021,-.1217],r:[.6279,.5816,.4074,.3186]},{t:[-.0092,-.031,-.0993],r:[.0472,-.1416,.6514,.7439]},{t:[6e-4,-.0142,-.1626],r:[-.5202,-.4929,.4819,.5042]},{t:[.0398,-.0159,-.1611],r:[.6996,.7076,.0706,.0696]},{t:[.0338,-.0161,-.1304],r:[.5876,.6289,.3607,.3593]},{t:[.0143,-.0168,-.1208],r:[.5876,.6289,.3607,.3593]},{t:[-.0081,-.0426,-.0982],r:[-.0269,-.0934,.6476,.7558]},{t:[.0026,-.0377,-.1578],r:[.5435,.4612,-.5243,-.4658]},{t:[.0366,-.0376,-.1559],r:[.6991,.7017,.0384,.1318]},{t:[.032,-.0347,-.1344],r:[.575,.6796,.2522,.3795]},{t:[.0166,-.0342,-.1237],r:[.575,.6796,.2522,.3795]}],[li.POINTING]:[{t:[-.0283,-.0376,-.0293],r:[.1372,-.208,.241,.938]},{t:[.0016,-.0246,-.0431],r:[.0106,-.3992,-.0014,.9168]},{t:[.0392,-.0237,-.0781],r:[-.1,-.2869,-.466,.831]},{t:[.0496,-.0357,-.1004],r:[-.1511,-.183,-.4918,.8377]},{t:[.0533,-.0497,-.1265],r:[-.1511,-.183,-.4918,.8377]},{t:[-.0078,-.0226,-.0496],r:[.1168,-.3031,.3253,.8881]},{t:[.0265,.0074,-.1082],r:[.0563,-.1303,.2725,.9516]},{t:[.0346,.0153,-.1453],r:[-.0635,-.1606,.2541,.9516]},{t:[.0419,.0144,-.1659],r:[-.1073,-.1342,.2464,.9538]},{t:[.0494,.0105,-.1873],r:[-.1073,-.1342,.2464,.9538]},{t:[-.0184,-.0273,-.0562],r:[.1156,-.2249,.3238,.9117]},{t:[.0052,-.0021,-.1177],r:[-.4452,-.2871,.2041,.8233]},{t:[.0324,-.0274,-.1363],r:[.8476,.3909,.031,-.3574]},{t:[.0392,-.0465,-.1142],r:[.9167,.3645,.16,-.0352]},{t:[.032,-.0501,-.0915],r:[.9167,.3645,.16,-.0352]},{t:[-.028,-.0348,-.0593],r:[.0757,-.1724,.308,.9326]},{t:[-.01,-.0186,-.1201],r:[-.5151,-.3075,.2332,.7654]},{t:[.018,-.0439,-.1306],r:[.8841,.4115,.0419,-.2175]},{t:[.0214,-.0572,-.1026],r:[.8915,.3885,.1955,.1266]},{t:[.0111,-.0549,-.0835],r:[.8915,.3885,.1955,.1266]},{t:[-.0357,-.0434,-.0601],r:[.0242,-.0998,.3079,.9459]},{t:[-.0254,-.037,-.1183],r:[-.4608,-.35,.2807,.7658]},{t:[.0022,-.0544,-.1281],r:[.8346,.4535,.0038,-.3127]},{t:[.0089,-.0663,-.1107],r:[.8657,.4769,.1519,-.0059]},{t:[.003,-.0699,-.0932],r:[.8657,.4769,.1519,-.0059]}],[li.ROCK]:[{t:[-.0123,-.0183,-.0267],r:[.5149,-.0845,-.1158,.8452],s:[1,1,1]},{t:[.0153,-.0052,-.0437],r:[.2665,-.0899,-.3721,.8846],s:[1,1,1]},{t:[.0335,.0154,-.0867],r:[.0177,.1842,-.6731,.716],s:[1,1,1]},{t:[.0267,.0228,-.1122],r:[.0728,.2226,-.6735,.7011],s:[1,1,1]},{t:[.019,.0341,-.1386],r:[.0728,.2226,-.6735,.7011],s:[1,1,1]},{t:[.0067,.0029,-.0406],r:[.475,-.2118,-.0726,.851],s:[1,1,1]},{t:[.0388,.061,-.0749],r:[.5779,-.1002,-.0602,.8077],s:[1,1,1]},{t:[.0481,.097,-.086],r:[.5059,-.0922,-.0672,.855],s:[1,1,1]},{t:[.0529,.1158,-.0964],r:[.4458,-.0565,-.053,.8918],s:[1,1,1]},{t:[.0562,.1334,-.1107],r:[.4458,-.0565,-.053,.8918],s:[1,1,1]},{t:[-.0052,.0075,-.0412],r:[.5055,-.126,-.0623,.8513],s:[1,1,1]},{t:[.0144,.0671,-.0735],r:[.1227,-.0631,-.0269,.9901],s:[1,1,1]},{t:[.0199,.0775,-.1133],r:[-.4479,-.0687,-.0876,.8871],s:[1,1,1]},{t:[.0211,.0534,-.1312],r:[-.6828,-.0523,-.1046,.7212],s:[1,1,1]},{t:[.0192,.0294,-.1316],r:[-.6828,-.0523,-.1046,.7212],s:[1,1,1]},{t:[-.0167,.0074,-.0424],r:[.491,-.0372,-.0778,.8669],s:[1,1,1]},{t:[-.0075,.0623,-.0758],r:[.1717,-.0904,.0273,.9806],s:[1,1,1]},{t:[-7e-4,.0753,-.1121],r:[-.3257,-.1136,-.0418,.9377],s:[1,1,1]},{t:[.005,.0561,-.1361],r:[-.5492,-.1111,-.0905,.8233],s:[1,1,1]},{t:[.0066,.0356,-.1433],r:[-.5492,-.1111,-.0905,.8233],s:[1,1,1]},{t:[-.0273,.0051,-.0431],r:[.4566,.0629,-.0766,.8841],s:[1,1,1]},{t:[-.0297,.0531,-.0769],r:[.3942,-.0035,.1163,.9116],s:[1,1,1]},{t:[-.0317,.0768,-.1013],r:[.4582,6e-4,.1099,.882],s:[1,1,1]},{t:[-.0341,.0951,-.1136],r:[.4085,-.0179,.0535,.911],s:[1,1,1]},{t:[-.0354,.1086,-.1266],r:[.4085,-.0179,.0535,.911],s:[1,1,1]}],[li.THUMBS_DOWN]:[{t:[-.0169,.0317,-.0845],r:[.2721,-.3488,-.6314,.6369],s:[1,1,1]},{t:[-.0019,.008,-.1021],r:[-.0533,.5043,.7891,-.3467],s:[1,1,1]},{t:[.0208,-.0318,-.1276],r:[-.2229,.6138,.7555,.0539],s:[1,1,1]},{t:[.0282,-.0578,-.1318],r:[-.2724,.6476,.7112,.0242],s:[1,1,1]},{t:[.0389,-.0856,-.1338],r:[-.2724,.6476,.7112,.0242],s:[1,1,1]},{t:[.0046,.0177,-.0997],r:[.1919,-.3993,-.6438,.6238],s:[1,1,1]},{t:[.0618,-.0034,-.1463],r:[-.1884,.0883,-.6795,.7035],s:[1,1,1]},{t:[.0481,-.0093,-.1821],r:[.6204,-.5352,.4297,-.3794],s:[1,1,1]},{t:[.0275,-.0094,-.1746],r:[.6806,-.6532,.2814,-.176],s:[1,1,1]},{t:[.0141,-.0064,-.1561],r:[.6806,-.6532,.2814,-.176],s:[1,1,1]},{t:[.0062,.0299,-.1019],r:[.2399,-.3631,-.598,.6731],s:[1,1,1]},{t:[.0621,.0218,-.1466],r:[-.241,.1225,-.6156,.7403],s:[1,1,1]},{t:[.0427,.0133,-.1823],r:[.7097,-.4862,.373,-.3475],s:[1,1,1]},{t:[.0165,.0095,-.1681],r:[.7968,-.5892,.1321,-.0209],s:[1,1,1]},{t:[.0119,.0128,-.1447],r:[.7968,-.5892,.1321,-.0209],s:[1,1,1]},{t:[.0033,.0406,-.1037],r:[.2574,-.3085,-.5681,.7183],s:[1,1,1]},{t:[.052,.0419,-.1485],r:[-.2306,.1278,-.5499,.7925],s:[1,1,1]},{t:[.0339,.0328,-.182],r:[.7575,-.4754,.2861,-.344],s:[1,1,1]},{t:[.0099,.025,-.1634],r:[.843,-.5293,.0926,-.0248],s:[1,1,1]},{t:[.0068,.0266,-.142],r:[.843,-.5293,.0926,-.0248],s:[1,1,1]},{t:[-.0018,.0508,-.104],r:[.2798,-.2351,-.5355,.7614],s:[1,1,1]},{t:[.0378,.0613,-.1483],r:[-.1652,.0952,-.5046,.842],s:[1,1,1]},{t:[.0259,.054,-.1792],r:[.7429,-.4404,.2677,-.4273],s:[1,1,1]},{t:[.0084,.0449,-.169],r:[.8704,-.4542,.1121,-.1532],s:[1,1,1]},{t:[.002,.0431,-.1514],r:[.8704,-.4542,.1121,-.1532],s:[1,1,1]}],[li.VICTORY]:[{t:[-.0485,-.0629,-.0748],r:[.5235,.0269,-.0122,.8515],s:[1,1,1]},{t:[-.0274,-.0424,-.0935],r:[.2683,-.0091,-.2476,.9309],s:[1,1,1]},{t:[-.0197,-.0171,-.1372],r:[-.0874,.2587,-.5403,.7959],s:[1,1,1]},{t:[-.0337,-.0134,-.1604],r:[-.1021,.3471,-.5231,.7717],s:[1,1,1]},{t:[-.0538,-.0084,-.1819],r:[-.1021,.3471,-.5231,.7717],s:[1,1,1]},{t:[-.0376,-.037,-.0897],r:[.5048,-.107,.0348,.8559],s:[1,1,1]},{t:[-.0266,.0281,-.1246],r:[.567,-.0696,.0098,.8207],s:[1,1,1]},{t:[-.0224,.0646,-.1371],r:[.5031,-.0677,.0059,.8615],s:[1,1,1]},{t:[-.0201,.0836,-.1477],r:[.4589,-.0365,.0223,.8874],s:[1,1,1]},{t:[-.019,.1018,-.1617],r:[.4589,-.0365,.0223,.8874],s:[1,1,1]},{t:[-.0503,-.0361,-.0891],r:[.5225,-.0136,.0382,.8517],s:[1,1,1]},{t:[-.0515,.0267,-.1211],r:[.5428,.1035,.1149,.8255],s:[1,1,1]},{t:[-.0638,.0631,-.1369],r:[.5306,.067,.0906,.8401],s:[1,1,1]},{t:[-.0702,.0896,-.1495],r:[.5467,.0608,.081,.8312],s:[1,1,1]},{t:[-.0747,.1108,-.1601],r:[.5467,.0608,.081,.8312],s:[1,1,1]},{t:[-.0613,-.0396,-.0891],r:[.4925,.0763,.0204,.8667],s:[1,1,1]},{t:[-.0712,.0158,-.1219],r:[.2546,-.0246,.1592,.9535],s:[1,1,1]},{t:[-.0722,.0349,-.1561],r:[-.2354,-.1181,.1042,.959],s:[1,1,1]},{t:[-.0638,.0217,-.1832],r:[-.4573,-.1496,.0503,.8752],s:[1,1,1]},{t:[-.0571,.0041,-.1941],r:[-.4573,-.1496,.0503,.8752],s:[1,1,1]},{t:[-.0706,-.045,-.0892],r:[.4433,.1733,.0233,.8791],s:[1,1,1]},{t:[-.0898,6e-4,-.1216],r:[.0458,-.1976,.107,.9733],s:[1,1,1]},{t:[-.0762,.0038,-.1526],r:[-.348,-.2273,.0117,.9095],s:[1,1,1]},{t:[-.0668,-.0095,-.1675],r:[-.5475,-.2656,-.0806,.7894],s:[1,1,1]},{t:[-.0618,-.0269,-.1725],r:[-.5475,-.2656,-.0806,.7894],s:[1,1,1]}]}),di=Object.freeze({[li.RELAXED]:[{t:[.05,-.08,-.1],r:[.5373,0,0,.8434]},{t:[.0279,-.0592,-.1167],r:[.3237,.1161,.293,.8921]},{t:[.0026,-.0313,-.158],r:[.2171,.0194,.5207,.8254]},{t:[-.0042,-.0219,-.1837],r:[.2597,-.0685,.6498,.711]},{t:[-.01,-.0084,-.2107],r:[.2597,-.0685,.6498,.711]},{t:[.037,-.0539,-.1123],r:[.5808,.1164,-.0414,.8046]},{t:[.0238,.0151,-.147],r:[.3081,.0484,-.0273,.9497]},{t:[.0206,.0393,-.1786],r:[-.0461,.0526,-.0104,.9975]},{t:[.0185,.0373,-.201],r:[-.1674,.0162,-.0064,.9857]},{t:[.0177,.0287,-.223],r:[-.1674,.0162,-.0064,.9857]},{t:[.05,-.0527,-.1126],r:[.5619,.0306,-.0478,.8252]},{t:[.0497,.0138,-.1449],r:[.353,.0474,-.1014,.9289]},{t:[.0491,.0425,-.1767],r:[.0777,.1076,-.0559,.9896]},{t:[.0431,.0478,-.2066],r:[-.0679,.1248,-.0343,.9893]},{t:[.0369,.0436,-.2302],r:[-.0679,.1248,-.0343,.9893]},{t:[.0614,-.0561,-.1136],r:[.5303,-.05,-.0384,.8455]},{t:[.0699,.0028,-.1472],r:[.4168,.0427,-.1662,.8926]},{t:[.0722,.0331,-.1739],r:[.1339,.1107,-.1236,.977]},{t:[.0665,.0425,-.2041],r:[-.0175,.1318,-.0809,.9878]},{t:[.0606,.0413,-.2257],r:[-.0175,.1318,-.0809,.9878]},{t:[.0711,-.0618,-.1145],r:[.4891,-.1378,-.0535,.8596]},{t:[.0892,-.0127,-.1484],r:[.3439,.0196,-.23,.9102]},{t:[.0924,.0087,-.1761],r:[.1965,.0585,-.2173,.9543]},{t:[.0921,.0184,-.1968],r:[.0936,.1069,-.1575,.9773]},{t:[.0896,.0217,-.2157],r:[.0936,.1069,-.1575,.9773]}],[li.PINCHING]:[{t:[.05,-.08,-.1],r:[.5373,0,0,.8434],s:[1,1,1]},{t:[.0279,-.0593,-.1166],r:[.307,.046,.2483,.9176],s:[1,1,1]},{t:[.0082,-.0291,-.1587],r:[.1833,-.0669,.4657,.8632],s:[.9999,1,1]},{t:[.0071,-.0186,-.185],r:[.2256,-.1369,.6093,.7477],s:[1,1,.9999]},{t:[.0064,-.0039,-.212],r:[.2256,-.1369,.6093,.7477],s:[1,1,.9999]},{t:[.037,-.0539,-.1122],r:[.5831,.1146,-.0388,.8034],s:[1,.9999,1]},{t:[.0237,.0153,-.147],r:[.1209,.0891,.0196,.9885],s:[1,.9999,1]},{t:[.0163,.0257,-.1849],r:[-.2747,.0723,.0511,.9574],s:[1,.9999,.9999]},{t:[.014,.0138,-.204],r:[-.3165,.0337,.0633,.9459],s:[1,.9999,1]},{t:[.0136,-.0012,-.2226],r:[-.3165,.0337,.0633,.9459],s:[1,.9999,1]},{t:[.0501,-.0527,-.1126],r:[.5625,.0291,-.0455,.825],s:[1,1,1]},{t:[.0497,.0141,-.1449],r:[.3465,.0658,-.0921,.9312],s:[1.0001,.9999,.9999]},{t:[.0473,.0424,-.177],r:[.0559,.1235,-.0403,.9899],s:[1.0001,1,.9999]},{t:[.0402,.0463,-.2069],r:[-.0703,.1381,-.0195,.9877],s:[1.0001,1,.9999]},{t:[.0335,.0419,-.2304],r:[-.0703,.1381,-.0195,.9877],s:[1.0001,1,.9999]},{t:[.0615,-.0561,-.1136],r:[.5287,-.0513,-.0363,.8465],s:[1.0001,1,.9999]},{t:[.07,.003,-.1472],r:[.4197,.0598,-.1607,.8913],s:[1,1,.9999]},{t:[.0709,.0336,-.1737],r:[.1329,.1258,-.1128,.9766],s:[1,1,1]},{t:[.0643,.0431,-.2038],r:[-.0172,.145,-.068,.9869],s:[1.0001,.9999,1]},{t:[.0577,.0418,-.2253],r:[-.0172,.145,-.068,.9869],s:[1.0001,.9999,1]},{t:[.0711,-.0617,-.1145],r:[.4861,-.139,-.0517,.8612],s:[1.0001,.9999,1]},{t:[.0893,-.0125,-.1485],r:[.317,.0459,-.2224,.9208],s:[1.0001,.9999,1]},{t:[.0902,.0078,-.1772],r:[.1921,.0784,-.2077,.9559],s:[1,1,.9999]},{t:[.0889,.0174,-.1979],r:[.0936,.1253,-.1462,.9768],s:[1.0001,1,1]},{t:[.0857,.0208,-.2167],r:[.0936,.1253,-.1462,.9768],s:[1.0001,1,1]}],[li.FIST]:[{t:[.0504,-.0155,-.1083],r:[.1392,.117,-.058,.9816]},{t:[.022,-.0122,-.1291],r:[-.0068,.3422,.1705,.924]},{t:[-.011,-.019,-.1691],r:[-.0952,.2257,.5977,.7634]},{t:[-.0171,-.0305,-.1932],r:[-.249,.0162,.627,.738]},{t:[-.0073,-.0427,-.2185],r:[-.249,.0162,.627,.738]},{t:[.0314,-.0068,-.133],r:[.1126,.213,-.1468,.9594]},{t:[.0035,.014,-.1987],r:[-.5177,.1865,.0124,.8349]},{t:[-.0086,-.0192,-.2148],r:[.9671,-.1129,-.1466,-.1747]},{t:[-.0031,-.0274,-.1952],r:[.9714,-.0492,-.2057,.1081]},{t:[.0063,-.0222,-.1749],r:[.9714,-.0492,-.2057,.1081]},{t:[.0441,-.0073,-.137],r:[.1251,.1341,-.1467,.972]},{t:[.0283,.0126,-.2028],r:[-.5227,.1469,-.0852,.8354]},{t:[.0144,-.0224,-.2202],r:[.9399,-.2078,-.0451,-.2671]},{t:[.0137,-.0382,-.1948],r:[.9665,-.181,-.1188,.1381]},{t:[.0207,-.0318,-.1726],r:[.9665,-.181,-.1188,.1381]},{t:[.0559,-.0112,-.1379],r:[.0948,.0732,-.1351,.9836]},{t:[.0482,.0022,-.2011],r:[-.5015,.1223,-.1588,.8416]},{t:[.0337,-.0294,-.2191],r:[.9432,-.2267,.0156,-.2423]},{t:[.0294,-.0438,-.1916],r:[.9569,-.2379,-.08,.1464]},{t:[.0346,-.0376,-.1714],r:[.9569,-.2379,-.08,.1464]},{t:[.0662,-.0164,-.1368],r:[.0546,-.0084,-.1349,.9893]},{t:[.068,-.0102,-.1955],r:[-.4587,.1335,-.2099,.853]},{t:[.0529,-.0353,-.2127],r:[.9107,-.2444,.0606,-.3274]},{t:[.0466,-.0483,-.1959],r:[.9518,-.3056,-.0236,.0063]},{t:[.0488,-.0485,-.1773],r:[.9518,-.3056,-.0236,.0063]}],[li.THUMBS_UP]:[{t:[.0317,-.0212,-.089],r:[.2199,.1003,-.594,.7673]},{t:[.0223,.009,-.1042],r:[.4294,.285,-.3619,.7768]},{t:[.0158,.0521,-.1273],r:[.6012,.067,-.0513,.7947]},{t:[.0145,.0784,-.1348],r:[.597,.0134,-.0918,.7968]},{t:[.0163,.1065,-.1446],r:[.597,.0134,-.0918,.7968]},{t:[.0303,.0032,-.1103],r:[.2434,.2002,-.656,.6858]},{t:[.0337,.0475,-.1698],r:[-.3298,.4729,-.4297,.6949]},{t:[-.0026,.0462,-.1835],r:[.7134,-.6368,-2e-4,-.2925]},{t:[-.0107,.0369,-.1654],r:[.7745,-.5891,-.2133,-.0877]},{t:[-.0047,.0282,-.145],r:[.7745,-.5891,-.2133,-.0877]},{t:[.0347,-.0077,-.1158],r:[.2088,.1254,-.6589,.7117]},{t:[.0416,.0251,-.1782],r:[-.3597,.4829,-.4746,.6421]},{t:[.0018,.0251,-.19],r:[-.673,.7069,-.0014,.2177]},{t:[-.0077,.0162,-.163],r:[.6957,-.6456,-.2988,.0994]},{t:[.0063,.0104,-.1443],r:[.6957,-.6456,-.2988,.0994]},{t:[.0361,-.0196,-.1178],r:[.1467,.0923,-.6537,.7367]},{t:[.0398,.0027,-.1801],r:[-.3611,.446,-.5466,.6099]},{t:[.0028,.0047,-.193],r:[-.6782,.7246,-.0014,.1226]},{t:[-.003,-6e-4,-.1628],r:[-.652,.6801,.2937,-.1613]},{t:[.0108,-.0046,-.1465],r:[-.652,.6801,.2937,-.1613]},{t:[.0343,-.0315,-.1182],r:[.0757,.0463,-.6692,.7378]},{t:[.0363,-.021,-.1779],r:[-.3141,.3981,-.6168,.602]},{t:[.0062,-.0166,-.1931],r:[-.6691,.7354,-.0331,.1021]},{t:[.0012,-.0185,-.1716],r:[-.6175,.7316,.235,-.168]},{t:[.0116,-.0223,-.1564],r:[-.6175,.7316,.235,-.168]}],[li.POINTING]:[{t:[-.0042,-.0248,-.0222],r:[.1163,-.0095,-.3006,.9466]},{t:[-.024,-.0114,-.048],r:[-.052,.2376,-.0719,.9673]},{t:[-.0482,-.0149,-.0937],r:[-.2324,.2162,.3797,.869]},{t:[-.0535,-.0306,-.1155],r:[-.2846,.1212,.4068,.8595]},{t:[-.0521,-.0492,-.1388],r:[-.2846,.1212,.4068,.8595]},{t:[-.0129,-.0119,-.0508],r:[.1258,.0866,-.3895,.9083]},{t:[-.0173,.01,-.1215],r:[.1174,-.0564,-.3421,.9306]},{t:[-.0097,.018,-.1587],r:[-.0512,.0028,-.347,.9365]},{t:[-.0105,.0158,-.1805],r:[-.1583,.003,-.3458,.9249]},{t:[-.0137,.0085,-.2021],r:[-.1583,.003,-.3458,.9249]},{t:[-.0017,-.019,-.052],r:[.1155,.0062,-.386,.9152]},{t:[.0038,-.0037,-.1206],r:[-.2494,.0619,-.3947,.8822]},{t:[-.0086,-.0197,-.1569],r:[-.7146,.3231,-.2612,.5628]},{t:[-.0306,-.0389,-.1502],r:[.8643,-.4054,.1306,-.2676]},{t:[-.0406,-.0469,-.1297],r:[.8643,-.4054,.1306,-.2676]},{t:[.0068,-.0279,-.0499],r:[.0671,-.0438,-.3807,.9212]},{t:[.0155,-.022,-.1146],r:[-.3096,.1005,-.4385,.8377]},{t:[-.0022,-.0389,-.1452],r:[.7388,-.369,.2794,-.4899]},{t:[-.0264,-.0553,-.1341],r:[.852,-.4611,.1257,-.214]},{t:[-.0346,-.0602,-.1146],r:[.852,-.4611,.1257,-.214]},{t:[.0126,-.0374,-.0464],r:[.0105,-.1129,-.3882,.9146]},{t:[.0254,-.0415,-.1045],r:[-.3088,.1125,-.4825,.8119]},{t:[.0078,-.0548,-.1304],r:[-.6368,.3211,-.3767,.5912]},{t:[-.0112,-.0661,-.1307],r:[.7535,-.4639,.2523,-.3916]},{t:[-.0244,-.0737,-.1196],r:[.7535,-.4639,.2523,-.3916]}],[li.ROCK]:[{t:[.0015,-.0417,-.0513],r:[.5617,.0123,.1355,.8161],s:[1,1,1]},{t:[-.0235,-.025,-.07],r:[.2818,.0046,.4006,.8718],s:[1,1,1]},{t:[-.0354,-1e-4,-.1128],r:[-.0257,-.2764,.6652,.6931],s:[1,1,1]},{t:[-.0238,.0089,-.1359],r:[-6e-4,-.3419,.6556,.6733],s:[1,1,1]},{t:[-.0088,.0215,-.1584],r:[-6e-4,-.3419,.6556,.6733],s:[1,1,1]},{t:[-.015,-.0179,-.0645],r:[.5302,.1299,.1154,.8299],s:[1,1,1]},{t:[-.0403,.0456,-.0947],r:[.5874,.0115,.0813,.8051],s:[1,1,1]},{t:[-.0451,.0825,-.1058],r:[.5048,.001,.0806,.8595],s:[1,1,1]},{t:[-.0468,.1015,-.1165],r:[.4494,-.0352,.0601,.8906],s:[1,1,1]},{t:[-.0465,.1195,-.1308],r:[.4494,-.0352,.0601,.8906],s:[1,1,1]},{t:[-.0029,-.0139,-.063],r:[.5567,.046,.0996,.8234],s:[1,1,1]},{t:[-.016,.0502,-.0895],r:[.1657,-.0189,.0053,.986],s:[1,1,1]},{t:[-.0146,.0642,-.1285],r:[-.4455,.0104,.0258,.8948],s:[1,1,1]},{t:[-.0143,.0404,-.1468],r:[-.7027,.0133,.0292,.7107],s:[1,1,1]},{t:[-.0137,.0163,-.146],r:[-.7027,.0133,.0292,.7107],s:[1,1,1]},{t:[.0087,-.0144,-.0627],r:[.5389,-.0411,.1061,.8346],s:[1,1,1]},{t:[.0058,.0446,-.0897],r:[.2331,.0139,-.0389,.9716],s:[1,1,1]},{t:[.0052,.0621,-.1248],r:[-.3041,.0513,-.0024,.9512],s:[1,1,1]},{t:[.0022,.0442,-.1503],r:[-.5472,.0609,.0335,.8341],s:[1,1,1]},{t:[9e-4,.0239,-.1579],r:[-.5472,.0609,.0335,.8341],s:[1,1,1]},{t:[.0194,-.0172,-.0627],r:[.5054,-.1365,.0899,.8473],s:[1,1,1]},{t:[.0276,.0346,-.0893],r:[.4597,-.0527,-.1093,.8797],s:[1,1,1]},{t:[.0334,.0611,-.1099],r:[.5162,-.056,-.0989,.8489],s:[1,1,1]},{t:[.0378,.0805,-.1194],r:[.4448,-.0407,-.0462,.8935],s:[1,1,1]},{t:[.0411,.0949,-.1311],r:[.4448,-.0407,-.0462,.8935],s:[1,1,1]}],[li.THUMBS_DOWN]:[{t:[.0237,.033,-.083],r:[.325,.2979,.5612,.7004],s:[1,1,1]},{t:[.0039,.0142,-.1018],r:[.0744,.4501,.7672,.4508],s:[1,1,1]},{t:[-.0239,-.0191,-.133],r:[.2089,.5732,.7915,.0363],s:[1,1,1]},{t:[-.0341,-.0435,-.1401],r:[.2664,.6251,.7316,.0555],s:[1,1,1]},{t:[-.0476,-.0698,-.144],r:[.2664,.6251,.7316,.0555],s:[1,1,1]},{t:[-3e-4,.0251,-.0989],r:[.2488,.3591,.5717,.6944],s:[1,1,1]},{t:[-.0603,.0201,-.1463],r:[-.2217,-.1036,.5936,.7667],s:[1,1,1]},{t:[-.045,.0116,-.1809],r:[.681,.4806,-.3657,-.4143],s:[1,1,1]},{t:[-.0253,.0071,-.1724],r:[.7487,.5817,-.2444,-.2032],s:[1,1,1]},{t:[-.0121,.0068,-.1535],r:[.7487,.5817,-.2444,-.2032],s:[1,1,1]},{t:[.001,.0374,-.1005],r:[.2971,.3158,.527,.7309],s:[1,1,1]},{t:[-.0548,.0447,-.1454],r:[-.2475,-.1117,.5236,.8076],s:[1,1,1]},{t:[-.0369,.0331,-.181],r:[.759,.413,-.3155,-.3922],s:[1,1,1]},{t:[-.0126,.0231,-.1665],r:[.8595,.4988,-.1065,-.0339],s:[1,1,1]},{t:[-.0084,.0248,-.1428],r:[.8595,.4988,-.1065,-.0339],s:[1,1,1]},{t:[.0064,.0472,-.1018],r:[.3122,.2567,.4998,.766],s:[1,1,1]},{t:[-.0402,.0619,-.1463],r:[-.22,-.1072,.4537,.8569],s:[1,1,1]},{t:[-.025,.0506,-.1806],r:[.8003,.3914,-.2353,-.3886],s:[1,1,1]},{t:[-.0035,.0369,-.1624],r:[.8979,.4322,-.0728,-.0395],s:[1,1,1]},{t:[-8e-4,.0373,-.1409],r:[.8979,.4322,-.0728,-.0395],s:[1,1,1]},{t:[.0136,.0558,-.1017],r:[.3278,.1772,.4672,.8018],s:[1,1,1]},{t:[-.0219,.0775,-.1452],r:[-.1811,-.0932,.4016,.8929],s:[1,1,1]},{t:[-.0108,.0677,-.1758],r:[.7842,.3582,-.2073,-.4623],s:[1,1,1]},{t:[.004,.0547,-.1656],r:[.9158,.3542,-.0821,-.1706],s:[1,1,1]},{t:[.0096,.0511,-.1481],r:[.9158,.3542,-.0821,-.1706],s:[1,1,1]}],[li.VICTORY]:[{t:[-.0017,-.0652,-.0663],r:[.5651,.0392,-.0573,.8221],s:[1,1,1]},{t:[-.0247,-.042,-.0786],r:[.3207,.0849,.243,.9115],s:[1,1,1]},{t:[-.0407,-.0141,-.1186],r:[-.0285,-.1953,.5625,.8029],s:[1,1,1]},{t:[-.031,-.0094,-.1439],r:[-.0751,-.3079,.5331,.7845],s:[1,1,1]},{t:[-.0133,-.0043,-.1673],r:[-.0751,-.3079,.5331,.7845],s:[1,1,1]},{t:[-.0136,-.0376,-.076],r:[.5464,.1682,-.0848,.8161],s:[1,1,1]},{t:[-.0272,.0313,-.1019],r:[.6129,.1411,-.0752,.7738],s:[1,1,1]},{t:[-.032,.0692,-.1089],r:[.5643,.143,-.0679,.8103],s:[1,1,1]},{t:[-.0353,.0897,-.1161],r:[.5256,.1162,-.0834,.8386],s:[1,1,1]},{t:[-.038,.11,-.1265],r:[.5256,.1162,-.0834,.8386],s:[1,1,1]},{t:[-9e-4,-.0372,-.0776],r:[.5593,.0765,-.0968,.8197],s:[1,1,1]},{t:[-.0021,.0287,-.1033],r:[.6072,-.0412,-.1868,.7712],s:[1,1,1]},{t:[.01,.0671,-.1136],r:[.5687,2e-4,-.1587,.8071],s:[1,1,1]},{t:[.0156,.0946,-.124],r:[.5609,.0092,-.1498,.8142],s:[1,1,1]},{t:[.019,.1163,-.1339],r:[.5609,.0092,-.1498,.8142],s:[1,1,1]},{t:[.0096,-.0411,-.08],r:[.5291,-.0092,-.0837,.8443],s:[1,1,1]},{t:[.0165,.0173,-.1087],r:[.2191,.1389,-.1874,.9474],s:[1,1,1]},{t:[.009,.0353,-.1427],r:[-.3548,.2386,-.0503,.9026],s:[1,1,1]},{t:[-.0055,.0162,-.1628],r:[-.5898,.2546,.0402,.7653],s:[1,1,1]},{t:[-.0126,-.0042,-.1657],r:[-.5898,.2546,.0402,.7653],s:[1,1,1]},{t:[.0184,-.0469,-.0826],r:[.4806,-.0996,-.0936,.8662],s:[1,1,1]},{t:[.034,.0014,-.1134],r:[.079,.2891,-.1225,.9461],s:[1,1,1]},{t:[.0152,.0077,-.141],r:[-.2784,.3171,.0012,.9066],s:[1,1,1]},{t:[.0023,-.0029,-.1556],r:[-.458,.3482,.1094,.8106],s:[1,1,1]},{t:[-.0053,-.0187,-.1623],r:[-.458,.3482,.1094,.8106],s:[1,1,1]}]}),ui=Object.freeze({[li.RELAXED]:"Relaxed",[li.PINCHING]:"Pinching",[li.FIST]:"Fist",[li.THUMBS_UP]:"Thumbs Up",[li.POINTING]:"Pointing",[li.ROCK]:"Rock",[li.THUMBS_DOWN]:"Thumbs Down",[li.VICTORY]:"Victory"});class pi{}const gi=new e.Vector3,mi=new e.Quaternion;class fi{constructor(t,i){this.simulatorControllerState=t,this.simulatorScene=i,this.leftController=new e.Object3D,this.rightController=new e.Object3D,this.leftHandBones=[],this.rightHandBones=[],this.leftHandPose=li.RELAXED,this.rightHandPose=li.RELAXED,this.leftHandTargetJoints=ci[li.RELAXED],this.rightHandTargetJoints=di[li.RELAXED],this.lerpSpeed=.1,this.onHandPoseChangeRequestBound=this.onHandPoseChangeRequest.bind(this),this.leftXRHand=new pi,this.rightXRHand=new pi}init({input:e}){this.input=e,this.loadMeshes(),this.simulatorScene.add(this.leftController),this.simulatorScene.add(this.rightController)}loadMeshes(){this.loader=new o,this.loader.setPath("https://cdn.jsdelivr.net/npm/@webxr-input-profiles/assets@1.0/dist/profiles/generic-hand/"),this.loader.load("left.glb",(e=>{this.leftHand=e.scene,this.leftController.add(this.leftHand),Ze.forEach((t=>{const i=e.scene.getObjectByName(t);i?this.leftHandBones.push(i):console.warn(`Couldn't find ${t} in left hand mesh`)})),this.setLeftHandJoints(this.leftHandTargetJoints),this.input.hands[0]?.dispatchEvent?.({type:"connected",data:{hand:this.leftXRHand,handedness:"left"}})})),this.loader.load("right.glb",(e=>{this.rightHand=e.scene,this.rightController.add(this.rightHand),Ze.forEach((t=>{const i=e.scene.getObjectByName(t);i?this.rightHandBones.push(i):console.warn(`Couldn't find ${t} in right hand mesh`)})),this.setRightHandJoints(this.rightHandTargetJoints),this.input.hands[1]?.dispatchEvent?.({type:"connected",data:{hand:this.rightXRHand,handedness:"right"}})}))}setLeftHandLerpPose(e){this.leftHandPose!==e&&(e===li.PINCHING?this.input.dispatchEvent({type:"selectstart",target:this.input.controllers[0],data:{handedness:"left"}}):this.leftHandPose===li.PINCHING&&this.input.dispatchEvent({type:"selectend",target:this.input.controllers[0],data:{handedness:"left"}}),this.leftHandPose=e,this.leftHandTargetJoints=ci[e],this.updateHandPosePanel())}setRightHandLerpPose(e){this.rightHandPose!==e&&(e===li.PINCHING?this.input.dispatchEvent({type:"selectstart",target:this.input.controllers[1],data:{handedness:"right"}}):this.rightHandPose===li.PINCHING&&this.input.dispatchEvent({type:"selectend",target:this.input.controllers[1],data:{handedness:"right"}}),this.rightHandPose=e,this.rightHandTargetJoints=di[e],this.updateHandPosePanel())}setLeftHandJoints(e){this.leftHandPose===li.PINCHING&&this.input.dispatchEvent({type:"selectend",target:this.input.controllers[1],data:{handedness:"left"}}),e!=this.leftHandTargetJoints&&(this.leftHandPose=void 0,this.leftHandTargetJoints=e);for(let t=0;t<this.leftHandBones.length;t++){const i=this.leftHandBones[t],s=e[t];i&&s&&(i.position.fromArray(s.t),i.quaternion.fromArray(s.r),i.scale.fromArray([1,1,1]))}}setRightHandJoints(e){this.rightHandPose===li.PINCHING&&this.input.dispatchEvent({type:"selectend",target:this.input.controllers[1],data:{handedness:"right"}}),e!=this.rightHandTargetJoints&&(this.rightHandPose=void 0,this.rightHandTargetJoints=e);for(let t=0;t<this.rightHandBones.length;t++){const i=this.rightHandBones[t],s=e[t];i&&s&&(i.position.fromArray(s.t),i.quaternion.fromArray(s.r),i.scale.fromArray([1,1,1]))}}update(){this.lerpLeftHandPose(),this.lerpRightHandPose(),this.syncHandJoints()}lerpLeftHandPose(){for(let e=0;e<this.leftHandBones.length;e++){const t=this.leftHandBones[e],i=this.leftHandTargetJoints[e];t&&i&&(gi.fromArray(i.t),mi.fromArray(i.r),t.position.lerp(gi,this.lerpSpeed),t.quaternion.slerp(mi,this.lerpSpeed))}}lerpRightHandPose(){for(let e=0;e<this.rightHandBones.length;e++){const t=this.rightHandBones[e],i=this.rightHandTargetJoints[e];t&&i&&(gi.fromArray(i.t),mi.fromArray(i.r),t.position.lerp(gi,this.lerpSpeed),t.quaternion.slerp(mi,this.lerpSpeed))}}syncHandJoints(){const t=this.input.hands,i=t[0];if(i){this.leftController.updateWorldMatrix(!0,!1),i.position.setFromMatrixPosition(this.leftController.matrixWorld),i.setRotationFromMatrix(this.leftController.matrixWorld),i.updateMatrix();for(let t=0;t<this.leftHandBones.length;t++){const s=Ze[t];s in i.joints||(i.joints[s]=new e.Group,i.add(i.joints[s])),i.joints[s].position.copy(this.leftHandBones[t].position),i.joints[s].quaternion.copy(this.leftHandBones[t].quaternion),i.updateWorldMatrix(!1,!0)}}const s=t[1];if(s){this.rightController.updateWorldMatrix(!0,!1),s.position.setFromMatrixPosition(this.rightController.matrixWorld),s.setRotationFromMatrix(this.rightController.matrixWorld),s.updateMatrix();for(let t=0;t<this.rightHandBones.length;t++){const i=Ze[t];i in s.joints||(s.joints[i]=new e.Group,s.add(s.joints[i])),s.joints[i].position.copy(this.rightHandBones[t].position),s.joints[i].quaternion.copy(this.rightHandBones[t].quaternion),s.updateWorldMatrix(!1,!0)}}}setLeftHandPinching(e=!0){this.setLeftHandLerpPose(e?li.PINCHING:li.RELAXED)}setRightHandPinching(e=!0){this.setRightHandLerpPose(e?li.PINCHING:li.RELAXED)}showHands(){this.leftController.visible=!0,this.rightController.visible=!0;for(let e=0;e<this.input.hands.length;e++)this.input.hands[e].visible=!0;this.updateHandPosePanel()}hideHands(){this.leftController.visible=!1,this.rightController.visible=!1;for(let e=0;e<this.input.hands.length;e++)this.input.hands[e].visible=!1;this.updateHandPosePanel()}updateHandPosePanel(){this.handPosePanelElement&&(0===this.simulatorControllerState.currentControllerIndex?(this.handPosePanelElement.visible=this.leftController.visible,this.handPosePanelElement.handPose=this.leftHandPose):(this.handPosePanelElement.visible=this.rightController.visible,this.handPosePanelElement.handPose=this.rightHandPose))}setHandPosePanelElement(e){this.handPosePanelElement&&this.handPosePanelElement.removeEventListener(hi.type,this.onHandPoseChangeRequestBound),e.addEventListener(hi.type,this.onHandPoseChangeRequestBound),this.handPosePanelElement=e,this.updateHandPosePanel()}onHandPoseChangeRequest(e){if(e.type!=hi.type)return;const t=e;0===this.simulatorControllerState.currentControllerIndex?this.setLeftHandLerpPose(t.pose):this.setRightHandLerpPose(t.pose)}toggleHandedness(){this.simulatorControllerState.currentControllerIndex=(this.simulatorControllerState.currentControllerIndex+1)%2,this.updateHandPosePanel()}}class vi{constructor(){this.elements=[],this.interfaceVisible=!0}init(e,t,i){this.createModeIndicator(e,t),this.showGeminiLivePanel(e),this.createHandPosePanel(e,i),this.showInstructions(e)}createModeIndicator(e,t){if(e.modeIndicator.enabled){const i=document.createElement(e.modeIndicator.element);document.body.appendChild(i),t.setModeIndicatorElement(i),this.elements.push(i)}}showInstructions(e){if(e.instructions.enabled){const t=document.createElement(e.instructions.element);t.customInstructions=e.instructions.customInstructions,document.body.appendChild(t),this.elements.push(t)}}showGeminiLivePanel(e){if(e.geminilive){const e=document.createElement("xrblocks-simulator-geminilive");document.body.appendChild(e),this.elements.push(e)}}createHandPosePanel(e,t){if(e.handPosePanel.enabled){const i=document.createElement(e.handPosePanel.element);document.body.appendChild(i),t.setHandPosePanelElement(i),this.elements.push(i)}}hideUiElements(){for(const e of this.elements)e.style.display="none";this.interfaceVisible=!1}showUiElements(){for(const e of this.elements)e.style.display="";this.interfaceVisible=!0}getInterfaceVisible(){return!this.interfaceVisible}toggleInterfaceVisible(){this.interfaceVisible?this.hideUiElements():this.showUiElements()}}class yi extends e.Scene{constructor(){super()}async init(t){this.addLights(),t.scenePath&&await this.loadGLTF(t.scenePath,new e.Vector3(t.initialScenePosition.x,t.initialScenePosition.y,t.initialScenePosition.z))}addLights(){this.add(new e.HemisphereLight(12303291,8947848,3))}async loadGLTF(e,t){const i=new o;return new Promise(((s,n)=>{i.load(e,(e=>{e.scene.position.copy(t),this.add(e.scene),this.gltf=e,s(e)}),(()=>{}),(e=>{n(e)}))}))}}async function wi(e,t,i){const s=e.constructor.dependencies;null!=s?await e.init(Object.fromEntries(Object.entries(s).map((([e,i])=>{const s=t.get(i);if(!s)throw new Error(`Dependency not found for key: ${i.name}`);return[e,s]})))):await e.init(i)}class xi extends S{static{this.dependencies={waitFrame:qe,registry:Ue}}constructor(){super(),this.journeyId=0}init({waitFrame:e,registry:t}){this.waitFrame=e,this.registry=t}stopJourney(){++this.journeyId}isOnJourneyId(e){return e==this.journeyId}async loadJourney(e){console.log("Load journey");const t=++this.journeyId;for(let i=0;this.isOnJourneyId(t)&&i<e.length;++i)wi(e[i],this.registry,void 0),await e[i].play({simulatorUser:this,journeyId:t,waitFrame:this.waitFrame});console.log("Journey finished")}}class Si extends S{static{this.dependencies={simulatorOptions:yt,input:ct,timer:e.Timer,camera:e.Camera,renderer:e.WebGLRenderer,scene:e.Scene,registry:Ue,options:Et,depth:Oe}}constructor(e){super(),this.renderMainScene=e,this.simulatorScene=new yi,this.depth=new ai(this.simulatorScene),this.simulatorControllerState=new Vt,this.hands=new fi(this.simulatorControllerState,this.simulatorScene),this.simulatorUser=new xi,this.userInterface=new vi,this.controls=new ri(this.simulatorControllerState,this.hands,this.setStereoRenderMode.bind(this),this.userInterface),this.renderDepthPass=!1,this.renderMode=It.DEFAULT,this.stereoCameras=[],this.initialized=!1,this.renderSimulatorSceneToCanvasBound=this.renderSimulatorSceneToCanvas.bind(this),this.add(this.simulatorUser)}async init({simulatorOptions:t,input:s,timer:n,camera:r,renderer:o,scene:a,registry:h,options:l,depth:c}){if(this.initialized)return;const d=h.get(je),u=h.get(ye);this.options=t,r.position.copy(this.options.initialCameraPosition),this.userInterface.init(t,this.controls,this.hands),o.autoClearColor=!1,await this.simulatorScene.init(t),this.hands.init({input:s}),this.controls.init({camera:r,input:s,timer:n,renderer:o,simulatorOptions:t}),d&&!this.camera&&(this.camera=new At(o),this.camera.init(),d.registerSimulatorCamera(this.camera)),l.depth.enabled&&(this.renderDepthPass=!0,this.depth.init(o,r,c),l.depth.depthMesh.enabled&&u&&r.add(u)),a.add(r),this.options.stereo.enabled&&this.setupStereoCameras(r),this.virtualSceneRenderTarget=new e.WebGLRenderTarget(o.domElement.width,o.domElement.height,{stencilBuffer:l.stencil});const p=new e.MeshBasicMaterial({map:this.virtualSceneRenderTarget.texture,transparent:!0});"screen"===this.options.blendingMode&&(p.blending=e.CustomBlending,p.blendSrc=e.OneFactor,p.blendDst=e.OneMinusSrcColorFactor,p.blendEquation=e.AddEquation),this.virtualSceneFullScreenQuad=new i(p),this.renderer=o,this.mainCamera=r,this.mainScene=a,this.initialized=!0}simulatorUpdate(){this.controls.update(),this.hands.update(),this.renderDepthPass&&this.depth.update()}setStereoRenderMode(e){this.options.stereo.enabled&&(this.renderMode=e)}setupStereoCameras(e){const t=e.clone(),i=e.clone();t.layers.disableAll(),t.layers.enable(0),t.layers.enable(1),i.layers.disableAll(),i.layers.enable(0),i.layers.enable(2),t.position.set(-.0315,0,0),i.position.set(.0315,0,0),t.updateWorldMatrix(!0,!1),i.updateWorldMatrix(!0,!1),this.stereoCameras.length=0,this.stereoCameras.push(t,i),e.add(t,i),this.setStereoRenderMode(It.STEREO_LEFT)}onBeforeSimulatorSceneRender(){this.camera&&this.camera.onBeforeSimulatorSceneRender(this.mainCamera,this.renderSimulatorSceneToCanvasBound)}onSimulatorSceneRendered(){this.camera&&this.camera.onSimulatorSceneRendered()}getRenderCamera(){return{[It.DEFAULT]:this.mainCamera,[It.STEREO_LEFT]:this.stereoCameras[0],[It.STEREO_RIGHT]:this.stereoCameras[1]}[this.renderMode]}renderScene(){if(this.renderer&&this.options.renderToRenderTexture){if(this.virtualSceneRenderTarget.width!=this.renderer.domElement.width||this.virtualSceneRenderTarget.height!=this.renderer.domElement.height){const t=!!this.virtualSceneRenderTarget?.stencilBuffer;this.virtualSceneRenderTarget.dispose(),this.virtualSceneRenderTarget=new e.WebGLRenderTarget(this.renderer.domElement.width,this.renderer.domElement.height,{stencilBuffer:t}),this.virtualSceneFullScreenQuad.material.map=this.virtualSceneRenderTarget.texture}this.renderer.setRenderTarget(this.virtualSceneRenderTarget),this.renderer.clear(),this.renderMainScene(this.getRenderCamera())}}renderSimulatorScene(){this.onBeforeSimulatorSceneRender(),this.renderSimulatorSceneToCanvas(this.getRenderCamera()),this.onSimulatorSceneRendered(),this.options.renderToRenderTexture?this.virtualSceneFullScreenQuad.render(this.renderer):this.renderMainScene(this.getRenderCamera())}renderSimulatorSceneToCanvas(e){this.renderer.setRenderTarget(null),this.renderer.render(this.simulatorScene,e),this.renderer.clearDepth()}}class bi extends S{static{this.dependencies={registry:Ue}}constructor(e={}){super(),this.isCapturing=!1,this.latestAudioBuffer=null,this.accumulatedChunks=[],this.isAccumulating=!1,this.options={sampleRate:16e3,channelCount:1,echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0,...e}}init({registry:e}){this.registry=e}async startCapture(e={}){if(!this.isCapturing){this.onAudioData=e.onAudioData,this.onError=e.onError,this.isAccumulating=e.accumulate||!1,this.isAccumulating&&(this.accumulatedChunks=[]);try{await this.setupAudioCapture(),this.isCapturing=!0}catch(e){console.error("Failed to start audio capture:",e),this.onError?.(e),this.cleanup()}}}stopCapture(){this.isCapturing&&(this.cleanup(),this.isCapturing=!1)}async setupAudioCapture(){this.audioStream=await navigator.mediaDevices.getUserMedia({audio:!0,video:!1});const e=this.audioStream.getAudioTracks()[0].getSettings().sampleRate;this.audioContext=new AudioContext({sampleRate:e}),await this.setupAudioWorklet(),this.sourceNode=this.audioContext.createMediaStreamSource(this.audioStream),this.processorNode=new AudioWorkletNode(this.audioContext,"audio-capture-processor"),this.processorNode.port.onmessage=e=>{"audioData"===e.data.type&&(this.latestAudioBuffer=e.data.data,this.isAccumulating&&this.accumulatedChunks.push(e.data.data),this.onAudioData?.(e.data.data),this.streamToAI(e.data.data))},"suspended"===this.audioContext.state&&await this.audioContext.resume(),this.sourceNode.connect(this.processorNode)}async setupAudioWorklet(){const e=new Blob(["\n class AudioCaptureProcessor extends AudioWorkletProcessor {\n process(inputs, outputs, parameters) {\n const input = inputs[0];\n if (input && input[0]) {\n const inputData = input[0];\n const pcmData = new Int16Array(inputData.length);\n for (let i = 0; i < inputData.length; i++) {\n pcmData[i] = Math.max(-32768, Math.min(32767, inputData[i] * 32768));\n }\n this.port.postMessage({type: 'audioData', data: pcmData.buffer});\n }\n return true;\n }\n }\n registerProcessor('audio-capture-processor', AudioCaptureProcessor);\n "],{type:"application/javascript"}),t=URL.createObjectURL(e);await this.audioContext.audioWorklet.addModule(t),URL.revokeObjectURL(t)}streamToAI(e){if(!this.aiService?.sendRealtimeInput)return;const t=function(e){const t=new Uint8Array(e);let i="";for(let e=0;e<t.length;e++)i+=String.fromCharCode(t[e]);return btoa(i)}(e),i=this.audioContext?.sampleRate||this.options.sampleRate;this.aiService.sendRealtimeInput({audio:{data:t,mimeType:`audio/pcm;rate=${i}`}})}setAIStreaming(e){this.aiService=e?this.registry.get($):void 0}cleanup(){this.processorNode?.disconnect(),this.sourceNode?.disconnect(),this.audioContext&&"closed"!==this.audioContext.state&&this.audioContext.close(),this.audioStream?.getTracks().forEach((e=>e.stop())),this.processorNode=void 0,this.sourceNode=void 0,this.audioContext=void 0,this.audioStream=void 0,this.onAudioData=void 0,this.onError=void 0,this.latestAudioBuffer=null,this.accumulatedChunks=[],this.isAccumulating=!1,this.aiService=void 0}static isSupported(){return!(!navigator.mediaDevices||!navigator.mediaDevices.getUserMedia)}getIsCapturing(){return this.isCapturing}getLatestAudioBuffer(){return this.latestAudioBuffer}clearLatestAudioBuffer(){this.latestAudioBuffer=null}getAccumulatedBuffer(){if(0===this.accumulatedChunks.length)return null;const e=this.accumulatedChunks.reduce(((e,t)=>e+t.byteLength),0),t=new ArrayBuffer(e),i=new Uint8Array(t);let s=0;for(const e of this.accumulatedChunks)i.set(new Uint8Array(e),s),s+=e.byteLength;return t}clearAccumulatedBuffer(){this.accumulatedChunks=[]}getAccumulatedChunkCount(){return this.accumulatedChunks.length}dispose(){this.stopCapture(),super.dispose()}}class Ci extends S{constructor(e={}){super(),this.options={},this.audioQueue=[],this.nextStartTime=0,this.volume=1,this.category="speech",this.options={sampleRate:24e3,channelCount:1,...e},e.category&&(this.category=e.category)}setCategoryVolumes(e){this.categoryVolumes=e,this.updateGainNodeVolume()}setVolume(e){this.volume=Math.max(0,Math.min(1,e)),this.updateGainNodeVolume()}updateGainNodeVolume(){if(this.gainNode&&this.categoryVolumes){const e=this.categoryVolumes.getEffectiveVolume(this.category,this.volume);this.gainNode.gain.value=e}else this.gainNode&&(this.gainNode.gain.value=this.volume)}async initializeAudioContext(){this.audioContext||(this.audioContext=new AudioContext({sampleRate:this.options.sampleRate}),this.nextStartTime=this.audioContext.currentTime,this.gainNode=this.audioContext.createGain(),this.gainNode.connect(this.audioContext.destination),this.updateGainNodeVolume()),"suspended"===this.audioContext.state&&await this.audioContext.resume()}async playAudioChunk(e){if(!e)return;await this.initializeAudioContext();const t=this.base64ToArrayBuffer(e),i=this.audioContext.createBuffer(this.options.channelCount,t.byteLength/2,this.options.sampleRate),s=i.getChannelData(0),n=new Int16Array(t);for(let e=0;e<n.length;e++)s[e]=n[e]/32768;this.audioQueue.push(i),this.scheduleAudioBuffers()}scheduleAudioBuffers(){for(;this.audioQueue.length>0&&this.nextStartTime<=this.audioContext.currentTime+.2;){const e=this.audioQueue.shift(),t=this.audioContext.currentTime,i=Math.max(this.nextStartTime,t),s=this.audioContext.createBufferSource();s.buffer=e,s.connect(this.gainNode||this.audioContext.destination),s.onended=()=>this.scheduleAudioBuffers(),s.start(i),this.nextStartTime=i+e.duration}}clearQueue(){this.audioQueue=[]}getIsPlaying(){return this.nextStartTime>this.audioContext.currentTime}getQueueLength(){return this.audioQueue.length}base64ToArrayBuffer(e){const t=atob(e),i=new Uint8Array(t.length);for(let e=0;e<t.length;e++)i[e]=t.charCodeAt(e);return i.buffer}stop(){this.clearQueue(),this.audioContext&&(this.audioContext.close(),this.audioContext=void 0,this.gainNode=void 0,this.nextStartTime=0)}static isSupported(){return!!("AudioContext"in window)}dispose(){this.stop(),super.dispose()}}const Ti=ae+"musicLibrary/",Ri={ambient:Ti+"AmbientLoop.opus",background:Ti+"BackgroundMusic4.mp3",buttonHover:Ti+"ButtonHover.opus",buttonPress:Ti+"ButtonPress.opus",menuDismiss:Ti+"MenuDismiss.opus"};class Mi extends S{constructor(t,i){super(),this.listener=t,this.categoryVolumes=i,this.audioLoader=new e.AudioLoader,this.currentAudio=null,this.isPlaying=!1,this.musicLibrary=Ri,this.specificVolume=.5,this.musicCategory="music"}setVolume(t){if(this.specificVolume=e.MathUtils.clamp(t,0,1),this.currentAudio&&this.isPlaying&&this.categoryVolumes){const e=this.categoryVolumes.getEffectiveVolume(this.musicCategory,this.specificVolume);this.currentAudio.setVolume(e),console.log(`BackgroundMusic volume updated to: ${e} (specific: ${this.specificVolume})`)}}playMusic(t,i="music"){if(!this.categoryVolumes||!this.listener||!this.audioLoader)return void console.error("BackgroundMusic not properly initialized.");const s=this.musicLibrary[t];if(!s)return void console.error(`BackgroundMusic: Music key "${t}" not found.`);this.stopMusic(),console.log(`BackgroundMusic: Loading sound: ${s}`),this.musicCategory=i;const n=this.listener;this.audioLoader.load(s,(i=>{console.log(`BackgroundMusic: Successfully loaded ${s}`);const r=new e.Audio(n);r.setBuffer(i),r.setLoop("music"===this.musicCategory||"ambient"===this.musicCategory);const o=this.categoryVolumes.getEffectiveVolume(this.musicCategory,this.specificVolume);r.setVolume(o),console.log(`BackgroundMusic: Setting volume for "${t}" to ${o}`),r.play(),this.currentAudio=r,this.isPlaying=!0,console.log(`BackgroundMusic: Playing "${t}" in category "${this.musicCategory}"`)}),(e=>{console.log(`BackgroundMusic: Loading ${s} - ${(e.loaded/e.total*100).toFixed(0)}% loaded`)}),(e=>{console.error(`BackgroundMusic: Error loading sound ${s}:`,e),this.currentAudio=null,this.isPlaying=!1}))}stopMusic(){this.currentAudio&&this.isPlaying&&(console.log("BackgroundMusic: Stopping current audio."),this.currentAudio.stop()),this.currentAudio=null,this.isPlaying=!1}destroy(){console.log("BackgroundMusic Destroying..."),this.stopMusic()}}var Di;!function(e){e.music="music",e.sfx="sfx",e.speech="speech",e.ui="ui"}(Di||(Di={}));class Ei{constructor(){this.isMuted=!1,this.masterVolume=1,this.volumes=Object.fromEntries(Object.values(Di).map((e=>[e,1])))}getCategoryVolume(e){return this.volumes[e]??1}getEffectiveVolume(t,i=1){if(this.isMuted)return 0;const s=this.getCategoryVolume(t),n=e.MathUtils.clamp(i,0,1);return this.masterVolume*s*n}}const _i={BEEP:{frequency:1e3,duration:.07,waveformType:"sine"},CLICK:[{frequency:1500,duration:.02,waveformType:"triangle",delay:0}],ACTIVATE:[{frequency:800,duration:.05,waveformType:"sine",delay:0},{frequency:1200,duration:.07,waveformType:"sine",delay:50}],DEACTIVATE:[{frequency:1200,duration:.05,waveformType:"sine",delay:0},{frequency:800,duration:.07,waveformType:"sine",delay:50}]};class Pi extends S{constructor(){super(...arguments),this.isInitialized=!1,this.debug=!1}_initAudioContext(){this.isInitialized||(this.audioContext=new AudioContext,this.isInitialized=!0,this.debug&&console.log("SoundSynthesizer: AudioContext initialized."))}playTone(e,t,i,s){if(this._initAudioContext(),!this.audioContext)return void console.error("SoundSynthesizer: AudioContext not available. Cannot play tone.");const n=this.audioContext.createOscillator();n.type=s,n.frequency.setValueAtTime(e,this.audioContext.currentTime);const r=this.audioContext.createGain();r.gain.setValueAtTime(i,this.audioContext.currentTime),n.connect(r),r.connect(this.audioContext.destination),n.start();const o=this.audioContext.currentTime+t,a=Math.max(.01,.1*t);r.gain.exponentialRampToValueAtTime(1e-5,o-a),n.stop(o)}playPresetTone(e,t=.5){const i=_i[e];if(i)if(Array.isArray(i))i.forEach((e=>{setTimeout((()=>{this.playTone(e.frequency,e.duration,t,e.waveformType)}),e.delay||0)}));else{const e=i;this.playTone(e.frequency,e.duration,t,e.waveformType)}else console.warn(`SoundSynthesizer: Preset '${e}' not found.`)}}const Ai={ambient:"musicLibrary/AmbientLoop.opus",buttonHover:"musicLibrary/ButtonHover.opus",paintOneShot1:"musicLibrary/PaintOneShot1.opus"};let Oi=0;class Ii extends S{constructor(t,i){super(),this.listener=t,this.categoryVolumes=i,this.audioLoader=new e.AudioLoader,this.soundLibrary=Ai,this.activeSounds=new Map,this.specificVolume=1,this.category="sfx",this.defaultRefDistance=1,this.defaultRolloffFactor=1}playSoundAtObject(t,i,s={}){if(!this.listener||!this.audioLoader||!i)return console.error("SpatialAudio not properly initialized or targetObject missing."),null;const n=this.soundLibrary[t];if(!n)return console.error(`SpatialAudio: Sound key "${t}" not found.`),null;const r=++Oi,o=void 0!==s.volume?s.volume:this.specificVolume,a=s.loop||!1,h=void 0!==s.refDistance?s.refDistance:this.defaultRefDistance,l=void 0!==s.rolloffFactor?s.rolloffFactor:this.defaultRolloffFactor;return console.log(`SpatialAudio: Loading sound "${t}" (${n})`),this.audioLoader.load(n,(n=>{if(console.log(`SpatialAudio: Successfully loaded "${t}"`),!this.listener)return void console.error("SpatialAudio: Listener lost during load.");const c=new e.PositionalAudio(this.listener);c.setBuffer(n),c.setLoop(a),c.setRefDistance(h),c.setRolloffFactor(l);const d=this.categoryVolumes.getEffectiveVolume(this.category,o);c.setVolume(d),i.add(c),this.activeSounds.set(r,{audio:c,target:i,options:s}),a||(c.onEnded=()=>{console.log(`SpatialAudio: Sound "${t}" (ID: ${r}) ended.`),this._cleanupSound(r),s.onEnded&&"function"==typeof s.onEnded&&s.onEnded(),c.onEnded=()=>{}}),c.play(),console.log(`SpatialAudio: Playing "${t}" (ID: ${r}) at object ${i.name||i.uuid}, Volume: ${d}`)}),(e=>{console.log(`SpatialAudio: Loading "${t}" - ${(e.loaded/e.total*100).toFixed(0)}% loaded`)}),(e=>{console.error(`SpatialAudio: Error loading sound "${t}":`,e),this.activeSounds.delete(r)})),r}stopSound(e){const t=this.activeSounds.get(e);t?(console.log(`SpatialAudio: Stopping sound ID: ${e}`),t.audio.isPlaying&&t.audio.stop(),this._cleanupSound(e)):console.warn(`SpatialAudio: Sound ID ${e} not found for stopping.`)}_cleanupSound(e){const t=this.activeSounds.get(e);if(t){if(t.audio.isPlaying)try{t.audio.stop()}catch{}t.target&&t.audio.parent===t.target&&t.target.remove(t.audio),this.activeSounds.delete(e),console.log(`SpatialAudio: Cleaned up sound ID: ${e}`)}}setVolume(t){this.specificVolume=e.MathUtils.clamp(t,0,1),console.log(`SpatialAudio default specific volume set to: ${this.specificVolume}`)}updateAllVolumes(){this.categoryVolumes&&(console.log(`SpatialAudio: Updating volumes for ${this.activeSounds.size} active sounds.`),this.activeSounds.forEach((e=>{const t=void 0!==e.options.volume?e.options.volume:this.specificVolume,i=this.categoryVolumes.getEffectiveVolume(this.category,t);e.audio.setVolume(i)})))}destroy(){console.log("SpatialAudio Destroying...");Array.from(this.activeSounds.keys()).forEach((e=>this.stopSound(e))),this.activeSounds.clear(),console.log("SpatialAudio Destroyed.")}}class Li extends S{static{this.dependencies={soundOptions:St}}constructor(e){super(),this.soundSynthesizer=e,this.isListening=!1,this.lastTranscript="",this.lastConfidence=0,this.playActivationSounds=!1,this.handleStartBound=this._handleStart.bind(this),this.handleResultBound=this._handleResult.bind(this),this.handleEndBound=this._handleEnd.bind(this),this.handleErrorBound=this._handleError.bind(this)}init({soundOptions:e}){this.options=e.speechRecognizer;const t=window.SpeechRecognition||window.webkitSpeechRecognition;if(!t)return console.warn("SpeechRecognizer: Speech Recognition API not supported in this browser."),void(this.error="API not supported");this.recognition=new t,this.recognition.lang=this.options.lang,this.recognition.continuous=this.options.continuous,this.recognition.interimResults=this.options.interimResults,this.recognition.onstart=this.handleStartBound,this.recognition.onresult=this.handleResultBound,this.recognition.onend=this.handleEndBound,this.recognition.onerror=this.handleErrorBound}onSimulatorStarted(){this.playActivationSounds=this.options.playSimulatorActivationSounds}start(){if(this.recognition)if(this.isListening)console.warn("SpeechRecognizer: Already listening.");else try{this.lastTranscript="",this.lastCommand=void 0,this.lastConfidence=0,this.error=void 0,this.recognition.start(),this.isListening=!0,console.debug("SpeechRecognizer: Listening started.")}catch(e){console.error("SpeechRecognizer: Error starting recognition:",e),this.error=e.message||"Start failed",this.isListening=!1,this.dispatchEvent({type:"error",error:this.error})}else console.error("SpeechRecognizer: Not initialized.")}stop(){if(this.recognition&&this.isListening)try{this.recognition.stop(),console.debug("SpeechRecognizer: Stop requested.")}catch(e){console.error("SpeechRecognizer: Error stopping recognition:",e),this.error=e.message||"Stop failed",this.isListening=!1}}getLastTranscript(){return this.lastTranscript}getLastCommand(){return this.lastCommand}getLastConfidence(){return this.lastConfidence}_handleStart(){console.debug("SpeechRecognizer: Listening started."),this.dispatchEvent({type:"start"}),this.playActivationSounds&&this.soundSynthesizer.playPresetTone("ACTIVATE")}_handleResult(e){let t="",i="",s=0;for(let n=e.resultIndex;n<e.results.length;++n){const r=e.results[n],o=r[0].transcript;r.isFinal?(i+=o,s=r[0].confidence):t+=o}if(this.lastTranscript=i.trim()||t.trim(),this.lastConfidence=s,this.lastCommand=void 0,i&&this.options.commands.length>0){const e=i.trim().toUpperCase();for(const t of this.options.commands)if(e.includes(t.toUpperCase())&&this.lastConfidence>=this.options.commandConfidenceThreshold){this.lastCommand=t,console.debug(`SpeechRecognizer Detected Command: ${this.lastCommand}`);break}}this.dispatchEvent({type:"result",originalEvent:e,transcript:this.lastTranscript,confidence:this.lastConfidence,command:this.lastCommand,isFinal:!!i})}_handleEnd(){this.isListening=!1,this.dispatchEvent({type:"end"}),this.options.continuous&&"aborted"!==this.error&&"no-speech"!==this.error?(console.debug("SpeechRecognizer: Restarting continuous listening..."),setTimeout((()=>this.start()),100)):this.playActivationSounds&&this.soundSynthesizer.playPresetTone("DEACTIVATE")}_handleError(e){console.error("SpeechRecognizer: Error:",e.error),this.error=e.error,this.isListening=!1,this.dispatchEvent({type:"error",error:e.error})}destroy(){this.stop(),this.recognition&&(this.recognition.onstart=null,this.recognition.onresult=null,this.recognition.onend=null,this.recognition.onerror=null,this.recognition=void 0)}}class Vi extends S{static{this.dependencies={soundOptions:St}}constructor(e,t=()=>{},i=()=>{},s=e=>{}){super(),this.categoryVolumes=e,this.onStartCallback=t,this.onEndCallback=i,this.onErrorCallback=s,this.synth=window.speechSynthesis,this.voices=[],this.isSpeaking=!1,this.debug=!1,this.specificVolume=1,this.speechCategory="speech",this.synth?(this.loadVoices(),void 0!==this.synth.onvoiceschanged&&(this.synth.onvoiceschanged=this.loadVoices.bind(this))):console.error("SpeechSynthesizer: Speech Synthesis API not supported."),!this.categoryVolumes&&this.synth&&console.warn("SpeechSynthesizer: CategoryVolumes not found. Volume control will use specificVolume only.")}init({soundOptions:e}){this.options=e.speechSynthesizer,this.debug&&console.log("SpeechSynthesizer initialized.")}loadVoices(){this.synth&&(this.voices=this.synth.getVoices(),this.debug&&console.log("SpeechSynthesizer: Voices loaded:",this.voices.length),this.selectedVoice=this.voices.find((e=>e.name.includes("Google")&&e.lang.startsWith("en")))||this.voices.find((e=>e.lang.startsWith("en"))),this.selectedVoice?this.debug&&console.log("SpeechSynthesizer: Selected voice:",this.selectedVoice.name):console.warn("SpeechSynthesizer: No suitable default voice found."))}setVolume(t){this.specificVolume=e.MathUtils.clamp(t,0,1),console.log(`SpeechSynthesizer specific volume set to: ${this.specificVolume}`)}speak(t,i="en-US",s=1,n=1){return new Promise(((r,o)=>{if(!this.synth)return console.warn("SpeechSynthesizer: Cannot speak. API not supported."),o(new Error("Speech Synthesis API not supported."));if(this.isSpeaking){if(!this.options.allowInterruptions){const e="Already speaking and interruptions are not allowed.";return console.warn(`SpeechSynthesizer: ${e}`),o(new Error(e))}console.warn("SpeechSynthesizer: Already speaking. Interrupting current speech."),this.cancel()}const a=new SpeechSynthesisUtterance(t);a.onstart=()=>{this.isSpeaking=!0,console.log("SpeechSynthesizer: Speaking started."),this.onStartCallback&&this.onStartCallback()},a.onend=()=>{this.isSpeaking=!1,console.log("SpeechSynthesizer: Speaking ended."),this.onEndCallback&&this.onEndCallback(),r()},a.onerror=e=>{!this.options.allowInterruptions||"interrupted"!==e.error&&"canceled"!==e.error?(console.error("SpeechSynthesizer: Error occurred:",e.error),this.isSpeaking=!1,this.onErrorCallback(new Error(`Speech synthesis error code ${e.error}`)),o(e.error)):console.warn(`SpeechSynthesizer: Speech utterance interrupted: ${e.error}`)};let h=this.selectedVoice;h&&h.lang.startsWith(i.substring(0,2))||(h=this.voices.find((e=>e.lang===i&&e.name.includes("Google")))||this.voices.find((e=>e.lang.startsWith(i.substring(0,2))&&e.name.includes("Google")))||this.voices.find((e=>e.lang===i))||this.voices.find((e=>e.lang.startsWith(i.substring(0,2))))),h?(a.voice=h,console.log(`SpeechSynthesizer: Using voice: ${h.name} for lang ${i}`)):(a.lang=i,console.warn(`SpeechSynthesizer: No specific voice found for lang ${i}. Using browser default.`)),a.pitch=e.MathUtils.clamp(s,0,2),a.rate=e.MathUtils.clamp(n,.1,10);let l=this.specificVolume;l=this.categoryVolumes?this.categoryVolumes.getEffectiveVolume(this.speechCategory,this.specificVolume):e.MathUtils.clamp(this.specificVolume,0,1),a.volume=l,console.log(`SpeechSynthesizer: Setting utterance volume to ${l}`),this.synth.speak(a)}))}tts(e,t,i,s){this.speak(e,t,i,s)}cancel(){this.synth&&this.synth.speaking&&(this.synth.cancel(),this.isSpeaking=!1,console.log("SpeechSynthesizer: Speech cancelled."))}destroy(){this.cancel(),this.synth&&void 0!==this.synth.onvoiceschanged&&(this.synth.onvoiceschanged=null),this.voices=[],console.log("SpeechSynthesizer destroyed.")}}class Bi extends S{constructor(){super(...arguments),this.categoryVolumes=new Ei,this.soundSynthesizer=new Pi,this.listener=new e.AudioListener}static{this.dependencies={camera:e.Camera,soundOptions:St}}init({camera:e,soundOptions:t}){this.options=t,this.backgroundMusic=new Mi(this.listener,this.categoryVolumes),this.spatialAudio=new Ii(this.listener,this.categoryVolumes),this.audioListener=new bi,this.audioPlayer=new Ci({sampleRate:48e3}),this.audioPlayer.setCategoryVolumes(this.categoryVolumes),e.add(this.listener),this.add(this.backgroundMusic),this.add(this.spatialAudio),this.add(this.audioListener),this.add(this.audioPlayer),this.add(this.soundSynthesizer),this.options.speechRecognizer.enabled&&(this.speechRecognizer=new Li(this.soundSynthesizer),this.add(this.speechRecognizer)),this.options.speechSynthesizer.enabled&&(this.speechSynthesizer=new Vi(this.categoryVolumes),this.add(this.speechSynthesizer))}getAudioListener(){return this.listener}setMasterVolume(t){this.categoryVolumes.masterVolume=e.MathUtils.clamp(t,0,1),this.audioPlayer?.updateGainNodeVolume()}getMasterVolume(){return this.categoryVolumes.isMuted?0:this.categoryVolumes.masterVolume}setCategoryVolume(t,i){t in this.categoryVolumes.volumes&&(this.categoryVolumes.volumes[t]=e.MathUtils.clamp(i,0,1))}getCategoryVolume(e){return e in this.categoryVolumes.volumes?this.categoryVolumes.volumes[e]:1}async enableAudio(e={}){const{streamToAI:t=!0,accumulate:i=!1}=e;t&&this.speechRecognizer?.isListening&&(console.log("Disabling SpeechRecognizer while streaming audio."),this.speechRecognizer.stop()),this.audioListener.setAIStreaming(t),await this.audioListener.startCapture({accumulate:i})}disableAudio(){this.audioListener?.stopCapture()}async startRecording(){await this.audioListener.startCapture({accumulate:!0})}stopRecording(){const e=this.audioListener.getAccumulatedBuffer();return this.audioListener.stopCapture(),e}getRecordedBuffer(){return this.audioListener.getAccumulatedBuffer()}clearRecordedBuffer(){this.audioListener.clearAccumulatedBuffer()}getRecordingSampleRate(){return this.audioListener.audioContext?.sampleRate||48e3}setAIStreaming(e){this.audioListener?.setAIStreaming(e)}isAIStreamingEnabled(){return null!==this.audioListener?.aiService}async playAIAudio(e){24e3!==this.audioPlayer.options.sampleRate&&(this.audioPlayer.options.sampleRate=24e3,this.audioPlayer.audioContext&&this.audioPlayer.stop()),await this.audioPlayer.playAudioChunk(e)}stopAIAudio(){this.audioPlayer?.clearQueue()}isAIAudioPlaying(){return this.audioPlayer?.getIsPlaying()}async playRecordedAudio(e,t){if(!e)return;t&&t!==this.audioPlayer.options.sampleRate&&(this.audioPlayer.options.sampleRate=t,this.audioPlayer.stop());const i=new Uint8Array(e);let s="";for(let e=0;e<i.length;e++)s+=String.fromCharCode(i[e]);const n=btoa(s);await this.audioPlayer.playAudioChunk(n)}isAudioEnabled(){return this.audioListener?.getIsCapturing()}getLatestAudioBuffer(){return this.audioListener?.getLatestAudioBuffer()}clearLatestAudioBuffer(){this.audioListener?.clearLatestAudioBuffer()}getEffectiveVolume(e,t=1){return this.categoryVolumes.getEffectiveVolume(e,t)}muteAll(){this.categoryVolumes.isMuted=!0}unmuteAll(){this.categoryVolumes.isMuted=!1}destroy(){this.backgroundMusic?.destroy(),this.spatialAudio?.destroy(),this.speechRecognizer?.destroy(),this.speechSynthesizer?.destroy(),this.audioListener?.dispose(),this.audioPlayer?.dispose(),this.listener?.parent?.remove(this.listener)}}const Fi=.868,zi=new e.Vector3;class ki extends S{get rangeX(){return Math.max(this.aspectRatio,1)}get rangeY(){return Math.max(1/this.aspectRatio,1)}constructor(t={},i,s){super(),this.name="View",this.isQuad=!0,this.isRoot=!1,this.isView=!0,this.selectable=!0,this.weight=.5,this.width=1,this.height=1,this.x=0,this.y=0,this.z=0,this.paddingX=0,this.paddingY=0,this.paddingZ=0,this.opacity=1,this.aspectRatio=1,i&&s&&(this.mesh=new e.Mesh(i,s),this.add(this.mesh)),Object.assign(this,t)}static dpToMeters(e){return e*Fi*.001}dpToLocalUnits(e){return this.getWorldScale(zi),ki.dpToMeters(e)/zi.x}show(){this.visible=!0,this.traverse((e=>{e.visible=!0}))}hide(){this.visible=!1,this.traverse((e=>{e.visible=!1}))}updateLayout(){this.isRoot||null==this.parent?(this.aspectRatio=this.width/this.height,this.scale.setScalar(Math.min(this.width,this.height))):this.parent instanceof ki&&(this.position.set((this.x+this.paddingX)*this.parent.rangeX,(this.y-this.paddingY)*this.parent.rangeY,this.paddingZ+ee),this.aspectRatio=this.width/this.height*this.parent.aspectRatio,this.scale.setScalar(Math.min(this.parent.rangeX*this.width,this.parent.rangeY*this.height)),this.renderOrder=this.parent.renderOrder+1)}updateLayouts(){this.updateLayoutsBFS()}updateLayoutsBFS(){const e=[this];for(;e.length>0;){const t=e.shift();t instanceof ki&&(t.updateLayout(),t.children.forEach((t=>{e.push(t)})))}}resetLayout(){}resetLayouts(){const e=[this];for(;e.length>0;){const t=e.shift();t instanceof ki&&(t.resetLayout(),t.children.forEach((t=>{e.push(t)})))}}add(...e){super.add(...e);for(const t of e)t instanceof ki&&t.updateLayoutsBFS();return this}onTriggered(e){}}const ji="https://fonts.gstatic.com/s/roboto/v18/KFOmCnqEu92Fr1Mu4mxM.woff",Ui="https://cdn.jsdelivr.net/gh/marella/material-icons@v1.13.14/iconfont/material-icons.woff";var Ni;let Gi;!function(e){e[e.PENDING=0]="PENDING",e[e.SUCCESS=1]="SUCCESS",e[e.FAILED=2]="FAILED"}(Ni||(Ni={}));let Hi,Wi=Ni.PENDING;class qi extends ki{set text(e){this._text=e,this.useSDFText&&Gi&&this.textObj instanceof Gi?(this.textObj.text=e,this.textObj.sync()):this.updateHTMLText()}get text(){return this._text}constructor(e={},t,i){super(e,t,i),this.useSDFText=!0,this.isRoot=!1,this.name="TextView",this.font=ji,this.fontColor=16777215,this.maxWidth=1,this.mode="fitWidth",this.anchorX="center",this.anchorY="middle",this.textAlign="center",this.imageOffsetX=0,this.imageOffsetY=0,this.x=0,this.y=0,this.width=1,this.height=1,this.lineHeight=0,this.lineCount=0,this._initializeTextCalled=!1,this._text="TextView",this.useSDFText=e.useSDFText??this.useSDFText,this.font=e.font??this.font,this.fontSize=e.fontSize??this.fontSize,this.fontSizeDp=e.fontSizeDp??this.fontSizeDp,this.fontColor=e.fontColor??this.fontColor,this.maxWidth=e.maxWidth??this.maxWidth,this.mode=e.mode??this.mode,this.anchorX=e.anchorX??this.anchorX,this.anchorY=e.anchorY??this.anchorY,this.textAlign=e.textAlign??this.textAlign,this.imageOverlay=e.imageOverlay??this.imageOverlay,this.imageOffsetX=e.imageOffsetX??this.imageOffsetX,this.imageOffsetY=e.imageOffsetY??this.imageOffsetY,this.text=e.text??this._text}async init(e){this.useSDFText=this.useSDFText&&await async function(){if(Gi)return!0;try{const e=await import("troika-three-text");return Gi=e.Text,Wi=Ni.SUCCESS,!0}catch(e){return e instanceof Error&&(Hi=e),Wi=Ni.FAILED,!1}}(),this._initializeText()}setText(e){this.text=e}updateLayout(){if(super.updateLayout(),this.textObj&&(this.textObj.renderOrder=this.renderOrder,void 0===this.fontSizeDp&&"fitWidth"===this.mode))this.textObj.scale.setScalar(this.rangeX);this.fontSizeDp&&this.textObj&&this.createTextSDF()}createTextSDF(){const e=Gi&&this.textObj instanceof Gi?this.textObj:new Gi;e.text=this.text,e.color=I(this.fontColor),e.font=this.font,e.anchorX=this.anchorX,e.anchorY=this.anchorY,void 0!==this.fontSizeDp?e.fontSize=this.dpToLocalUnits(this.fontSizeDp):void 0!==this.fontSize?e.fontSize=this.fontSize:e.fontSize=.06,e.maxWidth=this.maxWidth,e.textAlign=this.textAlign,e.material&&(e.material.depthWrite=!e.material.transparent),e.sync(),this.textObj=e,this.textObj.layers.mask=this.layers.mask,this.add(this.textObj)}createTextHTML(){this.canvas=document.createElement("canvas"),this.ctx=this.canvas.getContext("2d");const t=new e.PlaneGeometry(this.width,this.height),i=new e.CanvasTexture(this.canvas),s=new e.MeshBasicMaterial({map:i,transparent:!0});this.textObj=new e.Mesh(t,s),this.updateHTMLText(),this.add(this.textObj)}updateHTMLText(){if(!this.ctx)return;const{canvas:e,ctx:t}=this;e.width=256*this.width,e.height=256*this.height,t.clearRect(0,0,e.width,e.height);const i=void 0!==this.fontSizeDp?this.dpToLocalUnits(this.fontSizeDp):this.fontSize??.06;t.font=`${256*i}px ${this.font}`,t.fillStyle=`#${I(this.fontColor).toString(16).padStart(6,"0")}`,t.textAlign="center",t.textBaseline="middle",t.fillText(this.text,e.width/2,e.height/2),this.textObj?.material.map&&(this.textObj.material.map.needsUpdate=!0)}onSyncComplete(){if(!(this.useSDFText&&this.textObj instanceof Gi&&this.textObj.textRenderInfo))return;const e=this.textObj.textRenderInfo.caretPositions,t=e.length/4;let i=0;const s=t>0?e[0]:0;let n=999999;for(let s=0;s<t;s++){const t=e[4*s+2];t<n-(e[4*s+3]-t)/2&&(i++,n=t)}this.lineHeight=t>0?(s-n)/i:0,this.lineCount=i,this.dispatchEvent({type:"synccomplete"})}_initializeText(){this._initializeTextCalled||(this._initializeTextCalled=!0,this.useSDFText&&Wi===Ni.SUCCESS?this.createTextSDF():(Wi===Ni.FAILED&&(console.warn("Failed to import `troika-three-text`. For 3D text rendering, please ensure `troika-three-text`, `troika-three-utils`, `troika-worker-utils`, `bidi-js`, and `webgl-sdf-generator` are included in your importmap or installed via npm. Refer to templates/1_ui for an example. Falling back to HTML-based text rendering.","Error details:",Hi?.message),Hi=void 0),this.createTextHTML()),this.useSDFText&&Gi&&this.textObj instanceof Gi&&(this.textObj.addEventListener("synccomplete",this.onSyncComplete.bind(this)),this.imageOverlay&&(new e.TextureLoader).load(this.imageOverlay,(t=>{t.colorSpace=e.SRGBColorSpace,t.offset.x=this.imageOffsetX;const i=this.textObj;i.material.map=t,i.sync()}))),this.updateLayout())}syncTextObj(){Gi&&this.textObj instanceof Gi&&this.textObj.sync()}setTextColor(e){Gi&&this.textObj instanceof Gi&&(this.textObj.color=e)}dispose(){this.useSDFText&&this.textObj&&Gi&&this.textObj instanceof Gi&&this.textObj.removeEventListener("synccomplete",this.onSyncComplete.bind(this)),super.dispose()}}class Xi extends qi{get rangeX(){return 1}get rangeY(){return 1}constructor(t={}){const{backgroundColor:i=11184810}=t;super(t,new e.CircleGeometry(.5,32),new e.MeshBasicMaterial({color:i,transparent:!0,depthWrite:!1,opacity:0,side:e.FrontSide})),this.opacity=1,this.defaultOpacity=0,this.hoverColor=11184810,this.hoverOpacity=.2,this.selectedOpacity=.4,this.font=Ui,Object.assign(this,t)}async init(e){await super.init(),this.mesh&&(this.mesh.renderOrder=this.renderOrder),this.textObj&&(this.textObj.renderOrder=this.renderOrder+1)}onHoverOver(){this.ux&&this.update()}onHoverOut(){this.ux&&this.update()}update(){this.ux&&(this.ux.isHovered()||this.ux.isSelected()?this.mesh.material.opacity=this.ux.isSelected()?this.selectedOpacity*this.opacity:this.hoverOpacity*this.opacity:this.mesh.material.opacity=this.defaultOpacity*this.opacity)}_initializeText(){if(super._initializeText(),this.textObj){if(this.textObj.position.set(0,0,ee),this.textObj.raycast=()=>{},this.update(),"center"===this.mode)this.textObj.scale.setScalar(this.rangeX);this.textObj.scale.set(1,1,1)}this.syncTextObj(),this.updateLayout()}}class Ki extends qi{constructor(e={}){super({font:Ui,...e})}}class $i extends ki{constructor(t={}){super(t),this.initCalled=!1,this.textureLoader=new e.TextureLoader;const i=new e.MeshBasicMaterial({map:null,transparent:!0,depthWrite:!1,side:e.DoubleSide}),s=new e.PlaneGeometry(1,1);this.mesh=new e.Mesh(s,i),this.material=i,this.add(this.mesh)}init(){this.initCalled||(this.initCalled=!0,this.reload())}reload(){if(!this.src)return this.material.map&&(this.material.map=null),this.texture?.dispose(),void(this.texture=void 0);this.texture?.dispose(),this.texture=this.textureLoader.load(this.src,(t=>{t.colorSpace=e.SRGBColorSpace,this.material.map=t,this.updateLayout()}))}updateLayout(){super.updateLayout(),this.mesh&&(this.mesh.renderOrder=this.renderOrder),this.scaleImageToCorrectAspectRatio()}scaleImageToCorrectAspectRatio(){if(this.texture?.image){const{image:e}=this.texture,t=e.width,i=e.height,s=this.rangeX/t,n=this.rangeY/i,r=Math.min(s,n);this.mesh.scale.set(t*r,i*r,1)}}load(e){this.src=e,this.reload()}}class Qi extends qi{constructor(e={}){super(e),this.layers.set(4)}createTextSDF(){super.createTextSDF(),this.textObj.material.depthText=!1,this.textObj.material.depthWrite=!1}}const Yi={uniforms:{uMainTex:{value:null},uUseImage:{value:0},uBackgroundColor:{value:new e.Vector4(.4,.8,1,1)},uBoxSize:{value:new e.Vector2(.5,.5)},uRadius:{value:.05},uOpacity:{value:1}},vertexShader:"\n #define USE_UV\n #include <common>\n #include <batching_pars_vertex>\n #include <uv_pars_vertex>\n #include <envmap_pars_vertex>\n #include <color_pars_vertex>\n #include <fog_pars_vertex>\n #include <morphtarget_pars_vertex>\n #include <skinning_pars_vertex>\n #include <logdepthbuf_pars_vertex>\n #include <clipping_planes_pars_vertex>\n\n void main() {\n #include <uv_vertex>\n #include <color_vertex>\n #include <morphinstance_vertex>\n #include <morphcolor_vertex>\n #include <batching_vertex>\n\n #if defined ( USE_ENVMAP ) || defined ( USE_SKINNING )\n\n #include <beginnormal_vertex>\n #include <morphnormal_vertex>\n #include <skinbase_vertex>\n #include <skinnormal_vertex>\n #include <defaultnormal_vertex>\n\n #endif\n\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <skinning_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n\n #include <worldpos_vertex>\n #include <envmap_vertex>\n #include <fog_vertex>\n }\n ",fragmentShader:"\n precision mediump float;\n\n uniform sampler2D uMainTex;\n uniform vec4 uBackgroundColor;\n uniform vec2 uBoxSize;\n uniform float uRadius;\n uniform float uUseImage;\n uniform float uOpacity;\n\n #define USE_UV\n #include <common>\n #include <dithering_pars_fragment>\n #include <color_pars_fragment>\n #include <uv_pars_fragment>\n #include <map_pars_fragment>\n #include <alphamap_pars_fragment>\n #include <alphatest_pars_fragment>\n #include <alphahash_pars_fragment>\n #include <aomap_pars_fragment>\n #include <lightmap_pars_fragment>\n #include <envmap_common_pars_fragment>\n #include <envmap_pars_fragment>\n #include <fog_pars_fragment>\n #include <specularmap_pars_fragment>\n #include <logdepthbuf_pars_fragment>\n #include <clipping_planes_pars_fragment>\n\n // Distance function for rounded box.\n float distRoundBox(vec2 p, vec2 b, float r) {\n return length(max(abs(p) - b + r, 0.0)) - r;\n }\n\n void main(void) {\n #include <clipping_planes_fragment>\n\n #include <logdepthbuf_fragment>\n #include <map_fragment>\n #include <color_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n #include <alphahash_fragment>\n #include <specularmap_fragment>\n vec2 size = uBoxSize * 1000.0;\n\n // Calculates the adjusted radius based on box size.\n float radius = min(size.x, size.y) * (0.05 + uRadius);\n vec2 half_size = 0.5 * size;\n\n // Compute the distance from the rounded box edge.\n float dist = distRoundBox(vUv * size - half_size, half_size, radius);\n\n // Use lerp for smooth color transition based on distance.\n vec4 colorInside = uBackgroundColor;\n\n if (uUseImage > 0.5) {\n colorInside = texture2D(uMainTex, vUv);\n colorInside.a = 1.0;\n }\n\n // Transparent black for outside.\n vec4 colorOutside = vec4(0.0, 0.0, 0.0, 0.0);\n\n vec4 finalColor = mix(colorInside, colorOutside, smoothstep(0.0, 1.0, dist));\n\n // Return premultiplied alpha.\n gl_FragColor = uOpacity * finalColor.a * vec4(finalColor.rgb, 1.0);\n }\n "};class Ji extends qi{constructor(t={}){const i=new e.PlaneGeometry(1,1),s=O(t.backgroundColor??"#00000000"),{opacity:n=0,radius:r=Yi.uniforms.uRadius.value,boxSize:o=Yi.uniforms.uBoxSize.value}=t,a={...Yi.uniforms,uBackgroundColor:{value:s},uOpacity:{value:n},uAspect:{value:1},uRadius:{value:r},uBoxSize:{value:o}};super(t,i,new e.ShaderMaterial({...Yi,transparent:!0,uniforms:a,depthWrite:!1})),this.name="TextButton",this.fontSize=.05,this.fontColor=16777215,this.opacity=1,this.defaultOpacity=1,this.hoverColor=11184810,this.hoverOpacity=.2,this.selectedFontColor=10066329,this.selectedOpacity=.4,this.width=.9,this.height=.9,this.mode="center",this.imageOffsetX=0,this.imageOffsetY=0,this.uniforms=a,this.opacity=n,this.fontSize=t.fontSize??this.fontSize,this.fontColor=t.fontColor??this.fontColor,this.width=t.width??this.width,this.height=t.height??this.height}async init(){await super.init(),this.textObj.position.set(0,0,ee),this.mesh&&(this.mesh.renderOrder=this.renderOrder),this.textObj.renderOrder=this.renderOrder+1,this.textObj.raycast=()=>{}}update(){if(!this.textObj)return;this.textObj&&(this.textObj.renderOrder=this.renderOrder+1);const e=this.ux;e.isHovered()?e.isSelected()?this.setTextColor(6710886):this.setTextColor(11184810):(this.setTextColor(16777215),this.uniforms.uOpacity.value=this.defaultOpacity*this.opacity)}}class Zi extends ki{constructor(t={}){super(t),this.name="VideoView",this.mode="center",this.isRoot=!1,this.muted=!0,this.loop=!0,this.autoplay=!0,this.playsInline=!0,this.crossOrigin="anonymous",this.videoAspectRatio=0;const i=new e.PlaneGeometry(1,1),s=new e.MeshBasicMaterial({transparent:!0,depthWrite:!1,side:e.DoubleSide});this.mesh=new e.Mesh(i,s),this.material=s,this.add(this.mesh),this.texture instanceof e.Texture||(this.texture=new e.Texture),this.material.map=this.texture}init(){super.init(),this.material.map instanceof e.VideoTexture&&this.material.map.image?this.loadFromVideoTexture(this.material.map):this.src&&this.load(this.src)}load(t){t instanceof HTMLVideoElement?this.loadFromVideoElement(t):t instanceof e.VideoTexture?this.loadFromVideoTexture(t):"string"==typeof t?this.loadFromURL(t):t instanceof ke?this.loadFromStream(t):console.error("VideoView: Invalid video source provided.",t)}loadFromStream(e){this.disposeStreamListener_(),this.stream_=e,this.streamReadyCallback_=e=>{this.stream_?.texture?(this.loadFromVideoTexture(this.stream_.texture),void 0!==e.details?.aspectRatio&&(this.videoAspectRatio=e.details?.aspectRatio),this.updateLayout()):console.warn("Stream is ready, but its texture is not available.")},this.stream_.loaded?this.streamReadyCallback_({details:{aspectRatio:this.stream_.aspectRatio}}):this.stream_.addEventListener("statechange",this.streamReadyCallback_)}loadFromURL(e){this.src=e;const t=document.createElement("video");t.muted=this.muted,t.loop=this.loop,t.playsInline=this.playsInline,t.autoplay=this.autoplay,t.crossOrigin=this.crossOrigin,t.src=e,this.loadFromVideoElement(t)}loadFromVideoElement(t){this.video=t,this.video.autoplay&&this.video.paused&&this.video.play().catch((e=>{console.warn("VideoView: Autoplay prevented for video element.",e)}));const i=new e.VideoTexture(this.video);i.colorSpace=e.SRGBColorSpace,this.texture=i,this.material.map=this.texture;const s=()=>{this.video.videoWidth&&this.video.videoHeight?this.videoAspectRatio=this.video.videoWidth/this.video.videoHeight:(console.warn("VideoView: Video metadata loaded but dimensions are 0."),this.videoAspectRatio=0),this.updateLayout()};this.video.readyState>=this.video.HAVE_METADATA?s():this.video.addEventListener("loadedmetadata",s,{once:!0})}loadFromVideoTexture(e){this.texture=e,this.material.map=this.texture,this.video=this.texture.image,this.video&&this.video.videoWidth&&this.video.videoHeight?(this.videoAspectRatio=this.video.videoWidth/this.video.videoHeight,this.updateLayout()):this.video?this.video.addEventListener("loadedmetadata",(()=>{this.video.videoWidth&&this.video.videoHeight?this.videoAspectRatio=this.video.videoWidth/this.video.videoHeight:this.videoAspectRatio=0,this.updateLayout()}),{once:!0}):(console.warn("VideoView: VideoTexture does not have a valid underlying video element."),this.videoAspectRatio=0,this.updateLayout())}play(){this.video&&this.video.paused&&this.video.play().catch((e=>console.warn("VideoView: Error playing video:",e)))}pause(){this.video&&!this.video.paused&&this.video.pause()}disposeStreamListener_(){this.stream_&&this.streamReadyCallback_&&(this.stream_.removeEventListener("statechange",this.streamReadyCallback_),this.stream_=void 0,this.streamReadyCallback_=void 0)}dispose(){this.disposeStreamListener_(),this.video&&(this.video.pause(),this.video.removeAttribute("src"),this.video.load(),this.video=void 0),this.texture&&(this.texture.dispose(),this.texture=void 0),super.dispose()}updateLayout(){super.updateLayout(),"stretch"===this.mode||this.videoAspectRatio<=0||!this.material.map||this.mesh.scale.set(Math.min(this.rangeX,this.videoAspectRatio*this.rangeY),Math.min(this.rangeY,this.rangeX/this.videoAspectRatio),1)}}function es(e,t){let i=e;for(;i;){if(i===t)return!0;i=i.parent}return!1}function ts(e,t){if(t(e))return!0;for(const i of e.children)if(ts(i,t))return!0;return!1}class is extends S{static{this.dependencies={input:ct,scene:e.Scene}}constructor(){super(),this.local=!0,this.numHands=2,this.height=1.6,this.panelDistance=1.75,this.handedness=1,this.safeSpaceRadius=.2,this.objectDistance=1.5,this.objectAngle=-.1*Math.PI,this.pivots=[],this.hoveredObjectsForController=new Map,this.selectedObjectsForController=new Map,this.touchedObjects=new Map,this.grabbedObjects=new Map}init({input:e,scene:t}){this.input=e,this.controllers=e.controllers,this.scene=t}setHeight(e){this.height=e.position.y}enablePivots(){this.input.enablePivots()}getPivot(e){return this.controllers[e].getObjectByName("pivot")}getPivotPosition(t){return this.getPivot(t)?.getWorldPosition(new e.Vector3)}getReticleDirection(e){return this.controllers[e].reticle?.direction}getReticleTarget(e){return this.controllers[e].reticle?.targetObject}getReticleIntersection(e){return this.controllers[e].reticle?.intersection}isPointingAt(e){for(const t of this.hoveredObjectsForController.values())if(es(t,e))return!0;return!1}isSelectingAt(e){for(const t of this.selectedObjectsForController.values())if(es(t,e))return!0;return!1}getIntersectionAt(e,t=-1){if(-1==t){for(let t=0;t<2;++t)if(this.getReticleTarget(t)===e)return this.getReticleIntersection(t)}else if(this.getReticleTarget(t)===e)return this.getReticleIntersection(t);return null}getControllerPosition(t,i=new e.Vector3){return this.controllers[t].getWorldPosition(i),i}getControllerObjectDistance(t,i){const s=this.getControllerPosition(t),n=new e.Vector3;return i.getWorldPosition(n),s.distanceTo(n)}isSelecting(e=-1){return-1==e?this.input.controllers.some((e=>e.userData.selected)):this.input.controllers[e].userData.selected}isSqueezing(e=-1){return-1==e?this.input.controllers.some((e=>e.userData.squeezing)):this.input.controllers[e].userData.squeezing}onSelectStart(e){const t=e.target,i=this.input.intersectionsForController.get(t).filter((e=>{let t=e.object;for(;t;){if(!0===t.ignoreReticleRaycast)return!1;t=t.parent}return!0}));i&&i.length>0&&(this.selectedObjectsForController.set(t,i[0].object),this.callObjectSelectStart(e,i[0].object))}onSelectEnd(e){const t=e.target,i=this.input.intersectionsForController.get(t);if(i&&i.length>0){const i=this.selectedObjectsForController.get(t);this.callObjectSelectEnd(e,i||null),this.selectedObjectsForController.delete(t);let s=i||null;for(;s;){if(s.isView&&s.visible){s.onTriggered(t.userData.id);break}s=s.parent}}}onSqueezeStart(e){}onSqueezeEnd(e){}update(){if(this.input.controllersEnabled)for(const e of this.input.controllers)this.updateForController(e);this.updateTouchState(),this.updateGrabState()}updateGrabState(){if(this.hands)for(let e=0;e<this.numHands;e++){const t=this.isSelecting(e),i=this.touchedObjects.get(e)||new Set,s=t?i:new Set,n=this.grabbedObjects.get(e)||new Map,r=[...s].filter((e=>!n.has(e))),o=[...n.keys()].filter((e=>!s.has(e)));for(const t of r){const i=this.hands.getWrist(e);if(!i)continue;const s={handIndex:e,hand:i};this.grabbedObjects.has(e)||this.grabbedObjects.set(e,new Map),this.grabbedObjects.get(e).set(t,s),this.callObjectGrabStart(s,t)}for(const e of o){const t=n.get(e);this.callObjectGrabEnd(t,e),n.delete(e)}for(const e of s)if(n.has(e)){const t=n.get(e);this.callObjectGrabbing(t,e)}}}updateTouchState(){if(this.hands)for(let t=0;t<this.numHands;t++){const i=this.hands.getIndexTip(t);if(!i)continue;const s=new e.Vector3;i.getWorldPosition(s);const n=[];this.scene.traverse((t=>{if(t.isMesh&&t.visible){(new e.Box3).setFromObject(t).containsPoint(s)&&n.push(t)}}));const r=this.touchedObjects.get(t)||new Set,o=new Set(n),a=n.filter((e=>!r.has(e))),h=[...r].filter((e=>!o.has(e))),l={handIndex:t,touchPosition:s};if(a.length>0)for(const e of a)this.callObjectTouchStart(l,e);if(h.length>0)for(const e of h)this.callObjectTouchEnd(l,e);for(const e of o)this.callObjectTouching(l,e);o.size>0?this.touchedObjects.set(t,o):this.touchedObjects.delete(t)}}updateForController(e){const t=this.input.intersectionsForController.get(e),i=t.length>0?t[0].object:null,s=this.hoveredObjectsForController.get(e);s!==i?(this.callHoverExit(e,s||null),this.hoveredObjectsForController.set(e,i),this.callHoverEnter(e,i)):s&&this.callOnHovering(e,s)}callHoverExit(e,t){null!=t&&(t.isXRScript&&t.onHoverExit(e),this.callHoverExit(e,t.parent))}callHoverEnter(e,t){null!=t&&(t.isXRScript&&t.onHoverEnter(e),this.callHoverEnter(e,t.parent))}callOnHovering(e,t){null!=t&&(t.isXRScript&&t.onHovering(e),this.callOnHovering(e,t.parent))}callObjectSelectStart(e,t){null!=t&&(t.isXRScript&&t.onObjectSelectStart(e)||this.callObjectSelectStart(e,t.parent))}callObjectSelectEnd(e,t){null!=t&&(t.isXRScript&&t.onObjectSelectEnd(e)||this.callObjectSelectEnd(e,t.parent))}callObjectTouchStart(e,t){null!=t&&(t.isXRScript&&t.onObjectTouchStart(e),this.callObjectTouchStart(e,t.parent))}callObjectTouching(e,t){null!=t&&(t.isXRScript&&t.onObjectTouching(e),this.callObjectTouching(e,t.parent))}callObjectTouchEnd(e,t){null!=t&&(t.isXRScript&&t.onObjectTouchEnd(e),this.callObjectTouchEnd(e,t.parent))}callObjectGrabStart(e,t){null!=t&&(t.isXRScript&&t.onObjectGrabStart(e),this.callObjectGrabStart(e,t.parent))}callObjectGrabbing(e,t){null!=t&&(t.isXRScript&&t.onObjectGrabbing(e),this.callObjectGrabbing(e,t.parent))}callObjectGrabEnd(e,t){null!=t&&(t.isXRScript&&t.onObjectGrabEnd(e),this.callObjectGrabEnd(e,t.parent))}select(e,t){const i=this.input.intersectionsForController.get(t);return i&&i.length>0&&es(i[0].object,e)?i[0]:null}}const ss=Object.freeze(new e.Vector3(0,-1,0)),ns=Object.freeze(new e.Vector3(0,1,0)),rs=Object.freeze(new e.Vector3(0,0,-1)),os=Object.freeze(new e.Vector3(0,0,1)),as=Object.freeze(new e.Vector3(-1,0,0)),hs=Object.freeze(new e.Vector3(1,0,0)),ls=Object.freeze(new e.Vector3(0,0,0)),cs=new e.Quaternion,ds=new e.Euler,us=new e.Vector3;var ps;!function(e){e.TRANSLATING="TRANSLATING",e.ROTATING="ROTATING",e.SCALING="SCALING",e.DO_NOT_DRAG="DO_NOT_DRAG"}(ps||(ps={}));class gs extends S{constructor(){super(...arguments),this.mode=gs.IDLE,this.originalObjectPosition=new e.Vector3,this.originalObjectRotation=new e.Quaternion,this.originalObjectScale=new e.Vector3,this.originalController1Position=new e.Vector3,this.originalController1RotationInverse=new e.Quaternion,this.originalController1MatrixInverse=new e.Matrix4,this.originalScalingControllerDistance=0,this.originalScalingObjectScale=new e.Vector3}static{this.dependencies={input:ct,camera:e.Camera}}static{this.IDLE="IDLE"}static{this.TRANSLATING=ps.TRANSLATING}static{this.ROTATING=ps.ROTATING}static{this.SCALING=ps.SCALING}static{this.DO_NOT_DRAG=ps.DO_NOT_DRAG}init({input:e,camera:t}){this.input=e,this.camera=t}onSelectStart(e){const t=e.target,i=this.input.intersectionsForController.get(t);i&&i.length>0&&this.beginDragging(i[0],t)}onSelectEnd(){this.mode=gs.IDLE,this.intersection=void 0,this.draggableObject=void 0}update(){for(const e of this.input.controllers)this.updateDragging(e)}beginDragging(e,t){const[i,s]=this.findDraggableObjectAndDraggingMode(e.object);return null!=i&&null!=s&&s!=gs.DO_NOT_DRAG&&(this.mode!=gs.IDLE?this.beginScaling(t):(this.draggableObject=i,this.mode=s==gs.ROTATING?gs.ROTATING:gs.TRANSLATING,this.originalController1Position.copy(t.position),this.originalController1MatrixInverse.compose(t.position,t.quaternion,t.scale).invert(),this.originalController1RotationInverse.copy(t.quaternion).invert(),this.intersection=e,this.controller1=t,this.originalObjectRotation.copy(i.quaternion),this.originalObjectPosition.copy(i.position),this.originalObjectScale.copy(i.scale),!0))}beginScaling(e){return this.controller2=e,this.originalScalingControllerDistance=us.subVectors(this.controller1.position,this.controller2.position).length(),this.originalScalingObjectScale.copy(this.intersection.object.scale),this.mode=gs.SCALING,!0}updateDragging(e){return this.mode==gs.TRANSLATING?this.updateTranslating():this.mode==gs.ROTATING?this.updateRotating(e):this.mode==gs.SCALING&&this.updateScaling()}updateTranslating(){const e=this.draggableObject;return e.position.copy(this.originalObjectPosition),e.quaternion.copy(this.originalObjectRotation),e.scale.copy(this.originalObjectScale),e.updateMatrix(),this.controller1.updateMatrix(),e.matrix.premultiply(this.originalController1MatrixInverse).premultiply(this.controller1.matrix),e.position.setFromMatrixPosition(e.matrix),e.dragFacingCamera&&this.turnPanelToFaceTheCamera(),!0}updateRotating(t){if(t!=this.controller1)return;if(t instanceof at)return this.updateRotatingFromMouseController(t);const i=this.draggableObject,s=(new e.Vector3).subVectors(t.position,this.originalController1Position);s.applyQuaternion(this.originalController1RotationInverse);const n=cs.setFromAxisAngle(ns,10*s.x);return i.quaternion.multiplyQuaternions(n,this.originalObjectRotation),!0}updateRotatingFromMouseController(e){const t=this.draggableObject,i=cs.multiplyQuaternions(e.quaternion,this.originalController1RotationInverse),s=ds.setFromQuaternion(i,"YXZ"),n=cs.setFromAxisAngle(ns,-10*s.y);return t.quaternion.multiplyQuaternions(n,this.originalObjectRotation),!0}updateScaling(){const e=us.subVectors(this.controller1.position,this.controller2.position).length()/this.originalScalingControllerDistance;return this.draggableObject.scale.copy(this.originalScalingObjectScale).multiplyScalar(e),!0}turnPanelToFaceTheCamera(){const e=this.draggableObject;us.subVectors(e.position,this.camera.position),e.quaternion.setFromAxisAngle(ns,3*Math.PI/2-Math.atan2(us.z,us.x))}findDraggableObjectAndDraggingMode(e){let t,i,s=e;for(;s&&!t;)t=s.draggable?s:void 0,i=i??s.draggingMode,s=s.parent;return[t,i]}}class ms extends Xi{static{this.dependencies={renderer:e.WebGLRenderer}}constructor(e={}){super({text:"close",...e}),this.fontSize=.8,this.defaultOpacity=.2,this.hoverOpacity=.8,this.backgroundColor=16777215}async init({renderer:e}){await super.init(),this.renderer=e}onTriggered(){console.log("ExitButton triggered: Shutting down XR session.");const e=this.renderer.xr.getSession();e&&e.end()}}class fs extends ki{constructor(){super(...arguments),this.rowWeight=0,this.colWeight=0,this.leftWeight=0,this.topWeight=0,this.cols=0,this.rows=0}static init(e,t,i,s){fs.RowClass=e,fs.ColClass=t,fs.PanelClass=i,fs.OrbiterClass=s}addImage(e){const t=new $i(e);return this.add(t),t}addVideo(e){const t=new Zi(e);return this.add(t),t}addIconButton(e={}){const t=new Xi(e);return this.add(t),t}addTextButton(e={}){const t=new Ji(e);return this.add(t),t}addIcon(e={}){const t=new Ki(e);return this.add(t),t}addText(e={}){const t=new qi(e);return this.add(t),t}addLabel(e){const t=new Qi(e);return this.add(t),t}addOrbiter(e={}){const t=new fs.OrbiterClass(e);return this.add(t),t}addExitButton(e={}){const t=new ms(e);return this.add(t),t}addPanel(e={}){e.isRoot=!1;const t=new fs.PanelClass(e);return this.add(t),t}addRow(e={}){const t=new fs.RowClass(e);return t.topWeight=this.rowWeight,t.height=t.weight,this.rowWeight+=t.weight,this.add(t),this.rows++,t}addCol(e={}){const t=new fs.ColClass(e);return t.leftWeight=this.colWeight,t.width=t.weight,this.colWeight+=t.weight,this.add(t),this.cols++,t}updateLayout(){this.x=-.5+(this.leftWeight+this.width/2),this.y=.5-(this.topWeight+this.height/2),super.updateLayout()}resetLayout(){this.rows=0,this.cols=0,this.colWeight=0,this.rowWeight=0;for(const e of this.children)e instanceof fs.RowClass?(e.topWeight=this.rowWeight,e.height=e.weight,this.rowWeight+=e.weight,this.rows++):e instanceof fs.ColClass&&(e.leftWeight=this.colWeight,e.width=e.weight,this.colWeight+=e.weight,this.cols++)}}const vs={uniforms:{uMainTex:{value:null},uUseImage:{value:0},uBackgroundColor:{value:new e.Vector4(.4,.8,1,1)},uBoxSize:{value:new e.Vector2(.5,.5)},uRadius:{value:.05},uReticleUVs:{value:new e.Vector4(.5,.5,.5,.5)},uSelected:{value:new e.Vector2(0,0)},uBorderWidth:{value:.1},uHighlightRadius:{value:.2},uOutlineWidth:{value:.01},uOpacity:{value:1}},vertexShader:"\n varying vec2 vTexCoord;\n\n void main() {\n vTexCoord = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n }\n ",fragmentShader:"\n precision mediump float;\n\n uniform sampler2D uMainTex;\n uniform vec4 uBackgroundColor;\n uniform vec2 uBoxSize;\n uniform float uRadius;\n uniform float uUseImage;\n\n uniform vec4 uReticleUVs;\n uniform vec2 uSelected;\n uniform float uBorderWidth;\n uniform float uHighlightRadius;\n uniform float uOutlineWidth;\n uniform float uOpacity;\n\n varying vec2 vTexCoord;\n\n // Distance function for rounded box.\n float distRoundBox(vec2 p, vec2 b, highp float r) {\n return length(max(abs(p) - b + r, 0.0)) - r;\n }\n\n vec4 highlight(in vec4 baseColor, in vec4 colorOutside,\n in float distOuterUV, in float aa, in vec2 mouse, in float selected) {\n\n vec4 highlightColor = vec4(0.0);\n float normDist = 1.0; // Initialize outside the highlight range\n bool mousePressed = selected > 0.0;\n bool mouseHovering = selected <= 0.0 && length(uReticleUVs.xy) > 0.0;\n bool mouseNearBorder = (mouseHovering || mousePressed);\n vec4 finalColor = baseColor;\n\n if (mouseNearBorder) {\n // Scale mouse and fragment coordinates by the inverse of uBoxSize\n\n vec2 fragAspect = vTexCoord;\n fragAspect.x *= uBoxSize.x / uBoxSize.y;\n vec2 mouseAspect = mouse;\n mouseAspect.x *= uBoxSize.x / uBoxSize.y;\n\n // Calculate vector from mouse to fragment in aspect-corrected space\n vec2 diffAspect = fragAspect - mouseAspect;\n\n // Calculate the distance in the aspect-corrected space\n float distToMouseAspect = length(diffAspect);\n\n // Normalized distance from mouse within the highlight radius\n normDist = distToMouseAspect / uHighlightRadius;\n\n // Define highlight color\n float innerWhite = mousePressed ? 0.9 : 0.8;\n\n // Radial gradient calculation\n float radialFactor = smoothstep(1.0, 0.0, normDist); // 1 at center, 0 at edge\n highlightColor = vec4(vec3(innerWhite), 1.0) * vec4(vec3(1.0), radialFactor);\n\n // Calculate distance to the inner edge of the border in UV space\n float distInnerUV = distRoundBox(\n (vTexCoord - 0.5) * uBoxSize,\n (uBoxSize - uBorderWidth) * 0.5, 0.5 * uRadius);\n\n float highlightEdgeSharpness = 200.0;\n float innerHighlightAmount = clamp(highlightEdgeSharpness * -distOuterUV, 0.0, 1.0);\n float outerHighlightAmount = clamp(highlightEdgeSharpness * distInnerUV, 0.0, 1.0);\n float highlightAmount = min(innerHighlightAmount, outerHighlightAmount);\n vec4 highlightColor = mix(finalColor, finalColor + highlightColor, highlightColor.a);\n finalColor = mix(finalColor, highlightColor, highlightAmount);\n }\n return finalColor;\n }\n\n void main(void) {\n vec2 size = uBoxSize * 1000.0;\n float radius = min(size.x, size.y) * (0.05 + uRadius);\n vec2 half_size = 0.5 * size;\n\n // Distance to the outer edge of the round box in UV space (0-1)\n float distOuterUV = distRoundBox(vTexCoord * uBoxSize - uBoxSize * 0.5, uBoxSize * 0.5, uRadius);\n\n // Antialiasing delta\n float aa = fwidth(distOuterUV) * 0.8;\n\n // Base color: opaque inside, transparent outside\n vec4 colorInside = uBackgroundColor;\n if (uUseImage > 0.5) {\n colorInside = texture2D(uMainTex, vTexCoord);\n colorInside.a = 1.0;\n }\n vec4 colorOutside = vec4(0.0, 0.0, 0.0, 0.0);\n vec4 baseColor = mix(colorInside, colorOutside, smoothstep(0.0, aa, distOuterUV));\n\n vec4 finalColor1 = highlight(baseColor, colorOutside, distOuterUV, aa, uReticleUVs.xy, uSelected.x);\n vec4 finalColor2 = highlight(baseColor, colorOutside, distOuterUV, aa, uReticleUVs.zw, uSelected.y);\n\n gl_FragColor = uOpacity * max(finalColor1, finalColor2);\n }\n "};class ys extends e.Mesh{get uniforms(){return this.material.uniforms}constructor(t,i,s=1){const n=e.UniformsUtils.clone(t.uniforms),r=new e.ShaderMaterial({uniforms:n,vertexShader:t.vertexShader,fragmentShader:t.fragmentShader,transparent:!0,depthWrite:!1,side:e.DoubleSide});super(new e.PlaneGeometry(s,s),r),this.name="PanelMesh",i&&(n.uBackgroundColor.value=O(i))}setWidthHeight(e,t){this.uniforms.uBoxSize.value.set(e,t)}setAspectRatio(e){this.scale.set(Math.max(e,1),Math.max(1/e,1),1)}}const ws=888.832*.001,xs=624.96*.001;class Ss extends ki{static{this.dependencies={user:is,timer:e.Timer}}constructor(e={}){super(e),this.keepFacingCamera=!0,this.name="Panel",this.isPanel=!0,this.draggable=!1,this.touchable=!1,this.useDefaultPosition=!0,this.useBorderlessShader=!1,this.showHighlights=!1,this.backgroundColor="#c2c2c255",this._fadeState="idle",this._fadeDuration=.2,this._fadeTimer=0,this._currentOpacity=1,this._startOpacity=1,this._targetOpacity=1;const t=e.draggable??this.draggable,i=e.useBorderlessShader??!t,s=i?1:1.3,n=i?Yi:vs;e.useBorderlessShader=i,this.showHighlights=!i,this.backgroundColor=e.backgroundColor??this.backgroundColor,this.draggable=t,this.draggingMode=e.draggingMode??this.draggable?ps.TRANSLATING:ps.DO_NOT_DRAG,this.touchable=e.touchable??this.touchable,this.isRoot=e.isRoot??!0,this.width=e.width??(this.isRoot?ws:1),this.height=e.height??(this.isRoot?xs:1),this.showHighlights=e.showHighlights??this.showHighlights,this.useDefaultPosition=e.useDefaultPosition??this.useDefaultPosition,this.useBorderlessShader=e.useBorderlessShader??this.useBorderlessShader,this.mesh=new ys(n,this.backgroundColor,s),this.add(this.mesh),this.updateLayout()}init({user:e,timer:t}){super.init(),this.selectable=!0,this.timer=t,0===this.position.x&&0===this.position.y&&0===this.position.z||(this.useDefaultPosition=!1),this.isRoot&&this.useDefaultPosition?this.position.set(this.x,e.height+this.y,-e.panelDistance+this.z):this.position.set(this.position.x+this.x,this.position.y+this.y,this.position.z+this.z)}fadeIn(e,t){"fading-in"!==this._fadeState&&(this._startFade(1,e,t),this._fadeState="fading-in")}fadeOut(e,t){"fading-out"!==this._fadeState&&(this._startFade(0,e,t),this._fadeState="fading-out")}_startFade(e,t,i){this._fadeDuration=t??.2,this.onFadeComplete=i,this._fadeTimer=0,this._startOpacity=this._currentOpacity,this._targetOpacity=e,this._fadeDuration<=0?this._completeFade():this._prepareMaterialsForFade()}_prepareMaterialsForFade(){this.traverse((t=>{if(t instanceof e.Mesh&&t.material){(Array.isArray(t.material)?t.material:[t.material]).forEach((e=>{e.transparent=!0}))}}))}_applyOpacity(t){this.traverse((i=>{if(i instanceof ki&&(i.opacity=t),i instanceof e.Mesh&&i.material){(Array.isArray(i.material)?i.material:[i.material]).forEach((i=>{i instanceof e.ShaderMaterial?i.uniforms.uOpacity.value=t:i.opacity=t}))}}))}_completeFade(){this._currentOpacity=this._targetOpacity,this._applyOpacity(this._currentOpacity),this._fadeState="idle",0===this._currentOpacity?this.hide():this.show(),this.onFadeComplete?.()}update(){if("idle"!==this._fadeState){this._fadeTimer+=this.timer.getDelta();const t=Math.min(this._fadeTimer/this._fadeDuration,1);this._currentOpacity=e.MathUtils.lerp(this._startOpacity,this._targetOpacity,t),this._applyOpacity(this._currentOpacity),t>=1&&this._completeFade()}}addGrid(){const e=new fs;return this.add(e),e}updateLayout(){super.updateLayout(),this.mesh.setAspectRatio(this.aspectRatio);const e=this.isRoot||!this.parent?1:this.parent.aspectRatio;this.mesh.setWidthHeight(this.width*Math.max(e,1),this.height*Math.max(1/e,1))}getWidth(){return this.width}getHeight(){return this.height}}class bs extends fs{constructor(e={}){void 0===e.weight&&(e.weight=.5),super(e)}}class Cs extends fs{init(){super.init(),this.position.set(-.45*this.rangeX,.7*this.rangeY,this.position.z),this.scale.set(.2,.2,1)}}class Ts extends fs{constructor(e={}){void 0===e.weight&&(e.weight=.5),super(e)}}class Rs extends Ss{constructor(e={}){e.draggable=e.draggable??!0,e.dragFacingCamera=e.dragFacingCamera??!0,super(e),this.dragFacingCamera=!0,this.draggable=e.draggable??this.draggable,this.dragFacingCamera=e.dragFacingCamera??this.dragFacingCamera,this.mesh.material.visible=!1!==e.showEdge}update(){super.update(),this._updateInteractionFeedback()}_updateInteractionFeedback(){if(this.useBorderlessShader||!this.showHighlights)return;const[e,t]=this.ux.getPrimaryTwoControllerIds(),i=null!==e&&this.ux.selected[e],s=null!==t&&this.ux.selected[t];this.mesh.material.uniforms.uSelected.value.set(i?1:0,s?1:0);const n=null!==e?this.ux.uvs[e].x:-1,r=null!==e?this.ux.uvs[e].y:-1,o=null!==t?this.ux.uvs[t].x:-1,a=null!==t?this.ux.uvs[t].y:-1;this.mesh.material.uniforms.uReticleUVs.value.set(n,r,o,a)}}fs.init(Ts,bs,Ss,Cs);class Ms extends S{constructor(){super(...arguments),this.views=[]}static{this.ComponentRegistry=new Map}static registerComponent(e,t){Ms.ComponentRegistry.has(e)&&console.warn(`UI: Component type "${e}" is being overwritten.`),Ms.ComponentRegistry.set(e,t)}compose(e){const t=this._composeNode(e);return t&&(this.add(t),t.traverse((e=>{e instanceof ki&&this.views.push(e)}))),t}_composeNode(e){const{type:t,options:i={},position:s={x:0,y:0,z:0},rotation:n={x:0,y:0,z:0},children:r=[]}=e,o=Ms.ComponentRegistry.get(t);if(!o)return console.error(`UI Error: Unknown component type "${t}". Make sure it's registered.`),null;const a=new o(i);return a.position.set(s.x,s.y,s.z),a.rotation.set(n.x,n.y,n.z),r.forEach((e=>{const t=this._composeNode(e);t&&a.add(t)})),a instanceof fs&&a.resetLayouts(),a}}Ms.registerComponent("Panel",Ss),Ms.registerComponent("Grid",fs),Ms.registerComponent("Row",Ts),Ms.registerComponent("Col",bs),Ms.registerComponent("Orbiter",Cs),Ms.registerComponent("Text",qi),Ms.registerComponent("TextView",qi),Ms.registerComponent("Label",Qi),Ms.registerComponent("LabelView",Qi),Ms.registerComponent("VideoView",Zi),Ms.registerComponent("TextButton",Ji),Ms.registerComponent("IconButton",Xi),Ms.registerComponent("IconView",Ki),Ms.registerComponent("Image",$i),Ms.registerComponent("ImageView",$i),Ms.registerComponent("SpatialPanel",Rs);class Ds extends HTMLElement{static{this.style="\n /* Styles for the wrapper that covers the screen */\n .wrapper {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: rgba(0, 0, 0, 0.1);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 9999;\n transition: visibility 0s, opacity 0.2s linear;\n }\n\n /* The spinning circle */\n .spinner {\n border: 8px solid rgba(255, 255, 255, 0.3);\n border-left-color: #ffffff;\n border-radius: 50%;\n width: 60px;\n height: 60px;\n animation: spin 1s linear infinite;\n }\n\n /* The animation is safely scoped inside the shadow DOM */\n @keyframes spin {\n to {\n transform: rotate(360deg);\n }\n }"}static{this.innerHTML=`\n <style>\n ${Ds.style}\n </style>\n <div class="wrapper">\n <div class="spinner"></div>\n </div>\n `}connectedCallback(){this.attachShadow({mode:"open"}).innerHTML=Ds.innerHTML}}customElements.define("xb-blocks-loading-spinner",Ds);class Es{constructor(){this.isLoading=!1,this.setupCallbacks()}showSpinner(){this.spinnerElement||(this.spinnerElement=document.body.appendChild(document.createElement("xb-blocks-loading-spinner")))}hideSpinner(){this.spinnerElement&&(this.spinnerElement.remove(),this.spinnerElement=void 0)}setupCallbacks(){e.DefaultLoadingManager.onStart=(e,t,i)=>{this.isLoading=!0,window.parent.postMessage({type:"XR_LOADING_PROGRESS",payload:{progress:t/i,message:"Loading assets..."}},"*")},e.DefaultLoadingManager.onProgress=(e,t,i)=>{window.parent.postMessage({type:"XR_LOADING_PROGRESS",payload:{progress:t/i,message:`Loading ${Math.round(t/i*100)}%`}},"*")},e.DefaultLoadingManager.onLoad=()=>{this.isLoading=!1,this.hideSpinner(),window.parent.postMessage({type:"XR_LOADING_COMPLETE"},"*")},e.DefaultLoadingManager.onError=e=>{this.isLoading=!1,console.warn("XRBlocks: Error loading: "+e),this.hideSpinner(),window.parent.postMessage({type:"XR_LOADING_ERROR",payload:{url:e,message:"Failed to load assets."}},"*")}}}const _s=new Es,Ps=new e.Vector3,As=new e.Vector3,Os=new e.Vector3,Is=new e.Matrix4;function Ls(e,t,i){e.position.copy(t.point),t.object.updateWorldMatrix(!0,!1);const s=Os.copy(t.normal).transformDirection(t.object.matrixWorld),n=i.getWorldPosition(Ps).sub(e.position).cross(s).cross(s).multiplyScalar(-1).normalize(),r=As.crossVectors(s,n);return Is.makeBasis(r,s,n),e.quaternion.setFromRotationMatrix(Is),e}class Vs extends e.Object3D{constructor(e,t,i,s={}){super(),this.label=e,this.image=t,this.detection2DBoundingBox=i,Object.assign(this,s)}}class Bs extends S{constructor(){super(...arguments),this._detectedObjects=new Map}static{this.dependencies={options:Tt,ai:$,aiOptions:F,deviceCamera:je,depth:Oe,camera:e.Camera}}init({options:t,ai:i,aiOptions:s,deviceCamera:n,depth:r,camera:o}){this.options=t,this.ai=i,this.aiOptions=s,this.deviceCamera=n,this.depth=r,this.camera=o,this._geminiConfig=this._buildGeminiConfig(),this.options.objects.showDebugVisualizations&&(this._debugVisualsGroup=new e.Group,this._debugVisualsGroup.raycast=()=>{},this.add(this._debugVisualsGroup))}async runDetection(){return this.clear(),"gemini"===this.options.objects.backendConfig.activeBackend?this._runGeminiDetection():(console.warn(`ObjectDetector backend '${this.options.objects.backendConfig.activeBackend}' is not supported.`),[])}async _runGeminiDetection(){if(!this.ai.isAvailable())return console.error("Gemini is unavailable for object detection."),[];const t=this.deviceCamera.getSnapshot({outputFormat:"base64"});if(!t)return console.warn("Could not get device camera snapshot."),[];const{mimeType:i,strippedBase64:s}=L(t),n=this.depth.depthArray[0].slice(0),r=this.camera.matrixWorld.clone(),o=this.aiOptions.gemini.config;this.aiOptions.gemini.config=this._geminiConfig;try{const o=await this.ai.model.query({type:"multiPart",parts:[{inlineData:{mimeType:i||void 0,data:s}},{text:"What do you see in this image?"}]});let a;try{if(!o||!o.text)return console.error("AI response is missing text field:",o,"Raw response was:",o),[];a=JSON.parse(o.text)}catch(e){return console.error("Failed to parse AI response JSON:",e,"Raw response was:",o),[]}if(!Array.isArray(a))return console.error("Parsed AI response is not an array:",a),[];this.options.objects.showDebugVisualizations&&this._visualizeBoundingBoxesOnImage(t,a);const h=a.map((async i=>{const{ymin:s,xmin:o,ymax:a,xmax:h,objectName:l,...c}=i||{};if([s,o,a,h].some((e=>"number"!=typeof e)))return null;const d=new e.Box2(new e.Vector2(o/1e3,s/1e3),new e.Vector2(h/1e3,a/1e3)),u=new e.Vector2;d.getCenter(u);const p={u:u.x,v:u.y},g=this.deviceCamera.simulatorCamera?this.camera.projectionMatrix:(new e.Matrix4).fromArray(this.depth.view[0].projectionMatrix),m=Be(p,n,g,r,this.deviceCamera,this.depth);if(m){const e=this.options.objects.objectImageMargin,i=d.clone();i.min.subScalar(e),i.max.addScalar(e);const s=await Fe(t,i),n=new Vs(l,s,d,c);return n.position.copy(m),this.add(n),this._detectedObjects.set(n.uuid,n),this._debugVisualsGroup&&this._createDebugVisual(n),n}}));return(await Promise.all(h)).filter(Boolean)}catch(e){return console.error("AI query for object detection failed:",e),[]}finally{this.aiOptions.gemini.config=o}}get(e=null){const t=Array.from(this._detectedObjects.values());return e?t.filter((t=>t.label===e)):t}clear(){for(const e of this._detectedObjects.values())this.remove(e);return this._detectedObjects.clear(),this._debugVisualsGroup&&this._debugVisualsGroup.clear(),this}showDebugVisualizations(e=!0){this._debugVisualsGroup&&(this._debugVisualsGroup.visible=e)}_visualizeBoundingBoxesOnImage(e,t){const i=new Image;i.onload=()=>{const e=document.createElement("canvas");e.width=i.naturalWidth,e.height=i.naturalHeight;const s=e.getContext("2d");s.drawImage(i,0,0),t.forEach((t=>{const{ymin:i,xmin:n,ymax:r,xmax:o,objectName:a}=t||{};if([i,n,r,o].some((e=>"number"!=typeof e)))return;const h=n/1e3*e.width,l=i/1e3*e.height,c=(o-n)/1e3*e.width,d=(r-i)/1e3*e.height;s.strokeStyle="#FF0000",s.lineWidth=Math.max(2,e.width/400),s.strokeRect(h,l,c,d);const u=a||"unknown",p=Math.max(16,e.width/80);s.font=`bold ${p}px sans-serif`,s.textBaseline="bottom";const g=s.measureText(u);s.fillStyle="rgba(0, 0, 0, 0.6)",s.fillRect(h,l-p,g.width+8,p+4),s.fillStyle="#FFFFFF",s.fillText(u,h+4,l+2)}));const n=(new Date).toISOString().slice(0,19).replace("T","_").replace(/:/g,"-"),r=document.createElement("a");r.download=`detection_debug_${n}.png`,r.href=e.toDataURL("image/png"),r.click()},i.src=e}async _createDebugVisual(t){const i=new e.Mesh(new e.SphereGeometry(.03,16,16),new e.MeshBasicMaterial({color:4282549748}));i.position.copy(t.position);const{Text:s}=await import("troika-three-text"),n=new s;n.text=t.label,n.fontSize=.07,n.color=16777215,n.anchorX="center",n.anchorY="bottom",n.position.copy(i.position),n.position.y+=.04,this._debugVisualsGroup.add(i,n),n.sync()}_buildGeminiConfig(){const e=this.options.objects.backendConfig.gemini;return{thinkingConfig:{thinkingBudget:0},responseMimeType:"application/json",responseSchema:e.responseSchema,systemInstruction:[{text:e.systemInstruction}]}}}class Fs extends e.Mesh{constructor(t,i){const s=t.polygon,n=[];for(const t of s)n.push(new e.Vector2(t.x,t.z));const r=new e.Shape(n),o=new e.ShapeGeometry(r);o.rotateX(Math.PI/2),super(o,i),this.xrPlane=t,this.label=t.semanticLabel||"unknown",this.orientation=t.orientation}}class zs extends S{constructor(){super(...arguments),this._detectedPlanes=new Map}static{this.dependencies={options:Tt,renderer:e.WebGLRenderer}}init({options:t,renderer:i}){this.renderer=i,t.planes.showDebugVisualizations&&(this._debugMaterial=new e.MeshBasicMaterial({color:16776960,wireframe:!0,side:e.DoubleSide}))}update(e,t){if(!t||!t.detectedPlanes)return;if(this._xrRefSpace=this._xrRefSpace||this.renderer.xr.getReferenceSpace()||void 0,!this._xrRefSpace)return;const i=t.detectedPlanes,s=new Set(this._detectedPlanes.keys());for(const e of i){s.delete(e);const i=this._detectedPlanes.get(e);i?e.lastChangedTime>(i.xrPlane.lastChangedTime||0)&&this._updatePlaneMesh(t,i,e):this._addPlaneMesh(t,e)}for(const e of s)this._removePlaneMesh(e)}_addPlaneMesh(t,i){const s=this._debugMaterial||new e.MeshBasicMaterial({visible:!1}),n=new Fs(i,s);this._updatePlanePose(t,n,i),this._detectedPlanes.set(i,n),this.add(n)}_updatePlaneMesh(t,i,s){const n=s.polygon.map((t=>new e.Vector2(t.x,t.z))),r=new e.Shape(n),o=new e.ShapeGeometry(r);i.geometry.dispose(),i.geometry=o,i.xrPlane=s,this._updatePlanePose(t,i,s)}_removePlaneMesh(e){const t=this._detectedPlanes.get(e);t&&(t.geometry.dispose(),this.remove(t),this._detectedPlanes.delete(e))}_updatePlanePose(e,t,i){const s=e.getPose(i.planeSpace,this._xrRefSpace);s&&(t.position.copy(s.transform.position),t.quaternion.copy(s.transform.orientation))}get(e){const t=Array.from(this._detectedPlanes.values());return e?t.filter((t=>t.label===e)):t}showDebugVisualizations(e=!0){this._debugMaterial&&(this.visible=e)}}class ks extends S{constructor(){super(...arguments),this.raycaster=new e.Raycaster}static{this.dependencies={options:Tt,camera:e.Camera}}async init({options:e,camera:t}){this.options=e,this.camera=t,this.options&&this.options.enabled&&(this.options.planes.enabled&&(this.planes=new zs,this.add(this.planes)),this.options.objects.enabled&&(this.objects=new Bs,this.add(this.objects)))}anchorObjectAtReticle(e,t){throw new Error("Method not implemented")}update(e,t){this.options}placeOnSurface(e,t){if(!this.planes)return console.warn("Cannot placeOnSurface: PlaneDetector is not enabled."),!1;const i=this.planes.get();if(0===i.length)return!1;this.raycaster.setFromXRController(t);const s=this.raycaster.intersectObjects(i);if(s.length>0){return Ls(e,s[0],this.camera),!0}return!1}showDebugVisualizations(e=!0){this.planes?.showDebugVisualizations(e),this.objects?.showDebugVisualizations(e)}}class js extends C{static{this.dependencies={renderer:e.WebGLRenderer,camera:e.Camera,timer:e.Timer,scene:e.Scene,options:Et}}constructor(){super(new e.SphereGeometry(1,64,32),new e.MeshBasicMaterial({color:16777215,transparent:!0,opacity:0,depthTest:!1,side:e.BackSide})),this.ignoreReticleRaycast=!0,this.currentMode="AR",this.transitionTime=1.5,this.targetAlpha=0,this.defaultBackgroundColor=new e.Color(16777215),this.ignoreReticleRaycast=!0,this.renderOrder=-1/0}init({renderer:e,camera:t,timer:i,scene:s,options:n}){this.renderer=e,this.sceneCamera=t,this.timer=i,this.scene=s,this.transitionTime=n.transition.transitionTime,this.defaultBackgroundColor.set(n.transition.defaultBackgroundColor),this.material.color.copy(this.defaultBackgroundColor),this.scene.add(this)}toVR({targetAlpha:t=1,color:i}={}){this.targetAlpha=e.MathUtils.clamp(t,0,1),this.material.color.set(i??this.defaultBackgroundColor),this.currentMode="VR"}toAR(){this.targetAlpha=0,this.currentMode="AR"}update(){this.renderer.xr.isPresenting?this.renderer.xr.getCamera().getWorldPosition(this.position):this.sceneCamera.getWorldPosition(this.position);const t=this.material.opacity;if(t!==this.targetAlpha){const i=this.timer.getDelta()/this.transitionTime;this.material.opacity=e.MathUtils.lerp(t,this.targetAlpha,i),Math.abs(this.material.opacity-this.targetAlpha)<.01&&(this.material.opacity=this.targetAlpha)}}dispose(){this.parent&&this.parent.remove(this),this.material.dispose(),this.geometry.dispose()}}class Us{constructor(){if(this.screenshotSynthesizer=new He,this.waitFrame=new qe,this.registry=new Ue,this.timer=new e.Timer,this.input=new ct,this.scene=new e.Scene,this.user=new is,this.ui=new Ms,this.sound=new Bi,this.renderSceneBound=this.renderScene.bind(this),this.simulator=new Si(this.renderSceneBound),this.dragManager=new gs,this.world=new ks,this.textureLoader=new e.TextureLoader,this.webXRSettings={},this.simulatorRunning=!1,this.depth=new Oe,this.ai=new $,this.scriptsManager=new We((async e=>{await wi(e,this.registry,this),this.physics&&await e.initPhysics(this.physics)})),Us.instance)return Us.instance;Us.instance=this,this.scene.name="XR Blocks Scene",this.scene.add(this.user),this.scene.add(this.dragManager),this.scene.add(this.ui),this.scene.add(this.sound),this.scene.add(this.world),this.registry.register(this.registry),this.registry.register(this.waitFrame),this.registry.register(this.scene),this.registry.register(this.timer),this.registry.register(this.input),this.registry.register(this.user),this.registry.register(this.ui),this.registry.register(this.sound),this.registry.register(this.dragManager),this.registry.register(this.user),this.registry.register(this.simulator),this.registry.register(this.scriptsManager),this.registry.register(this.depth)}async init(t=new Et){if(_s.showSpinner(),this.registry.register(t,Et),this.registry.register(t.depth,xe),this.registry.register(t.simulator,yt),this.registry.register(t.world,Tt),this.registry.register(t.ai,F),this.registry.register(t.sound,St),t.transition.enabled&&(this.transition=new js,this.user.add(this.transition),this.registry.register(this.transition)),this.camera=new e.PerspectiveCamera(90,window.innerWidth/window.innerHeight,t.camera.near,t.camera.far),this.registry.register(this.camera,e.Camera),this.registry.register(this.camera,e.PerspectiveCamera),this.renderer=new e.WebGLRenderer({canvas:t.canvas,antialias:t.antialias,stencil:t.stencil,alpha:!0,logarithmicDepthBuffer:t.logarithmicDepthBuffer}),this.renderer.setPixelRatio(window.devicePixelRatio),this.renderer.setSize(window.innerWidth,window.innerHeight),this.renderer.xr.enabled=!0,this.renderer.xr.getDepthSensingMesh=function(){return null},this.registry.register(this.renderer),this.renderer.xr.setReferenceSpaceType(t.referenceSpaceType),!t.canvas){const e=document.createElement("div");document.body.appendChild(e),e.appendChild(this.renderer.domElement)}this.options=t,t.controllers.enabled&&(this.input.init({scene:this.scene,options:t,renderer:this.renderer}),this.input.bindSelectStart(this.scriptsManager.callSelectStartBound),this.input.bindSelectEnd(this.scriptsManager.callSelectEndBound),this.input.bindSelect(this.scriptsManager.callSelectBound),this.input.bindSqueezeStart(this.scriptsManager.callSqueezeStartBound),this.input.bindSqueezeEnd(this.scriptsManager.callSqueezeEndBound),this.input.bindSqueeze(this.scriptsManager.callSqueezeBound),this.input.bindKeyDown(this.scriptsManager.callKeyDownBound),this.input.bindKeyUp(this.scriptsManager.callKeyUpBound)),t.deviceCamera?.enabled&&(this.deviceCamera=new je(t.deviceCamera),this.registry.register(this.deviceCamera));const i=t.webxrRequiredFeatures;this.webXRSettings.requiredFeatures=i,t.depth.enabled&&(i.push("depth-sensing"),i.push("local-floor"),this.webXRSettings.depthSensing={usagePreference:[],dataFormatPreference:[this.options.depth.useFloat32?"float32":"luminance-alpha"]},this.depth.init(this.camera,t.depth,this.renderer,this.registry,this.scene)),t.hands.enabled&&(i.push("hand-tracking"),this.user.hands=new tt(this.input.hands)),t.world.planes.enabled&&i.push("plane-detection"),t.lighting.enabled&&(i.push("light-estimation"),this.lighting=new dt,this.lighting.init(t.lighting,this.renderer,this.scene,this.depth)),t.physics&&t.physics.RAPIER&&(this.physics=new ut,this.registry.register(this.physics),await this.physics.init({physicsOptions:t.physics}),t.depth.enabled&&this.depth.depthMesh?.initRapierPhysics(this.physics.RAPIER,this.physics.blendedWorld)),this.webXRSessionManager=new Ke(this.renderer,this.webXRSettings,"immersive-ar"),this.webXRSessionManager.addEventListener(Xe.SESSION_START,(e=>this.onXRSessionStarted(e.session))),this.webXRSessionManager.addEventListener(Xe.SESSION_END,this.onXRSessionEnded.bind(this));const s=this.options.xrButton.autostartSimulator||this.options.xrButton.autostartSimulatorOnDesktop&&this.options.xrButton.enableSimulator&&fe();!s&&t.xrButton.enabled&&(this.xrButton=new Qe(this.webXRSessionManager,t.xrButton?.startText,t.xrButton?.endText,t.xrButton?.invalidText,t.xrButton?.startSimulatorText,t.xrButton?.enableSimulator,t.xrButton?.showSimulatorButtonOnMobile,this.startSimulator.bind(this)),document.body.appendChild(this.xrButton.domElement)),await this.webXRSessionManager.initialize(),t.usePostprocessing&&(this.effects=new Je(this.renderer,this.scene,this.timer),this.simulator.effects=this.effects),t.ai.enabled&&(this.registry.register(this.ai),this.scene.add(this.ai),await this.scriptsManager.initScript(this.ai)),await this.scriptsManager.syncScriptsWithScene(this.scene),window.addEventListener("resize",this.onWindowResize.bind(this)),this.renderer.setAnimationLoop(this.update.bind(this)),this.physics&&setInterval(this.physicsStep.bind(this),1e3*this.physics.timestep),this.options.reticles.enabled&&this.input.addReticles(),s&&this.startSimulator(),_s.isLoading||_s.hideSpinner()}update(e,t){this.currentFrame=t,this.timer.update(e),this.simulatorRunning&&this.simulator.simulatorUpdate(),this.depth.update(t),this.lighting&&this.lighting.update(),this.scriptsManager.syncScriptsWithScene(this.scene);for(const e of this.scriptsManager.scripts)e.ux.reset();this.input.update();for(const e of this.input.controllers)if(e.userData.selected)for(const t of this.scriptsManager.scripts)t.onSelecting({target:e});for(const e of this.input.controllers)if(e.userData.squeezing)for(const t of this.scriptsManager.scripts)t.onSqueezing({target:e});this.waitFrame.onFrame();for(const i of this.scriptsManager.scripts)i.update(e,t);this.renderSimulatorAndScene(),this.screenshotSynthesizer.onAfterRender(this.renderer,this.renderSceneBound,this.deviceCamera),this.simulatorRunning&&this.simulator.renderSimulatorScene()}physicsStep(){this.physics.physicsStep();for(const e of this.scriptsManager.scripts)e.physicsStep()}async onXRSessionStarted(e){this.options.deviceCamera?.enabled&&await this.deviceCamera.init(),this.scriptsManager.onXRSessionStarted(e)}async startSimulator(){this.xrButton?.domElement.remove(),this.scene.add(this.simulator),await this.scriptsManager.initScript(this.simulator),this.onSimulatorStarted()}onXRSessionEnded(){this.startSimulator(),this.scriptsManager.onXRSessionEnded()}onSimulatorStarted(){this.simulatorRunning=!0,this.scriptsManager.onSimulatorStarted(),this.lighting&&(this.lighting.simulatorRunning=!0)}onWindowResize(){this.camera.aspect=window.innerWidth/window.innerHeight,this.camera.updateProjectionMatrix(),this.renderer.setSize(window.innerWidth,window.innerHeight)}renderSimulatorAndScene(){this.simulatorRunning?this.simulator.renderScene():this.renderScene()}renderScene(e){if(this.renderSceneOverride)this.renderSceneOverride(this.renderer,this.scene,e??this.camera);else if(this.effects)this.effects.render();else if(this.renderer.render(this.scene,e??this.camera),ts(this.scene,(e=>e.layers.isEnabled(4)))){const e=this.camera.layers.mask;this.camera.layers.set(4),this.renderer.render(this.scene,this.camera),this.camera.layers.mask=e}}}class Ns{static createOcclusionMapOverrideMaterial(){return new e.MeshBasicMaterial}static addOcclusionToShader(t){t.uniforms.occlusionEnabled={value:!0},t.uniforms.tOcclusionMap={value:null},t.uniforms.uOcclusionClipFromWorld={value:new e.Matrix4},t.defines={USE_UV:!0,DISTANCE:!0},t.vertexShader=t.vertexShader.replace("#include <common>",["uniform mat4 uOcclusionClipFromWorld;","varying vec4 vOcclusionScreenCoord;","#include <common>"].join("\n")).replace("#include <fog_vertex>",["#include <fog_vertex>","vOcclusionScreenCoord = uOcclusionClipFromWorld * worldPosition;"].join("\n")),t.fragmentShader=t.fragmentShader.replace("uniform vec3 diffuse;",["uniform vec3 diffuse;","uniform bool occlusionEnabled;","uniform sampler2D tOcclusionMap;","varying vec4 vOcclusionScreenCoord;"].join("\n")).replace("vec4 diffuseColor = vec4( diffuse, opacity );",["vec4 diffuseColor = vec4( diffuse, opacity );","vec2 occlusion_coordinates = 0.5 + 0.5 * vOcclusionScreenCoord.xy / vOcclusionScreenCoord.w;","vec2 occlusion_sample = texture2D(tOcclusionMap, occlusion_coordinates.xy).rg;","occlusion_sample = occlusion_sample / max(0.0001, occlusion_sample.g);","float occlusion_value = clamp(occlusion_sample.r, 0.0, 1.0);","diffuseColor.a *= occlusionEnabled ? occlusion_value : 1.0;"].join("\n"))}}const Gs=new e.Euler,Hs=new e.Matrix4,Ws=new e.Vector3;function qs(t,i=new e.Quaternion){return Gs.setFromQuaternion(t,"YXZ"),i.setFromAxisAngle(ns,Gs.y)}function Xs(t,i=ns,s=new e.Quaternion){return Hs.lookAt(ls,t,i),s.setFromRotationMatrix(Hs)}function Ks(e,t){let i=2*Math.acos(e.w);if(i=(i+Math.PI)%(2*Math.PI)-Math.PI,Math.abs(i)<=t)return;const s=Ws.set(e.x,e.y,e.z).multiplyScalar(1/Math.sqrt(1-e.w*e.w));s.normalize(),e.setFromAxisAngle(s,t*Math.sign(i))}class $s{static{this.dependencies={}}async init(e={}){}async play(e={}){}}const Qs=3*Math.PI/180,Ys=new e.Vector3,Js=new e.Vector3,Zs=new e.Vector3,en=new e.Quaternion,tn=new e.Quaternion,sn=new e.Quaternion;class nn extends $s{static{this.dependencies={simulator:Si,camera:e.Camera,timer:e.Timer,input:ct}}constructor(e){super(),this.target=e}async init({simulator:e,camera:t,timer:i,input:s}){this.simulator=e,this.camera=t,this.timer=i,this.input=s}controllerIsPointingAtButton(e,t){const i=e.simulatorControllerState,s=i.currentControllerIndex,n=i.localControllerPositions[s],r=i.localControllerOrientations[s];this.target.getWorldPosition(Js),Zs.copy(Js).applyMatrix4(t.matrixWorldInverse),en.copy(r).invert(),Ys.copy(Zs).sub(n),Xs(Ys,ns,tn);return(tn.angleTo(r)+Math.PI)%(2*Math.PI)-Math.PI<Qs}rotateControllerTowardsButton(e,t,i){const s=e.simulatorControllerState,n=s.currentControllerIndex,r=s.localControllerPositions[n],o=s.localControllerOrientations[n];this.target.getWorldPosition(Js),Zs.copy(Js).applyMatrix4(t.matrixWorldInverse),en.copy(o).invert(),Ys.copy(Zs).sub(r),Xs(Ys,ns,tn),sn.copy(tn).multiply(en),Ks(sn,1*i),o.premultiply(sn)}pinchController(){const e=this.simulator,t=e.controls.simulatorControllerState,i=!0;this.input.dispatchEvent({type:"selectstart",target:this.input.controllers[t.currentControllerIndex]}),0==t.currentControllerIndex?e.hands.setLeftHandPinching(i):e.hands.setRightHandPinching(i)}async play({simulatorUser:e,journeyId:t,waitFrame:i}){let s=!1;for(;e.isOnJourneyId(t)&&!s;){const e=this.timer.getDelta();this.controllerIsPointingAtButton(this.simulator.controls,this.camera)?(this.pinchController(),s=!0):this.rotateControllerTowardsButton(this.simulator.controls,this.camera,e),await i.waitFrame()}}}class rn extends $s{static{this.dependencies={simulator:Si}}async init({simulator:e}){this.simulator=e}async play(){this.simulator.hands&&this.simulator.hands.showHands()}}const on=3*Math.PI/180,an=new e.Vector3,hn=new e.Vector3,ln=new e.Vector3,cn=new e.Quaternion,dn=new e.Quaternion,un=new e.Quaternion;class pn extends $s{static{this.dependencies={camera:e.Camera,timer:e.Timer}}constructor(e){super(),this.target=e}async init({camera:e,timer:t}){this.camera=e,this.timer=t}isLookingAtTarget(){const e=this.camera;this.target.getWorldPosition(an),hn.copy(an).sub(e.position),Xs(hn,ns,dn);return(dn.angleTo(e.quaternion)+Math.PI)%(2*Math.PI)-Math.PI<on}isNearTarget(){const e=this.camera;return this.target.getWorldPosition(an),hn.copy(an).sub(e.position),Math.abs(hn.length()-.5)<.1}lookAtTarget(){const e=this.camera;un.copy(e.quaternion).invert(),this.target.getWorldPosition(an),hn.copy(an).sub(e.position),Xs(hn,ns,dn),e.quaternion.copy(dn)}lookTowardsTarget(){const e=this.camera;un.copy(e.quaternion).invert();const t=this.timer.getDelta();this.target.getWorldPosition(an),hn.copy(an).sub(e.position),Xs(hn,ns,dn),cn.copy(dn).multiply(un),Ks(cn,1*t),e.quaternion.premultiply(cn)}moveTowardsTarget(){const e=this.camera,t=this.timer.getDelta();this.target.getWorldPosition(an),hn.copy(an).sub(e.position),ln.copy(an).addScaledVector(hn,-.1);const i=ln.sub(e.position),s=T(i.length(),0,1*t);e.position.addScaledVector(i,s/i.length())}async play({simulatorUser:e,journeyId:t,waitFrame:i}){let s=this.isLookingAtTarget(),n=this.isNearTarget(),r=e.isOnJourneyId(t);for(;r&&(!s||!n);)s?(this.lookAtTarget(),this.moveTowardsTarget()):this.lookTowardsTarget(),await i.waitFrame(),s=this.isLookingAtTarget(),n=this.isNearTarget(),r=e.isOnJourneyId(t)}}const gn=new Us,mn=gn.scene,fn=gn.user,vn=gn.world,yn=gn.ai;function wn(...e){return mn.add(...e)}function xn(e=new Et){return gn.init(e)}function Sn(e){return gn.scriptsManager.initScript(e)}function bn(e){return gn.scriptsManager.uninitScript(e)}function Cn(){return gn.timer.getDelta()}function Tn(e){gn.depth.depthMesh&&(gn.depth.depthMesh.ignoreReticleRaycast=!e)}function Rn(){return gn.renderer.xr.getCamera().cameras[0]}function Mn(){return gn.renderer.xr.getCamera().cameras[1]}function Dn(e){return e.layers.set(1),e.children.forEach((e=>{Dn(e)})),e}function En(e){return e.layers.set(2),e.children.forEach((e=>{En(e)})),e}async function _n(t){const i=await new Promise(((i,s)=>{(new e.ImageLoader).load(t,i,void 0,s)})),s=new e.Texture;s.image=i,s.repeat.x=.5,s.needsUpdate=!0;const n=s.clone();return n.offset.x=.5,n.needsUpdate=!0,[s,n]}class Pn extends ki{#e;get icon(){return this.#e}set icon(e){this.#e!=e&&(this.#e=e,this.updateIcon())}#t;get iconWeight(){return this.#t}set iconWeight(e){this.#t!=e&&(this.#t=e,this.updateIcon())}#i;get iconStyle(){return this.#i}set iconStyle(e){this.#i!=e&&(this.#i=e,this.updateIcon())}#s;get iconColor(){return this.#s}set iconColor(t){this.#s!=t&&(this.#s=t,this.group?.traverse?.((i=>{i instanceof e.Mesh&&i.material?.color?.set?.(t)})))}constructor({icon:e="sunny",iconWeight:t=400,iconStyle:i="outlined",iconScale:s=1,iconColor:n="#FFFFFF"}){super({}),this.#e="",this.#t=400,this.#i="",this.#s="",this.iconScale=1,this.icon=e,this.iconWeight=t,this.iconStyle=i,this.iconScale=s,this.iconColor=n}async init(){null==this.group&&await this.updateIcon()}async updateIcon(){if(!this.icon||!this.iconWeight||!this.iconStyle)return;const t="https://cdn.jsdelivr.net/gh/marella/material-symbols@v0.33.0/svg/{{weight}}/{{style}}/{{icon}}.svg".replace("{{style}}",this.iconStyle).replace("{{icon}}",this.icon).replace("{{weight}}",String(this.iconWeight));if(t==this.loadedSvgPath||t==this.loadingSvgPath)return;this.loadingSvgPath=t;const i=await new Promise(((e,i)=>{(new a).load(t,e,void 0,i)}));this.loadingSvgPath=void 0,this.loadedSvgPath=t;const[s,n,r,o]=i.xml.attributes.viewBox.value.split(" "),h=i.paths,l=new e.Group,c=1/Math.max(r,o),d=new e.MeshBasicMaterial({color:this.iconColor,transparent:!0,side:e.DoubleSide,depthWrite:!1});for(let t=0;t<h.length;t++){const i=h[t],r=a.createShapes(i);for(let t=0;t<r.length;t++){const i=r[t],o=new e.ShapeGeometry(i),a=new e.Mesh(o,d);a.scale.set(c,-c,c),a.position.x=-.5-s*c,a.position.y=.5+n*c,l.add(a)}}this.group&&(this.remove(this.group),this.group?.traverse?.((t=>{"dispose"in t&&"function"==typeof t.dispose&&t.dispose?.(),t instanceof e.Mesh&&(t.geometry?.dispose?.(),t.material?.dispose?.())}))),this.group=l,l.scale.setScalar(this.iconScale),this.add(l)}}class An extends S{constructor(){super(...arguments),this.scrollSpeedLinesPerSecond=3,this.lines=1,this.currentLine=0,this.targetLine=0,this.shouldUpdate=!0,this.lineCount=0}static{this.dependencies={timer:e.Timer}}init({timer:e}){this.timer=e}update(){if(super.update(),!this.shouldUpdate)return!1;const e=this.timer.getDelta(),t=this.scrollSpeedLinesPerSecond*e,i=this.targetLine-this.currentLine;this.currentLine+=T(i,-t,t)}}const On=new e.Vector3;class In extends ki{constructor(e={}){super(e)}updateLayout(){On.copy(this.position),super.updateLayout(),this.position.copy(On)}}class Ln extends S{static{this.dependencies={timer:e.Timer}}constructor({pages:e=1}){super(),this.currentPage=0,this.shouldUpdate=!0,this.pages=1,this.pages=e}init({timer:e}){this.timer=e}update(){if(super.update(),!this.shouldUpdate)return!1;const e=Math.sin(Math.PI*(this.currentPage%1)),t=(this.currentPage%1>=.5?1:-1)*Number(Math.abs(e)>.01),i=T(this.currentPage+t,0,this.pages-1),s=Math.abs(i-this.currentPage);this.currentPage+=t*T(e*this.timer.getDelta(),0,s)}addPage(){return this.pages++}}const Vn=new e.Vector3,Bn=new e.Matrix4;class Fn extends ki{static{this.dependencies={renderer:e.WebGLRenderer,input:ct}}constructor(t={}){super(t),this.localClippingPlanes=[new e.Plane(new e.Vector3(1,0,0),.5),new e.Plane(new e.Vector3(-1,0,0),.5)],this.raycastMesh=new e.Mesh(new e.PlaneGeometry,new e.MeshBasicMaterial({visible:!1})),this.clippingPlanes=[],this.selecting=!1,this.selectStartPositionLocal=new e.Vector3,this.selectStartPage=0,this.raycastPlane=new e.Plane,this.selectingRay=new e.Ray,this.selectingRayTarget=new e.Vector3;const{state:i=new Ln({pages:1}),enableRaycastOnChildren:s=!0,continuousScrolling:n=!0}=t;this.state=i,this.enableRaycastOnChildren=s,this.continuousScrolling=n;for(let e=0;e<this.state.pages;e++)this.add(new In);for(let e=0;e<this.localClippingPlanes.length;e++)this.clippingPlanes.push(this.localClippingPlanes[e].clone())}init({renderer:e,input:t}){e.localClippingEnabled=!0,this.input=t}updatePageCount(){this.remove(this.raycastMesh);for(let e=this.children.length;e<this.state.pages;e++)this.add(new In);for(let e=this.state.pages;e<this.children.length;)this.children[e].dispose?.(),this.remove(this.children[e]);this.add(this.raycastMesh)}updatePagePositions(){const e=Math.floor(this.state.pages/2);for(let t=0;t<this.state.pages;t++){const i=this.continuousScrolling&&this.state.pages>1?(t-this.state.currentPage+e+this.state.pages)%this.state.pages-e:t-this.state.currentPage;this.children[t].position.x=i*this.rangeX}}resetClippingPlanesToLocalSpace(){for(let e=0;e<this.localClippingPlanes.length&&e<this.clippingPlanes.length;e++)this.clippingPlanes[e].copy(this.localClippingPlanes[e])}updateClippingPlanes(){this.resetClippingPlanesToLocalSpace(),this.updateWorldMatrix(!0,!1);for(const e of this.clippingPlanes)e.applyMatrix4(this.matrixWorld);this.traverse((t=>{t instanceof e.Mesh&&(t.material.clippingPlanes=this.clippingPlanes)}))}update(){this.updatePageCount(),this.updatePagePositions(),this.updateClippingPlanes()}updateLayout(){super.updateLayout(),this.raycastMesh.scale.set(this.rangeX,this.rangeY,1)}onObjectSelectStart(e){const t=e.target,i=this.input.intersectionsForController.get(t),s=i.findIndex((e=>e.object==this));if(-1==s)return!1;const n=i[s];return this.selecting=!0,this.selectingController=t,this.updateMatrixWorld(),this.selectStartPositionLocal.copy(n.point).applyMatrix4(Bn.copy(this.matrixWorld).invert()),this.raycastPlane.normal.set(0,0,1),this.raycastPlane.constant=0,this.raycastPlane.applyMatrix4(this.matrixWorld),this.selectStartPage=this.state.currentPage,!0}computeSelectingDelta(e,t){return(e.x-t.x)/this.rangeX}onSelecting(){if(this.selecting){this.selectingRay.origin.set(0,0,0),this.selectingRay.direction.set(0,0,-1),this.selectingController.updateMatrixWorld(),this.selectingRay.applyMatrix4(this.selectingController.matrixWorld),this.selectingRay.intersectPlane(this.raycastPlane,this.selectingRayTarget),this.updateMatrixWorld(),this.selectingRayTarget.applyMatrix4(Bn.copy(this.matrixWorld).invert());const e=this.computeSelectingDelta(this.selectingRayTarget,this.selectStartPositionLocal);this.state.currentPage=this.continuousScrolling&&this.state.pages>1?(this.selectStartPage-e+this.state.pages)%this.state.pages:T(this.selectStartPage-e,0,this.state.pages-1)}}onObjectSelectEnd(e){return e.target==this.selectingController&&(this.selecting=!1),!0}raycast(e,t){const i=[];if(this.raycastMesh.raycast(e,i),i.forEach((e=>{e.object=this,t.push(e)})),this.enableRaycastOnChildren){const i=[];for(const t of this.children)e.intersectObject(t,!0,i);this.updateMatrixWorld(),Bn.copy(this.matrixWorld).invert();for(const e of i){const i=Vn.copy(e.point).applyMatrix4(Bn);Math.abs(i.x)<.5&&t.push(e)}}return!1}}class zn extends Fn{constructor(){super(...arguments),this.localClippingPlanes=[new e.Plane(new e.Vector3(0,1,0),.5),new e.Plane(new e.Vector3(0,-1,0),.5)]}updateLayout(){super.updateLayout(),this.localClippingPlanes[0].constant=.5*this.rangeY,this.localClippingPlanes[1].constant=.5*this.rangeY}computeSelectingDelta(e,t){return(e.y-t.y)/this.rangeY}}class kn extends ki{constructor({text:e="ScrollingTroikaTextView",textAlign:t="left",scrollerState:i=new An,fontSize:s=.06}={}){super(),this.onTextSyncCompleteBound=this.onTextSyncComplete.bind(this),this.currentText="",this.scrollerState=i||new An,this.pager=new zn,this.textViewWrapper=new ki,this.pager.children[0].add(this.textViewWrapper),this.textView=new qi({text:e,textAlign:t,fontSize:s,anchorX:0,anchorY:0}),this.textView.x=-.5,this.textView.addEventListener("synccomplete",this.onTextSyncCompleteBound),this.textViewWrapper.add(this.textView),this.add(this.scrollerState),this.add(this.pager)}update(){this.textViewWrapper.y=this.textView.lineHeight*this.textView.aspectRatio*this.scrollerState.currentLine,this.textViewWrapper.updateLayout()}addText(e){this.setText(this.currentText+e)}setText(e){this.currentText=e,this.textView.setText(this.currentText)}onTextSyncComplete(){this.textView.lineCount>0&&(this.textView.y=this.textView.lineHeight*this.textView.aspectRatio-.5,this.textView.updateLayout(),this.scrollerState.lineCount=this.textView.lineCount,this.scrollerState.targetLine=this.textView.lineCount-1,this.clipToLineHeight())}clipToLineHeight(){const e=this.textView.lineHeight*this.textView.aspectRatio,t=Math.floor(1/e)*e;this.pager.localClippingPlanes[1].constant=t-.5}}const jn=new e.Vector3,Un=new e.Quaternion,Nn=new e.Euler;class Gn{constructor(t=0,i=0,s=1,n=1,r){this.startingValue=t,this.minValue=i,this.maxValue=s,this.scale=n,this.initialPosition=new e.Vector3,this.initialRotationInverse=new e.Quaternion,this.rotationScale=null!=r?r:-this.scale}setInitialPose(e,t){this.initialPosition.copy(e),this.initialRotationInverse.copy(t).invert()}setInitialPoseFromController(e){this.setInitialPose(e.position,e.quaternion)}getValue(e){return jn.copy(e).sub(this.initialPosition).applyQuaternion(this.initialRotationInverse),T(this.startingValue+this.scale*jn.x,this.minValue,this.maxValue)}getValueFromRotation(e){return Un.copy(e).multiply(this.initialRotationInverse),Nn.setFromQuaternion(Un,"YXZ"),T(this.startingValue+this.rotationScale*Nn.y,this.minValue,this.maxValue)}getValueFromController(e){return e instanceof at?this.getValueFromRotation(e.quaternion):this.getValue(e.position)}updateValue(e){this.startingValue=e}}const Hn=`https://cdn.jsdelivr.net/npm/three@0.${e.REVISION}.0/examples/jsm/`;let Wn;class qn{constructor(t=e.DefaultLoadingManager){this.manager=t}async load({path:e,url:t="",renderer:i,onProgress:s}){s&&console.warn("ModelLoader: An onProgress callback was provided to load(), but a LoadingManager is in use. Progress will be reported via the LoadingManager's onProgress callback. The provided callback will be ignored.");const n=t.split(".").pop()?.toLowerCase()||"";return["gltf","glb"].includes(n)?await this.loadGLTF({path:e,url:t,renderer:i}):["ply","spz","splat","ksplat"].includes(n)?await this.loadSplat({url:t}):(console.error("Unsupported file type: "+n),null)}async loadSplat({url:e=""}){const{SplatMesh:t}=await import("@sparkjsdev/spark"),i=new t({url:e});return await i.initialized,i}async loadGLTF({path:e,url:t="",renderer:i}){const s=function(e,t){if(Wn)return Wn;const i=new h(t);i.setDecoderPath(Hn+"libs/draco/"),i.setDecoderConfig({type:"js"});const s=new l(t);return s.setTranscoderPath(Hn+"libs/basis/"),e&&s.detectSupport(e),Wn=new o(t),Wn.setDRACOLoader(i),Wn.setKTX2Loader(s),Wn}(i,this.manager);return e&&s.setPath(e),new Promise(((e,i)=>{s.load(t,(t=>e(t)),void 0,(e=>i(e)))}))}}class Xn extends e.BufferGeometry{constructor(t=1,i=.4,s=12,n=48){super();const r=[],o=[],a=[],h=[],l=new e.Vector3,c=new e.Vector3,d=new e.Vector3;for(let e=0;e<=s;e++)for(let r=0;r<=n;r++){const u=r/n*Math.PI/2,p=e/s*Math.PI+3*Math.PI/2;c.x=(t+i*Math.cos(p))*Math.cos(u),c.y=(t+i*Math.cos(p))*Math.sin(u),c.z=i*Math.sin(p),o.push(c.x,c.y,c.z),l.x=t*Math.cos(u),l.y=t*Math.sin(u),d.subVectors(c,l).normalize(),a.push(d.x,d.y,d.z),h.push(r/n),h.push(e/s)}for(let e=1;e<=s;e++)for(let t=1;t<=n;t++){const i=(n+1)*e+t-1,s=(n+1)*(e-1)+t-1,o=(n+1)*(e-1)+t,a=(n+1)*e+t;r.push(i,s,a),r.push(s,o,a)}this.setIndex(r),this.setAttribute("position",new e.Float32BufferAttribute(o,3)),this.setAttribute("normal",new e.Float32BufferAttribute(a,3)),this.setAttribute("uv",new e.Float32BufferAttribute(h,2))}}function Kn(t=1,i=1,s=.02,n=.03,r=5,o=5){const a=function(t=1,i=1,s=.01,n=.03,r=5,o=5){const a=new Xn(n,s/2,o,r).rotateX(Math.PI/2),h=a.clone().rotateY(2*Math.PI/2).translate(-(t/2-n),0,-(i/2-n)),l=a.clone().rotateY(3*Math.PI/2).translate(-(t/2-n),0,i/2-n),c=a.clone().rotateY(4*Math.PI/2).translate(t/2-n,0,i/2-n),d=a.rotateY(5*Math.PI/2).translate(t/2-n,0,-(i/2-n)),u=[h,l,c,d],p=new e.CylinderGeometry(s/2,s/2,t-2*n,o,1,!0,0,Math.PI).rotateZ(Math.PI/2),g=p.clone().rotateX(-Math.PI/2).translate(0,0,-i/2),m=p.rotateX(Math.PI/2).translate(0,0,i/2),f=new e.CylinderGeometry(s/2,s/2,i-2*n,o,1,!0,0,Math.PI).rotateX(-Math.PI/2),v=f.clone().rotateY(Math.PI).translate(-t/2,0,0),y=f.translate(t/2,0,0);return[...u,g,m,v,y]}(t,i,s,n,r,o),h=a.reduce(((e,t)=>e+t.index.count),0),l=function(t=1,i=1,s=.01,n=.03,r=5){const o=t-2*n,a=i-2*n,h=new e.PlaneGeometry(t,a).rotateX(-Math.PI/2),l=new e.PlaneGeometry(o,n).rotateX(-Math.PI/2),c=a/2+n/2,d=l.clone().translate(0,0,c),u=l.translate(0,0,-c),p=[h,d,u],g=new e.CircleGeometry(n,r,0,Math.PI/2).rotateX(-Math.PI/2),m=a/2,f=o/2,v=g.clone().rotateY(3*Math.PI/2).translate(f,0,m),y=g.clone().rotateY(0*Math.PI/2).translate(f,0,-m),w=g.clone().rotateY(1*Math.PI/2).translate(-f,0,-m),x=g.clone().rotateY(2*Math.PI/2).translate(-f,0,m),S=[...p,v,y,w,x],b=S.map((e=>e.clone().rotateX(Math.PI).translate(0,-s/2,0)));return S.forEach((e=>e.translate(0,s/2,0))),[...S,...b]}(t,i,s,n,r),d=l.reduce(((e,t)=>e+t.index.count),0),u=[...a,...l],p=c.mergeGeometries(u);return u.forEach((e=>e.dispose())),p.addGroup(0,h,0),p.addGroup(h,d,1),p.computeBoundingBox(),p}class $n extends e.Mesh{constructor(t,i,s){super(Kn(t,i,s),[new e.MeshLambertMaterial({color:16777215,transparent:!0,opacity:0}),new e.MeshLambertMaterial({color:16777215,transparent:!0,opacity:0})]),this.draggingMode=gs.TRANSLATING,this.opacity=new rt(0,0,.5,0)}update(e){this.opacity.update(e),this.material[0].opacity=this.opacity.value,this.material[1].opacity=.5*this.opacity.value,this.visible=this.opacity.value>.001}}const Qn=new e.Vector2(.2,.2),Yn=new e.Vector3,Jn=new e.Quaternion,Zn=new e.Quaternion;class er extends e.Object3D{constructor(){super(...arguments),this.draggingMode=ps.ROTATING}}class tr extends e.Mesh{constructor(e,t){super(e,t),this.draggingMode=ps.ROTATING}}class ir extends S{static{this.dependencies={camera:e.Camera,depth:Oe,scene:e.Scene,renderer:e.WebGLRenderer}}constructor({castShadow:t=!0,receiveShadow:i=!0,raycastToChildren:s=!1}){super(),this.draggable=!0,this.rotatable=!0,this.scalable=!0,this.platformAnimationSpeed=2,this.platformThickness=.02,this.isOneOneScale=!1,this.initialScale=(new e.Vector3).setScalar(1),this.startAnimationOnLoad=!0,this.clipActions=[],this.clock=new e.Clock,this.hoveringControllers=new Set,this.occludableShaders=new Set,this.bbox=new e.Box3,this.castShadow=t,this.receiveShadow=i,this.raycastToChildren=s}async init({camera:e,depth:t,scene:i,renderer:s}){this.camera=e,this.depth=t,this.scene=i,this.renderer=s;for(const e of this.occludableShaders)this.depth.occludableShaders.add(e);this.splatMesh&&(await this.createSparkRendererIfNeeded(),this.scene.add(this.splatMesh))}async loadSplatModel({data:t,onSceneLoaded:i=e=>{},platformMargin:s=Qn,setupRaycastCylinder:n=!0,setupRaycastBox:r=!1,setupPlatform:o=!0}){this.data=t,t.scale&&this.initialScale.copy(t.scale);const a=await(new qn).loadSplat({url:t.model});return this.splatMesh=a,a.raycast=()=>{},this.splatAnchor=new er,t.scale&&this.splatAnchor.scale.copy(t.scale),t.rotation&&this.splatAnchor.rotation.set(e.MathUtils.degToRad(t.rotation.x),e.MathUtils.degToRad(t.rotation.y),e.MathUtils.degToRad(t.rotation.z)),t.position&&this.splatAnchor.position.copy(t.position),this.add(this.splatAnchor),this.scene&&(await this.createSparkRendererIfNeeded(),this.scene.add(this.splatMesh)),await this.setupBoundingBox(!1!==t.verticallyAlignObject,!1!==t.horizontallyAlignObject),n?this.setupRaycastCylinder():r&&this.setupRaycastBox(),o&&this.setupPlatform(s),this.setCastShadow(this.castShadow),this.setReceiveShadow(this.receiveShadow),i?i(this.splatAnchor):this.splatAnchor}async loadGLTFModel({data:t,onSceneLoaded:i=()=>{},platformMargin:s=Qn,setupRaycastCylinder:n=!0,setupRaycastBox:r=!1,setupPlatform:o=!0,renderer:a,addOcclusionToShader:h=!1}){this.data=t,t.scale&&this.initialScale.copy(t.scale);const l=await(new qn).loadGLTF({path:t.path,url:t.model,renderer:a}),c=new e.AnimationMixer(l.scene);if(l.animations.forEach((e=>{this.startAnimationOnLoad?c.clipAction(e).play():this.clipActions.push(c.clipAction(e))})),l.scene.draggingMode=gs.ROTATING,this.gltfMesh=l,this.animationMixer=c,t.scale&&this.gltfMesh.scene.scale.copy(t.scale),t.rotation&&l.scene.rotation.set(e.MathUtils.degToRad(t.rotation.x),e.MathUtils.degToRad(t.rotation.y),e.MathUtils.degToRad(t.rotation.z)),t.position&&l.scene.position.copy(t.position),l.scene.draggingMode=gs.ROTATING,this.add(l.scene),await this.setupBoundingBox(!1!==t.verticallyAlignObject,!1!==t.horizontallyAlignObject),n?this.setupRaycastCylinder():r&&this.setupRaycastBox(),o&&this.setupPlatform(s),this.setCastShadow(this.castShadow),this.setReceiveShadow(this.receiveShadow),h){for(const e of this.platform?.material||[])e.onBeforeCompile=t=>{Ns.addOcclusionToShader(t),t.uniforms.occlusionEnabled.value=!0,e.userData.shader=t,this.occludableShaders.add(t),this.depth?.occludableShaders.add(t)};this.platform?.layers.enable(3),l.scene.traverse((e=>{if(e.isMesh){const t=e;(t.material instanceof Array?t.material:[t.material]).forEach((e=>{e.transparent=!0,e.onBeforeCompile=e=>{Ns.addOcclusionToShader(e),e.uniforms.occlusionEnabled.value=!0,this.occludableShaders.add(e),this.depth?.occludableShaders.add(e)}})),e.layers.enable(3)}}))}return i?i(l.scene):l.scene}async setupBoundingBox(t=!0,i=!0){if(this.splatMesh){const s=await this.splatMesh.getBoundingBox(!1);if(s.isEmpty())return void(this.bbox=s);this.splatAnchor.updateMatrix();const n=s.clone().applyMatrix4(this.splatAnchor.matrix),r=new e.Vector3;n.getCenter(r).multiplyScalar(-1),r.y=t?-n.min.y:0,i||(r.x=0,r.z=0),this.splatAnchor.position.add(r),this.bbox=n.translate(r)}else{const s=this.children.filter((e=>e!==this.platform&&e!==this.rotationRaycastMesh&&e!==this.controlBar));if(this.bbox=function(t){const i=new e.Box3;if(0===t.length)return i;const s=new Map;for(const e of t)e.parent&&(s.set(e,e.parent),e.removeFromParent()),i.expandByObject(e,!0);for(const[e,t]of s.entries())t.add(e);return i}(s),this.bbox.isEmpty())return;const n=new e.Vector3;this.bbox.getCenter(n).multiplyScalar(-1),n.y=t?-this.bbox.min.y:0,i||(n.x=0,n.z=0);for(const e of s)e.position.add(n);this.bbox.translate(n)}}setupRaycastCylinder(){const t=new e.Vector3;this.bbox.getSize(t);const i=.05+.5*Math.min(t.x,t.z),s=new tr(new e.CylinderGeometry(i,i,t.y),new e.MeshBasicMaterial({color:10027008,wireframe:!0}));this.bbox.getCenter(s.position),this.rotationRaycastMesh=s,this.rotationRaycastMesh.visible=!1,this.add(this.rotationRaycastMesh)}setupRaycastBox(){this.rotationRaycastMesh&&(this.rotationRaycastMesh.removeFromParent(),this.rotationRaycastMesh.geometry.dispose(),this.rotationRaycastMesh.material.dispose());const t=new e.Vector3;this.bbox.getSize(t);const i=new tr(new e.BoxGeometry(t.x,t.y,t.z),new e.MeshBasicMaterial({color:10027008,wireframe:!0}));this.bbox.getCenter(i.position),this.rotationRaycastMesh=i,this.rotationRaycastMesh.visible=!1,this.add(this.rotationRaycastMesh)}setupPlatform(t=Qn){const i=new e.Vector3;this.bbox.getSize(i);const s=i.x+t.x,n=i.z+t.y;this.platform=new $n(s,n,this.platformThickness);const r=new e.Vector3;this.bbox.getCenter(r),this.platform.position.set(r.x,-this.platformThickness/2,r.z),this.add(this.platform)}update(){this.splatMesh&&this.splatAnchor&&(this.updateMatrixWorld(!0),this.splatAnchor.matrixWorld.decompose(this.splatMesh.position,this.splatMesh.quaternion,this.splatMesh.scale));const e=this.clock.getDelta();this.animationMixer&&this.animationMixer.update(e),this.platform&&this.platform.update(e);const t=this.camera;if(null!=this.controlBar&&this.controlBar.parent==this&&null!=t){const e=Yn.copy(t.position).sub(this.position),i=e.length(),s=Math.asin(e.normalize().y);e.y=0,e.normalize(),Jn.copy(this.quaternion).invert(),this.controlBar.quaternion.setFromAxisAngle(as,s).premultiply(Zn.setFromUnitVectors(os,e)).premultiply(Jn),this.controlBar.position.setScalar(0).addScaledVector(e,.5).applyQuaternion(Jn),this.controlBar.position.y=0,this.controlBar.scale.set(i/this.scale.x,i/this.scale.y,i/this.scale.z)}}onObjectSelectStart(){return this.draggable||this.rotatable||this.scalable}onObjectSelectEnd(){return this.draggable||this.rotatable||this.scalable}onHoverEnter(e){this.hoveringControllers.add(e),this.platform&&(this.platform.opacity.speed=this.platformAnimationSpeed)}onHoverExit(e){this.hoveringControllers.delete(e),this.platform&&0==this.hoveringControllers.size&&(this.platform.opacity.speed=-this.platformAnimationSpeed)}raycast(e,t){const i=this.gltfMesh?.scene??this.splatMesh;if(this.raycastToChildren&&i){const i=[];for(const t of this.children)t!=this.rotationRaycastMesh&&t!=this.platform&&t!=this.controlBar&&e.intersectObject(t,!0,i);t.push(...i)}if(this.rotationRaycastMesh){const i=[];this.rotationRaycastMesh.raycast(e,i);for(const e of i)t.push(e)}if(this.platform){const i=[];this.platform.raycast(e,i);for(const e of i)t.push(e)}if(null!=this.controlBar&&this.controlBar.parent==this){const i=[];this.controlBar.raycast(e,i);for(const e of i)t.push(e)}return!1}onScaleButtonClick(){this.scale.setScalar(1)}setCastShadow(e){this.castShadow=e,this.gltfMesh&&this.gltfMesh.scene.traverse((function(t){t.castShadow=e})),this.platform&&(this.platform.castShadow=!1)}setReceiveShadow(e){this.receiveShadow=e,this.gltfMesh&&this.gltfMesh.scene.traverse((function(t){t.receiveShadow=e})),this.platform&&(this.platform.receiveShadow=e)}getOcclusionEnabled(){for(const e of this.occludableShaders)return e.uniforms.occlusionEnabled.value;return!1}setOcclusionEnabled(e){for(const t of this.occludableShaders)t.uniforms.occlusionEnabled.value=e}playClipAnimationOnce(){this.startAnimationOnLoad||0===this.clipActions.length||this.clipActions.forEach((t=>{t.reset(),t.clampWhenFinished=!0,t.loop=e.LoopOnce,t.play()}))}async createSparkRendererIfNeeded(){const{SparkRenderer:e}=await import("@sparkjsdev/spark");let t=!1;this.scene.traverse((i=>{t||=i instanceof e})),t||this.scene.add(new e({renderer:this.renderer,maxStdDev:Math.sqrt(5)}))}}class sr extends ki{static{this.dependencies={user:is}}constructor(){const t=document.createElement("canvas");t.width=1024,t.height=1024;const i=t.getContext("2d"),s=new e.CanvasTexture(t),n=new e.PlaneGeometry(.001*t.width,.001*t.height),r=new e.MeshBasicMaterial({map:s,toneMapped:!1,alphaTest:.01});super({},n,r),this.activeHand=-1,this.activeLine=[],this.activeLines=[],this.removedLines=[],this.isDrawing=!1,this.canvas=t,this.ctx=i,this.material=r,this.width=.001*t.width,this.height=.001*t.height,this.scale.set(this.width,this.height,1)}init({user:e}){super.init(),this.user=e,this.clearCanvas()}getContext(){return this.ctx}triggerUpdate(){this.material.map.needsUpdate=!0}onSelectStart(e){-1===this.activeHand&&(this.activeHand=e?.target?.userData?.id??-1,0!==this.activeHand&&1!==this.activeHand||(this.activeLine=[],this.ctx.beginPath()))}onSelectEnd(e){(e?.target?.userData?.id??-1)===this.activeHand&&(this.activeHand>=0&&this.activeLine.length>1&&(this.activeLines.push(this.activeLine),this.removedLines=[]),this.isDrawing=!1,this.activeLine=[],this.activeHand=-1)}onSelecting(e){const t=e.target.userData.id;if(t!==this.activeHand)return;const i=this.user.getReticleIntersection(t);if(i)if(i.object instanceof sr&&i.uv){const e=Math.round(1024*i.uv.x),t=Math.round(1024-1024*i.uv.y),s=this.ctx;this.isDrawing?(s.lineTo(e,t),s.strokeStyle="black",s.lineWidth=6,s.stroke(),this.triggerUpdate(),this.activeLine.push({x:e,y:t})):(this.activeLine.push({x:e,y:t,b:!0}),s.moveTo(e,t),this.isDrawing=!0)}else this.isDrawing=!1;else this.isDrawing=!1}clearCanvas(e=!0){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.ctx.fillStyle="#FFFFFF",this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height),e&&this.triggerUpdate()}removeAll(){this.activeLines=[],this.removedLines=[],this.clearCanvas()}undo(){if(0===this.activeLines.length)return;this.ctx=this.canvas.getContext("2d");const e=this.activeLines.pop();this.removedLines.push(e),this.clearCanvas(!1),this.activeLines.forEach((e=>{this.#n(e)})),this.triggerUpdate()}redo(){if(0===this.removedLines.length)return;const e=this.removedLines.pop();this.activeLines.push(e),this.#n(e),this.triggerUpdate()}#n(e){this.ctx.beginPath(),this.ctx.strokeStyle="black",this.ctx.lineWidth=6,e.forEach((e=>{e.b?this.ctx.moveTo(e.x,e.y):(this.ctx.lineTo(e.x,e.y),this.ctx.stroke())}))}update(){}}class nr extends Fn{constructor(){super(...arguments),this.localClippingPlanes=[new e.Plane(new e.Vector3(1,0,0),.5),new e.Plane(new e.Vector3(-1,0,0),.5)]}updateLayout(){super.updateLayout(),this.localClippingPlanes[0].constant=.5*this.rangeX,this.localClippingPlanes[1].constant=.5*this.rangeX}}class rr extends qi{constructor({pagerState:e}){super({text:""}),this.emptyPageIndicator="◦",this.currentPageIndicator="•",this.numberOfPages=0,this.previousPage=0,this.pagerState=e,this.previousPage=Math.round(e.currentPage),this.numberOfPages=e.pages,this.updateText()}update(){super.update();const e=Math.round(this.pagerState.currentPage);this.previousPage===e&&this.numberOfPages===this.pagerState.pages||this.updateText()}updateText(){const e=Math.round(this.pagerState.currentPage)%this.pagerState.pages,t=new Array(this.pagerState.pages).fill(this.emptyPageIndicator);t[e]=this.currentPageIndicator,this.setText(t.join("")),this.previousPage=e}}class or extends ke{constructor({videoFile:e,willCaptureFrequently:t=!1}={}){super({willCaptureFrequently:t}),this.videoFile_=e}async init(){await super.init(),this.videoFile_?(this.setState_(ze.INITIALIZING),await this.initStream_()):(console.warn("VideoFileStream initialized without a video file."),this.setState_(ze.IDLE))}async initStream_(){if(!this.videoFile_)throw new Error("No video file has been provided.");this.stop_(),this.video_.srcObject=null,this.video_.src="string"==typeof this.videoFile_?this.videoFile_:URL.createObjectURL(this.videoFile_),this.video_.loop=!0,this.video_.muted=!0,await new Promise(((e,t)=>{this.video_.onloadedmetadata=()=>{this.handleVideoStreamLoadedMetadata(e,t)},this.video_.onerror=()=>{const e=new Error("Error occurred while loading the video file.");this.setState_(ze.ERROR,{error:e}),t(e)},this.video_.play()})),this.setState_(ze.STREAMING,{width:this.width,height:this.height,aspectRatio:this.aspectRatio,videoFile:this.videoFile_})}async setSource(e){if(!e)return console.warn("setSource called with no file. Stopping stream."),this.stop_(),void(this.videoFile_=void 0);this.setState_(ze.INITIALIZING),this.videoFile_=e,await this.initStream_()}}export{$ as AI,F as AIOptions,Ot as AVERAGE_IPD_METERS,ht as ActiveControllers,p as Agent,rt as AnimatableNumber,bi as AudioListener,Ci as AudioPlayer,os as BACK,Mi as BackgroundMusic,Ei as CategoryVolumes,bs as Col,Us as Core,Bi as CoreSound,oe as DEFAULT_DEVICE_CAMERA_HEIGHT,re as DEFAULT_DEVICE_CAMERA_WIDTH,ss as DOWN,Oe as Depth,ye as DepthMesh,we as DepthMeshOptions,xe as DepthOptions,Te as DepthTextures,Vs as DetectedObject,Fs as DetectedPlane,ce as DeviceCameraOptions,gs as DragManager,ps as DragMode,ms as ExitButton,rs as FORWARD,Gn as FreestandingSlider,ot as GazeController,W as Gemini,V as GeminiOptions,m as GenerateSkyboxTool,v as GetWeatherTool,fs as Grid,Z as HAND_BONE_IDX_CONNECTION_MAP,Y as HAND_JOINT_COUNT,J as HAND_JOINT_IDX_CONNECTION_MAP,Ze as HAND_JOINT_NAMES,et as Handedness,tt as Hands,pt as HandsOptions,nr as HorizontalPager,Xi as IconButton,Ki as IconView,$i as ImageView,ct as Input,Rt as InputOptions,Lt as Keycodes,as as LEFT,te as LEFT_VIEW_ONLY_LAYER,Qi as LabelView,dt as Lighting,gt as LightingOptions,Es as LoadingSpinnerManager,Pn as MaterialSymbolsView,C as MeshScript,qn as ModelLoader,ir as ModelViewer,at as MouseController,vt as NEXT_SIMULATOR_MODE,Q as NUM_HANDS,se as OCCLUDABLE_ITEMS_LAYER,Bs as ObjectDetector,bt as ObjectsOptions,Pe as OcclusionPass,Ns as OcclusionUtils,X as OpenAI,B as OpenAIOptions,Et as Options,rr as PageIndicator,Fn as Pager,Ln as PagerState,Ss as Panel,ys as PanelMesh,ut as Physics,mt as PhysicsOptions,nn as PinchOnButtonAction,zs as PlaneDetector,Ct as PlanesOptions,hs as RIGHT,ie as RIGHT_VIEW_ONLY_LAYER,Ue as Registry,st as Reticle,Mt as ReticleOptions,tr as RotationRaycastMesh,Ts as Row,ui as SIMULATOR_HAND_POSE_NAMES,ci as SIMULATOR_HAND_POSE_TO_JOINTS_LEFT,di as SIMULATOR_HAND_POSE_TO_JOINTS_RIGHT,_i as SOUND_PRESETS,He as ScreenshotSynthesizer,S as Script,w as ScriptMixin,We as ScriptsManager,kn as ScrollingTroikaTextView,si as SetSimulatorModeEvent,rn as ShowHandsAction,Si as Simulator,At as SimulatorCamera,Ht as SimulatorControlMode,Vt as SimulatorControllerState,ri as SimulatorControls,ai as SimulatorDepth,oi as SimulatorDepthMaterial,li as SimulatorHandPose,hi as SimulatorHandPoseChangeRequestEvent,fi as SimulatorHands,vi as SimulatorInterface,_t as SimulatorMediaDeviceInfo,ft as SimulatorMode,yt as SimulatorOptions,It as SimulatorRenderMode,yi as SimulatorScene,xi as SimulatorUser,$s as SimulatorUserAction,sr as SketchPanel,f as SkyboxAgent,St as SoundOptions,Pi as SoundSynthesizer,Ii as SpatialAudio,Rs as SpatialPanel,Li as SpeechRecognizer,xt as SpeechRecognizerOptions,Vi as SpeechSynthesizer,wt as SpeechSynthesizerOptions,er as SplatAnchor,ze as StreamState,Ji as TextButton,An as TextScrollerState,qi as TextView,g as Tool,Ms as UI,ne as UI_OVERLAY_LAYER,ns as UP,y as UX,is as User,ee as VIEW_DEPTH_GAP,zn as VerticalPager,or as VideoFileStream,ke as VideoStream,Zi as VideoView,ki as View,Di as VolumeCategory,qe as WaitFrame,pn as WalkTowardsPanelAction,ks as World,Tt as WorldOptions,Qe as XRButton,je as XRDeviceCamera,Je as XREffects,Ye as XRPass,Dt as XRTransitionOptions,ae as XR_BLOCKS_ASSETS_PATH,ls as ZERO_VECTOR3,wn as add,yn as ai,Ie as aspectRatios,wi as callInitWithDependencyInjection,T as clamp,Ks as clampRotationToAngle,gn as core,Fe as cropImage,qs as extractYaw,I as getColorHex,Cn as getDeltaTime,_ as getUrlParamBool,A as getUrlParamFloat,P as getUrlParamInt,E as getUrlParameter,O as getVec4ByColorString,Rn as getXrCameraLeft,Mn as getXrCameraRight,xn as init,Sn as initScript,R as lerp,_n as loadStereoImageAsTextures,_s as loadingSpinnerManager,Xs as lookAtRotation,es as objectIsDescendantOf,fe as onDesktopUserAgent,L as parseBase64DataURL,Ls as placeObjectAtIntersectionFacingTarget,M as print,Le as rgbToDepthParams,mn as scene,Dn as showOnlyInLeftEye,En as showOnlyInRightEye,Tn as showReticleOnDepthMesh,Ve as transformRgbToDepthUv,Be as transformRgbUvToWorld,ts as traverseUtil,bn as uninitScript,D as urlParams,fn as user,vn as world,Se as xrDepthMeshOptions,Ce as xrDepthMeshPhysicsOptions,be as xrDepthMeshVisualizationOptions,ge as xrDeviceCameraEnvironmentContinuousOptions,ue as xrDeviceCameraEnvironmentOptions,me as xrDeviceCameraUserContinuousOptions,pe as xrDeviceCameraUserOptions};
1
+ import*as e from"three";import{Pass as t,FullScreenQuad as i}from"three/addons/postprocessing/Pass.js";import{XRControllerModelFactory as s}from"three/addons/webxr/XRControllerModelFactory.js";import{XRHandModelFactory as n}from"three/addons/webxr/XRHandModelFactory.js";import{XREstimatedLight as r}from"three/addons/webxr/XREstimatedLight.js";import{GLTFLoader as o}from"three/addons/loaders/GLTFLoader.js";import{SVGLoader as a}from"three/addons/loaders/SVGLoader.js";import{DRACOLoader as h}from"three/addons/loaders/DRACOLoader.js";import{KTX2Loader as l}from"three/addons/loaders/KTX2Loader.js";import*as c from"three/addons/utils/BufferGeometryUtils.js";class d{constructor(e="You are a helpful assistant."){this.instructions=e}get instruction(){return this.instructions}build(e,t){const i=e.getShortTerm().map(e=>this.formatEntry(e)).join("\n"),s=t.map(e=>`- ${e.name}: ${e.description}`).join("\n");return`${this.instructions} You have access to the following tools: ${s}\n Current Conversation history: ${i}. You should reply to the user or call a tool as needed.`}formatEntry(e){switch(e.role){case"user":return`User: ${e.content}`;case"ai":return`AI: ${e.content}`;case"tool":return`Tool Output: ${e.content}`}}}class u{constructor(){this.shortTermMemory=[]}addShortTerm(e){this.shortTermMemory.push(e)}getShortTerm(){return[...this.shortTermMemory]}clear(){this.shortTermMemory.length=0}}class p{static{this.dependencies={}}constructor(e,t=[],i="",s){this.isSessionActive=!1,this.ai=e,this.tools=t,this.memory=new u,this.contextBuilder=new d(i),this.lifecycleCallbacks=s}async start(e){return this.memory.addShortTerm({role:"user",content:e}),this.ai.isAvailable()||await this.ai.init({aiOptions:this.ai.options}),this.run()}async run(){for(;;){const e=this.contextBuilder.build(this.memory,this.tools),t=await this.ai.model.query({type:"text",text:e},this.tools);if(this.memory.addShortTerm({role:"ai",content:JSON.stringify(t)}),!t?.toolCall){if(t?.text)return console.log(`Final Response: ${t.text}`),t.text;{const e="The AI did not provide a valid response.";return console.error(e),e}}{console.log(`Executing tool: ${t.toolCall.name}`);const e=this.findTool(t.toolCall.name);if(e){const i=await e.execute(t.toolCall.args);this.memory.addShortTerm({role:"tool",content:JSON.stringify(i)})}else{const e=`Error: Tool "${t.toolCall.name}" not found.`;console.error(e),this.memory.addShortTerm({role:"tool",content:e})}}}}findTool(e){return this.tools.find(t=>t.name===e)}getSessionState(){return{isActive:this.isSessionActive,toolCount:this.tools.length,memorySize:this.memory.getShortTerm?.()?.length||0}}}class g{constructor(e){this.name=e.name,this.description=e.description,this.parameters=e.parameters||{},this.onTriggered=e.onTriggered,this.behavior=e.behavior}async execute(e){try{if(this.onTriggered){return{success:!0,data:await Promise.resolve(this.onTriggered(e)),metadata:{executedAt:Date.now(),toolName:this.name}}}throw new Error("The execute method must be implemented by a subclass or onTriggered must be provided.")}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e),metadata:{executedAt:Date.now(),toolName:this.name}}}}toJSON(){const e={name:this.name};return this.description&&(e.description=this.description),this.parameters&&(e.parameters=this.parameters),this.behavior&&(e.behavior=this.behavior),e}}class m extends g{constructor(e,t){super({name:"generateSkybox",description:"Generate a 360 equirectangular skybox image for the given prompt.",parameters:{type:"OBJECT",properties:{prompt:{type:"STRING",description:'A description of the skybox to generate, e.g. "a sunny beach with palm trees"'}},required:["prompt"]}}),this.ai=e,this.scene=t}async execute(t){try{const i=await this.ai.generate("Generate a 360 equirectangular skybox image for the prompt of:"+t.prompt,"image","Generate a 360 equirectangular skybox image for the prompt","gemini-2.5-flash-image-preview");return i?(console.log("Applying texture..."),this.scene.background=(new e.TextureLoader).load(i),this.scene.background.mapping=e.EquirectangularReflectionMapping,{success:!0,data:"Skybox generated successfully.",metadata:{prompt:t.prompt,timestamp:Date.now()}}):{success:!1,error:"Failed to generate skybox image",metadata:{prompt:t.prompt,timestamp:Date.now()}}}catch(e){return console.error("error:",e),{success:!1,error:e instanceof Error?e.message:"Unknown error while creating skybox",metadata:{prompt:t.prompt,timestamp:Date.now()}}}}}class f extends p{constructor(e,t,i,s){super(e,[new m(e,i)],"You are a friendly and helpful skybox designer. The response should be short. Your only capability\n is to generate a 360-degree equirectangular skybox image based on\n a user's description. You will generate a default skybox if the user\n does not provide any description. You will use the tool 'generateSkybox'\n with the summarized description as the 'prompt' argument to create the skybox.",s),this.sound=t,this.sessionState={isActive:!1,messageCount:0,toolCallCount:0}}async startLiveSession(e){const t=this.wrapCallbacks(e);e&&this.ai.setLiveCallbacks(t);const i=this.tools.map(e=>e.toJSON()),s={parts:[{text:this.contextBuilder.instruction}]};await this.ai.startLiveSession({tools:[{functionDeclarations:i}],systemInstruction:s}),this.sessionState.isActive=!0,this.sessionState.startTime=Date.now(),this.isSessionActive=!0,await(this.lifecycleCallbacks?.onSessionStart?.())}async stopLiveSession(){await this.ai.stopLiveSession(),this.sessionState.isActive=!1,this.sessionState.endTime=Date.now(),this.isSessionActive=!1,await(this.lifecycleCallbacks?.onSessionEnd?.())}wrapCallbacks(e){return{onopen:()=>{e?.onopen?.()},onmessage:t=>{this.sessionState.messageCount++,e?.onmessage?.(t)},onerror:t=>{this.sessionState.lastError=t.message,this.lifecycleCallbacks?.onError?.(new Error(t.message)),e?.onerror?.(t)},onclose:t=>{this.sessionState.isActive=!1,this.sessionState.endTime=Date.now(),this.isSessionActive=!1,e?.onclose?.(t)}}}async sendToolResponse(e){if(!this.validateToolResponse(e))return void console.error("Invalid tool response format:",e);const t=Array.isArray(e.functionResponses)?e.functionResponses:[e.functionResponses];this.sessionState.toolCallCount+=t.length,console.log("Sending tool response:",e),this.ai.sendToolResponse(e)}validateToolResponse(e){if(!e.functionResponses)return!1;return(Array.isArray(e.functionResponses)?e.functionResponses:[e.functionResponses]).every(e=>e.id&&e.name&&void 0!==e.response)}static createToolResponse(e,t,i){return{id:e,name:t,response:i.success?{result:i.data}:{error:i.error}}}getLiveSessionState(){return{...this.sessionState}}getSessionDuration(){if(!this.sessionState.startTime)return null;return(this.sessionState.endTime||Date.now())-this.sessionState.startTime}}class v extends g{constructor(){super({name:"get_weather",description:"Gets the current weather for a specific location.",parameters:{type:"OBJECT",properties:{location:{type:"STRING",description:"The city and state, e.g. San Francisco, CA"},unit:{type:"STRING",enum:["celsius","fahrenheit"]}},required:["location"]}})}async execute(e){e.latitude&&e.longitude||(e.latitude=37.7749,e.longitude=-122.4194);const t=`https://api.open-meteo.com/v1/forecast?latitude=${e.latitude}&longitude=${e.longitude}&current=weather_code,temperature_2m&temperature_unit=fahrenheit`;try{const i=await fetch(t),s=await i.json();return i.ok?{success:!0,data:{temperature:s.current.temperature_2m,weathercode:s.current.weather_code},metadata:{latitude:e.latitude,longitude:e.longitude,timestamp:Date.now()}}:{success:!1,error:"Could not retrieve weather for the specified location.",metadata:{latitude:e.latitude,longitude:e.longitude}}}catch(t){return console.error("Error fetching weather:",t),{success:!1,error:t instanceof Error?t.message:"There was an error fetching the weather.",metadata:{latitude:e.latitude,longitude:e.longitude}}}}}class y{constructor(t){this.draggable=!1,this.selectable=!1,this.touchable=!1,this.selected=[],this.hovered=[],this.touched=[],this.activeDragged=[],this.positions=[],this.distances=[],this.uvs=[],this.initialPosition=new e.Vector3,this.parent=t}isHovered(){return this.hovered.includes(!0)}isSelected(){return this.selected.includes(!0)}isDragging(){return this.activeDragged.includes(!0)}update(e,t){const i=e.userData.id;this.initializeVariablesForId(i),t.object!==this.parent&&t.object!==this.parent.mesh||(this.hovered[i]=!0,this.selected[i]=e.userData.selected,t.uv&&this.uvs[i].copy(t.uv),this.positions[i].copy(t.point),this.distances[i]=t.distance,this.selected[i]||(this.activeDragged[i]=!1))}initializeVariablesForId(t){for(;this.selected.length<=t;)this.selected.push(!1),this.hovered.push(!1),this.activeDragged.push(!1),this.positions.push(new e.Vector3),this.distances.push(1),this.uvs.push(new e.Vector2)}reset(){for(const e in this.selected)this.selected[e]=!1,this.hovered[e]=!1}getPrimaryTwoControllerIds(){const e=[];if(this.hovered)for(let t=0;t<this.hovered.length&&e.length<2;++t)this.hovered[t]&&e.push(t);return[e[0]??null,e[1]??null]}}function w(e){return class extends e{constructor(){super(...arguments),this.ux=new y(this),this.isXRScript=!0}init(e){}update(e,t){}initPhysics(e){}physicsStep(){}onXRSessionStarted(e){}onXRSessionEnded(){}onSimulatorStarted(){}onSelectStart(e){}onSelectEnd(e){}onSelect(e){}onSelecting(e){}onKeyDown(e){}onKeyUp(e){}onSqueezeStart(e){}onSqueezeEnd(e){}onSqueezing(e){}onSqueeze(e){}onObjectSelectStart(e){return!1}onObjectSelectEnd(e){return!1}onHoverEnter(e){}onHoverExit(e){}onHovering(e){}onObjectTouchStart(e){}onObjectTouching(e){}onObjectTouchEnd(e){}onObjectGrabStart(e){}onObjectGrabbing(e){}onObjectGrabEnd(e){}dispose(){}}}const x=w(e.Object3D);class S extends x{}const b=w(e.Mesh);class C extends b{constructor(e,t){super(e,t)}}function T(e,t,i){return Math.min(Math.max(e,t),i)}function R(e,t,i){return e+(t-e)*i}function M(...e){console.log("*",...e)}const D=new URLSearchParams(window.location.search);function E(e){return new URLSearchParams(window.location.search).get(e)}function P(e,t=!1){const i=D.get(e)?.toLowerCase();return"true"===i||"1"===i||"false"!==i&&"0"!==i&&t}function _(e,t=0){const i=D.get(e);if(i){const e=parseInt(i,10);if(!isNaN(e))return e}return t}function A(e,t=0){const i=D.get(e);if(i){const e=parseFloat(i);if(!isNaN(e))return e}return t}function O(t){if("string"!=typeof t)throw new Error("colorString must be a string");const i=t.startsWith("#")?t.slice(1):t,s=i.length;let n=1,r=i;if(3!==s&&4!==s||(r=i.split("").map(e=>e+e).join("")),8===r.length)n=parseInt(r.slice(6,8),16)/255,r=r.slice(0,6);else if(6!==r.length)throw new Error(`Invalid hex color string format: ${t}`);const o=parseInt(r.slice(0,2),16)/255,a=parseInt(r.slice(2,4),16)/255,h=parseInt(r.slice(4,6),16)/255;if(isNaN(o)||isNaN(a)||isNaN(h)||isNaN(n))throw new Error(`Invalid hex values in color string: ${t}`);return new e.Vector4(o,a,h,n)}function I(e){if("string"==typeof e){const t=O(e);return(Math.round(255*t.x)<<16)+(Math.round(255*t.y)<<8)+Math.round(255*t.z)}return"number"==typeof e?e:16777215}function L(e){const t=e.match(/^data:(image\/[a-zA-Z0-9\-+.]+);base64,/);if(t){const i=t[1];return{strippedBase64:e.substring(t[0].length),mimeType:i}}return{strippedBase64:e,mimeType:null}}class V{constructor(){this.apiKey="",this.urlParam="geminiKey",this.keyValid=!1,this.enabled=!1,this.model="gemini-2.0-flash",this.config={},this.live={enabled:!1,model:"gemini-live-2.5-flash-preview",voiceName:"Aoede",screenshotInterval:3e3,audioConfig:{sampleRate:16e3,channelCount:1,echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0}}}}class B{constructor(){this.apiKey="",this.urlParam="openaiKey",this.model="gpt-4.1",this.enabled=!1}}class F{constructor(){this.enabled=!1,this.model="gemini",this.gemini=new V,this.openai=new B,this.globalUrlParams={key:"key"}}}class z{constructor(){}}let k,j,U,N,G,H;class W extends z{constructor(e){super(),this.options=e,this.inited=!1,this.isLiveMode=!1,this.liveCallbacks={}}async init(){await async function(){if(!U)try{const e=await import("@google/genai");if(!e||!e.GoogleGenAI)throw new Error("'@google/genai' module loaded but is not valid.");k=e.createPartFromUri,j=e.createUserContent,U=e.GoogleGenAI,N=e.EndSensitivity,G=e.StartSensitivity,H=e.Modality,console.log("'@google/genai' module loaded successfully.")}catch(e){const t=`The '@google/genai' module is required for Gemini but failed to load. Error: ${e}`;throw console.error(t),new Error(t)}}()}isAvailable(){return!!U&&(this.inited||(this.ai=new U({apiKey:this.options.apiKey}),this.inited=!0),!0)}isLiveAvailable(){return this.isAvailable()&&N&&G&&H}async startLiveSession(e={},t="gemini-2.5-flash-native-audio-preview-09-2025"){if(!this.isLiveAvailable())throw new Error("Live API not available. Make sure @google/genai module is loaded.");if(this.liveSession)return this.liveSession;const i={responseModalities:[H.AUDIO],speechConfig:{voiceConfig:{prebuiltVoiceConfig:{voiceName:"Aoede"}}},outputAudioTranscription:{},inputAudioTranscription:{},...e},s={onopen:()=>{this.isLiveMode=!0,console.log("🔓 Live session opened."),this.liveCallbacks?.onopen&&this.liveCallbacks.onopen()},onmessage:e=>{this.liveCallbacks?.onmessage&&this.liveCallbacks.onmessage(e)},onerror:e=>{console.error("❌ Live session error:",e),this.liveCallbacks?.onerror&&this.liveCallbacks.onerror(e)},onclose:e=>{this.isLiveMode=!1,this.liveSession=void 0,e.reason?console.warn("🔒 Live session closed:",e):console.warn("🔒 Live session closed without reason."),this.liveCallbacks?.onclose&&this.liveCallbacks.onclose(e)}};try{const e={model:t,callbacks:s,config:i};return console.log("Connecting with params:",e),this.liveSession=await this.ai.live.connect(e),this.liveSession}catch(e){throw console.error("❌ Failed to start live session:",e),e}}async stopLiveSession(){this.liveSession&&(this.liveSession.close(),this.liveSession=void 0,this.isLiveMode=!1)}setLiveCallbacks(e){this.liveCallbacks=e}sendToolResponse(e){this.liveSession&&(console.debug("Sending tool response to gemini:",e),this.liveSession.sendToolResponse(e))}sendRealtimeInput(e){if(this.liveSession)try{this.liveSession.sendRealtimeInput(e)}catch(e){throw console.error("❌ Error sending realtime input:",e),e}}getLiveSessionStatus(){return{isActive:this.isLiveMode,hasSession:!!this.liveSession,isAvailable:this.isLiveAvailable()}}async query(e,t=[]){if(!this.inited)return console.warn("Gemini not inited."),null;const i=this.options,s=i.config||{};if(!("type"in e)){return{text:(await this.ai.models.generateContent({model:i.model,contents:e.prompt,config:s})).text||null}}const n=this.ai.models,r={model:this.options.model,contents:[],config:this.options.config||{}};let o=null;switch(e.type){case"text":r.contents=e.text,o=await n.generateContent(r);break;case"base64":e.mimeType||(e.mimeType="image/png"),r.contents={inlineData:{mimeType:e.mimeType,data:e.base64}},o=await n.generateContent(r);break;case"uri":r.contents=j([k(e.uri,e.mimeType),e.text]),o=await n.generateContent(r);break;case"multiPart":r.contents=[{role:"user",parts:e.parts}],o=await n.generateContent(r)}if(!o)return{text:null};const a=o.functionCalls?.[0];return a&&a.name?{toolCall:{name:a.name,args:a.args}}:{text:o.text||null}}async generate(e,t="image",i="Generate an image",s="gemini-2.5-flash-image-preview"){if(!this.isAvailable())return;let n;n=Array.isArray(e)?e.map(e=>{if("string"==typeof e){if(e.startsWith("data:image/")){const[t,i]=e.split(",");return{inlineData:{mimeType:t.split(";")[0].split(":")[1],data:i}}}return{text:e}}return e}):e;const r=await this.ai.models.generateContent({model:s,contents:n,config:{systemInstruction:i}});if(r.candidates&&r.candidates.length>0){const e=r.candidates[0];for(const i of e?.content?.parts||[])if("image"===t&&i.inlineData)return"data:image/png;base64,"+i.inlineData.data}}}let q=null;class X extends z{constructor(e){super(),this.options=e}async init(){await async function(){if(!q)try{const e=await import("openai");q=e.default,console.log("'openai' module loaded successfully.")}catch(e){console.warn("'openai' module not found. Using fallback implementations.","Error details:",e)}}(),this.options.apiKey&&q?(this.openai=new q({apiKey:this.options.apiKey,dangerouslyAllowBrowser:!0}),console.log("OpenAI model initialized")):console.error("OpenAI API key is missing or module failed to load.")}isAvailable(){return!!this.openai}async query(e,t){if(!this.isAvailable())throw new Error("OpenAI model is not initialized.");try{const t=(await this.openai.chat.completions.create({messages:[{role:"user",content:e.prompt}],model:this.options.model})).choices[0].message.content;return t?{text:t}:null}catch(e){throw console.error("Error querying OpenAI:",e),e}}async generate(){throw new Error("Wrapper not implemented")}}const K={gemini:W,openai:X};class $ extends S{constructor(){super(...arguments),this.lock=!1}static{this.dependencies={aiOptions:F}}async loadKeysFromFile(){if(this.keysCache)return this.keysCache;try{const e=await fetch("./keys.json");if(e.ok)return this.keysCache=await e.json(),console.log("🔑 Loaded keys.json"),this.keysCache}catch{}return null}async init({aiOptions:e}){if(this.lock=!1,this.options=e,!e.enabled)return void console.log("AI is disabled in options");const t=e.model,i=K[t];if(i){const s=e[t];s&&s.enabled?await this.initializeModel(i,s):console.log(`${t} is disabled in AI options`)}else console.error(`Unsupported AI model: ${t}`)}async initializeModel(e,t){const i=await this.resolveApiKey(t);if(i&&this.isValidApiKey(i)){t.apiKey=i,this.model=new e(t);try{await this.model.init(),console.log(`${this.options.model} initialized`)}catch(e){console.error(`Failed to initialize ${this.options.model}:`,e),this.model=void 0}}else console.error(`No valid API key found for ${this.options.model}`)}async resolveApiKey(e){const t=this.options.model;if(e.apiKey)return e.apiKey;const i=E("key");if(i)return i;const s=E(e.urlParam);if(s)return s;const n=E("geminiKey64");if(n)return window.atob(n);const r=await this.loadKeysFromFile();if(r){const e=t+"ApiKey";let i=null;if("object"==typeof r[t]?i=r[t]?.apiKey:"string"==typeof r[e]?i=r[e]:"string"==typeof r[t]&&(i=r[t]),i)return console.log(`🔑 Using ${t} key from keys.json`),i}return null}isValidApiKey(e){return e&&"string"==typeof e&&e.length>0}isAvailable(){return this.model&&this.model.isAvailable()&&!this.lock}async query(e,t){if(!this.isAvailable())throw new Error("AI is not available. Check if it's enabled and properly initialized.");return await this.model.query(e,t)}async startLiveSession(e={},t){if(!this.model)throw new Error("AI model is not initialized.");if(!("isLiveAvailable"in this.model)||!this.model.isLiveAvailable())throw new Error("Live session is not available for the current model.");this.lock=!0;try{return await this.model.startLiveSession(e,t)}catch(e){throw this.lock=!1,console.error("❌ Failed to start Live session:",e),e}}async stopLiveSession(){if(this.model)try{await("stopLiveSession"in this.model&&this.model.stopLiveSession())}catch(e){console.error("❌ Error stopping Live session:",e)}finally{this.lock=!1}}async setLiveCallbacks(e){this.model&&"setLiveCallbacks"in this.model&&this.model.setLiveCallbacks(e)}sendToolResponse(e){this.model&&"sendToolResponse"in this.model&&this.model.sendToolResponse(e)}sendRealtimeInput(e){return!(!this.model||!("sendRealtimeInput"in this.model))&&this.model.sendRealtimeInput(e)}getLiveSessionStatus(){return this.model&&"getLiveSessionStatus"in this.model?this.model.getLiveSessionStatus():{isActive:!1,hasSession:!1,isAvailable:!1}}isLiveAvailable(){return this.model&&"isLiveAvailable"in this.model&&this.model.isLiveAvailable()}triggerKeyPopup(){}async generate(e,t="image",i="Generate an image",s="gemini-2.5-flash-image-preview"){return this.model.generate(e,t,i,s)}static createSampleKeysStructure(){return{gemini:{apiKey:"YOUR_GEMINI_API_KEY_HERE"},openai:{apiKey:"YOUR_OPENAI_API_KEY_HERE"}}}async hasApiKey(){if(!this.options)return!1;const e=this.options[this.options.model];if(!e)return!1;const t=await this.resolveApiKey(e);return t&&this.isValidApiKey(t)}}const Q=2,Y=25,J=[[1,2],[2,3],[3,4],[5,6],[6,7],[7,8],[8,9],[10,11],[11,12],[12,13],[13,14],[15,16],[16,17],[17,18],[18,19],[20,21],[21,22],[22,23],[23,24]],Z=[[0,1],[1,2],[3,4],[4,5],[5,6],[7,8],[8,9],[9,10],[11,12],[12,13],[13,14],[15,16],[16,17],[17,18]],ee=.002,te=1,ie=2,se=3,ne=4,re=1280,oe=720,ae="https://cdn.jsdelivr.net/gh/xrblocks/assets@34228db7ec7cef66fd65ef3250ef6f4a930fe373/";function he(e){return Object.freeze(e),Object.getOwnPropertyNames(e).forEach(t=>{const i=e[t];i&&"object"==typeof i&&!Object.isFrozen(i)&&he(i)}),e}function le(e,t){if(null==t)return e;const i=e;for(const e in t)if(Object.prototype.hasOwnProperty.call(t,e)){const s=i[e],n=t[e];s&&"object"==typeof s&&n&&"object"==typeof n?le(s,n):i[e]=n}}class ce{constructor(e){this.enabled=!1,this.willCaptureFrequently=!1,le(this,e)}}const de={enabled:!0,videoConstraints:{width:{ideal:1280},height:{ideal:720}}},ue=he(new ce({...de,videoConstraints:{...de.videoConstraints,facingMode:"environment"}})),pe=he(new ce({...de,videoConstraints:{...de.videoConstraints,facingMode:"user"}})),ge=he(new ce({...ue,willCaptureFrequently:!0})),me=he(new ce({...pe,willCaptureFrequently:!0}));function fe(){return!/Mobi|Android|iPhone/i.test(navigator.userAgent)}const ve={vertexShader:"\nvarying vec3 vNormal;\nvarying vec3 vViewPosition;\nvarying vec2 vUv;\n\nvoid main() {\n vUv = uv;\n vNormal = normal;\n\n // Computes the view position.\n vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);\n vViewPosition = -mvPosition.xyz;\n\n gl_Position = projectionMatrix * mvPosition;\n}\n",fragmentShader:"\n#include <packing>\n\nuniform vec3 uColor;\nuniform sampler2D uDepthTexture;\nuniform sampler2DArray uDepthTextureArray;\nuniform vec3 uLightDirection;\nuniform vec2 uResolution;\nuniform float uRawValueToMeters;\n\nvarying vec3 vNormal;\nvarying vec3 vViewPosition;\nvarying vec2 vUv;\n\nconst highp float kMaxDepthInMeters = 8.0;\nconst float kInvalidDepthThreshold = 0.01;\nuniform float uMinDepth;\nuniform float uMaxDepth;\nuniform float uDebug;\nuniform float uOpacity;\nuniform bool uUsingFloatDepth;\nuniform bool uIsTextureArray;\n\nfloat saturate(in float x) {\n return clamp(x, 0.0, 1.0);\n}\n\nvec3 TurboColormap(in float x) {\n const vec4 kRedVec4 = vec4(0.55305649, 3.00913185, -5.46192616, -11.11819092);\n const vec4 kGreenVec4 = vec4(0.16207513, 0.17712472, 15.24091500, -36.50657960);\n const vec4 kBlueVec4 = vec4(-0.05195877, 5.18000081, -30.94853351, 81.96403246);\n const vec2 kRedVec2 = vec2(27.81927491, -14.87899417);\n const vec2 kGreenVec2 = vec2(25.95549545, -5.02738237);\n const vec2 kBlueVec2 = vec2(-86.53476570, 30.23299484);\n\n // Adjusts color space via 6 degree poly interpolation to avoid pure red.\n vec4 v4 = vec4( 1.0, x, x * x, x * x * x);\n vec2 v2 = v4.zw * v4.z;\n return vec3(\n dot(v4, kRedVec4) + dot(v2, kRedVec2),\n dot(v4, kGreenVec4) + dot(v2, kGreenVec2),\n dot(v4, kBlueVec4) + dot(v2, kBlueVec2)\n );\n}\n\n// Depth is packed into the luminance and alpha components of its texture.\n// The texture is in a normalized format, storing raw values that need to be\n// converted to meters.\nfloat DepthGetMeters(in sampler2D depth_texture, in vec2 depth_uv) {\n if (uUsingFloatDepth) {\n return texture2D(depth_texture, depth_uv).r * uRawValueToMeters;\n }\n vec2 packedDepthAndVisibility = texture2D(depth_texture, depth_uv).rg;\n return dot(packedDepthAndVisibility, vec2(255.0, 256.0 * 255.0)) * uRawValueToMeters;\n}\n\nfloat DepthArrayGetMeters(in sampler2DArray depth_texture, in vec2 depth_uv) {\n return uRawValueToMeters * texture(uDepthTextureArray, vec3 (depth_uv.x, depth_uv.y, 0)).r;\n}\n\nvec3 DepthGetColorVisualization(in float x) {\n return step(kInvalidDepthThreshold, x) * TurboColormap(x);\n}\n\nvoid main() {\n vec3 lightDirection = normalize(uLightDirection);\n\n // Compute UV coordinates relative to resolution\n // vec2 uv = gl_FragCoord.xy / uResolution;\n vec2 uv = vUv;\n\n // Ambient, diffuse, and specular terms\n vec3 ambient = 0.1 * uColor;\n float diff = max(dot(vNormal, lightDirection), 0.0);\n vec3 diffuse = diff * uColor;\n\n vec3 viewDir = normalize(vViewPosition);\n vec3 reflectDir = reflect(-lightDirection, vNormal);\n float spec = pow(max(dot(viewDir, reflectDir), 0.0), 16.0);\n vec3 specular = vec3(0.5) * spec; // Adjust specular color/strength\n\n // Combine Phong lighting\n vec3 finalColor = ambient + diffuse + specular;\n // finalColor = vec3(vNormal);\n\n // Output color\n gl_FragColor = uOpacity * vec4(finalColor, 1.0);\n\n if (uDebug > 0.5) {\n return;\n }\n\n vec2 depth_uv = uv;\n depth_uv.y = 1.0 - depth_uv.y;\n\n float depth = (uIsTextureArray ? DepthArrayGetMeters(uDepthTextureArray, depth_uv) : DepthGetMeters(uDepthTexture, depth_uv)) * 8.0;\n float normalized_depth =\n saturate((depth - uMinDepth) / (uMaxDepth - uMinDepth));\n gl_FragColor = uOpacity * vec4(TurboColormap(normalized_depth), 1.0);\n}\n"};class ye extends C{static{this.dependencies={camera:e.Camera,renderer:e.WebGLRenderer}}static{this.isDepthMesh=!0}constructor(t,i,s,n){const r=t.depthMesh,o=new e.PlaneGeometry(1,1,159,159);let a,h;r.useDepthTexture||r.showDebugTexture?(h={uDepthTexture:{value:null},uDepthTextureArray:{value:null},uIsTextureArray:{value:0},uColor:{value:new e.Color(11184810)},uResolution:{value:new e.Vector2(i,s)},uRawValueToMeters:{value:1},uMinDepth:{value:0},uMaxDepth:{value:8},uOpacity:{value:r.opacity},uDebug:{value:r.showDebugTexture?1:0},uLightDirection:{value:new e.Vector3(1,1,1).normalize()},uUsingFloatDepth:{value:t.useFloat32}},a=new e.ShaderMaterial({uniforms:h,vertexShader:ve.vertexShader,fragmentShader:ve.fragmentShader,side:e.FrontSide,transparent:!0})):(a=new e.ShadowMaterial({opacity:r.shadowOpacity}),a.depthWrite=!1),super(o,a),this.depthOptions=t,this.depthTextures=n,this.ignoreReticleRaycast=!1,this.worldPosition=new e.Vector3,this.worldQuaternion=new e.Quaternion,this.updateVertexNormals=!1,this.minDepth=8,this.maxDepth=0,this.minDepthPrev=8,this.maxDepthPrev=0,this.colliders=[],this.projectionMatrixInverse=new e.Matrix4,this.lastColliderUpdateTime=0,this.colliderId=0,this.visible=r.showDebugTexture||r.renderShadow,this.options=r,this.projectionMatrixInverse=new e.Matrix4,this.lastColliderUpdateTime=performance.now(),this.updateVertexNormals=r.updateVertexNormals,this.colliderUpdateFps=r.colliderUpdateFps,this.depthTextureMaterialUniforms=h,r.renderShadow&&(this.receiveShadow=!0,this.castShadow=!1),r.useDownsampledGeometry&&(this.downsampledGeometry=new e.PlaneGeometry(1,1,39,39),this.downsampledMesh=new e.Mesh(this.downsampledGeometry,a),this.downsampledMesh.visible=!1,this.add(this.downsampledMesh))}init({camera:e,renderer:t}){this.camera=e,this.renderer=t}updateDepth(t){const i=this.renderer.xr?.getCamera?.()?.cameras?.[0]||this.camera;if(!i)return;this.projectionMatrixInverse.copy(i.projectionMatrix).invert(),this.minDepth=8,this.maxDepth=0,this.options.updateFullResolutionGeometry&&this.updateFullResolutionGeometry(t),this.downsampledGeometry&&this.updateGeometry(t,this.downsampledGeometry),this.minDepthPrev=this.minDepth,this.maxDepthPrev=this.maxDepth,this.geometry.attributes.position.needsUpdate=!0;const s=this.depthTextures?.get(0);if(s&&this.depthTextureMaterialUniforms){const t=s instanceof e.ExternalTexture;this.depthTextureMaterialUniforms.uIsTextureArray.value=t?1:0,t?this.depthTextureMaterialUniforms.uDepthTextureArray.value=s:this.depthTextureMaterialUniforms.uDepthTexture.value=s,this.depthTextureMaterialUniforms.uMinDepth.value=this.minDepth,this.depthTextureMaterialUniforms.uMaxDepth.value=this.maxDepth,this.depthTextureMaterialUniforms.uRawValueToMeters.value=this.depthTextures.depthData.length?this.depthTextures.depthData[0].rawValueToMeters:1}this.options.updateVertexNormals&&this.geometry.computeVertexNormals(),this.updateColliderIfNeeded()}updateGPUDepth(e){this.updateDepth(this.convertGPUToGPU(e))}convertGPUToGPU(t){if(!this.depthTarget){this.depthTarget=new e.WebGLRenderTarget(t.width,t.height,{format:e.RedFormat,type:e.FloatType,internalFormat:"R32F",minFilter:e.NearestFilter,magFilter:e.NearestFilter,depthBuffer:!1}),this.depthTexture=new e.ExternalTexture(t.texture);this.renderer.properties.get(this.depthTexture).__webglTexture=t.texture,this.gpuPixels=new Float32Array(t.width*t.height);const i=new e.ShaderMaterial({vertexShader:"\n varying vec2 vUv;\n void main() {\n vUv = uv;\n vUv.y = 1.0-vUv.y;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n ",fragmentShader:"\n precision highp float;\n precision highp sampler2DArray;\n\n uniform sampler2DArray uTexture;\n uniform float uCameraNear;\n varying vec2 vUv;\n\n void main() {\n float z = texture(uTexture, vec3(vUv, 0)).r;\n z = uCameraNear / (1.0 - z);\n z = clamp(z, 0.0, 20.0);\n gl_FragColor = vec4(z, 0, 0, 1.0);\n }\n ",uniforms:{uTexture:{value:this.depthTexture},uCameraNear:{value:t.depthNear}},blending:e.NoBlending,depthTest:!1,depthWrite:!1,side:e.DoubleSide}),s=new e.Mesh(new e.PlaneGeometry(2,2),i);this.depthScene=new e.Scene,this.depthScene.add(s),this.depthCamera=new e.OrthographicCamera(-1,1,1,-1,0,1)}const i=this.renderer.getRenderTarget();return this.renderer.xr.enabled=!1,this.renderer.setRenderTarget(this.depthTarget),this.renderer.render(this.depthScene,this.depthCamera),this.renderer.readRenderTargetPixels(this.depthTarget,0,0,t.width,t.height,this.gpuPixels,0),this.renderer.xr.enabled=!0,this.renderer.setRenderTarget(i),{width:t.width,height:t.height,data:this.gpuPixels.buffer,rawValueToMeters:t.rawValueToMeters}}updateFullResolutionGeometry(e){this.updateGeometry(e,this.geometry)}updateGeometry(t,i){const s=t.width,n=t.height,r=this.depthOptions.useFloat32?new Float32Array(t.data):new Uint16Array(t.data),o=new e.Vector3;for(let e=0;e<i.attributes.position.count;++e){const a=i.attributes.uv.array[2*e],h=i.attributes.uv.array[2*e+1],l=Math.round(T(a*s,0,s-1)),c=r[Math.round(T((1-h)*n,0,n-1))*s+l];let d=t.rawValueToMeters*c;this.depthOptions.useFloat32&&(d=c),d>0&&(d<this.minDepth?this.minDepth=d:d>this.maxDepth&&(this.maxDepth=d)),0==d&&this.options.patchHoles&&(d=this.maxDepthPrev),this.options.patchHolesUpper&&h>.9&&(d=this.minDepthPrev),o.set(2*(a-.5),2*(h-.5),-1),o.applyMatrix4(this.projectionMatrixInverse),o.multiplyScalar(-d/o.z),i.attributes.position.array[3*e+0]=o.x,i.attributes.position.array[3*e+1]=o.y,i.attributes.position.array[3*e+2]=o.z}}updateColliderIfNeeded(){const e=performance.now()-this.lastColliderUpdateTime;if(this.RAPIER&&e>1e3/this.colliderUpdateFps){this.getWorldPosition(this.worldPosition),this.getWorldQuaternion(this.worldQuaternion),this.rigidBody.setTranslation(this.worldPosition,!1),this.rigidBody.setRotation(this.worldQuaternion,!1);const e=this.downsampledGeometry?this.downsampledGeometry:this.geometry,t=e.attributes.position.array,i=e.getIndex().array,s=this.RAPIER.ColliderDesc.trimesh(t,i).setDensity(1);if(this.options.useDualCollider)this.colliderId=(this.colliderId+1)%2,this.blendedWorld.removeCollider(this.colliders[this.colliderId],!1),this.colliders[this.colliderId]=this.blendedWorld.createCollider(s,this.rigidBody);else{const e=this.blendedWorld.createCollider(s,this.rigidBody);this.blendedWorld.removeCollider(this.collider,!1),this.collider=e}this.lastColliderUpdateTime=performance.now()}}initRapierPhysics(e,t){this.getWorldPosition(this.worldPosition),this.getWorldQuaternion(this.worldQuaternion);const i=e.RigidBodyDesc.fixed().setTranslation(this.worldPosition.x,this.worldPosition.y,this.worldPosition.z).setRotation(this.worldQuaternion);this.rigidBody=t.createRigidBody(i);const s=this.geometry.attributes.position.array,n=this.geometry.getIndex().array,r=e.ColliderDesc.trimesh(s,n);this.options.useDualCollider?(this.colliders=[],this.colliders.push(t.createCollider(r,this.rigidBody),t.createCollider(r,this.rigidBody)),this.colliderId=0):this.collider=t.createCollider(r,this.rigidBody),this.RAPIER=e,this.blendedWorld=t,this.lastColliderUpdateTime=performance.now()}getDepth(t,i,s){const n=new e.Vector2(i.x,i.y);t.setFromCamera(n,s);const r=t.intersectObject(this);if(r.length>0){return r[0].distance}return-1}raycast(e,t){const i=[];return this.downsampledMesh?this.downsampledMesh.raycast(e,i):super.raycast(e,i),i.forEach(e=>{e.object=this}),this.updateVertexNormals||i.forEach(e=>{e.normal&&e.face&&e.normal.copy(e.face.normal)}),t.push(...i),!0}getColliderFromHandle(e){if(this.collider?.handle==e)return this.collider;for(const t of this.colliders)if(t?.handle==e)return t}}class we{constructor(){this.enabled=!1,this.updateVertexNormals=!1,this.showDebugTexture=!1,this.useDepthTexture=!1,this.renderShadow=!1,this.shadowOpacity=.25,this.patchHoles=!1,this.patchHolesUpper=!1,this.opacity=1,this.useDualCollider=!1,this.useDownsampledGeometry=!0,this.updateFullResolutionGeometry=!1,this.colliderUpdateFps=5}}class xe{constructor(e){this.debugging=!1,this.enabled=!1,this.depthMesh=new we,this.depthTexture={enabled:!1,constantKernel:!1,applyGaussianBlur:!1,applyKawaseBlur:!1},this.occlusion={enabled:!1},this.useFloat32=!0,le(this,e)}}const Se=he(new xe({enabled:!0,depthMesh:{enabled:!0,updateVertexNormals:!1,showDebugTexture:!1,useDepthTexture:!1,renderShadow:!1,shadowOpacity:.25,patchHoles:!0,useDownsampledGeometry:!0,updateFullResolutionGeometry:!1,colliderUpdateFps:5}})),be=he(new xe({enabled:!0,depthMesh:{enabled:!0,updateVertexNormals:!0,showDebugTexture:!0,useDepthTexture:!0,renderShadow:!1,shadowOpacity:.25,patchHoles:!0,opacity:.1,useDownsampledGeometry:!0,updateFullResolutionGeometry:!0,colliderUpdateFps:5},depthTexture:{enabled:!0,constantKernel:!0,applyGaussianBlur:!0,applyKawaseBlur:!0}})),Ce=he(new xe({enabled:!0,depthMesh:{enabled:!0,updateVertexNormals:!1,showDebugTexture:!1,useDepthTexture:!1,renderShadow:!0,shadowOpacity:.25,patchHoles:!0,patchHolesUpper:!0,useDualCollider:!1,useDownsampledGeometry:!0,updateFullResolutionGeometry:!1,colliderUpdateFps:5}}));class Te{constructor(e){this.options=e,this.uint16Arrays=[],this.uint8Arrays=[],this.dataTextures=[],this.nativeTextures=[],this.depthData=[]}createDataDepthTextures(t,i){if(this.dataTextures[i]&&this.dataTextures[i].dispose(),this.options.useFloat32){const s=new Uint16Array(t.width*t.height),n=e.RedFormat,r=e.HalfFloatType;this.uint16Arrays[i]=s,this.dataTextures[i]=new e.DataTexture(s,t.width,t.height,n,r)}else{const s=new Uint8Array(t.width*t.height*2),n=e.RGFormat,r=e.UnsignedByteType;this.uint8Arrays[i]=s,this.dataTextures[i]=new e.DataTexture(s,t.width,t.height,n,r)}}updateData(t,i){if((this.dataTextures.length<i+1||this.dataTextures[i].image.width!==t.width||this.dataTextures[i].image.height!==t.height)&&this.createDataDepthTextures(t,i),this.options.useFloat32){const s=new Float32Array(t.data),n=new Uint16Array(s.length);for(let t=0;t<n.length;t++)n[t]=e.DataUtils.toHalfFloat(s[t]);this.uint16Arrays[i].set(n)}else this.uint8Arrays[i].set(new Uint8Array(t.data));this.dataTextures[i].needsUpdate=!0,this.depthData[i]=t}updateNativeTexture(t,i,s){this.dataTextures.length<s+1?this.nativeTextures[s]=new e.ExternalTexture(t.texture):this.nativeTextures[s].sourceTexture=t.texture;const n=i.properties.get(this.nativeTextures[s]);n.__webglTexture=t.texture,n.__version=1}get(e){return this.dataTextures.length>0?this.dataTextures[e]:this.nativeTextures[e]}}const Re={vertexShader:"\n uniform float uBlurSize;\n uniform vec2 uTexelSize;\n varying vec2 vTexCoord;\n varying vec4 uv1;\n varying vec4 uv2;\n varying vec4 uv3;\n varying vec4 uv4;\n\n void vertCopy(vec2 uv) {}\n\n void vertUpsample(vec2 uv) {\n vec2 halfPixel = uTexelSize * 0.5;\n vec2 offset = vec2(uBlurSize);\n uv1.xy = uv + vec2(-halfPixel.x * 2.0, 0.0) * offset;\n uv1.zw = uv + vec2(-halfPixel.x, halfPixel.y) * offset;\n uv2.xy = uv + vec2(0.0, halfPixel.y * 2.0) * offset;\n uv2.zw = uv + halfPixel * offset;\n uv3.xy = uv + vec2(halfPixel.x * 2.0, 0.0) * offset;\n uv3.zw = uv + vec2(halfPixel.x, -halfPixel.y) * offset;\n uv4.xy = uv + vec2(0.0, -halfPixel.y * 2.0) * offset;\n uv4.zw = uv - halfPixel * offset;\n }\n\n void vertDownsample(vec2 uv) {\n vec2 halfPixel = uTexelSize * 0.5;\n vec2 offset = vec2(uBlurSize);\n uv1.xy = uv - halfPixel * offset;\n uv1.zw = uv + halfPixel * offset;\n uv2.xy = uv - vec2(halfPixel.x, -halfPixel.y) * offset;\n uv2.zw = uv + vec2(halfPixel.x, -halfPixel.y) * offset;\n }\n\n void main() {\n vTexCoord = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n if (MODE == 0) {\n vertCopy(uv);\n } else if (MODE == 1) {\n vertDownsample(uv);\n } else {\n vertUpsample(uv);\n }\n }\n",fragmentShader:"\n uniform sampler2D tDiffuse;\n varying vec2 vTexCoord;\n varying vec4 uv1;\n varying vec4 uv2;\n varying vec4 uv3;\n varying vec4 uv4;\n\n vec2 getUV0() {\n return vTexCoord;\n }\n\n vec4 fragCopy() {\n return texture2D(tDiffuse, getUV0());\n }\n\n vec4 fragDownsample() {\n vec4 sum = texture2D(tDiffuse, getUV0()) * 4.0;\n sum += texture2D(tDiffuse, uv1.xy);\n sum += texture2D(tDiffuse, uv1.zw);\n sum += texture2D(tDiffuse, uv2.xy);\n sum += texture2D(tDiffuse, uv2.zw);\n return sum * 0.125;\n }\n\n vec4 fragUpsample() {\n vec4 sum = texture2D(tDiffuse, uv1.xy);\n sum += texture2D(tDiffuse, uv1.zw) * 2.0;\n sum += texture2D(tDiffuse, uv2.xy);\n sum += texture2D(tDiffuse, uv2.zw) * 2.0;\n sum += texture2D(tDiffuse, uv3.xy);\n sum += texture2D(tDiffuse, uv3.zw) * 2.0;\n sum += texture2D(tDiffuse, uv4.xy);\n sum += texture2D(tDiffuse, uv4.zw) * 2.0;\n return sum * 0.0833;\n }\n\n void main(void) {\n if (MODE == 0) {\n gl_FragColor = fragCopy();\n } else if (MODE == 1) {\n gl_FragColor = fragDownsample();\n } else {\n gl_FragColor = fragUpsample();\n }\n }\n"},Me={vertexShader:"\nvarying vec2 vTexCoord;\n\nvoid main() {\n vTexCoord = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}\n ",fragmentShader:"\nprecision mediump float;\n\nuniform sampler2D tDiffuse;\nuniform sampler2D tOcclusionMap;\n\nvarying vec2 vTexCoord;\n\nvoid main(void) {\n vec4 diffuse = texture2D(tDiffuse, vTexCoord);\n vec4 occlusion = texture2D(tOcclusionMap, vTexCoord);\n float occlusionValue = occlusion.r / max(0.0001, occlusion.g);\n occlusionValue = clamp(occlusionValue, 0.0, 1.0);\n gl_FragColor = occlusionValue * diffuse;\n\n gl_FragColor = sRGBTransferOETF( gl_FragColor );\n}\n"},De={vertexShader:"\nvarying vec2 vTexCoord;\n\nvoid main() {\n vTexCoord = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}\n ",fragmentShader:"\n#include <packing>\n\nprecision mediump float;\n\nuniform sampler2D uDepthTexture;\nuniform mat4 uUvTransform;\nuniform float uRawValueToMeters;\nuniform float uAlpha;\nuniform float uViewId;\nuniform bool uFloatDepth;\n\nuniform sampler2D tDiffuse;\nuniform sampler2D tDepth;\nuniform float cameraNear;\nuniform float cameraFar;\n\nvarying vec2 vTexCoord;\n\nfloat DepthGetMeters(in sampler2D depth_texture, in vec2 depth_uv) {\n // Depth is packed into the luminance and alpha components of its texture.\n // The texture is in a normalized format, storing raw values that need to be\n // converted to meters.\n vec2 packedDepthAndVisibility = texture2D(depth_texture, depth_uv).rg;\n if (uFloatDepth) {\n return packedDepthAndVisibility.r * uRawValueToMeters;\n }\n return dot(packedDepthAndVisibility, vec2(255.0, 256.0 * 255.0)) * uRawValueToMeters;\n}\n\nfloat readOrthographicDepth( sampler2D depthSampler, vec2 coord ) {\n float fragCoordZ = texture2D( depthSampler, coord ).x;\n // See https://github.com/mrdoob/three.js/issues/23072.\n #ifdef USE_LOGDEPTHBUF\n float viewZ = 1.0 - exp2(fragCoordZ * log(cameraFar + 1.0) / log(2.0));\n #else\n float viewZ = perspectiveDepthToViewZ(fragCoordZ, cameraNear, cameraFar);\n #endif\n return viewZToOrthographicDepth( viewZ, cameraNear, cameraFar );\n}\n\nvoid main(void) {\n vec4 texCoord = vec4(vTexCoord, 0, 1);\n vec2 uv = texCoord.xy;\n uv.y = 1.0 - uv.y;\n\n vec4 diffuse = texture2D( tDiffuse, texCoord.xy );\n highp float real_depth = DepthGetMeters(uDepthTexture, uv);\n highp float virtual_depth =\n (readOrthographicDepth(tDepth, texCoord.xy ) *\n (cameraFar - cameraNear) + cameraNear);\n gl_FragColor = vec4(step(virtual_depth, real_depth), step(0.001, diffuse.a), 0.0, 0.0);\n}\n"};class Ee extends e.MeshBasicMaterial{constructor(e,t){super(),this.uniforms={uDepthTexture:{value:null},uDepthTextureArray:{value:null},uViewId:{value:0},uIsTextureArray:{value:0},uRawValueToMeters:{value:8/65536},cameraFar:{value:e.far},cameraNear:{value:e.near},uFloatDepth:{value:t},uDepthNear:{value:0}},this.onBeforeCompile=e=>{Object.assign(e.uniforms,this.uniforms),this.uniforms=e.uniforms,e.vertexShader=e.vertexShader.replace("#include <common>",["varying vec2 vTexCoord;","varying float vVirtualDepth;","#include <common>"].join("\n")).replace("#include <fog_vertex>",["#include <fog_vertex>","vec4 view_position = modelViewMatrix * vec4( position, 1.0 );","vVirtualDepth = -view_position.z;","gl_Position = gl_Position / gl_Position.w;","vTexCoord = 0.5 + 0.5 * gl_Position.xy;"].join("\n")),e.fragmentShader=e.fragmentShader.replace("uniform vec3 diffuse;",["uniform vec3 diffuse;","uniform sampler2D uDepthTexture;","uniform sampler2DArray uDepthTextureArray;","uniform float uRawValueToMeters;","uniform float cameraNear;","uniform float cameraFar;","uniform bool uFloatDepth;","uniform bool uIsTextureArray;","uniform float uDepthNear;","uniform int uViewId;","varying vec2 vTexCoord;","varying float vVirtualDepth;"].join("\n")).replace("#include <clipping_planes_pars_fragment>",["#include <clipping_planes_pars_fragment>","\n float DepthGetMeters(in sampler2D depth_texture, in vec2 depth_uv) {\n // Depth is packed into the luminance and alpha components of its texture.\n // The texture is in a normalized format, storing raw values that need to be\n // converted to meters.\n vec2 packedDepthAndVisibility = texture2D(depth_texture, depth_uv).rg;\n if (uFloatDepth) {\n return packedDepthAndVisibility.r * uRawValueToMeters;\n }\n return dot(packedDepthAndVisibility, vec2(255.0, 256.0 * 255.0)) * uRawValueToMeters;\n }\n float DepthArrayGetMeters(in sampler2DArray depth_texture, in vec2 depth_uv) {\n float textureValue = texture(depth_texture, vec3(depth_uv.x, depth_uv.y, uViewId)).r;\n return uRawValueToMeters * uDepthNear / (1.0 - textureValue);\n }\n"].join("\n")).replace("#include <dithering_fragment>",["#include <dithering_fragment>","vec4 texCoord = vec4(vTexCoord, 0, 1);","vec2 uv = vec2(texCoord.x, uIsTextureArray?texCoord.y:(1.0 - texCoord.y));","highp float real_depth = uIsTextureArray ? DepthArrayGetMeters(uDepthTextureArray, uv) : DepthGetMeters(uDepthTexture, uv);","gl_FragColor = vec4(step(vVirtualDepth, real_depth), 1.0, 0.0, 1.0);"].join("\n"))}}}var Pe;!function(e){e[e.COPY=0]="COPY",e[e.DOWN=1]="DOWN",e[e.UP=2]="UP"}(Pe||(Pe={}));class _e extends t{constructor(t,s,n=!0,r=!1,o=3){super(),this.scene=t,this.camera=s,this.renderToScreen=r,this.occludableItemsLayer=o,this.depthTextures=[],this.depthNear=[],this.occlusionMeshMaterial=new Ee(s,n),this.occlusionMapUniforms={uDepthTexture:{value:null},uDepthTextureArray:{value:null},uViewId:{value:0},uIsTextureArray:{value:0},uUvTransform:{value:new e.Matrix4},uRawValueToMeters:{value:8/65536},uAlpha:{value:.75},tDiffuse:{value:null},tDepth:{value:null},uFloatDepth:{value:n},cameraFar:{value:s.far},cameraNear:{value:s.near}},this.occlusionMapQuad=new i(new e.ShaderMaterial({name:"OcclusionMapShader",uniforms:this.occlusionMapUniforms,vertexShader:De.vertexShader,fragmentShader:De.fragmentShader})),this.occlusionMapTexture=new e.WebGLRenderTarget,this.kawaseBlurTargets=[new e.WebGLRenderTarget,new e.WebGLRenderTarget,new e.WebGLRenderTarget],this.kawaseBlurQuads=[this.setupKawaseBlur(Pe.DOWN,this.occlusionMapTexture.texture),this.setupKawaseBlur(Pe.DOWN,this.kawaseBlurTargets[0].texture),this.setupKawaseBlur(Pe.DOWN,this.kawaseBlurTargets[1].texture),this.setupKawaseBlur(Pe.UP,this.kawaseBlurTargets[2].texture),this.setupKawaseBlur(Pe.UP,this.kawaseBlurTargets[1].texture),this.setupKawaseBlur(Pe.UP,this.kawaseBlurTargets[0].texture)],this.occlusionUniforms={tDiffuse:{value:null},tOcclusionMap:{value:this.occlusionMapTexture.texture}},this.occlusionQuad=new i(new e.ShaderMaterial({name:"OcclusionShader",uniforms:this.occlusionUniforms,vertexShader:Me.vertexShader,fragmentShader:Me.fragmentShader})),this.occludableItemsLayer=o}setupKawaseBlur(t,s){const n={uBlurSize:{value:7},uTexelSize:{value:new e.Vector2},tDiffuse:{value:s}},r=new e.ShaderMaterial({name:"Kawase",uniforms:n,vertexShader:Re.vertexShader,fragmentShader:Re.fragmentShader,defines:{MODE:t}});return new i(r)}setDepthTexture(e,t,i,s){this.depthTextures[i]=e,this.occlusionMapUniforms.uRawValueToMeters.value=t,this.occlusionMeshMaterial.uniforms.uRawValueToMeters.value=t,this.depthNear[i]=s,e.needsUpdate=!0}render(t,i,s,n=0){const r=t.getRenderTarget(),o=new e.Vector2;null==s?this.renderOcclusionMapFromScene(t,o,n):this.renderOcclusionMapFromReadBuffer(t,s,o,n),this.blurOcclusionMap(t,o),this.applyOcclusionMapToRenderedImage(t,s,i),t.setRenderTarget(r)}renderOcclusionMapFromScene(t,i,s){const n=this.depthTextures[s],r=n instanceof e.ExternalTexture;this.occlusionMeshMaterial.uniforms.uIsTextureArray.value=r?1:0,this.occlusionMeshMaterial.uniforms.uViewId.value=s,r?(this.occlusionMeshMaterial.uniforms.uDepthTextureArray.value=n,this.occlusionMeshMaterial.uniforms.uDepthNear.value=this.depthNear[s]):this.occlusionMeshMaterial.uniforms.uDepthTexture.value=n,this.scene.overrideMaterial=this.occlusionMeshMaterial,t.getDrawingBufferSize(i),this.occlusionMapTexture.setSize(i.x,i.y);const o=this.occlusionMapTexture;t.setRenderTarget(o);const a=t.xr.getCamera().cameras[s]||this.camera,h=Array.from(Array(32).keys()).filter(e=>a.layers.isEnabled(e));a.layers.set(this.occludableItemsLayer),t.render(this.scene,a),a.layers.disableAll(),h.forEach(e=>{a.layers.enable(e)}),this.scene.overrideMaterial=null}renderOcclusionMapFromReadBuffer(t,i,s,n){this.occlusionMapUniforms.tDiffuse.value=i.texture,this.occlusionMapUniforms.tDepth.value=i.depthTexture;const r=this.depthTextures[n],o=r instanceof e.ExternalTexture;this.occlusionMeshMaterial.uniforms.uIsTextureArray.value=o?1:0,this.occlusionMeshMaterial.uniforms.uViewId.value=n,o?(this.occlusionMeshMaterial.uniforms.uDepthTextureArray.value=r,this.occlusionMeshMaterial.uniforms.uDepthNear.value=this.depthNear[n]):this.occlusionMeshMaterial.uniforms.uDepthTexture.value=r,t.getDrawingBufferSize(s),this.occlusionMapTexture.setSize(s.x,s.y),t.setRenderTarget(this.occlusionMapTexture),this.occlusionMapQuad.render(t)}blurOcclusionMap(e,t){for(let e=0;e<3;e++)this.kawaseBlurTargets[e].setSize(t.x/2**e,t.y/2**e);for(let e=0;e<3;e++)this.kawaseBlurQuads[e].material.uniforms.uTexelSize.value.set(1/(t.x/2**e),1/(t.y/2**e)),this.kawaseBlurQuads[this.kawaseBlurQuads.length-1-e].material.uniforms.uTexelSize.value.set(1/(t.x/2**(e-1)),1/(t.y/2**(e-1)));e.setRenderTarget(this.kawaseBlurTargets[0]),this.kawaseBlurQuads[0].render(e),e.setRenderTarget(this.kawaseBlurTargets[1]),this.kawaseBlurQuads[1].render(e),e.setRenderTarget(this.kawaseBlurTargets[2]),this.kawaseBlurQuads[2].render(e),e.setRenderTarget(this.kawaseBlurTargets[1]),this.kawaseBlurQuads[3].render(e),e.setRenderTarget(this.kawaseBlurTargets[0]),this.kawaseBlurQuads[4].render(e),e.setRenderTarget(this.occlusionMapTexture),this.kawaseBlurQuads[5].render(e)}applyOcclusionMapToRenderedImage(e,t,i){t&&(this.renderToScreen||i)&&(this.occlusionUniforms.tDiffuse.value=t.texture,e.setRenderTarget(i&&!this.renderToScreen?i:null),this.occlusionQuad.render(e))}dispose(){this.occlusionMeshMaterial.dispose(),this.occlusionMapTexture.dispose();for(let e=0;e<this.kawaseBlurQuads.length;e++)this.kawaseBlurQuads[e].dispose()}updateOcclusionMapUniforms(e,t){const i=t.xr.getCamera().cameras[0]||this.camera;e.tOcclusionMap.value=this.occlusionMapTexture.texture,e.uOcclusionClipFromWorld.value.copy(i.projectionMatrix).multiply(i.matrixWorldInverse)}}const Ae=new e.Vector3;class Oe{constructor(){if(this.projectionMatrixInverse=new e.Matrix4,this.view=[],this.cpuDepthData=[],this.gpuDepthData=[],this.depthArray=[],this.options=new xe,this.width=160,this.height=160,this.rawValueToMeters=.0010000000474974513,this.occludableShaders=new Set,this.depthClientsInitialized=!1,this.depthClients=new Set,Oe.instance)return Oe.instance;Oe.instance=this}init(t,i,s,n,r){this.camera=t,this.options=i,this.renderer=s,this.scene=r,this.options.depthTexture.enabled&&(this.depthTextures=new Te(i),n.register(this.depthTextures)),this.options.depthMesh.enabled&&(this.depthMesh=new ye(i,this.width,this.height,this.depthTextures),n.register(this.depthMesh),this.options.depthMesh.renderShadow&&(this.renderer.shadowMap.enabled=!0,this.renderer.shadowMap.type=e.PCFShadowMap),t.add(this.depthMesh),r.add(t)),this.options.occlusion.enabled&&(this.occlusionPass=new _e(r,t))}getDepth(e,t){if(!this.depthArray[0])return 0;const i=Math.round(T(e*this.width,0,this.width-1)),s=Math.round(T((1-t)*this.height,0,this.height-1)),n=this.depthArray[0][s*this.width+i];return this.rawValueToMeters*n}getProjectedDepthViewPositionFromWorldPosition(t,i=new e.Vector3){const s=this.renderer.xr?.getCamera?.()?.cameras?.[0]||this.camera;Ae.copy(t).applyMatrix4(s.matrixWorldInverse).applyMatrix4(s.projectionMatrix);const n=.5*(Ae.x+1),r=.5*(Ae.y+1),o=this.getDepth(n,r);return i.set(2*(n-.5),2*(r-.5),-1),i.applyMatrix4(s.projectionMatrixInverse),i.multiplyScalar((i.z-o)/i.z),i}getVertex(t,i){if(!this.depthArray[0])return null;const s=Math.round(T(t*this.width,0,this.width-1)),n=Math.round(T((1-i)*this.height,0,this.height-1)),r=this.depthArray[0][n*this.width+s],o=this.rawValueToMeters*r,a=new e.Vector3(2*(t-.5),2*(i-.5),-1);return a.applyMatrix4(this.projectionMatrixInverse),a.multiplyScalar(-o/a.z),a}updateCPUDepthData(e,t=0){this.cpuDepthData[t]=e,this.rawValueToMeters=e.rawValueToMeters,this.options.useFloat32&&(this.rawValueToMeters=1),null==this.depthArray[t]?(this.depthArray[t]=this.options.useFloat32?new Float32Array(e.data):new Uint16Array(e.data),this.width=e.width,this.height=e.height):this.depthArray[t].set(this.options.useFloat32?new Float32Array(e.data):new Uint16Array(e.data)),this.options.depthTexture.enabled&&this.depthTextures&&this.depthTextures.updateData(e,t),this.options.depthMesh.enabled&&this.depthMesh&&0==t&&this.depthMesh.updateDepth(e)}updateGPUDepthData(e,t=0){this.gpuDepthData[t]=e,this.rawValueToMeters=e.rawValueToMeters,this.options.useFloat32&&(this.rawValueToMeters=1);const i=this.options.depthMesh.enabled&&this.depthMesh?this.depthMesh.convertGPUToGPU(e):null;i&&(null==this.depthArray[t]?(this.depthArray[t]=this.options.useFloat32?new Float32Array(i.data):new Uint16Array(i.data),this.width=i.width,this.height=i.height):this.depthArray[t].set(this.options.useFloat32?new Float32Array(i.data):new Uint16Array(i.data))),this.options.depthTexture.enabled&&this.depthTextures&&this.depthTextures.updateNativeTexture(e,this.renderer,t),this.options.depthMesh.enabled&&this.depthMesh&&0==t&&(i?this.depthMesh.updateDepth(i):this.depthMesh.updateGPUDepth(e))}getTexture(e){if(this.options.depthTexture.enabled)return this.depthTextures?.get(e)}update(e){this.options.enabled&&(this.updateLocalDepth(e),this.options.occlusion.enabled&&this.renderOcclusionPass())}updateLocalDepth(e){if(fe())return;const t=this.renderer.xr?.getCamera?.()?.cameras?.[0];if(t&&this.depthMesh&&this.depthMesh.parent!=t&&(t.add(this.depthMesh),this.scene.add(t)),!e)return;const i=e.session,s=this.renderer.xr.getBinding();if(void 0!==i.depthActive&&this.depthClientsInitialized){const e=this.depthClients.size>0;if(i.depthActive&&!e?i.pauseDepthSensing?.():!i.depthActive&&e&&i.resumeDepthSensing?.(),0==this.depthClients.size)return}if(null==this.xrRefSpace)i.requestReferenceSpace("local").then(e=>{this.xrRefSpace=e}),i.addEventListener("end",()=>{this.xrRefSpace=void 0});else{const t=e.getViewerPose(this.xrRefSpace);if(t)for(let n=0;n<t.views.length;++n){const r=t.views[n];if(this.view[n]=r,"gpu-optimized"===i.depthUsage){const e=s.getDepthInformation(r);if(!e)return;this.updateGPUDepthData(e,n)}else{const t=e.getDepthInformation(r);if(!t)return;this.updateCPUDepthData(t,n)}}else console.error("Pose unavailable in the current frame.")}}renderOcclusionPass(){const e=this.getTexture(0);e&&this.occlusionPass.setDepthTexture(e,this.rawValueToMeters,0,this.gpuDepthData[0]?.depthNear);const t=this.getTexture(1);t&&this.occlusionPass.setDepthTexture(t,this.rawValueToMeters,1,this.gpuDepthData[1]?.depthNear);const i=this.renderer.xr.isPresenting;this.renderer.xr.isPresenting=!1,this.occlusionPass.render(this.renderer,void 0,void 0,0),this.renderer.xr.isPresenting=i;for(const e of this.occludableShaders)this.occlusionPass.updateOcclusionMapUniforms(e.uniforms,this.renderer)}debugLog(){const e=this.cpuDepthData[0].data,t=new Uint8Array(e),i=Array.from(t,e=>String.fromCharCode(e)).join(""),s=btoa(i);console.log(s)}resumeDepth(e){this.depthClientsInitialized=!0,this.depthClients.add(e)}pauseDepth(e){this.depthClientsInitialized=!0,this.depthClients.delete(e)}}const Ie={depth:1,RGB:4/3},Le={scale:1,scaleX:.75,scaleY:.63,translateU:.2,translateV:-.02,k1:-.046,k2:0,k3:0,p1:0,p2:0,xc:0,yc:0};function Ve(e,t){if(t?.simulatorCamera){const i=window.innerWidth/window.innerHeight,s=t.simulatorCamera.width/t.simulatorCamera.height;let{u:n,v:r}=e;if(i>s){const e=s/i;n=n*e+(1-e)/2}else{const e=i/s;r=r*e+(1-e)/2}return{u:n,v:1-r}}if(!Ie||!Ie.depth||!Ie.RGB)return console.error("Invalid aspect ratios provided."),null;let i,s;Ie.depth>Ie.RGB?(s=1,i=Ie.RGB/Ie.depth):(i=1,s=Ie.depth/Ie.RGB);const n=e.u-.5,r=e.v-.5,o=n-Le.xc,a=r-Le.yc,h=o*o+a*a,l=1+Le.k1*h+Le.k2*h*h+Le.k3*h*h*h;return{u:((o*l+(2*Le.p1*o*a+Le.p2*(h+2*o*o))+Le.xc)*i+Le.translateU)*Le.scale*Le.scaleX+.5,v:1-(((a*l+(Le.p1*(h+2*a*a)+2*Le.p2*o*a)+Le.yc)*s+Le.translateV)*Le.scale*Le.scaleY+.5)}}function Be(t,i,s,n,r,o=Oe.instance){if(!(i&&s&&n&&o))return null;const a=Ve(t,r);if(!a)return null;const{u:h,v:l}=a,c=Math.round(T(h*o.width,0,o.width-1)),d=i[Math.round(T((1-l)*o.height,0,o.height-1))*o.width+c],u=o.rawValueToMeters*d,p=new e.Vector3(2*(h-.5),2*(l-.5),-1),g=s.clone().invert();p.applyMatrix4(g),p.multiplyScalar(-u/p.z);return p.clone().applyMatrix4(n)}async function Fe(t,i){if(!t)throw new Error("No image data provided for cropping.");const s=new Image;await new Promise((e,i)=>{s.onload=e,s.onerror=e=>{console.error("Error loading image for cropping:",e),i(new Error("Failed to load image for cropping."))},s.src=t.startsWith("data:image")?t:`data:image/png;base64,${t}`});const n=document.createElement("canvas"),r=n.getContext("2d"),o=new e.Box2(new e.Vector2(0,0),new e.Vector2(1,1)),a=i.clone().intersect(o),h=new e.Vector2;if(a.getSize(h),0===h.x||0===h.y)return"data:image/png;base64,";const l=s.width*a.min.x,c=s.height*a.min.y,d=s.width*h.x,u=s.height*h.y;return n.width=d,n.height=u,r.drawImage(s,l,c,d,u,0,0,d,u),n.toDataURL("image/png")}var ze;!function(e){e.IDLE="idle",e.INITIALIZING="initializing",e.STREAMING="streaming",e.ERROR="error",e.NO_DEVICES_FOUND="no_devices_found"}(ze||(ze={}));class ke extends S{constructor({willCaptureFrequently:t=!1}={}){super(),this.loaded=!1,this.state=ze.IDLE,this.stream_=null,this.video_=document.createElement("video"),this.frozenTexture_=null,this.canvas_=null,this.context_=null,this.willCaptureFrequently_=t,this.video_.autoplay=!0,this.video_.muted=!0,this.video_.playsInline=!0,this.texture=new e.VideoTexture(this.video_),this.texture.colorSpace=e.SRGBColorSpace,this.texture.minFilter=e.LinearFilter,this.texture.magFilter=e.LinearFilter}setState_(e,t={}){(this.state!==e||t.force)&&(this.state=e,this.dispatchEvent({type:"statechange",state:this.state,...t}),console.debug(`VideoStream state changed to ${e} with details:`,t))}handleVideoStreamLoadedMetadata(e,t,i=!1){try{if(this.video_.videoWidth>0&&this.video_.videoHeight>0)this.width=this.video_.videoWidth,this.height=this.video_.videoHeight,this.aspectRatio=this.width/this.height,this.loaded=!0,e();else if(i)setTimeout(()=>{this.handleVideoStreamLoadedMetadata(e,t,!1)},500);else{const e=new Error("Failed to get valid video dimensions.");this.setState_(ze.ERROR,{error:e}),t(e)}}catch(e){e instanceof Error&&(this.setState_(ze.ERROR,{error:e}),t(e))}}getSnapshot({width:t=this.width,height:i=this.height,outputFormat:s="texture",mimeType:n="image/jpeg",quality:r=.9}={}){if(!this.loaded||!t||!i||this.video_.readyState<this.video_.HAVE_CURRENT_DATA)return null;(t>this.width||i>this.height)&&console.warn(`The requested snapshot width (${t}px x ${i}px) is larger than the source video width (${this.width}px x ${this.height}px). The snapshot will be upscaled.`);try{switch(this.canvas_&&this.canvas_.width===t&&this.canvas_.height===i||(this.canvas_=document.createElement("canvas"),this.canvas_.width=t,this.canvas_.height=i,this.context_=this.canvas_.getContext("2d",{willCaptureFrequently:this.willCaptureFrequently_})),this.context_.drawImage(this.video_,0,0,t,i),s){case"imageData":return this.context_.getImageData(0,0,t,i);case"base64":return this.canvas_.toDataURL(n,r);default:{const t=new e.Texture(this.canvas_);return t.needsUpdate=!0,t.colorSpace=e.SRGBColorSpace,this.frozenTexture_=t,this.frozenTexture_}}}catch(e){return console.error("Error capturing snapshot:",e),null}}stop_(){this.stream_&&(this.stream_.getTracks().forEach(e=>e.stop()),this.stream_=null),this.video_.srcObject&&(this.video_.srcObject=null),this.video_.src&&this.video_.src.startsWith("blob:")&&URL.revokeObjectURL(this.video_.src),this.video_.src="",this.loaded=!1,this.setState_(ze.IDLE)}dispose(){this.stop_(),this.texture?.dispose(),this.frozenTexture_?.dispose(),this.canvas_=null,this.context_=null,super.dispose()}}class je extends ke{constructor({videoConstraints:e={facingMode:"environment"},willCaptureFrequently:t=!1}={}){super({willCaptureFrequently:t}),this.isInitializing_=!1,this.availableDevices_=[],this.currentDeviceIndex_=-1,this.videoConstraints_={...e}}async getAvailableVideoDevices(){if(!navigator.mediaDevices?.enumerateDevices)return console.warn("navigator.mediaDevices.enumerateDevices() is not supported."),[];const e=[...await navigator.mediaDevices.enumerateDevices()];if(this.simulatorCamera){const t=await this.simulatorCamera.enumerateDevices();e.push(...t)}return e.filter(e=>"videoinput"===e.kind)}async init(){this.setState_(ze.INITIALIZING);try{this.availableDevices_=await this.getAvailableVideoDevices(),this.availableDevices_.length>0?await this.initStream_():(this.setState_(ze.NO_DEVICES_FOUND),console.warn("No video devices found."))}catch(e){throw this.setState_(ze.ERROR,{error:e}),console.error("Error initializing XRDeviceCamera:",e),e}}async initStream_(){if(!this.isInitializing_){this.isInitializing_=!0,this.setState_(ze.INITIALIZING),this.currentTrackSettings_=void 0,this.currentDeviceIndex_=-1;try{console.debug("Requesting media stream with constraints:",this.videoConstraints_);let e=null;const t=this.videoConstraints_.deviceId,i="string"==typeof t?t:Array.isArray(t)?t[0]:t?.exact;if(!!this.simulatorCamera&&(i&&"simulator"===this.availableDevices_.find(e=>e.deviceId===i)?.groupId||!i&&"environment"===this.videoConstraints_.facingMode)){if(e=this.simulatorCamera.getMedia(this.videoConstraints_),!e)throw new Error("Simulator camera failed to provide a media stream.")}else e=await navigator.mediaDevices.getUserMedia({video:this.videoConstraints_});const s=e?.getVideoTracks()||[];if(!s.length)throw new Error("MediaStream has no video tracks.");const n=s[0];this.currentTrackSettings_=n.getSettings(),console.debug("Active track settings:",this.currentTrackSettings_),this.currentTrackSettings_.deviceId?this.currentDeviceIndex_=this.availableDevices_.findIndex(e=>e.deviceId===this.currentTrackSettings_.deviceId):console.warn("Stream started without deviceId as it was unavailable"),this.stop_(),this.stream_=e,this.video_.srcObject=e,this.video_.src="",await new Promise((e,t)=>{this.video_.onloadedmetadata=()=>{this.handleVideoStreamLoadedMetadata(e,t,!0)},this.video_.onerror=()=>{const e=new Error("Error playing camera stream.");this.setState_(ze.ERROR,{error:e}),t(e)},this.video_.play()});const r={width:this.width,height:this.height,aspectRatio:this.aspectRatio,device:this.getCurrentDevice(),facingMode:this.currentTrackSettings_.facingMode,trackSettings:this.currentTrackSettings_};this.setState_(ze.STREAMING,r)}catch(e){throw this.setState_(ze.ERROR,{error:e}),e}finally{this.isInitializing_=!1}}}async setDeviceId(e){const t=this.availableDevices_.findIndex(t=>t.deviceId===e);if(-1===t)throw new Error(`Device with ID ${e} not found.`);t!==this.currentDeviceIndex_?(delete this.videoConstraints_.facingMode,this.videoConstraints_.deviceId={exact:e},await this.initStream_()):console.log(`Device ${e} is already active.`)}async setFacingMode(e){delete this.videoConstraints_.deviceId,this.videoConstraints_.facingMode=e,this.currentDeviceIndex_=-1,await this.initStream_()}getAvailableDevices(){return this.availableDevices_}getCurrentDevice(){if(-1!==this.currentDeviceIndex_&&this.availableDevices_.length)return this.availableDevices_[this.currentDeviceIndex_]}getCurrentTrackSettings(){return this.currentTrackSettings_}getCurrentDeviceIndex(){return this.currentDeviceIndex_}registerSimulatorCamera(e){this.simulatorCamera=e,this.init()}}class Ue{constructor(){this.instances=new Map}register(e,t){const i=t??e.constructor;if(!(e instanceof i))throw new Error(`Instance of type '${e.constructor.name}' is not an instance of the registration type '${i.name}'.`);this.instances.set(i,e)}get(e){return this.instances.get(e)}getOrCreate(e,t){let i=this.get(e);if(void 0===i){if(i=t(),!(i instanceof e))throw new Error(`Factory for type ${e.name} returned an incompatible instance of type ${i.constructor.name}.`);this.register(i,e)}return i}unregister(e){this.instances.delete(e)}}function Ne(e,t,i){const s=4*t,n=new Uint8Array(s);for(let t=0;t<i/2;t++){const r=t*s,o=(i-1-t)*s;n.set(e.subarray(r,r+s)),e.set(e.subarray(o,o+s),r),e.set(n,o)}}class Ge{constructor(e,t,i){this.resolve=e,this.reject=t,this.overlayOnCamera=i}}class He{constructor(){this.pendingScreenshotRequests=[],this.virtualBuffer=new Uint8Array,this.virtualRealBuffer=new Uint8Array,this.renderTargetWidth=640}async onAfterRender(e,t,i){if(0==this.pendingScreenshotRequests.length)return;this.pendingScreenshotRequests.every(e=>!e.overlayOnCamera)&&this.createVirtualImageDataURL(e,t).then(e=>{this.resolveVirtualOnlyRequests(e)});const s=this.pendingScreenshotRequests.some(e=>e.overlayOnCamera);if(s&&i)this.createVirtualRealImageDataURL(e,t,i).then(e=>{e&&this.resolveVirtualRealRequests(e)});else if(s)throw new Error("No device camera provided")}async createVirtualImageDataURL(t,i){const s=t.getRenderTarget(),n=t.xr.isPresenting&&2==t.xr.getCamera().cameras.length?s.width/2:s.width,r=Math.round(s.height*(this.renderTargetWidth/n));this.virtualRenderTarget&&this.virtualRenderTarget.width==this.renderTargetWidth||(this.virtualRenderTarget?.dispose(),this.virtualRenderTarget=new e.WebGLRenderTarget(this.renderTargetWidth,r,{colorSpace:e.SRGBColorSpace}));const o=t.xr.isPresenting;t.xr.isPresenting=!1;const a=this.virtualRenderTarget;t.setRenderTarget(a),t.clearColor(),t.clearDepth(),i(),t.setRenderTarget(s),t.xr.isPresenting=o;const h=a.width*a.height*4;this.virtualBuffer.length!=h&&(this.virtualBuffer=new Uint8Array(h));const l=this.virtualBuffer;await t.readRenderTargetPixelsAsync(a,0,0,a.width,a.height,l),Ne(l,a.width,a.height);const c=this.virtualCanvas||(this.virtualCanvas=document.createElement("canvas"));c.width=a.width,c.height=a.height;const d=c.getContext("2d");if(!d)throw new Error("Failed to get 2D context");const u=new ImageData(new Uint8ClampedArray(l),a.width,a.height);return d.putImageData(u,0,0),c.toDataURL()}resolveVirtualOnlyRequests(e){let t=0;for(let i=0;i<this.pendingScreenshotRequests.length;i++){const s=this.pendingScreenshotRequests[i];s.overlayOnCamera?this.pendingScreenshotRequests[t++]=s:s.resolve(e)}this.pendingScreenshotRequests.length=t}async createVirtualRealImageDataURL(t,i,s){if(!s.loaded)return console.debug("Waiting for device camera to be loaded"),null;const n=t.getRenderTarget(),r=t.xr.isPresenting&&2==t.xr.getCamera().cameras.length,o=new e.Vector2;n?o.set(n.width,n.height):t.getSize(o);const a=r?o.x/2:o.y,h=Math.round(o.y*(this.renderTargetWidth/a));this.virtualRealRenderTarget&&this.virtualRealRenderTarget.height==h||(this.virtualRealRenderTarget?.dispose(),this.virtualRealRenderTarget=new e.WebGLRenderTarget(this.renderTargetWidth,h,{colorSpace:e.SRGBColorSpace}));const l=this.virtualRealRenderTarget;t.setRenderTarget(l);const c=t.xr.isPresenting;t.xr.isPresenting=!1;const d=this.getFullScreenQuad();d.material.map=s.texture,d.render(t),i(),t.xr.isPresenting=c,t.setRenderTarget(n),this.virtualRealBuffer.length!=l.width*l.height*4&&(this.virtualRealBuffer=new Uint8Array(l.width*l.height*4));const u=this.virtualRealBuffer;await t.readRenderTargetPixelsAsync(l,0,0,l.width,l.height,u),Ne(u,l.width,l.height);const p=this.virtualRealCanvas||(this.virtualRealCanvas=document.createElement("canvas"));p.width=l.width,p.height=l.height;const g=p.getContext("2d");if(!g)throw new Error("Failed to get 2D context");const m=new ImageData(new Uint8ClampedArray(u),l.width,l.height);return g.putImageData(m,0,0),p.toDataURL()}resolveVirtualRealRequests(e){let t=0;for(let i=0;i<this.pendingScreenshotRequests.length;i++){const s=this.pendingScreenshotRequests[i];s.overlayOnCamera?s.resolve(e):this.pendingScreenshotRequests[t++]=s}this.pendingScreenshotRequests.length=t}getFullScreenQuad(){return this.fullScreenQuad||(this.fullScreenQuad=new i(new e.MeshBasicMaterial({transparent:!0}))),this.fullScreenQuad}async getScreenshot(e=!1){return new Promise((t,i)=>{this.pendingScreenshotRequests.push(new Ge(t,i,e))})}}class We{constructor(e){this.initScriptFunction=e,this.scripts=new Set,this.callSelectStartBound=this.callSelectStart.bind(this),this.callSelectEndBound=this.callSelectEnd.bind(this),this.callSelectBound=this.callSelect.bind(this),this.callSqueezeStartBound=this.callSqueezeStart.bind(this),this.callSqueezeEndBound=this.callSqueezeEnd.bind(this),this.callSqueezeBound=this.callSqueeze.bind(this),this.callKeyDownBound=this.callKeyDown.bind(this),this.callKeyUpBound=this.callKeyUp.bind(this),this.initializingScripts=new Set}async initScript(e){this.scripts.has(e)||this.initializingScripts.has(e)||(this.initializingScripts.add(e),await this.initScriptFunction(e),this.scripts.add(e),this.initializingScripts.delete(e))}uninitScript(e){this.scripts.has(e)&&(e.dispose(),this.scripts.delete(e),this.initializingScripts.delete(e))}async syncScriptsWithScene(e){const t=new Set,i=[];e.traverse(e=>{if(e.isXRScript){const s=e;i.push(this.initScript(s)),t.add(s)}}),await Promise.allSettled(i);for(const e of this.scripts)t.has(e)||this.uninitScript(e)}callSelectStart(e){for(const t of this.scripts)t.onSelectStart(e)}callSelectEnd(e){for(const t of this.scripts)t.onSelectEnd(e)}callSelect(e){for(const t of this.scripts)t.onSelect(e)}callSqueezeStart(e){for(const t of this.scripts)t.onSqueezeStart(e)}callSqueezeEnd(e){for(const t of this.scripts)t.onSqueezeEnd(e)}callSqueeze(e){for(const t of this.scripts)t.onSqueeze(e)}callKeyDown(e){for(const t of this.scripts)t.onKeyDown(e)}callKeyUp(e){for(const t of this.scripts)t.onKeyUp(e)}onXRSessionStarted(e){for(const t of this.scripts)t.onXRSessionStarted(e)}onXRSessionEnded(){for(const e of this.scripts)e.onXRSessionEnded()}onSimulatorStarted(){for(const e of this.scripts)e.onSimulatorStarted()}}class qe{constructor(){this.callbacks=[]}onFrame(){this.callbacks.forEach(e=>{try{e()}catch(e){console.error(e)}}),this.callbacks.length=0}async waitFrame(){return new Promise(e=>{this.callbacks.push(e)})}}var Xe;!function(e){e.UNSUPPORTED="unsupported",e.READY="ready",e.SESSION_START="sessionstart",e.SESSION_END="sessionend"}(Xe||(Xe={}));class Ke extends e.EventDispatcher{constructor(e,t,i){super(),this.renderer=e,this.sessionInit=t,this.mode=i,this.onSessionEndedBound=this.onSessionEndedInternal.bind(this)}async initialize(){if(!("xr"in navigator))return console.warn("WebXR not supported"),this.xrModeSupported=!1,void this.dispatchEvent({type:Xe.UNSUPPORTED});let e=!1;try{e=await navigator.xr.isSessionSupported(this.mode)||!1}catch(e){return console.error("Error getting isSessionSupported",e),this.xrModeSupported=!1,void this.dispatchEvent({type:Xe.UNSUPPORTED})}e?(this.xrModeSupported=!0,this.sessionOptions={...this.sessionInit,optionalFeatures:["local-floor",...this.sessionInit.optionalFeatures||[]]},this.dispatchEvent({type:Xe.READY,sessionOptions:this.sessionOptions}),void 0!==navigator.xr.offerSession&&navigator.xr.offerSession(this.mode,this.sessionOptions).then(this.onSessionStartedInternal.bind(this)).catch(e=>{console.warn(e)})):(console.log(`${this.mode} not supported`),this.xrModeSupported=!1,this.dispatchEvent({type:Xe.UNSUPPORTED}))}startSession(){if(void 0===this.xrModeSupported)throw new Error("Initialize not yet complete");if(!this.xrModeSupported)throw new Error("WebXR not supported");if(this.currentSession)throw new Error("Session already started");navigator.xr.requestSession(this.mode,this.sessionOptions).then(this.onSessionStartedInternal.bind(this))}endSession(){if(!this.currentSession)throw new Error("No session to end");this.currentSession.end(),this.currentSession=void 0}isXRSupported(){return this.xrModeSupported}async onSessionStartedInternal(e){e.addEventListener("end",this.onSessionEndedBound),await this.renderer.xr.setSession(e),this.currentSession=e,this.dispatchEvent({type:Xe.SESSION_START,session:e})}onSessionEndedInternal(){this.dispatchEvent({type:Xe.SESSION_END}),this.currentSession?.removeEventListener("end",this.onSessionEndedBound),this.currentSession=void 0}}const $e="XRButton";class Qe{constructor(e,t="ENTER XR",i="END XR",s="XR NOT SUPPORTED",n="START SIMULATOR",r=!1,o=!1,a=()=>{}){this.sessionManager=e,this.startText=t,this.endText=i,this.invalidText=s,this.startSimulatorText=n,this.startSimulator=a,this.domElement=document.createElement("div"),this.simulatorButtonElement=document.createElement("button"),this.xrButtonElement=document.createElement("button"),this.domElement.id="XRButtonWrapper",this.createXRButtonElement(),r&&(fe()||o)&&this.createSimulatorButton(),this.sessionManager.addEventListener(Xe.UNSUPPORTED,this.showXRNotSupported.bind(this)),this.sessionManager.addEventListener(Xe.READY,()=>this.onSessionReady()),this.sessionManager.addEventListener(Xe.SESSION_START,()=>this.onSessionStarted()),this.sessionManager.addEventListener(Xe.SESSION_END,this.onSessionEnded.bind(this))}createSimulatorButton(){this.simulatorButtonElement.classList.add($e),this.simulatorButtonElement.innerText=this.startSimulatorText,this.simulatorButtonElement.onclick=()=>{this.domElement.remove(),this.startSimulator()},this.domElement.appendChild(this.simulatorButtonElement)}createXRButtonElement(){this.xrButtonElement.classList.add($e),this.xrButtonElement.disabled=!0,this.xrButtonElement.textContent="...",this.domElement.appendChild(this.xrButtonElement)}onSessionReady(){const e=this.xrButtonElement;e.style.display="",e.innerHTML=this.startText,e.disabled=!1,e.onclick=()=>{this.sessionManager.startSession()}}showXRNotSupported(){this.xrButtonElement.textContent=this.invalidText,this.xrButtonElement.disabled=!0}async onSessionStarted(){this.xrButtonElement.innerHTML=this.endText}onSessionEnded(){this.xrButtonElement.innerHTML=this.startText}}class Ye extends t{render(e,t,i,s,n,r=0){}}class Je{constructor(t,i,s){this.renderer=t,this.scene=i,this.timer=s,this.passes=[],this.renderTargets=[],this.dimensions=new e.Vector2}addPass(e){e.renderToScreen=!1,this.passes.push(e)}setupRenderTargets(t){const i=this.renderer.getRenderTarget();if(null==i)return;const s=this.renderer.xr.isPresenting?4:2;for(let n=0;n<s;n++)(n>=this.renderTargets.length||this.renderTargets[n].width!=t.x||this.renderTargets[n].height!=t.y)&&(this.renderTargets[n]?.depthTexture?.dispose(),this.renderTargets[n]?.dispose(),this.renderTargets[n]=i.clone(),this.renderTargets[n].depthTexture=new e.DepthTexture(t.x,t.y));for(let e=s;e<this.renderTargets.length;e++)this.renderTargets[e].depthTexture?.dispose(),this.renderTargets[e].dispose()}render(){this.renderer.getDrawingBufferSize(this.dimensions),this.setupRenderTargets(this.dimensions),this.renderer.xr.cameraAutoUpdate=!1;this.renderer.getRenderTarget()&&(this.renderer.xr.isPresenting?this.renderXr():this.renderSimulator())}renderXr(){const t=this.renderer.getRenderTarget(),i=this.renderer,s=i.xr.enabled,n=i.xr.isPresenting,r=this.renderTargets,o=new e.Vector4;i.getViewport(o),i.xr.cameraAutoUpdate=!1,i.xr.enabled=!1;const a=this.timer.getDelta();if(2==i.xr.getCamera().cameras.length){for(let e=0;e<2;++e){const t=i.xr.getCamera().cameras[e];i.setViewport(t.viewport),i.setRenderTarget(r[e]),i.clear(),i.xr.isPresenting=!0,i.render(this.scene,t)}i.setRenderTarget(t),i.clear(),i.xr.isPresenting=!1,i.autoClearColor=!1;for(let e=0;e<2;e++){for(let s=0;s<this.passes.length-1;++s){const n=s%2,r=(s+1)%2;t.viewport.set(e*this.dimensions.x/2,0,this.dimensions.x/2,this.dimensions.y),this.passes[s].render(i,this.renderTargets[2*r+e],this.renderTargets[2*n+e],a,!1,e)}if(this.passes.length>0){const s=(this.passes.length-1)%2;t.viewport.set(e*this.dimensions.x/2,0,this.dimensions.x/2,this.dimensions.y),this.passes[this.passes.length-1].render(i,t,this.renderTargets[2*s+e],a,!1,e)}}i.xr.enabled=s,i.xr.isPresenting=n}}renderSimulator(){const t=this.renderer.getRenderTarget(),i=this.renderer,s=i.xr.enabled,n=i.xr.isPresenting,r=new e.Vector4;i.getViewport(r),i.xr.cameraAutoUpdate=!1,i.xr.enabled=!1;const o=this.timer.getDelta();i.setRenderTarget(t),i.clear(),i.xr.isPresenting=!1,i.autoClearColor=!1;for(let e=0;e<this.passes.length-1;++e){const t=e%2,s=(e+1)%2;this.passes[e].render(i,this.renderTargets[s],this.renderTargets[t],o,!1,0)}if(this.passes.length>0){const e=(this.passes.length-1)%2;this.passes[this.passes.length-1].render(i,t,this.renderTargets[e],o,!1,0)}i.xr.enabled=s,i.xr.isPresenting=n}}const Ze=["wrist","thumb-metacarpal","thumb-phalanx-proximal","thumb-phalanx-distal","thumb-tip","index-finger-metacarpal","index-finger-phalanx-proximal","index-finger-phalanx-intermediate","index-finger-phalanx-distal","index-finger-tip","middle-finger-metacarpal","middle-finger-phalanx-proximal","middle-finger-phalanx-intermediate","middle-finger-phalanx-distal","middle-finger-tip","ring-finger-metacarpal","ring-finger-phalanx-proximal","ring-finger-phalanx-intermediate","ring-finger-phalanx-distal","ring-finger-tip","pinky-finger-metacarpal","pinky-finger-phalanx-proximal","pinky-finger-phalanx-intermediate","pinky-finger-phalanx-distal","pinky-finger-tip"];var et;!function(e){e[e.NONE=-1]="NONE",e[e.LEFT=0]="LEFT",e[e.RIGHT=1]="RIGHT"}(et||(et={}));class tt{constructor(e){this.hands=e,this.dominant=et.RIGHT}getJoint(e,t){let i=t;i===et.NONE&&(i=this.dominant);const s=this.hands[i];if(s){if(s.joints&&e in s.joints)return s.joints[e]}else console.log("no hand")}getIndexTip(e=et.NONE){return this.getJoint("index-finger-tip",e)}getThumbTip(e=et.NONE){return this.getJoint("thumb-tip",e)}getMiddleTip(e=et.NONE){return this.getJoint("middle-finger-tip",e)}getRingTip(e=et.NONE){return this.getJoint("ring-finger-tip",e)}getPinkyTip(e=et.NONE){return this.getJoint("pinky-finger-tip",e)}getWrist(e=et.NONE){return this.getJoint("wrist",e)}toString(){let e="";return[et.LEFT,et.RIGHT].forEach(t=>{const i=this.hands[t];i&&i.joints?Ze.forEach(s=>{const n=i.joints[s];n?n.position?e+=`${t} - ${s}: ${n.position.x.toFixed(3)}, ${n.position.y.toFixed(3)}, ${n.position.z.toFixed(3)}\n`:e+=`${t} - ${s}: Position unavailable\n`:e+=`${t} - ${s}: Joint unavailable\n`}):e+=`${t} Hand: Data unavailable\n`}),e}toPositionQuaternionArray(){const e=[],t=[et.LEFT,et.RIGHT],i=Ze.length;t.forEach(t=>{const i=this.hands[t],s=i&&i.joints;Ze.forEach(t=>{const n=s?i.joints[t]:null;if(n&&n.position&&n.quaternion)e.push(n.position.x,n.position.y,n.position.z),e.push(n.quaternion.x,n.quaternion.y,n.quaternion.z,n.quaternion.w);else for(let t=0;t<7;t++)e.push(0)})});const s=t.length*i*7;if(e.length!==s)for(console.error(`XRHands.toPositionQuaternionArray: Output array size mismatch. Expected ${s}, got ${e.length}. Padding with zeros.`);e.length<s;)e.push(0);return e}isValid(e){return!(!this.hands||!Array.isArray(this.hands)||2!==this.hands.length)&&(0===e||1===e?!!this.hands[e]:!!this.hands[et.LEFT]&&!!this.hands[et.RIGHT])}}const it={uniforms:{uColor:{value:(new e.Color).setHex(16777215)},uPressed:{value:0}},vertexShader:"\n varying vec2 vTexCoord;\n\n void main() {\n vTexCoord = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n // Makes the position slightly closer to avoid z fighting.\n gl_Position.z -= 0.1;\n }\n",fragmentShader:'\n precision mediump float;\n\n uniform sampler2D uDepthTexture;\n uniform vec3 uColor;\n uniform float uPressed;\n\n varying vec2 vTexCoord;\n\n void main(void) {\n // Distance from center of quad.\n highp float dist = distance(vTexCoord, vec2(0.5f, 0.5f));\n if (dist > 0.45) discard;\n\n // Get the rate of change of dist on x and y.\n highp vec2 dist_grad = vec2(dFdx(dist), dFdy(dist));\n highp float grad_magnitude = length(dist_grad);\n highp float antialias_dist = max(grad_magnitude, 0.001f);\n\n // Outer radius is 0.5, but we want to bring it in a few pixels so we have room\n // for a gradient outward to anti-alias the circle.\n // These "few pixels" are determined by our derivative calculation above.\n highp float outerradius = 0.5f - antialias_dist;\n highp float delta_to_outer = dist - outerradius;\n highp float clamped_outer_delta = clamp(delta_to_outer, 0.0f, antialias_dist);\n highp float outer_alpha = 1.0f - (clamped_outer_delta / antialias_dist);\n\n // #FFFFFF = (1,1,1)\n // #FFFFFF with 0.5 alpha = (((1,1,1) * 0.5), 0.5)\n vec4 inner_base_color = vec4(0.5 * uColor, 0.5);\n vec4 pressed_inner_color = vec4(uColor, 1.0);\n // #505050 = (0.077,0.077,0.077)\n // #505050 with 0.7 alpha = (((0.077,0.077,0.077)*0.7), 0.7)\n const vec4 inner_gradient_color = vec4(0.054, 0.054, 0.054, 1.0);\n const vec4 outer_ring_color = vec4(0.077, 0.077, 0.077, 1.0);\n // 0.5 - stoke_width (0.75dp = 0.04 approx)\n const float gradient_end = 0.46;\n // 73% of gradient_end\n const float gradient_start = 0.33;\n // gradient_end - 130% stoke_width. Additional 30% to account for the down scaling.\n const float pressed_inner_radius = 0.41;\n\n vec4 unpressed_inner_color =\n mix(inner_base_color, inner_gradient_color,\n smoothstep(gradient_start, gradient_end, dist));\n vec4 unpressed_color =\n mix(unpressed_inner_color, outer_ring_color,\n step(gradient_end, dist));\n\n // Builds a smooth gradient to fade between colors.\n highp float smooth_distance = antialias_dist * 4.0;\n float percent_to_inner_rad = max(pressed_inner_radius - dist, 0.0) / pressed_inner_radius;\n highp float pressed_color_t = 1.0 - percent_to_inner_rad;\n pressed_color_t -= (1.0 - smooth_distance);\n pressed_color_t *= (1.0 / smooth_distance);\n pressed_color_t = clamp(pressed_color_t, 0.0, 1.0);\n vec4 pressed_color = mix(pressed_inner_color, outer_ring_color, pressed_color_t);\n\n vec4 final_color = mix(unpressed_color, pressed_color, uPressed);\n gl_FragColor = final_color * outer_alpha;\n // Converts to straight alpha.\n gl_FragColor.rgb = gl_FragColor.rgb / max(gl_FragColor.a, 0.001);\n }\n'};class st extends e.Mesh{constructor(t=.8,i=.001,s=.019,n=!1){const r=new e.CircleGeometry(s,32);r.applyMatrix4((new e.Matrix4).makeTranslation(0,0,i)),super(r,new e.ShaderMaterial({uniforms:e.UniformsUtils.clone(it.uniforms),vertexShader:it.vertexShader,fragmentShader:it.fragmentShader,depthTest:n,transparent:!0})),this.name="Reticle",this.ignoreReticleRaycast=!0,this.direction=new e.Vector3,this.renderOrder=1e3,this.originalNormal=new e.Vector3(0,0,1),this.newRotation=new e.Quaternion,this.objectRotation=new e.Quaternion,this.normalVector=new e.Vector3,this.rotationSmoothing=t,this.offset=i}setRotationFromNormalVector(e){const t=this.originalNormal.angleTo(e);this.originalNormal.cross(e).normalize(),this.newRotation.setFromAxisAngle(this.originalNormal,t),this.originalNormal.set(0,0,1),this.quaternion.slerp(this.newRotation,1-this.rotationSmoothing)}setPoseFromIntersection(e){e&&e.normal&&(this.intersection=e,this.position.copy(e.point),e.object.getWorldQuaternion(this.objectRotation),this.normalVector.copy(e.normal).applyQuaternion(this.objectRotation),this.setRotationFromNormalVector(this.normalVector))}setColor(e){this.material.uniforms.uColor.value.set(e)}getColor(){return this.material.uniforms.uColor.value}setPressed(e){this.material.uniforms.uPressed.value=e?1:0,this.scale.setScalar(e?.7:1)}setPressedAmount(e){this.material.uniforms.uPressed.value=e,this.scale.setScalar(R(1,.7,e))}raycast(){}}class nt extends e.Line{constructor(){super((new e.BufferGeometry).setFromPoints([new e.Vector3(0,0,0),new e.Vector3(0,0,-1)])),this.scale.z=5}raycast(){}}class rt{constructor(e=0,t=0,i=1,s=1){this.value=e,this.minValue=t,this.maxValue=i,this.speed=s}update(e){this.value=T(this.value+e*this.speed,this.minValue,this.maxValue)}}class ot extends S{constructor(){super(...arguments),this.userData={connected:!1,id:2,selected:!1},this.reticle=new st,this.activationTimeSeconds=1.5,this.activationAmount=new rt(0,0,1,1/this.activationTimeSeconds),this.lastReticlePosition=new e.Vector3,this.clock=new e.Clock}static{this.dependencies={camera:e.Camera}}init({camera:e}){this.camera=e}update(){super.update(),this.position.copy(this.camera.position),this.quaternion.copy(this.camera.quaternion),this.updateMatrixWorld();const e=this.clock.getDelta();this.activationAmount.update(e);this.lastReticlePosition.distanceTo(this.reticle.position)/e>.2&&(this.activationAmount.value=0,this.userData.selected&&this.callSelectEnd(),this.userData.selected=!1),1!=this.activationAmount.value||this.userData.selected||this.callSelectStart(),this.updateReticleScale(),this.lastReticlePosition.copy(this.reticle.position)}updateReticleScale(){this.reticle.setPressedAmount(this.activationAmount.value)}callSelectStart(){this.dispatchEvent({type:"selectstart",target:this})}callSelectEnd(){this.dispatchEvent({type:"selectend",target:this})}connect(){this.dispatchEvent({type:"connected",target:this})}disconnect(){this.dispatchEvent({type:"disconnected",target:this})}}class at extends S{static{this.dependencies={camera:e.Camera}}constructor(){super(),this.userData={id:3,connected:!1,selected:!1},this.raycaster=new e.Raycaster,this.forwardVector=new e.Vector3(0,0,-1)}init({camera:e}){this.camera=e}update(){super.update(),this.userData.connected&&this.position.copy(this.camera.position)}updateMousePositionFromEvent(t){this.position.copy(this.camera.position);const i=new e.Vector2;i.x=t.clientX/window.innerWidth*2-1,i.y=-t.clientY/window.innerHeight*2+1,this.raycaster.setFromCamera(i,this.camera);const s=this.raycaster.ray.direction;this.quaternion.setFromUnitVectors(this.forwardVector,s),this.updateMatrixWorld()}callSelectStart(){this.dispatchEvent({type:"selectstart",target:this})}callSelectEnd(){this.dispatchEvent({type:"selectend",target:this})}connect(){this.dispatchEvent({type:"connected",target:this})}disconnect(){this.dispatchEvent({type:"disconnected",target:this})}}class ht extends e.Object3D{}const lt=new e.Matrix4;class ct{constructor(){this.controllers=[],this.controllerGrips=[],this.hands=[],this.raycaster=new e.Raycaster,this.initialized=!1,this.pivotsEnabled=!1,this.gazeController=new ot,this.mouseController=new at,this.controllersEnabled=!0,this.listeners=new Map,this.intersectionsForController=new Map,this.intersections=[],this.activeControllers=new ht}init({scene:e,options:t,renderer:i}){e.add(this.activeControllers),this.options=t,this.scene=e;const r=this.controllers,o=this.controllerGrips;for(let e=0;e<2;++e)r.push(i.xr.getController(e)),r[e].userData.id=e,this.activeControllers.add(this.controllers[e]);r.push(this.gazeController),r.push(this.mouseController),this.activeControllers.add(this.mouseController);for(const e of r)this.intersectionsForController.set(e,[]);if(t.controllers.enabled){if(t.controllers.visualization){const e=new s;for(let t=0;t<2;++t)o.push(i.xr.getControllerGrip(t)),o[t].add(e.createControllerModel(o[t])),this.activeControllers.add(o[t])}if(t.hands.enabled){for(let e=0;e<2;++e)this.hands.push(i.xr.getHand(e)),this.activeControllers.add(this.hands[e]);if(t.hands.visualization){if(t.hands.visualizeJoints){console.log("Visualize hand joints.");const e=new n;for(let t=0;t<2;++t){const i=e.createHandModel(this.hands[t],"boxes");i.ignoreReticleRaycast=!0,this.hands[t].add(i)}}if(t.hands.visualizeMeshes){console.log("Visualize hand meshes.");const e=new n;for(let t=0;t<2;++t){const i=e.createHandModel(this.hands[t],"mesh");i.ignoreReticleRaycast=!0,this.hands[t].add(i)}}}}}if(t.controllers.visualizeRays)for(let e=0;e<2;++e)r[e].add(new nt);this.bindSelectStart(this.defaultOnSelectStart.bind(this)),this.bindSelectEnd(this.defaultOnSelectEnd.bind(this)),this.bindSqueezeStart(this.defaultOnSelectStart.bind(this)),this.bindSqueezeEnd(this.defaultOnSelectEnd.bind(this)),this.bindListener("connected",this.defaultOnConnected.bind(this)),this.bindListener("disconnected",this.defaultOnDisconnected.bind(this))}get(e){return this.controllers[e]}addObject(t){const i=new e.Group;i.add(t);for(let e=0;e<this.controllers.length;++e)this.controllers[e].add(i.clone())}enablePivots(){if(this.pivotsEnabled)return;this.pivotsEnabled=!0;const t=new e.Mesh(new e.IcosahedronGeometry(.01,3));t.name="pivot",t.position.z=-.05,this.addObject(t)}addReticles(){let e=0;for(const t of this.controllers)null==t.reticle&&(t.reticle=new st,t.reticle.name="Reticle "+e,++e),t.reticle.visible=!1,this.scene.add(t.reticle)}defaultOnSelectStart(e){const t=e.target;t.userData.selected=!0,this._setRaycasterFromController(t),this.performRaycastOnScene(t)}defaultOnSelectEnd(e){e.target.userData.selected=!1}defaultOnSqueezeStart(e){e.target.userData.squeezing=!0}defaultOnSqueezeEnd(e){e.target.userData.squeezing=!1}defaultOnConnected(e){const t=e.target;switch(t.userData.connected=!0,t.gamepad=e.data?.gamepad,t.inputSource=e.data,e.data?.handedness){case"left":this.leftController=t;break;case"right":this.rightController=t}}defaultOnDisconnected(e){const t=e.target;switch(t.userData.connected=!1,t.reticle&&(t.reticle.visible=!1),delete t?.gamepad,e.data?.handedness){case"left":this.leftController=void 0;break;case"right":this.rightController=void 0}}bindListener(e,t){for(const i of this.controllers)i.addEventListener(e,t);this.listeners.has(e)||this.listeners.set(e,[]),this.listeners.get(e).push(t)}unbindListener(e,t){if(this.listeners.has(e)){const i=this.listeners.get(e),s=i.indexOf(t);-1!==s&&i.splice(s,1)}for(const i of this.controllers)i.removeEventListener(e,t)}dispatchEvent(e){if(this.listeners.has(e.type))for(const t of this.listeners.get(e.type))t(e)}bindSelectStart(e){this.bindListener("selectstart",e)}bindSelectEnd(e){this.bindListener("selectend",e)}bindSelect(e){this.bindListener("select",e)}bindSqueezeStart(e){this.bindListener("squeezestart",e)}bindSqueezeEnd(e){this.bindListener("squeezeend",e)}bindSqueeze(e){this.bindListener("squeeze",e)}bindKeyDown(e){window.addEventListener("keydown",e)}bindKeyUp(e){window.addEventListener("keyup",e)}unbindKeyDown(e){window.removeEventListener("keydown",e)}unbindKeyUp(e){window.removeEventListener("keyup",e)}intersectObjectByController(e,t){return e.updateMatrixWorld(),this._setRaycasterFromController(e),this.raycaster.intersectObject(t,!1)}intersectObjectByEvent(e,t){return this.intersectObjectByController(e.target,t)}intersectObject(e){const t=this.intersectObjectByController(this.controllers[0],e);return t.length>0?t:this.intersectObjectByController(this.controllers[1],e)}update(){if(this.controllersEnabled)for(const e of this.controllers)this.updateController(e)}updateController(e){!1!==e.userData.connected&&(e.updateMatrixWorld(),this._setRaycasterFromController(e),this.performRaycastOnScene(e),this.updateReticleFromIntersections(e))}_setRaycasterFromController(e){e.getWorldPosition(this.raycaster.ray.origin),lt.identity().extractRotation(e.matrixWorld),this.raycaster.ray.direction.set(0,0,-1).applyMatrix4(lt).normalize()}updateReticleFromIntersections(e){if(!e.reticle)return;const t=e.reticle,i=this.intersectionsForController.get(e)?.find(e=>{let t=e.object;for(;t;){if(!0===t.ignoreReticleRaycast)return!1;t=t.parent}return!0});i?(t.visible=!0,i.object?.isXRScript?i.object.ux.update(e,i):i.object?.parent?.isXRScript&&i.object.parent.ux.update(e,i),t.intersection=i,t.direction.copy(this.raycaster.ray.direction).normalize(),t.setPoseFromIntersection(i),t.setPressed(e.userData.selected)):t.visible=!1}enableGazeController(){this.activeControllers.add(this.gazeController),this.gazeController.connect()}disableGazeController(){this.gazeController.disconnect(),this.activeControllers.remove(this.gazeController)}disableControllers(){this.controllersEnabled=!1;for(const e of this.controllers)e.userData.selected=!1,e.reticle&&(e.reticle.visible=!1,e.reticle.targetObject=void 0)}enableControllers(){this.controllersEnabled=!0}performRaycastOnScene(e){this.intersectionsForController.has(e)||this.intersectionsForController.set(e,[]);const t=this.intersectionsForController.get(e);t.length=0,this.raycaster.intersectObject(this.scene,!0,t)}}function dt(e,t){let i=e;for(;i;){if(i===t)return!0;i=i.parent}return!1}function ut(e,t){if(t(e))return!0;for(const i of e.children)if(ut(i,t))return!0;return!1}class pt extends S{static{this.dependencies={input:ct,scene:e.Scene}}constructor(){super(),this.local=!0,this.numHands=2,this.height=1.6,this.panelDistance=1.75,this.handedness=1,this.safeSpaceRadius=.2,this.objectDistance=1.5,this.objectAngle=-.1*Math.PI,this.pivots=[],this.hoveredObjectsForController=new Map,this.selectedObjectsForController=new Map,this.touchedObjects=new Map,this.grabbedObjects=new Map}init({input:e,scene:t}){this.input=e,this.controllers=e.controllers,this.scene=t}setHeight(e){this.height=e.position.y}enablePivots(){this.input.enablePivots()}getPivot(e){return this.controllers[e].getObjectByName("pivot")}getPivotPosition(t){return this.getPivot(t)?.getWorldPosition(new e.Vector3)}getReticleDirection(e){return this.controllers[e].reticle?.direction}getReticleTarget(e){return this.controllers[e].reticle?.targetObject}getReticleIntersection(e){return this.controllers[e].reticle?.intersection}isPointingAt(e){for(const t of this.hoveredObjectsForController.values())if(dt(t,e))return!0;return!1}isSelectingAt(e){for(const t of this.selectedObjectsForController.values())if(dt(t,e))return!0;return!1}getIntersectionAt(e,t=-1){if(-1==t){for(let t=0;t<2;++t)if(this.getReticleTarget(t)===e)return this.getReticleIntersection(t)}else if(this.getReticleTarget(t)===e)return this.getReticleIntersection(t);return null}getControllerPosition(t,i=new e.Vector3){return this.controllers[t].getWorldPosition(i),i}getControllerObjectDistance(t,i){const s=this.getControllerPosition(t),n=new e.Vector3;return i.getWorldPosition(n),s.distanceTo(n)}isSelecting(e=-1){return-1==e?this.input.controllers.some(e=>e.userData.selected):this.input.controllers[e].userData.selected}isSqueezing(e=-1){return-1==e?this.input.controllers.some(e=>e.userData.squeezing):this.input.controllers[e].userData.squeezing}onSelectStart(e){const t=e.target,i=this.input.intersectionsForController.get(t).filter(e=>{let t=e.object;for(;t;){if(!0===t.ignoreReticleRaycast)return!1;t=t.parent}return!0});i&&i.length>0&&(this.selectedObjectsForController.set(t,i[0].object),this.callObjectSelectStart(e,i[0].object))}onSelectEnd(e){const t=e.target,i=this.input.intersectionsForController.get(t);if(i&&i.length>0){const i=this.selectedObjectsForController.get(t);this.callObjectSelectEnd(e,i||null),this.selectedObjectsForController.delete(t);let s=i||null;for(;s;){if(s.isView&&s.visible){s.onTriggered(t.userData.id);break}s=s.parent}}}onSqueezeStart(e){}onSqueezeEnd(e){}update(){if(this.input.controllersEnabled)for(const e of this.input.controllers)this.updateForController(e);this.updateTouchState(),this.updateGrabState()}updateGrabState(){if(this.hands)for(let e=0;e<this.numHands;e++){const t=this.isSelecting(e),i=this.touchedObjects.get(e)||new Set,s=t?i:new Set,n=this.grabbedObjects.get(e)||new Map,r=[...s].filter(e=>!n.has(e)),o=[...n.keys()].filter(e=>!s.has(e));for(const t of r){const i=this.hands.getWrist(e);if(!i)continue;const s={handIndex:e,hand:i};this.grabbedObjects.has(e)||this.grabbedObjects.set(e,new Map),this.grabbedObjects.get(e).set(t,s),this.callObjectGrabStart(s,t)}for(const e of o){const t=n.get(e);this.callObjectGrabEnd(t,e),n.delete(e)}for(const e of s)if(n.has(e)){const t=n.get(e);this.callObjectGrabbing(t,e)}}}updateTouchState(){if(this.hands)for(let t=0;t<this.numHands;t++){const i=this.hands.getIndexTip(t);if(!i)continue;const s=new e.Vector3;i.getWorldPosition(s);const n=[];this.scene.traverse(t=>{if(t.isMesh&&t.visible){(new e.Box3).setFromObject(t).containsPoint(s)&&n.push(t)}});const r=this.touchedObjects.get(t)||new Set,o=new Set(n),a=n.filter(e=>!r.has(e)),h=[...r].filter(e=>!o.has(e)),l={handIndex:t,touchPosition:s};if(a.length>0)for(const e of a)this.callObjectTouchStart(l,e);if(h.length>0)for(const e of h)this.callObjectTouchEnd(l,e);for(const e of o)this.callObjectTouching(l,e);o.size>0?this.touchedObjects.set(t,o):this.touchedObjects.delete(t)}}updateForController(e){const t=this.input.intersectionsForController.get(e),i=t.length>0?t[0].object:null,s=this.hoveredObjectsForController.get(e);s!==i?(this.callHoverExit(e,s||null),this.hoveredObjectsForController.set(e,i),this.callHoverEnter(e,i)):s&&this.callOnHovering(e,s)}callHoverExit(e,t){null!=t&&(t.isXRScript&&t.onHoverExit(e),this.callHoverExit(e,t.parent))}callHoverEnter(e,t){null!=t&&(t.isXRScript&&t.onHoverEnter(e),this.callHoverEnter(e,t.parent))}callOnHovering(e,t){null!=t&&(t.isXRScript&&t.onHovering(e),this.callOnHovering(e,t.parent))}callObjectSelectStart(e,t){null!=t&&(t.isXRScript&&t.onObjectSelectStart(e)||this.callObjectSelectStart(e,t.parent))}callObjectSelectEnd(e,t){null!=t&&(t.isXRScript&&t.onObjectSelectEnd(e)||this.callObjectSelectEnd(e,t.parent))}callObjectTouchStart(e,t){null!=t&&(t.isXRScript&&t.onObjectTouchStart(e),this.callObjectTouchStart(e,t.parent))}callObjectTouching(e,t){null!=t&&(t.isXRScript&&t.onObjectTouching(e),this.callObjectTouching(e,t.parent))}callObjectTouchEnd(e,t){null!=t&&(t.isXRScript&&t.onObjectTouchEnd(e),this.callObjectTouchEnd(e,t.parent))}callObjectGrabStart(e,t){null!=t&&(t.isXRScript&&t.onObjectGrabStart(e),this.callObjectGrabStart(e,t.parent))}callObjectGrabbing(e,t){null!=t&&(t.isXRScript&&t.onObjectGrabbing(e),this.callObjectGrabbing(e,t.parent))}callObjectGrabEnd(e,t){null!=t&&(t.isXRScript&&t.onObjectGrabEnd(e),this.callObjectGrabEnd(e,t.parent))}select(e,t){const i=this.input.intersectionsForController.get(t);return i&&i.length>0&&dt(i[0].object,e)?i[0]:null}}class gt{constructor(e){if(this.enabled=!1,this.provider="heuristics",this.minimumConfidence=.6,this.updateIntervalMs=33,this.gestures={pinch:{enabled:!0,threshold:.025},"open-palm":{enabled:!0},fist:{enabled:!0},"thumbs-up":{enabled:!0},point:{enabled:!1},spread:{enabled:!1,threshold:.04}},le(this,e),e?.gestures)for(const[t,i]of Object.entries(e.gestures)){const e=t;this.gestures[e]=le({...this.gestures[e]},i)}}enable(){return this.enabled=!0,this}setGestureEnabled(e,t){return this.gestures[e]??={enabled:t},this.gestures[e].enabled=t,this}}const mt=1e-6,ft=["index","middle","ring","pinky"],vt={index:"index-finger",middle:"middle-finger",ring:"ring-finger",pinky:"pinky-finger"},yt={pinch:function(e,t){const i=Tt(e,"thumb-tip"),s=Tt(e,"index-finger-tip");if(!i||!s)return;const n=St(e),r=t.threshold??Math.max(.018,.35*n),o=i.distanceTo(s);if(!Number.isFinite(o)||o<mt)return{confidence:0};const a=Mt(1-o/(.85*r)),h=Mt(1-o/(1.4*r));return{confidence:Mt(o<=r?a:.4*h),data:{distance:o,threshold:r}}},"open-palm":function(e,t){const i=xt(e);if(!i.length)return;const s=St(e),n=bt(e)??.85*s,r=i.map(({tipDistance:e})=>Mt((e-.5*s)/(.45*s))),o=i.map(({curlRatio:e})=>Mt((e-1.1)/.5)),a=Ct(e),h=a.average!==1/0&&n>mt?Mt((a.average-.55*n)/(.35*n)):0,l=Dt(r),c=Dt(o);return{confidence:Mt(.5*l+.3*c+.2*h),data:{extensionScore:l,straightScore:c,spreadScore:h,threshold:t.threshold}}},fist:function(e,t){const i=xt(e);if(!i.length)return;const s=St(e),n=bt(e)??.85*s,r=Dt(i.map(e=>e.tipDistance)),o=Dt(i.map(e=>e.curlRatio)),a=Ct(e),h=a.average!==1/0&&n>mt?Mt((.5*n-a.average)/(.35*n)):0,l=Mt((.55*s-r)/(.25*s)),c=Mt((1.08-o)/.25);return{confidence:Mt(.5*l+.35*c+.15*h),data:{tipAverage:r,curlAverage:o,clusterScore:h,threshold:t.threshold}}},"thumbs-up":function(t,i){const s=function(e){const t=Tt(e,"thumb-tip"),i=Tt(e,"wrist");if(!t||!i)return;const s=Tt(e,"thumb-metacarpal")??Tt(e,"thumb-phalanx-proximal");if(!s)return;const n=s.distanceTo(i),r=t.distanceTo(i);return{tip:t,metacarpal:s,referenceDistance:n,tipDistance:r}}(t),n=xt(t);if(!s||n.length<2)return;const r=St(t),o=bt(t)??.85*r,a=function(t){const i=function(t){const i=Tt(t,"wrist"),s=Rt(t,"index","metacarpal"),n=Rt(t,"pinky","metacarpal");if(!i||!s||!n)return null;const r=(new e.Vector3).subVectors(s,i),o=(new e.Vector3).subVectors(n,i);if(0===r.lengthSq()||0===o.lengthSq())return null;const a=(new e.Vector3).crossVectors(r,o);if(0===a.lengthSq())return null;"left"===t.handLabel&&a.multiplyScalar(-1);return a.normalize()}(t),s=function(t){const i=Rt(t,"index","metacarpal"),s=Rt(t,"pinky","metacarpal");if(!i||!s)return null;const n=(new e.Vector3).subVectors(i,s);"left"===t.handLabel&&n.multiplyScalar(-1);return 0===n.lengthSq()?null:n.normalize()}(t);if(!i||!s)return null;const n=(new e.Vector3).copy(s).cross(i);return 0===n.lengthSq()?null:n.normalize()}(t),h=Mt((1.05-Dt(n.map(e=>e.curlRatio)))/.25),l=s.referenceDistance>mt?s.tipDistance/s.referenceDistance:0,c=Mt((l-1.15)/.5),d=Tt(t,"index-finger-tip"),u=d?s.tip.distanceTo(d):0,p=o>mt?Mt((u-.4*o)/(.25*o)):0;let g=0;if(a){const t=(new e.Vector3).copy(s.tip).sub(s.metacarpal??s.tip);if(t.lengthSq()>mt){t.normalize();g=Mt((t.dot(a)-.35)/.35)}}return{confidence:Mt(.35*c+.3*h+.2*g+.15*p),data:{thumbReachRatio:l,curledScore:h,orientationScore:g,separationScore:p,threshold:i.threshold}}},point:function(e,t){const i=wt(e,"index");if(!i)return;const s=ft.slice(1).map(t=>wt(e,t)).filter(Boolean);if(!s.length)return;const n=St(e),r=Mt((i.curlRatio-1.2)/.35),o=Mt((i.tipDistance-.6*n)/(.25*n)),a=Mt((1.05-Dt(s.map(e=>e.curlRatio)))/.25);return{confidence:Mt(.45*r+.25*o+.3*a),data:{indexCurlScore:r,indexReachScore:o,othersCurledScore:a,threshold:t.threshold}}},spread:function(e,t){const i=xt(e);if(!i.length)return;const s=St(e),n=bt(e)??.85*s,r=Ct(e),o=r.average!==1/0&&n>mt?Mt((r.average-.6*n)/(.35*n)):0,a=Mt((Dt(i.map(e=>e.curlRatio))-1.15)/.45);return{confidence:Mt(.6*o+.4*a),data:{spreadScore:o,extensionScore:a,threshold:t.threshold}}}};function wt(e,t){const i=Rt(e,t,"tip"),s=Rt(e,t,"phalanx-proximal"),n=Rt(e,t,"metacarpal"),r=Tt(e,"wrist");if(!i||!r)return null;const o=s??n;if(!o)return null;const a=o.distanceTo(r),h=i.distanceTo(r);return{tip:i,metacarpal:n,referenceDistance:a,tipDistance:h,curlRatio:a>mt?h/a:0}}function xt(e){return ft.map(t=>wt(e,t)).filter(Boolean)}function St(e){const t=Tt(e,"wrist"),i=Tt(e,"middle-finger-tip"),s=Tt(e,"middle-finger-metacarpal"),n=bt(e),r=[];return t&&i&&r.push(i.distanceTo(t)),n&&r.push(n),t&&s&&r.push(2*s.distanceTo(t)),r.length?Dt(r):.08}function bt(e){const t=Rt(e,"index","metacarpal"),i=Rt(e,"pinky","metacarpal");return t&&i?t.distanceTo(i):null}function Ct(e){const t=ft.map(t=>Rt(e,t,"tip"));if(t.some(e=>!e))return{average:1/0};return{average:Dt([t[0].distanceTo(t[1]),t[1].distanceTo(t[2]),t[2].distanceTo(t[3])])}}function Tt(e,t){return e.joints.get(t)}function Rt(e,t,i){return Tt(e,`${vt[t]}-${i}`)}function Mt(t){return e.MathUtils.clamp(t,0,1)}function Dt(e){return e.length?e.reduce((e,t)=>e+t,0)/e.length:0}const Et={[et.LEFT]:"left",[et.RIGHT]:"right"},Pt=new Map;class _t extends S{constructor(){super(...arguments),this.activeGestures={left:new Map,right:new Map},this.lastEvaluation=0,this.detectors=new Map,this.activeProvider=null,this.providerWarned=!1}static{this.dependencies={input:ct,user:pt,options:gt}}async init({options:e,user:t,input:i}){this.options=e,this.user=t,this.input=i,this.configureProvider(!0),this.options.enabled||console.info("GestureRecognition initialized but disabled. Call options.enableGestures() to activate.")}update(){if(!this.options.enabled)return;if(!this.user.hands?.isValid?.())return;this.configureProvider();const e=performance.now(),t="heuristics"===this.activeProvider?0:this.options.updateIntervalMs;t>0&&e-this.lastEvaluation<t||(this.lastEvaluation=e,this.evaluateHand(et.LEFT),this.evaluateHand(et.RIGHT))}configureProvider(e=!1){const t=this.options.provider;if(e||t!==this.activeProvider){switch(this.detectors.clear(),t){case"heuristics":this.assignDetectors(yt),this.providerWarned=!1;break;case"mediapipe":case"tfjs":this.assignDetectors(yt),this.providerWarned||(console.warn(`GestureRecognition: provider '${t}' is not yet implemented; falling back to heuristics.`),this.providerWarned=!0);break;default:this.assignDetectors(yt),this.providerWarned||(console.warn(`GestureRecognition: provider '${t}' is unknown; falling back to heuristics.`),this.providerWarned=!0)}this.activeProvider=t}}assignDetectors(e){for(const[t,i]of Object.entries(e))i&&this.detectors.set(t,i)}evaluateHand(t){const i=Et[t],s=this.activeGestures[i];if(!i)return;const n=this.buildHandContext(t,i);if(!n){for(const[e]of s.entries())this.emitGesture("gestureend",{name:e,hand:i,confidence:0});return void s.clear()}const r=new Set;for(const[t,o]of Object.entries(this.options.gestures)){const a=t;if(!o?.enabled)continue;const h=this.detectors.get(a);if(!h)continue;const l=h(n,o),c=l&&l.confidence>=this.options.minimumConfidence;r.add(a);const d=s.get(a);if(c){const t={name:a,hand:i,confidence:e.MathUtils.clamp(l.confidence,0,1),data:l.data};d?(d.confidence=t.confidence,d.data=t.data,this.emitGesture("gestureupdate",t)):(s.set(a,{confidence:t.confidence,data:t.data}),this.emitGesture("gesturestart",t))}else d&&(s.delete(a),this.emitGesture("gestureend",{name:a,hand:i,confidence:0}))}for(const e of Array.from(s.keys()))r.has(e)||(s.delete(e),this.emitGesture("gestureend",{name:e,hand:i,confidence:0}))}buildHandContext(t,i){if(!this.user.hands)return null;const s=this.user.hands.hands[t];if(!s?.joints)return null;let n=Pt.get(i);n||(n=new Map,Pt.set(i,n));const r=n;r.clear();for(const t of Ze){const i=s.joints[t];if(!i)continue;let n=r.get(t);n||(n=new e.Vector3,r.set(t,n)),n.setFromMatrixPosition(i.matrixWorld)}return r.size?{handedness:t,handLabel:i,joints:r}:null}emitGesture(e,t){const i={type:e,detail:t,target:this};this.dispatchEvent(i)}}class At{constructor(){if(this.dirLight=new e.DirectionalLight,this.ambientProbe=new e.LightProbe,this.ambientLight=new e.Vector3,this.shadowOpacity=0,this.lightGroup=new e.Group,this.simulatorRunning=!1,At.instance)return At.instance;At.instance=this}init(t,i,s,n){if(this.options=t,this.depth=n,this.options.enabled){if(this.xrLight=new r(i),this.options.castDirectionalLightShadow&&(i.shadowMap.enabled=!0,i.shadowMap.type=e.PCFShadowMap),this.options.castDirectionalLightShadow){const t=this.dirLight;t.castShadow=!0,t.shadow.mapSize.width=2048,t.shadow.mapSize.height=2048,t.shadow.camera.near=.3,t.shadow.camera.far=50;const i=4;t.shadow.camera.left=-i,t.shadow.camera.right=i,t.shadow.camera.top=i,t.shadow.camera.bottom=-i,t.shadow.blurSamples=25,t.shadow.radius=5,t.shadow.bias=0,this.lightGroup.add(t.target),this.options.debugging&&s.add(new e.CameraHelper(t.shadow.camera))}this.options.useAmbientSH&&this.lightGroup.add(this.ambientProbe),this.options.useDirectionalLight&&this.lightGroup.add(this.dirLight),s.add(this.lightGroup),this.xrLight.addEventListener("estimationend",()=>{s.remove(this.xrLight)})}}update(){if(this.options.enabled&&(this.dirLight.position.copy(this.xrLight.directionalLight.position).multiplyScalar(20),this.dirLight.target.position.setScalar(0),this.dirLight.color=this.xrLight.directionalLight.color,this.dirLight.intensity=this.xrLight.directionalLight.intensity,this.ambientProbe.sh.copy(this.xrLight.lightProbe.sh),this.ambientProbe.intensity=this.xrLight.lightProbe.intensity,this.ambientLight.copy(this.xrLight.lightProbe.sh.coefficients[0]),this.simulatorRunning&&(this.dirLight.position.set(-10,10,-2),this.dirLight.target.position.set(0,0,-.5),this.dirLight.color.setHex(16777215),this.dirLight.intensity=3.8,this.ambientProbe.sh.fromArray([.22636516392230988,.2994415760040283,.2827182114124298,.03430574759840965,.029604531824588776,-.002050594426691532,.016114741563796997,.004344218410551548,.07621686905622482,.024204734712839127,-.02397896535694599,-.07645703107118607,.15790101885795593,.16706973314285278,.18418270349502563,-.13088643550872803,-.1461198776960373,-.1411236822605133,.04788218438625336,.08909443765878677,.10185115039348602,.020251473411917686,-.002100071171298623,-.06455840915441513,-.12393051385879517,-.05158703774213791,-.00532124936580658]),this.ambientProbe.intensity=1,this.ambientLight.copy(this.ambientProbe.sh.coefficients[0])),this.options.castDirectionalLightShadow&&this.options.useDynamicSoftShadow)){const t=this.ambientLight,i=.21*t.x+.72*t.y+.07*t.z,s=new e.Vector3(this.dirLight.color.r,this.dirLight.color.g,this.dirLight.color.b).multiplyScalar(this.dirLight.intensity),n=i/(.21*s.x+.72*s.y+.07*s.z);this.dirLight.shadow.radius=Math.min(Math.max(1,30*n),10),this.shadowOpacity=Math.max(Math.min(.7*(10-30*n),.7),.3),this.depth?.options?.enabled&&this.depth.options.depthMesh.enabled&&this.depth.depthMesh?.material instanceof e.ShadowMaterial&&(this.depth.depthMesh.material.opacity=this.shadowOpacity)}this.options.debugging&&this.debugLog()}debugLog(){console.log("Lighting.dirLight",this.dirLight),console.log("Lighting.ambientProbe",this.ambientProbe),console.log("Lighting.ambientLight",this.ambientLight)}}class Ot{constructor(){this.initialized=!1,this.fps=0}get timestep(){return 1/this.fps}async init({physicsOptions:e}){this.options=e,this.RAPIER=this.options.RAPIER,this.fps=this.options.fps,this.RAPIER.init&&await this.RAPIER.init(),this.blendedWorld=new this.RAPIER.World(this.options.gravity),this.blendedWorld.timestep=this.timestep,this.options.useEventQueue&&(this.eventQueue=new this.RAPIER.EventQueue(!0)),this.initialized=!0}physicsStep(){this.options?.worldStep&&this.blendedWorld&&this.blendedWorld.step(this.eventQueue)}dispose(){this.eventQueue&&this.eventQueue.free(),this.blendedWorld&&this.blendedWorld.free()}}class It{constructor(e){this.enabled=!1,this.visualization=!1,this.visualizeJoints=!1,this.visualizeMeshes=!1,this.debugging=!1,le(this,e)}enableHands(){return this.enabled=!0,this}enableHandsVisualization(){return this.enabled=!0,this.visualization=!0,this}}class Lt{constructor(e){this.debugging=!1,this.enabled=!1,this.useAmbientSH=!1,this.useDirectionalLight=!1,this.castDirectionalLightShadow=!1,this.useDynamicSoftShadow=!1,le(this,e)}}class Vt{constructor(){this.fps=45,this.gravity={x:0,y:-9.81,z:0},this.worldStep=!0,this.useEventQueue=!1}}var Bt;!function(e){e.USER="User",e.POSE="Navigation",e.CONTROLLER="Hands"}(Bt||(Bt={}));const Ft={[Bt.USER]:Bt.POSE,[Bt.POSE]:Bt.CONTROLLER,[Bt.CONTROLLER]:Bt.USER};class zt{constructor(e){this.initialCameraPosition={x:0,y:1.5,z:0},this.scenePath=ae+"simulator/scenes/XREmulatorsceneV5_livingRoom.glb",this.initialScenePosition={x:-1.6,y:.3,z:0},this.defaultMode=Bt.USER,this.defaultHand=et.LEFT,this.modeIndicator={enabled:!0,element:"xrblocks-simulator-mode-indicator"},this.instructions={enabled:!0,element:"xrblocks-simulator-instructions",customInstructions:[]},this.handPosePanel={enabled:!0,element:"xrblocks-simulator-hand-pose-panel"},this.geminilive=!1,this.stereo={enabled:!1},this.renderToRenderTexture=!0,this.blendingMode="normal",le(this,e)}}class kt{constructor(){this.enabled=!1,this.allowInterruptions=!1}}class jt{constructor(){this.enabled=!0,this.lang="en-US",this.continuous=!1,this.commands=[],this.interimResults=!1,this.commandConfidenceThreshold=.7,this.playSimulatorActivationSounds=!0}}class Ut{constructor(){this.speechSynthesizer=new kt,this.speechRecognizer=new jt}}class Nt{constructor(e){this.debugging=!1,this.enabled=!1,this.showDebugVisualizations=!1,this.objectImageMargin=.05,this.backendConfig={activeBackend:"gemini",gemini:{systemInstruction:"Please provide me with the bounding box coordinates for the primary objects in the given image, prioritizing objects that are nearby. For each bounding box, include ymin, xmin, ymax, and xmax. These coordinates should be absolute values ranging from 0 to 1000, corresponding to the image as if it were resized to 1000x1000 pixels. The origin (xmin:0; ymin:0) is the top-left corner of the image, and (xmax:1000; ymax:1000) is the bottom-right corner. List a maximum of 5 objects. Ignore hands and other human body parts, as well as any UI elements attached to them (e.g., a blue circle attached to a finger).",responseSchema:{type:"ARRAY",items:{type:"OBJECT",required:["objectName","ymin","xmin","ymax","xmax"],properties:{objectName:{type:"STRING"},ymin:{type:"NUMBER"},xmin:{type:"NUMBER"},ymax:{type:"NUMBER"},xmax:{type:"NUMBER"}}}}},mediapipe:{}},e&&le(this,e)}enable(){return this.enabled=!0,this}}class Gt{constructor(e){this.debugging=!1,this.enabled=!1,this.showDebugVisualizations=!1,e&&le(this,e)}enable(){return this.enabled=!0,this}}class Ht{constructor(e){this.debugging=!1,this.enabled=!1,this.planes=new Gt,this.objects=new Nt,e&&le(this,e)}enablePlaneDetection(){return this.enabled=!0,this.planes.enable(),this}enableObjectDetection(){return this.enabled=!0,this.objects.enable(),this}}class Wt{constructor(){this.enabled=!0,this.enabledMouse=!0,this.debug=!1,this.visualization=!1,this.visualizeRays=!1}}class qt{constructor(){this.enabled=!0}}class Xt{constructor(){this.enabled=!1,this.transitionTime=.5,this.defaultBackgroundColor=16777215}}class Kt{constructor(e){this.antialias=!0,this.logarithmicDepthBuffer=!1,this.debugging=!1,this.stencil=!1,this.webxrRequiredFeatures=[],this.referenceSpaceType="local-floor",this.controllers=new Wt,this.depth=new xe,this.lighting=new Lt,this.deviceCamera=new ce,this.hands=new It,this.gestures=new gt,this.reticles=new qt,this.sound=new Ut,this.ai=new F,this.simulator=new zt,this.world=new Ht,this.physics=new Vt,this.transition=new Xt,this.camera={near:.01,far:500},this.usePostprocessing=!1,this.xrButton={enabled:!0,startText:"Enter XR",endText:"Exit XR",invalidText:"XR Not Supported",startSimulatorText:"Enter Simulator",enableSimulator:!0,showSimulatorButtonOnMobile:!1,autostartSimulatorOnDesktop:!0,autostartSimulator:!1},le(this,e)}enableUI(){return this.antialias=!0,this.reticles.enabled=!0,this}enableReticles(){return this.reticles.enabled=!0,this}enableDepth(){return this.depth=new xe(Se),this}enablePlaneDetection(){return this.world.enablePlaneDetection(),this}enableObjectDetection(){return this.world.enableObjectDetection(),this}enableCamera(e="environment"){return this.deviceCamera=new ce("environment"===e?ue:pe),this}enableHands(){return this.hands.enabled=!0,this}enableGestures(){return this.enableHands(),this.gestures.enable(),this}enableHandRays(){return this.controllers.visualizeRays=!0,this}enableGeminiLive(){return this.simulator.geminilive=!0,this}enableAI(){return this.ai.enabled=!0,this.ai.gemini.enabled=!0,this.ai.gemini.live.enabled=!0,this}enableXRTransitions(){return this.transition.enabled=!0,this}}class $t{constructor(e="simulator",t="simulator",i="videoinput",s="Simulator Camera"){this.deviceId=e,this.groupId=t,this.kind=i,this.label=s}}var Qt;!function(e){e[e.EXACT=0]="EXACT",e[e.IDEAL=1]="IDEAL",e[e.ACCEPTABLE=2]="ACCEPTABLE",e[e.UNACCEPTABLE=3]="UNACCEPTABLE"}(Qt||(Qt={}));class Yt{constructor(t){this.renderer=t,this.cameraCreated=!1,this.fps=30,this.matchRenderingCamera=!0,this.width=512,this.height=512,this.camera=new e.PerspectiveCamera}init(){this.createSimulatorCamera()}createSimulatorCamera(){if(this.cameraCreated)return;this.canvas=document.createElement("canvas"),this.canvas.width=this.width,this.canvas.height=this.height,this.context=this.canvas.getContext("2d"),this.mediaStream=this.canvas.captureStream(this.fps);const e=this.mediaStream.getVideoTracks()[0],t=this.mediaStream.getVideoTracks()[0].getSettings().deviceId;this.cameraInfo=new $t(t),e.stop(),this.cameraCreated=!0}async enumerateDevices(){return this.cameraInfo?[this.cameraInfo]:[]}onBeforeSimulatorSceneRender(e,t){if(this.cameraCreated&&!this.matchRenderingCamera){this.camera.position.copy(e.position),this.camera.quaternion.copy(e.quaternion),t(this.camera);const i=this.renderer.domElement.width,s=this.renderer.domElement.height,n=this.width/this.height,r=Math.min(i,s*n),o=Math.min(s,i/n),a=(i-r)/2,h=(s-o)/2;this.context.drawImage(this.renderer.domElement,a,h,r,o,0,0,this.width,this.height)}}onSimulatorSceneRendered(){if(this.cameraCreated&&this.matchRenderingCamera){const e=this.renderer.domElement.width,t=this.renderer.domElement.height,i=this.width/this.height,s=Math.min(e,t*i),n=Math.min(t,e/i),r=(e-s)/2,o=(t-n)/2;this.context.drawImage(this.renderer.domElement,r,o,s,n,0,0,this.width,this.height)}}restartVideoTrack(){if(!this.cameraCreated)return;this.mediaStream=this.canvas.captureStream(this.fps);const e=this.mediaStream.getVideoTracks()[0].getSettings().deviceId;this.cameraInfo.deviceId=e||""}getMedia(e={}){if(this.cameraCreated){if(!e?.deviceId||function(e,t){const i=(e,t)=>"string"==typeof e?t===e:e.includes(t);return null==e?Qt.ACCEPTABLE:"string"==typeof e||Array.isArray(e)?i(e,t)?Qt.EXACT:Qt.UNACCEPTABLE:"object"==typeof e?void 0!==e.exact?i(e.exact,t)?Qt.EXACT:Qt.UNACCEPTABLE:void 0!==e.ideal&&i(e.ideal,t)?Qt.IDEAL:Qt.ACCEPTABLE:Qt.UNACCEPTABLE}(e?.deviceId,this.cameraInfo.deviceId)!=Qt.UNACCEPTABLE){return"ended"==this.mediaStream.getVideoTracks()[0].readyState&&this.restartVideoTrack(),this.mediaStream}return null}}}const Jt=.063;var Zt,ei;!function(e){e.DEFAULT="default",e.STEREO_LEFT="left",e.STEREO_RIGHT="right"}(Zt||(Zt={}));class ti{constructor(){this.localControllerPositions=[new e.Vector3(-.3,-.1,-.3),new e.Vector3(.3,-.1,-.3)],this.localControllerOrientations=[new e.Quaternion,new e.Quaternion],this.currentControllerIndex=0}}!function(e){e.W_CODE="KeyW",e.A_CODE="KeyA",e.S_CODE="KeyS",e.D_CODE="KeyD",e.UP="ArrowUp",e.DOWN="ArrowDown",e.LEFT="ArrowLeft",e.RIGHT="ArrowRight",e.Q_CODE="KeyQ",e.E_CODE="KeyE",e.PAGE_UP="PageUp",e.PAGE_DOWN="PageDown",e.SPACE_CODE="Space",e.ENTER_CODE="Enter",e.T_CODE="KeyT",e.LEFT_SHIFT_CODE="ShiftLeft",e.RIGHT_SHIFT_CODE="ShiftRight",e.LEFT_CTRL_CODE="ControlLeft",e.RIGHT_CTRL_CODE="ControlRight",e.LEFT_ALT_CODE="AltLeft",e.RIGHT_ALT_CODE="AltRight",e.CAPS_LOCK_CODE="CapsLock",e.ESCAPE_CODE="Escape",e.TAB_CODE="Tab",e.B_CODE="KeyB",e.C_CODE="KeyC",e.F_CODE="KeyF",e.G_CODE="KeyG",e.H_CODE="KeyH",e.I_CODE="KeyI",e.J_CODE="KeyJ",e.K_CODE="KeyK",e.L_CODE="KeyL",e.M_CODE="KeyM",e.N_CODE="KeyN",e.O_CODE="KeyO",e.P_CODE="KeyP",e.R_CODE="KeyR",e.U_CODE="KeyU",e.V_CODE="KeyV",e.X_CODE="KeyX",e.Y_CODE="KeyY",e.Z_CODE="KeyZ",e.DIGIT_0="Digit0",e.DIGIT_1="Digit1",e.DIGIT_2="Digit2",e.DIGIT_3="Digit3",e.DIGIT_4="Digit4",e.DIGIT_5="Digit5",e.DIGIT_6="Digit6",e.DIGIT_7="Digit7",e.DIGIT_8="Digit8",e.DIGIT_9="Digit9",e.BACKQUOTE="Backquote"}(ei||(ei={}));const{A_CODE:ii,D_CODE:si,E_CODE:ni,Q_CODE:ri,S_CODE:oi,W_CODE:ai}=ei,hi=new e.Vector3,li=new e.Euler;class ci{constructor(e,t,i,s,n){this.simulatorControllerState=e,this.downKeys=t,this.hands=i,this.setStereoRenderMode=s,this.toggleUserInterface=n}init({camera:e,input:t,timer:i}){this.camera=e,this.input=t,this.timer=i}onPointerDown(e){}onPointerUp(e){}onPointerMove(e){}onKeyDown(e){e.code==ei.DIGIT_1?this.setStereoRenderMode(Zt.STEREO_LEFT):e.code==ei.DIGIT_2?this.setStereoRenderMode(Zt.STEREO_RIGHT):e.code==ei.BACKQUOTE&&this.toggleUserInterface()}onModeActivated(){}onModeDeactivated(){}update(){this.updateCameraPosition(),this.updateControllerPositions()}updateCameraPosition(){const e=this.timer.getDelta(),t=this.camera.quaternion,i=this.camera.position,s=this.downKeys;hi.set(Number(s.has(si))-Number(s.has(ii)),Number(s.has(ri))-Number(s.has(ni)),Number(s.has(oi))-Number(s.has(ai))).multiplyScalar(e).applyQuaternion(t),i.add(hi)}updateControllerPositions(){this.camera.updateMatrixWorld();for(let e=0;e<2;e++){const t=this.input.controllers[e];t.position.copy(this.simulatorControllerState.localControllerPositions[e]).applyMatrix4(this.camera.matrixWorld),t.quaternion.copy(this.simulatorControllerState.localControllerOrientations[e]).premultiply(this.camera.quaternion),t.updateMatrix();const i=0==e?this.hands.leftController:this.hands.rightController;i.position.copy(t.position),i.quaternion.copy(t.quaternion)}}rotateOnPointerMove(e,t,i=.002){li.setFromQuaternion(t,"YXZ"),li.y+=e.movementX*i,li.x+=e.movementY*i;const s=Math.PI/2;li.x=Math.max(.01-s,Math.min(s-.01,li.x)),t.setFromEuler(li)}enableSimulatorHands(){this.hands.showHands(),this.input.dispatchEvent({type:"connected",target:this.input.controllers[0],data:{handedness:"left"}}),this.input.dispatchEvent({type:"connected",target:this.input.controllers[1],data:{handedness:"right"}})}disableSimulatorHands(){this.hands.hideHands(),this.input.dispatchEvent({type:"disconnected",target:this.input.controllers[0],data:{handedness:"left"}}),this.input.dispatchEvent({type:"disconnected",target:this.input.controllers[1],data:{handedness:"right"}})}}const di=new e.Vector3,{A_CODE:ui,D_CODE:pi,E_CODE:gi,Q_CODE:mi,S_CODE:fi,SPACE_CODE:vi,T_CODE:yi,W_CODE:wi}=ei;class xi extends ci{onPointerMove(e){if(e.buttons){const t=this.simulatorControllerState.localControllerOrientations[this.simulatorControllerState.currentControllerIndex];this.rotateOnPointerMove(e,t,-.002)}}update(){this.updateControllerPositions()}onModeActivated(){this.enableSimulatorHands()}updateControllerPositions(){const e=this.timer.getDelta(),t=this.downKeys;di.set(Number(t.has(pi))-Number(t.has(ui)),Number(t.has(mi))-Number(t.has(gi)),Number(t.has(fi))-Number(t.has(wi))).multiplyScalar(e),this.simulatorControllerState.localControllerPositions[this.simulatorControllerState.currentControllerIndex].add(di),super.updateControllerPositions()}toggleControllerIndex(){this.hands.toggleHandedness()}onKeyDown(e){if(super.onKeyDown(e),e.code==yi)this.toggleControllerIndex();else if(e.code==vi){const e=this.input.controllers[this.simulatorControllerState.currentControllerIndex].userData?.selected,t=!e;0==this.simulatorControllerState.currentControllerIndex?this.hands.setLeftHandPinching(t):this.hands.setRightHandPinching(t)}}}class Si extends ci{onModeActivated(){this.enableSimulatorHands()}onPointerMove(e){e.buttons&&this.rotateOnPointerMove(e,this.camera.quaternion)}}class bi extends ci{onModeActivated(){this.disableSimulatorHands(),this.input.mouseController.connect()}onModeDeactivated(){this.input.mouseController.disconnect()}onPointerDown(e){1&e.buttons&&this.input.mouseController.callSelectStart()}onPointerUp(){this.input.mouseController.userData.selected&&this.input.mouseController.callSelectEnd()}onPointerMove(e){this.input.mouseController.updateMousePositionFromEvent(e),2&e.buttons&&this.rotateOnPointerMove(e,this.camera.quaternion)}}class Ci extends Event{static{this.type="setSimulatorMode"}constructor(e){super(Ci.type,{bubbles:!0,composed:!0}),this.simulatorMode=e}}function Ti(e){e.preventDefault()}class Ri{constructor(e,t,i,s){this.simulatorControllerState=e,this.hands=t,this.userInterface=s,this.pointerDown=!1,this.downKeys=new Set,this.simulatorMode=Bt.USER,this._onPointerDown=this.onPointerDown.bind(this),this._onPointerUp=this.onPointerUp.bind(this),this._onKeyDown=this.onKeyDown.bind(this),this._onKeyUp=this.onKeyUp.bind(this),this._onPointerMove=this.onPointerMove.bind(this);const n=()=>{this.userInterface.toggleInterfaceVisible()};this.simulatorModes={[Bt.USER]:new bi(this.simulatorControllerState,this.downKeys,t,i,n),[Bt.POSE]:new Si(this.simulatorControllerState,this.downKeys,t,i,n),[Bt.CONTROLLER]:new xi(this.simulatorControllerState,this.downKeys,t,i,n)},this.simulatorModeControls=this.simulatorModes[this.simulatorMode]}init({camera:e,input:t,timer:i,renderer:s,simulatorOptions:n}){for(const s in this.simulatorModes)this.simulatorModes[s].init({camera:e,input:t,timer:i});this.renderer=s,this.setSimulatorMode(n.defaultMode),this.simulatorControllerState.currentControllerIndex=n.defaultHand===et.LEFT?0:1,this.connect()}connect(){const e=this.renderer.domElement;document.addEventListener("keyup",this._onKeyUp),document.addEventListener("keydown",this._onKeyDown),e.addEventListener("pointermove",this._onPointerMove),e.addEventListener("pointerdown",this._onPointerDown),e.addEventListener("pointerup",this._onPointerUp),e.addEventListener("contextmenu",Ti)}update(){this.simulatorModeControls.update()}onPointerMove(e){this.simulatorModeControls.onPointerMove(e)}onPointerDown(e){this.simulatorModeControls.onPointerDown(e),this.pointerDown=!0}onPointerUp(e){this.simulatorModeControls.onPointerUp(e),this.pointerDown=!1}onKeyDown(e){this.downKeys.add(e.code),e.code==ei.LEFT_SHIFT_CODE&&this.setSimulatorMode(Ft[this.simulatorMode]),this.simulatorModeControls.onKeyDown(e)}onKeyUp(e){this.downKeys.delete(e.code)}setSimulatorMode(e){this.simulatorMode=e,this.simulatorModeControls.onModeDeactivated(),this.simulatorModeControls=this.simulatorModes[this.simulatorMode],this.simulatorModeControls.onModeActivated(),this.modeIndicatorElement&&(this.modeIndicatorElement.simulatorMode=e)}setModeIndicatorElement(e){e.simulatorMode=this.simulatorMode,e.addEventListener("setSimulatorMode",e=>{e instanceof Ci&&this.setSimulatorMode(e.simulatorMode)}),this.modeIndicatorElement=e}}class Mi extends e.MeshBasicMaterial{onBeforeCompile(e){e.vertexShader=e.vertexShader.replace("#include <clipping_planes_pars_vertex>",["#include <clipping_planes_pars_vertex>","varying vec4 vViewCoordinates;"].join("\n")).replace("#include <project_vertex>",["#include <project_vertex>","vViewCoordinates = mvPosition;"].join("\n")),e.fragmentShader=e.fragmentShader.replace("#include <clipping_planes_pars_fragment>",["#include <clipping_planes_pars_fragment>","varying vec4 vViewCoordinates;"].join("\n")).replace("#include <dithering_fragment>",["#include <dithering_fragment>","gl_FragColor = vec4(-vViewCoordinates.z, 0.0, 0.0, 1.0);"].join("\n"))}}class Di{constructor(e){this.simulatorScene=e,this.depthWidth=160,this.depthHeight=160,this.depthBufferSlice=new Float32Array}init(e,t,i){this.renderer=e,this.camera=t,this.depth=i,this.createRenderTarget(),this.depthMaterial=new Mi}createRenderTarget(){this.depthRenderTarget=new e.WebGLRenderTarget(this.depthWidth,this.depthHeight,{format:e.RedFormat,type:e.FloatType}),this.depthBuffer=new Float32Array(this.depthWidth*this.depthHeight)}update(){this.renderDepthScene(),this.updateDepth()}renderDepthScene(){const e=this.renderer.getRenderTarget();this.renderer.setRenderTarget(this.depthRenderTarget),this.simulatorScene.overrideMaterial=this.depthMaterial,this.renderer.render(this.simulatorScene,this.camera),this.simulatorScene.overrideMaterial=null,this.renderer.setRenderTarget(e)}updateDepth(){const e=this.renderer.getContext();e.bindBuffer(e.PIXEL_PACK_BUFFER,null),this.renderer.readRenderTargetPixels(this.depthRenderTarget,0,0,this.depthWidth,this.depthHeight,this.depthBuffer),this.depthBufferSlice.length!=this.depthWidth&&(this.depthBufferSlice=new Float32Array(this.depthWidth));for(let e=0;e<this.depthHeight/2;++e){const t=this.depthHeight-1-e,i=e*this.depthWidth,s=t*this.depthWidth;this.depthBufferSlice.set(this.depthBuffer.subarray(i,i+this.depthWidth)),this.depthBuffer.copyWithin(i,s,s+this.depthWidth),this.depthBuffer.set(this.depthBufferSlice,s)}const t={width:this.depthWidth,height:this.depthHeight,data:this.depthBuffer.buffer,rawValueToMeters:1};this.depth.updateCPUDepthData(t,0)}}class Ei extends Event{static{this.type="SimulatorHandPoseChangeRequestEvent"}constructor(e){super(Ei.type,{bubbles:!0,composed:!0}),this.pose=e}}var Pi;!function(e){e.RELAXED="relaxed",e.PINCHING="pinching",e.FIST="fist",e.THUMBS_UP="thumbs_up",e.POINTING="pointing",e.ROCK="rock",e.THUMBS_DOWN="thumbs_down",e.VICTORY="victory"}(Pi||(Pi={}));const _i=Object.freeze({[Pi.RELAXED]:[{t:[-.05,-.08,-.1],r:[.5373,0,0,.8434]},{t:[-.0281,-.0594,-.1165],r:[.3943,-.2036,-.3103,.8407]},{t:[.0026,-.0299,-.1518],r:[.3476,-.1049,-.5285,.7674]},{t:[.0169,-.0181,-.1728],r:[.3521,.0515,-.635,.6857]},{t:[.0268,-.0018,-.1966],r:[.3521,.0515,-.635,.6857]},{t:[-.0369,-.0541,-.1121],r:[.5882,-.1036,.0205,.8018]},{t:[-.024,.0143,-.1465],r:[.3269,-.0887,-3e-4,.9409]},{t:[-.0172,.0394,-.1765],r:[-.0114,-.0813,-.0286,.9962]},{t:[-.0138,.0388,-.1986],r:[-.1994,-.0379,-.0372,.9785]},{t:[-.0125,.0287,-.2199],r:[-.1994,-.0379,-.0372,.9785]},{t:[-.0499,-.0528,-.1125],r:[.5569,-.0203,.0319,.8297]},{t:[-.0496,.0131,-.1445],r:[.3908,-.0273,.1089,.9136]},{t:[-.0513,.0438,-.1738],r:[.0747,-.0923,.0634,.9909]},{t:[-.0462,.0488,-.2036],r:[-.1936,-.1156,.0299,.9738]},{t:[-.0404,.0387,-.2253],r:[-.1936,-.1156,.0299,.9738]},{t:[-.0612,-.0561,-.1138],r:[.5095,.0572,.0274,.8581]},{t:[-.0698,.0022,-.1468],r:[.4396,-.0068,.1748,.881]},{t:[-.0751,.0329,-.1719],r:[.071,-.0911,.1344,.9842]},{t:[-.0703,.0383,-.2029],r:[-.1764,-.1244,.0831,.9729]},{t:[-.0641,.0302,-.2227],r:[-.1764,-.1244,.0831,.9729]},{t:[-.0708,-.0616,-.1145],r:[.4571,.1437,.0457,.8765]},{t:[-.0889,-.0132,-.148],r:[.3971,.0569,.2436,.883]},{t:[-.098,.0096,-.1727],r:[.1604,-.0085,.243,.9566]},{t:[-.0997,.0171,-.194],r:[-.0034,-.0735,.1859,.9798]},{t:[-.0979,.0165,-.2131],r:[-.0034,-.0735,.1859,.9798]}],[Pi.PINCHING]:[{t:[-.05,-.08,-.1],r:[.5373,0,0,.8434],s:[1,1,1]},{t:[-.0281,-.0594,-.1165],r:[.3072,-.0483,-.257,.915],s:[1,1,1]},{t:[-.0083,-.0299,-.1581],r:[.1832,.0632,-.4718,.8602],s:[1,1,1]},{t:[-.0069,-.0195,-.1841],r:[.2232,.1362,-.6112,.747],s:[1,1,.9999]},{t:[-.0063,-.0051,-.2109],r:[.2232,.1362,-.6112,.747],s:[1,1,.9999]},{t:[-.0369,-.0541,-.112],r:[.5858,-.1038,.0205,.8035],s:[1,1,1]},{t:[-.024,.0142,-.1465],r:[.1342,-.1392,-.0707,.9786],s:[1.0001,1,.9999]},{t:[-.0122,.0248,-.1828],r:[-.2614,-.0983,-.1184,.9529],s:[1.0001,.9999,.9999]},{t:[-.0095,.0131,-.2017],r:[-.3454,-.0506,-.1338,.9275],s:[1,.9999,1]},{t:[-.0098,-.0028,-.219],r:[-.3454,-.0506,-.1338,.9275],s:[1,.9999,1]},{t:[-.0498,-.0529,-.1126],r:[.5552,-.0196,.0307,.8309],s:[1.0001,1,1]},{t:[-.0496,.0131,-.1444],r:[.3957,-.0669,.0916,.9113],s:[1,.9999,1]},{t:[-.0477,.0443,-.173],r:[.0284,-.1256,.0276,.9913],s:[1,1,.9999]},{t:[-.0403,.0463,-.2027],r:[-.1956,-.1387,-.007,.9708],s:[1.0001,1,1]},{t:[-.0339,.036,-.224],r:[-.1956,-.1387,-.007,.9708],s:[1.0001,1,1]},{t:[-.0612,-.0561,-.1137],r:[.5088,.0591,.0245,.8585],s:[1,1.0001,1]},{t:[-.0697,.0021,-.1467],r:[.464,-.0595,.1601,.8692],s:[1,1,1]},{t:[-.0713,.0348,-.1698],r:[.0595,-.1373,.0948,.9842],s:[1.0001,1.0001,1]},{t:[-.0633,.0395,-.2003],r:[-.1735,-.159,.0354,.9713],s:[1,1,.9999]},{t:[-.0561,.0313,-.2197],r:[-.1735,-.159,.0354,.9713],s:[1,1,.9999]},{t:[-.0707,-.0617,-.1146],r:[.4573,.1467,.0408,.8762],s:[1,1,1]},{t:[-.0889,-.0132,-.148],r:[.4065,.0051,.2314,.8838],s:[1,.9999,1.0001]},{t:[-.0946,.0109,-.1723],r:[.1595,-.0578,.2175,.9612],s:[1,.9999,1]},{t:[-.094,.019,-.1934],r:[-.0122,-.1189,.1509,.9813],s:[1.0001,1,1]},{t:[-.0904,.0182,-.2123],r:[-.0122,-.1189,.1509,.9813],s:[1.0001,1,1]}],[Pi.FIST]:[{t:[-.0933,-.0266,-.1338],r:[.1346,-.1437,.0038,.9804]},{t:[-.0648,-.0265,-.1529],r:[.0354,-.3351,-.1786,.9244]},{t:[-.0318,-.0293,-.1932],r:[.0407,-.2202,-.5685,.7916]},{t:[-.0212,-.0345,-.2179],r:[.0132,-.12,-.576,.8084]},{t:[-.0161,-.039,-.2469],r:[.0132,-.12,-.576,.8084]},{t:[-.0731,-.0197,-.1569],r:[.0999,-.2377,.0822,.9627]},{t:[-.0399,-.0023,-.2221],r:[-.4356,-.1075,-.0127,.8936]},{t:[-.0325,-.0319,-.246],r:[.9331,.066,.0832,-.3436]},{t:[-.035,-.0462,-.2296],r:[.9874,.021,.128,-.0903]},{t:[-.0408,-.0496,-.2076],r:[.9874,.021,.128,-.0903]},{t:[-.0853,-.0187,-.1614],r:[.115,-.1594,.0889,.9765]},{t:[-.0646,-7e-4,-.2271],r:[-.4919,-.1197,.0382,.8616]},{t:[-.0544,-.0353,-.2477],r:[.9309,.1571,.0605,-.324]},{t:[-.0548,-.0542,-.2244],r:[.9835,.1315,.1097,.0583]},{t:[-.0607,-.051,-.2013],r:[.9835,.1315,.1097,.0583]},{t:[-.0972,-.0213,-.1628],r:[.0881,-.0966,.0847,.9878]},{t:[-.0856,-.0088,-.2263],r:[-.4818,-.1075,.1033,.8635]},{t:[-.0742,-.0406,-.246],r:[.9378,.1774,.0089,-.2983]},{t:[-.0715,-.0585,-.2205],r:[.9769,.1847,.0804,.0714]},{t:[-.0757,-.0552,-.1994],r:[.9769,.1847,.0804,.0714]},{t:[-.1078,-.0253,-.162],r:[.0535,-.0126,.0933,.9941]},{t:[-.1069,-.0188,-.2215],r:[-.4433,-.1294,.1523,.8738]},{t:[-.0939,-.0444,-.2398],r:[.9002,.2018,-.0275,-.385]},{t:[-.0891,-.0599,-.2248],r:[.9644,.2553,.0425,-.0538]},{t:[-.0914,-.0623,-.2063],r:[.9644,.2553,.0425,-.0538]}],[Pi.THUMBS_UP]:[{t:[-.011,-.0299,-.0701],r:[.1224,-.1562,.6052,.771]},{t:[.0025,-.0017,-.0854],r:[.3796,-.3776,.3843,.7521]},{t:[.0162,.041,-.1065],r:[.6152,-.1749,.0935,.763]},{t:[.0204,.0676,-.1116],r:[.5992,-.1247,.1335,.7795]},{t:[.0225,.096,-.1202],r:[.5992,-.1247,.1335,.7795]},{t:[-.0042,-.008,-.0928],r:[.1427,-.2467,.6763,.6793]},{t:[.0063,.0312,-.155],r:[-.4551,-.5645,.3425,.5974]},{t:[.0447,.0257,-.1538],r:[.7509,.6277,.1981,-.053]},{t:[.0396,.0184,-.1338],r:[.7246,.5124,.4244,.1797]},{t:[.0207,.0148,-.1212],r:[.7246,.5124,.4244,.1797]},{t:[-.0078,-.0192,-.0982],r:[.109,-.1737,.6698,.7137]},{t:[-6e-4,.0083,-.163],r:[-.4929,-.5301,.4215,.5462]},{t:[.0407,.0046,-.1614],r:[.705,.703,.0897,-.0263]},{t:[.0382,-5e-4,-.132],r:[.6279,.5816,.4074,.3186]},{t:[.0165,-.0021,-.1217],r:[.6279,.5816,.4074,.3186]},{t:[-.0092,-.031,-.0993],r:[.0472,-.1416,.6514,.7439]},{t:[6e-4,-.0142,-.1626],r:[-.5202,-.4929,.4819,.5042]},{t:[.0398,-.0159,-.1611],r:[.6996,.7076,.0706,.0696]},{t:[.0338,-.0161,-.1304],r:[.5876,.6289,.3607,.3593]},{t:[.0143,-.0168,-.1208],r:[.5876,.6289,.3607,.3593]},{t:[-.0081,-.0426,-.0982],r:[-.0269,-.0934,.6476,.7558]},{t:[.0026,-.0377,-.1578],r:[.5435,.4612,-.5243,-.4658]},{t:[.0366,-.0376,-.1559],r:[.6991,.7017,.0384,.1318]},{t:[.032,-.0347,-.1344],r:[.575,.6796,.2522,.3795]},{t:[.0166,-.0342,-.1237],r:[.575,.6796,.2522,.3795]}],[Pi.POINTING]:[{t:[-.0283,-.0376,-.0293],r:[.1372,-.208,.241,.938]},{t:[.0016,-.0246,-.0431],r:[.0106,-.3992,-.0014,.9168]},{t:[.0392,-.0237,-.0781],r:[-.1,-.2869,-.466,.831]},{t:[.0496,-.0357,-.1004],r:[-.1511,-.183,-.4918,.8377]},{t:[.0533,-.0497,-.1265],r:[-.1511,-.183,-.4918,.8377]},{t:[-.0078,-.0226,-.0496],r:[.1168,-.3031,.3253,.8881]},{t:[.0265,.0074,-.1082],r:[.0563,-.1303,.2725,.9516]},{t:[.0346,.0153,-.1453],r:[-.0635,-.1606,.2541,.9516]},{t:[.0419,.0144,-.1659],r:[-.1073,-.1342,.2464,.9538]},{t:[.0494,.0105,-.1873],r:[-.1073,-.1342,.2464,.9538]},{t:[-.0184,-.0273,-.0562],r:[.1156,-.2249,.3238,.9117]},{t:[.0052,-.0021,-.1177],r:[-.4452,-.2871,.2041,.8233]},{t:[.0324,-.0274,-.1363],r:[.8476,.3909,.031,-.3574]},{t:[.0392,-.0465,-.1142],r:[.9167,.3645,.16,-.0352]},{t:[.032,-.0501,-.0915],r:[.9167,.3645,.16,-.0352]},{t:[-.028,-.0348,-.0593],r:[.0757,-.1724,.308,.9326]},{t:[-.01,-.0186,-.1201],r:[-.5151,-.3075,.2332,.7654]},{t:[.018,-.0439,-.1306],r:[.8841,.4115,.0419,-.2175]},{t:[.0214,-.0572,-.1026],r:[.8915,.3885,.1955,.1266]},{t:[.0111,-.0549,-.0835],r:[.8915,.3885,.1955,.1266]},{t:[-.0357,-.0434,-.0601],r:[.0242,-.0998,.3079,.9459]},{t:[-.0254,-.037,-.1183],r:[-.4608,-.35,.2807,.7658]},{t:[.0022,-.0544,-.1281],r:[.8346,.4535,.0038,-.3127]},{t:[.0089,-.0663,-.1107],r:[.8657,.4769,.1519,-.0059]},{t:[.003,-.0699,-.0932],r:[.8657,.4769,.1519,-.0059]}],[Pi.ROCK]:[{t:[-.0123,-.0183,-.0267],r:[.5149,-.0845,-.1158,.8452],s:[1,1,1]},{t:[.0153,-.0052,-.0437],r:[.2665,-.0899,-.3721,.8846],s:[1,1,1]},{t:[.0335,.0154,-.0867],r:[.0177,.1842,-.6731,.716],s:[1,1,1]},{t:[.0267,.0228,-.1122],r:[.0728,.2226,-.6735,.7011],s:[1,1,1]},{t:[.019,.0341,-.1386],r:[.0728,.2226,-.6735,.7011],s:[1,1,1]},{t:[.0067,.0029,-.0406],r:[.475,-.2118,-.0726,.851],s:[1,1,1]},{t:[.0388,.061,-.0749],r:[.5779,-.1002,-.0602,.8077],s:[1,1,1]},{t:[.0481,.097,-.086],r:[.5059,-.0922,-.0672,.855],s:[1,1,1]},{t:[.0529,.1158,-.0964],r:[.4458,-.0565,-.053,.8918],s:[1,1,1]},{t:[.0562,.1334,-.1107],r:[.4458,-.0565,-.053,.8918],s:[1,1,1]},{t:[-.0052,.0075,-.0412],r:[.5055,-.126,-.0623,.8513],s:[1,1,1]},{t:[.0144,.0671,-.0735],r:[.1227,-.0631,-.0269,.9901],s:[1,1,1]},{t:[.0199,.0775,-.1133],r:[-.4479,-.0687,-.0876,.8871],s:[1,1,1]},{t:[.0211,.0534,-.1312],r:[-.6828,-.0523,-.1046,.7212],s:[1,1,1]},{t:[.0192,.0294,-.1316],r:[-.6828,-.0523,-.1046,.7212],s:[1,1,1]},{t:[-.0167,.0074,-.0424],r:[.491,-.0372,-.0778,.8669],s:[1,1,1]},{t:[-.0075,.0623,-.0758],r:[.1717,-.0904,.0273,.9806],s:[1,1,1]},{t:[-7e-4,.0753,-.1121],r:[-.3257,-.1136,-.0418,.9377],s:[1,1,1]},{t:[.005,.0561,-.1361],r:[-.5492,-.1111,-.0905,.8233],s:[1,1,1]},{t:[.0066,.0356,-.1433],r:[-.5492,-.1111,-.0905,.8233],s:[1,1,1]},{t:[-.0273,.0051,-.0431],r:[.4566,.0629,-.0766,.8841],s:[1,1,1]},{t:[-.0297,.0531,-.0769],r:[.3942,-.0035,.1163,.9116],s:[1,1,1]},{t:[-.0317,.0768,-.1013],r:[.4582,6e-4,.1099,.882],s:[1,1,1]},{t:[-.0341,.0951,-.1136],r:[.4085,-.0179,.0535,.911],s:[1,1,1]},{t:[-.0354,.1086,-.1266],r:[.4085,-.0179,.0535,.911],s:[1,1,1]}],[Pi.THUMBS_DOWN]:[{t:[-.0169,.0317,-.0845],r:[.2721,-.3488,-.6314,.6369],s:[1,1,1]},{t:[-.0019,.008,-.1021],r:[-.0533,.5043,.7891,-.3467],s:[1,1,1]},{t:[.0208,-.0318,-.1276],r:[-.2229,.6138,.7555,.0539],s:[1,1,1]},{t:[.0282,-.0578,-.1318],r:[-.2724,.6476,.7112,.0242],s:[1,1,1]},{t:[.0389,-.0856,-.1338],r:[-.2724,.6476,.7112,.0242],s:[1,1,1]},{t:[.0046,.0177,-.0997],r:[.1919,-.3993,-.6438,.6238],s:[1,1,1]},{t:[.0618,-.0034,-.1463],r:[-.1884,.0883,-.6795,.7035],s:[1,1,1]},{t:[.0481,-.0093,-.1821],r:[.6204,-.5352,.4297,-.3794],s:[1,1,1]},{t:[.0275,-.0094,-.1746],r:[.6806,-.6532,.2814,-.176],s:[1,1,1]},{t:[.0141,-.0064,-.1561],r:[.6806,-.6532,.2814,-.176],s:[1,1,1]},{t:[.0062,.0299,-.1019],r:[.2399,-.3631,-.598,.6731],s:[1,1,1]},{t:[.0621,.0218,-.1466],r:[-.241,.1225,-.6156,.7403],s:[1,1,1]},{t:[.0427,.0133,-.1823],r:[.7097,-.4862,.373,-.3475],s:[1,1,1]},{t:[.0165,.0095,-.1681],r:[.7968,-.5892,.1321,-.0209],s:[1,1,1]},{t:[.0119,.0128,-.1447],r:[.7968,-.5892,.1321,-.0209],s:[1,1,1]},{t:[.0033,.0406,-.1037],r:[.2574,-.3085,-.5681,.7183],s:[1,1,1]},{t:[.052,.0419,-.1485],r:[-.2306,.1278,-.5499,.7925],s:[1,1,1]},{t:[.0339,.0328,-.182],r:[.7575,-.4754,.2861,-.344],s:[1,1,1]},{t:[.0099,.025,-.1634],r:[.843,-.5293,.0926,-.0248],s:[1,1,1]},{t:[.0068,.0266,-.142],r:[.843,-.5293,.0926,-.0248],s:[1,1,1]},{t:[-.0018,.0508,-.104],r:[.2798,-.2351,-.5355,.7614],s:[1,1,1]},{t:[.0378,.0613,-.1483],r:[-.1652,.0952,-.5046,.842],s:[1,1,1]},{t:[.0259,.054,-.1792],r:[.7429,-.4404,.2677,-.4273],s:[1,1,1]},{t:[.0084,.0449,-.169],r:[.8704,-.4542,.1121,-.1532],s:[1,1,1]},{t:[.002,.0431,-.1514],r:[.8704,-.4542,.1121,-.1532],s:[1,1,1]}],[Pi.VICTORY]:[{t:[-.0485,-.0629,-.0748],r:[.5235,.0269,-.0122,.8515],s:[1,1,1]},{t:[-.0274,-.0424,-.0935],r:[.2683,-.0091,-.2476,.9309],s:[1,1,1]},{t:[-.0197,-.0171,-.1372],r:[-.0874,.2587,-.5403,.7959],s:[1,1,1]},{t:[-.0337,-.0134,-.1604],r:[-.1021,.3471,-.5231,.7717],s:[1,1,1]},{t:[-.0538,-.0084,-.1819],r:[-.1021,.3471,-.5231,.7717],s:[1,1,1]},{t:[-.0376,-.037,-.0897],r:[.5048,-.107,.0348,.8559],s:[1,1,1]},{t:[-.0266,.0281,-.1246],r:[.567,-.0696,.0098,.8207],s:[1,1,1]},{t:[-.0224,.0646,-.1371],r:[.5031,-.0677,.0059,.8615],s:[1,1,1]},{t:[-.0201,.0836,-.1477],r:[.4589,-.0365,.0223,.8874],s:[1,1,1]},{t:[-.019,.1018,-.1617],r:[.4589,-.0365,.0223,.8874],s:[1,1,1]},{t:[-.0503,-.0361,-.0891],r:[.5225,-.0136,.0382,.8517],s:[1,1,1]},{t:[-.0515,.0267,-.1211],r:[.5428,.1035,.1149,.8255],s:[1,1,1]},{t:[-.0638,.0631,-.1369],r:[.5306,.067,.0906,.8401],s:[1,1,1]},{t:[-.0702,.0896,-.1495],r:[.5467,.0608,.081,.8312],s:[1,1,1]},{t:[-.0747,.1108,-.1601],r:[.5467,.0608,.081,.8312],s:[1,1,1]},{t:[-.0613,-.0396,-.0891],r:[.4925,.0763,.0204,.8667],s:[1,1,1]},{t:[-.0712,.0158,-.1219],r:[.2546,-.0246,.1592,.9535],s:[1,1,1]},{t:[-.0722,.0349,-.1561],r:[-.2354,-.1181,.1042,.959],s:[1,1,1]},{t:[-.0638,.0217,-.1832],r:[-.4573,-.1496,.0503,.8752],s:[1,1,1]},{t:[-.0571,.0041,-.1941],r:[-.4573,-.1496,.0503,.8752],s:[1,1,1]},{t:[-.0706,-.045,-.0892],r:[.4433,.1733,.0233,.8791],s:[1,1,1]},{t:[-.0898,6e-4,-.1216],r:[.0458,-.1976,.107,.9733],s:[1,1,1]},{t:[-.0762,.0038,-.1526],r:[-.348,-.2273,.0117,.9095],s:[1,1,1]},{t:[-.0668,-.0095,-.1675],r:[-.5475,-.2656,-.0806,.7894],s:[1,1,1]},{t:[-.0618,-.0269,-.1725],r:[-.5475,-.2656,-.0806,.7894],s:[1,1,1]}]}),Ai=Object.freeze({[Pi.RELAXED]:[{t:[.05,-.08,-.1],r:[.5373,0,0,.8434]},{t:[.0279,-.0592,-.1167],r:[.3237,.1161,.293,.8921]},{t:[.0026,-.0313,-.158],r:[.2171,.0194,.5207,.8254]},{t:[-.0042,-.0219,-.1837],r:[.2597,-.0685,.6498,.711]},{t:[-.01,-.0084,-.2107],r:[.2597,-.0685,.6498,.711]},{t:[.037,-.0539,-.1123],r:[.5808,.1164,-.0414,.8046]},{t:[.0238,.0151,-.147],r:[.3081,.0484,-.0273,.9497]},{t:[.0206,.0393,-.1786],r:[-.0461,.0526,-.0104,.9975]},{t:[.0185,.0373,-.201],r:[-.1674,.0162,-.0064,.9857]},{t:[.0177,.0287,-.223],r:[-.1674,.0162,-.0064,.9857]},{t:[.05,-.0527,-.1126],r:[.5619,.0306,-.0478,.8252]},{t:[.0497,.0138,-.1449],r:[.353,.0474,-.1014,.9289]},{t:[.0491,.0425,-.1767],r:[.0777,.1076,-.0559,.9896]},{t:[.0431,.0478,-.2066],r:[-.0679,.1248,-.0343,.9893]},{t:[.0369,.0436,-.2302],r:[-.0679,.1248,-.0343,.9893]},{t:[.0614,-.0561,-.1136],r:[.5303,-.05,-.0384,.8455]},{t:[.0699,.0028,-.1472],r:[.4168,.0427,-.1662,.8926]},{t:[.0722,.0331,-.1739],r:[.1339,.1107,-.1236,.977]},{t:[.0665,.0425,-.2041],r:[-.0175,.1318,-.0809,.9878]},{t:[.0606,.0413,-.2257],r:[-.0175,.1318,-.0809,.9878]},{t:[.0711,-.0618,-.1145],r:[.4891,-.1378,-.0535,.8596]},{t:[.0892,-.0127,-.1484],r:[.3439,.0196,-.23,.9102]},{t:[.0924,.0087,-.1761],r:[.1965,.0585,-.2173,.9543]},{t:[.0921,.0184,-.1968],r:[.0936,.1069,-.1575,.9773]},{t:[.0896,.0217,-.2157],r:[.0936,.1069,-.1575,.9773]}],[Pi.PINCHING]:[{t:[.05,-.08,-.1],r:[.5373,0,0,.8434],s:[1,1,1]},{t:[.0279,-.0593,-.1166],r:[.307,.046,.2483,.9176],s:[1,1,1]},{t:[.0082,-.0291,-.1587],r:[.1833,-.0669,.4657,.8632],s:[.9999,1,1]},{t:[.0071,-.0186,-.185],r:[.2256,-.1369,.6093,.7477],s:[1,1,.9999]},{t:[.0064,-.0039,-.212],r:[.2256,-.1369,.6093,.7477],s:[1,1,.9999]},{t:[.037,-.0539,-.1122],r:[.5831,.1146,-.0388,.8034],s:[1,.9999,1]},{t:[.0237,.0153,-.147],r:[.1209,.0891,.0196,.9885],s:[1,.9999,1]},{t:[.0163,.0257,-.1849],r:[-.2747,.0723,.0511,.9574],s:[1,.9999,.9999]},{t:[.014,.0138,-.204],r:[-.3165,.0337,.0633,.9459],s:[1,.9999,1]},{t:[.0136,-.0012,-.2226],r:[-.3165,.0337,.0633,.9459],s:[1,.9999,1]},{t:[.0501,-.0527,-.1126],r:[.5625,.0291,-.0455,.825],s:[1,1,1]},{t:[.0497,.0141,-.1449],r:[.3465,.0658,-.0921,.9312],s:[1.0001,.9999,.9999]},{t:[.0473,.0424,-.177],r:[.0559,.1235,-.0403,.9899],s:[1.0001,1,.9999]},{t:[.0402,.0463,-.2069],r:[-.0703,.1381,-.0195,.9877],s:[1.0001,1,.9999]},{t:[.0335,.0419,-.2304],r:[-.0703,.1381,-.0195,.9877],s:[1.0001,1,.9999]},{t:[.0615,-.0561,-.1136],r:[.5287,-.0513,-.0363,.8465],s:[1.0001,1,.9999]},{t:[.07,.003,-.1472],r:[.4197,.0598,-.1607,.8913],s:[1,1,.9999]},{t:[.0709,.0336,-.1737],r:[.1329,.1258,-.1128,.9766],s:[1,1,1]},{t:[.0643,.0431,-.2038],r:[-.0172,.145,-.068,.9869],s:[1.0001,.9999,1]},{t:[.0577,.0418,-.2253],r:[-.0172,.145,-.068,.9869],s:[1.0001,.9999,1]},{t:[.0711,-.0617,-.1145],r:[.4861,-.139,-.0517,.8612],s:[1.0001,.9999,1]},{t:[.0893,-.0125,-.1485],r:[.317,.0459,-.2224,.9208],s:[1.0001,.9999,1]},{t:[.0902,.0078,-.1772],r:[.1921,.0784,-.2077,.9559],s:[1,1,.9999]},{t:[.0889,.0174,-.1979],r:[.0936,.1253,-.1462,.9768],s:[1.0001,1,1]},{t:[.0857,.0208,-.2167],r:[.0936,.1253,-.1462,.9768],s:[1.0001,1,1]}],[Pi.FIST]:[{t:[.0504,-.0155,-.1083],r:[.1392,.117,-.058,.9816]},{t:[.022,-.0122,-.1291],r:[-.0068,.3422,.1705,.924]},{t:[-.011,-.019,-.1691],r:[-.0952,.2257,.5977,.7634]},{t:[-.0171,-.0305,-.1932],r:[-.249,.0162,.627,.738]},{t:[-.0073,-.0427,-.2185],r:[-.249,.0162,.627,.738]},{t:[.0314,-.0068,-.133],r:[.1126,.213,-.1468,.9594]},{t:[.0035,.014,-.1987],r:[-.5177,.1865,.0124,.8349]},{t:[-.0086,-.0192,-.2148],r:[.9671,-.1129,-.1466,-.1747]},{t:[-.0031,-.0274,-.1952],r:[.9714,-.0492,-.2057,.1081]},{t:[.0063,-.0222,-.1749],r:[.9714,-.0492,-.2057,.1081]},{t:[.0441,-.0073,-.137],r:[.1251,.1341,-.1467,.972]},{t:[.0283,.0126,-.2028],r:[-.5227,.1469,-.0852,.8354]},{t:[.0144,-.0224,-.2202],r:[.9399,-.2078,-.0451,-.2671]},{t:[.0137,-.0382,-.1948],r:[.9665,-.181,-.1188,.1381]},{t:[.0207,-.0318,-.1726],r:[.9665,-.181,-.1188,.1381]},{t:[.0559,-.0112,-.1379],r:[.0948,.0732,-.1351,.9836]},{t:[.0482,.0022,-.2011],r:[-.5015,.1223,-.1588,.8416]},{t:[.0337,-.0294,-.2191],r:[.9432,-.2267,.0156,-.2423]},{t:[.0294,-.0438,-.1916],r:[.9569,-.2379,-.08,.1464]},{t:[.0346,-.0376,-.1714],r:[.9569,-.2379,-.08,.1464]},{t:[.0662,-.0164,-.1368],r:[.0546,-.0084,-.1349,.9893]},{t:[.068,-.0102,-.1955],r:[-.4587,.1335,-.2099,.853]},{t:[.0529,-.0353,-.2127],r:[.9107,-.2444,.0606,-.3274]},{t:[.0466,-.0483,-.1959],r:[.9518,-.3056,-.0236,.0063]},{t:[.0488,-.0485,-.1773],r:[.9518,-.3056,-.0236,.0063]}],[Pi.THUMBS_UP]:[{t:[.0317,-.0212,-.089],r:[.2199,.1003,-.594,.7673]},{t:[.0223,.009,-.1042],r:[.4294,.285,-.3619,.7768]},{t:[.0158,.0521,-.1273],r:[.6012,.067,-.0513,.7947]},{t:[.0145,.0784,-.1348],r:[.597,.0134,-.0918,.7968]},{t:[.0163,.1065,-.1446],r:[.597,.0134,-.0918,.7968]},{t:[.0303,.0032,-.1103],r:[.2434,.2002,-.656,.6858]},{t:[.0337,.0475,-.1698],r:[-.3298,.4729,-.4297,.6949]},{t:[-.0026,.0462,-.1835],r:[.7134,-.6368,-2e-4,-.2925]},{t:[-.0107,.0369,-.1654],r:[.7745,-.5891,-.2133,-.0877]},{t:[-.0047,.0282,-.145],r:[.7745,-.5891,-.2133,-.0877]},{t:[.0347,-.0077,-.1158],r:[.2088,.1254,-.6589,.7117]},{t:[.0416,.0251,-.1782],r:[-.3597,.4829,-.4746,.6421]},{t:[.0018,.0251,-.19],r:[-.673,.7069,-.0014,.2177]},{t:[-.0077,.0162,-.163],r:[.6957,-.6456,-.2988,.0994]},{t:[.0063,.0104,-.1443],r:[.6957,-.6456,-.2988,.0994]},{t:[.0361,-.0196,-.1178],r:[.1467,.0923,-.6537,.7367]},{t:[.0398,.0027,-.1801],r:[-.3611,.446,-.5466,.6099]},{t:[.0028,.0047,-.193],r:[-.6782,.7246,-.0014,.1226]},{t:[-.003,-6e-4,-.1628],r:[-.652,.6801,.2937,-.1613]},{t:[.0108,-.0046,-.1465],r:[-.652,.6801,.2937,-.1613]},{t:[.0343,-.0315,-.1182],r:[.0757,.0463,-.6692,.7378]},{t:[.0363,-.021,-.1779],r:[-.3141,.3981,-.6168,.602]},{t:[.0062,-.0166,-.1931],r:[-.6691,.7354,-.0331,.1021]},{t:[.0012,-.0185,-.1716],r:[-.6175,.7316,.235,-.168]},{t:[.0116,-.0223,-.1564],r:[-.6175,.7316,.235,-.168]}],[Pi.POINTING]:[{t:[-.0042,-.0248,-.0222],r:[.1163,-.0095,-.3006,.9466]},{t:[-.024,-.0114,-.048],r:[-.052,.2376,-.0719,.9673]},{t:[-.0482,-.0149,-.0937],r:[-.2324,.2162,.3797,.869]},{t:[-.0535,-.0306,-.1155],r:[-.2846,.1212,.4068,.8595]},{t:[-.0521,-.0492,-.1388],r:[-.2846,.1212,.4068,.8595]},{t:[-.0129,-.0119,-.0508],r:[.1258,.0866,-.3895,.9083]},{t:[-.0173,.01,-.1215],r:[.1174,-.0564,-.3421,.9306]},{t:[-.0097,.018,-.1587],r:[-.0512,.0028,-.347,.9365]},{t:[-.0105,.0158,-.1805],r:[-.1583,.003,-.3458,.9249]},{t:[-.0137,.0085,-.2021],r:[-.1583,.003,-.3458,.9249]},{t:[-.0017,-.019,-.052],r:[.1155,.0062,-.386,.9152]},{t:[.0038,-.0037,-.1206],r:[-.2494,.0619,-.3947,.8822]},{t:[-.0086,-.0197,-.1569],r:[-.7146,.3231,-.2612,.5628]},{t:[-.0306,-.0389,-.1502],r:[.8643,-.4054,.1306,-.2676]},{t:[-.0406,-.0469,-.1297],r:[.8643,-.4054,.1306,-.2676]},{t:[.0068,-.0279,-.0499],r:[.0671,-.0438,-.3807,.9212]},{t:[.0155,-.022,-.1146],r:[-.3096,.1005,-.4385,.8377]},{t:[-.0022,-.0389,-.1452],r:[.7388,-.369,.2794,-.4899]},{t:[-.0264,-.0553,-.1341],r:[.852,-.4611,.1257,-.214]},{t:[-.0346,-.0602,-.1146],r:[.852,-.4611,.1257,-.214]},{t:[.0126,-.0374,-.0464],r:[.0105,-.1129,-.3882,.9146]},{t:[.0254,-.0415,-.1045],r:[-.3088,.1125,-.4825,.8119]},{t:[.0078,-.0548,-.1304],r:[-.6368,.3211,-.3767,.5912]},{t:[-.0112,-.0661,-.1307],r:[.7535,-.4639,.2523,-.3916]},{t:[-.0244,-.0737,-.1196],r:[.7535,-.4639,.2523,-.3916]}],[Pi.ROCK]:[{t:[.0015,-.0417,-.0513],r:[.5617,.0123,.1355,.8161],s:[1,1,1]},{t:[-.0235,-.025,-.07],r:[.2818,.0046,.4006,.8718],s:[1,1,1]},{t:[-.0354,-1e-4,-.1128],r:[-.0257,-.2764,.6652,.6931],s:[1,1,1]},{t:[-.0238,.0089,-.1359],r:[-6e-4,-.3419,.6556,.6733],s:[1,1,1]},{t:[-.0088,.0215,-.1584],r:[-6e-4,-.3419,.6556,.6733],s:[1,1,1]},{t:[-.015,-.0179,-.0645],r:[.5302,.1299,.1154,.8299],s:[1,1,1]},{t:[-.0403,.0456,-.0947],r:[.5874,.0115,.0813,.8051],s:[1,1,1]},{t:[-.0451,.0825,-.1058],r:[.5048,.001,.0806,.8595],s:[1,1,1]},{t:[-.0468,.1015,-.1165],r:[.4494,-.0352,.0601,.8906],s:[1,1,1]},{t:[-.0465,.1195,-.1308],r:[.4494,-.0352,.0601,.8906],s:[1,1,1]},{t:[-.0029,-.0139,-.063],r:[.5567,.046,.0996,.8234],s:[1,1,1]},{t:[-.016,.0502,-.0895],r:[.1657,-.0189,.0053,.986],s:[1,1,1]},{t:[-.0146,.0642,-.1285],r:[-.4455,.0104,.0258,.8948],s:[1,1,1]},{t:[-.0143,.0404,-.1468],r:[-.7027,.0133,.0292,.7107],s:[1,1,1]},{t:[-.0137,.0163,-.146],r:[-.7027,.0133,.0292,.7107],s:[1,1,1]},{t:[.0087,-.0144,-.0627],r:[.5389,-.0411,.1061,.8346],s:[1,1,1]},{t:[.0058,.0446,-.0897],r:[.2331,.0139,-.0389,.9716],s:[1,1,1]},{t:[.0052,.0621,-.1248],r:[-.3041,.0513,-.0024,.9512],s:[1,1,1]},{t:[.0022,.0442,-.1503],r:[-.5472,.0609,.0335,.8341],s:[1,1,1]},{t:[9e-4,.0239,-.1579],r:[-.5472,.0609,.0335,.8341],s:[1,1,1]},{t:[.0194,-.0172,-.0627],r:[.5054,-.1365,.0899,.8473],s:[1,1,1]},{t:[.0276,.0346,-.0893],r:[.4597,-.0527,-.1093,.8797],s:[1,1,1]},{t:[.0334,.0611,-.1099],r:[.5162,-.056,-.0989,.8489],s:[1,1,1]},{t:[.0378,.0805,-.1194],r:[.4448,-.0407,-.0462,.8935],s:[1,1,1]},{t:[.0411,.0949,-.1311],r:[.4448,-.0407,-.0462,.8935],s:[1,1,1]}],[Pi.THUMBS_DOWN]:[{t:[.0237,.033,-.083],r:[.325,.2979,.5612,.7004],s:[1,1,1]},{t:[.0039,.0142,-.1018],r:[.0744,.4501,.7672,.4508],s:[1,1,1]},{t:[-.0239,-.0191,-.133],r:[.2089,.5732,.7915,.0363],s:[1,1,1]},{t:[-.0341,-.0435,-.1401],r:[.2664,.6251,.7316,.0555],s:[1,1,1]},{t:[-.0476,-.0698,-.144],r:[.2664,.6251,.7316,.0555],s:[1,1,1]},{t:[-3e-4,.0251,-.0989],r:[.2488,.3591,.5717,.6944],s:[1,1,1]},{t:[-.0603,.0201,-.1463],r:[-.2217,-.1036,.5936,.7667],s:[1,1,1]},{t:[-.045,.0116,-.1809],r:[.681,.4806,-.3657,-.4143],s:[1,1,1]},{t:[-.0253,.0071,-.1724],r:[.7487,.5817,-.2444,-.2032],s:[1,1,1]},{t:[-.0121,.0068,-.1535],r:[.7487,.5817,-.2444,-.2032],s:[1,1,1]},{t:[.001,.0374,-.1005],r:[.2971,.3158,.527,.7309],s:[1,1,1]},{t:[-.0548,.0447,-.1454],r:[-.2475,-.1117,.5236,.8076],s:[1,1,1]},{t:[-.0369,.0331,-.181],r:[.759,.413,-.3155,-.3922],s:[1,1,1]},{t:[-.0126,.0231,-.1665],r:[.8595,.4988,-.1065,-.0339],s:[1,1,1]},{t:[-.0084,.0248,-.1428],r:[.8595,.4988,-.1065,-.0339],s:[1,1,1]},{t:[.0064,.0472,-.1018],r:[.3122,.2567,.4998,.766],s:[1,1,1]},{t:[-.0402,.0619,-.1463],r:[-.22,-.1072,.4537,.8569],s:[1,1,1]},{t:[-.025,.0506,-.1806],r:[.8003,.3914,-.2353,-.3886],s:[1,1,1]},{t:[-.0035,.0369,-.1624],r:[.8979,.4322,-.0728,-.0395],s:[1,1,1]},{t:[-8e-4,.0373,-.1409],r:[.8979,.4322,-.0728,-.0395],s:[1,1,1]},{t:[.0136,.0558,-.1017],r:[.3278,.1772,.4672,.8018],s:[1,1,1]},{t:[-.0219,.0775,-.1452],r:[-.1811,-.0932,.4016,.8929],s:[1,1,1]},{t:[-.0108,.0677,-.1758],r:[.7842,.3582,-.2073,-.4623],s:[1,1,1]},{t:[.004,.0547,-.1656],r:[.9158,.3542,-.0821,-.1706],s:[1,1,1]},{t:[.0096,.0511,-.1481],r:[.9158,.3542,-.0821,-.1706],s:[1,1,1]}],[Pi.VICTORY]:[{t:[-.0017,-.0652,-.0663],r:[.5651,.0392,-.0573,.8221],s:[1,1,1]},{t:[-.0247,-.042,-.0786],r:[.3207,.0849,.243,.9115],s:[1,1,1]},{t:[-.0407,-.0141,-.1186],r:[-.0285,-.1953,.5625,.8029],s:[1,1,1]},{t:[-.031,-.0094,-.1439],r:[-.0751,-.3079,.5331,.7845],s:[1,1,1]},{t:[-.0133,-.0043,-.1673],r:[-.0751,-.3079,.5331,.7845],s:[1,1,1]},{t:[-.0136,-.0376,-.076],r:[.5464,.1682,-.0848,.8161],s:[1,1,1]},{t:[-.0272,.0313,-.1019],r:[.6129,.1411,-.0752,.7738],s:[1,1,1]},{t:[-.032,.0692,-.1089],r:[.5643,.143,-.0679,.8103],s:[1,1,1]},{t:[-.0353,.0897,-.1161],r:[.5256,.1162,-.0834,.8386],s:[1,1,1]},{t:[-.038,.11,-.1265],r:[.5256,.1162,-.0834,.8386],s:[1,1,1]},{t:[-9e-4,-.0372,-.0776],r:[.5593,.0765,-.0968,.8197],s:[1,1,1]},{t:[-.0021,.0287,-.1033],r:[.6072,-.0412,-.1868,.7712],s:[1,1,1]},{t:[.01,.0671,-.1136],r:[.5687,2e-4,-.1587,.8071],s:[1,1,1]},{t:[.0156,.0946,-.124],r:[.5609,.0092,-.1498,.8142],s:[1,1,1]},{t:[.019,.1163,-.1339],r:[.5609,.0092,-.1498,.8142],s:[1,1,1]},{t:[.0096,-.0411,-.08],r:[.5291,-.0092,-.0837,.8443],s:[1,1,1]},{t:[.0165,.0173,-.1087],r:[.2191,.1389,-.1874,.9474],s:[1,1,1]},{t:[.009,.0353,-.1427],r:[-.3548,.2386,-.0503,.9026],s:[1,1,1]},{t:[-.0055,.0162,-.1628],r:[-.5898,.2546,.0402,.7653],s:[1,1,1]},{t:[-.0126,-.0042,-.1657],r:[-.5898,.2546,.0402,.7653],s:[1,1,1]},{t:[.0184,-.0469,-.0826],r:[.4806,-.0996,-.0936,.8662],s:[1,1,1]},{t:[.034,.0014,-.1134],r:[.079,.2891,-.1225,.9461],s:[1,1,1]},{t:[.0152,.0077,-.141],r:[-.2784,.3171,.0012,.9066],s:[1,1,1]},{t:[.0023,-.0029,-.1556],r:[-.458,.3482,.1094,.8106],s:[1,1,1]},{t:[-.0053,-.0187,-.1623],r:[-.458,.3482,.1094,.8106],s:[1,1,1]}]}),Oi=Object.freeze({[Pi.RELAXED]:"Relaxed",[Pi.PINCHING]:"Pinching",[Pi.FIST]:"Fist",[Pi.THUMBS_UP]:"Thumbs Up",[Pi.POINTING]:"Pointing",[Pi.ROCK]:"Rock",[Pi.THUMBS_DOWN]:"Thumbs Down",[Pi.VICTORY]:"Victory"});class Ii{}const Li=new e.Vector3,Vi=new e.Quaternion;class Bi{constructor(t,i){this.simulatorControllerState=t,this.simulatorScene=i,this.leftController=new e.Object3D,this.rightController=new e.Object3D,this.leftHandBones=[],this.rightHandBones=[],this.leftHandPose=Pi.RELAXED,this.rightHandPose=Pi.RELAXED,this.leftHandTargetJoints=_i[Pi.RELAXED],this.rightHandTargetJoints=Ai[Pi.RELAXED],this.lerpSpeed=.1,this.onHandPoseChangeRequestBound=this.onHandPoseChangeRequest.bind(this),this.leftXRHand=new Ii,this.rightXRHand=new Ii}init({input:e}){this.input=e,this.loadMeshes(),this.simulatorScene.add(this.leftController),this.simulatorScene.add(this.rightController)}loadMeshes(){this.loader=new o,this.loader.setPath("https://cdn.jsdelivr.net/npm/@webxr-input-profiles/assets@1.0/dist/profiles/generic-hand/"),this.loader.load("left.glb",e=>{this.leftHand=e.scene,this.leftController.add(this.leftHand),Ze.forEach(t=>{const i=e.scene.getObjectByName(t);i?this.leftHandBones.push(i):console.warn(`Couldn't find ${t} in left hand mesh`)}),this.setLeftHandJoints(this.leftHandTargetJoints),this.input.hands[0]?.dispatchEvent?.({type:"connected",data:{hand:this.leftXRHand,handedness:"left"}})}),this.loader.load("right.glb",e=>{this.rightHand=e.scene,this.rightController.add(this.rightHand),Ze.forEach(t=>{const i=e.scene.getObjectByName(t);i?this.rightHandBones.push(i):console.warn(`Couldn't find ${t} in right hand mesh`)}),this.setRightHandJoints(this.rightHandTargetJoints),this.input.hands[1]?.dispatchEvent?.({type:"connected",data:{hand:this.rightXRHand,handedness:"right"}})})}setLeftHandLerpPose(e){this.leftHandPose!==e&&(e===Pi.PINCHING?this.input.dispatchEvent({type:"selectstart",target:this.input.controllers[0],data:{handedness:"left"}}):this.leftHandPose===Pi.PINCHING&&this.input.dispatchEvent({type:"selectend",target:this.input.controllers[0],data:{handedness:"left"}}),this.leftHandPose=e,this.leftHandTargetJoints=_i[e],this.updateHandPosePanel())}setRightHandLerpPose(e){this.rightHandPose!==e&&(e===Pi.PINCHING?this.input.dispatchEvent({type:"selectstart",target:this.input.controllers[1],data:{handedness:"right"}}):this.rightHandPose===Pi.PINCHING&&this.input.dispatchEvent({type:"selectend",target:this.input.controllers[1],data:{handedness:"right"}}),this.rightHandPose=e,this.rightHandTargetJoints=Ai[e],this.updateHandPosePanel())}setLeftHandJoints(e){this.leftHandPose===Pi.PINCHING&&this.input.dispatchEvent({type:"selectend",target:this.input.controllers[1],data:{handedness:"left"}}),e!=this.leftHandTargetJoints&&(this.leftHandPose=void 0,this.leftHandTargetJoints=e);for(let t=0;t<this.leftHandBones.length;t++){const i=this.leftHandBones[t],s=e[t];i&&s&&(i.position.fromArray(s.t),i.quaternion.fromArray(s.r),i.scale.fromArray([1,1,1]))}}setRightHandJoints(e){this.rightHandPose===Pi.PINCHING&&this.input.dispatchEvent({type:"selectend",target:this.input.controllers[1],data:{handedness:"right"}}),e!=this.rightHandTargetJoints&&(this.rightHandPose=void 0,this.rightHandTargetJoints=e);for(let t=0;t<this.rightHandBones.length;t++){const i=this.rightHandBones[t],s=e[t];i&&s&&(i.position.fromArray(s.t),i.quaternion.fromArray(s.r),i.scale.fromArray([1,1,1]))}}update(){this.lerpLeftHandPose(),this.lerpRightHandPose(),this.syncHandJoints()}lerpLeftHandPose(){for(let e=0;e<this.leftHandBones.length;e++){const t=this.leftHandBones[e],i=this.leftHandTargetJoints[e];t&&i&&(Li.fromArray(i.t),Vi.fromArray(i.r),t.position.lerp(Li,this.lerpSpeed),t.quaternion.slerp(Vi,this.lerpSpeed))}}lerpRightHandPose(){for(let e=0;e<this.rightHandBones.length;e++){const t=this.rightHandBones[e],i=this.rightHandTargetJoints[e];t&&i&&(Li.fromArray(i.t),Vi.fromArray(i.r),t.position.lerp(Li,this.lerpSpeed),t.quaternion.slerp(Vi,this.lerpSpeed))}}syncHandJoints(){const t=this.input.hands,i=t[0];if(i){this.leftController.updateWorldMatrix(!0,!1),i.position.setFromMatrixPosition(this.leftController.matrixWorld),i.setRotationFromMatrix(this.leftController.matrixWorld),i.updateMatrix();for(let t=0;t<this.leftHandBones.length;t++){const s=Ze[t];s in i.joints||(i.joints[s]=new e.Group,i.add(i.joints[s])),i.joints[s].position.copy(this.leftHandBones[t].position),i.joints[s].quaternion.copy(this.leftHandBones[t].quaternion),i.updateWorldMatrix(!1,!0)}}const s=t[1];if(s){this.rightController.updateWorldMatrix(!0,!1),s.position.setFromMatrixPosition(this.rightController.matrixWorld),s.setRotationFromMatrix(this.rightController.matrixWorld),s.updateMatrix();for(let t=0;t<this.rightHandBones.length;t++){const i=Ze[t];i in s.joints||(s.joints[i]=new e.Group,s.add(s.joints[i])),s.joints[i].position.copy(this.rightHandBones[t].position),s.joints[i].quaternion.copy(this.rightHandBones[t].quaternion),s.updateWorldMatrix(!1,!0)}}}setLeftHandPinching(e=!0){this.setLeftHandLerpPose(e?Pi.PINCHING:Pi.RELAXED)}setRightHandPinching(e=!0){this.setRightHandLerpPose(e?Pi.PINCHING:Pi.RELAXED)}showHands(){this.leftController.visible=!0,this.rightController.visible=!0;for(let e=0;e<this.input.hands.length;e++)this.input.hands[e].visible=!0;this.updateHandPosePanel()}hideHands(){this.leftController.visible=!1,this.rightController.visible=!1;for(let e=0;e<this.input.hands.length;e++)this.input.hands[e].visible=!1;this.updateHandPosePanel()}updateHandPosePanel(){this.handPosePanelElement&&(0===this.simulatorControllerState.currentControllerIndex?(this.handPosePanelElement.visible=this.leftController.visible,this.handPosePanelElement.handPose=this.leftHandPose):(this.handPosePanelElement.visible=this.rightController.visible,this.handPosePanelElement.handPose=this.rightHandPose))}setHandPosePanelElement(e){this.handPosePanelElement&&this.handPosePanelElement.removeEventListener(Ei.type,this.onHandPoseChangeRequestBound),e.addEventListener(Ei.type,this.onHandPoseChangeRequestBound),this.handPosePanelElement=e,this.updateHandPosePanel()}onHandPoseChangeRequest(e){if(e.type!=Ei.type)return;const t=e;0===this.simulatorControllerState.currentControllerIndex?this.setLeftHandLerpPose(t.pose):this.setRightHandLerpPose(t.pose)}toggleHandedness(){this.simulatorControllerState.currentControllerIndex=(this.simulatorControllerState.currentControllerIndex+1)%2,this.updateHandPosePanel()}}class Fi{constructor(){this.elements=[],this.interfaceVisible=!0}init(e,t,i){this.createModeIndicator(e,t),this.showGeminiLivePanel(e),this.createHandPosePanel(e,i),this.showInstructions(e)}createModeIndicator(e,t){if(e.modeIndicator.enabled){const i=document.createElement(e.modeIndicator.element);document.body.appendChild(i),t.setModeIndicatorElement(i),this.elements.push(i)}}showInstructions(e){if(e.instructions.enabled){const t=document.createElement(e.instructions.element);t.customInstructions=e.instructions.customInstructions,document.body.appendChild(t),this.elements.push(t)}}showGeminiLivePanel(e){if(e.geminilive){const e=document.createElement("xrblocks-simulator-geminilive");document.body.appendChild(e),this.elements.push(e)}}createHandPosePanel(e,t){if(e.handPosePanel.enabled){const i=document.createElement(e.handPosePanel.element);document.body.appendChild(i),t.setHandPosePanelElement(i),this.elements.push(i)}}hideUiElements(){for(const e of this.elements)e.style.display="none";this.interfaceVisible=!1}showUiElements(){for(const e of this.elements)e.style.display="";this.interfaceVisible=!0}getInterfaceVisible(){return!this.interfaceVisible}toggleInterfaceVisible(){this.interfaceVisible?this.hideUiElements():this.showUiElements()}}class zi extends e.Scene{constructor(){super()}async init(t){this.addLights(),t.scenePath&&await this.loadGLTF(t.scenePath,new e.Vector3(t.initialScenePosition.x,t.initialScenePosition.y,t.initialScenePosition.z))}addLights(){this.add(new e.HemisphereLight(12303291,8947848,3))}async loadGLTF(e,t){const i=new o;return new Promise((s,n)=>{i.load(e,e=>{e.scene.position.copy(t),this.add(e.scene),this.gltf=e,s(e)},()=>{},e=>{n(e)})})}}async function ki(e,t,i){const s=e.constructor.dependencies;null!=s?await e.init(Object.fromEntries(Object.entries(s).map(([e,i])=>{const s=t.get(i);if(!s)throw new Error(`Dependency not found for key: ${i.name}`);return[e,s]}))):await e.init(i)}class ji extends S{static{this.dependencies={waitFrame:qe,registry:Ue}}constructor(){super(),this.journeyId=0}init({waitFrame:e,registry:t}){this.waitFrame=e,this.registry=t}stopJourney(){++this.journeyId}isOnJourneyId(e){return e==this.journeyId}async loadJourney(e){console.log("Load journey");const t=++this.journeyId;for(let i=0;this.isOnJourneyId(t)&&i<e.length;++i)ki(e[i],this.registry,void 0),await e[i].play({simulatorUser:this,journeyId:t,waitFrame:this.waitFrame});console.log("Journey finished")}}class Ui{constructor(e){this.renderer=e}}class Ni extends S{static{this.dependencies={simulatorOptions:zt,input:ct,timer:e.Timer,camera:e.Camera,renderer:e.WebGLRenderer,scene:e.Scene,registry:Ue,options:Kt,depth:Oe}}constructor(e){super(),this.renderMainScene=e,this.simulatorScene=new zi,this.depth=new Di(this.simulatorScene),this.simulatorControllerState=new ti,this.hands=new Bi(this.simulatorControllerState,this.simulatorScene),this.simulatorUser=new ji,this.userInterface=new Fi,this.controls=new Ri(this.simulatorControllerState,this.hands,this.setStereoRenderMode.bind(this),this.userInterface),this.renderDepthPass=!1,this.renderMode=Zt.DEFAULT,this.stereoCameras=[],this.initialized=!1,this.renderSimulatorSceneToCanvasBound=this.renderSimulatorSceneToCanvas.bind(this),this.add(this.simulatorUser)}async init({simulatorOptions:t,input:s,timer:n,camera:r,renderer:o,scene:a,registry:h,options:l,depth:c}){if(this.initialized)return;const d=h.get(je),u=h.get(ye);this.options=t,r.position.copy(this.options.initialCameraPosition),this.userInterface.init(t,this.controls,this.hands),o.autoClearColor=!1,await this.simulatorScene.init(t),this.hands.init({input:s}),this.controls.init({camera:r,input:s,timer:n,renderer:o,simulatorOptions:t}),d&&!this.camera&&(this.camera=new Yt(o),this.camera.init(),d.registerSimulatorCamera(this.camera)),l.depth.enabled&&(this.renderDepthPass=!0,this.depth.init(o,r,c),l.depth.depthMesh.enabled&&u&&r.add(u)),a.add(r),this.options.stereo.enabled&&this.setupStereoCameras(r),this.virtualSceneRenderTarget=new e.WebGLRenderTarget(o.domElement.width,o.domElement.height,{stencilBuffer:l.stencil});const p=new e.MeshBasicMaterial({map:this.virtualSceneRenderTarget.texture,transparent:!0});"screen"===this.options.blendingMode&&(p.blending=e.CustomBlending,p.blendSrc=e.OneFactor,p.blendDst=e.OneMinusSrcColorFactor,p.blendEquation=e.AddEquation),this.virtualSceneFullScreenQuad=new i(p),this.renderer=o,this.mainCamera=r,this.mainScene=a,this.registry=h,this.initialized=!0}simulatorUpdate(){this.controls.update(),this.hands.update(),this.renderDepthPass&&this.depth.update()}setStereoRenderMode(e){this.options.stereo.enabled&&(this.renderMode=e)}setupStereoCameras(e){const t=e.clone(),i=e.clone();t.layers.disableAll(),t.layers.enable(0),t.layers.enable(1),i.layers.disableAll(),i.layers.enable(0),i.layers.enable(2),t.position.set(-.0315,0,0),i.position.set(.0315,0,0),t.updateWorldMatrix(!0,!1),i.updateWorldMatrix(!0,!1),this.stereoCameras.length=0,this.stereoCameras.push(t,i),e.add(t,i),this.setStereoRenderMode(Zt.STEREO_LEFT)}onBeforeSimulatorSceneRender(){this.camera&&this.camera.onBeforeSimulatorSceneRender(this.mainCamera,this.renderSimulatorSceneToCanvasBound)}onSimulatorSceneRendered(){this.camera&&this.camera.onSimulatorSceneRendered()}getRenderCamera(){return{[Zt.DEFAULT]:this.mainCamera,[Zt.STEREO_LEFT]:this.stereoCameras[0],[Zt.STEREO_RIGHT]:this.stereoCameras[1]}[this.renderMode]}renderScene(){if(this.renderer&&this.options.renderToRenderTexture){if(this.virtualSceneRenderTarget.width!=this.renderer.domElement.width||this.virtualSceneRenderTarget.height!=this.renderer.domElement.height){const t=!!this.virtualSceneRenderTarget?.stencilBuffer;this.virtualSceneRenderTarget.dispose(),this.virtualSceneRenderTarget=new e.WebGLRenderTarget(this.renderer.domElement.width,this.renderer.domElement.height,{stencilBuffer:t}),this.virtualSceneFullScreenQuad.material.map=this.virtualSceneRenderTarget.texture}this.sparkRenderer=this.sparkRenderer||this.registry.get(Ui)?.renderer,this.sparkRenderer&&(this.sparkRenderer.defaultView.encodeLinear=!0),this.renderer.setRenderTarget(this.virtualSceneRenderTarget),this.renderer.clear(),this.renderMainScene(this.getRenderCamera())}}renderSimulatorScene(){this.onBeforeSimulatorSceneRender(),this.renderSimulatorSceneToCanvas(this.getRenderCamera()),this.onSimulatorSceneRendered(),this.options.renderToRenderTexture?this.virtualSceneFullScreenQuad.render(this.renderer):this.renderMainScene(this.getRenderCamera())}renderSimulatorSceneToCanvas(e){this.sparkRenderer&&(this.sparkRenderer.defaultView.encodeLinear=!1),this.renderer.setRenderTarget(null),this.renderer.render(this.simulatorScene,e),this.renderer.clearDepth()}}class Gi extends S{static{this.dependencies={registry:Ue}}constructor(e={}){super(),this.isCapturing=!1,this.latestAudioBuffer=null,this.accumulatedChunks=[],this.isAccumulating=!1,this.options={sampleRate:16e3,channelCount:1,echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0,...e}}init({registry:e}){this.registry=e}async startCapture(e={}){if(!this.isCapturing){this.onAudioData=e.onAudioData,this.onError=e.onError,this.isAccumulating=e.accumulate||!1,this.isAccumulating&&(this.accumulatedChunks=[]);try{await this.setupAudioCapture(),this.isCapturing=!0}catch(e){console.error("Failed to start audio capture:",e),this.onError?.(e),this.cleanup()}}}stopCapture(){this.isCapturing&&(this.cleanup(),this.isCapturing=!1)}async setupAudioCapture(){this.audioStream=await navigator.mediaDevices.getUserMedia({audio:!0,video:!1});const e=this.audioStream.getAudioTracks()[0].getSettings().sampleRate;this.audioContext=new AudioContext({sampleRate:e}),await this.setupAudioWorklet(),this.sourceNode=this.audioContext.createMediaStreamSource(this.audioStream),this.processorNode=new AudioWorkletNode(this.audioContext,"audio-capture-processor"),this.processorNode.port.onmessage=e=>{"audioData"===e.data.type&&(this.latestAudioBuffer=e.data.data,this.isAccumulating&&this.accumulatedChunks.push(e.data.data),this.onAudioData?.(e.data.data),this.streamToAI(e.data.data))},"suspended"===this.audioContext.state&&await this.audioContext.resume(),this.sourceNode.connect(this.processorNode)}async setupAudioWorklet(){const e=new Blob(["\n class AudioCaptureProcessor extends AudioWorkletProcessor {\n process(inputs, outputs, parameters) {\n const input = inputs[0];\n if (input && input[0]) {\n const inputData = input[0];\n const pcmData = new Int16Array(inputData.length);\n for (let i = 0; i < inputData.length; i++) {\n pcmData[i] = Math.max(-32768, Math.min(32767, inputData[i] * 32768));\n }\n this.port.postMessage({type: 'audioData', data: pcmData.buffer});\n }\n return true;\n }\n }\n registerProcessor('audio-capture-processor', AudioCaptureProcessor);\n "],{type:"application/javascript"}),t=URL.createObjectURL(e);await this.audioContext.audioWorklet.addModule(t),URL.revokeObjectURL(t)}streamToAI(e){if(!this.aiService?.sendRealtimeInput)return;const t=function(e){const t=new Uint8Array(e);let i="";for(let e=0;e<t.length;e++)i+=String.fromCharCode(t[e]);return btoa(i)}(e),i=this.audioContext?.sampleRate||this.options.sampleRate;this.aiService.sendRealtimeInput({audio:{data:t,mimeType:`audio/pcm;rate=${i}`}})}setAIStreaming(e){this.aiService=e?this.registry.get($):void 0}cleanup(){this.processorNode?.disconnect(),this.sourceNode?.disconnect(),this.audioContext&&"closed"!==this.audioContext.state&&this.audioContext.close(),this.audioStream?.getTracks().forEach(e=>e.stop()),this.processorNode=void 0,this.sourceNode=void 0,this.audioContext=void 0,this.audioStream=void 0,this.onAudioData=void 0,this.onError=void 0,this.latestAudioBuffer=null,this.accumulatedChunks=[],this.isAccumulating=!1,this.aiService=void 0}static isSupported(){return!(!navigator.mediaDevices||!navigator.mediaDevices.getUserMedia)}getIsCapturing(){return this.isCapturing}getLatestAudioBuffer(){return this.latestAudioBuffer}clearLatestAudioBuffer(){this.latestAudioBuffer=null}getAccumulatedBuffer(){if(0===this.accumulatedChunks.length)return null;const e=this.accumulatedChunks.reduce((e,t)=>e+t.byteLength,0),t=new ArrayBuffer(e),i=new Uint8Array(t);let s=0;for(const e of this.accumulatedChunks)i.set(new Uint8Array(e),s),s+=e.byteLength;return t}clearAccumulatedBuffer(){this.accumulatedChunks=[]}getAccumulatedChunkCount(){return this.accumulatedChunks.length}dispose(){this.stopCapture(),super.dispose()}}class Hi extends S{constructor(e={}){super(),this.options={},this.audioQueue=[],this.nextStartTime=0,this.volume=1,this.category="speech",this.options={sampleRate:24e3,channelCount:1,...e},e.category&&(this.category=e.category)}setCategoryVolumes(e){this.categoryVolumes=e,this.updateGainNodeVolume()}setVolume(e){this.volume=Math.max(0,Math.min(1,e)),this.updateGainNodeVolume()}updateGainNodeVolume(){if(this.gainNode&&this.categoryVolumes){const e=this.categoryVolumes.getEffectiveVolume(this.category,this.volume);this.gainNode.gain.value=e}else this.gainNode&&(this.gainNode.gain.value=this.volume)}async initializeAudioContext(){this.audioContext||(this.audioContext=new AudioContext({sampleRate:this.options.sampleRate}),this.nextStartTime=this.audioContext.currentTime,this.gainNode=this.audioContext.createGain(),this.gainNode.connect(this.audioContext.destination),this.updateGainNodeVolume()),"suspended"===this.audioContext.state&&await this.audioContext.resume()}async playAudioChunk(e){if(!e)return;await this.initializeAudioContext();const t=this.base64ToArrayBuffer(e),i=this.audioContext.createBuffer(this.options.channelCount,t.byteLength/2,this.options.sampleRate),s=i.getChannelData(0),n=new Int16Array(t);for(let e=0;e<n.length;e++)s[e]=n[e]/32768;this.audioQueue.push(i),this.scheduleAudioBuffers()}scheduleAudioBuffers(){for(;this.audioQueue.length>0&&this.nextStartTime<=this.audioContext.currentTime+.2;){const e=this.audioQueue.shift(),t=this.audioContext.currentTime,i=Math.max(this.nextStartTime,t),s=this.audioContext.createBufferSource();s.buffer=e,s.connect(this.gainNode||this.audioContext.destination),s.onended=()=>this.scheduleAudioBuffers(),s.start(i),this.nextStartTime=i+e.duration}}clearQueue(){this.audioQueue=[]}getIsPlaying(){return this.nextStartTime>this.audioContext.currentTime}getQueueLength(){return this.audioQueue.length}base64ToArrayBuffer(e){const t=atob(e),i=new Uint8Array(t.length);for(let e=0;e<t.length;e++)i[e]=t.charCodeAt(e);return i.buffer}stop(){this.clearQueue(),this.audioContext&&(this.audioContext.close(),this.audioContext=void 0,this.gainNode=void 0,this.nextStartTime=0)}static isSupported(){return!!("AudioContext"in window)}dispose(){this.stop(),super.dispose()}}const Wi=ae+"musicLibrary/",qi={ambient:Wi+"AmbientLoop.opus",background:Wi+"BackgroundMusic4.mp3",buttonHover:Wi+"ButtonHover.opus",buttonPress:Wi+"ButtonPress.opus",menuDismiss:Wi+"MenuDismiss.opus"};class Xi extends S{constructor(t,i){super(),this.listener=t,this.categoryVolumes=i,this.audioLoader=new e.AudioLoader,this.currentAudio=null,this.isPlaying=!1,this.musicLibrary=qi,this.specificVolume=.5,this.musicCategory="music"}setVolume(t){if(this.specificVolume=e.MathUtils.clamp(t,0,1),this.currentAudio&&this.isPlaying&&this.categoryVolumes){const e=this.categoryVolumes.getEffectiveVolume(this.musicCategory,this.specificVolume);this.currentAudio.setVolume(e),console.log(`BackgroundMusic volume updated to: ${e} (specific: ${this.specificVolume})`)}}playMusic(t,i="music"){if(!this.categoryVolumes||!this.listener||!this.audioLoader)return void console.error("BackgroundMusic not properly initialized.");const s=this.musicLibrary[t];if(!s)return void console.error(`BackgroundMusic: Music key "${t}" not found.`);this.stopMusic(),console.log(`BackgroundMusic: Loading sound: ${s}`),this.musicCategory=i;const n=this.listener;this.audioLoader.load(s,i=>{console.log(`BackgroundMusic: Successfully loaded ${s}`);const r=new e.Audio(n);r.setBuffer(i),r.setLoop("music"===this.musicCategory||"ambient"===this.musicCategory);const o=this.categoryVolumes.getEffectiveVolume(this.musicCategory,this.specificVolume);r.setVolume(o),console.log(`BackgroundMusic: Setting volume for "${t}" to ${o}`),r.play(),this.currentAudio=r,this.isPlaying=!0,console.log(`BackgroundMusic: Playing "${t}" in category "${this.musicCategory}"`)},e=>{console.log(`BackgroundMusic: Loading ${s} - ${(e.loaded/e.total*100).toFixed(0)}% loaded`)},e=>{console.error(`BackgroundMusic: Error loading sound ${s}:`,e),this.currentAudio=null,this.isPlaying=!1})}stopMusic(){this.currentAudio&&this.isPlaying&&(console.log("BackgroundMusic: Stopping current audio."),this.currentAudio.stop()),this.currentAudio=null,this.isPlaying=!1}destroy(){console.log("BackgroundMusic Destroying..."),this.stopMusic()}}var Ki;!function(e){e.music="music",e.sfx="sfx",e.speech="speech",e.ui="ui"}(Ki||(Ki={}));class $i{constructor(){this.isMuted=!1,this.masterVolume=1,this.volumes=Object.fromEntries(Object.values(Ki).map(e=>[e,1]))}getCategoryVolume(e){return this.volumes[e]??1}getEffectiveVolume(t,i=1){if(this.isMuted)return 0;const s=this.getCategoryVolume(t),n=e.MathUtils.clamp(i,0,1);return this.masterVolume*s*n}}const Qi={BEEP:{frequency:1e3,duration:.07,waveformType:"sine"},CLICK:[{frequency:1500,duration:.02,waveformType:"triangle",delay:0}],ACTIVATE:[{frequency:800,duration:.05,waveformType:"sine",delay:0},{frequency:1200,duration:.07,waveformType:"sine",delay:50}],DEACTIVATE:[{frequency:1200,duration:.05,waveformType:"sine",delay:0},{frequency:800,duration:.07,waveformType:"sine",delay:50}]};class Yi extends S{constructor(){super(...arguments),this.isInitialized=!1,this.debug=!1}_initAudioContext(){this.isInitialized||(this.audioContext=new AudioContext,this.isInitialized=!0,this.debug&&console.log("SoundSynthesizer: AudioContext initialized."))}playTone(e,t,i,s){if(this._initAudioContext(),!this.audioContext)return void console.error("SoundSynthesizer: AudioContext not available. Cannot play tone.");const n=this.audioContext.createOscillator();n.type=s,n.frequency.setValueAtTime(e,this.audioContext.currentTime);const r=this.audioContext.createGain();r.gain.setValueAtTime(i,this.audioContext.currentTime),n.connect(r),r.connect(this.audioContext.destination),n.start();const o=this.audioContext.currentTime+t,a=Math.max(.01,.1*t);r.gain.exponentialRampToValueAtTime(1e-5,o-a),n.stop(o)}playPresetTone(e,t=.5){const i=Qi[e];if(i)if(Array.isArray(i))i.forEach(e=>{setTimeout(()=>{this.playTone(e.frequency,e.duration,t,e.waveformType)},e.delay||0)});else{const e=i;this.playTone(e.frequency,e.duration,t,e.waveformType)}else console.warn(`SoundSynthesizer: Preset '${e}' not found.`)}}const Ji={ambient:"musicLibrary/AmbientLoop.opus",buttonHover:"musicLibrary/ButtonHover.opus",paintOneShot1:"musicLibrary/PaintOneShot1.opus"};let Zi=0;class es extends S{constructor(t,i){super(),this.listener=t,this.categoryVolumes=i,this.audioLoader=new e.AudioLoader,this.soundLibrary=Ji,this.activeSounds=new Map,this.specificVolume=1,this.category="sfx",this.defaultRefDistance=1,this.defaultRolloffFactor=1}playSoundAtObject(t,i,s={}){if(!this.listener||!this.audioLoader||!i)return console.error("SpatialAudio not properly initialized or targetObject missing."),null;const n=this.soundLibrary[t];if(!n)return console.error(`SpatialAudio: Sound key "${t}" not found.`),null;const r=++Zi,o=void 0!==s.volume?s.volume:this.specificVolume,a=s.loop||!1,h=void 0!==s.refDistance?s.refDistance:this.defaultRefDistance,l=void 0!==s.rolloffFactor?s.rolloffFactor:this.defaultRolloffFactor;return console.log(`SpatialAudio: Loading sound "${t}" (${n})`),this.audioLoader.load(n,n=>{if(console.log(`SpatialAudio: Successfully loaded "${t}"`),!this.listener)return void console.error("SpatialAudio: Listener lost during load.");const c=new e.PositionalAudio(this.listener);c.setBuffer(n),c.setLoop(a),c.setRefDistance(h),c.setRolloffFactor(l);const d=this.categoryVolumes.getEffectiveVolume(this.category,o);c.setVolume(d),i.add(c),this.activeSounds.set(r,{audio:c,target:i,options:s}),a||(c.onEnded=()=>{console.log(`SpatialAudio: Sound "${t}" (ID: ${r}) ended.`),this._cleanupSound(r),s.onEnded&&"function"==typeof s.onEnded&&s.onEnded(),c.onEnded=()=>{}}),c.play(),console.log(`SpatialAudio: Playing "${t}" (ID: ${r}) at object ${i.name||i.uuid}, Volume: ${d}`)},e=>{console.log(`SpatialAudio: Loading "${t}" - ${(e.loaded/e.total*100).toFixed(0)}% loaded`)},e=>{console.error(`SpatialAudio: Error loading sound "${t}":`,e),this.activeSounds.delete(r)}),r}stopSound(e){const t=this.activeSounds.get(e);t?(console.log(`SpatialAudio: Stopping sound ID: ${e}`),t.audio.isPlaying&&t.audio.stop(),this._cleanupSound(e)):console.warn(`SpatialAudio: Sound ID ${e} not found for stopping.`)}_cleanupSound(e){const t=this.activeSounds.get(e);if(t){if(t.audio.isPlaying)try{t.audio.stop()}catch{}t.target&&t.audio.parent===t.target&&t.target.remove(t.audio),this.activeSounds.delete(e),console.log(`SpatialAudio: Cleaned up sound ID: ${e}`)}}setVolume(t){this.specificVolume=e.MathUtils.clamp(t,0,1),console.log(`SpatialAudio default specific volume set to: ${this.specificVolume}`)}updateAllVolumes(){this.categoryVolumes&&(console.log(`SpatialAudio: Updating volumes for ${this.activeSounds.size} active sounds.`),this.activeSounds.forEach(e=>{const t=void 0!==e.options.volume?e.options.volume:this.specificVolume,i=this.categoryVolumes.getEffectiveVolume(this.category,t);e.audio.setVolume(i)}))}destroy(){console.log("SpatialAudio Destroying...");Array.from(this.activeSounds.keys()).forEach(e=>this.stopSound(e)),this.activeSounds.clear(),console.log("SpatialAudio Destroyed.")}}class ts extends S{static{this.dependencies={soundOptions:Ut}}constructor(e){super(),this.soundSynthesizer=e,this.isListening=!1,this.lastTranscript="",this.lastConfidence=0,this.playActivationSounds=!1,this.handleStartBound=this._handleStart.bind(this),this.handleResultBound=this._handleResult.bind(this),this.handleEndBound=this._handleEnd.bind(this),this.handleErrorBound=this._handleError.bind(this)}init({soundOptions:e}){this.options=e.speechRecognizer;const t=window.SpeechRecognition||window.webkitSpeechRecognition;if(!t)return console.warn("SpeechRecognizer: Speech Recognition API not supported in this browser."),void(this.error="API not supported");this.recognition=new t,this.recognition.lang=this.options.lang,this.recognition.continuous=this.options.continuous,this.recognition.interimResults=this.options.interimResults,this.recognition.onstart=this.handleStartBound,this.recognition.onresult=this.handleResultBound,this.recognition.onend=this.handleEndBound,this.recognition.onerror=this.handleErrorBound}onSimulatorStarted(){this.playActivationSounds=this.options.playSimulatorActivationSounds}start(){if(this.recognition)if(this.isListening)console.warn("SpeechRecognizer: Already listening.");else try{this.lastTranscript="",this.lastCommand=void 0,this.lastConfidence=0,this.error=void 0,this.recognition.start(),this.isListening=!0,console.debug("SpeechRecognizer: Listening started.")}catch(e){console.error("SpeechRecognizer: Error starting recognition:",e),this.error=e.message||"Start failed",this.isListening=!1,this.dispatchEvent({type:"error",error:this.error})}else console.error("SpeechRecognizer: Not initialized.")}stop(){if(this.recognition&&this.isListening)try{this.recognition.stop(),console.debug("SpeechRecognizer: Stop requested.")}catch(e){console.error("SpeechRecognizer: Error stopping recognition:",e),this.error=e.message||"Stop failed",this.isListening=!1}}getLastTranscript(){return this.lastTranscript}getLastCommand(){return this.lastCommand}getLastConfidence(){return this.lastConfidence}_handleStart(){console.debug("SpeechRecognizer: Listening started."),this.dispatchEvent({type:"start"}),this.playActivationSounds&&this.soundSynthesizer.playPresetTone("ACTIVATE")}_handleResult(e){let t="",i="",s=0;for(let n=e.resultIndex;n<e.results.length;++n){const r=e.results[n],o=r[0].transcript;r.isFinal?(i+=o,s=r[0].confidence):t+=o}if(this.lastTranscript=i.trim()||t.trim(),this.lastConfidence=s,this.lastCommand=void 0,i&&this.options.commands.length>0){const e=i.trim().toUpperCase();for(const t of this.options.commands)if(e.includes(t.toUpperCase())&&this.lastConfidence>=this.options.commandConfidenceThreshold){this.lastCommand=t,console.debug(`SpeechRecognizer Detected Command: ${this.lastCommand}`);break}}this.dispatchEvent({type:"result",originalEvent:e,transcript:this.lastTranscript,confidence:this.lastConfidence,command:this.lastCommand,isFinal:!!i})}_handleEnd(){this.isListening=!1,this.dispatchEvent({type:"end"}),this.options.continuous&&"aborted"!==this.error&&"no-speech"!==this.error?(console.debug("SpeechRecognizer: Restarting continuous listening..."),setTimeout(()=>this.start(),100)):this.playActivationSounds&&this.soundSynthesizer.playPresetTone("DEACTIVATE")}_handleError(e){console.error("SpeechRecognizer: Error:",e.error),this.error=e.error,this.isListening=!1,this.dispatchEvent({type:"error",error:e.error})}destroy(){this.stop(),this.recognition&&(this.recognition.onstart=null,this.recognition.onresult=null,this.recognition.onend=null,this.recognition.onerror=null,this.recognition=void 0)}}class is extends S{static{this.dependencies={soundOptions:Ut}}constructor(e,t=()=>{},i=()=>{},s=e=>{}){super(),this.categoryVolumes=e,this.onStartCallback=t,this.onEndCallback=i,this.onErrorCallback=s,this.synth=window.speechSynthesis,this.voices=[],this.isSpeaking=!1,this.debug=!1,this.specificVolume=1,this.speechCategory="speech",this.synth?(this.loadVoices(),void 0!==this.synth.onvoiceschanged&&(this.synth.onvoiceschanged=this.loadVoices.bind(this))):console.error("SpeechSynthesizer: Speech Synthesis API not supported."),!this.categoryVolumes&&this.synth&&console.warn("SpeechSynthesizer: CategoryVolumes not found. Volume control will use specificVolume only.")}init({soundOptions:e}){this.options=e.speechSynthesizer,this.debug&&console.log("SpeechSynthesizer initialized.")}loadVoices(){this.synth&&(this.voices=this.synth.getVoices(),this.debug&&console.log("SpeechSynthesizer: Voices loaded:",this.voices.length),this.selectedVoice=this.voices.find(e=>e.name.includes("Google")&&e.lang.startsWith("en"))||this.voices.find(e=>e.lang.startsWith("en")),this.selectedVoice?this.debug&&console.log("SpeechSynthesizer: Selected voice:",this.selectedVoice.name):console.warn("SpeechSynthesizer: No suitable default voice found."))}setVolume(t){this.specificVolume=e.MathUtils.clamp(t,0,1),console.log(`SpeechSynthesizer specific volume set to: ${this.specificVolume}`)}speak(t,i="en-US",s=1,n=1){return new Promise((r,o)=>{if(!this.synth)return console.warn("SpeechSynthesizer: Cannot speak. API not supported."),o(new Error("Speech Synthesis API not supported."));if(this.isSpeaking){if(!this.options.allowInterruptions){const e="Already speaking and interruptions are not allowed.";return console.warn(`SpeechSynthesizer: ${e}`),o(new Error(e))}console.warn("SpeechSynthesizer: Already speaking. Interrupting current speech."),this.cancel()}const a=new SpeechSynthesisUtterance(t);a.onstart=()=>{this.isSpeaking=!0,console.log("SpeechSynthesizer: Speaking started."),this.onStartCallback&&this.onStartCallback()},a.onend=()=>{this.isSpeaking=!1,console.log("SpeechSynthesizer: Speaking ended."),this.onEndCallback&&this.onEndCallback(),r()},a.onerror=e=>{!this.options.allowInterruptions||"interrupted"!==e.error&&"canceled"!==e.error?(console.error("SpeechSynthesizer: Error occurred:",e.error),this.isSpeaking=!1,this.onErrorCallback(new Error(`Speech synthesis error code ${e.error}`)),o(e.error)):console.warn(`SpeechSynthesizer: Speech utterance interrupted: ${e.error}`)};let h=this.selectedVoice;h&&h.lang.startsWith(i.substring(0,2))||(h=this.voices.find(e=>e.lang===i&&e.name.includes("Google"))||this.voices.find(e=>e.lang.startsWith(i.substring(0,2))&&e.name.includes("Google"))||this.voices.find(e=>e.lang===i)||this.voices.find(e=>e.lang.startsWith(i.substring(0,2)))),h?(a.voice=h,console.log(`SpeechSynthesizer: Using voice: ${h.name} for lang ${i}`)):(a.lang=i,console.warn(`SpeechSynthesizer: No specific voice found for lang ${i}. Using browser default.`)),a.pitch=e.MathUtils.clamp(s,0,2),a.rate=e.MathUtils.clamp(n,.1,10);let l=this.specificVolume;l=this.categoryVolumes?this.categoryVolumes.getEffectiveVolume(this.speechCategory,this.specificVolume):e.MathUtils.clamp(this.specificVolume,0,1),a.volume=l,console.log(`SpeechSynthesizer: Setting utterance volume to ${l}`),this.synth.speak(a)})}tts(e,t,i,s){this.speak(e,t,i,s)}cancel(){this.synth&&this.synth.speaking&&(this.synth.cancel(),this.isSpeaking=!1,console.log("SpeechSynthesizer: Speech cancelled."))}destroy(){this.cancel(),this.synth&&void 0!==this.synth.onvoiceschanged&&(this.synth.onvoiceschanged=null),this.voices=[],console.log("SpeechSynthesizer destroyed.")}}class ss extends S{constructor(){super(...arguments),this.categoryVolumes=new $i,this.soundSynthesizer=new Yi,this.listener=new e.AudioListener}static{this.dependencies={camera:e.Camera,soundOptions:Ut}}init({camera:e,soundOptions:t}){this.options=t,this.backgroundMusic=new Xi(this.listener,this.categoryVolumes),this.spatialAudio=new es(this.listener,this.categoryVolumes),this.audioListener=new Gi,this.audioPlayer=new Hi({sampleRate:48e3}),this.audioPlayer.setCategoryVolumes(this.categoryVolumes),e.add(this.listener),this.add(this.backgroundMusic),this.add(this.spatialAudio),this.add(this.audioListener),this.add(this.audioPlayer),this.add(this.soundSynthesizer),this.options.speechRecognizer.enabled&&(this.speechRecognizer=new ts(this.soundSynthesizer),this.add(this.speechRecognizer)),this.options.speechSynthesizer.enabled&&(this.speechSynthesizer=new is(this.categoryVolumes),this.add(this.speechSynthesizer))}getAudioListener(){return this.listener}setMasterVolume(t){this.categoryVolumes.masterVolume=e.MathUtils.clamp(t,0,1),this.audioPlayer?.updateGainNodeVolume()}getMasterVolume(){return this.categoryVolumes.isMuted?0:this.categoryVolumes.masterVolume}setCategoryVolume(t,i){t in this.categoryVolumes.volumes&&(this.categoryVolumes.volumes[t]=e.MathUtils.clamp(i,0,1))}getCategoryVolume(e){return e in this.categoryVolumes.volumes?this.categoryVolumes.volumes[e]:1}async enableAudio(e={}){const{streamToAI:t=!0,accumulate:i=!1}=e;t&&this.speechRecognizer?.isListening&&(console.log("Disabling SpeechRecognizer while streaming audio."),this.speechRecognizer.stop()),this.audioListener.setAIStreaming(t),await this.audioListener.startCapture({accumulate:i})}disableAudio(){this.audioListener?.stopCapture()}async startRecording(){await this.audioListener.startCapture({accumulate:!0})}stopRecording(){const e=this.audioListener.getAccumulatedBuffer();return this.audioListener.stopCapture(),e}getRecordedBuffer(){return this.audioListener.getAccumulatedBuffer()}clearRecordedBuffer(){this.audioListener.clearAccumulatedBuffer()}getRecordingSampleRate(){return this.audioListener.audioContext?.sampleRate||48e3}setAIStreaming(e){this.audioListener?.setAIStreaming(e)}isAIStreamingEnabled(){return null!==this.audioListener?.aiService}async playAIAudio(e){24e3!==this.audioPlayer.options.sampleRate&&(this.audioPlayer.options.sampleRate=24e3,this.audioPlayer.audioContext&&this.audioPlayer.stop()),await this.audioPlayer.playAudioChunk(e)}stopAIAudio(){this.audioPlayer?.clearQueue()}isAIAudioPlaying(){return this.audioPlayer?.getIsPlaying()}async playRecordedAudio(e,t){if(!e)return;t&&t!==this.audioPlayer.options.sampleRate&&(this.audioPlayer.options.sampleRate=t,this.audioPlayer.stop());const i=new Uint8Array(e);let s="";for(let e=0;e<i.length;e++)s+=String.fromCharCode(i[e]);const n=btoa(s);await this.audioPlayer.playAudioChunk(n)}isAudioEnabled(){return this.audioListener?.getIsCapturing()}getLatestAudioBuffer(){return this.audioListener?.getLatestAudioBuffer()}clearLatestAudioBuffer(){this.audioListener?.clearLatestAudioBuffer()}getEffectiveVolume(e,t=1){return this.categoryVolumes.getEffectiveVolume(e,t)}muteAll(){this.categoryVolumes.isMuted=!0}unmuteAll(){this.categoryVolumes.isMuted=!1}destroy(){this.backgroundMusic?.destroy(),this.spatialAudio?.destroy(),this.speechRecognizer?.destroy(),this.speechSynthesizer?.destroy(),this.audioListener?.dispose(),this.audioPlayer?.dispose(),this.listener?.parent?.remove(this.listener)}}const ns=.868,rs=new e.Vector3;class os extends S{get rangeX(){return Math.max(this.aspectRatio,1)}get rangeY(){return Math.max(1/this.aspectRatio,1)}constructor(t={},i,s){super(),this.name="View",this.isQuad=!0,this.isRoot=!1,this.isView=!0,this.selectable=!0,this.weight=.5,this.width=1,this.height=1,this.x=0,this.y=0,this.z=0,this.paddingX=0,this.paddingY=0,this.paddingZ=0,this.opacity=1,this.aspectRatio=1,i&&s&&(this.mesh=new e.Mesh(i,s),this.add(this.mesh)),Object.assign(this,t)}static dpToMeters(e){return e*ns*.001}dpToLocalUnits(e){return this.getWorldScale(rs),os.dpToMeters(e)/rs.x}show(){this.visible=!0,this.traverse(e=>{e.visible=!0})}hide(){this.visible=!1,this.traverse(e=>{e.visible=!1})}updateLayout(){this.isRoot||null==this.parent?(this.aspectRatio=this.width/this.height,this.scale.setScalar(Math.min(this.width,this.height))):this.parent instanceof os&&(this.position.set((this.x+this.paddingX)*this.parent.rangeX,(this.y-this.paddingY)*this.parent.rangeY,this.paddingZ+ee),this.aspectRatio=this.width/this.height*this.parent.aspectRatio,this.scale.setScalar(Math.min(this.parent.rangeX*this.width,this.parent.rangeY*this.height)),this.renderOrder=this.parent.renderOrder+1)}updateLayouts(){this.updateLayoutsBFS()}updateLayoutsBFS(){const e=[this];for(;e.length>0;){const t=e.shift();t instanceof os&&(t.updateLayout(),t.children.forEach(t=>{e.push(t)}))}}resetLayout(){}resetLayouts(){const e=[this];for(;e.length>0;){const t=e.shift();t instanceof os&&(t.resetLayout(),t.children.forEach(t=>{e.push(t)}))}}add(...e){super.add(...e);for(const t of e)t instanceof os&&t.updateLayoutsBFS();return this}onTriggered(e){}}const as="https://fonts.gstatic.com/s/roboto/v18/KFOmCnqEu92Fr1Mu4mxM.woff",hs="https://cdn.jsdelivr.net/gh/marella/material-icons@v1.13.14/iconfont/material-icons.woff";var ls;let cs;!function(e){e[e.PENDING=0]="PENDING",e[e.SUCCESS=1]="SUCCESS",e[e.FAILED=2]="FAILED"}(ls||(ls={}));let ds,us=ls.PENDING;class ps extends os{set text(e){this._text=e,this.useSDFText&&cs&&this.textObj instanceof cs?(this.textObj.text=e,this.textObj.sync()):this.updateHTMLText()}get text(){return this._text}constructor(e={},t,i){super(e,t,i),this.useSDFText=!0,this.isRoot=!1,this.name="TextView",this.font=as,this.fontColor=16777215,this.maxWidth=1,this.mode="fitWidth",this.anchorX="center",this.anchorY="middle",this.textAlign="center",this.imageOffsetX=0,this.imageOffsetY=0,this.x=0,this.y=0,this.width=1,this.height=1,this.lineHeight=0,this.lineCount=0,this._initializeTextCalled=!1,this._text="TextView",this.useSDFText=e.useSDFText??this.useSDFText,this.font=e.font??this.font,this.fontSize=e.fontSize??this.fontSize,this.fontSizeDp=e.fontSizeDp??this.fontSizeDp,this.fontColor=e.fontColor??this.fontColor,this.maxWidth=e.maxWidth??this.maxWidth,this.mode=e.mode??this.mode,this.anchorX=e.anchorX??this.anchorX,this.anchorY=e.anchorY??this.anchorY,this.textAlign=e.textAlign??this.textAlign,this.imageOverlay=e.imageOverlay??this.imageOverlay,this.imageOffsetX=e.imageOffsetX??this.imageOffsetX,this.imageOffsetY=e.imageOffsetY??this.imageOffsetY,this.text=e.text??this._text}async init(e){this.useSDFText=this.useSDFText&&await async function(){if(cs)return!0;try{const e=await import("troika-three-text");return cs=e.Text,us=ls.SUCCESS,!0}catch(e){return e instanceof Error&&(ds=e),us=ls.FAILED,!1}}(),this._initializeText()}setText(e){this.text=e}updateLayout(){if(super.updateLayout(),this.textObj&&(this.textObj.renderOrder=this.renderOrder,void 0===this.fontSizeDp&&"fitWidth"===this.mode))this.textObj.scale.setScalar(this.rangeX);this.fontSizeDp&&this.textObj&&this.createTextSDF()}createTextSDF(){const e=cs&&this.textObj instanceof cs?this.textObj:new cs;e.text=this.text,e.color=I(this.fontColor),e.font=this.font,e.anchorX=this.anchorX,e.anchorY=this.anchorY,void 0!==this.fontSizeDp?e.fontSize=this.dpToLocalUnits(this.fontSizeDp):void 0!==this.fontSize?e.fontSize=this.fontSize:e.fontSize=.06,e.maxWidth=this.maxWidth,e.textAlign=this.textAlign,e.material&&(e.material.depthWrite=!e.material.transparent),e.sync(),this.textObj=e,this.textObj.layers.mask=this.layers.mask,this.add(this.textObj)}createTextHTML(){this.canvas=document.createElement("canvas"),this.ctx=this.canvas.getContext("2d");const t=new e.PlaneGeometry(this.width,this.height),i=new e.CanvasTexture(this.canvas),s=new e.MeshBasicMaterial({map:i,transparent:!0});this.textObj=new e.Mesh(t,s),this.updateHTMLText(),this.add(this.textObj)}updateHTMLText(){if(!this.ctx)return;const{canvas:e,ctx:t}=this;e.width=256*this.width,e.height=256*this.height,t.clearRect(0,0,e.width,e.height);const i=void 0!==this.fontSizeDp?this.dpToLocalUnits(this.fontSizeDp):this.fontSize??.06;t.font=`${256*i}px ${this.font}`,t.fillStyle=`#${I(this.fontColor).toString(16).padStart(6,"0")}`,t.textAlign="center",t.textBaseline="middle",t.fillText(this.text,e.width/2,e.height/2),this.textObj?.material.map&&(this.textObj.material.map.needsUpdate=!0)}onSyncComplete(){if(!(this.useSDFText&&this.textObj instanceof cs&&this.textObj.textRenderInfo))return;const e=this.textObj.textRenderInfo.caretPositions,t=e.length/4;let i=0;const s=t>0?e[0]:0;let n=999999;for(let s=0;s<t;s++){const t=e[4*s+2];t<n-(e[4*s+3]-t)/2&&(i++,n=t)}this.lineHeight=t>0?(s-n)/i:0,this.lineCount=i,this.dispatchEvent({type:"synccomplete"})}_initializeText(){this._initializeTextCalled||(this._initializeTextCalled=!0,this.useSDFText&&us===ls.SUCCESS?this.createTextSDF():(us===ls.FAILED&&(console.warn("Failed to import `troika-three-text`. For 3D text rendering, please ensure `troika-three-text`, `troika-three-utils`, `troika-worker-utils`, `bidi-js`, and `webgl-sdf-generator` are included in your importmap or installed via npm. Refer to templates/1_ui for an example. Falling back to HTML-based text rendering.","Error details:",ds?.message),ds=void 0),this.createTextHTML()),this.useSDFText&&cs&&this.textObj instanceof cs&&(this.textObj.addEventListener("synccomplete",this.onSyncComplete.bind(this)),this.imageOverlay&&(new e.TextureLoader).load(this.imageOverlay,t=>{t.colorSpace=e.SRGBColorSpace,t.offset.x=this.imageOffsetX;const i=this.textObj;i.material.map=t,i.sync()})),this.updateLayout())}syncTextObj(){cs&&this.textObj instanceof cs&&this.textObj.sync()}setTextColor(e){cs&&this.textObj instanceof cs&&(this.textObj.color=e)}dispose(){this.useSDFText&&this.textObj&&cs&&this.textObj instanceof cs&&this.textObj.removeEventListener("synccomplete",this.onSyncComplete.bind(this)),super.dispose()}}class gs extends ps{get rangeX(){return 1}get rangeY(){return 1}constructor(t={}){const{backgroundColor:i=11184810}=t;super(t,new e.CircleGeometry(.5,32),new e.MeshBasicMaterial({color:i,transparent:!0,depthWrite:!1,opacity:0,side:e.FrontSide})),this.opacity=1,this.defaultOpacity=0,this.hoverColor=11184810,this.hoverOpacity=.2,this.selectedOpacity=.4,this.font=hs,Object.assign(this,t)}async init(e){await super.init(),this.mesh&&(this.mesh.renderOrder=this.renderOrder),this.textObj&&(this.textObj.renderOrder=this.renderOrder+1)}onHoverOver(){this.ux&&this.update()}onHoverOut(){this.ux&&this.update()}update(){this.ux&&(this.ux.isHovered()||this.ux.isSelected()?this.mesh.material.opacity=this.ux.isSelected()?this.selectedOpacity*this.opacity:this.hoverOpacity*this.opacity:this.mesh.material.opacity=this.defaultOpacity*this.opacity)}_initializeText(){if(super._initializeText(),this.textObj){if(this.textObj.position.set(0,0,ee),this.textObj.raycast=()=>{},this.update(),"center"===this.mode)this.textObj.scale.setScalar(this.rangeX);this.textObj.scale.set(1,1,1)}this.syncTextObj(),this.updateLayout()}}class ms extends ps{constructor(e={}){super({font:hs,...e})}}class fs extends os{constructor(t={}){super(t),this.initCalled=!1,this.textureLoader=new e.TextureLoader;const i=new e.MeshBasicMaterial({map:null,transparent:!0,depthWrite:!1,side:e.DoubleSide}),s=new e.PlaneGeometry(1,1);this.mesh=new e.Mesh(s,i),this.material=i,this.add(this.mesh)}init(){this.initCalled||(this.initCalled=!0,this.reload())}reload(){if(!this.src)return this.material.map&&(this.material.map=null),this.texture?.dispose(),void(this.texture=void 0);this.texture?.dispose(),this.texture=this.textureLoader.load(this.src,t=>{t.colorSpace=e.SRGBColorSpace,this.material.map=t,this.updateLayout()})}updateLayout(){super.updateLayout(),this.mesh&&(this.mesh.renderOrder=this.renderOrder),this.scaleImageToCorrectAspectRatio()}scaleImageToCorrectAspectRatio(){if(this.texture?.image){const{image:e}=this.texture,t=e.width,i=e.height,s=this.rangeX/t,n=this.rangeY/i,r=Math.min(s,n);this.mesh.scale.set(t*r,i*r,1)}}load(e){this.src=e,this.reload()}}class vs extends ps{constructor(e={}){super(e),this.layers.set(4)}createTextSDF(){super.createTextSDF(),this.textObj.material.depthText=!1,this.textObj.material.depthWrite=!1}}const ys={uniforms:{uMainTex:{value:null},uUseImage:{value:0},uBackgroundColor:{value:new e.Vector4(.4,.8,1,1)},uBoxSize:{value:new e.Vector2(.5,.5)},uRadius:{value:.05},uOpacity:{value:1}},vertexShader:"\n #define USE_UV\n #include <common>\n #include <batching_pars_vertex>\n #include <uv_pars_vertex>\n #include <envmap_pars_vertex>\n #include <color_pars_vertex>\n #include <fog_pars_vertex>\n #include <morphtarget_pars_vertex>\n #include <skinning_pars_vertex>\n #include <logdepthbuf_pars_vertex>\n #include <clipping_planes_pars_vertex>\n\n void main() {\n #include <uv_vertex>\n #include <color_vertex>\n #include <morphinstance_vertex>\n #include <morphcolor_vertex>\n #include <batching_vertex>\n\n #if defined ( USE_ENVMAP ) || defined ( USE_SKINNING )\n\n #include <beginnormal_vertex>\n #include <morphnormal_vertex>\n #include <skinbase_vertex>\n #include <skinnormal_vertex>\n #include <defaultnormal_vertex>\n\n #endif\n\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <skinning_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n\n #include <worldpos_vertex>\n #include <envmap_vertex>\n #include <fog_vertex>\n }\n ",fragmentShader:"\n precision mediump float;\n\n uniform sampler2D uMainTex;\n uniform vec4 uBackgroundColor;\n uniform vec2 uBoxSize;\n uniform float uRadius;\n uniform float uUseImage;\n uniform float uOpacity;\n\n #define USE_UV\n #include <common>\n #include <dithering_pars_fragment>\n #include <color_pars_fragment>\n #include <uv_pars_fragment>\n #include <map_pars_fragment>\n #include <alphamap_pars_fragment>\n #include <alphatest_pars_fragment>\n #include <alphahash_pars_fragment>\n #include <aomap_pars_fragment>\n #include <lightmap_pars_fragment>\n #include <envmap_common_pars_fragment>\n #include <envmap_pars_fragment>\n #include <fog_pars_fragment>\n #include <specularmap_pars_fragment>\n #include <logdepthbuf_pars_fragment>\n #include <clipping_planes_pars_fragment>\n\n // Distance function for rounded box.\n float distRoundBox(vec2 p, vec2 b, float r) {\n return length(max(abs(p) - b + r, 0.0)) - r;\n }\n\n void main(void) {\n #include <clipping_planes_fragment>\n\n #include <logdepthbuf_fragment>\n #include <map_fragment>\n #include <color_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n #include <alphahash_fragment>\n #include <specularmap_fragment>\n vec2 size = uBoxSize * 1000.0;\n\n // Calculates the adjusted radius based on box size.\n float radius = min(size.x, size.y) * (0.05 + uRadius);\n vec2 half_size = 0.5 * size;\n\n // Compute the distance from the rounded box edge.\n float dist = distRoundBox(vUv * size - half_size, half_size, radius);\n\n // Use lerp for smooth color transition based on distance.\n vec4 colorInside = uBackgroundColor;\n\n if (uUseImage > 0.5) {\n colorInside = texture2D(uMainTex, vUv);\n colorInside.a = 1.0;\n }\n\n // Transparent black for outside.\n vec4 colorOutside = vec4(0.0, 0.0, 0.0, 0.0);\n\n vec4 finalColor = mix(colorInside, colorOutside, smoothstep(0.0, 1.0, dist));\n\n // Return premultiplied alpha.\n gl_FragColor = uOpacity * finalColor.a * vec4(finalColor.rgb, 1.0);\n }\n "};class ws extends ps{constructor(t={}){const i=new e.PlaneGeometry(1,1),s=O(t.backgroundColor??"#00000000"),{opacity:n=0,radius:r=ys.uniforms.uRadius.value,boxSize:o=ys.uniforms.uBoxSize.value}=t,a={...ys.uniforms,uBackgroundColor:{value:s},uOpacity:{value:n},uAspect:{value:1},uRadius:{value:r},uBoxSize:{value:o}};super(t,i,new e.ShaderMaterial({...ys,transparent:!0,uniforms:a,depthWrite:!1})),this.name="TextButton",this.fontSize=.05,this.fontColor=16777215,this.opacity=1,this.defaultOpacity=1,this.hoverColor=11184810,this.hoverOpacity=.2,this.selectedFontColor=10066329,this.selectedOpacity=.4,this.width=.9,this.height=.9,this.mode="center",this.imageOffsetX=0,this.imageOffsetY=0,this.uniforms=a,this.opacity=n,this.fontSize=t.fontSize??this.fontSize,this.fontColor=t.fontColor??this.fontColor,this.width=t.width??this.width,this.height=t.height??this.height}async init(){await super.init(),this.textObj.position.set(0,0,ee),this.mesh&&(this.mesh.renderOrder=this.renderOrder),this.textObj.renderOrder=this.renderOrder+1,this.textObj.raycast=()=>{}}update(){if(!this.textObj)return;this.textObj&&(this.textObj.renderOrder=this.renderOrder+1);const e=this.ux;e.isHovered()?e.isSelected()?this.setTextColor(6710886):this.setTextColor(11184810):(this.setTextColor(16777215),this.uniforms.uOpacity.value=this.defaultOpacity*this.opacity)}}class xs extends os{constructor(t={}){super(t),this.name="VideoView",this.mode="center",this.isRoot=!1,this.muted=!0,this.loop=!0,this.autoplay=!0,this.playsInline=!0,this.crossOrigin="anonymous",this.videoAspectRatio=0;const i=new e.PlaneGeometry(1,1),s=new e.MeshBasicMaterial({transparent:!0,depthWrite:!1,side:e.DoubleSide});this.mesh=new e.Mesh(i,s),this.material=s,this.add(this.mesh),this.texture instanceof e.Texture||(this.texture=new e.Texture),this.material.map=this.texture}init(){super.init(),this.material.map instanceof e.VideoTexture&&this.material.map.image?this.loadFromVideoTexture(this.material.map):this.src&&this.load(this.src)}load(t){t instanceof HTMLVideoElement?this.loadFromVideoElement(t):t instanceof e.VideoTexture?this.loadFromVideoTexture(t):"string"==typeof t?this.loadFromURL(t):t instanceof ke?this.loadFromStream(t):console.error("VideoView: Invalid video source provided.",t)}loadFromStream(e){this.disposeStreamListener_(),this.stream_=e,this.streamReadyCallback_=e=>{this.stream_?.texture?(this.loadFromVideoTexture(this.stream_.texture),void 0!==e.details?.aspectRatio&&(this.videoAspectRatio=e.details?.aspectRatio),this.updateLayout()):console.warn("Stream is ready, but its texture is not available.")},this.stream_.loaded?this.streamReadyCallback_({details:{aspectRatio:this.stream_.aspectRatio}}):this.stream_.addEventListener("statechange",this.streamReadyCallback_)}loadFromURL(e){this.src=e;const t=document.createElement("video");t.muted=this.muted,t.loop=this.loop,t.playsInline=this.playsInline,t.autoplay=this.autoplay,t.crossOrigin=this.crossOrigin,t.src=e,this.loadFromVideoElement(t)}loadFromVideoElement(t){this.video=t,this.video.autoplay&&this.video.paused&&this.video.play().catch(e=>{console.warn("VideoView: Autoplay prevented for video element.",e)});const i=new e.VideoTexture(this.video);i.colorSpace=e.SRGBColorSpace,this.texture=i,this.material.map=this.texture;const s=()=>{this.video.videoWidth&&this.video.videoHeight?this.videoAspectRatio=this.video.videoWidth/this.video.videoHeight:(console.warn("VideoView: Video metadata loaded but dimensions are 0."),this.videoAspectRatio=0),this.updateLayout()};this.video.readyState>=this.video.HAVE_METADATA?s():this.video.addEventListener("loadedmetadata",s,{once:!0})}loadFromVideoTexture(e){this.texture=e,this.material.map=this.texture,this.video=this.texture.image,this.video&&this.video.videoWidth&&this.video.videoHeight?(this.videoAspectRatio=this.video.videoWidth/this.video.videoHeight,this.updateLayout()):this.video?this.video.addEventListener("loadedmetadata",()=>{this.video.videoWidth&&this.video.videoHeight?this.videoAspectRatio=this.video.videoWidth/this.video.videoHeight:this.videoAspectRatio=0,this.updateLayout()},{once:!0}):(console.warn("VideoView: VideoTexture does not have a valid underlying video element."),this.videoAspectRatio=0,this.updateLayout())}play(){this.video&&this.video.paused&&this.video.play().catch(e=>console.warn("VideoView: Error playing video:",e))}pause(){this.video&&!this.video.paused&&this.video.pause()}disposeStreamListener_(){this.stream_&&this.streamReadyCallback_&&(this.stream_.removeEventListener("statechange",this.streamReadyCallback_),this.stream_=void 0,this.streamReadyCallback_=void 0)}dispose(){this.disposeStreamListener_(),this.video&&(this.video.pause(),this.video.removeAttribute("src"),this.video.load(),this.video=void 0),this.texture&&(this.texture.dispose(),this.texture=void 0),super.dispose()}updateLayout(){super.updateLayout(),"stretch"===this.mode||this.videoAspectRatio<=0||!this.material.map||this.mesh.scale.set(Math.min(this.rangeX,this.videoAspectRatio*this.rangeY),Math.min(this.rangeY,this.rangeX/this.videoAspectRatio),1)}}const Ss=Object.freeze(new e.Vector3(0,-1,0)),bs=Object.freeze(new e.Vector3(0,1,0)),Cs=Object.freeze(new e.Vector3(0,0,-1)),Ts=Object.freeze(new e.Vector3(0,0,1)),Rs=Object.freeze(new e.Vector3(-1,0,0)),Ms=Object.freeze(new e.Vector3(1,0,0)),Ds=Object.freeze(new e.Vector3(0,0,0)),Es=new e.Quaternion,Ps=new e.Euler,_s=new e.Vector3;var As;!function(e){e.TRANSLATING="TRANSLATING",e.ROTATING="ROTATING",e.SCALING="SCALING",e.DO_NOT_DRAG="DO_NOT_DRAG"}(As||(As={}));class Os extends S{constructor(){super(...arguments),this.mode=Os.IDLE,this.originalObjectPosition=new e.Vector3,this.originalObjectRotation=new e.Quaternion,this.originalObjectScale=new e.Vector3,this.originalController1Position=new e.Vector3,this.originalController1RotationInverse=new e.Quaternion,this.originalController1MatrixInverse=new e.Matrix4,this.originalScalingControllerDistance=0,this.originalScalingObjectScale=new e.Vector3}static{this.dependencies={input:ct,camera:e.Camera}}static{this.IDLE="IDLE"}static{this.TRANSLATING=As.TRANSLATING}static{this.ROTATING=As.ROTATING}static{this.SCALING=As.SCALING}static{this.DO_NOT_DRAG=As.DO_NOT_DRAG}init({input:e,camera:t}){this.input=e,this.camera=t}onSelectStart(e){const t=e.target,i=this.input.intersectionsForController.get(t);i&&i.length>0&&this.beginDragging(i[0],t)}onSelectEnd(){this.mode=Os.IDLE,this.intersection=void 0,this.draggableObject=void 0}update(){for(const e of this.input.controllers)this.updateDragging(e)}beginDragging(e,t){const[i,s]=this.findDraggableObjectAndDraggingMode(e.object);return null!=i&&null!=s&&s!=Os.DO_NOT_DRAG&&(this.mode!=Os.IDLE?this.beginScaling(t):(this.draggableObject=i,this.mode=s==Os.ROTATING?Os.ROTATING:Os.TRANSLATING,this.originalController1Position.copy(t.position),this.originalController1MatrixInverse.compose(t.position,t.quaternion,t.scale).invert(),this.originalController1RotationInverse.copy(t.quaternion).invert(),this.intersection=e,this.controller1=t,this.originalObjectRotation.copy(i.quaternion),this.originalObjectPosition.copy(i.position),this.originalObjectScale.copy(i.scale),!0))}beginScaling(e){return this.controller2=e,this.originalScalingControllerDistance=_s.subVectors(this.controller1.position,this.controller2.position).length(),this.originalScalingObjectScale.copy(this.intersection.object.scale),this.mode=Os.SCALING,!0}updateDragging(e){return this.mode==Os.TRANSLATING?this.updateTranslating():this.mode==Os.ROTATING?this.updateRotating(e):this.mode==Os.SCALING&&this.updateScaling()}updateTranslating(){const e=this.draggableObject;return e.position.copy(this.originalObjectPosition),e.quaternion.copy(this.originalObjectRotation),e.scale.copy(this.originalObjectScale),e.updateMatrix(),this.controller1.updateMatrix(),e.matrix.premultiply(this.originalController1MatrixInverse).premultiply(this.controller1.matrix),e.position.setFromMatrixPosition(e.matrix),e.dragFacingCamera&&this.turnPanelToFaceTheCamera(),!0}updateRotating(t){if(t!=this.controller1)return;if(t instanceof at)return this.updateRotatingFromMouseController(t);const i=this.draggableObject,s=(new e.Vector3).subVectors(t.position,this.originalController1Position);s.applyQuaternion(this.originalController1RotationInverse);const n=Es.setFromAxisAngle(bs,10*s.x);return i.quaternion.multiplyQuaternions(n,this.originalObjectRotation),!0}updateRotatingFromMouseController(e){const t=this.draggableObject,i=Es.multiplyQuaternions(e.quaternion,this.originalController1RotationInverse),s=Ps.setFromQuaternion(i,"YXZ"),n=Es.setFromAxisAngle(bs,-10*s.y);return t.quaternion.multiplyQuaternions(n,this.originalObjectRotation),!0}updateScaling(){const e=_s.subVectors(this.controller1.position,this.controller2.position).length()/this.originalScalingControllerDistance;return this.draggableObject.scale.copy(this.originalScalingObjectScale).multiplyScalar(e),!0}turnPanelToFaceTheCamera(){const e=this.draggableObject;_s.subVectors(e.position,this.camera.position),e.quaternion.setFromAxisAngle(bs,3*Math.PI/2-Math.atan2(_s.z,_s.x))}findDraggableObjectAndDraggingMode(e){let t,i,s=e;for(;s&&!t;)t=s.draggable?s:void 0,i=i??s.draggingMode,s=s.parent;return[t,i]}}class Is extends gs{static{this.dependencies={renderer:e.WebGLRenderer}}constructor(e={}){super({text:"close",...e}),this.fontSize=.8,this.defaultOpacity=.2,this.hoverOpacity=.8,this.backgroundColor=16777215}async init({renderer:e}){await super.init(),this.renderer=e}onTriggered(){console.log("ExitButton triggered: Shutting down XR session.");const e=this.renderer.xr.getSession();e&&e.end()}}class Ls extends os{constructor(){super(...arguments),this.rowWeight=0,this.colWeight=0,this.leftWeight=0,this.topWeight=0,this.cols=0,this.rows=0}static init(e,t,i,s){Ls.RowClass=e,Ls.ColClass=t,Ls.PanelClass=i,Ls.OrbiterClass=s}addImage(e){const t=new fs(e);return this.add(t),t}addVideo(e){const t=new xs(e);return this.add(t),t}addIconButton(e={}){const t=new gs(e);return this.add(t),t}addTextButton(e={}){const t=new ws(e);return this.add(t),t}addIcon(e={}){const t=new ms(e);return this.add(t),t}addText(e={}){const t=new ps(e);return this.add(t),t}addLabel(e){const t=new vs(e);return this.add(t),t}addOrbiter(e={}){const t=new Ls.OrbiterClass(e);return this.add(t),t}addExitButton(e={}){const t=new Is(e);return this.add(t),t}addPanel(e={}){e.isRoot=!1;const t=new Ls.PanelClass(e);return this.add(t),t}addRow(e={}){const t=new Ls.RowClass(e);return t.topWeight=this.rowWeight,t.height=t.weight,this.rowWeight+=t.weight,this.add(t),this.rows++,t}addCol(e={}){const t=new Ls.ColClass(e);return t.leftWeight=this.colWeight,t.width=t.weight,this.colWeight+=t.weight,this.add(t),this.cols++,t}updateLayout(){this.x=-.5+(this.leftWeight+this.width/2),this.y=.5-(this.topWeight+this.height/2),super.updateLayout()}resetLayout(){this.rows=0,this.cols=0,this.colWeight=0,this.rowWeight=0;for(const e of this.children)e instanceof Ls.RowClass?(e.topWeight=this.rowWeight,e.height=e.weight,this.rowWeight+=e.weight,this.rows++):e instanceof Ls.ColClass&&(e.leftWeight=this.colWeight,e.width=e.weight,this.colWeight+=e.weight,this.cols++)}}const Vs={uniforms:{uMainTex:{value:null},uUseImage:{value:0},uBackgroundColor:{value:new e.Vector4(.4,.8,1,1)},uBoxSize:{value:new e.Vector2(.5,.5)},uRadius:{value:.05},uReticleUVs:{value:new e.Vector4(.5,.5,.5,.5)},uSelected:{value:new e.Vector2(0,0)},uBorderWidth:{value:.1},uHighlightRadius:{value:.2},uOutlineWidth:{value:.01},uOpacity:{value:1}},vertexShader:"\n varying vec2 vTexCoord;\n\n void main() {\n vTexCoord = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n }\n ",fragmentShader:"\n precision mediump float;\n\n uniform sampler2D uMainTex;\n uniform vec4 uBackgroundColor;\n uniform vec2 uBoxSize;\n uniform float uRadius;\n uniform float uUseImage;\n\n uniform vec4 uReticleUVs;\n uniform vec2 uSelected;\n uniform float uBorderWidth;\n uniform float uHighlightRadius;\n uniform float uOutlineWidth;\n uniform float uOpacity;\n\n varying vec2 vTexCoord;\n\n // Distance function for rounded box.\n float distRoundBox(vec2 p, vec2 b, highp float r) {\n return length(max(abs(p) - b + r, 0.0)) - r;\n }\n\n vec4 highlight(in vec4 baseColor, in vec4 colorOutside,\n in float distOuterUV, in float aa, in vec2 mouse, in float selected) {\n\n vec4 highlightColor = vec4(0.0);\n float normDist = 1.0; // Initialize outside the highlight range\n bool mousePressed = selected > 0.0;\n bool mouseHovering = selected <= 0.0 && length(uReticleUVs.xy) > 0.0;\n bool mouseNearBorder = (mouseHovering || mousePressed);\n vec4 finalColor = baseColor;\n\n if (mouseNearBorder) {\n // Scale mouse and fragment coordinates by the inverse of uBoxSize\n\n vec2 fragAspect = vTexCoord;\n fragAspect.x *= uBoxSize.x / uBoxSize.y;\n vec2 mouseAspect = mouse;\n mouseAspect.x *= uBoxSize.x / uBoxSize.y;\n\n // Calculate vector from mouse to fragment in aspect-corrected space\n vec2 diffAspect = fragAspect - mouseAspect;\n\n // Calculate the distance in the aspect-corrected space\n float distToMouseAspect = length(diffAspect);\n\n // Normalized distance from mouse within the highlight radius\n normDist = distToMouseAspect / uHighlightRadius;\n\n // Define highlight color\n float innerWhite = mousePressed ? 0.9 : 0.8;\n\n // Radial gradient calculation\n float radialFactor = smoothstep(1.0, 0.0, normDist); // 1 at center, 0 at edge\n highlightColor = vec4(vec3(innerWhite), 1.0) * vec4(vec3(1.0), radialFactor);\n\n // Calculate distance to the inner edge of the border in UV space\n float distInnerUV = distRoundBox(\n (vTexCoord - 0.5) * uBoxSize,\n (uBoxSize - uBorderWidth) * 0.5, 0.5 * uRadius);\n\n float highlightEdgeSharpness = 200.0;\n float innerHighlightAmount = clamp(highlightEdgeSharpness * -distOuterUV, 0.0, 1.0);\n float outerHighlightAmount = clamp(highlightEdgeSharpness * distInnerUV, 0.0, 1.0);\n float highlightAmount = min(innerHighlightAmount, outerHighlightAmount);\n vec4 highlightColor = mix(finalColor, finalColor + highlightColor, highlightColor.a);\n finalColor = mix(finalColor, highlightColor, highlightAmount);\n }\n return finalColor;\n }\n\n void main(void) {\n vec2 size = uBoxSize * 1000.0;\n float radius = min(size.x, size.y) * (0.05 + uRadius);\n vec2 half_size = 0.5 * size;\n\n // Distance to the outer edge of the round box in UV space (0-1)\n float distOuterUV = distRoundBox(vTexCoord * uBoxSize - uBoxSize * 0.5, uBoxSize * 0.5, uRadius);\n\n // Antialiasing delta\n float aa = fwidth(distOuterUV) * 0.8;\n\n // Base color: opaque inside, transparent outside\n vec4 colorInside = uBackgroundColor;\n if (uUseImage > 0.5) {\n colorInside = texture2D(uMainTex, vTexCoord);\n colorInside.a = 1.0;\n }\n vec4 colorOutside = vec4(0.0, 0.0, 0.0, 0.0);\n vec4 baseColor = mix(colorInside, colorOutside, smoothstep(0.0, aa, distOuterUV));\n\n vec4 finalColor1 = highlight(baseColor, colorOutside, distOuterUV, aa, uReticleUVs.xy, uSelected.x);\n vec4 finalColor2 = highlight(baseColor, colorOutside, distOuterUV, aa, uReticleUVs.zw, uSelected.y);\n\n gl_FragColor = uOpacity * max(finalColor1, finalColor2);\n }\n "};class Bs extends e.Mesh{get uniforms(){return this.material.uniforms}constructor(t,i,s=1){const n=e.UniformsUtils.clone(t.uniforms),r=new e.ShaderMaterial({uniforms:n,vertexShader:t.vertexShader,fragmentShader:t.fragmentShader,transparent:!0,depthWrite:!1,side:e.DoubleSide});super(new e.PlaneGeometry(s,s),r),this.name="PanelMesh",i&&(n.uBackgroundColor.value=O(i))}setWidthHeight(e,t){this.uniforms.uBoxSize.value.set(e,t)}setAspectRatio(e){this.scale.set(Math.max(e,1),Math.max(1/e,1),1)}}const Fs=888.832*.001,zs=624.96*.001;class ks extends os{static{this.dependencies={user:pt,timer:e.Timer}}constructor(e={}){super(e),this.keepFacingCamera=!0,this.name="Panel",this.isPanel=!0,this.draggable=!1,this.touchable=!1,this.useDefaultPosition=!0,this.useBorderlessShader=!1,this.showHighlights=!1,this.backgroundColor="#c2c2c255",this._fadeState="idle",this._fadeDuration=.2,this._fadeTimer=0,this._currentOpacity=1,this._startOpacity=1,this._targetOpacity=1;const t=e.draggable??this.draggable,i=e.useBorderlessShader??!t,s=i?1:1.3,n=i?ys:Vs;e.useBorderlessShader=i,this.showHighlights=!i,this.backgroundColor=e.backgroundColor??this.backgroundColor,this.draggable=t,this.draggingMode=e.draggingMode??this.draggable?As.TRANSLATING:As.DO_NOT_DRAG,this.touchable=e.touchable??this.touchable,this.isRoot=e.isRoot??!0,this.width=e.width??(this.isRoot?Fs:1),this.height=e.height??(this.isRoot?zs:1),this.showHighlights=e.showHighlights??this.showHighlights,this.useDefaultPosition=e.useDefaultPosition??this.useDefaultPosition,this.useBorderlessShader=e.useBorderlessShader??this.useBorderlessShader,this.mesh=new Bs(n,this.backgroundColor,s),this.add(this.mesh),this.updateLayout()}init({user:e,timer:t}){super.init(),this.selectable=!0,this.timer=t,0===this.position.x&&0===this.position.y&&0===this.position.z||(this.useDefaultPosition=!1),this.isRoot&&this.useDefaultPosition?this.position.set(this.x,e.height+this.y,-e.panelDistance+this.z):this.position.set(this.position.x+this.x,this.position.y+this.y,this.position.z+this.z)}fadeIn(e,t){"fading-in"!==this._fadeState&&(this._startFade(1,e,t),this._fadeState="fading-in")}fadeOut(e,t){"fading-out"!==this._fadeState&&(this._startFade(0,e,t),this._fadeState="fading-out")}_startFade(e,t,i){this._fadeDuration=t??.2,this.onFadeComplete=i,this._fadeTimer=0,this._startOpacity=this._currentOpacity,this._targetOpacity=e,this._fadeDuration<=0?this._completeFade():this._prepareMaterialsForFade()}_prepareMaterialsForFade(){this.traverse(t=>{if(t instanceof e.Mesh&&t.material){(Array.isArray(t.material)?t.material:[t.material]).forEach(e=>{e.transparent=!0})}})}_applyOpacity(t){this.traverse(i=>{if(i instanceof os&&(i.opacity=t),i instanceof e.Mesh&&i.material){(Array.isArray(i.material)?i.material:[i.material]).forEach(i=>{i instanceof e.ShaderMaterial?i.uniforms.uOpacity.value=t:i.opacity=t})}})}_completeFade(){this._currentOpacity=this._targetOpacity,this._applyOpacity(this._currentOpacity),this._fadeState="idle",0===this._currentOpacity?this.hide():this.show(),this.onFadeComplete?.()}update(){if("idle"!==this._fadeState){this._fadeTimer+=this.timer.getDelta();const t=Math.min(this._fadeTimer/this._fadeDuration,1);this._currentOpacity=e.MathUtils.lerp(this._startOpacity,this._targetOpacity,t),this._applyOpacity(this._currentOpacity),t>=1&&this._completeFade()}}addGrid(){const e=new Ls;return this.add(e),e}updateLayout(){super.updateLayout(),this.mesh.setAspectRatio(this.aspectRatio);const e=this.isRoot||!this.parent?1:this.parent.aspectRatio;this.mesh.setWidthHeight(this.width*Math.max(e,1),this.height*Math.max(1/e,1))}getWidth(){return this.width}getHeight(){return this.height}}class js extends Ls{constructor(e={}){void 0===e.weight&&(e.weight=.5),super(e)}}class Us extends Ls{init(){super.init(),this.position.set(-.45*this.rangeX,.7*this.rangeY,this.position.z),this.scale.set(.2,.2,1)}}class Ns extends Ls{constructor(e={}){void 0===e.weight&&(e.weight=.5),super(e)}}class Gs extends ks{constructor(e={}){e.draggable=e.draggable??!0,e.dragFacingCamera=e.dragFacingCamera??!0,super(e),this.dragFacingCamera=!0,this.draggable=e.draggable??this.draggable,this.dragFacingCamera=e.dragFacingCamera??this.dragFacingCamera,this.mesh.material.visible=!1!==e.showEdge}update(){super.update(),this._updateInteractionFeedback()}_updateInteractionFeedback(){if(this.useBorderlessShader||!this.showHighlights)return;const[e,t]=this.ux.getPrimaryTwoControllerIds(),i=null!==e&&this.ux.selected[e],s=null!==t&&this.ux.selected[t];this.mesh.material.uniforms.uSelected.value.set(i?1:0,s?1:0);const n=null!==e?this.ux.uvs[e].x:-1,r=null!==e?this.ux.uvs[e].y:-1,o=null!==t?this.ux.uvs[t].x:-1,a=null!==t?this.ux.uvs[t].y:-1;this.mesh.material.uniforms.uReticleUVs.value.set(n,r,o,a)}}Ls.init(Ns,js,ks,Us);class Hs extends S{constructor(){super(...arguments),this.views=[]}static{this.ComponentRegistry=new Map}static registerComponent(e,t){Hs.ComponentRegistry.has(e)&&console.warn(`UI: Component type "${e}" is being overwritten.`),Hs.ComponentRegistry.set(e,t)}compose(e){const t=this._composeNode(e);return t&&(this.add(t),t.traverse(e=>{e instanceof os&&this.views.push(e)})),t}_composeNode(e){const{type:t,options:i={},position:s={x:0,y:0,z:0},rotation:n={x:0,y:0,z:0},children:r=[]}=e,o=Hs.ComponentRegistry.get(t);if(!o)return console.error(`UI Error: Unknown component type "${t}". Make sure it's registered.`),null;const a=new o(i);return a.position.set(s.x,s.y,s.z),a.rotation.set(n.x,n.y,n.z),r.forEach(e=>{const t=this._composeNode(e);t&&a.add(t)}),a instanceof Ls&&a.resetLayouts(),a}}Hs.registerComponent("Panel",ks),Hs.registerComponent("Grid",Ls),Hs.registerComponent("Row",Ns),Hs.registerComponent("Col",js),Hs.registerComponent("Orbiter",Us),Hs.registerComponent("Text",ps),Hs.registerComponent("TextView",ps),Hs.registerComponent("Label",vs),Hs.registerComponent("LabelView",vs),Hs.registerComponent("VideoView",xs),Hs.registerComponent("TextButton",ws),Hs.registerComponent("IconButton",gs),Hs.registerComponent("IconView",ms),Hs.registerComponent("Image",fs),Hs.registerComponent("ImageView",fs),Hs.registerComponent("SpatialPanel",Gs);class Ws extends HTMLElement{static{this.style="\n /* Styles for the wrapper that covers the screen */\n .wrapper {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: rgba(0, 0, 0, 0.1);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 9999;\n transition: visibility 0s, opacity 0.2s linear;\n }\n\n /* The spinning circle */\n .spinner {\n border: 8px solid rgba(255, 255, 255, 0.3);\n border-left-color: #ffffff;\n border-radius: 50%;\n width: 60px;\n height: 60px;\n animation: spin 1s linear infinite;\n }\n\n /* The animation is safely scoped inside the shadow DOM */\n @keyframes spin {\n to {\n transform: rotate(360deg);\n }\n }"}static{this.innerHTML=`\n <style>\n ${Ws.style}\n </style>\n <div class="wrapper">\n <div class="spinner"></div>\n </div>\n `}connectedCallback(){this.attachShadow({mode:"open"}).innerHTML=Ws.innerHTML}}customElements.define("xb-blocks-loading-spinner",Ws);class qs{constructor(){this.isLoading=!1,this.setupCallbacks()}showSpinner(){this.spinnerElement||(this.spinnerElement=document.body.appendChild(document.createElement("xb-blocks-loading-spinner")))}hideSpinner(){this.spinnerElement&&(this.spinnerElement.remove(),this.spinnerElement=void 0)}setupCallbacks(){e.DefaultLoadingManager.onStart=(e,t,i)=>{this.isLoading=!0,window.parent.postMessage({type:"XR_LOADING_PROGRESS",payload:{progress:t/i,message:"Loading assets..."}},"*")},e.DefaultLoadingManager.onProgress=(e,t,i)=>{window.parent.postMessage({type:"XR_LOADING_PROGRESS",payload:{progress:t/i,message:`Loading ${Math.round(t/i*100)}%`}},"*")},e.DefaultLoadingManager.onLoad=()=>{this.isLoading=!1,this.hideSpinner(),window.parent.postMessage({type:"XR_LOADING_COMPLETE"},"*")},e.DefaultLoadingManager.onError=e=>{this.isLoading=!1,console.warn("XRBlocks: Error loading: "+e),this.hideSpinner(),window.parent.postMessage({type:"XR_LOADING_ERROR",payload:{url:e,message:"Failed to load assets."}},"*")}}}const Xs=new qs,Ks=new e.Vector3,$s=new e.Vector3,Qs=new e.Vector3,Ys=new e.Matrix4;function Js(e,t,i){e.position.copy(t.point),t.object.updateWorldMatrix(!0,!1);const s=Qs.copy(t.normal).transformDirection(t.object.matrixWorld),n=i.getWorldPosition(Ks).sub(e.position).cross(s).cross(s).multiplyScalar(-1).normalize(),r=$s.crossVectors(s,n);return Ys.makeBasis(r,s,n),e.quaternion.setFromRotationMatrix(Ys),e}class Zs extends e.Object3D{constructor(e,t,i,s={}){super(),this.label=e,this.image=t,this.detection2DBoundingBox=i,Object.assign(this,s)}}class en extends S{constructor(){super(...arguments),this._detectedObjects=new Map}static{this.dependencies={options:Ht,ai:$,aiOptions:F,deviceCamera:je,depth:Oe,camera:e.Camera}}init({options:t,ai:i,aiOptions:s,deviceCamera:n,depth:r,camera:o}){this.options=t,this.ai=i,this.aiOptions=s,this.deviceCamera=n,this.depth=r,this.camera=o,this._geminiConfig=this._buildGeminiConfig(),this.options.objects.showDebugVisualizations&&(this._debugVisualsGroup=new e.Group,this._debugVisualsGroup.raycast=()=>{},this.add(this._debugVisualsGroup))}async runDetection(){return this.clear(),"gemini"===this.options.objects.backendConfig.activeBackend?this._runGeminiDetection():(console.warn(`ObjectDetector backend '${this.options.objects.backendConfig.activeBackend}' is not supported.`),[])}async _runGeminiDetection(){if(!this.ai.isAvailable())return console.error("Gemini is unavailable for object detection."),[];const t=this.deviceCamera.getSnapshot({outputFormat:"base64"});if(!t)return console.warn("Could not get device camera snapshot."),[];const{mimeType:i,strippedBase64:s}=L(t),n=this.depth.depthArray[0].slice(0),r=this.camera.matrixWorld.clone(),o=this.aiOptions.gemini.config;this.aiOptions.gemini.config=this._geminiConfig;try{const o=await this.ai.model.query({type:"multiPart",parts:[{inlineData:{mimeType:i||void 0,data:s}},{text:"What do you see in this image?"}]});let a;try{if(!o||!o.text)return console.error("AI response is missing text field:",o,"Raw response was:",o),[];a=JSON.parse(o.text)}catch(e){return console.error("Failed to parse AI response JSON:",e,"Raw response was:",o),[]}if(!Array.isArray(a))return console.error("Parsed AI response is not an array:",a),[];this.options.objects.showDebugVisualizations&&this._visualizeBoundingBoxesOnImage(t,a);const h=a.map(async i=>{const{ymin:s,xmin:o,ymax:a,xmax:h,objectName:l,...c}=i||{};if([s,o,a,h].some(e=>"number"!=typeof e))return null;const d=new e.Box2(new e.Vector2(o/1e3,s/1e3),new e.Vector2(h/1e3,a/1e3)),u=new e.Vector2;d.getCenter(u);const p={u:u.x,v:u.y},g=this.deviceCamera.simulatorCamera?this.camera.projectionMatrix:(new e.Matrix4).fromArray(this.depth.view[0].projectionMatrix),m=Be(p,n,g,r,this.deviceCamera,this.depth);if(m){const e=this.options.objects.objectImageMargin,i=d.clone();i.min.subScalar(e),i.max.addScalar(e);const s=await Fe(t,i),n=new Zs(l,s,d,c);return n.position.copy(m),this.add(n),this._detectedObjects.set(n.uuid,n),this._debugVisualsGroup&&this._createDebugVisual(n),n}});return(await Promise.all(h)).filter(Boolean)}catch(e){return console.error("AI query for object detection failed:",e),[]}finally{this.aiOptions.gemini.config=o}}get(e=null){const t=Array.from(this._detectedObjects.values());return e?t.filter(t=>t.label===e):t}clear(){for(const e of this._detectedObjects.values())this.remove(e);return this._detectedObjects.clear(),this._debugVisualsGroup&&this._debugVisualsGroup.clear(),this}showDebugVisualizations(e=!0){this._debugVisualsGroup&&(this._debugVisualsGroup.visible=e)}_visualizeBoundingBoxesOnImage(e,t){const i=new Image;i.onload=()=>{const e=document.createElement("canvas");e.width=i.naturalWidth,e.height=i.naturalHeight;const s=e.getContext("2d");s.drawImage(i,0,0),t.forEach(t=>{const{ymin:i,xmin:n,ymax:r,xmax:o,objectName:a}=t||{};if([i,n,r,o].some(e=>"number"!=typeof e))return;const h=n/1e3*e.width,l=i/1e3*e.height,c=(o-n)/1e3*e.width,d=(r-i)/1e3*e.height;s.strokeStyle="#FF0000",s.lineWidth=Math.max(2,e.width/400),s.strokeRect(h,l,c,d);const u=a||"unknown",p=Math.max(16,e.width/80);s.font=`bold ${p}px sans-serif`,s.textBaseline="bottom";const g=s.measureText(u);s.fillStyle="rgba(0, 0, 0, 0.6)",s.fillRect(h,l-p,g.width+8,p+4),s.fillStyle="#FFFFFF",s.fillText(u,h+4,l+2)});const n=(new Date).toISOString().slice(0,19).replace("T","_").replace(/:/g,"-"),r=document.createElement("a");r.download=`detection_debug_${n}.png`,r.href=e.toDataURL("image/png"),r.click()},i.src=e}async _createDebugVisual(t){const i=new e.Mesh(new e.SphereGeometry(.03,16,16),new e.MeshBasicMaterial({color:4282549748}));i.position.copy(t.position);const{Text:s}=await import("troika-three-text"),n=new s;n.text=t.label,n.fontSize=.07,n.color=16777215,n.anchorX="center",n.anchorY="bottom",n.position.copy(i.position),n.position.y+=.04,this._debugVisualsGroup.add(i,n),n.sync()}_buildGeminiConfig(){const e=this.options.objects.backendConfig.gemini;return{thinkingConfig:{thinkingBudget:0},responseMimeType:"application/json",responseSchema:e.responseSchema,systemInstruction:[{text:e.systemInstruction}]}}}class tn extends e.Mesh{constructor(t,i){const s=t.polygon,n=[];for(const t of s)n.push(new e.Vector2(t.x,t.z));const r=new e.Shape(n),o=new e.ShapeGeometry(r);o.rotateX(Math.PI/2),super(o,i),this.xrPlane=t,this.label=t.semanticLabel||"unknown",this.orientation=t.orientation}}class sn extends S{constructor(){super(...arguments),this._detectedPlanes=new Map}static{this.dependencies={options:Ht,renderer:e.WebGLRenderer}}init({options:t,renderer:i}){this.renderer=i,t.planes.showDebugVisualizations&&(this._debugMaterial=new e.MeshBasicMaterial({color:16776960,wireframe:!0,side:e.DoubleSide}))}update(e,t){if(!t||!t.detectedPlanes)return;if(this._xrRefSpace=this._xrRefSpace||this.renderer.xr.getReferenceSpace()||void 0,!this._xrRefSpace)return;const i=t.detectedPlanes,s=new Set(this._detectedPlanes.keys());for(const e of i){s.delete(e);const i=this._detectedPlanes.get(e);i?e.lastChangedTime>(i.xrPlane.lastChangedTime||0)&&this._updatePlaneMesh(t,i,e):this._addPlaneMesh(t,e)}for(const e of s)this._removePlaneMesh(e)}_addPlaneMesh(t,i){const s=this._debugMaterial||new e.MeshBasicMaterial({visible:!1}),n=new tn(i,s);this._updatePlanePose(t,n,i),this._detectedPlanes.set(i,n),this.add(n)}_updatePlaneMesh(t,i,s){const n=s.polygon.map(t=>new e.Vector2(t.x,t.z)),r=new e.Shape(n),o=new e.ShapeGeometry(r);i.geometry.dispose(),i.geometry=o,i.xrPlane=s,this._updatePlanePose(t,i,s)}_removePlaneMesh(e){const t=this._detectedPlanes.get(e);t&&(t.geometry.dispose(),this.remove(t),this._detectedPlanes.delete(e))}_updatePlanePose(e,t,i){const s=e.getPose(i.planeSpace,this._xrRefSpace);s&&(t.position.copy(s.transform.position),t.quaternion.copy(s.transform.orientation))}get(e){const t=Array.from(this._detectedPlanes.values());return e?t.filter(t=>t.label===e):t}showDebugVisualizations(e=!0){this._debugMaterial&&(this.visible=e)}}class nn extends S{constructor(){super(...arguments),this.raycaster=new e.Raycaster}static{this.dependencies={options:Ht,camera:e.Camera}}async init({options:e,camera:t}){this.options=e,this.camera=t,this.options&&this.options.enabled&&(this.options.planes.enabled&&(this.planes=new sn,this.add(this.planes)),this.options.objects.enabled&&(this.objects=new en,this.add(this.objects)))}anchorObjectAtReticle(e,t){throw new Error("Method not implemented")}update(e,t){this.options}placeOnSurface(e,t){if(!this.planes)return console.warn("Cannot placeOnSurface: PlaneDetector is not enabled."),!1;const i=this.planes.get();if(0===i.length)return!1;this.raycaster.setFromXRController(t);const s=this.raycaster.intersectObjects(i);if(s.length>0){return Js(e,s[0],this.camera),!0}return!1}showDebugVisualizations(e=!0){this.planes?.showDebugVisualizations(e),this.objects?.showDebugVisualizations(e)}}class rn extends C{static{this.dependencies={renderer:e.WebGLRenderer,camera:e.Camera,timer:e.Timer,scene:e.Scene,options:Kt}}constructor(){super(new e.SphereGeometry(1,64,32),new e.MeshBasicMaterial({color:16777215,transparent:!0,opacity:0,depthTest:!1,side:e.BackSide})),this.ignoreReticleRaycast=!0,this.currentMode="AR",this.transitionTime=1.5,this.targetAlpha=0,this.defaultBackgroundColor=new e.Color(16777215),this.ignoreReticleRaycast=!0,this.renderOrder=-1/0}init({renderer:e,camera:t,timer:i,scene:s,options:n}){this.renderer=e,this.sceneCamera=t,this.timer=i,this.scene=s,this.transitionTime=n.transition.transitionTime,this.defaultBackgroundColor.set(n.transition.defaultBackgroundColor),this.material.color.copy(this.defaultBackgroundColor),this.scene.add(this)}toVR({targetAlpha:t=1,color:i}={}){this.targetAlpha=e.MathUtils.clamp(t,0,1),this.material.color.set(i??this.defaultBackgroundColor),this.currentMode="VR"}toAR(){this.targetAlpha=0,this.currentMode="AR"}update(){this.renderer.xr.isPresenting?this.renderer.xr.getCamera().getWorldPosition(this.position):this.sceneCamera.getWorldPosition(this.position);const t=this.material.opacity;if(t!==this.targetAlpha){const i=this.timer.getDelta()/this.transitionTime;this.material.opacity=e.MathUtils.lerp(t,this.targetAlpha,i),Math.abs(this.material.opacity-this.targetAlpha)<.01&&(this.material.opacity=this.targetAlpha)}}dispose(){this.parent&&this.parent.remove(this),this.material.dispose(),this.geometry.dispose()}}class on{constructor(){if(this.screenshotSynthesizer=new He,this.waitFrame=new qe,this.registry=new Ue,this.timer=new e.Timer,this.input=new ct,this.scene=new e.Scene,this.user=new pt,this.ui=new Hs,this.sound=new ss,this.renderSceneBound=this.renderScene.bind(this),this.simulator=new Ni(this.renderSceneBound),this.dragManager=new Os,this.world=new nn,this.textureLoader=new e.TextureLoader,this.webXRSettings={},this.simulatorRunning=!1,this.depth=new Oe,this.ai=new $,this.scriptsManager=new We(async e=>{await ki(e,this.registry,this),this.physics&&await e.initPhysics(this.physics)}),on.instance)return on.instance;on.instance=this,this.scene.name="XR Blocks Scene",this.scene.add(this.user),this.scene.add(this.dragManager),this.scene.add(this.ui),this.scene.add(this.sound),this.scene.add(this.world),this.registry.register(this.registry),this.registry.register(this.waitFrame),this.registry.register(this.scene),this.registry.register(this.timer),this.registry.register(this.input),this.registry.register(this.user),this.registry.register(this.ui),this.registry.register(this.sound),this.registry.register(this.dragManager),this.registry.register(this.user),this.registry.register(this.simulator),this.registry.register(this.scriptsManager),this.registry.register(this.depth)}async init(t=new Kt){if(Xs.showSpinner(),this.registry.register(t,Kt),this.registry.register(t.depth,xe),this.registry.register(t.simulator,zt),this.registry.register(t.world,Ht),this.registry.register(t.ai,F),this.registry.register(t.sound,Ut),this.registry.register(t.gestures,gt),t.transition.enabled&&(this.transition=new rn,this.user.add(this.transition),this.registry.register(this.transition)),this.camera=new e.PerspectiveCamera(90,window.innerWidth/window.innerHeight,t.camera.near,t.camera.far),this.registry.register(this.camera,e.Camera),this.registry.register(this.camera,e.PerspectiveCamera),this.renderer=new e.WebGLRenderer({canvas:t.canvas,antialias:t.antialias,stencil:t.stencil,alpha:!0,logarithmicDepthBuffer:t.logarithmicDepthBuffer}),this.renderer.setPixelRatio(window.devicePixelRatio),this.renderer.setSize(window.innerWidth,window.innerHeight),this.renderer.xr.enabled=!0,this.renderer.xr.getDepthSensingMesh=function(){return null},this.registry.register(this.renderer),this.renderer.xr.setReferenceSpaceType(t.referenceSpaceType),!t.canvas){const e=document.createElement("div");document.body.appendChild(e),e.appendChild(this.renderer.domElement)}this.options=t,t.controllers.enabled&&(this.input.init({scene:this.scene,options:t,renderer:this.renderer}),this.input.bindSelectStart(this.scriptsManager.callSelectStartBound),this.input.bindSelectEnd(this.scriptsManager.callSelectEndBound),this.input.bindSelect(this.scriptsManager.callSelectBound),this.input.bindSqueezeStart(this.scriptsManager.callSqueezeStartBound),this.input.bindSqueezeEnd(this.scriptsManager.callSqueezeEndBound),this.input.bindSqueeze(this.scriptsManager.callSqueezeBound),this.input.bindKeyDown(this.scriptsManager.callKeyDownBound),this.input.bindKeyUp(this.scriptsManager.callKeyUpBound)),t.deviceCamera?.enabled&&(this.deviceCamera=new je(t.deviceCamera),this.registry.register(this.deviceCamera));const i=t.webxrRequiredFeatures;this.webXRSettings.requiredFeatures=i,t.depth.enabled&&(i.push("depth-sensing"),i.push("local-floor"),this.webXRSettings.depthSensing={usagePreference:[],dataFormatPreference:[this.options.depth.useFloat32?"float32":"luminance-alpha"]},this.depth.init(this.camera,t.depth,this.renderer,this.registry,this.scene)),t.hands.enabled&&(i.push("hand-tracking"),this.user.hands=new tt(this.input.hands),t.gestures.enabled&&(this.gestureRecognition=new _t,this.scene.add(this.gestureRecognition),this.registry.register(this.gestureRecognition))),t.world.planes.enabled&&i.push("plane-detection"),t.lighting.enabled&&(i.push("light-estimation"),this.lighting=new At,this.lighting.init(t.lighting,this.renderer,this.scene,this.depth)),t.physics&&t.physics.RAPIER&&(this.physics=new Ot,this.registry.register(this.physics),await this.physics.init({physicsOptions:t.physics}),t.depth.enabled&&this.depth.depthMesh?.initRapierPhysics(this.physics.RAPIER,this.physics.blendedWorld)),this.webXRSessionManager=new Ke(this.renderer,this.webXRSettings,"immersive-ar"),this.webXRSessionManager.addEventListener(Xe.SESSION_START,e=>this.onXRSessionStarted(e.session)),this.webXRSessionManager.addEventListener(Xe.SESSION_END,this.onXRSessionEnded.bind(this));const s=this.options.xrButton.autostartSimulator||this.options.xrButton.autostartSimulatorOnDesktop&&this.options.xrButton.enableSimulator&&fe();!s&&t.xrButton.enabled&&(this.xrButton=new Qe(this.webXRSessionManager,t.xrButton?.startText,t.xrButton?.endText,t.xrButton?.invalidText,t.xrButton?.startSimulatorText,t.xrButton?.enableSimulator,t.xrButton?.showSimulatorButtonOnMobile,this.startSimulator.bind(this)),document.body.appendChild(this.xrButton.domElement)),await this.webXRSessionManager.initialize(),t.usePostprocessing&&(this.effects=new Je(this.renderer,this.scene,this.timer),this.simulator.effects=this.effects),t.ai.enabled&&(this.registry.register(this.ai),this.scene.add(this.ai),await this.scriptsManager.initScript(this.ai)),await this.scriptsManager.syncScriptsWithScene(this.scene),window.addEventListener("resize",this.onWindowResize.bind(this)),this.renderer.setAnimationLoop(this.update.bind(this)),this.physics&&setInterval(this.physicsStep.bind(this),1e3*this.physics.timestep),this.options.reticles.enabled&&this.input.addReticles(),s&&this.startSimulator(),Xs.isLoading||Xs.hideSpinner()}update(e,t){this.currentFrame=t,this.timer.update(e),this.simulatorRunning&&this.simulator.simulatorUpdate(),this.depth.update(t),this.lighting&&this.lighting.update(),this.scriptsManager.syncScriptsWithScene(this.scene);for(const e of this.scriptsManager.scripts)e.ux.reset();this.input.update();for(const e of this.input.controllers)if(e.userData.selected)for(const t of this.scriptsManager.scripts)t.onSelecting({target:e});for(const e of this.input.controllers)if(e.userData.squeezing)for(const t of this.scriptsManager.scripts)t.onSqueezing({target:e});this.waitFrame.onFrame();for(const i of this.scriptsManager.scripts)i.update(e,t);this.renderSimulatorAndScene(),this.screenshotSynthesizer.onAfterRender(this.renderer,this.renderSceneBound,this.deviceCamera),this.simulatorRunning&&this.simulator.renderSimulatorScene()}physicsStep(){this.physics.physicsStep();for(const e of this.scriptsManager.scripts)e.physicsStep()}async onXRSessionStarted(e){this.options.deviceCamera?.enabled&&await this.deviceCamera.init(),this.scriptsManager.onXRSessionStarted(e)}async startSimulator(){this.xrButton?.domElement.remove(),this.scene.add(this.simulator),await this.scriptsManager.initScript(this.simulator),this.onSimulatorStarted()}onXRSessionEnded(){this.startSimulator(),this.scriptsManager.onXRSessionEnded()}onSimulatorStarted(){this.simulatorRunning=!0,this.scriptsManager.onSimulatorStarted(),this.lighting&&(this.lighting.simulatorRunning=!0)}onWindowResize(){this.camera.aspect=window.innerWidth/window.innerHeight,this.camera.updateProjectionMatrix(),this.renderer.setSize(window.innerWidth,window.innerHeight)}renderSimulatorAndScene(){this.simulatorRunning?this.simulator.renderScene():this.renderScene()}renderScene(e){if(this.renderSceneOverride)this.renderSceneOverride(this.renderer,this.scene,e??this.camera);else if(this.effects)this.effects.render();else if(this.renderer.render(this.scene,e??this.camera),ut(this.scene,e=>e.layers.isEnabled(4))){const e=this.camera.layers.mask;this.camera.layers.set(4),this.renderer.render(this.scene,this.camera),this.camera.layers.mask=e}}}class an{static createOcclusionMapOverrideMaterial(){return new e.MeshBasicMaterial}static addOcclusionToShader(t){t.uniforms.occlusionEnabled={value:!0},t.uniforms.tOcclusionMap={value:null},t.uniforms.uOcclusionClipFromWorld={value:new e.Matrix4},t.defines={USE_UV:!0,DISTANCE:!0},t.vertexShader=t.vertexShader.replace("#include <common>",["uniform mat4 uOcclusionClipFromWorld;","varying vec4 vOcclusionScreenCoord;","#include <common>"].join("\n")).replace("#include <fog_vertex>",["#include <fog_vertex>","vOcclusionScreenCoord = uOcclusionClipFromWorld * worldPosition;"].join("\n")),t.fragmentShader=t.fragmentShader.replace("uniform vec3 diffuse;",["uniform vec3 diffuse;","uniform bool occlusionEnabled;","uniform sampler2D tOcclusionMap;","varying vec4 vOcclusionScreenCoord;"].join("\n")).replace("vec4 diffuseColor = vec4( diffuse, opacity );",["vec4 diffuseColor = vec4( diffuse, opacity );","vec2 occlusion_coordinates = 0.5 + 0.5 * vOcclusionScreenCoord.xy / vOcclusionScreenCoord.w;","vec2 occlusion_sample = texture2D(tOcclusionMap, occlusion_coordinates.xy).rg;","occlusion_sample = occlusion_sample / max(0.0001, occlusion_sample.g);","float occlusion_value = clamp(occlusion_sample.r, 0.0, 1.0);","diffuseColor.a *= occlusionEnabled ? occlusion_value : 1.0;"].join("\n"))}}const hn=new e.Euler,ln=new e.Matrix4,cn=new e.Vector3;function dn(t,i=new e.Quaternion){return hn.setFromQuaternion(t,"YXZ"),i.setFromAxisAngle(bs,hn.y)}function un(t,i=bs,s=new e.Quaternion){return ln.lookAt(Ds,t,i),s.setFromRotationMatrix(ln)}function pn(e,t){let i=2*Math.acos(e.w);if(i=(i+Math.PI)%(2*Math.PI)-Math.PI,Math.abs(i)<=t)return;const s=cn.set(e.x,e.y,e.z).multiplyScalar(1/Math.sqrt(1-e.w*e.w));s.normalize(),e.setFromAxisAngle(s,t*Math.sign(i))}class gn{static{this.dependencies={}}async init(e={}){}async play(e={}){}}const mn=3*Math.PI/180,fn=new e.Vector3,vn=new e.Vector3,yn=new e.Vector3,wn=new e.Quaternion,xn=new e.Quaternion,Sn=new e.Quaternion;class bn extends gn{static{this.dependencies={simulator:Ni,camera:e.Camera,timer:e.Timer,input:ct}}constructor(e){super(),this.target=e}async init({simulator:e,camera:t,timer:i,input:s}){this.simulator=e,this.camera=t,this.timer=i,this.input=s}controllerIsPointingAtButton(e,t){const i=e.simulatorControllerState,s=i.currentControllerIndex,n=i.localControllerPositions[s],r=i.localControllerOrientations[s];this.target.getWorldPosition(vn),yn.copy(vn).applyMatrix4(t.matrixWorldInverse),wn.copy(r).invert(),fn.copy(yn).sub(n),un(fn,bs,xn);return(xn.angleTo(r)+Math.PI)%(2*Math.PI)-Math.PI<mn}rotateControllerTowardsButton(e,t,i){const s=e.simulatorControllerState,n=s.currentControllerIndex,r=s.localControllerPositions[n],o=s.localControllerOrientations[n];this.target.getWorldPosition(vn),yn.copy(vn).applyMatrix4(t.matrixWorldInverse),wn.copy(o).invert(),fn.copy(yn).sub(r),un(fn,bs,xn),Sn.copy(xn).multiply(wn),pn(Sn,1*i),o.premultiply(Sn)}pinchController(){const e=this.simulator,t=e.controls.simulatorControllerState,i=!0;this.input.dispatchEvent({type:"selectstart",target:this.input.controllers[t.currentControllerIndex]}),0==t.currentControllerIndex?e.hands.setLeftHandPinching(i):e.hands.setRightHandPinching(i)}async play({simulatorUser:e,journeyId:t,waitFrame:i}){let s=!1;for(;e.isOnJourneyId(t)&&!s;){const e=this.timer.getDelta();this.controllerIsPointingAtButton(this.simulator.controls,this.camera)?(this.pinchController(),s=!0):this.rotateControllerTowardsButton(this.simulator.controls,this.camera,e),await i.waitFrame()}}}class Cn extends gn{static{this.dependencies={simulator:Ni}}async init({simulator:e}){this.simulator=e}async play(){this.simulator.hands&&this.simulator.hands.showHands()}}const Tn=3*Math.PI/180,Rn=new e.Vector3,Mn=new e.Vector3,Dn=new e.Vector3,En=new e.Quaternion,Pn=new e.Quaternion,_n=new e.Quaternion;class An extends gn{static{this.dependencies={camera:e.Camera,timer:e.Timer}}constructor(e){super(),this.target=e}async init({camera:e,timer:t}){this.camera=e,this.timer=t}isLookingAtTarget(){const e=this.camera;this.target.getWorldPosition(Rn),Mn.copy(Rn).sub(e.position),un(Mn,bs,Pn);return(Pn.angleTo(e.quaternion)+Math.PI)%(2*Math.PI)-Math.PI<Tn}isNearTarget(){const e=this.camera;return this.target.getWorldPosition(Rn),Mn.copy(Rn).sub(e.position),Math.abs(Mn.length()-.5)<.1}lookAtTarget(){const e=this.camera;_n.copy(e.quaternion).invert(),this.target.getWorldPosition(Rn),Mn.copy(Rn).sub(e.position),un(Mn,bs,Pn),e.quaternion.copy(Pn)}lookTowardsTarget(){const e=this.camera;_n.copy(e.quaternion).invert();const t=this.timer.getDelta();this.target.getWorldPosition(Rn),Mn.copy(Rn).sub(e.position),un(Mn,bs,Pn),En.copy(Pn).multiply(_n),pn(En,1*t),e.quaternion.premultiply(En)}moveTowardsTarget(){const e=this.camera,t=this.timer.getDelta();this.target.getWorldPosition(Rn),Mn.copy(Rn).sub(e.position),Dn.copy(Rn).addScaledVector(Mn,-.1);const i=Dn.sub(e.position),s=T(i.length(),0,1*t);e.position.addScaledVector(i,s/i.length())}async play({simulatorUser:e,journeyId:t,waitFrame:i}){let s=this.isLookingAtTarget(),n=this.isNearTarget(),r=e.isOnJourneyId(t);for(;r&&(!s||!n);)s?(this.lookAtTarget(),this.moveTowardsTarget()):this.lookTowardsTarget(),await i.waitFrame(),s=this.isLookingAtTarget(),n=this.isNearTarget(),r=e.isOnJourneyId(t)}}const On=new on,In=On.scene,Ln=On.user,Vn=On.world,Bn=On.ai;function Fn(...e){return In.add(...e)}function zn(e=new Kt){return On.init(e)}function kn(e){return On.scriptsManager.initScript(e)}function jn(e){return On.scriptsManager.uninitScript(e)}function Un(){return On.timer.getDelta()}function Nn(e){On.depth.depthMesh&&(On.depth.depthMesh.ignoreReticleRaycast=!e)}function Gn(){return On.renderer.xr.getCamera().cameras[0]}function Hn(){return On.renderer.xr.getCamera().cameras[1]}function Wn(e){return e.layers.set(1),e.children.forEach(e=>{Wn(e)}),e}function qn(e){return e.layers.set(2),e.children.forEach(e=>{qn(e)}),e}async function Xn(t){const i=await new Promise((i,s)=>{(new e.ImageLoader).load(t,i,void 0,s)}),s=new e.Texture;s.image=i,s.repeat.x=.5,s.needsUpdate=!0;const n=s.clone();return n.offset.x=.5,n.needsUpdate=!0,[s,n]}class Kn extends os{#e;get icon(){return this.#e}set icon(e){this.#e!=e&&(this.#e=e,this.updateIcon())}#t;get iconWeight(){return this.#t}set iconWeight(e){this.#t!=e&&(this.#t=e,this.updateIcon())}#i;get iconStyle(){return this.#i}set iconStyle(e){this.#i!=e&&(this.#i=e,this.updateIcon())}#s;get iconColor(){return this.#s}set iconColor(t){this.#s!=t&&(this.#s=t,this.group?.traverse?.(i=>{i instanceof e.Mesh&&i.material?.color?.set?.(t)}))}constructor({icon:e="sunny",iconWeight:t=400,iconStyle:i="outlined",iconScale:s=1,iconColor:n="#FFFFFF"}){super({}),this.#e="",this.#t=400,this.#i="",this.#s="",this.iconScale=1,this.icon=e,this.iconWeight=t,this.iconStyle=i,this.iconScale=s,this.iconColor=n}async init(){null==this.group&&await this.updateIcon()}async updateIcon(){if(!this.icon||!this.iconWeight||!this.iconStyle)return;const t="https://cdn.jsdelivr.net/gh/marella/material-symbols@v0.33.0/svg/{{weight}}/{{style}}/{{icon}}.svg".replace("{{style}}",this.iconStyle).replace("{{icon}}",this.icon).replace("{{weight}}",String(this.iconWeight));if(t==this.loadedSvgPath||t==this.loadingSvgPath)return;this.loadingSvgPath=t;const i=await new Promise((e,i)=>{(new a).load(t,e,void 0,i)});this.loadingSvgPath=void 0,this.loadedSvgPath=t;const[s,n,r,o]=i.xml.attributes.viewBox.value.split(" "),h=i.paths,l=new e.Group,c=1/Math.max(r,o),d=new e.MeshBasicMaterial({color:this.iconColor,transparent:!0,side:e.DoubleSide,depthWrite:!1});for(let t=0;t<h.length;t++){const i=h[t],r=a.createShapes(i);for(let t=0;t<r.length;t++){const i=r[t],o=new e.ShapeGeometry(i),a=new e.Mesh(o,d);a.scale.set(c,-c,c),a.position.x=-.5-s*c,a.position.y=.5+n*c,l.add(a)}}this.group&&(this.remove(this.group),this.group?.traverse?.(t=>{"dispose"in t&&"function"==typeof t.dispose&&t.dispose?.(),t instanceof e.Mesh&&(t.geometry?.dispose?.(),t.material?.dispose?.())})),this.group=l,l.scale.setScalar(this.iconScale),this.add(l)}}class $n extends S{constructor(){super(...arguments),this.scrollSpeedLinesPerSecond=3,this.lines=1,this.currentLine=0,this.targetLine=0,this.shouldUpdate=!0,this.lineCount=0}static{this.dependencies={timer:e.Timer}}init({timer:e}){this.timer=e}update(){if(super.update(),!this.shouldUpdate)return!1;const e=this.timer.getDelta(),t=this.scrollSpeedLinesPerSecond*e,i=this.targetLine-this.currentLine;this.currentLine+=T(i,-t,t)}}const Qn=new e.Vector3;class Yn extends os{constructor(e={}){super(e)}updateLayout(){Qn.copy(this.position),super.updateLayout(),this.position.copy(Qn)}}class Jn extends S{static{this.dependencies={timer:e.Timer}}constructor({pages:e=1}){super(),this.currentPage=0,this.shouldUpdate=!0,this.pages=1,this.pages=e}init({timer:e}){this.timer=e}update(){if(super.update(),!this.shouldUpdate)return!1;const e=Math.sin(Math.PI*(this.currentPage%1)),t=(this.currentPage%1>=.5?1:-1)*Number(Math.abs(e)>.01),i=T(this.currentPage+t,0,this.pages-1),s=Math.abs(i-this.currentPage);this.currentPage+=t*T(e*this.timer.getDelta(),0,s)}addPage(){return this.pages++}}const Zn=new e.Vector3,er=new e.Matrix4;class tr extends os{static{this.dependencies={renderer:e.WebGLRenderer,input:ct}}constructor(t={}){super(t),this.localClippingPlanes=[new e.Plane(new e.Vector3(1,0,0),.5),new e.Plane(new e.Vector3(-1,0,0),.5)],this.raycastMesh=new e.Mesh(new e.PlaneGeometry,new e.MeshBasicMaterial({visible:!1})),this.clippingPlanes=[],this.selecting=!1,this.selectStartPositionLocal=new e.Vector3,this.selectStartPage=0,this.raycastPlane=new e.Plane,this.selectingRay=new e.Ray,this.selectingRayTarget=new e.Vector3;const{state:i=new Jn({pages:1}),enableRaycastOnChildren:s=!0,continuousScrolling:n=!0}=t;this.state=i,this.enableRaycastOnChildren=s,this.continuousScrolling=n;for(let e=0;e<this.state.pages;e++)this.add(new Yn);for(let e=0;e<this.localClippingPlanes.length;e++)this.clippingPlanes.push(this.localClippingPlanes[e].clone())}init({renderer:e,input:t}){e.localClippingEnabled=!0,this.input=t}updatePageCount(){this.remove(this.raycastMesh);for(let e=this.children.length;e<this.state.pages;e++)this.add(new Yn);for(let e=this.state.pages;e<this.children.length;)this.children[e].dispose?.(),this.remove(this.children[e]);this.add(this.raycastMesh)}updatePagePositions(){const e=Math.floor(this.state.pages/2);for(let t=0;t<this.state.pages;t++){const i=this.continuousScrolling&&this.state.pages>1?(t-this.state.currentPage+e+this.state.pages)%this.state.pages-e:t-this.state.currentPage;this.children[t].position.x=i*this.rangeX}}resetClippingPlanesToLocalSpace(){for(let e=0;e<this.localClippingPlanes.length&&e<this.clippingPlanes.length;e++)this.clippingPlanes[e].copy(this.localClippingPlanes[e])}updateClippingPlanes(){this.resetClippingPlanesToLocalSpace(),this.updateWorldMatrix(!0,!1);for(const e of this.clippingPlanes)e.applyMatrix4(this.matrixWorld);this.traverse(t=>{t instanceof e.Mesh&&(t.material.clippingPlanes=this.clippingPlanes)})}update(){this.updatePageCount(),this.updatePagePositions(),this.updateClippingPlanes()}updateLayout(){super.updateLayout(),this.raycastMesh.scale.set(this.rangeX,this.rangeY,1)}onObjectSelectStart(e){const t=e.target,i=this.input.intersectionsForController.get(t),s=i.findIndex(e=>e.object==this);if(-1==s)return!1;const n=i[s];return this.selecting=!0,this.selectingController=t,this.updateMatrixWorld(),this.selectStartPositionLocal.copy(n.point).applyMatrix4(er.copy(this.matrixWorld).invert()),this.raycastPlane.normal.set(0,0,1),this.raycastPlane.constant=0,this.raycastPlane.applyMatrix4(this.matrixWorld),this.selectStartPage=this.state.currentPage,!0}computeSelectingDelta(e,t){return(e.x-t.x)/this.rangeX}onSelecting(){if(this.selecting){this.selectingRay.origin.set(0,0,0),this.selectingRay.direction.set(0,0,-1),this.selectingController.updateMatrixWorld(),this.selectingRay.applyMatrix4(this.selectingController.matrixWorld),this.selectingRay.intersectPlane(this.raycastPlane,this.selectingRayTarget),this.updateMatrixWorld(),this.selectingRayTarget.applyMatrix4(er.copy(this.matrixWorld).invert());const e=this.computeSelectingDelta(this.selectingRayTarget,this.selectStartPositionLocal);this.state.currentPage=this.continuousScrolling&&this.state.pages>1?(this.selectStartPage-e+this.state.pages)%this.state.pages:T(this.selectStartPage-e,0,this.state.pages-1)}}onObjectSelectEnd(e){return e.target==this.selectingController&&(this.selecting=!1),!0}raycast(e,t){const i=[];if(this.raycastMesh.raycast(e,i),i.forEach(e=>{e.object=this,t.push(e)}),this.enableRaycastOnChildren){const i=[];for(const t of this.children)e.intersectObject(t,!0,i);this.updateMatrixWorld(),er.copy(this.matrixWorld).invert();for(const e of i){const i=Zn.copy(e.point).applyMatrix4(er);Math.abs(i.x)<.5&&t.push(e)}}return!1}}class ir extends tr{constructor(){super(...arguments),this.localClippingPlanes=[new e.Plane(new e.Vector3(0,1,0),.5),new e.Plane(new e.Vector3(0,-1,0),.5)]}updateLayout(){super.updateLayout(),this.localClippingPlanes[0].constant=.5*this.rangeY,this.localClippingPlanes[1].constant=.5*this.rangeY}computeSelectingDelta(e,t){return(e.y-t.y)/this.rangeY}}class sr extends os{constructor({text:e="ScrollingTroikaTextView",textAlign:t="left",scrollerState:i=new $n,fontSize:s=.06}={}){super(),this.onTextSyncCompleteBound=this.onTextSyncComplete.bind(this),this.currentText="",this.scrollerState=i||new $n,this.pager=new ir,this.textViewWrapper=new os,this.pager.children[0].add(this.textViewWrapper),this.textView=new ps({text:e,textAlign:t,fontSize:s,anchorX:0,anchorY:0}),this.textView.x=-.5,this.textView.addEventListener("synccomplete",this.onTextSyncCompleteBound),this.textViewWrapper.add(this.textView),this.add(this.scrollerState),this.add(this.pager)}update(){this.textViewWrapper.y=this.textView.lineHeight*this.textView.aspectRatio*this.scrollerState.currentLine,this.textViewWrapper.updateLayout()}addText(e){this.setText(this.currentText+e)}setText(e){this.currentText=e,this.textView.setText(this.currentText)}onTextSyncComplete(){this.textView.lineCount>0&&(this.textView.y=this.textView.lineHeight*this.textView.aspectRatio-.5,this.textView.updateLayout(),this.scrollerState.lineCount=this.textView.lineCount,this.scrollerState.targetLine=this.textView.lineCount-1,this.clipToLineHeight())}clipToLineHeight(){const e=this.textView.lineHeight*this.textView.aspectRatio,t=Math.floor(1/e)*e;this.pager.localClippingPlanes[1].constant=t-.5}}const nr=new e.Vector3,rr=new e.Quaternion,or=new e.Euler;class ar{constructor(t=0,i=0,s=1,n=1,r){this.startingValue=t,this.minValue=i,this.maxValue=s,this.scale=n,this.initialPosition=new e.Vector3,this.initialRotationInverse=new e.Quaternion,this.rotationScale=null!=r?r:-this.scale}setInitialPose(e,t){this.initialPosition.copy(e),this.initialRotationInverse.copy(t).invert()}setInitialPoseFromController(e){this.setInitialPose(e.position,e.quaternion)}getValue(e){return nr.copy(e).sub(this.initialPosition).applyQuaternion(this.initialRotationInverse),T(this.startingValue+this.scale*nr.x,this.minValue,this.maxValue)}getValueFromRotation(e){return rr.copy(e).multiply(this.initialRotationInverse),or.setFromQuaternion(rr,"YXZ"),T(this.startingValue+this.rotationScale*or.y,this.minValue,this.maxValue)}getValueFromController(e){return e instanceof at?this.getValueFromRotation(e.quaternion):this.getValue(e.position)}updateValue(e){this.startingValue=e}}const hr=`https://cdn.jsdelivr.net/npm/three@0.${e.REVISION}.0/examples/jsm/`;let lr;class cr{constructor(t=e.DefaultLoadingManager){this.manager=t}async load({path:e,url:t="",renderer:i,onProgress:s}){s&&console.warn("ModelLoader: An onProgress callback was provided to load(), but a LoadingManager is in use. Progress will be reported via the LoadingManager's onProgress callback. The provided callback will be ignored.");const n=t.split(".").pop()?.toLowerCase()||"";return["gltf","glb"].includes(n)?await this.loadGLTF({path:e,url:t,renderer:i}):["ply","spz","splat","ksplat"].includes(n)?await this.loadSplat({url:t}):(console.error("Unsupported file type: "+n),null)}async loadSplat({url:e=""}){const{SplatMesh:t}=await import("@sparkjsdev/spark"),i=new t({url:e});return await i.initialized,i}async loadGLTF({path:e,url:t="",renderer:i}){const s=function(e,t){if(lr)return lr;const i=new h(t);i.setDecoderPath(hr+"libs/draco/"),i.setDecoderConfig({type:"js"});const s=new l(t);return s.setTranscoderPath(hr+"libs/basis/"),e&&s.detectSupport(e),lr=new o(t),lr.setDRACOLoader(i),lr.setKTX2Loader(s),lr}(i,this.manager);return e&&s.setPath(e),new Promise((e,i)=>{s.load(t,t=>e(t),void 0,e=>i(e))})}}class dr extends e.BufferGeometry{constructor(t=1,i=.4,s=12,n=48){super();const r=[],o=[],a=[],h=[],l=new e.Vector3,c=new e.Vector3,d=new e.Vector3;for(let e=0;e<=s;e++)for(let r=0;r<=n;r++){const u=r/n*Math.PI/2,p=e/s*Math.PI+3*Math.PI/2;c.x=(t+i*Math.cos(p))*Math.cos(u),c.y=(t+i*Math.cos(p))*Math.sin(u),c.z=i*Math.sin(p),o.push(c.x,c.y,c.z),l.x=t*Math.cos(u),l.y=t*Math.sin(u),d.subVectors(c,l).normalize(),a.push(d.x,d.y,d.z),h.push(r/n),h.push(e/s)}for(let e=1;e<=s;e++)for(let t=1;t<=n;t++){const i=(n+1)*e+t-1,s=(n+1)*(e-1)+t-1,o=(n+1)*(e-1)+t,a=(n+1)*e+t;r.push(i,s,a),r.push(s,o,a)}this.setIndex(r),this.setAttribute("position",new e.Float32BufferAttribute(o,3)),this.setAttribute("normal",new e.Float32BufferAttribute(a,3)),this.setAttribute("uv",new e.Float32BufferAttribute(h,2))}}function ur(t=1,i=1,s=.02,n=.03,r=5,o=5){const a=function(t=1,i=1,s=.01,n=.03,r=5,o=5){const a=new dr(n,s/2,o,r).rotateX(Math.PI/2),h=a.clone().rotateY(2*Math.PI/2).translate(-(t/2-n),0,-(i/2-n)),l=a.clone().rotateY(3*Math.PI/2).translate(-(t/2-n),0,i/2-n),c=a.clone().rotateY(4*Math.PI/2).translate(t/2-n,0,i/2-n),d=a.rotateY(5*Math.PI/2).translate(t/2-n,0,-(i/2-n)),u=[h,l,c,d],p=new e.CylinderGeometry(s/2,s/2,t-2*n,o,1,!0,0,Math.PI).rotateZ(Math.PI/2),g=p.clone().rotateX(-Math.PI/2).translate(0,0,-i/2),m=p.rotateX(Math.PI/2).translate(0,0,i/2),f=new e.CylinderGeometry(s/2,s/2,i-2*n,o,1,!0,0,Math.PI).rotateX(-Math.PI/2),v=f.clone().rotateY(Math.PI).translate(-t/2,0,0),y=f.translate(t/2,0,0);return[...u,g,m,v,y]}(t,i,s,n,r,o),h=a.reduce((e,t)=>e+t.index.count,0),l=function(t=1,i=1,s=.01,n=.03,r=5){const o=t-2*n,a=i-2*n,h=new e.PlaneGeometry(t,a).rotateX(-Math.PI/2),l=new e.PlaneGeometry(o,n).rotateX(-Math.PI/2),c=a/2+n/2,d=l.clone().translate(0,0,c),u=l.translate(0,0,-c),p=[h,d,u],g=new e.CircleGeometry(n,r,0,Math.PI/2).rotateX(-Math.PI/2),m=a/2,f=o/2,v=g.clone().rotateY(3*Math.PI/2).translate(f,0,m),y=g.clone().rotateY(0*Math.PI/2).translate(f,0,-m),w=g.clone().rotateY(1*Math.PI/2).translate(-f,0,-m),x=g.clone().rotateY(2*Math.PI/2).translate(-f,0,m),S=[...p,v,y,w,x],b=S.map(e=>e.clone().rotateX(Math.PI).translate(0,-s/2,0));return S.forEach(e=>e.translate(0,s/2,0)),[...S,...b]}(t,i,s,n,r),d=l.reduce((e,t)=>e+t.index.count,0),u=[...a,...l],p=c.mergeGeometries(u);return u.forEach(e=>e.dispose()),p.addGroup(0,h,0),p.addGroup(h,d,1),p.computeBoundingBox(),p}class pr extends e.Mesh{constructor(t,i,s){super(ur(t,i,s),[new e.MeshLambertMaterial({color:16777215,transparent:!0,opacity:0}),new e.MeshLambertMaterial({color:16777215,transparent:!0,opacity:0})]),this.draggingMode=Os.TRANSLATING,this.opacity=new rt(0,0,.5,0)}update(e){this.opacity.update(e),this.material[0].opacity=this.opacity.value,this.material[1].opacity=.5*this.opacity.value,this.visible=this.opacity.value>.001}}const gr=new e.Vector2(.2,.2),mr=new e.Vector3,fr=new e.Quaternion,vr=new e.Quaternion;class yr extends e.Object3D{constructor(){super(...arguments),this.draggingMode=As.ROTATING}}class wr extends e.Mesh{constructor(e,t){super(e,t),this.draggingMode=As.ROTATING}}class xr extends S{static{this.dependencies={camera:e.Camera,depth:Oe,scene:e.Scene,renderer:e.WebGLRenderer,registry:Ue}}constructor({castShadow:t=!0,receiveShadow:i=!0,raycastToChildren:s=!1}){super(),this.draggable=!0,this.rotatable=!0,this.scalable=!0,this.platformAnimationSpeed=2,this.platformThickness=.02,this.isOneOneScale=!1,this.initialScale=(new e.Vector3).setScalar(1),this.startAnimationOnLoad=!0,this.clipActions=[],this.clock=new e.Clock,this.hoveringControllers=new Set,this.occludableShaders=new Set,this.bbox=new e.Box3,this.castShadow=t,this.receiveShadow=i,this.raycastToChildren=s}async init({camera:e,depth:t,scene:i,renderer:s,registry:n}){this.camera=e,this.depth=t,this.scene=i,this.renderer=s,this.registry=n;for(const e of this.occludableShaders)this.depth.occludableShaders.add(e);this.splatMesh&&(await this.createSparkRendererIfNeeded(),this.scene.add(this.splatMesh))}async loadSplatModel({data:t,onSceneLoaded:i=e=>{},platformMargin:s=gr,setupRaycastCylinder:n=!0,setupRaycastBox:r=!1,setupPlatform:o=!0}){this.data=t,t.scale&&this.initialScale.copy(t.scale);const a=await(new cr).loadSplat({url:t.model});return this.splatMesh=a,a.raycast=()=>{},this.splatAnchor=new yr,this.splatAnchor.add(a),t.scale&&this.splatAnchor.scale.copy(t.scale),t.rotation&&this.splatAnchor.rotation.set(e.MathUtils.degToRad(t.rotation.x),e.MathUtils.degToRad(t.rotation.y),e.MathUtils.degToRad(t.rotation.z)),t.position&&this.splatAnchor.position.copy(t.position),this.add(this.splatAnchor),await this.createSparkRendererIfNeeded(),await this.setupBoundingBox(!1!==t.verticallyAlignObject,!1!==t.horizontallyAlignObject),n?this.setupRaycastCylinder():r&&this.setupRaycastBox(),o&&this.setupPlatform(s),this.setCastShadow(this.castShadow),this.setReceiveShadow(this.receiveShadow),i?i(this.splatAnchor):this.splatAnchor}async loadGLTFModel({data:t,onSceneLoaded:i=()=>{},platformMargin:s=gr,setupRaycastCylinder:n=!0,setupRaycastBox:r=!1,setupPlatform:o=!0,renderer:a,addOcclusionToShader:h=!1}){this.data=t,t.scale&&this.initialScale.copy(t.scale);const l=await(new cr).loadGLTF({path:t.path,url:t.model,renderer:a}),c=new e.AnimationMixer(l.scene);if(l.animations.forEach(e=>{this.startAnimationOnLoad?c.clipAction(e).play():this.clipActions.push(c.clipAction(e))}),l.scene.draggingMode=Os.ROTATING,this.gltfMesh=l,this.animationMixer=c,t.scale&&this.gltfMesh.scene.scale.copy(t.scale),t.rotation&&l.scene.rotation.set(e.MathUtils.degToRad(t.rotation.x),e.MathUtils.degToRad(t.rotation.y),e.MathUtils.degToRad(t.rotation.z)),t.position&&l.scene.position.copy(t.position),l.scene.draggingMode=Os.ROTATING,this.add(l.scene),await this.setupBoundingBox(!1!==t.verticallyAlignObject,!1!==t.horizontallyAlignObject),n?this.setupRaycastCylinder():r&&this.setupRaycastBox(),o&&this.setupPlatform(s),this.setCastShadow(this.castShadow),this.setReceiveShadow(this.receiveShadow),h){for(const e of this.platform?.material||[])e.onBeforeCompile=t=>{an.addOcclusionToShader(t),t.uniforms.occlusionEnabled.value=!0,e.userData.shader=t,this.occludableShaders.add(t),this.depth?.occludableShaders.add(t)};this.platform?.layers.enable(3),l.scene.traverse(e=>{if(e.isMesh){const t=e;(t.material instanceof Array?t.material:[t.material]).forEach(e=>{e.transparent=!0,e.onBeforeCompile=e=>{an.addOcclusionToShader(e),e.uniforms.occlusionEnabled.value=!0,this.occludableShaders.add(e),this.depth?.occludableShaders.add(e)}}),e.layers.enable(3)}})}return i?i(l.scene):l.scene}async setupBoundingBox(t=!0,i=!0){if(this.splatMesh){const s=await this.splatMesh.getBoundingBox(!1);if(s.isEmpty())return void(this.bbox=s);this.splatAnchor.updateMatrix();const n=s.clone().applyMatrix4(this.splatAnchor.matrix),r=new e.Vector3;n.getCenter(r).multiplyScalar(-1),r.y=t?-n.min.y:0,i||(r.x=0,r.z=0),this.splatAnchor.position.add(r),this.bbox=n.translate(r)}else{const s=this.children.filter(e=>e!==this.platform&&e!==this.rotationRaycastMesh&&e!==this.controlBar);if(this.bbox=function(t){const i=new e.Box3;if(0===t.length)return i;const s=new Map;for(const e of t)e.parent&&(s.set(e,e.parent),e.removeFromParent()),i.expandByObject(e,!0);for(const[e,t]of s.entries())t.add(e);return i}(s),this.bbox.isEmpty())return;const n=new e.Vector3;this.bbox.getCenter(n).multiplyScalar(-1),n.y=t?-this.bbox.min.y:0,i||(n.x=0,n.z=0);for(const e of s)e.position.add(n);this.bbox.translate(n)}}setupRaycastCylinder(){const t=new e.Vector3;this.bbox.getSize(t);const i=.05+.5*Math.min(t.x,t.z),s=new wr(new e.CylinderGeometry(i,i,t.y),new e.MeshBasicMaterial({color:10027008,wireframe:!0}));this.bbox.getCenter(s.position),this.rotationRaycastMesh=s,this.rotationRaycastMesh.visible=!1,this.add(this.rotationRaycastMesh)}setupRaycastBox(){this.rotationRaycastMesh&&(this.rotationRaycastMesh.removeFromParent(),this.rotationRaycastMesh.geometry.dispose(),this.rotationRaycastMesh.material.dispose());const t=new e.Vector3;this.bbox.getSize(t);const i=new wr(new e.BoxGeometry(t.x,t.y,t.z),new e.MeshBasicMaterial({color:10027008,wireframe:!0}));this.bbox.getCenter(i.position),this.rotationRaycastMesh=i,this.rotationRaycastMesh.visible=!1,this.add(this.rotationRaycastMesh)}setupPlatform(t=gr){const i=new e.Vector3;this.bbox.getSize(i);const s=i.x+t.x,n=i.z+t.y;this.platform=new pr(s,n,this.platformThickness);const r=new e.Vector3;this.bbox.getCenter(r),this.platform.position.set(r.x,-this.platformThickness/2,r.z),this.add(this.platform)}update(){const e=this.clock.getDelta();this.animationMixer&&this.animationMixer.update(e),this.platform&&this.platform.update(e);const t=this.camera;if(null!=this.controlBar&&this.controlBar.parent==this&&null!=t){const e=mr.copy(t.position).sub(this.position),i=e.length(),s=Math.asin(e.normalize().y);e.y=0,e.normalize(),fr.copy(this.quaternion).invert(),this.controlBar.quaternion.setFromAxisAngle(Rs,s).premultiply(vr.setFromUnitVectors(Ts,e)).premultiply(fr),this.controlBar.position.setScalar(0).addScaledVector(e,.5).applyQuaternion(fr),this.controlBar.position.y=0,this.controlBar.scale.set(i/this.scale.x,i/this.scale.y,i/this.scale.z)}}onObjectSelectStart(){return this.draggable||this.rotatable||this.scalable}onObjectSelectEnd(){return this.draggable||this.rotatable||this.scalable}onHoverEnter(e){this.hoveringControllers.add(e),this.platform&&(this.platform.opacity.speed=this.platformAnimationSpeed)}onHoverExit(e){this.hoveringControllers.delete(e),this.platform&&0==this.hoveringControllers.size&&(this.platform.opacity.speed=-this.platformAnimationSpeed)}raycast(e,t){const i=this.gltfMesh?.scene??this.splatMesh;if(this.raycastToChildren&&i){const i=[];for(const t of this.children)t!=this.rotationRaycastMesh&&t!=this.platform&&t!=this.controlBar&&e.intersectObject(t,!0,i);t.push(...i)}if(this.rotationRaycastMesh){const i=[];this.rotationRaycastMesh.raycast(e,i);for(const e of i)t.push(e)}if(this.platform){const i=[];this.platform.raycast(e,i);for(const e of i)t.push(e)}if(null!=this.controlBar&&this.controlBar.parent==this){const i=[];this.controlBar.raycast(e,i);for(const e of i)t.push(e)}return!1}onScaleButtonClick(){this.scale.setScalar(1)}setCastShadow(e){this.castShadow=e,this.gltfMesh&&this.gltfMesh.scene.traverse(function(t){t.castShadow=e}),this.platform&&(this.platform.castShadow=!1)}setReceiveShadow(e){this.receiveShadow=e,this.gltfMesh&&this.gltfMesh.scene.traverse(function(t){t.receiveShadow=e}),this.platform&&(this.platform.receiveShadow=e)}getOcclusionEnabled(){for(const e of this.occludableShaders)return e.uniforms.occlusionEnabled.value;return!1}setOcclusionEnabled(e){for(const t of this.occludableShaders)t.uniforms.occlusionEnabled.value=e}playClipAnimationOnce(){this.startAnimationOnLoad||0===this.clipActions.length||this.clipActions.forEach(t=>{t.reset(),t.clampWhenFinished=!0,t.loop=e.LoopOnce,t.play()})}async createSparkRendererIfNeeded(){const{SparkRenderer:e}=await import("@sparkjsdev/spark");let t=!1;if(this.scene.traverse(i=>{t||=i instanceof e}),!t){const t=new e({renderer:this.renderer,maxStdDev:Math.sqrt(5)});this.registry.register(new Ui(t)),this.scene.add(t)}}}class Sr extends os{static{this.dependencies={user:pt}}constructor(){const t=document.createElement("canvas");t.width=1024,t.height=1024;const i=t.getContext("2d"),s=new e.CanvasTexture(t),n=new e.PlaneGeometry(.001*t.width,.001*t.height),r=new e.MeshBasicMaterial({map:s,toneMapped:!1,alphaTest:.01});super({},n,r),this.activeHand=-1,this.activeLine=[],this.activeLines=[],this.removedLines=[],this.isDrawing=!1,this.canvas=t,this.ctx=i,this.material=r,this.width=.001*t.width,this.height=.001*t.height,this.scale.set(this.width,this.height,1)}init({user:e}){super.init(),this.user=e,this.clearCanvas()}getContext(){return this.ctx}triggerUpdate(){this.material.map.needsUpdate=!0}onSelectStart(e){-1===this.activeHand&&(this.activeHand=e?.target?.userData?.id??-1,0!==this.activeHand&&1!==this.activeHand||(this.activeLine=[],this.ctx.beginPath()))}onSelectEnd(e){(e?.target?.userData?.id??-1)===this.activeHand&&(this.activeHand>=0&&this.activeLine.length>1&&(this.activeLines.push(this.activeLine),this.removedLines=[]),this.isDrawing=!1,this.activeLine=[],this.activeHand=-1)}onSelecting(e){const t=e.target.userData.id;if(t!==this.activeHand)return;const i=this.user.getReticleIntersection(t);if(i)if(i.object instanceof Sr&&i.uv){const e=Math.round(1024*i.uv.x),t=Math.round(1024-1024*i.uv.y),s=this.ctx;this.isDrawing?(s.lineTo(e,t),s.strokeStyle="black",s.lineWidth=6,s.stroke(),this.triggerUpdate(),this.activeLine.push({x:e,y:t})):(this.activeLine.push({x:e,y:t,b:!0}),s.moveTo(e,t),this.isDrawing=!0)}else this.isDrawing=!1;else this.isDrawing=!1}clearCanvas(e=!0){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.ctx.fillStyle="#FFFFFF",this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height),e&&this.triggerUpdate()}removeAll(){this.activeLines=[],this.removedLines=[],this.clearCanvas()}undo(){if(0===this.activeLines.length)return;this.ctx=this.canvas.getContext("2d");const e=this.activeLines.pop();this.removedLines.push(e),this.clearCanvas(!1),this.activeLines.forEach(e=>{this.#n(e)}),this.triggerUpdate()}redo(){if(0===this.removedLines.length)return;const e=this.removedLines.pop();this.activeLines.push(e),this.#n(e),this.triggerUpdate()}#n(e){this.ctx.beginPath(),this.ctx.strokeStyle="black",this.ctx.lineWidth=6,e.forEach(e=>{e.b?this.ctx.moveTo(e.x,e.y):(this.ctx.lineTo(e.x,e.y),this.ctx.stroke())})}update(){}}class br extends tr{constructor(){super(...arguments),this.localClippingPlanes=[new e.Plane(new e.Vector3(1,0,0),.5),new e.Plane(new e.Vector3(-1,0,0),.5)]}updateLayout(){super.updateLayout(),this.localClippingPlanes[0].constant=.5*this.rangeX,this.localClippingPlanes[1].constant=.5*this.rangeX}}class Cr extends ps{constructor({pagerState:e}){super({text:""}),this.emptyPageIndicator="◦",this.currentPageIndicator="•",this.numberOfPages=0,this.previousPage=0,this.pagerState=e,this.previousPage=Math.round(e.currentPage),this.numberOfPages=e.pages,this.updateText()}update(){super.update();const e=Math.round(this.pagerState.currentPage);this.previousPage===e&&this.numberOfPages===this.pagerState.pages||this.updateText()}updateText(){const e=Math.round(this.pagerState.currentPage)%this.pagerState.pages,t=new Array(this.pagerState.pages).fill(this.emptyPageIndicator);t[e]=this.currentPageIndicator,this.setText(t.join("")),this.previousPage=e}}class Tr extends ke{constructor({videoFile:e,willCaptureFrequently:t=!1}={}){super({willCaptureFrequently:t}),this.videoFile_=e}async init(){await super.init(),this.videoFile_?(this.setState_(ze.INITIALIZING),await this.initStream_()):(console.warn("VideoFileStream initialized without a video file."),this.setState_(ze.IDLE))}async initStream_(){if(!this.videoFile_)throw new Error("No video file has been provided.");this.stop_(),this.video_.srcObject=null,this.video_.src="string"==typeof this.videoFile_?this.videoFile_:URL.createObjectURL(this.videoFile_),this.video_.loop=!0,this.video_.muted=!0,await new Promise((e,t)=>{this.video_.onloadedmetadata=()=>{this.handleVideoStreamLoadedMetadata(e,t)},this.video_.onerror=()=>{const e=new Error("Error occurred while loading the video file.");this.setState_(ze.ERROR,{error:e}),t(e)},this.video_.play()}),this.setState_(ze.STREAMING,{width:this.width,height:this.height,aspectRatio:this.aspectRatio,videoFile:this.videoFile_})}async setSource(e){if(!e)return console.warn("setSource called with no file. Stopping stream."),this.stop_(),void(this.videoFile_=void 0);this.setState_(ze.INITIALIZING),this.videoFile_=e,await this.initStream_()}}export{$ as AI,F as AIOptions,Jt as AVERAGE_IPD_METERS,ht as ActiveControllers,p as Agent,rt as AnimatableNumber,Gi as AudioListener,Hi as AudioPlayer,Ts as BACK,Xi as BackgroundMusic,$i as CategoryVolumes,js as Col,on as Core,ss as CoreSound,oe as DEFAULT_DEVICE_CAMERA_HEIGHT,re as DEFAULT_DEVICE_CAMERA_WIDTH,Ss as DOWN,Oe as Depth,ye as DepthMesh,we as DepthMeshOptions,xe as DepthOptions,Te as DepthTextures,Zs as DetectedObject,tn as DetectedPlane,ce as DeviceCameraOptions,Os as DragManager,As as DragMode,Is as ExitButton,Cs as FORWARD,ar as FreestandingSlider,ot as GazeController,W as Gemini,V as GeminiOptions,m as GenerateSkyboxTool,_t as GestureRecognition,gt as GestureRecognitionOptions,v as GetWeatherTool,Ls as Grid,Z as HAND_BONE_IDX_CONNECTION_MAP,Y as HAND_JOINT_COUNT,J as HAND_JOINT_IDX_CONNECTION_MAP,Ze as HAND_JOINT_NAMES,et as Handedness,tt as Hands,It as HandsOptions,br as HorizontalPager,gs as IconButton,ms as IconView,fs as ImageView,ct as Input,Wt as InputOptions,ei as Keycodes,Rs as LEFT,te as LEFT_VIEW_ONLY_LAYER,vs as LabelView,At as Lighting,Lt as LightingOptions,qs as LoadingSpinnerManager,Kn as MaterialSymbolsView,C as MeshScript,cr as ModelLoader,xr as ModelViewer,at as MouseController,Ft as NEXT_SIMULATOR_MODE,Q as NUM_HANDS,se as OCCLUDABLE_ITEMS_LAYER,en as ObjectDetector,Nt as ObjectsOptions,_e as OcclusionPass,an as OcclusionUtils,X as OpenAI,B as OpenAIOptions,Kt as Options,Cr as PageIndicator,tr as Pager,Jn as PagerState,ks as Panel,Bs as PanelMesh,Ot as Physics,Vt as PhysicsOptions,bn as PinchOnButtonAction,sn as PlaneDetector,Gt as PlanesOptions,Ms as RIGHT,ie as RIGHT_VIEW_ONLY_LAYER,Ue as Registry,st as Reticle,qt as ReticleOptions,wr as RotationRaycastMesh,Ns as Row,Oi as SIMULATOR_HAND_POSE_NAMES,_i as SIMULATOR_HAND_POSE_TO_JOINTS_LEFT,Ai as SIMULATOR_HAND_POSE_TO_JOINTS_RIGHT,Qi as SOUND_PRESETS,He as ScreenshotSynthesizer,S as Script,w as ScriptMixin,We as ScriptsManager,sr as ScrollingTroikaTextView,Ci as SetSimulatorModeEvent,Cn as ShowHandsAction,Ni as Simulator,Yt as SimulatorCamera,ci as SimulatorControlMode,ti as SimulatorControllerState,Ri as SimulatorControls,Di as SimulatorDepth,Mi as SimulatorDepthMaterial,Pi as SimulatorHandPose,Ei as SimulatorHandPoseChangeRequestEvent,Bi as SimulatorHands,Fi as SimulatorInterface,$t as SimulatorMediaDeviceInfo,Bt as SimulatorMode,zt as SimulatorOptions,Zt as SimulatorRenderMode,zi as SimulatorScene,ji as SimulatorUser,gn as SimulatorUserAction,Sr as SketchPanel,f as SkyboxAgent,Ut as SoundOptions,Yi as SoundSynthesizer,es as SpatialAudio,Gs as SpatialPanel,ts as SpeechRecognizer,jt as SpeechRecognizerOptions,is as SpeechSynthesizer,kt as SpeechSynthesizerOptions,yr as SplatAnchor,ze as StreamState,ws as TextButton,$n as TextScrollerState,ps as TextView,g as Tool,Hs as UI,ne as UI_OVERLAY_LAYER,bs as UP,y as UX,pt as User,ee as VIEW_DEPTH_GAP,ir as VerticalPager,Tr as VideoFileStream,ke as VideoStream,xs as VideoView,os as View,Ki as VolumeCategory,qe as WaitFrame,An as WalkTowardsPanelAction,nn as World,Ht as WorldOptions,Qe as XRButton,je as XRDeviceCamera,Je as XREffects,Ye as XRPass,Xt as XRTransitionOptions,ae as XR_BLOCKS_ASSETS_PATH,Ds as ZERO_VECTOR3,Fn as add,Bn as ai,Ie as aspectRatios,ki as callInitWithDependencyInjection,T as clamp,pn as clampRotationToAngle,On as core,Fe as cropImage,dn as extractYaw,I as getColorHex,Un as getDeltaTime,P as getUrlParamBool,A as getUrlParamFloat,_ as getUrlParamInt,E as getUrlParameter,O as getVec4ByColorString,Gn as getXrCameraLeft,Hn as getXrCameraRight,zn as init,kn as initScript,R as lerp,Xn as loadStereoImageAsTextures,Xs as loadingSpinnerManager,un as lookAtRotation,dt as objectIsDescendantOf,fe as onDesktopUserAgent,L as parseBase64DataURL,Js as placeObjectAtIntersectionFacingTarget,M as print,Le as rgbToDepthParams,In as scene,Wn as showOnlyInLeftEye,qn as showOnlyInRightEye,Nn as showReticleOnDepthMesh,Ve as transformRgbToDepthUv,Be as transformRgbUvToWorld,ut as traverseUtil,jn as uninitScript,D as urlParams,Ln as user,Vn as world,Se as xrDepthMeshOptions,Ce as xrDepthMeshPhysicsOptions,be as xrDepthMeshVisualizationOptions,ge as xrDeviceCameraEnvironmentContinuousOptions,ue as xrDeviceCameraEnvironmentOptions,me as xrDeviceCameraUserContinuousOptions,pe as xrDeviceCameraUserOptions};
2
2
  //# sourceMappingURL=xrblocks.min.js.map